{*******************************************************} { } { Responsive Software http://www.responsive.co.nz } { } { Copyright (c) 2003-2006 Responsive Software Limited } { } {*******************************************************} unit Items; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, BaseFrameUnit, StdCtrls, Grids, ComCtrls, ExtCtrls, DatabaseObjects; type TItemsFrame = class(TBaseFrame) StatusLabel: TLabel; HeadingLabel: TLabel; HeadingShape: TShape; Label10: TLabel; NameEdit: TEdit; FindButton: TButton; Label16: TLabel; LookupCodesListBox: TListBox; NewButton: TButton; EditButton: TButton; CancelButton: TButton; SaveButton: TButton; Label13: TLabel; PriceEdit: TEdit; Label1: TLabel; LookupCodeEdit: TEdit; ActiveCheckBox: TCheckBox; PictureImage: TImage; BrowseButton: TButton; IdHeadingLabel: TLabel; IdLabel: 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 PriceEditKeyPress(Sender: TObject; var Key: Char); procedure PriceEditChange(Sender: TObject); procedure LookupCodesListBoxKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure LookupCodeEditKeyPress(Sender: TObject; var Key: Char); procedure ActiveCheckBoxClick(Sender: TObject); procedure ActiveCheckBoxKeyPress(Sender: TObject; var Key: Char); procedure BrowseButtonClick(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 // Item refers to the item currently being viewed or edited Item : TItem; // copy of lookup codes before editing LookupCodes : TDatabaseObjectCollection; procedure UpdateLabels; procedure UpdateControls; procedure UpdateControlStates; procedure CancelChanges; procedure SaveChanges; function NewItem : boolean; procedure CopyLookupCodes; procedure AddLookupCode (Code : string); public { Public declarations } procedure UpdateDisplay; procedure UpdateComboBoxes (Full : boolean); override; procedure Setup; override; function CanClose : boolean; override; procedure HandleEscape; override; procedure HandleF6; override; end; implementation uses GeneralUtilities, DatabaseManager, Globals, Base, Utilities, Main, Entries, PromptString, CommunicationsManager; {$R *.dfm} procedure TItemsFrame.CopyLookupCodes; var i : integer; begin LookupCodes.Clear; if Item <> nil then begin for i := 0 to Item.LookupCodes.Count - 1 do LookupCodes.Update(Item.LookupCodes[i]); end; end; procedure TItemsFrame.AddLookupCode (Code : string); var LookupCode : TLookupCode; begin if LookupCodesListBox.Items.IndexOf(Code) = -1 then begin LookupCodesListBox.AddItem(Code,nil); LookupCode := TLookupCode.Create; LookupCode.Code := Code; Item.LookupCodes.Add(LookupCode); end; end; // return true if new item function TItemsFrame.NewItem : boolean; begin // it is a new item if the Id field has not yet been assigned Result := (Item <> nil) and (Item.Id = 0); end; procedure TItemsFrame.CancelChanges; var TempItem : TItem; begin // if this is an existing item then reload from database if (Item <> nil) and (Item.Id <> 0) then TempItem := TItem(LoadDatabaseObject(TItem,Item.Id)) else TempItem := nil; Item.Free; Item := TempItem; UnlockDatabaseObject(Item); // switch to view mode EditMode := false; UpdateDisplay; if FindButton.Enabled then FindButton.SetFocus; end; procedure TItemsFrame.SaveChanges; var i : integer; Str : string; begin if Item = nil then Exit; // if a lookup code has been entered then add it now Str := Trim(LookupCodeEdit.Text); if Str <> '' then AddLookupCode(Str); // save to database Item.FullSaveToDatabase(true); UnlockDatabaseObject(Item); // ensure that picture is also saved in local // attachment cache when we are in client mode Item.Picture.LocalSave; // reload lookup codes from database Item.ReloadLookupCodes; // notify workstations of deleted lookup codes for i := 0 to LookupCodes.Count - 1 do if Item.LookupCodes.ObjectsById[LookupCodes[i].Id] = nil then DeleteDatabaseObjectFromLoggedOnWorkstations(TLookupCode,LookupCodes[i].Id); // notify workstations of new lookup codes for i := 0 to Item.LookupCodes.Count - 1 do if LookupCodes.ObjectsById[Item.LookupCodes[i].Id] = nil then UpdateDatabaseObjectOnLoggedOnWorkstations(TLookupCode,Item.LookupCodes[i]); // switch to view mode EditMode := false; UpdateDisplay; if FindButton.Enabled then FindButton.SetFocus; end; function TItemsFrame.CanClose : boolean; begin if EditMode then Result := false else Result := true; end; procedure TItemsFrame.HandleEscape; begin if EditMode then if MessageDlg('Do you wish to cancel changes to this item?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then CancelChanges; end; procedure TItemsFrame.HandleF6; begin MainForm.SwitchToFrame('Sales'); end; procedure TItemsFrame.Setup; begin // create and initialise objects EditMode := false; UpdateComboBoxes(false); UpdateDisplay; LookupCodes := TDatabaseObjectCollection.Create; LookupCodes.Owned := true; end; procedure TItemsFrame.UpdateComboBoxes (Full : boolean); begin end; procedure TItemsFrame.UpdateLabels; begin if (Item <> nil) and (Item.Picture.AttachmentId <> 0) then begin IdHeadingLabel.Visible := true; IdLabel.Caption := IntToStr(Item.Picture.AttachmentId) end else begin IdHeadingLabel.Visible := false; IdLabel.Caption := ''; end; end; procedure TItemsFrame.UpdateControls; var i : integer; begin IgnoreChangeEvents := true; if Item <> nil then begin NameEdit.Text := Item.Name; PriceEdit.Text := ConvertDoubleToString(Item.Price); LookupCodesListBox.Clear; for i := 0 to Item.LookupCodes.Count - 1 do LookupCodesListBox.AddItem(TLookupCode(Item.LookupCodes[i]).Code,nil); LoadImageFromFile(PictureImage,Item.Picture.FileName,Item.Picture.FileContents); ActiveCheckBox.Checked := NewItem or Item.Active; end else begin NameEdit.Text := ''; PriceEdit.Text := ''; LookupCodesListBox.Clear; PictureImage.Picture := nil; ActiveCheckBox.Checked := false; end; LookupCodeEdit.Text := ''; UpdateLabels; IgnoreChangeEvents := false; end; procedure TItemsFrame.UpdateControlStates; begin FindButton.Enabled := not EditMode; NameEdit.Enabled := EditMode; PriceEdit.Enabled := EditMode; LookupCodeEdit.Enabled := EditMode; BrowseButton.Enabled := EditMode; ActiveCheckBox.Enabled := EditMode and (Item <> nil) and (not NewItem); // display status label if EditMode then begin if NewItem then StatusLabel.Caption := 'New Item' else StatusLabel.Caption := 'Edit Mode' end else StatusLabel.Caption := ''; NewButton.Enabled := not EditMode; EditButton.Enabled := (not EditMode) and (Item <> nil) and (not NewItem); CancelButton.Enabled := EditMode; SaveButton.Enabled := EditMode; end; procedure TItemsFrame.UpdateDisplay; begin UpdateControls; UpdateControlStates; end; {******************************************************************************} procedure TItemsFrame.FindButtonClick(Sender: TObject); var TempItem : TItem; begin TempItem := FindItem; if TempItem <> nil then begin // destroy existing item Item.Free; Item := TempItem; EditMode := false; UpdateComboBoxes(false); UpdateDisplay; end; end; procedure TItemsFrame.NewButtonClick(Sender: TObject); begin // destroy any existing item Item.Free; // create new item Item := TItem.Create; CopyLookupCodes; EditMode := true; UpdateComboBoxes(false); UpdateDisplay; if NameEdit.Enabled then NameEdit.SetFocus; end; procedure TItemsFrame.EditButtonClick(Sender: TObject); var TempItem : TItem; begin if (Item <> nil) and LockDatabaseObject(Item) then begin // reload to ensure we have the latest info TempItem := TItem(LoadDatabaseObject(TItem,Item.Id)); Item.Free; Item := TempItem; CopyLookupCodes; EditMode := true; UpdateComboBoxes(false); UpdateDisplay; if LookupCodeEdit.Enabled then LookupCodeEdit.SetFocus; end; end; procedure TItemsFrame.CancelButtonClick(Sender: TObject); begin CancelChanges; end; procedure TItemsFrame.SaveButtonClick(Sender: TObject); begin SaveChanges; end; {***** NameEdit event handling ************************************************} procedure TItemsFrame.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 TItemsFrame.NameEditChange(Sender: TObject); begin if IgnoreChangeEvents then Exit; if Item = nil then Exit; Item.Name := TEdit(Sender).Text; end; {***** PriceEdit event handling ***********************************************} procedure TItemsFrame.PriceEditKeyPress(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 TItemsFrame.PriceEditChange(Sender: TObject); begin if IgnoreChangeEvents then Exit; if Item = nil then Exit; Item.Price := ConvertStringToDouble(TEdit(Sender).Text); end; {***** LookupCodesListBox event handling **************************************} procedure TItemsFrame.LookupCodesListBoxKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var Index : integer; i : integer; begin // Del is used to delete lookup code if Key = VK_DELETE then begin if EditMode and (Item <> nil) then begin Index := -1; for i := 0 to TListBox(Sender).Items.Count - 1 do if TListBox(Sender).Selected[i] then begin Index := i; break; end; if Index <> -1 then begin Item.LookupCodes.Delete(Index); TListBox(Sender).DeleteSelected; end; end; Key := 0; end; end; {***** LookupCodeEdit event handling ******************************************} procedure TItemsFrame.LookupCodeEditKeyPress(Sender: TObject; var Key: Char); var Str : string; begin if Key = Char(VK_RETURN) then begin Str := Trim(TEdit(Sender).Text); if (Str <> '') and (Item <> nil) then AddLookupCode(Str); TEdit(Sender).Text := ''; Key := Char(0); end; end; {***** BrowseButton event handling ********************************************} procedure TItemsFrame.BrowseButtonClick(Sender: TObject); var FileName : string; begin if Item = nil then Exit; FileName := GetRegistryString('ItemPictureLocation'); if ChoosePicture(FileName) then begin if Item.Picture.SetFile(FileName) then begin UpdateLabels; LoadImageFromFile(PictureImage,Item.Picture.FileName,Item.Picture.FileContents); SaveRegistryString('ItemPictureLocation',ExtractFilePath(FileName)); end; end; end; {***** ActiveCheckBox event handling ******************************************} procedure TItemsFrame.ActiveCheckBoxKeyPress(Sender: TObject; var Key: Char); begin if Key = Char(VK_RETURN) then begin TBaseForm(Parent).GoToNextControl; Key := Char(0); end; end; procedure TItemsFrame.ActiveCheckBoxClick(Sender: TObject); begin if IgnoreChangeEvents then Exit; if Item = nil then Exit; Item.Active := TCheckBox(Sender).Checked; end; {******************************************************************************} end.