unit options;

interface

uses Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,
  Buttons, ExtCtrls, ComCtrls, RegUtil, Dialogs;

type
  TOptions = class
  public
    ShowDotFiles  : Boolean;
    ShowBackups   : Boolean;
    DebugLevel    : Integer;
    AutoSave      : Boolean;

    ShowDebug   : Boolean;
    ShowStatus  : Boolean;
    ShowToolbar : Boolean;

    ViewStyle : TViewStyle;

    Prefix : String;

    WriteSupport  : Boolean;
    FloppyScan    : Boolean;

    NonStandard : Integer;

    UMask      : String;

    PasswdFile : String;
    GroupFile  : String;

    ViewerProg : String;
    ViewText   : Boolean;

    SortColumn : Integer;
    SortDir    : Boolean;

    ColumnWidths : TList;


    constructor Create;
    destructor Destroy; override;
    function Execute : Boolean;

    procedure ReadOptions;
    procedure SaveOptions;

    function GetUMask : Integer;
  end;

  TOptionsDlg = class(TForm)
    OKBtn: TButton;
    CancelBtn: TButton;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    DebugLevel: TRadioGroup;
    DebugWindow: TCheckBox;
    GroupBox1: TGroupBox;
    DotFiles: TCheckBox;
    Backups: TCheckBox;
    GroupBox2: TGroupBox;
    ToolbarCheckBox: TCheckBox;
    StatusCheckBox: TCheckBox;
    TabSheet3: TTabSheet;
    Label1: TLabel;
    PrefixEdit: TEdit;
    RWCheckBox: TCheckBox;
    NonStandardCheckBox: TCheckBox;
    NonStandardEdit: TEdit;
    Label2: TLabel;
    FloppyCheckBox: TCheckBox;
    Bevel1: TBevel;
    Label3: TLabel;
    UMaskEdit: TEdit;
    TabSheet4: TTabSheet;
    Label4: TLabel;
    PasswdEdit: TEdit;
    Label5: TLabel;
    GroupEdit: TEdit;
    PasswdButton: TButton;
    GroupButton: TButton;
    OpenDialog1: TOpenDialog;
    Label6: TLabel;
    ViewerEdit: TEdit;
    ViewerButton: TButton;
    ViewTextCheckBox: TCheckBox;
    AutoSaveCheckBox: TCheckBox;
    procedure RWCheckBoxClick(Sender: TObject);
    procedure NonStandardCheckBoxClick(Sender: TObject);
    procedure PasswdButtonClick(Sender: TObject);
    procedure GroupButtonClick(Sender: TObject);
    procedure ViewerButtonClick(Sender: TObject);
  private
    { Private declarations }
    CurrentOptions : TOptions;
  public
    { Public declarations }
  end;

var
  OptionsDlg: TOptionsDlg;

implementation

uses ex2explore;

{$R *.DFM}

/////////////////////////////
// TOptions
/////////////////////////////

constructor TOptions.Create;
begin
   ColumnWidths := Tlist.Create;
   ReadOptions;
end;

destructor TOptions.Destroy;
begin
   SaveOptions;
   ColumnWidths.Free;
end;

function TOptions.Execute : Boolean;
var
   Dlg : TOptionsDlg;
