home *** CD-ROM | disk | FTP | other *** search
/ Softwarová Záchrana 3 / Softwarova-zachrana-3.bin / ArsClip / source.zip / UnitFrmPermanentNew.pas < prev    next >
Pascal/Delphi Source File  |  2004-11-09  |  32KB  |  1,141 lines

  1. unit UnitFrmPermanentNew;
  2. {
  3.     Purpose:
  4.         This unit stores/reads/edits the permanent items.
  5.         The form is not a dummy form.
  6.  
  7.  
  8.     Updates:
  9.         New: Permanent Items Groups sorted by name
  10.         --------------
  11.         Fix: Up button did not range check
  12.         --------------
  13.         Changes for complex item as permanent items,
  14.         show them when it's shown or hovered
  15.  
  16.         Folder list not cleared when "LoadPermanent" was called
  17.         ----------------
  18.         Made scalable
  19.         New Keystroke support
  20.  
  21.         -----------------
  22.         Updates for autotamically switching PIGs for a specific program
  23.  
  24.         -------------------
  25.         Complete Rewrite. Old form was too poorly designed
  26.         to save.
  27.  
  28.  
  29. }
  30.  
  31. interface
  32.  
  33. uses
  34.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  35.   Dialogs, StdCtrls, ExtCtrls, INIFiles, ComCtrls {for THahsedStringList},
  36.   UnitClipQueue, UnitFrmDummyUnicodeTooltip, Menus, Buttons, ClipBrd;
  37.  
  38. const DEFAULT_FOLDER = 'Default';
  39.       ADDNEW_FOLDER = '<add new>';
  40.       PERM0_FILE = 'perm0.ini';
  41.       PERM1_FILE = 'perm1.ini';
  42.       EXEPIG_FILE = 'exepigs.ini';
  43.  
  44.  
  45.  
  46. type
  47.   TFrmPermanent = class(TForm)
  48.     pcPermanent: TPageControl;
  49.     TabSheet1: TTabSheet;
  50.     TabSheet2: TTabSheet;
  51.     Label1: TLabel;
  52.     cbPIGs: TComboBox;
  53.     btnAddPIG: TButton;
  54.     btnDeletePIG: TButton;
  55.     pnlNames: TPanel;
  56.     btnUp: TButton;
  57.     btnDown: TButton;
  58.     btnDelete: TButton;
  59.     lbItemNames: TListBox;
  60.     btnEdit: TButton;
  61.     btnNew: TButton;
  62.     Panel2: TPanel;
  63.     Label2: TLabel;
  64.     Label3: TLabel;
  65.     Label4: TLabel;
  66.     txtItemName: TEdit;
  67.     mItemText: TMemo;
  68.     btnSave: TButton;
  69.     btnCancel: TButton;
  70.     lvAutoSwitch: TListView;
  71.     Label5: TLabel;
  72.     cbKeystrokes: TCheckBox;
  73.     pnlKeys: TPanel;
  74.     Button1: TButton;
  75.     Button2: TButton;
  76.     Button3: TButton;
  77.     Button4: TButton;
  78.     Button5: TButton;
  79.     Button6: TButton;
  80.     Button7: TButton;
  81.     Button8: TButton;
  82.     Button9: TButton;
  83.     Button10: TButton;
  84.     Button11: TButton;
  85.     pPreview: TImage;
  86.     bGetClipboard: TButton;
  87.     lblClipType: TLabel;
  88.     reItemText: TRichEdit;
  89.     bGetClipboardAs: TBitBtn;
  90.     pmGetAs: TPopupMenu;
  91.     PlaintText1: TMenuItem;
  92.     DIBPicture1: TMenuItem;
  93.     CopiedFiles1: TMenuItem;
  94.     RichTExt1: TMenuItem;
  95.     btnMove: TButton;
  96.     procedure FormCreate(Sender: TObject);
  97.     procedure FormShow(Sender: TObject);
  98.     procedure cbPIGsChange(Sender: TObject);
  99.     procedure btnDeleteClick(Sender: TObject);
  100.     procedure btnDownClick(Sender: TObject);
  101.     procedure btnUpClick(Sender: TObject);
  102.     procedure btnEditClick(Sender: TObject);
  103.     procedure lbItemNamesClick(Sender: TObject);
  104.     procedure btnCancelClick(Sender: TObject);
  105.     procedure btnSaveClick(Sender: TObject);
  106.     procedure btnAddPIGClick(Sender: TObject);
  107.     procedure btnNewClick(Sender: TObject);
  108.     procedure btnDeletePIGClick(Sender: TObject);
  109.     procedure FormDestroy(Sender: TObject);
  110.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  111.     procedure cbKeystrokesClick(Sender: TObject);
  112.     procedure Button1Click(Sender: TObject);
  113.     procedure bGetClipboardClick(Sender: TObject);
  114.     procedure bGetClipboardAsClick(Sender: TObject);
  115.     procedure btnMoveClick(Sender: TObject);
  116.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  117.   private
  118.   { Private declarations }
  119.         AppPath : string;
  120.         CurrentPermPath : string;
  121.         FolderList : TStringList;
  122.         ItemNameList : TStringList;
  123.         ItemDataList : TStringList;
  124.         EXEPigList : THashedStringList;
  125.         EXEPasteList : THashedStringList;
  126.         Tooltip : TTooltipWindow;
  127.         Clipboard : TClipItem;
  128.  
  129.         PushpopPath : string;
  130.         EditModeOn : boolean;
  131.  
  132.         // util functions
  133.         function GetOldDataFilename (i: integer): string;
  134.         function GetDataFilename (i: integer): string;
  135.         procedure UpdateFolderList;
  136.         procedure LoadPermanentItemsGroup;
  137.         procedure SavePermanentItemsGroup;
  138.         function IsPermanentPathFolder(folder : string) : boolean;
  139.         procedure RefreshFormData;
  140.         //
  141.         procedure SetEditMode(value : boolean);
  142.         procedure ShowSelectedItem;
  143.         procedure RefreshCurrentItem;
  144.  
  145.         procedure PopupItemClick(sender: TObject);
  146.  
  147.         function GetNextComplexIndex : integer;
  148.         function ExtractComplexIndex(s : string) : integer;
  149.   public
  150.   { Public declarations }
  151.         procedure SetPermanentPath( path : string );
  152.         function GetPermanentPath : string;
  153.         function GetPermanentPathFull : string;
  154.         // to enumerate permanent item names
  155.         function PermFoldersGetCount : cardinal;
  156.         function PermFoldersGetItem(index : cardinal) : string;
  157.         function IsComplexItem(s : string) : boolean;
  158.         function GetComplexItem(s : string) : TClipItem;
  159.  
  160.         procedure PermFolderPush;
  161.         procedure PermFolderPop;
  162.  
  163.         // to enumerate items in the current permanent folder
  164.         function GetCount: integer;
  165.         function GetItemName(i: integer): string;
  166.         function GetItemText(i: integer): string;
  167.         function GetTextFrom(name: string): string;
  168.  
  169.         // display form with a newly created item
  170.         procedure ShowWithNewItem(item : string; name : string = ''); overload;
  171.         procedure ShowWithNewComplexItem(ci : TClipItem; name : string = ''); overload;
  172.  
  173.         procedure AutoSwitch(EXEName : string);
  174.         procedure AssignPIG(EXEName : string);
  175.  
  176.  
  177.   end;
  178.  
  179. var
  180.   FrmPermanent: TFrmPermanent;
  181.  
  182. implementation
  183.  
  184. uses UnitMisc, StrUtils, UnitFrmClipboardManager, UnitFrmMove;
  185.  
  186. {$R *.dfm}
  187.  
  188.  
  189. //
  190. // public API
  191. //
  192. procedure TfrmPermanent.SetPermanentPath( path : string );
  193. begin
  194.     if (self.EditModeOn) then begin
  195.         ShowMessage('Cannot switch groups while editing a permanent item.');
  196.         EXIT;
  197.     end;
  198.  
  199.     if Self.IsPermanentPathFolder(path) then  begin
  200.         CurrentPermPath := path;
  201.         self.LoadPermanentItemsGroup;
  202.     end else begin
  203.         CurrentPermPath := DEFAULT_FOLDER;
  204.         self.LoadPermanentItemsGroup;
  205.     end;
  206.  
  207.     lbItemNames.ItemIndex := -1;
  208. end;
  209.  
  210. function TfrmPermanent.GetPermanentPath : string;
  211. begin
  212.     result := self.CurrentPermPath;
  213. end;
  214.  
  215. function TFrmPermanent.GetPermanentPathFull: string;
  216. begin
  217.     result := IncludeTrailingPathDelimiter(
  218.         IncludeTrailingPathDelimiter(self.AppPath) + self.GetPermanentPath
  219.     );
  220. end;
  221.  
  222.  
  223. function TfrmPermanent.PermFoldersGetCount : cardinal;
  224. begin
  225.     result := FolderList.Count;
  226. end;
  227. function TfrmPermanent.PermFoldersGetItem(index : cardinal) : string;
  228. begin
  229.     result := FolderList[index];
  230. end;
  231.  
  232.  
  233. function TfrmPermanent.GetCount: integer;
  234. begin
  235.     result := ItemNameList.Count;
  236. end;
  237. function TfrmPermanent.GetItemName(i: integer): string;
  238. begin
  239.     result := ItemNameList[i];
  240. end;
  241. function TfrmPermanent.GetItemText(i: integer): string;
  242. begin
  243.     result := ItemDataList[i];
  244. end;
  245. function TfrmPermanent.GetTextFrom(name: string): string;
  246. var pos: integer;
  247.     i: integer;
  248. begin
  249.     pos := -1;
  250.     for i := 0 to ItemNameList.count - 1 do begin
  251.         if (lowercase(name) = lowercase(ItemNameList[i])) then begin
  252.             pos := i;
  253.         end;
  254.     end;
  255.  
  256.     result := ItemDataList[pos];
  257. end;
  258.  
  259.  
  260. procedure TfrmPermanent.ShowWithNewItem(item : string; name : string = '');
  261. begin
  262.     self.Show;
  263.     self.btnNew.Click;
  264.     mItemText.text := item;
  265.     txtItemName.text := name;
  266.     self.SetEditMode(true);
  267.     self.RefreshCurrentItem;
  268. end;
  269.  
  270. procedure TFrmPermanent.ShowWithNewComplexItem(ci: TClipItem; name : string = '');
  271. var i : integer;
  272. begin
  273.     i := self.GetNextComplexIndex;
  274.     if (ci <> nil) then begin
  275.  
  276.         ci.SaveToFile(self.GetPermanentPathFull, i );
  277.     end;
  278.  
  279.     self.ShowWithNewItem('[FILE=' + IntToStr(i) + ']', name);
  280. end;
  281.  
  282.  
  283. //
  284. // Create / Destroy
  285. //
  286.  
  287. procedure TFrmPermanent.FormCreate(Sender: TObject);
  288. var name: string;
  289.     lc : TListColumn;
  290. begin
  291.     self.Font.Size := 8;
  292.  
  293.     self.FolderList := TStringList.Create;
  294.     self.ItemNameList := TStringList.Create;
  295.     self.ItemDataList := TStringList.Create;
  296.     self.EXEPigList := THashedStringList.Create;
  297.     self.EXEPasteList := THashedStringList.Create;
  298.     self.Tooltip := TTooltipWindow.Create;
  299.     self.Clipboard := TClipItem.Create;
  300.  
  301.     self.CurrentPermPath := DEFAULT_FOLDER;
  302.     self.AppPath := IncludeTrailingPathDelimiter(
  303.           ExtractFilePath(application.ExeName));
  304.  
  305.     // fix
  306.     if FileExists(self.AppPath + EXEPIG_FILE) then begin
  307.         self.EXEPigList.LoadFromFile(self.AppPath + EXEPIG_FILE);
  308.     end;
  309.  
  310.     //
  311.     // make the new Default directory and import and
  312.     // current permanent items
  313.     //
  314.     if not DirectoryExists( self.AppPath + DEFAULT_FOLDER) then begin
  315.         mkdir(self.AppPath + DEFAULT_FOLDER);
  316.  
  317.         name := GetOldDataFilename(0);
  318.         if FileExists(name) then
  319.             copyfile(pchar(name), PChar(GetDataFileName(0)), true);
  320.  
  321.         name := GetOldDataFilename(1);
  322.         if fileExists(name) then
  323.             copyfile(pchar(name), PChar(GetDataFilename(1)), true);
  324.     end;
  325.  
  326.     self.UpdateFolderList;
  327.  
  328.     //
  329.     // init the Auto Switch window
  330.     //
  331.     lc := lvAutoSwitch.Columns.Add;
  332.     lc.Caption := 'Program Name';
  333.     lc.Width := 100;
  334.  
  335.     lc := lvAutoSwitch.Columns.Add;
  336.     lc.Caption := 'Group';
  337.     lc.Width := 100;
  338.  
  339.     lblClipType.Caption := '';
  340.  
  341.     pcPermanent.ActivePageIndex := 0;
  342.     pcPermanent.Align := alClient;
  343. end;
  344.  
  345. procedure TFrmPermanent.FormDestroy(Sender: TObject);
  346. begin
  347.     self.EXEPigList.SaveToFile(EXEPIG_FILE);
  348.     MyFree(self.EXEPasteList);
  349.     MyFree(self.ItemNameList);
  350.     MyFree(self.ItemDataList);
  351.     MyFree(self.FolderList);
  352.     MyFree(self.Tooltip);
  353.     MyFree(self.Clipboard);
  354. end;
  355. //
  356. // Util Functions
  357. //
  358.  
  359. function TfrmPermanent.GetOldDataFilename(i: integer): string;
  360. begin
  361.     result := self.AppPath + 'perm' + IntToStr(i) + '.ini';
  362. end;
  363. function TfrmPermanent.GetDataFilename(i: integer): string;
  364. begin
  365.     case i of
  366.     0: result := IncludeTrailingPathDelimiter(self.AppPath + CurrentPermPath) + PERM0_FILE;
  367.     1: result := IncludeTrailingPathDelimiter(self.AppPath + CurrentPermPath) + PERM1_FILE;
  368.     end
  369. end;
  370.  
  371. procedure TfrmPermanent.LoadPermanentItemsGroup;
  372. var name, itemText, s : string;
  373.     lineCount : cardinal;
  374.     i : integer;
  375.     tf : textfile;
  376. begin
  377.     //
  378.     // load permanent items
  379.     //
  380.     ItemNameList.Clear;
  381.     name := GetDataFilename(0);
  382.     if FileExists(name) then begin
  383.         ItemNameList.LoadFromFile(name);
  384.     end;
  385.  
  386.     //
  387.     // abort reading and show message on error
  388.     // always close the file
  389.     //
  390.     ItemDataList.Clear;
  391.     name := GetDataFilename(1);
  392.     if FileExists(name) then begin
  393.         AssignFile(tf, name);
  394.         Reset(tf, name);
  395.  
  396.         try
  397.             while not eof(tf) do begin
  398.                 try
  399.                     Readln(tf, s);
  400.                     itemText := '';
  401.                     lineCount := StrToInt(s);
  402.  
  403.                     for i := 0 to lineCount - 1 do begin
  404.                         Readln(tf, s);
  405.                         if (itemText = '') then begin
  406.                             itemText := s;
  407.                         end else begin
  408.                             itemText := itemText + chr(13) + chr(10) + s;
  409.                         end;
  410.                     end;
  411.  
  412.                     ItemDataList.Add(itemText);
  413.                 except
  414.                      on E: Exception do begin
  415.                         ShowMessage('The "Permanent Item" file for group ' + CurrentPermPath + ' is corrupted - ' + name + #13#10#13#10 +
  416.                                     'Error Message: ' + E.Message);
  417.                         break;
  418.                      end;
  419.                 end;
  420.             end;
  421.         finally
  422.             CloseFile(tf);
  423.         end;
  424.     end;
  425. end;
  426.  
  427. procedure TfrmPermanent.SavePermanentItemsGroup;
  428. var name: string;
  429.     s : string;
  430.     cnt : cardinal;
  431.  
  432.     i,j: longint;
  433.     tf: textfile;
  434. begin
  435.     if (CurrentPermPath = '') then
  436.         EXIT;
  437.  
  438.     if not DirectoryExists(IncludeTrailingPathDelimiter(AppPath) + CurrentPermPath) then begin
  439.         mkdir(IncludeTrailingPathDelimiter(AppPath) + CurrentPermPath);
  440.     end;
  441.     //
  442.     // save items
  443.     //
  444.     name := GetDataFilename(0);
  445.     ItemNameList.SaveToFile(name);
  446.  
  447.     name := GetDataFilename(1);
  448.     AssignFile(tf, name);
  449.     Rewrite(tf);
  450.  
  451.  
  452.     for i := 0 to ItemDataList.Count - 1 do begin
  453.         s := ItemDataList[i];
  454.  
  455.         cnt := 1;
  456.         for j := 1 to length(s) - 1 do begin
  457.             if (s[j] = #13) and (s[j+1]= #10) then inc(cnt);
  458.         end;
  459.  
  460.         writeln(tf, cnt);
  461.         writeln(tf, s);
  462.     end;
  463.  
  464.     CloseFile(tf);
  465. end;
  466.  
  467.  
  468. procedure TfrmPermanent.UpdateFolderList;
  469. var rec : TSearchRec;
  470.     r : integer;
  471. begin
  472.     //
  473.     // scan each subfolder and look for permanent item config files
  474.     // this will generate a list of permanent item groups (using their
  475.     // folder name)
  476.     //
  477.     FolderList.clear;
  478.     FolderList.Sorted := true;
  479.     r := FindFirst(AppPath + '*.*', faDirectory, rec);
  480.     while (r = 0) do begin
  481.         // is file a subfolder?
  482.         if (rec.Attr and faDirectory) > 0 then begin
  483.             if (rec.name <> '.') and (rec.name <> '..') then begin
  484.                 if IsPermanentPathFolder(rec.name) then begin
  485.                     FolderList.Add(rec.name);
  486.                 end;
  487.             end;
  488.         end;
  489.  
  490.         r := FindNext(rec);
  491.     end;
  492. end;
  493.  
  494. function TFrmPermanent.IsPermanentPathFolder(folder : string) : boolean;
  495. begin
  496.     result := fileexists(IncludeTrailingPathDelimiter(AppPath) + folder + '\' + PERM0_FILE )
  497. end;
  498.  
  499.  
  500. //===================================================
  501. // User Interface Interaction
  502. // [State Philosophy]
  503. // Save after any action that changes the current group.
  504. // This includes item position, additions, or deletions.
  505. //===================================================
  506. procedure TFrmPermanent.FormShow(Sender: TObject);
  507. begin
  508.     self.LoadPermanentItemsGroup;
  509.     self.RefreshFormData;
  510.     self.SetEditMode(false);
  511.     txtItemName.Text := '';
  512.     mItemText.Text := '';
  513.  
  514.     self.btnEdit.Enabled := false;
  515.     self.btnDelete.Enabled := false;
  516.     self.btnUp.Enabled := false;
  517.     self.btnDown.Enabled := false;
  518.     self.btnMove.Enabled := false;
  519. end;
  520.  
  521. procedure TFrmPermanent.RefreshFormData;
  522. var i : integer;
  523.     li : TListItem;
  524. begin
  525.     // show the curent Permanent Item Group names and
  526.     // select the current folder in the dropdown
  527.     cbpigs.Clear;
  528.     cbPIGs.Items.AddStrings(FolderList);
  529.     for i := 0 to FolderList.Count - 1 do begin
  530.         if lowercase(cbpigs.Items[i]) = lowercase(CurrentPermPath) then begin
  531.             cbPIGs.ItemIndex := i;
  532.         end;
  533.     end;
  534.  
  535.     // load the current item names
  536.     //
  537.     lbItemNames.Clear;
  538.     lbItemNames.Items.AddStrings(ItemNameList);
  539.  
  540.     lvAutoSwitch.Items.clear;
  541.     for i := 0 to EXEPigList.Count - 1 do begin
  542.         li := lvAutoSwitch.items.Add;
  543.         li.Caption := EXEPigList.Names[i];
  544.         li.SubItems.Add(EXEPigList.Values[EXEPigList.Names[i]]);
  545.     end;
  546. end;
  547.  
  548.  
  549. //
  550. // group changed or item clicked
  551. //
  552. procedure TFrmPermanent.cbPIGsChange(Sender: TObject);
  553. begin
  554.     //self.SavePermanentItemsGroup;
  555.     self.SetPermanentPath(cbpigs.text);
  556.     self.RefreshFormData;
  557.     txtItemName.Text := '';
  558.     mItemText.Text := '';
  559. end;
  560.  
  561. procedure TFrmPermanent.lbItemNamesClick(Sender: TObject);
  562. begin
  563.     self.ShowSelectedItem;
  564.     self.btnEdit.Enabled := true;
  565.     self.btnDelete.Enabled := true;
  566.     self.btnUp.Enabled := true;
  567.     self.btnDown.Enabled := true;
  568.     self.btnMove.Enabled := true;
  569. end;
  570.  
  571. procedure TFrmPermanent.FormClose(Sender: TObject;
  572.   var Action: TCloseAction);
  573. begin
  574.     self.btnEdit.Enabled := false;
  575.     self.btnDelete.Enabled := false;
  576.     self.btnUp.Enabled := false;
  577.     self.btnDown.Enabled := false;
  578.     self.btnMove.Enabled := false;
  579.     Tooltip.CloseTooltip;
  580. end;
  581.  
  582.  
  583. // permanent item edit buttons
  584. //
  585. procedure TfrmPermanent.btnUpClick(Sender: TObject);
  586. var i: integer;
  587. begin
  588.     i := lbItemNames.ItemIndex;
  589.     if not (i < 0) then begin
  590.         ItemNameList.Move(i, i - 1);
  591.         ItemDataList.Move(i, i - 1);
  592.         lbItemNames.Items.Move(i, i - 1);
  593.  
  594.         lbItemNames.ItemIndex := i - 1;
  595.     end;
  596.  
  597.     self.SavePermanentItemsGroup;
  598. end;
  599. procedure TfrmPermanent.btnDownClick(Sender: TObject);
  600. var i: integer;
  601. begin
  602.     i := lbItemNames.ItemIndex;
  603.     if (i <> lbItemNames.Count -1) and (i <> -1)then begin
  604.         ItemNameList.Move(i, i + 1);
  605.         ItemDataList.Move(i, i + 1);
  606.         lbItemNames.Items.Move(i, i + 1);
  607.  
  608.         lbItemNames.ItemIndex := i + 1;
  609.     end;
  610.  
  611.     self.SavePermanentItemsGroup;
  612. end;
  613.  
  614. procedure TfrmPermanent.btnDeleteClick(Sender: TObject);
  615. var i: integer;
  616. begin
  617.     Tooltip.CloseTooltip;
  618.  
  619.     i := lbItemNames.ItemIndex;
  620.     if (i <> -1) then begin
  621.         ItemNameList.Delete(i);
  622.         ItemDataList.Delete(i);
  623.         lbItemNames.DeleteSelected;
  624.     end;
  625.  
  626.     self.SavePermanentItemsGroup;
  627.  
  628.     //TODO : clear the screen or select something else
  629.     if (lbItemNames.Count > 0) then begin
  630.         // Select the previous item if the last item item in list was delted
  631.         while (i >= lbItemNames.Count) and (i > 0) do begin
  632.             Dec(i);
  633.         end;
  634.         lbItemNames.ItemIndex := i;
  635.     end else begin
  636.         self.mItemText.Text := '';
  637.         self.txtItemName.text := '';
  638.     end;
  639.     Self.ShowSelectedItem;
  640.     Self.RefreshCurrentItem;
  641. end;
  642.  
  643. procedure TFrmPermanent.btnEditClick(Sender: TObject);
  644. var i: integer;
  645. begin
  646.     i := lbItemNames.ItemIndex;
  647.     if (i <> -1) then begin
  648.         //ShowSelectedItem;
  649.         SetEditMode(true);
  650.     end;
  651. end;
  652.  
  653.  
  654. procedure TfrmPermanent.SetEditMode(value : boolean);
  655. var i : integer;
  656.     prefix : string;
  657. begin
  658.     Tooltip.CloseTooltip;
  659.     
  660.     Self.EditModeOn := value;
  661.     if (value) then begin
  662.         txtItemName.Enabled := true;
  663.         mItemText.enabled := true;
  664.  
  665.         btnSave.Visible := true;
  666.         btnCancel.Visible := true;
  667.         cbKeystrokes.Visible := true;
  668.  
  669.         bGetClipboard.Visible := true;
  670.         bGetClipboardAs.Visible := true;
  671.         prefix := uppercase(leftstr(mItemText.Text,6));
  672.         cbKeystrokes.Checked :=  prefix = '[KEYS]';
  673.         pnlKeys.Visible := cbKeystrokes.Checked;
  674.  
  675.         for i := 0 to pnlNames.ControlCount - 1 do begin
  676.             pnlNames.Controls[i].Enabled := false;
  677.         end;
  678.         pnlNames.Enabled := false;
  679.         lbItemNames.Enabled := false;
  680.         cbPIGs.Enabled := false;
  681.  
  682.  
  683.         if (self.IsComplexItem(mItemText.text)) then begin
  684.             mItemText.ReadOnly := true;
  685.             cbKeystrokes.Visible := false;
  686.         end else begin
  687.             mItemText.ReadOnly := false;            
  688.         end;
  689.  
  690.     end else begin
  691.         mItemText.Visible := true;
  692.         pPreview.Visible := false;
  693.         reItemText.Visible := false;
  694.  
  695.         txtItemName.Enabled := false;
  696.         mItemText.Enabled := false;
  697.  
  698.         btnSave.Visible := false;
  699.         btnCancel.Visible := false;
  700.         cbKeystrokes.Visible := false;
  701.         pnlKeys.Visible := false;
  702.         bGetClipboard.Visible := false;
  703.         bGetClipboardAs.Visible := false;
  704.  
  705.         for i := 0 to pnlNames.ControlCount - 1 do begin
  706.             pnlNames.Controls[i].Enabled := true;
  707.         end;
  708.         pnlNames.Enabled := true;
  709.         lbItemNames.Enabled := true;
  710.         cbPIGs.Enabled := true;
  711.     end;
  712. end;
  713.  
  714. procedure TfrmPermanent.ShowSelectedItem;
  715. var i : integer;
  716. begin
  717.     i := lbItemNames.ItemIndex;
  718.     if (i <> -1) then begin
  719.         txtItemName.Text := ItemNameList[i];
  720.         mItemText.Text := ItemDataList[i];
  721.     end;
  722.  
  723.     Tooltip.CloseTooltip;
  724.  
  725.     Clipboard.GetClipboardItem(0);
  726.     bGetClipboard.Caption := 'Get Clipboard as ' + Clipboard.GetFormatName;
  727.     
  728.     self.RefreshCurrentItem;
  729. end;
  730.  
  731. procedure TFrmPermanent.RefreshCurrentItem;
  732. var ci : TClipItem;
  733.     p : TPoint;
  734.     s  : string;
  735. begin
  736.     // display the appropriete control depending on the content
  737.     // (supports the new [file=] clip format)
  738.     
  739.     pPreview.Visible := false;
  740.     mItemText.Visible := false;
  741.     reItemText.Visible := false;
  742.     if (self.IsComplexItem(mItemText.text)) then begin
  743.         ci := self.GetComplexItem(mItemText.text);
  744.         lblClipType.Caption := ci.GetFormatName;
  745.         if (ci.GetFormat = Windows.CF_DIB) then begin
  746.             pPreview.Visible := true;
  747.             ci.GetDIB(pPreview.Picture);
  748.             pPreview.Hint := mItemText.text;
  749.         end else if (ci.GetFormat = frmClipboardManager.CF_RICHTEXT)
  750.             or (ci.GetFormat = frmClipboardManager.CF_HTML) then begin
  751.             reItemText.Visible := true;
  752.             reItemText.PlainText := false;
  753.             reItemText.Lines.Clear;
  754.             ci.GetRichText(s);
  755.             reItemText.Text := s;
  756.             reItemText.Hint := mItemText.Text;
  757.         end else if (ci.GetFormat = Windows.CF_UNICODETEXT) then begin
  758.             //mItemText.Visible := true;
  759.             Windows.ClientToScreen(mItemText.Handle, p);
  760.             Tooltip.ShowTooltip(ci, p);
  761.             MyFree(ci);
  762.         end else begin
  763.  
  764.         end;
  765.     end else begin
  766.         mItemText.Visible := true;
  767.         lblClipType.Caption := 'Plain Text';
  768.     end;
  769. end;
  770.  
  771.  
  772. //
  773. // Save / Cancel button used durring Edit Mode 
  774. //
  775. procedure TFrmPermanent.btnCancelClick(Sender: TObject);
  776. begin
  777.  
  778.     self.SetEditMode(false);
  779.     self.ShowSelectedItem;
  780.     if (lbItemNames.ItemIndex = -1) then begin
  781.         self.btnEdit.Enabled := false;
  782.         self.btnDelete.Enabled := false;
  783.         self.btnUp.Enabled := false;
  784.         self.btnDown.Enabled := false;
  785.         self.mItemText.Text := '';
  786.         self.txtItemName.text := '';
  787.     end;
  788. end;
  789.  
  790. procedure TFrmPermanent.btnSaveClick(Sender: TObject);
  791. var i : integer;
  792. begin
  793.    { TODO : Rewrite teh NEw/Edit logic }
  794.  
  795.     if txtItemName.text = '' then begin
  796.         ShowMessage('A name is required for an item');
  797.         EXIT;
  798.     end;
  799.     // detect 'New' or 'Edit'
  800.     i := lbItemNames.ItemIndex;
  801.     if (cbKeystrokes.checked) then begin
  802.     end;
  803.  
  804.     if (i = -1) then begin
  805.         i := lbItemNames.count;
  806.         ItemNameList.Add(txtItemName.Text);
  807.         ItemDataList.Add(mItemText.text);
  808.     end else begin
  809.         ItemNameList[i] := txtItemName.Text;
  810.         ItemDataList[i] := mItemText.text;
  811.     end;
  812.  
  813.     self.SavePermanentItemsGroup;
  814.     self.SetEditMode(false);
  815.     self.RefreshFormData;
  816.     
  817.     lbItemNames.ItemIndex := i;
  818.     self.ShowSelectedItem;
  819. end;
  820.  
  821.  
  822. procedure TFrmPermanent.btnNewClick(Sender: TObject);
  823. begin
  824.     Tooltip.CloseTooltip;
  825.  
  826.     txtItemName.text := '';
  827.     mItemText.text := '';
  828.     reItemText.Text := '';
  829.     self.RefreshCurrentItem;
  830.     lbItemNames.ItemIndex := -1;
  831.  
  832.     self.SetEditMode(true);
  833.  
  834.     Clipboard.GetClipboardItem(0);
  835.     bGetClipboard.Caption := 'Get Clipboard as ' + Clipboard.GetFormatName;
  836.     lblClipType.Caption := 'Plain Text';
  837.     self.txtItemName.SetFocus;
  838. end;
  839.  
  840. //
  841. // add / delete Permanent Item Group
  842. //
  843. procedure TFrmPermanent.btnAddPIGClick(Sender: TObject);
  844. var newgroup : string;
  845. begin
  846.     if
  847.     Dialogs.InputQuery('Add Group','Please enter a new group name', newgroup)
  848.     then begin
  849.         if not IsPermanentPathFolder(newgroup) then begin
  850.             self.CurrentPermPath  := newgroup;
  851.             self.ItemNameList.Clear;
  852.             self.ItemDataList.clear;
  853.             self.SavePermanentItemsGroup;
  854.             self.UpdateFolderList;
  855.             self.RefreshFormData;
  856.         end else begin
  857.             Dialogs.showmessage('Group name already exists');
  858.         end;
  859.     end;
  860. end;
  861.  
  862.  
  863. procedure TFrmPermanent.btnDeletePIGClick(Sender: TObject);
  864. begin
  865.     if DirectoryExists(IncludeTrailingPathDelimiter(AppPath) + cbPIGs.Text) then begin
  866.         deletefile( GetDataFilename(0) );
  867.         deleteFile( GetDataFilename(1) );
  868.         RmDir(IncludeTrailingPathDelimiter(AppPath) + cbPIGs.Text);
  869.         self.SetPermanentPath(cbPIGs.Items[0]);
  870.         self.UpdateFolderList;
  871.         self.RefreshFormData;
  872.     end;
  873. end;
  874.  
  875.  
  876. procedure TFrmPermanent.AutoSwitch(EXEName: string);
  877. var path : string;
  878. begin
  879.     // given an EXE name, change to a PIG if it's associated with one
  880.     // Associate the current PIG with the EXE if no association exist
  881.     
  882.     path := EXEPigList.Values[EXEName];
  883.     if (path <> '') then begin
  884.         self.SetPermanentPath(path);
  885.     end else begin
  886.         if EXEName <> '' then begin
  887.             EXEPigList.Values[EXEName] := self.GetPermanentPath;
  888.         end;
  889.     end;
  890. end;
  891.  
  892.  
  893.  
  894. procedure TFrmPermanent.AssignPIG(EXEName: string);
  895. begin
  896.     EXEPigList.Values[EXEName] := self.GetPermanentPath;
  897. end;
  898.  
  899.  
  900.  
  901. procedure TFrmPermanent.cbKeystrokesClick(Sender: TObject);
  902. begin
  903.     // add or remove the [KEYS] tag
  904.     if (cbKeystrokes.Checked) then begin
  905.         if (uppercase(leftstr(mItemText.text, 6)) <> '[KEYS]') then begin
  906.             mItemText.Text := '[KEYS]' + mItemText.Text;
  907.         end;
  908.         pnlKeys.Visible := true;
  909.     end else begin
  910.         if (uppercase(leftstr(mItemText.text, 6)) = '[KEYS]') then begin
  911.             mItemText.Text := rightstr(mItemText.Text, length(mItemText.Text) - 6);
  912.         end;
  913.         pnlKeys.Visible := false;
  914.     end;
  915. end;
  916.  
  917. procedure TFrmPermanent.Button1Click(Sender: TObject);
  918. var btn : TButton;
  919. begin
  920.     btn := TButton(sender);
  921.     mItemText.SelText := '[' + btn.Caption + ']';
  922. end;
  923.  
  924.  
  925.  
  926.  
  927.  
  928. function TFrmPermanent.GetComplexItem(s: string): TClipItem;
  929. var i : integer;
  930. begin
  931.     result := TClipItem.Create;
  932.  
  933.     s := midstr(s,7,length(s)-7);
  934.     i := StrToInt(s);
  935.     result.LoadFromFIle(
  936.         self.GetPermanentPathFull,
  937.         i);
  938. end;
  939.  
  940. function TFrmPermanent.IsComplexItem(s: string): boolean;
  941. begin
  942.     result := uppercase(leftstr(s,6)) =  '[FILE=';
  943. end;
  944.  
  945.  
  946.  
  947.  
  948. procedure TFrmPermanent.bGetClipboardClick(Sender: TObject);
  949. var i : integer;
  950. begin
  951.     // find the first unused index
  952.     // default to selected item index, or (last used + 1)
  953.     // to store the clip item
  954.  
  955.     i := self.GetNextComplexIndex;
  956.  
  957.     while FileExists(clipboard.GetFilename(self.GetPermanentPathFull, i)) do
  958.         inc(i);
  959.  
  960.     clipboard.SaveToFile(self.GetPermanentPathFull, i);
  961.     mItemText.Text := '[FILE=' + IntToStr(i) + ']';
  962.  
  963.     self.SetEditMode(true);
  964.     self.RefreshCurrentItem;
  965.  
  966. end;
  967.  
  968.  
  969.  
  970. procedure TFrmPermanent.bGetClipboardAsClick(Sender: TObject);
  971. var mi : TMenuItem;
  972.     p : TPoint;
  973. begin
  974.     pmGetAs.Items.Clear;
  975.      if Clipbrd.clipboard.HasFormat(CF_WAVE) then begin
  976.         mi := TMenuItem.Create(pmGetAs);
  977.         mi.Caption := 'Wave Audio';
  978.         mi.Hint := IntToStr(CF_WAVE);
  979.         mi.OnClick := self.PopupItemClick;
  980.         pmGetAs.Items.Add(mi);
  981.     end;
  982.     if Clipbrd.clipboard.HasFormat(CF_DIB) then begin
  983.         mi := TMenuItem.Create(pmGetAs);
  984.         mi.Caption := 'DIB (Picture)';
  985.         mi.Hint := IntToStr(CF_DIB);
  986.         mi.OnClick := self.PopupItemClick;
  987.         pmGetAs.Items.Add(mi);
  988.     end;
  989.     if Clipbrd.clipboard.HasFormat(CF_HDROP) then begin
  990.         mi := TMenuItem.Create(pmGetAs);
  991.         mi.Caption := 'File(s)';
  992.         mi.Hint := IntToStr(CF_HDROP);
  993.         mi.OnClick := self.PopupItemClick;
  994.         pmGetAs.Items.Add(mi);
  995.     end;
  996.     if Clipbrd.clipboard.HasFormat(frmClipboardManager.CF_RICHTEXT) then begin
  997.         mi := TMenuItem.Create(pmGetAs);
  998.         mi.Caption := 'Rich Text';
  999.         mi.Hint := IntToStr(frmClipboardManager.CF_RICHTEXT);
  1000.         mi.OnClick := self.PopupItemClick;
  1001.         pmGetAs.Items.Add(mi);
  1002.     end;
  1003.     if Clipbrd.clipboard.HasFormat(frmClipboardManager.CF_HTML) then begin
  1004.         mi := TMenuItem.Create(pmGetAs);
  1005.         mi.Caption := 'HTML';
  1006.         mi.Hint := IntToStr(frmClipboardManager.CF_HTML);
  1007.         mi.OnClick := self.PopupItemClick;
  1008.         pmGetAs.Items.Add(mi);
  1009.     end;
  1010.     if Clipbrd.clipboard.HasFormat(CF_UNICODETEXT) then begin
  1011.         mi := TMenuItem.Create(pmGetAs);
  1012.         mi.Hint := IntToStr(CF_UNICODETEXT);
  1013.         mi.OnClick := self.PopupItemClick;
  1014.         mi.Caption := 'Unicode';
  1015.         pmGetAs.Items.Add(mi);
  1016.     end;
  1017.     Windows.ClientToScreen(bGetClipboardAs.Handle, p);
  1018.     pmGetAs.Popup(p.X + 4, p.y + 4);
  1019. end;
  1020.  
  1021. procedure TFrmPermanent.PopupItemClick(sender: TObject);
  1022. var i, format : integer;
  1023. begin
  1024.     with sender as TMenuItem do begin
  1025.         format := StrToInt(Hint);
  1026.     end;
  1027.  
  1028.     {TODO: This is copy/pasted code and should be actually chared with the normal
  1029.         GetClipboard button }
  1030.     // find the first unused index
  1031.     // default to selected item index, or (last used + 1)
  1032.     // to store the clip item
  1033.  
  1034.     i := self.GetNextComplexIndex;
  1035.  
  1036.     while FileExists(clipboard.GetFilename(self.GetPermanentPathFull, i)) do
  1037.         inc(i);
  1038.  
  1039.     clipboard.GetClipboardItem(0, Format);
  1040.     clipboard.SaveToFile(self.GetPermanentPathFull, i);
  1041.     mItemText.Text := '[FILE=' + IntToStr(i) + ']';
  1042.  
  1043.     self.SetEditMode(true);
  1044.     self.RefreshCurrentItem;
  1045.  
  1046. end;
  1047.  
  1048. procedure TFrmPermanent.PermFolderPop;
  1049. begin
  1050.     if self.PushpopPath <> self.CurrentPermPath then begin
  1051.         self.SetPermanentPath(self.PushpopPath);
  1052.     end;
  1053. end;
  1054.  
  1055. procedure TFrmPermanent.PermFolderPush;
  1056. begin
  1057.     self.PushpopPath := self.CurrentPermPath;
  1058. end;
  1059.  
  1060.  
  1061.  
  1062. procedure TFrmPermanent.btnMoveClick(Sender: TObject);
  1063. var ci : TClipItem;
  1064.     name, text : string;
  1065. begin
  1066.     self.Tooltip.CloseTooltip;
  1067.  
  1068.     // get as complex item or plain text
  1069.     ci := nil;
  1070.     name := txtItemName.Text;    
  1071.     if (self.IsComplexItem(mItemText.text)) then begin
  1072.         ci := self.GetComplexItem(mItemText.text);
  1073.     end else begin
  1074.         text := mItemText.text;
  1075.     end;
  1076.  
  1077.     // Show the Move dialog
  1078.     // Delete the selected item,
  1079.     // Show the form with the new item,
  1080.     // click save, select the new item in the list
  1081.     // cleanup
  1082.  
  1083.     FrmMove.ShowModal;
  1084.     if (FrmMove.ModalResult = mrOK) then begin
  1085.         btnDelete.Click;
  1086.         self.SetPermanentPath(FrmMove.cbMove.text);
  1087.         self.RefreshFormData;
  1088.  
  1089.         //self.hide;
  1090.         if (ci = nil) then begin
  1091.             self.ShowWithNewItem(text, name);
  1092.         end else begin
  1093.             self.ShowWithNewComplexItem(ci, name);
  1094.             self.btnSave.Click;
  1095.         end;
  1096.     end;
  1097.     //lbItemNames.ItemIndex := lbItemNames.count - 1;
  1098.     UnitMisc.MyFree(ci);
  1099.  
  1100. end;
  1101.  
  1102. function TFrmPermanent.GetNextComplexIndex: integer;
  1103. var i, j : integer;
  1104.     sl : TStringList;
  1105. begin
  1106.     sl := TStringList.Create;
  1107.  
  1108.     for i := 0 to (ItemDataList.Count - 1) do begin
  1109.         if self.IsComplexItem(ItemDataList[i]) then begin
  1110.             j := self.ExtractComplexIndex(ItemDataList[i]);
  1111.  
  1112.             sl.Add(IntToStr(j));
  1113.         end;
  1114.     end;
  1115.  
  1116.     result := 0;
  1117.     while sl.IndexOf(IntToStr(result)) <> -1 do inc(result);
  1118.  
  1119.     UnitMisc.MyFree(sl);
  1120. end;
  1121.  
  1122. function TFrmPermanent.ExtractComplexIndex(s: string): integer;
  1123. begin
  1124.     s := midstr(s,7,length(s)-7);
  1125.     result := StrToInt(s);
  1126. end;
  1127.  
  1128.  
  1129.  
  1130. procedure TFrmPermanent.FormCloseQuery(Sender: TObject;
  1131.   var CanClose: Boolean);
  1132. begin
  1133.     if btnCancel.Visible then begin
  1134.         btnCancel.Click;
  1135.     end;
  1136.  
  1137.     CanClose := true;
  1138. end;
  1139.  
  1140. end.
  1141.