home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 2000 May / PCP163A.iso / handson / files / copydelp.exe / td.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-12-22  |  9.6 KB  |  322 lines

  1. unit td;
  2. {
  3. Sample ToDo list application for PC Plus's Delphi Workshop
  4. Author: Huw Collingbourne
  5. Compatibility: Delphi 3 Standard or above
  6.  
  7. Changes/Additions to the application developed in the previous
  8. issue of PC Plus.
  9. * In DBGrid the data is now sorted when a column header is clicked
  10. * Filters have been added.
  11. * Drop-down PickLists added to selected fields
  12. * CheckBox toggles row-select or edit in grid
  13. * Button by Dates loads Calendar for date-picking
  14. * 2nd table of categories has been added
  15. * sub-Form lets user pick date from calendar (when editing in Grid)
  16. * sub-Form lets user manage catagories (add, delete or select)
  17. * DBLookupComboBox displays picklist of Types from Categories table
  18.  
  19. NOTE: In a finished application you would need to add exception-handling to
  20.       recover gracefully from invalid input (e.g. if the user enters an
  21.       invalid value into one of the columns of the DBGrid).
  22. }
  23. interface
  24.  
  25. uses
  26.   SysUtils, Windows, Messages, Classes, Graphics, Controls,
  27.   StdCtrls, Forms, DBCtrls, DB, DBTables, Mask, ExtCtrls, ComCtrls, Grids,
  28.   DBGrids, Dialogs;
  29.  
  30. type
  31.   TToDoForm = class(TForm)
  32.     ToDoTableItemNumber: TAutoIncField;
  33.     ToDoTableItem: TStringField;
  34.     ToDoTablePriority: TSmallintField;
  35.     ToDoTableType: TStringField;
  36.     ToDoTableDateentered: TDateField;
  37.     ToDoTableDatedue: TDateField;
  38.     ToDoTableDone: TBooleanField;
  39.     ToDoTableNotes: TBlobField;
  40.     ScrollBox: TScrollBox;
  41.     Label1: TLabel;
  42.     EditItemNumber: TDBEdit;
  43.     Label2: TLabel;
  44.     EditItem: TDBEdit;
  45.     Label4: TLabel;
  46.     Label5: TLabel;
  47.     Label6: TLabel;
  48.     Label7: TLabel;
  49.     CheckBoxDone: TDBCheckBox;
  50.     Label8: TLabel;
  51.     DBNavigator: TDBNavigator;
  52.     Panel1: TPanel;
  53.     ToDoDataSource: TDataSource;
  54.     Panel2: TPanel;
  55.     ToDoTable: TTable;
  56.     DBRichEdit1: TDBRichEdit;
  57.     DTPDateEntered: TDateTimePicker;
  58.     DBRadioGroup1: TDBRadioGroup;
  59.     DTPDatedue: TDateTimePicker;
  60.     Panel3: TPanel;
  61.     DBGrid1: TDBGrid;
  62.     GridEditCB: TCheckBox;
  63.     GroupBox1: TGroupBox;
  64.     Label3: TLabel;
  65.     Label9: TLabel;
  66.     OverdueCB: TCheckBox;
  67.     ApplyFilterBtn: TButton;
  68.     PriorityCombo: TComboBox;
  69.     RemoveFilterBtn: TButton;
  70.     TypeCombo: TComboBox;
  71.     DBLookupComboBox1: TDBLookupComboBox;
  72.     CategoriesDataSource: TDataSource;
  73.     CategoriesTable: TTable;
  74.     CategoriesTableType: TStringField;
  75.     LoadCatAddBtn: TButton;
  76.     procedure FormCreate(Sender: TObject);
  77.     procedure DTPDateEnteredChange(Sender: TObject);
  78.     procedure DBRichEdit1KeyUp(Sender: TObject; var Key: Word;
  79.       Shift: TShiftState);
  80.     procedure ItemBtnClick(Sender: TObject);
  81.     procedure DoneBtnClick(Sender: TObject);
  82.     procedure EditDateenteredExit(Sender: TObject);
  83.     procedure DTPDatedueChange(Sender: TObject);
  84.     procedure ToDoTableAfterScroll(DataSet: TDataSet);
  85.     procedure ToDoTableAfterInsert(DataSet: TDataSet);
  86.     procedure PriorityBtnClick(Sender: TObject);
  87.     procedure DBGrid1TitleClick(Column: TColumn);
  88.     procedure ApplyFilterBtnClick(Sender: TObject);
  89.     procedure RemoveFilterBtnClick(Sender: TObject);
  90.     procedure GridEditCBClick(Sender: TObject);
  91.     procedure DBGrid1EditButtonClick(Sender: TObject);
  92.     procedure LoadCatAddBtnClick(Sender: TObject);
  93.   private
  94.     { private declarations }
  95.   public
  96.     { public declarations }
  97.     function AddAnd( s : string ) : string;
  98.     procedure ShowCatAddForm;
  99.     procedure CreateTypeComboList;
  100.   end;
  101.  
  102. var
  103.   ToDoForm: TToDoForm;
  104.  
  105. const
  106.    // These match the TColumn.ID values that identify columns. The
  107.    // ID property (unlike the Index property) stays the same even if
  108.    // columns are moved or deleted.
  109.    ITEMID = 0;
  110.    PRIORITYID = 1;
  111.    TYPEID = 2;
  112.    DATEENTEREDID = 3;
  113.    DATEDUEID = 4;
  114.    DONEID = 5;
  115.  
  116.    PRIORITIES : set of char = ['1','2','3'];
  117.  
  118.    DEFAULT_DBGRID_OPTIONS = [dgTitles..dgCancelOnExit];
  119.    EDITING_DBGRID_OPTIONS = [dgEditing..dgTabs,dgAlwaysShowSelection..dgCancelOnExit];
  120.  
  121. implementation
  122.  
  123. uses dt, catadd;
  124.  
  125. {$R *.DFM}
  126. procedure TToDoForm.CreateTypeComboList;
  127. // build Items list for TypeCombo list to match current Categories table
  128. var
  129.  i : integer;
  130. begin
  131.    TypeCombo.Clear;
  132.    CategoriesTable.First;    // initially, move to 1st record in table
  133.    for i := 0 to CategoriesTable.RecordCount-1 do
  134.    begin
  135.      TypeCombo.Items.Insert(0,CategoriesTableType.Value);
  136.      CategoriesTable.Next;
  137.    end;
  138.    TypeCombo.Items.Insert(0,'Any');
  139.    TypeCombo.Text := 'Any';
  140. end;
  141.  
  142. function TToDoForm.AddAnd( s : string ) : string;
  143. begin
  144.   if s = '' then
  145.      result := s
  146.   else
  147.      result := s + ' and ';
  148. end;
  149.  
  150. procedure TToDoForm.FormCreate(Sender: TObject);
  151. begin
  152.   ToDoTable.Open;
  153.   CreateTypeComboList;
  154.   DBGrid1.Options := DEFAULT_DBGRID_OPTIONS;
  155. end;
  156.  
  157. procedure TToDoForm.DTPDateEnteredChange(Sender: TObject);
  158. begin
  159.     ToDoDataSource.Edit;   // put into edit mode and assign the date
  160.     ToDoTableDateentered.Value := DTPDateEntered.Date;
  161. end;
  162.  
  163. procedure TToDoForm.DBRichEdit1KeyUp(Sender: TObject; var Key: Word;
  164.   Shift: TShiftState);
  165. begin
  166.    if (ssCtrl in Shift) and (Chr(Key) = 'B') then
  167.    with DBRichEdit1.SelAttributes do
  168.    begin
  169.       if fsBold in Style then
  170.          Style := Style - [fsBold]
  171.       else Style := Style+[fsBold];
  172.    end
  173.    else
  174.    if (ssCtrl in Shift) and (Chr(Key) = 'U') then
  175.    with DBRichEdit1.SelAttributes do
  176.    begin
  177.       if fsUnderline in Style then
  178.          Style := Style - [fsUnderline]
  179.       else Style := Style+[fsUnderline];
  180.    end
  181. end;
  182.  
  183. procedure TToDoForm.ItemBtnClick(Sender: TObject);
  184. begin
  185.    if ToDoTable.IndexName = 'ItemIDX' then
  186.       ToDoTable.IndexName := ''
  187.    else ToDoTable.IndexName := 'ItemIDX';
  188. end;
  189.  
  190. procedure TToDoForm.DoneBtnClick(Sender: TObject);
  191. begin
  192.    if ToDoTable.IndexName = 'DoneIDX' then
  193.       ToDoTable.IndexName := ''
  194.    else ToDoTable.IndexName := 'DoneIDX';
  195. end;
  196.  
  197. procedure TToDoForm.PriorityBtnClick(Sender: TObject);
  198. begin
  199.    if ToDoTable.IndexName = 'PriorityIDX' then
  200.       ToDoTable.IndexName := ''
  201.    else ToDoTable.IndexName := 'PriorityIDX';
  202. end;
  203.  
  204. procedure TToDoForm.EditDateenteredExit(Sender: TObject);
  205. begin
  206.    DTPDateEntered.Date := ToDoTableDateentered.Value;
  207. end;
  208.  
  209. procedure TToDoForm.DTPDatedueChange(Sender: TObject);
  210. begin
  211.     ToDoDataSource.Edit;   // put into edit mode and assign the date
  212.     ToDoTableDatedue.Value := DTPDatedue.Date;
  213. end;
  214.  
  215. procedure TToDoForm.ToDoTableAfterScroll(DataSet: TDataSet);
  216. begin
  217.    DTPDateEntered.Date := ToDoTableDateentered.Value;
  218.    DTPDateDue.Date := ToDoTableDatedue.Value;
  219. end;
  220.  
  221. procedure TToDoForm.ToDoTableAfterInsert(DataSet: TDataSet);
  222. begin
  223.    ToDoTableDateentered.Value := Now;
  224.    ToDoTableDatedue.Value := Now;
  225.    ToDoTablePriority.Value := 2;
  226. end;
  227.  
  228.  
  229. procedure TToDoForm.DBGrid1TitleClick(Column: TColumn);
  230. // Sort data according to which column header has been clicked
  231. begin
  232.    case Column.ID of
  233.      ITEMID: ToDoTable.IndexName := 'ItemIDX';
  234.      PRIORITYID: ToDoTable.IndexName := 'PriorityIDX';
  235.      TYPEID: ToDoTable.IndexName := 'TypeIDX';
  236.      DATEENTEREDID: ToDoTable.IndexName := 'DateEnteredIDX';
  237.      DATEDUEID: ToDoTable.IndexName := 'DateDueIDX';
  238.      DONEID:ToDoTable.IndexName := 'DoneIDX';
  239.      else ShowMessage( 'Error: Invalid Column Header was clicked!');
  240.    end;
  241. end;
  242.  
  243. procedure TToDoForm.ApplyFilterBtnClick(Sender: TObject);
  244. var
  245.    FS : string;
  246. begin
  247.    FS := '';
  248.     // Try to apply a filter if optiuons have been set
  249.    begin       // Create a Filter String, FS
  250.       if OverdueCB.Checked then FS := '(''Done'' = False) and (''Date due'' < ''' + DateToStr(Now) +''')';
  251.       if PriorityCombo.Text[1] in PRIORITIES then FS := AddAnd(FS) + ' (''Priority'' = ' + PriorityCombo.Text[1] +' )';
  252.       if CategoriesTable.FindKey( [TypeCombo.Text]) then FS := AddAnd(FS) + ' (''Type'' = '''+TypeCombo.Text +''' )';
  253.               // Now apply the filter
  254.       // ShowMessage( '['+FS+']' ); //!! Uncomment this to preview filter string
  255.         ToDoTable.Filter := FS;
  256.         ToDoTable.Filtered := true;
  257.    end;
  258.  
  259. end;
  260.  
  261. procedure TToDoForm.RemoveFilterBtnClick(Sender: TObject);
  262. begin
  263.   ToDoTable.Filtered := false;
  264. end;
  265.  
  266. procedure TToDoForm.GridEditCBClick(Sender: TObject);
  267. begin
  268.   if GridEditCB.Checked then
  269.   begin
  270.     DBGrid1.Options := EDITING_DBGRID_OPTIONS;
  271.     ActiveControl := DBGrid1;
  272.   end
  273.   else DBGrid1.Options := DEFAULT_DBGRID_OPTIONS;
  274. end;
  275.  
  276. procedure TToDoForm.DBGrid1EditButtonClick(Sender: TObject);
  277. var
  278.    d : TDateTime;
  279. begin
  280.    if (DBGrid1.SelectedField.FieldName = 'Type') then
  281.       ShowCatAddForm
  282.    else
  283.    if (DBGrid1.SelectedField.FieldName = 'Date entered') or
  284.       (DBGrid1.SelectedField.FieldName = 'Date due') then
  285.    begin
  286.       // if date cell is blank, d := today's date.
  287.       // else d := date in cell
  288.       if DBGrid1.SelectedField.IsNull then
  289.          d := Now
  290.       else
  291.          d := DBGrid1.SelectedField.Value;
  292.       // display calendar form and set its date(s) to d
  293.       with CalendarForm do
  294.       begin
  295.          DateTimePicker1.Date := d;
  296.          SetCalendarDate( d );
  297.       end;
  298.       // if OK button was clicked, set cell to the selected date
  299.       if CalendarForm.ShowModal = mrOK then
  300.       begin
  301.          ToDoDataSource.Edit; // put dataset into edit mode
  302.          DBGrid1.SelectedField.Value := CalendarForm.DateTimePicker1.Date;
  303.       end;
  304.    end;
  305. end;
  306.  
  307. procedure TToDoForm.ShowCatAddForm;
  308. begin
  309.    if CatAddForm.ShowModal = mrOK then
  310.    begin
  311.     ToDoDataSource.Edit;   // put into edit mode and assign the category
  312.     ToDoTableType.Value := CategoriesTableType.Value;
  313.    end;
  314. end;
  315.  
  316. procedure TToDoForm.LoadCatAddBtnClick(Sender: TObject);
  317. begin
  318.    ShowCatAddForm;
  319. end;
  320.  
  321. end.
  322.