{*******************************************************} { } { Responsive Software http://www.responsive.co.nz } { } { Copyright (c) 2003-2006 Responsive Software Limited } { } {*******************************************************} unit Documents; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, BaseFrameUnit, StdCtrls, Grids, ComCtrls, ExtCtrls, DatabaseObjects; type TDocumentsFrame = class(TBaseFrame) StatusLabel: TLabel; HeadingLabel: TLabel; HeadingShape: TShape; Label10: TLabel; NameEdit: TEdit; FindButton: TButton; NewButton: TButton; EditButton: TButton; CancelButton: TButton; SaveButton: TButton; AttachButton: TButton; Label35: TLabel; NotesMemo: TMemo; DetachButton: TButton; IdHeadingLabel: TLabel; IdLabel: TLabel; FileNameHeadingLabel: TLabel; FileNameLabel: TLabel; FileDateTimeHeadingLabel: TLabel; FileDateTimeLabel: TLabel; FileAttributeHeadingLabel: TLabel; FileAttributeLabel: TLabel; FileSizeHeadingLabel: TLabel; FileSizeLabel: TLabel; procedure FindButtonClick(Sender: TObject); procedure NewButtonClick(Sender: TObject); procedure EditButtonClick(Sender: TObject); procedure CancelButtonClick(Sender: TObject); procedure SaveButtonClick(Sender: TObject); procedure NameEditKeyPress(Sender: TObject; var Key: Char); procedure NameEditChange(Sender: TObject); procedure AttachButtonClick(Sender: TObject); procedure NotesMemoChange(Sender: TObject); procedure NotesMemoKeyPress(Sender: TObject; var Key: Char); procedure DetachButtonClick(Sender: TObject); private { Private declarations } EditMode : boolean; // true if editing, otherwise view mode assumed IgnoreChangeEvents : boolean; // set this to true when updating controls in code // Document refers to the document currently being viewed or edited Document : TDocument; procedure UpdateLabels; procedure UpdateControls; procedure UpdateControlStates; procedure CancelChanges; procedure SaveChanges; function NewDocument : boolean; public { Public declarations } procedure UpdateDisplay; procedure UpdateComboBoxes (Full : boolean); override; procedure Setup; override; function CanClose : boolean; override; procedure HandleEscape; override; end; implementation uses GeneralUtilities, DatabaseManager, Globals, Base, Utilities, Main, Entries, PromptString, CommunicationsManager; {$R *.dfm} // return true if new document function TDocumentsFrame.NewDocument : boolean; begin // it is a new document if the Id field has not yet been assigned Result := (Document <> nil) and (Document.Id = 0); end; procedure TDocumentsFrame.CancelChanges; var TempDocument : TDocument; begin // if this is an existing document then reload from database if (Document <> nil) and (Document.Id <> 0) then TempDocument := TDocument(LoadDatabaseObject(TDocument,Document.Id)) else TempDocument := nil; Document.Free; Document := TempDocument; UnlockDatabaseObject(Document); // switch to view mode EditMode := false; UpdateDisplay; if FindButton.Enabled then FindButton.SetFocus; end; procedure TDocumentsFrame.SaveChanges; begin if Document = nil then Exit; // save to database if ClientMode then ClientCommunicator.ShowProgress := true; Document.FullSaveToDatabase(true); if ClientMode then ClientCommunicator.ShowProgress := false; UnlockDatabaseObject(Document); // ensure that attachment is also saved in local // attachment cache when we are in client mode Document.Attachment.LocalSave; // switch to view mode EditMode := false; UpdateDisplay; if FindButton.Enabled then FindButton.SetFocus; end; function TDocumentsFrame.CanClose : boolean; begin if EditMode then Result := false else Result := true; end; procedure TDocumentsFrame.HandleEscape; begin if EditMode then if MessageDlg('Do you wish to cancel changes to this document?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then CancelChanges; end; procedure TDocumentsFrame.Setup; begin // create and initialise objects EditMode := false; UpdateComboBoxes(false); UpdateDisplay; end; procedure TDocumentsFrame.UpdateComboBoxes (Full : boolean); begin end; procedure TDocumentsFrame.UpdateLabels; begin if (Document <> nil) and (Document.Attachment.FileName <> '') then begin IdHeadingLabel.Visible := true; FileNameHeadingLabel.Visible := true; FileDateTimeHeadingLabel.Visible := true; FileAttributeHeadingLabel.Visible := true; FileSizeHeadingLabel.Visible := true; if Document.Attachment.AttachmentId <> 0 then IdLabel.Caption := IntToStr(Document.Attachment.AttachmentId) else IdLabel.Caption := ''; FileNameLabel.Caption := Document.Attachment.FileName; FileDateTimeLabel.Caption := FormatDate(Document.Attachment.FileDateTime); FileAttributeLabel.Caption := FormatFileAttribute(Document.Attachment.FileAttribute); if Document.Attachment.FileSize = 1 then FileSizeLabel.Caption := '1 byte' else FileSizeLabel.Caption := AddCommasToNumber(IntToStr(Document.Attachment.FileSize)) + ' bytes'; end else begin IdHeadingLabel.Visible := false; FileNameHeadingLabel.Visible := false; FileDateTimeHeadingLabel.Visible := false; FileAttributeHeadingLabel.Visible := false; FileSizeHeadingLabel.Visible := false; IdLabel.Caption := ''; FileNameLabel.Caption := ''; FileDateTimeLabel.Caption := ''; FileAttributeLabel.Caption := ''; FileSizeLabel.Caption := ''; end; end; procedure TDocumentsFrame.UpdateControls; begin IgnoreChangeEvents := true; if Document <> nil then begin NameEdit.Text := Document.Name; NotesMemo.Text := Document.Notes.AsString; end else begin NameEdit.Text := ''; NotesMemo.Text := ''; end; UpdateLabels; IgnoreChangeEvents := false; end; procedure TDocumentsFrame.UpdateControlStates; begin FindButton.Enabled := not EditMode; NameEdit.Enabled := EditMode; NotesMemo.Enabled := EditMode; AttachButton.Enabled := EditMode; DetachButton.Enabled := (not EditMode) and (Document <> nil) and (Document.Attachment.AttachmentId <> 0); // display status label if EditMode then begin if NewDocument then StatusLabel.Caption := 'New Document' else StatusLabel.Caption := 'Edit Mode' end else StatusLabel.Caption := ''; NewButton.Enabled := not EditMode; EditButton.Enabled := (not EditMode) and (Document <> nil) and (not NewDocument); CancelButton.Enabled := EditMode; SaveButton.Enabled := EditMode; end; procedure TDocumentsFrame.UpdateDisplay; begin UpdateControls; UpdateControlStates; end; {******************************************************************************} procedure TDocumentsFrame.FindButtonClick(Sender: TObject); var TempDocument : TDocument; begin TempDocument := FindDocument; if TempDocument <> nil then begin // destroy existing document Document.Free; Document := TempDocument; EditMode := false; UpdateComboBoxes(false); UpdateDisplay; end; end; procedure TDocumentsFrame.NewButtonClick(Sender: TObject); begin // destroy any existing document Document.Free; // create new document Document := TDocument.Create; EditMode := true; UpdateComboBoxes(false); UpdateDisplay; if NameEdit.Enabled then NameEdit.SetFocus; end; procedure TDocumentsFrame.EditButtonClick(Sender: TObject); var TempDocument : TDocument; begin if (Document <> nil) and LockDatabaseObject(Document) then begin // reload to ensure we have the latest info TempDocument := TDocument(LoadDatabaseObject(TDocument,Document.Id)); Document.Free; Document := TempDocument; EditMode := true; UpdateComboBoxes(false); UpdateDisplay; if NameEdit.Enabled then NameEdit.SetFocus; end; end; procedure TDocumentsFrame.CancelButtonClick(Sender: TObject); begin CancelChanges; end; procedure TDocumentsFrame.SaveButtonClick(Sender: TObject); begin SaveChanges; end; {***** NameEdit event handling ************************************************} procedure TDocumentsFrame.NameEditKeyPress(Sender: TObject; var Key: Char); begin if Key = Char(VK_RETURN) then begin if Trim(TEdit(Sender).Text) = '' then Exit; TBaseForm(Parent).GoToNextControl; Key := Char(0); end; end; procedure TDocumentsFrame.NameEditChange(Sender: TObject); begin if IgnoreChangeEvents then Exit; if Document = nil then Exit; Document.Name := TEdit(Sender).Text; end; {***** NotesMemo event handling ***********************************************} procedure TDocumentsFrame.NotesMemoKeyPress(Sender: TObject; var Key: Char); begin if Key = Char(VK_RETURN) then begin if Trim(TMemo(Sender).Text) <> '' then Exit; TBaseForm(Parent).GoToNextControl; Key := Char(0); end; end; procedure TDocumentsFrame.NotesMemoChange(Sender: TObject); begin if IgnoreChangeEvents then Exit; if Document = nil then Exit; Document.Notes.SetString(Trim(TMemo(Sender).Text)); end; {***** AttachButton event handling ********************************************} procedure TDocumentsFrame.AttachButtonClick(Sender: TObject); var FileName : string; begin if Document = nil then Exit; FileName := GetRegistryString('DocumentAttachmentLocation'); if ChooseFileOpen(FileName,'Select File Attachment','Any file (*.*)|*.*') then if Document.Attachment.SetFile(FileName) then begin UpdateLabels; if NameEdit.Text = '' then NameEdit.Text := ExtractFileName(FileName); if NotesMemo.Text = '' then NotesMemo.SetFocus; SaveRegistryString('DocumentAttachmentLocation',ExtractFilePath(FileName)); end; end; {***** DetachButton event handling ********************************************} procedure TDocumentsFrame.DetachButtonClick(Sender: TObject); var FileName : string; begin if Document = nil then Exit; FileName := GetRegistryString('DocumentDetachmentLocation'); FileName := FileName + Document.Attachment.FileName; if ChooseFileSave(FileName,'Save File As','Any file (*.*)|*.*') then begin if (not FileExists(FileName)) or (MessageDlg('Overwrite existing file?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then begin if ClientMode then ClientCommunicator.ShowProgress := true; if Document.Attachment.GetFile(FileName) then SaveRegistryString('DocumentDetachmentLocation',ExtractFilePath(FileName)) else MessageDlg('Unable to retrieve attachment',mtError,[mbOk],0); if ClientMode then ClientCommunicator.ShowProgress := false; end; end; end; {******************************************************************************} end.