OPT MODULE,OSVERSION=37
OPT PREPROCESS,REG=5

/*
 *-- AutoRev header do NOT edit!!
 *
 *   Project         :   AMIGA kontekst 3
 *   File            :   prefs_Class.e
 *   Description     :   klasa BGUI BOOPSI (opcje programu)
 *   Copyright       :   © 1995-1997 by Piotr Gapiļski
 *   Author          :   Piotr Gapiļski
 *   Creation Date   :   04.05.97
 *   Current version :   v0.810
 *   Translator      :   AmigaE v3.2e
 *
 *   REVISION HISTORY
 *
 *   v0.810 (04.05.97)
 *      - zmienione atrybuty klasy (PREFS_Options)
 *      - struktura ps_Options jest teraz PUBLICZNA i wymagana przy atrybucie
 *        PREFS_Options
 *
 *   v0.809 (28.04.97)
 *      - poprawione dziaīanie metody PM_STANDARD przy flagach STANDARD_LAST,
 *        STANDARD_PREV (warunek koļca pėtli to napotkanie poczātku listy standardów,
 *        a nie jak byīo poprzednio zerowy wskaśnik NIL)
 *      - poprawione dziaīanie atrybutu PREFS_OutDir
 *        teraz, gdy PREFS_OutDir jest pusty (czyli nie zdefiniowano katalogu
 *        docelowego) zwracany jest wskaśnik do katalogu śródīowego
 *
 *   v0.808 (24.04.97)
 *      - poprawiona metoda PM_STANDARD
 *        metoda nie zwracaīa nigdy NIL w przypadku korzystania z flag
 *        STANDARD_NEXT,STANDARD_PREV
 *
 *   v0.807 (17.04.97)
 *      - nowy format pliku PREFS_FILE i CONFIG_FILE
 *      - ustawianie preferencji (via OM_SET) powoduje automatyczne odōwierzanie
 *        wyglādu obiektów
 *
 *
 *
 *---nowe metody:
 *   [PM_SAVEPREFS]:msg
 *      opis:
 *        zapis preferencji na dysk (PREFS_FILE) do pliku (format IFF/PREF) w aktualnym
 *        katalogu programu
 *        chunk OPTS : zainicjowana struktura ps_Options
 *              SDIR : katalog śródīowy
 *              DDIR : katalog docelowy
 *              SSTD : nazwa standardu śródīowego
 *              DSTD : nazwa standardu docelowego
 *      argumenty:
 *        brak
 *      zwraca:
 *        TRUE :sukces
 *        FALSE:bīād
 *      uwagi:
 *        brak
 *
 *   [PM_LOADPREFS]:msg
 *      opis:
 *        odczyt preferencji (PREFS_FILE) z dysku (z aktualnego katalogu programu)
 *        w przypadku gdy plik nie istnieje lub nastāpiī bīād I/O przyjmowane sā
 *        ustawienia domyōlne:
 *           konwersja             = ON
 *           format docelowy       = bez zmain
 *           napisywanie           = OFF
 *           formatowanie akapitów = OFF
 *           kopiowanie ikonek     = OFF
 *           pliki drag'n'drop     = ignorowanie
 *      argumenty:
 *        brak
 *      zwraca:
 *        TRUE :sukces
 *        FALSE:bīād
 *      uwagi:
 *        MUSI wystāpiź PO metodzie [PM_LOADCONFIG] by wyōwietlane przez obiekty tej
 *        klasy dane byīy aktualne
 *
 *   [PM_LOADCONFIG]:msg
 *      opis:
 *        odczyt konfiguracji (definicji tablic konwersji) z pliku (CONFIG_FILE) z
 *        aktualnego katalogu programu)
 *        format pliku konfiguracyjnego jest opisany w [kontekst.std]
 *      argumenty:
 *        brak
 *      zwraca:
 *        TRUE :sukces
 *        FALSE:bīād
 *      uwagi:
 *        gdy nastāpi bīād metoda zwraca FALSE i wywoīuje procedurė informUser() z
 *        parametrami - nazwa pliku i numer bīėdnej linii
 *
 *   [PM_STANDARD,stdType,flags,stdNum]:psm_Standard
 *      opis:
 *        metoda umoūliwiajāca wybór standardu konwersji polskich znaków
 *        (poprzez utworzenie obiektu klasy stdList_Class) z listā
 *        wszystkich standardów okreōlonych przez stdType:
 *        wybór standardu odbywa siė przez jego wskazanie w liōcie (doubleclick,
 *        lub naciōniėcie ENTER)
 *      argumenty:
 *        stdType                 : jakich standardów operacja dotyczy
 *          STDTYPE_SOURCE        : standardy o kodach > 127
 *          STDTYPE_DESTINATION   : wszystkie standardy
 *        flags                   : dodatkowe informacje o sposobie dziaīania metody
 *          STANDARD_SELECT       : ustaw stdNum standard w liōcie
 *          STANDARD_FIRST        : pobierz pierwszy standard w liōcie
 *          STANDARD_NEXT         : pobierz nastėpny standard
 *          STANDARD_LAST         : pobierz ostatni standard w liōcie
 *          STANDARD_PREV         : pobierz poprzedni standard
 *          STANDARD_CURRENT      : pobierz ostatnio ustawiony standard
 *        stdNum                  : gdy stdType ma warotōź STANDARD_SELECT to pole to zawiera numer
 *                                  standardu który ma zostaź ustawiony a gdy stdNum=(-1)
 *                                  to zostanie wyōwietlone okienko z listā standardów do wyboru
 *      zwraca:
 *        sukces:  PTR TO ps_Standard wybranego standardu
 *        bīād  :  NIL
 *      uwagi:
 *        okienko wyboru standardów jest tworzone (i otwierane) TYLKO WTEDY gdy
 *        flags=STANDARD_SELECT oraz stdNum=(-1)
 *        UWAGA! okienko wyboru standardów moūna obsīugiwaź z klawiatury i myszkā
 *               (szczegóīy w opisie metody SLM_SELECT/stdList_Class)
 *
 *
 *---nowe atrybuty:
 *   PREFS_AutoLoad     (I...)
 *      opis:
 *        decyduje czy preferencje i konfiguracja bėdā odczytywane z dysku
 *        przy inicjalizacji obiektu klasy prefs_Class
 *      argument:
 *        TRUE/FALSE
 *      domyōlnie:
 *        FALSE (nie odczytuje)
 *      uwagi:
 *        brak
 *
 *   PREFS_OutDir       (.SG..)
 *      opis:
 *        obsīuguje katalog docelowy
 *        jeōli przy pobieraniu okaūe siė ūe katalog jest pusty - pobierany jest
 *        katalog okreōlony atrybutem PREFS_InDir
 *      argument:
 *        PTR TO CHAR
 *      uwagi:
 *        zobacz takūe PREFS_InDir
 *
 *   PREFS_InDir       (.SG..)
 *      opis:
 *        obsīuguje katalog śródīowy
 *      argument:
 *        PTR TO CHAR
 *      uwagi:
 *        zobacz takūe PREFS_OutDir
 *
 *   PREFS_Options     (.SG..)
 *      opis:
 *        obsīuguje opcje programu przez strukturė ps_Options
 *      argument:
 *        PTR TO ps_Options
 *      uwagi:
 *        musi byź <> NIL
 *
 *   PREFS_InStandard,  (.SG..)
 *   PREFS_OutStandard  (.SG..)
 *      opis:
 *        obsīugujā standardy konwersji polskich znaków
 *      argument:
 *        PTR TO ps_Standard
 *      uwagi:
 *        musi byź <> NIL
 *
 *   PREFS_WindowObject (ISG..)
 *      opis:
 *        przekazuje wstaśnik do obiektu WindowObject niezbėdnego do poprawnego
 *        funkcjonowania obiektów klasy PrefsClass
 *        (to znaczy jest ono potrzebne do odōwieūania wyglādu gadūetów)
 *      argument:
 *        PTR TO object
 *      domyōlnie
 *        NIL
 *      uwagi:
 *        brak
 *
 *   PREFS_Window       (..G..)
 *      opis:
 *        pobiera adres struktury window naleūācej do obiektu przekazywanego za
 *        pomocā PREFS_WindowObject lub NIL gdy WindowObject nie jest zdefiniowany
 *      argument:
 *        PTR TO window
 *      uwagi:
 *        zobacz PREFS_WindowObject
 *
 *   PREFS_AppAction    (.SG..)
 *      opis:
 *        okreōla rodzaj akcji jaka ma towarzyszyź obsīudze plików z appwindow
 *      argument:
 *        LONG - kod akcji
 *
 *        ACTION_IGNORE    ignorowanie plików
 *        ACTION_CONVERT   konwertowanie plików
 *        ACTION_CHECK     sprawdzanie plików
 *        ACTION_DELETE    kasowanie plików
 *
 *      uwagi:
 *        brak
 *
 *
 *-- REV_END --*
 */