begin
   //
   Dlg := TOptionsDlg.Create(Application.MainForm);
   try
      Dlg.CurrentOptions := self;

      Dlg.DotFiles.Checked := ShowDotFiles;
      Dlg.Backups.Checked  := ShowBackups;

      Dlg.DebugLevel.ItemIndex     := DebugLevel;
      Dlg.DebugWindow.Checked      := ShowDebug;
      Dlg.AutoSaveCheckBox.Checked := AutoSave;

      Dlg.ToolbarCheckBox.Checked := ShowToolbar;
      Dlg.StatusCheckBox.Checked  := ShowStatus;

      Dlg.PrefixEdit.Text := Prefix;

      Dlg.RWCheckBox.Checked := WriteSupport;

      Dlg.FloppyCheckBox.Checked := FloppyScan;

      if NonStandard > 0 then
      begin
         Dlg.NonStandardCheckBox.Checked := True;
         Dlg.NonStandardEdit.Text := IntToHex(NonStandard, 2);
         Dlg.NonStandardEdit.Enabled := True;
      end
      else
      begin
         Dlg.NonStandardCheckBox.Checked := False;
         Dlg.NonStandardEdit.Enabled := False;
      end;

      Dlg.UMaskEdit.Text := UMask;

      Dlg.PasswdEdit.Text  := PasswdFile;
      Dlg.GroupEdit.Text   := GroupFile;
      Dlg.ViewerEdit.Text  := ViewerProg;
      Dlg.ViewTextCheckBox.Checked := ViewText;

      if Dlg.ShowModal = mrOK then
      begin
         ShowDotFiles   := Dlg.DotFiles.Checked;
         ShowBackups    := Dlg.Backups.Checked;

         DebugLevel     := Dlg.DebugLevel.ItemIndex;
         ShowDebug      := Dlg.DebugWindow.Checked;
         AutoSave       := Dlg.AutoSaveCheckBox.Checked;

         ShowToolbar := Dlg.ToolbarCheckBox.Checked;
         ShowStatus  := Dlg.StatusCheckBox.Checked;

         Prefix := Dlg.PrefixEdit.Text;

         WriteSupport := Dlg.RWCheckBox.Checked;
         FloppyScan   := Dlg.FloppyCheckBox.Checked;

         if Dlg.NonStandardCheckBox.Checked then
         begin
            NonStandard := StrToInt('$' + Dlg.NonStandardEdit.Text);
         end
         else
         begin
            NonStandard := 0;
         end;

         UMask := Dlg.UMaskEdit.Text;

         PasswdFile  := Dlg.PasswdEdit.Text;
         GroupFile   := Dlg.GroupEdit.Text;
         ViewerProg  := Dlg.ViewerEdit.Text;
         ViewText    := Dlg.ViewTextCheckBox.Checked;

         Result := True;
      end
      else
      begin
         Result := False;
      end;
   finally
      Dlg.Free;
   end;
end;

procedure TOptions.ReadOptions;
var
   Reg : TSoftwareRegistry;
   i     : Integer;
   Width : Integer;
begin
   // Be a real prick and use the registry
   Reg := TSoftwareRegistry.Create('Newbigin', 'explore2fs');
   try
      ShowDotFiles   := Reg.GetBool('ShowDotFiles', True);
      ShowBackups    := Reg.GetBool('ShowBackups',  True);

      DebugLevel  := Reg.GetInteger('DebugLevel', DebugOff);
      AutoSave    := Reg.GetBool('AutoSaveDebug', True);

      ShowDebug    := Reg.GetBool('ShowDebug',   False);
      ShowStatus   := Reg.GetBool('ShowStatus',  True);
      ShowToolbar  := Reg.GetBool('ShowToolbar', True);

      ViewStyle := TViewStyle(Reg.GetInteger('ViewStyle', Integer(vsIcon)));

      Prefix := Reg.GetString('Prefix', 'hd');

      WriteSupport   := Reg.GetBool('WriteSupport', False);
      FloppyScan     := Reg.GetBool('Floppy', False);

      NonStandard := Reg.GetInteger('NonStandard', 0);

      UMask := Reg.GetString('umask', '022');

      PasswdFile := Reg.GetString('PasswdFile', '');
      GroupFile  := Reg.GetString('GroupFile',  '');

      ViewerProg := Reg.GetString('Viewer',  'write');
      ViewText   := Reg.GetBool('ViewText',  false);

      SortColumn := Reg.GetInteger('SortColumn', 0);
      SortDir    := Reg.GetBool('SortDir',  false);

      // read the column header widths
      i := 0;
      while True do
      begin
         Width := Reg.GetInteger('Column' + IntToStr(i), -1);
         if Width <> -1 then
         begin
            ColumnWidths.Add(Pointer(Width));
            i := i + 1;
         end
         else break;
      end;

   finally
      Reg.Free;
   end;
