home *** CD-ROM | disk | FTP | other *** search
/ Chip 1999 January / Chip_1999-01_cd.bin / zkuste / delphi / QDB / ADDBOOK.ZIP / AB_main.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-06-28  |  11.7 KB  |  451 lines

  1.  
  2. {*****************************************************************************}
  3. {                                                                             }
  4. {                             Address Book Demo                               }
  5. {                                                                             }
  6. {                     illustrating the use of the                             }
  7. {                                                                             }
  8. {            QDB v2.10 Visual Components for Delphi 1, 2, & 3                 }
  9. {                                                                             }
  10. {          Copyright (c) 1995, 1996, 1997, Robert R. Marsh, S.J.              }
  11. {             & the British Province of the Society of Jesus                  }
  12. {                                                                             }
  13. {                                                                             }
  14. {       You may use this demonstration application and modify it in           }
  15. {       whatever way you choose. You may not, however, sell it for            }
  16. {       profit unless the changes you have made are substantial (i.e.,        }
  17. {       more than 50% new code), in which case I'd appreciate                 }
  18. {       receiving a copy of your new work.                                    }
  19. {                                                                             }
  20. {       If you like add_book and find yourself using it please                }
  21. {       consider making a donation to your favorite charity.                  }
  22. {                                                                             }
  23. {    Users of add_book must accept the following disclaimer of warranty:      }
  24. {                                                                             }
  25. {       add_book is supplied as is. The author disclaims all warranties,      }
  26. {       expressed or implied, including, without limitation, the              }
  27. {       warranties of merchantability and of fitness for any purpose.         }
  28. {       The author assumes no liability for damages, direct or                }
  29. {       consequential, which may result from the use of add_book.             }
  30. {                                                                             }
  31. {*****************************************************************************}
  32.  
  33. unit AB_main;
  34.  
  35. interface
  36.  
  37. uses
  38.   SysUtils, WinTypes, WinProcs, Classes, Graphics, Controls,
  39.   Forms, Dialogs, StdCtrls, Buttons, ExtCtrls, Menus, QDB;
  40.  
  41. type
  42.   TAB_form = class(TForm)
  43.     MainMenu: TMainMenu;
  44.     FileNewItem: TMenuItem;
  45.     FileOpenItem: TMenuItem;
  46.     FileSaveItem: TMenuItem;
  47.     FileCloseItem: TMenuItem;
  48.     FileExitItem: TMenuItem;
  49.     StatusLine: TPanel;
  50.     OpenDialog: TOpenDialog;
  51.     SaveDialog: TSaveDialog;
  52.     Addresses: TQDB;
  53.     SpeedBar: TPanel;
  54.     FileNewSButton: TSpeedButton;
  55.     FileOpenSButton: TSpeedButton;
  56.     FileSaveSButton: TSpeedButton;
  57.     FileCloseSButton: TSpeedButton;
  58.     FileExitSButton: TSpeedButton;
  59.     ListPanel: TPanel;
  60.     KeyList: TListBox;
  61.     EntryPanel: TPanel;
  62.     AddBox: TMemo;
  63.     IsPerson: TCheckBox;
  64.     HPhone: TEdit;
  65.     WPhone: TEdit;
  66.     FPhone: TEdit;
  67.     E_Mail: TEdit;
  68.     Label1: TLabel;
  69.     Label2: TLabel;
  70.     Label3: TLabel;
  71.     Label4: TLabel;
  72.     Label6: TLabel;
  73.     ButtonPanel: TPanel;
  74.     AddButton: TButton;
  75.     ClearButton: TButton;
  76.     DeleteButton: TButton;
  77.     Image: TImage;
  78.     procedure FormCreate(Sender: TObject);
  79.     procedure ShowHint(Sender: TObject);
  80.     procedure FileNew(Sender: TObject);
  81.     procedure FileOpen(Sender: TObject);
  82.     procedure FileSave(Sender: TObject);
  83.     procedure FileClose(Sender: TObject);
  84.     procedure FileExit(Sender: TObject);
  85.     procedure HelpContents(Sender: TObject);
  86.     procedure AddButtonClick(Sender: TObject);
  87.     procedure ClearButtonClick(Sender: TObject);
  88.     procedure DeleteButtonClick(Sender: TObject);
  89.     procedure KeyListClick(Sender: TObject);
  90.     procedure AddressesProgressUpdate(Sender: TObject;
  91.       Percent: TPercentage; Kind: TProgressOrigin);
  92.   private
  93.     procedure BlankEntries;
  94.     procedure MyActivate;
  95.     procedure MyDeActivate;
  96.     procedure ScreenToItem(P: PChar; var PLen: word);
  97.     procedure ItemToScreen(P: PChar);
  98.     function CurrentKey: TKey;
  99.     procedure MyUpdate;
  100.   end;
  101.  
  102. var
  103.   AB_form: TAB_form;
  104.  
  105. implementation
  106.  
  107. {$R *.DFM}
  108.  
  109. {invert a name to put the surname first}
  110. {e.g. Robert R. Marsh => Marsh, Robert R.}
  111.  
  112. function NameToKey(Name: string): string;
  113.  
  114.   {return first position of a char after position n}
  115.   function PosCAfter(c: char; s: string; n: integer): integer;
  116.   var
  117.     i: integer;
  118.   begin
  119.     Result := 0;
  120.     for i := n + 1 to Length(s) do
  121.       if s[i] = c then
  122.       begin
  123.         Result := i;
  124.         Break;
  125.       end;
  126.   end;
  127.  
  128. {$IFNDEF WIN32}
  129.   procedure TrimLeft(var s: string);
  130.   begin
  131.     while s[1] = ' ' do Delete(s, 1, 1);
  132.   end;
  133.  
  134.   procedure TrimRight(var s: string);
  135.   begin
  136.     while s[length(s)] = ' ' do delete(s, length(s), 1);
  137.   end;
  138. {$ENDIF}
  139.  
  140. var
  141.   NewName: string;
  142.   CommaPos: Byte;
  143.   SpacePos: Byte;
  144.   LastSpacePos: Byte;
  145. begin
  146.   NewName := Name;
  147.   TrimLeft(NewName);
  148. { then remove anything after a comma, e.g. strip off the S.J.'s}
  149.   CommaPos := PosCAfter(',', NewName, 0);
  150.   if CommaPos <> 0 then
  151.     NewName := Copy(NewName, 1, CommaPos - 1);
  152. { now strip off trailing spaces and see if anything is left }
  153.   TrimRight(NewName);
  154.   if Length(NewName) = 0 then
  155.   begin
  156.     Result := '';
  157.     Exit;
  158.   end;
  159. { finally, find the last space in the name and take it to delimit the surname }
  160.   LastSpacePos := 1;
  161.   SpacePos := 1;
  162.   while SpacePos <> 0 do
  163.   begin
  164.     LastSpacePos := SpacePos;
  165.     SpacePos := PosCAfter(' ', NewName, SpacePos);
  166.   end;
  167. { then just invert the order }
  168.   if LastSpacePos = 1 then
  169.     Result := NewName
  170.   else
  171.     Result := Copy(NewName, LastSpacePos + 1, high(integer)) + ', ' + Copy(NewName, 1, LastSpacePos - 1);
  172. end;
  173.  
  174. const
  175.   MaxSize = 400; {largest item possible}
  176.   BaseTitle = 'Address Book Demo';
  177.  
  178. procedure TAB_form.FormCreate(Sender: TObject);
  179. begin
  180.   Application.OnHint := ShowHint;
  181.   AB_form.Caption := BaseTitle;
  182.   MyDeActivate;
  183. end;
  184.  
  185. procedure TAB_form.ShowHint(Sender: TObject);
  186. begin
  187.   StatusLine.Caption := Application.Hint;
  188. end;
  189.  
  190. procedure TAB_form.FileNew(Sender: TObject);
  191. var
  192.   NewFileName: string;
  193. begin
  194.   if SaveDialog.Execute then
  195.   begin
  196.     NewFileName := SaveDialog.FileName;
  197.     if FileExists(NewFileName) then SysUtils.DeleteFile(NewFileName);
  198.     Addresses.FileName := NewFileName;
  199.     AB_form.Caption := BaseTitle + ' - ' + ExtractFileName(Addresses.FileName);
  200.     KeyList.Items.Clear;
  201.     MyUpdate;
  202.     MyActivate;
  203.   end;
  204. end;
  205.  
  206. procedure TAB_form.FileOpen(Sender: TObject);
  207. begin
  208.   if OpenDialog.Execute then
  209.   begin
  210.     Addresses.FileName := OpenDialog.FileName;
  211.     Addresses.CacheSize := 8 * 1024;
  212.     BlankEntries;
  213.     Addresses.AssignKeyList(KeyList.Items);
  214.     if KeyList.Items.Count > 0 then
  215.     begin
  216.       KeyList.ItemIndex := 0;
  217.       MyUpdate;
  218.     end;
  219.     AB_form.Caption := BaseTitle + ' - ' + ExtractFileName(Addresses.FileName);
  220.     MyActivate;
  221.   end;
  222. end;
  223.  
  224. procedure TAB_form.FileSave(Sender: TObject);
  225. begin
  226.   Addresses.Save;
  227.   Addresses.Pack;
  228. end;
  229.  
  230. procedure TAB_form.FileExit(Sender: TObject);
  231. begin
  232.   if Addresses.FileName <> '' then
  233.   begin
  234.     Addresses.FileName := '';
  235.   end;
  236.   Close;
  237. end;
  238.  
  239. procedure TAB_form.HelpContents(Sender: TObject);
  240. begin
  241.   Application.HelpCommand(HELP_CONTENTS, 0);
  242. end;
  243.  
  244. procedure TAB_form.FileClose(Sender: TObject);
  245. begin
  246.   Addresses.Save;
  247.   Addresses.Pack;
  248.   Addresses.FileName := '';
  249.   BlankEntries;
  250.   KeyList.Items.Clear;
  251.   AB_form.Caption := BaseTitle;
  252.   MyDeActivate;
  253. end;
  254.  
  255. {pack the data on the screen into an item we can store}
  256.  
  257. procedure TAB_form.ScreenToItem(P: PChar; var PLen: word);
  258. var
  259.   PP: PChar;
  260. begin
  261.   PP := P;
  262.   StrPCopy(PP, AddBox.Text);
  263.   inc(PP, StrLen(PP) + 1);
  264.   if IsPerson.Checked then
  265.   begin
  266.     StrPCopy(PP, 'Y');
  267.     inc(PP, StrLen(PP) + 1);
  268.   end
  269.   else
  270.   begin
  271.     StrPCopy(PP, 'N');
  272.     inc(PP, StrLen(PP) + 1);
  273.   end;
  274.   StrPCopy(PP, HPhone.Text);
  275.   inc(PP, StrLen(PP) + 1);
  276.   StrPCopy(PP, WPhone.Text);
  277.   inc(PP, StrLen(PP) + 1);
  278.   StrPCopy(PP, FPhone.Text);
  279.   inc(PP, StrLen(PP) + 1);
  280.   StrPCopy(PP, E_Mail.Text);
  281.   inc(PP, StrLen(PP) + 1);
  282.   PLen := PP - P + 1;
  283. end;
  284.  
  285. {unpack an item onto the screen}
  286.  
  287. procedure TAB_form.ItemToScreen(P: PChar);
  288. var
  289.   PP: PChar;
  290. begin
  291.   Addresses.GetItem(P);
  292.   PP := P;
  293.   AddBox.SetTextBuf(PP);
  294.   inc(PP, StrLen(PP) + 1);
  295.   IsPerson.Checked := (StrPas(PP) = 'Y');
  296.   inc(PP, StrLen(PP) + 1);
  297.   HPhone.Text := StrPas(PP);
  298.   inc(PP, StrLen(PP) + 1);
  299.   WPhone.Text := StrPas(PP);
  300.   inc(PP, StrLen(PP) + 1);
  301.   FPhone.Text := StrPas(PP);
  302.   inc(PP, StrLen(PP) + 1);
  303.   E_Mail.Text := StrPas(PP);
  304. end;
  305.  
  306. procedure TAB_form.BlankEntries;
  307. begin
  308.   AddBox.Text := '';
  309.   IsPerson.Checked := true;
  310.   HPhone.Text := '';
  311.   WPhone.Text := '';
  312.   FPhone.Text := '';
  313.   E_Mail.Text := '';
  314.   AddBox.SetFocus;
  315. end;
  316.  
  317. procedure TAB_form.MyActivate;
  318. begin
  319.   AddButton.Enabled := true;
  320.   ClearButton.Enabled := true;
  321.   DeleteButton.Enabled := true;
  322. end;
  323.  
  324. procedure TAB_form.MyDeActivate;
  325. begin
  326.   AddButton.Enabled := false;
  327.   ClearButton.Enabled := false;
  328.   DeleteButton.Enabled := false;
  329. end;
  330.  
  331. function TAB_form.CurrentKey: TKey;
  332. var
  333.   ThisItem: integer;
  334. begin
  335.   if KeyList.Items.Count > 0 then
  336.   begin
  337.     ThisItem := KeyList.ItemIndex;
  338.     if ThisItem < 0 then
  339.     begin
  340.       Result := '';
  341.     end
  342.     else
  343.     begin
  344.       Result := KeyList.Items[ThisItem];
  345.     end;
  346.   end
  347.   else
  348.   begin
  349.     Result := '';
  350.   end;
  351. end;
  352.  
  353. procedure TAB_form.AddButtonClick(Sender: TObject);
  354. var
  355.   NewKey: TKey;
  356.   Item: PChar;
  357.   ItemLen: word;
  358. begin
  359.   NewKey := NameToKey(AddBox.Lines[0]);
  360.   if NewKey <> '' then
  361.   begin
  362.     if NewKey <> CurrentKey then {Add}
  363.     begin
  364.       GetMem(Item, MaxSize);
  365.       try
  366.         ScreenToItem(Item, ItemLen);
  367.         Addresses.AddItem(Item, ItemLen, NewKey);
  368.       finally
  369.         FreeMem(Item, Maxsize);
  370.       end;
  371.       Addresses.AssignKeyList(KeyList.Items);
  372.       KeyList.ItemIndex := KeyList.Items.IndexOf(NewKey);
  373.     end
  374.     else {Change}
  375.     begin
  376.       GetMem(Item, MaxSize);
  377.       try
  378.         ScreenToItem(Item, ItemLen);
  379.         if Addresses.ExactMatch(NewKey) then
  380.           Addresses.ChangeItem(Item, ItemLen);
  381.       finally
  382.         FreeMem(Item, MaxSize);
  383.       end;
  384.     end;
  385.   end
  386.   else
  387.   begin
  388.     ShowMessage('No address to add');
  389.   end;
  390. end;
  391.  
  392. procedure TAB_form.ClearButtonClick(Sender: TObject);
  393. begin
  394.   BlankEntries;
  395. end;
  396.  
  397. procedure TAB_form.DeleteButtonClick(Sender: TObject);
  398. var
  399.   ThisItem: integer;
  400.   KeyToGo: string;
  401. begin
  402.   ThisItem := KeyList.ItemIndex;
  403.   if ThisItem <> -1 then
  404.   begin
  405.     KeyToGo := KeyList.Items[ThisItem];
  406.     if Addresses.ExactMatch(KeyToGo) then
  407.     begin
  408.       Addresses.DeleteItem;
  409.       Addresses.AssignKeyList(KeyList.Items);
  410.     end;
  411.   end;
  412.   if ThisItem >= KeyList.Items.Count then
  413.   begin
  414.     dec(ThisItem);
  415.   end;
  416.   KeyList.ItemIndex := ThisItem;
  417.   MyUpdate;
  418. end;
  419.  
  420. procedure TAB_form.KeyListClick(Sender: TObject);
  421. begin
  422.   MyUpdate;
  423. end;
  424.  
  425. procedure TAB_form.MyUpdate;
  426. var
  427.   ThisKey: TKey;
  428.   ThisItem: PChar;
  429. begin
  430.   ThisKey := CurrentKey;
  431.   if Addresses.ExactMatch(ThisKey) then
  432.   begin
  433.     ThisItem := StrAlloc(Addresses.ItemSize);
  434.     ItemToScreen(ThisItem);
  435.     StrDispose(ThisItem);
  436.   end
  437.   else
  438.   begin
  439.     BlankEntries;
  440.   end;
  441. end;
  442.  
  443. procedure TAB_form.AddressesProgressUpdate(Sender: TObject;
  444.   Percent: TPercentage; Kind: TProgressOrigin);
  445. begin
  446.   StatusLine.Caption := IntToStr(Percent);
  447. end;
  448.  
  449. end.
  450.  
  451.