MODULE 'fabio/IFFParser_oo'
MODULE 'bgui/bgui','bgui/bguic','bgui/bguim','bgui',
       'utility/tagitem','utility/hooks','utility',
       'intuition/classusr','intuition/classes',
       'intuition/intuition','intuition/gadgetclass',
       'intuition/screens',
       'graphics/text','dos/dos','dos/rdargs',
       'exec/memory','exec/nodes','exec/lists'
MODULE 'amigalib/boopsi','amigalib/lists','tools/installhook','tools/async'
MODULE '*global_Defs'
MODULE '*stdList_Class'


#define PREFS_FILE          'kontekst.opts'
#define CONFIG_FILE         'kontekst.std'


->- nowe metody klasy prefs_Class
EXPORT CONST
  PM_SAVEPREFS              = TAG_PREFS + 1,
  PM_STANDARD               = TAG_PREFS + 2,
  PM_LOADPREFS              = TAG_PREFS + 3,
  PM_LOADCONFIG             = TAG_PREFS + 4

->- nowe atrybuty klasy prefs_Class
EXPORT CONST
  PREFS_Options             = TAG_PREFS + 21,     /*.SG..*/   ->- PTR TO ps_Options
  PREFS_InStandard          = TAG_PREFS + 22,     /*.SG..*/   ->- PTR TO ps_Standard
  PREFS_OutStandard         = TAG_PREFS + 23,     /*.SG..*/   ->- PTR TO ps_Standard
  PREFS_InDir               = TAG_PREFS + 24,     /*.SG..*/   ->- PTR TO CHAR
  PREFS_OutDir              = TAG_PREFS + 25,     /*.SG..*/   ->- PTR TO CHAR
  PREFS_WindowObject        = TAG_PREFS + 26,     /*ISG..*/   ->- PTR TO object
  PREFS_AutoLoad            = TAG_PREFS + 27,     /*I....*/   ->- BOOL
  PREFS_Window              = TAG_PREFS + 28,     /*..G..*/   ->- PTR TO window
  PREFS_AppAction           = TAG_PREFS + 29      /*.SG..*/   ->- ACTION_#?