end;

procedure TOptions.SaveOptions;
var
   Reg : TSoftwareRegistry;
   i   : Integer;
begin
   // Be a real prick and use the registry
   Reg := TSoftwareRegistry.Create('Newbigin', 'explore2fs');
   try
      Reg.SetBool('ShowDotFiles', ShowDotFiles);
      Reg.SetBool('ShowBackups',  ShowBackups);

      Reg.SetInteger('DebugLevel', DebugLevel);
      Reg.SetBool('AutoSaveDebug', AutoSave);

      Reg.SetBool('ShowDebug',   ShowDebug);
      Reg.SetBool('ShowStatus',  ShowStatus);
      Reg.SetBool('ShowToolbar', ShowToolbar);

      Reg.SetInteger('ViewStyle', Integer(ViewStyle));

      Reg.SetString('Prefix', Prefix);

      Reg.SetBool('WriteSupport', WriteSupport);
      Reg.SetBool('Floppy', FloppyScan);

      Reg.SetInteger('NonStandard', NonStandard);

      Reg.SetString('umask', UMask);

      Reg.SetString('PasswdFile', PasswdFile);
      Reg.SetString('GroupFile',  GroupFile);

      Reg.SetString('Viewer', ViewerProg);
      Reg.SetBool('ViewText', ViewText);

      Reg.SetInteger('SortColumn', SortColumn);
      Reg.SetBool('SortDir', SortDir);

      for i := 0 to ColumnWidths.Count - 1 do
      begin
         Reg.SetInteger('Column' + IntToStr(i), Integer(ColumnWidths[i]));
      end;
   finally
      Reg.Free;
   end;
end;

function TOptions.GetUMask : Integer;
var
   i     : Integer;
   Mask  : Integer;
begin
   // convert the UMask octal string into a decimal
//   UMask := '0' + UMask;
   Mask := 0;
   for i := 1 to Length(UMask) do
   begin
      if UMask[i] in ['0'..'7'] then
      begin
         Mask := (Mask * 8) + (Ord(UMask[i]) - Ord('0'));
      end
      else
      begin
         break;
      end;
   end;

   // now we have the mask
   // but we realy want to return the permissions to give the file
   Result := ($1B6 and (not mask)) and $1FF;
end;

procedure TOptionsDlg.RWCheckBoxClick(Sender: TObject);
begin
   if RWCheckBox.Focused and RWCheckBox.Checked then
   begin
      MessageDlg('WARNING'#10'Write support is experimental, use at your own risk!', mtInformation, [mbOK], 0);
   end;
end;

procedure TOptionsDlg.NonStandardCheckBoxClick(Sender: TObject);
begin
   NonStandardEdit.Enabled := NonStandardCheckBox.Checked;
end;

procedure TOptionsDlg.PasswdButtonClick(Sender: TObject);
begin
   OpenDialog1.FilterIndex := 2; // I hope
   OpenDialog1.FileName := PasswdEdit.Text;
   if OpenDialog1.Execute then
   begin
      PasswdEdit.Text := OpenDialog1.FileName;
   end;
end;

procedure TOptionsDlg.GroupButtonClick(Sender: TObject);
begin
   OpenDialog1.FilterIndex := 3;
   OpenDialog1.FileName := GroupEdit.Text;
   if OpenDialog1.Execute then
   begin
      GroupEdit.Text := OpenDialog1.FileName;
   end;
end;

procedure TOptionsDlg.ViewerButtonClick(Sender: TObject);
begin
   OpenDialog1.FilterIndex := 4;
   OpenDialog1.FileName := ViewerEdit.Text;
   if OpenDialog1.Execute then
   begin
      ViewerEdit.Text := OpenDialog1.FileName;
   end;
end;

end.