EXPORT OBJECT ps_Options
  conversion                ->- konwersja ON/OFF
  fileFormat                ->- format pliku docelowego FORMAT_#?
  overWrite                 ->- nadpisywanie ON/OFF
  dtp                       ->- formatowanie akapitów w plikach ON/OFF
  copyIcons                 ->- kopiowanie ikonek plików ON/OFF
  appAction                 ->- odpowiedś na appwindow ACTION_#?
ENDOBJECT

->- rodzaje akcji, które mogā byź podejmowane po przeciāgniėciu ikonek na
->- gīówne okienko programu
EXPORT CONST
  ACTION_IGNORE             = 0,  ->- ignorowanie
  ACTION_CONVERT            = 1,  ->- konwertowanie
  ACTION_CHECK              = 2,  ->- sprawdzanie
  ACTION_DELETE             = 3   ->- kasowanie

->- typy formatów plików tekstowych
EXPORT CONST
  FORMAT_SAME               = 0,  ->- format bez zmian
  FORMAT_AMIGA              = 1,  ->- format AMIGA, koniec linii jest oznaczany przez LF
  FORMAT_IBM                = 2,  ->- format PC, koniec linii jest oznaczany przez LF+CR
  FORMAT_MACINTOSH          = 3   ->- format MacIntosh, koniec linii jest oznaczany przez CR

EXPORT CONST
  STANDARD_CHARS            = 18 ->- ile polskich znaków w standardzie

->- struktura opisujāca standard polskich znaków
EXPORT OBJECT ps_Standard OF ln
  isSource
  chars[STANDARD_CHARS]:ARRAY OF CHAR
ENDOBJECT

->- obiekt uūywany przez metodė PM_STANDARD
EXPORT OBJECT psm_Standard OF msg
  stdType                   ->- typ listy standardów STDLIST_#?
  flags                     ->- flagi STANDARD_#?
  stdNum                    ->- numer wybieranego standardu lub (-1)
ENDOBJECT

->- psm_Standard.flags
EXPORT CONST
  STANDARD_SELECT           = 0,
  STANDARD_FIRST            = -1,
  STANDARD_NEXT             = -2,
  STANDARD_LAST             = -3,
  STANDARD_PREV             = -4,
  STANDARD_CURRENT          = -5


->--------------------------------------------------------- prefs_Class -------------
DEF prefs_Class:PTR TO iclass

->- wewnėtrzne dane obiektów klasy prefs_Class
->- (cm=check mark, st=string, bt=button, io=info, cy=cycle)
OBJECT prefs_Data
  cm_conversion
  bt_in
  io_in
  bt_out
  io_out
  cy_fileformat
  st_destination
  st_source
  cm_overwrite
  cm_dtp
  cm_copyicons
  cy_appaction

  objWindow:PTR TO object

  ->- obsīuga standardów
  standards:lh
  inStandard:PTR TO ps_Standard
  outStandard:PTR TO ps_Standard
  currentStandard:PTR TO ps_Standard
ENDOBJECT

->- obiekt wykorzystywany przez procedurė parseCommand
OBJECT ps_Parse
  command:PTR TO CHAR
  template:PTR TO CHAR
  func
ENDOBJECT


->- METODY -----------------------------
PROC prefs_New(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO opset) HANDLE
  DEF data:PTR TO prefs_Data
  DEF cm_conv,bt_in,io_in,bt_out,io_out,
      cy_format,
      st_path,
      cm_over,cm_dtp,cm_icons,
      cy_action

  ->- test
  ->- IF utilitybase=NIL THEN RETURN NIL

  ->- klasa bazowā
  IF (obj:=doSuperMethodA(cl,obj,
     [ OM_NEW,
     [ GROUP_STYLE,GRSTYLE_VERTICAL,
       NarrowSpacing,

       StartMember,VGroupObject,
         NarrowSpacing,NarrowHOffset,NarrowVOffset,
         ButtonFrame,
         FRM_Flags,FRF_RECESSED OR FRF_THIN_FRAME,
         StartMember,cm_conv:=CheckBoxObject,
           FRM_Flags,FRF_THIN_FRAME,
           LAB_Label,'_konwersja standardów...',
           LAB_Place,PLACE_RIGHT,
         EndObject,FixMinWidth,EndMember,
         StartMember,HGroupObject,
           NarrowSpacing,
           FRM_Flags,FRF_RECESSED OR FRF_THIN_FRAME,
           StartMember,bt_in:=ButtonObject,
             FRM_Flags,FRF_THIN_FRAME,
             VIT_BuiltIn,BUILTIN_POPUP,
             LAB_Label,'ś_ródīowy:',
             LAB_Place,PLACE_LEFT,
             GA_ID,PREFS_INSTANDARD_ID,
           EndObject,FixMinWidth,EndMember,
           StartMember,io_in:=InfoObject,
             ButtonFrame,
             FRM_Flags,FRF_THIN_FRAME OR FRF_RECESSED,
             INFO_TextFormat,'%s',
             INFO_Args,[NIL],
             INFO_HorizOffset,4,
             INFO_VertOffset,2,
           EndObject,EndMember,
         EndObject,EndMember,
         StartMember,HGroupObject,
           NarrowSpacing,
           FRM_Flags,FRF_RECESSED OR FRF_THIN_FRAME,
           StartMember,bt_out:=ButtonObject,
             FRM_Flags,FRF_THIN_FRAME,
             VIT_BuiltIn,BUILTIN_POPUP,
             LAB_Label,'_docelowy:',
             LAB_Place,PLACE_LEFT,
             GA_ID,PREFS_OUTSTANDARD_ID,
           EndObject,FixMinWidth,EndMember,
           StartMember,io_out:=InfoObject,
             ButtonFrame,
             FRM_Flags,FRF_THIN_FRAME OR FRF_RECESSED,
             INFO_TextFormat,'%s',
             INFO_Args,[NIL],
             INFO_HorizOffset,4,
             INFO_VertOffset,2,
           EndObject,EndMember,
         EndObject,EndMember,
       EndObject,FixMinHeight,EndMember,

       StartMember,VGroupObject,
         NarrowSpacing,NarrowHOffset,NarrowVOffset,
         ButtonFrame,
         FRM_Flags,FRF_EDGES_ONLY OR FRF_RECESSED OR FRF_THIN_FRAME,
         StartMember,cy_format:=CycleObject,
           FRM_Flags,FRF_THIN_FRAME,
           LAB_Label,'_format pliku\ndocelowego',
           ->- LAB_Style,FSF_EXTENDED,
           CYC_Labels,['Bez zmian','Amiga','IBM PC','MacIntosh',NIL],
         EndObject,EndMember,
       EndObject,FixMinHeight,EndMember,

       StartMember,HGroupObject,
         NarrowHOffset,NarrowVOffset,
         ButtonFrame,
         FRM_Flags,FRF_EDGES_ONLY OR FRF_RECESSED OR FRF_THIN_FRAME,
         StartMember,st_path:=StringObject,
           LAB_Label,'ka_talog docelowy:',
           LAB_Place,PLACE_LEFT,
           STRINGA_TEXTVAL,'',
           STRINGA_MAXCHARS,DEF_PATH_LEN,
           STRINGA_MINCHARSVISIBLE,6,
         EndObject,EndMember,
         StartMember,ButtonObject,
           VIT_BuiltIn,BUILTIN_GETPATH,
           GA_ID,PREFS_OUTDIR_ID,
         EndObject,FixMinWidth,EndMember,
       EndObject,FixMinHeight,EndMember,

       StartMember,VGroupObject,
         NarrowSpacing,NarrowHOffset,NarrowVOffset,
         ButtonFrame,
         FRM_Flags,FRF_EDGES_ONLY OR FRF_RECESSED OR FRF_THIN_FRAME,
         StartMember,cm_over:=CheckBoxObject,
           FRM_Flags,FRF_THIN_FRAME,
           LAB_Label,'_nadpisywanie istniejācych plików',
           LAB_Place,PLACE_RIGHT,
         EndObject,FixMinWidth,EndMember,
         StartMember,cm_dtp:=CheckBoxObject,
           FRM_Flags,FRF_THIN_FRAME,
           LAB_Label,'f_ormatowanie akapitów w plikach',
           LAB_Place,PLACE_RIGHT,
         EndObject,FixMinWidth,EndMember,
         StartMember,cm_icons:=CheckBoxObject,
           FRM_Flags,FRF_THIN_FRAME,
           LAB_Label,'kopiowanie _ikonek plików',
           LAB_Place,PLACE_RIGHT,
         EndObject,FixMinWidth,EndMember,
       EndObject,FixMinHeight,EndMember,

       StartMember,VGroupObject,
         NarrowSpacing,NarrowHOffset,NarrowVOffset,
         ButtonFrame,
         FRM_Flags,FRF_EDGES_ONLY OR FRF_RECESSED OR FRF_THIN_FRAME,
         StartMember,cy_action:=CycleObject,
           FRM_Flags,FRF_THIN_FRAME,
           LAB_Label,'pliki\ndr_ag\an\adrop',
           ->- LAB_Style,FSF_EXTENDED,
           CYC_Labels,['Ignorowanie','Konwertowanie','Sprawdzanie','Usuwanie',NIL],
         EndObject,EndMember,
       EndObject,FixMinHeight,EndMember,
     TAG_DONE],
  NIL]))=NIL THEN RETURN NIL

  ->- inicjalizacja
  data:=INST_DATA(cl,obj)
  bzero(data,SIZEOF prefs_Data)

  data.cm_conversion:=cm_conv
  data.bt_in:=bt_in
  data.io_in:=io_in
  data.bt_out:=bt_out
  data.io_out:=io_out
  data.cy_fileformat:=cy_format
  data.st_destination:=st_path
  data.cm_overwrite:=cm_over
  data.cm_dtp:=cm_dtp
  data.cm_copyicons:=cm_icons
  data.cy_appaction:=cy_action
  data.st_source:=StringObject,
                    STRINGA_TEXTVAL,'',
                    STRINGA_MAXCHARS,DEF_PATH_LEN,
                  EndObject
  IF data.st_source=NIL THEN Raise(ERROR)

  ->- pobierz (ewentualnie) przekazywany obiekt (objWindow)
  data.objWindow:=GetTagData(PREFS_WindowObject,NIL,msg.attrlist)

  ->- automatyczny (podczas tworzenia obiektu) odczyt preferencji?
  IF GetTagData(PREFS_AutoLoad,FALSE,msg.attrlist)=TRUE
    IF doMethodA(obj,[PM_LOADCONFIG])=FALSE THEN Raise(ERROR)
    doMethodA(obj,[PM_LOADPREFS])
  ENDIF

  RETURN obj
EXCEPT
  coerceMethodA(cl,obj,[OM_DISPOSE])
ENDPROC NIL

PROC prefs_Dispose(cl:PTR TO iclass,obj:PTR TO object,msg)
  DEF data:PTR TO prefs_Data
  DEF node:PTR TO ps_Standard

  data:=INST_DATA(cl,obj)
  IF IsListEmpty(data.standards)=FALSE
    WHILE (node:=RemHead(data.standards)) DO END node.name[DEF_FILENAME_LEN],node
  ENDIF
  DisposeObject(data.st_source)
ENDPROC doSuperMethodA(cl,obj,msg)

PROC prefs_Get(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO opget)
  DEF data:PTR TO prefs_Data
  DEF storage,rc=TRUE,id,wnd,tmp
  DEF opts:PTR TO ps_Options

  data:=INST_DATA(cl,obj)
  storage:=msg.storage
  id:=msg.attrid
  SELECT id

  CASE PREFS_Options
    opts:=^storage
    opts.conversion    :=  getBool(data.cm_conversion,GA_SELECTED)
    opts.fileFormat    :=  get(data.cy_fileformat,CYC_ACTIVE)
    opts.overWrite     :=  getBool(data.cm_overwrite,GA_SELECTED)
    opts.dtp           :=  getBool(data.cm_dtp,GA_SELECTED)
    opts.copyIcons     :=  getBool(data.cm_copyicons,GA_SELECTED)
    opts.appAction     :=  get(data.cy_appaction,CYC_ACTIVE)

  CASE PREFS_AppAction
    ^storage:=get(data.cy_appaction,CYC_ACTIVE)

  CASE PREFS_InStandard
    ^storage:=data.inStandard
  CASE PREFS_OutStandard
    ^storage:=data.outStandard

  CASE PREFS_OutDir
    tmp:=get(data.st_destination,STRINGA_TEXTVAL)
    ->- jeūeli katalog docelowy jest pusty to uūywaj śródīowego
    ^storage:=IF StrLen(tmp)=0 THEN
              get(data.st_source,STRINGA_TEXTVAL) ELSE tmp
  CASE PREFS_InDir
    ^storage:=get(data.st_source,STRINGA_TEXTVAL)

  CASE PREFS_WindowObject
    ^storage:=data.objWindow
  CASE PREFS_Window
    IF data.objWindow
      GetAttr(WINDOW_Window,data.objWindow,{wnd})
    ELSE
      wnd:=NIL
    ENDIF
    ^storage:=wnd

  DEFAULT
    rc:=doSuperMethodA(cl,obj,msg)
  ENDSELECT
ENDPROC rc

PROC prefs_Set(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO opset)
  DEF data:PTR TO prefs_Data
  DEF tag:PTR TO tagitem,tags,id,rc,std:PTR TO ps_Standard,wnd
  DEF opts:PTR TO ps_Options

  ->- klasa bazowa
  rc:=doSuperMethodA(cl,obj,msg);

  data:=INST_DATA(cl,obj)
  GetAttr(WINDOW_Window,data.objWindow,{wnd})

  data:=INST_DATA(cl,obj)
  tags:=msg.attrlist
  WHILE (tag:=NextTagItem({tags}))
    id:=tag.tag
    SELECT id

    CASE PREFS_Options
      opts:=tag.data
      set(data.cm_conversion,GA_SELECTED,opts.conversion,wnd)
      set(data.cy_fileformat,CYC_ACTIVE,opts.fileFormat,wnd)
      set(data.cm_overwrite,GA_SELECTED,opts.overWrite,wnd)
      set(data.cm_dtp,GA_SELECTED,opts.dtp,wnd)
      set(data.cm_copyicons,GA_SELECTED,opts.copyIcons,wnd)
      set(data.cy_appaction,CYC_ACTIVE,opts.appAction,wnd)

    CASE PREFS_AppAction
      set(data.cy_appaction,CYC_ACTIVE,opts.appAction,wnd)

    CASE PREFS_InStandard
      IF (std:=tag.data)<>NIL THEN set(data.io_in,INFO_ARGS,[std.name,NIL],wnd)
      data.inStandard:=std
    CASE PREFS_OutStandard
      IF (std:=tag.data)<>NIL THEN set(data.io_out,INFO_ARGS,[std.name,NIL],wnd)
      data.outStandard:=std

    CASE PREFS_InDir
      ->- nie moūna odōwieūaź wygladu gadūetu bo nie jest on podīāczony
      ->- do okienka!
      set(data.st_source,STRINGA_TEXTVAL,tag.data,NIL)
    CASE PREFS_OutDir
      set(data.st_destination,STRINGA_TEXTVAL,tag.data,wnd)

    CASE PREFS_WindowObject
      data.objWindow:=tag.data
    ENDSELECT
  ENDWHILE
ENDPROC rc

PROC prefs_SavePrefs(cl:PTR TO iclass,obj:PTR TO object,msg) HANDLE
  DEF data:PTR TO prefs_Data
  DEF iff=NIL:PTR TO iffparser,rc=FALSE
  DEF std:PTR TO ps_Standard,dir
  DEF opts:ps_Options

  VOID msg
  data:=INST_DATA(cl,obj)

  ->- inicjalizacja struktury ps_Options
  GetAttr(PREFS_Options,obj,{opts})

  ->-
  NEW iff.iffparser()
  iff.save(PREFS_FILE)
  iff.createchunk("PREF","FORM")

  ->-
  iff.createchunk("PREF","OPTS")
  iff.writechunk(opts,SIZEOF ps_Options)
  iff.closechunk()

  ->-
  ->- dir:=get(data.st_source,STRINGA_TEXTVAL)
  dir:=get(obj,PREFS_InDir)
  iff.createchunk("PREF","SDIR")
  iff.writechunk(dir,StrLen(dir)+1)
  iff.closechunk()

  ->-
  ->- chyba lepiej uūywaź tego niū PREFS_OutDir bo gdy OutDir=NIL to zostanie
  ->- zwrócony wskaśnik do InDir co nie zawsze jest poūādane!
  dir:=get(data.st_destination,STRINGA_TEXTVAL)
  ->- dir:=get(obj,PREFS_OutDir)
  iff.createchunk("PREF","DDIR")
  iff.writechunk(dir,StrLen(dir)+1)
  iff.closechunk()

  ->-
  IF (std:=data.inStandard)
    iff.createchunk("PREF","SSTD")
    iff.writechunk(std.name,StrLen(std.name)+1)
    iff.closechunk()
  ENDIF

  ->-
  IF (std:=data.outStandard)
    iff.createchunk("PREF","DSTD")
    iff.writechunk(std.name,StrLen(std.name)+1)
    iff.closechunk()
  ENDIF

  ->-
  iff.closechunk()
  rc:=TRUE

EXCEPT DO
  IF iff THEN iff.close() ->- zamknij plik
  END iff
ENDPROC rc

PROC prefs_LoadPrefs(cl:PTR TO iclass,obj:PTR TO object,msg) HANDLE
  DEF data:PTR TO prefs_Data
  DEF iff=NIL:PTR TO iffparser,rc=FALSE
  DEF opts=NIL:PTR TO ps_Options,optsTags
  DEF inDir=NIL,outDir=NIL,inStd=NIL,inStdName=NIL,outStd=NIL,outStdName=NIL

  VOID msg
  data:=INST_DATA(cl,obj)

  ->- otwórz plik z preferencjami
  NEW iff.iffparser()
  iff.load(PREFS_FILE)
  iff.setscan("PREF","OPTS")
  iff.setscan("PREF","SSTD")
  iff.setscan("PREF","DSTD")
  iff.setscan("PREF","SDIR")
  iff.setscan("PREF","DDIR")
  iff.exit("PREF","FORM")
  iff.scan()                      ->- przeglādaj plik

  opts:=iff.first("PREF","OPTS")
  inDir:=iff.first("PREF","SDIR")
  outDir:=iff.first("PREF","DDIR")
  inStdName:=iff.first("PREF","SSTD")
  outStdName:=iff.first("PREF","DSTD")
  rc:=TRUE

EXCEPT DO
  IF inDir=NIL THEN inDir:=''
  IF outDir=NIL THEN outDir:=''
  IF inStdName<>NIL THEN inStd:=FindName(data.standards,inStdName)
  IF outStdName<>NIL THEN outStd:=FindName(data.standards,outStdName)
  IF inStd=NIL
    IF data.standards THEN inStd:=data.standards.head.succ
  ENDIF
  IF outStd=NIL
    IF data.standards THEN outStd:=data.standards.head
  ENDIF
  IF opts
    optsTags:=[ opts.conversion,
                opts.fileFormat,
                opts.overWrite,
                opts.dtp,
                opts.copyIcons,
                opts.appAction  ]:ps_Options

  ELSE
    optsTags:=[ TRUE,             ->- conversion
                FORMAT_SAME,      ->- fileFormat
                FALSE,            ->- overWrite
                FALSE,            ->- dtp
                FALSE,            ->- copyIcons
                ACTION_IGNORE ]:ps_Options
  ENDIF
  SetAttrsA(obj,
    [ PREFS_InStandard,inStd,
      PREFS_OutStandard,outStd,
      PREFS_InDir,inDir,
      PREFS_OutDir,outDir,
      PREFS_Options,optsTags,TAG_DONE  ])

  IF iff THEN iff.close() ->- zamknij plik
  END iff
ENDPROC rc

CONST DEF_PARSE_BUFFER = 148
PROC prefs_LoadConfig(cl:PTR TO iclass,obj:PTR TO object,msg) HANDLE
  DEF data:PTR TO prefs_Data
  DEF rda=NIL:PTR TO rdargs,handle=NIL,buffer:PTR TO CHAR
  DEF line=0,rc=FALSE,i,std:PTR TO ps_Standard
  DEF parser

  VOID msg
  data:=INST_DATA(cl,obj)

  NEW buffer[DEF_PARSE_BUFFER]
  newList(data.standards)
  rda:=AllocDosObject(DOS_RDARGS,NIL)
  IF rda
    rda.flags:=rda.flags OR RDAF_NOPROMPT

    ->- otwórz plik (asynchronicznie)
    handle:=as_Open(CONFIG_FILE,MODE_OLDFILE,3,2048)
    IF handle

      parser:=[NIL,'STANDARD/K,CODES/M',{parseFunc}]:ps_Parse
      ->- odczytuj linia po linii
      line:=0
      WHILE as_FGetS(handle,buffer,DEF_PARSE_BUFFER)

        ->- analizuj od poczātku linii
        i:=0
        ->- zwiėksz numer analizowanej linii
        INC line
        ->- pomiļ widāce spacje, tabulatory...
        WHILE (buffer[i]=" ")OR(buffer[i]="\t") DO i++

        ->- jakieō znaki jeszcze zostaīy?
        ->- oby nie komentaū...
        IF (buffer[i]<>"\0")AND(buffer[i]<>"\n")AND
           (buffer[i]<>";")AND(buffer[i]<>"#")AND(buffer[i]<>"@")

          IF (std:=parseCommand(rda,parser,buffer+i))
            AddTail(data.standards,std)
          ELSE
            informUser('konfiguracja: bīād w pliku \a\s\a (linia #\d)\n',
                       [CONFIG_FILE,line,NIL])
            Raise(ERROR)
          ENDIF
        ENDIF
      ENDWHILE
      ->- jeūeli IoErr()=0 to znaczy, ūe napotkano koniec pliku
      IF IoErr()=0 THEN rc:=TRUE
    ELSE
      informUser('konfiguracja: brak pliku \a\s\a \n',[CONFIG_FILE,NIL])
    ENDIF
  ENDIF
EXCEPT DO
  END buffer[DEF_PARSE_BUFFER]
  IF handle THEN as_Close(handle)
  IF rda THEN FreeDosObject(DOS_RDARGS,rda)
ENDPROC rc

PROC prefs_Standard(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO psm_Standard)
  DEF data:PTR TO prefs_Data
  DEF objStd:PTR TO object,wnd:PTR TO window,active,screen,flags
  DEF x,cstd:PTR TO ps_Standard,tagPrefs

  data:=INST_DATA(cl,obj)
  flags:=msg.flags
  IF flags<0
    SELECT flags

    CASE STANDARD_CURRENT
      cstd:=IF msg.stdType=STDTYPE_SOURCE THEN data.inStandard ELSE data.outStandard

    CASE STANDARD_FIRST
      cstd:=data.standards.head
      WHILE cstd
        EXIT msg.stdType<>STDTYPE_SOURCE
        EXIT cstd.isSource=TRUE
        cstd:=cstd.succ
      ENDWHILE

    CASE STANDARD_NEXT
      cstd:=data.currentStandard
      WHILE cstd
        cstd:=cstd.succ
        EXIT cstd=NIL
        EXIT msg.stdType<>STDTYPE_SOURCE
        EXIT cstd.isSource=TRUE
      ENDWHILE

    CASE STANDARD_LAST
      cstd:=data.standards.tailpred
      WHILE cstd
        EXIT msg.stdType<>STDTYPE_SOURCE
        EXIT cstd.isSource=TRUE
        cstd:=cstd.pred
      ENDWHILE

    CASE STANDARD_PREV
      cstd:=data.currentStandard
      WHILE cstd
        cstd:=cstd.pred
        EXIT cstd=data.standards.head
        EXIT msg.stdType<>STDTYPE_SOURCE
        EXIT cstd.isSource=TRUE
      ENDWHILE

    ENDSELECT
    data.currentStandard:=cstd
    RETURN cstd
  ENDIF

  tagPrefs:=IF msg.stdType=STDTYPE_SOURCE THEN
               PREFS_InStandard ELSE PREFS_OutStandard
  IF msg.stdNum>=0
    cstd:=data.standards.head
    FOR x:=0 TO msg.stdNum-1 DO IF cstd THEN cstd:=cstd.succ
    set(obj,tagPrefs,cstd)
    RETURN cstd
  ENDIF

  GetAttr(WINDOW_Window,data.objWindow,{wnd})
  screen:=IF wnd THEN wnd.wscreen ELSE NIL
  active:=IF msg.stdType=STDTYPE_SOURCE THEN data.inStandard ELSE data.outStandard

  objStd:=NewObjectA(stdList_MakeClass(),NIL,
    [ WINDOW_PubScreen,screen,
      STDLIST_Entries,data.standards,
      STDLIST_ActiveItem,active,
      STDLIST_Type,msg.stdType,
      TAG_DONE  ])

  IF objStd
    cstd:=doMethodA(objStd,[SLM_SELECT])
    IF cstd THEN set(obj,tagPrefs,cstd)
    DisposeObject(objStd)
  ELSE
    DisplayBeep(NIL)
  ENDIF
ENDPROC cstd

PROC prefs_Dispatcher(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO msg)
  DEF id,rc=0

  id:=msg.methodid
  SELECT id
  CASE OM_NEW
    rc:=prefs_New(cl,obj,msg)
  CASE OM_DISPOSE
    rc:=prefs_Dispose(cl,obj,msg)
  CASE OM_SET
    rc:=prefs_Set(cl,obj,msg)
  CASE OM_GET
    rc:=prefs_Get(cl,obj,msg)

  CASE PM_SAVEPREFS
    rc:=prefs_SavePrefs(cl,obj,msg)
  CASE PM_LOADPREFS
    rc:=prefs_LoadPrefs(cl,obj,msg)
  CASE PM_LOADCONFIG
    rc:=prefs_LoadConfig(cl,obj,msg)
  CASE PM_STANDARD
    rc:=prefs_Standard(cl,obj,msg)

  DEFAULT
    rc:=doSuperMethodA(cl,obj,msg)
  ENDSELECT
ENDPROC rc


->- FUNKCJE INICJALIZACYJNE ------------
->- tworzenie klasy
EXPORT PROC prefs_MakeClass()
  ->- VOID bguibase
  IF prefs_Class=NIL
    prefs_Class:=bguiMakeClass(
      [ CLASS_SuperClassBGUI,BGUI_GROUP_GADGET,
        CLASS_ObjectSize,SIZEOF prefs_Data,
        CLASS_Dispatcher,{prefs_Dispatcher},
        TAG_DONE  ])
  ENDIF
ENDPROC prefs_Class

->- usuwanie klasy
EXPORT PROC prefs_FreeClass()
  stdList_FreeClass()
  bguiFreeClass(prefs_Class)
  prefs_Class:=NIL
ENDPROC


->- FUNKCJE POMOCNICZE -----------------
->- pobieranie atrybutu 'id' obiektu 'obj'
PROC get(obj,id)
  DEF x=0
  GetAttr(id,obj,{x})
ENDPROC x
PROC getBool(obj,id) IS IF get(obj,id)=FALSE THEN FALSE ELSE TRUE

->- ustawianie strybutu 'id' obiektu 'obj' na wartoōź 'attr'
PROC set(obj,id,attr,wnd=NIL) IS SetGadgetAttrsA(obj,wnd,NIL,[id,attr,TAG_DONE])

->- uniwersalna procedura analizujāca tekst w buforze na podstawie obiektu
->- ps_Parse (komenda,wzorzec,funkcja obsīugujāca)
->- zwraca:
->-  wynik funkcji obsīugujācej komendė
PROC parseCommand(rda:PTR TO rdargs,parser:PTR TO ps_Parse,buffer:PTR TO CHAR) HANDLE
  DEF rd,i,char,func
  DEF args:PTR TO LONG,nargs=0,rc=NIL

  ->- nie potrzeba argumentów
  func:=parser.func
  IF parser.template=NIL THEN RETURN func()

  ->- policz ile jest argumentów
  i:=0
  WHILE (char:=parser.template[i])
    IF char="," THEN nargs++
    i++
  ENDWHILE
  nargs++
  NEW args[nargs]
  rda.source.buffer:=buffer
  rda.source.length:=StrLen(buffer)
  rda.source.curchr:=0
  rda.dalist:=NIL
  rda.buffer:=NIL

  rd:=ReadArgs(parser.template,args,rda)
  IF rd
    ->- wywoīaj odpowiedniā funkcjė
    rc:=func(args)
    FreeArgs(rd)
  ENDIF
EXCEPT DO
  END args[nargs]
ENDPROC rc

->- funckja obsīugujāca analizė danych z pliku konfiguracyjnego
->- zwraca:
->-  PTR TO ps_Standard
->-  NIL                  : bīād
ENUM ARG_STANDARD,ARG_CODES
PROC parseFunc(args:PTR TO LONG) HANDLE
  DEF std:PTR TO ps_Standard
  DEF x,codes,code,value,read,rc=NIL

  MOVE.L  args,A1
  TST.L   0(A1)
  BEQ.W   parseExit
  TST.L   4(A1)
  BEQ.W   parseExit
  MOVE.L  4(A1),codes                     ->- codes:=args[ARG_CODES]
  NEW std
  NEW std.name[DEF_FILENAME_LEN]
  AstrCopy(std.name,args[ARG_STANDARD],DEF_FILENAME_LEN)
  MOVE.L    std,A0
  MOVE.L    #TRUE,14(A0)                  ->- std.isSource:=TRUE
  MOVE.L    #0,x
  WHILE (code:=^codes++)<>NIL
    value:=Val(code,{read})
    IF x>(STANDARD_CHARS-1)OR(read<>3)
      END std.name[DEF_FILENAME_LEN],std
      Raise(ERROR)
    ENDIF
    MOVE.L  std,A0
    MOVE.L  value,D1
    MOVE.L  x,D0
    MOVE.B  D1,18(A0,D0.W)
    BTST.B  #7,D1
    BNE.B   skip
    MOVE.L  #FALSE,14(A0)
    skip:
    ADD.L   #1,x
  ENDWHILE
  rc:=std
parseExit:
EXCEPT DO
ENDPROC rc
/*EE folds
-1
335 162 338 8 341 47 344 46 347 58 350 62 354 54 357 78 360 25 366 8 370 3 376 2 387 29 395 34 
EE folds*/
