summaryrefslogtreecommitdiff
path: root/extras
diff options
context:
space:
mode:
authorgraemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf>2008-09-05 22:47:56 +0000
committergraemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf>2008-09-05 22:47:56 +0000
commita89206b6e0221d5cd71c60541b4f273e294396de (patch)
treed13b8c8f3d9c3113a2e22a377843e294b41f5c3d /extras
parent025b1efbc8918cf7765e9687531d27e93f662201 (diff)
downloadfpGUI-a89206b6e0221d5cd71c60541b4f273e294396de.tar.xz
* Started implementing a full Address Book demo, showcasing the new Model-GUI-Mediator implementation. This is still work in progress.
Diffstat (limited to 'extras')
-rw-r--r--extras/tiopf/demos/Demo_21_AdrsBook_MGM/_readme.txt14
-rw-r--r--extras/tiopf/demos/Demo_21_AdrsBook_MGM/contactmanager.pas192
-rw-r--r--extras/tiopf/demos/Demo_21_AdrsBook_MGM/demo_adrsbook_mgm.lpi80
-rw-r--r--extras/tiopf/demos/Demo_21_AdrsBook_MGM/demo_adrsbook_mgm.lpr32
-rw-r--r--extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmcitylist.pas162
-rw-r--r--extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmcontactmaint.pas285
-rw-r--r--extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmmain.pas181
-rw-r--r--extras/tiopf/demos/Demo_21_AdrsBook_MGM/model.pas564
8 files changed, 1510 insertions, 0 deletions
diff --git a/extras/tiopf/demos/Demo_21_AdrsBook_MGM/_readme.txt b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/_readme.txt
new file mode 100644
index 00000000..51897ba0
--- /dev/null
+++ b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/_readme.txt
@@ -0,0 +1,14 @@
+ToDo:
+ This demo must be modified for the latest structure in Adrs_bom.pas
+
+ This demo implements a Address Book. It uses standard components
+ and the Model-GUI-Mediator pattern to make those components
+ object-aware.
+
+ This demo is still work in progress... Not complete!
+
+
+ Graeme Geldenhuys
+
+
+
diff --git a/extras/tiopf/demos/Demo_21_AdrsBook_MGM/contactmanager.pas b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/contactmanager.pas
new file mode 100644
index 00000000..d9b61a44
--- /dev/null
+++ b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/contactmanager.pas
@@ -0,0 +1,192 @@
+unit contactmanager;
+
+{$IFDEF FPC}
+ {$mode objfpc}{$H+}
+{$ENDIF}
+
+interface
+
+uses
+ model;
+
+type
+
+ { TContactManager }
+
+ TContactManager = class(TMarkObject)
+ private
+ FCityList: TCityList;
+ FContactList: TContactList;
+ FCountryList: TCountryList;
+ procedure PopulateCountries;
+ procedure PopulateCities;
+ function GenPhone: string;
+ public
+ constructor Create; override;
+ destructor Destroy; override;
+ procedure PopulateContacts;
+ published
+ property CountryList: TCountryList read FCountryList;
+ property CityList: TCityList read FCityList;
+ property ContactList: TContactList read FContactList;
+ end;
+
+
+// Global singleton
+function gContactManager: TContactManager;
+
+
+implementation
+
+uses
+ SysUtils;
+
+var
+ uContactManager: TContactManager;
+
+const
+ LastNames: array[1..10] of string = ('Geldenhuys', 'Botha', 'Johnson', 'Fourie',
+ 'Louw', 'Bougas', 'van der Mescht', 'Waskanski', 'Welgens', 'Viljoen');
+
+ FirstNames: array[1..10] of string = ('Graeme', 'Johan', 'Debbie', 'Freda',
+ 'Jack', 'Ryno', 'Dirkus', 'Angela', 'Denise', 'Daniel');
+
+ StreetNames: array[1..11] of string = ('Stellenberg Rd', 'Stellendal Rd',
+ 'Abelia', 'Main Rd', 'Links Drive', 'Short Street',
+ 'Long Street', 'Loop Street', 'Hillside Rd', 'Mountain Rd', 'Beach Drive');
+
+function gContactManager: TContactManager;
+begin
+ if not Assigned(uContactManager) then
+ uContactManager:= TContactManager.Create;
+ result:= uContactManager;
+end;
+
+{ TContactManager }
+
+procedure TContactManager.PopulateCountries;
+begin
+ FCountryList.Add(TCountry.CreateNew('za', 'South Africa'));
+ FCountryList.Add(TCountry.CreateNew('gb', 'Great Britain'));
+ FCountryList.Add(TCountry.CreateNew('uk', 'Ukrain'));
+ FCountryList.Add(TCountry.CreateNew('fr', 'France'));
+ FCountryList.Add(TCountry.CreateNew('us', 'United States'));
+ FCountryList.Add(TCountry.CreateNew('gr', 'Germany'));
+end;
+
+procedure TContactManager.PopulateCities;
+var
+ c: TCity;
+begin
+ c:= TCity.CreateNew;
+ c.Name:= 'Somerset West';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['za'], True));
+ FCityList.Add(c);
+ c:= TCity.CreateNew;
+ c.Name:= 'Cape Town';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['za'], True));
+ FCityList.Add(c);
+ c:= TCity.CreateNew;
+ c.Name:= 'Pretoria';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['za'], True));
+ FCityList.Add(c);
+ c:= TCity.CreateNew;
+ c.Name:= 'Durban';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['za'], True));
+ FCityList.Add(c);
+ c:= TCity.CreateNew;
+ c.Name:= 'London';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['gb'], True));
+ FCityList.Add(c);
+ c:= TCity.CreateNew;
+ c.Name:= 'Watford';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['gb'], True));
+ FCityList.Add(c);
+ c:= TCity.CreateNew;
+ c.Name:= 'Frankfurt';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['gr'], True));
+ FCityList.Add(c);
+ c:= TCity.CreateNew;
+ c.Name:= 'New York';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['us'], True));
+ FCityList.Add(c);
+ c:= TCity.CreateNew;
+ c.Name:= 'San Fransisco';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['us'], True));
+ FCityList.Add(c);
+ c:= TCity.CreateNew;
+ c.Name:= 'Paris';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['fr'], True));
+ FCityList.Add(c);
+ c:= TCity.CreateNew;
+ c.Name:= 'Big City';
+ c.Country:= TCountry(FCountryList.FindByProps(['ISO'], ['uk'], True));
+ FCityList.Add(c);
+end;
+
+function TContactManager.GenPhone: string;
+begin
+ result:= '+27 ' + IntToStr(Random(9)) + IntToStr(Random(9)) + ' '
+ + IntToStr(Random(9)) + IntToStr(Random(9)) + IntToStr(Random(9)) + '-'
+ + IntToStr(Random(9)) + IntToStr(Random(9)) + IntToStr(Random(9)) + IntToStr(Random(9));
+end;
+
+constructor TContactManager.Create;
+begin
+ inherited Create;
+ FCountryList:= TCountryList.Create;
+ FCountryList.Owner:= self;
+ FCityList:= TCityList.Create;
+ FCityList.Owner:= self;
+ FContactList:= TContactList.Create;
+ FContactList.Owner:= self;
+end;
+
+destructor TContactManager.Destroy;
+begin
+ FContactList.Free;
+ FCityList.Free;
+ FCountryList.Free;
+ inherited Destroy;
+end;
+
+procedure TContactManager.PopulateContacts;
+var
+ C: TContact;
+ I,J: Integer;
+ A: TAddress;
+begin
+ PopulateCountries;
+ PopulateCities;
+ for I:= 1 to 10 do
+ begin
+ C:= TContact.CreateNew;
+ C.FirstName:= FirstNames[I];
+ C.LastName := LastNames[I];
+ C.Mobile := GenPhone;
+ C.Email := LowerCase(FirstNames[i])+ '@freepascal.org';
+ for J:= 1 to 1+Random(2) do
+ begin
+ A:= TAddress.CreateNew;
+ A.Street := StreetNames[1+Random(10)];
+ A.Nr := Random(100)+1;
+ A.City := FCityList[Random(10)];
+ A.Fax := GenPhone;
+ A.Telephone1:= GenPhone;
+ If Random(2)>0 then
+ A.Telephone2:= GenPhone;
+ C.AddressList.Add(A);
+ end;
+ FContactList.Add(C);
+ end;
+end;
+
+
+initialization
+ uContactManager:= nil;
+
+finalization
+ uContactManager.Free;
+
+end.
+
diff --git a/extras/tiopf/demos/Demo_21_AdrsBook_MGM/demo_adrsbook_mgm.lpi b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/demo_adrsbook_mgm.lpi
new file mode 100644
index 00000000..87043803
--- /dev/null
+++ b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/demo_adrsbook_mgm.lpi
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<CONFIG>
+ <ProjectOptions>
+ <PathDelim Value="/"/>
+ <Version Value="6"/>
+ <General>
+ <Flags>
+ <SaveOnlyProjectUnits Value="True"/>
+ </Flags>
+ <SessionStorage Value="InProjectDir"/>
+ <MainUnit Value="0"/>
+ <IconPath Value="./"/>
+ <TargetFileExt Value=""/>
+ </General>
+ <VersionInfo>
+ <ProjectVersion Value=""/>
+ </VersionInfo>
+ <PublishOptions>
+ <Version Value="2"/>
+ <IgnoreBinaries Value="False"/>
+ <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+ <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+ </PublishOptions>
+ <RunParams>
+ <local>
+ <FormatVersion Value="1"/>
+ <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
+ </local>
+ </RunParams>
+ <RequiredPackages Count="1">
+ <Item1>
+ <PackageName Value="tiOPFfpGUI"/>
+ </Item1>
+ </RequiredPackages>
+ <Units Count="6">
+ <Unit0>
+ <Filename Value="demo_adrsbook_mgm.lpr"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="demo_adrsbook_mgm"/>
+ </Unit0>
+ <Unit1>
+ <Filename Value="contactmanager.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="contactmanager"/>
+ </Unit1>
+ <Unit2>
+ <Filename Value="model.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="model"/>
+ </Unit2>
+ <Unit3>
+ <Filename Value="frmmain.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="frmmain"/>
+ </Unit3>
+ <Unit4>
+ <Filename Value="frmcontactmaint.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="frmcontactmaint"/>
+ </Unit4>
+ <Unit5>
+ <Filename Value="frmcitylist.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="frmCityList"/>
+ </Unit5>
+ </Units>
+ </ProjectOptions>
+ <CompilerOptions>
+ <Version Value="8"/>
+ <Parsing>
+ <SyntaxOptions>
+ <CStyleOperator Value="False"/>
+ </SyntaxOptions>
+ </Parsing>
+ <Other>
+ <CustomOptions Value="-FUunits"/>
+ <CompilerPath Value="$(CompPath)"/>
+ </Other>
+ </CompilerOptions>
+</CONFIG>
diff --git a/extras/tiopf/demos/Demo_21_AdrsBook_MGM/demo_adrsbook_mgm.lpr b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/demo_adrsbook_mgm.lpr
new file mode 100644
index 00000000..7dbad7f5
--- /dev/null
+++ b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/demo_adrsbook_mgm.lpr
@@ -0,0 +1,32 @@
+program demo_adrsbook_mgm;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}{$IFDEF UseCThreads}
+ cthreads,
+ {$ENDIF}{$ENDIF}
+ Classes, fpgfx, frmmain, frmcontactmaint, frmCityList;
+
+
+
+procedure MainProc;
+var
+ frm: TMainForm;
+begin
+ fpgApplication.Initialize;
+ frm := TMainForm.Create(nil);
+ try
+ frm.Show;
+ fpgApplication.Run;
+ finally
+ frm.Free;
+ end;
+end;
+
+begin
+ Randomize;
+ MainProc;
+end.
+
+
diff --git a/extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmcitylist.pas b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmcitylist.pas
new file mode 100644
index 00000000..9c83c09d
--- /dev/null
+++ b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmcitylist.pas
@@ -0,0 +1,162 @@
+unit frmCityList;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ SysUtils, Classes, gfxbase, fpgfx, gui_edit,
+ gfx_widget, gui_form, gui_label, gui_button,
+ gui_listbox, gui_memo, gui_combobox, gui_basegrid, gui_grid,
+ gui_dialogs, gui_checkbox, gui_tree, gui_trackbar,
+ gui_progressbar, gui_radiobutton, gui_tab, gui_menu,
+ gui_panel, gui_popupcalendar, gui_gauge,
+ tiFormMediator, model;
+
+type
+
+ TCityListForm = class(TfpgForm)
+ private
+ {@VFD_HEAD_BEGIN: CityListForm}
+ bvlName1: TfpgBevel;
+ btnAdd: TfpgButton;
+ btnEdit: TfpgButton;
+ btnDelete: TfpgButton;
+ grdName1: TfpgStringGrid;
+ btnCancel: TfpgButton;
+ {@VFD_HEAD_END: CityListForm}
+ FData: TCityList;
+ FMediator: TFormMediator;
+ procedure SetData(const AValue: TCityList);
+ procedure SetupMediators;
+ public
+ procedure AfterCreate; override;
+ procedure AfterConstruction; override;
+ property Data: TCityList read FData write SetData;
+ end;
+
+{@VFD_NEWFORM_DECL}
+
+procedure ShowCities(const AList: TCityList);
+
+
+implementation
+
+uses
+ tiListMediators;
+
+
+procedure ShowCities(const AList: TCityList);
+var
+ frm: TCityListForm;
+begin
+ frm := TCityListForm.Create(nil);
+ try
+ frm.SetData(AList);
+ frm.ShowModal;
+ finally;
+ frm.Free;
+ end;
+end;
+
+{@VFD_NEWFORM_IMPL}
+
+procedure TCityListForm.SetupMediators;
+begin
+ if not Assigned(FMediator) then
+ begin
+ FMediator := TFormMediator.Create(self);
+ FMediator.AddComposite('Name(110);Zip(80);CountryAsString(150)', grdName1);
+ end;
+ FMediator.Subject := FData;
+ FMediator.Active := True;
+end;
+
+procedure TCityListForm.SetData(const AValue: TCityList);
+begin
+ if FData=AValue then exit;
+ FData:=AValue;
+ SetupMediators;
+end;
+
+procedure TCityListForm.AfterCreate;
+begin
+ {@VFD_BODY_BEGIN: CityListForm}
+ Name := 'CityListForm';
+ SetPosition(412, 278, 421, 315);
+ WindowTitle := 'City Listing';
+
+ bvlName1 := TfpgBevel.Create(self);
+ with bvlName1 do
+ begin
+ Name := 'bvlName1';
+ SetPosition(0, 0, 420, 36);
+ Anchors := [anLeft,anRight,anTop];
+ Shape := bsSpacer;
+ end;
+
+ btnAdd := TfpgButton.Create(bvlName1);
+ with btnAdd do
+ begin
+ Name := 'btnAdd';
+ SetPosition(12, 4, 52, 24);
+ Text := 'Add';
+ FontDesc := '#Label1';
+ ImageName := '';
+ end;
+
+ btnEdit := TfpgButton.Create(bvlName1);
+ with btnEdit do
+ begin
+ Name := 'btnEdit';
+ SetPosition(68, 4, 52, 24);
+ Text := 'Edit';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 1;
+ end;
+
+ btnDelete := TfpgButton.Create(bvlName1);
+ with btnDelete do
+ begin
+ Name := 'btnDelete';
+ SetPosition(124, 4, 52, 24);
+ Text := 'Delete';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 2;
+ end;
+
+ grdName1 := TfpgStringGrid.Create(self);
+ with grdName1 do
+ begin
+ Name := 'grdName1';
+ SetPosition(8, 40, 404, 220);
+ FontDesc := '#Grid';
+ HeaderFontDesc := '#GridHeader';
+ TabOrder := 1;
+ end;
+
+ btnCancel := TfpgButton.Create(self);
+ with btnCancel do
+ begin
+ Name := 'btnCancel';
+ SetPosition(332, 276, 80, 24);
+ Text := 'Cancel';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 2;
+ ModalResult := mrOK;
+ end;
+
+ {@VFD_BODY_END: CityListForm}
+end;
+
+procedure TCityListForm.AfterConstruction;
+begin
+ inherited AfterConstruction;
+// SetupMediators;
+end;
+
+
+end.
diff --git a/extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmcontactmaint.pas b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmcontactmaint.pas
new file mode 100644
index 00000000..c3dc8496
--- /dev/null
+++ b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmcontactmaint.pas
@@ -0,0 +1,285 @@
+unit frmcontactmaint;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ SysUtils, Classes, gfxbase, fpgfx, gui_edit,
+ gfx_widget, gui_form, gui_label, gui_button,
+ gui_listview, gui_memo,
+ model, tiFormMediator,
+ tiMediators;
+
+type
+
+ TContactEditForm = class(TfpgForm)
+ private
+ FData: TContact;
+ {@VFD_HEAD_BEGIN: ContactEditForm}
+ lblName1: TfpgLabel;
+ edFName: TfpgEdit;
+ lblName2: TfpgLabel;
+ edLName: TfpgEdit;
+ lblName3: TfpgLabel;
+ edEmail: TfpgEdit;
+ lblName4: TfpgLabel;
+ edMobile: TfpgEdit;
+ lblName5: TfpgLabel;
+ meComments: TfpgMemo;
+ lblName6: TfpgLabel;
+ lvAddresses: TfpgListView;
+ btnSave: TfpgButton;
+ btnCancel: TfpgButton;
+ btnAdd: TfpgButton;
+ btnEdit: TfpgButton;
+ btnDelete: TfpgButton;
+ {@VFD_HEAD_END: ContactEditForm}
+ FMediator: TFormMediator;
+ FAdrsMediator: TFormMediator;
+ procedure SetData(const AValue: TContact);
+ procedure SetupMediators;
+ public
+ procedure AfterCreate; override;
+ property Data: TContact read FData write SetData;
+ end;
+
+{@VFD_NEWFORM_DECL}
+
+function EditContact(AData: TContact): Boolean;
+
+
+implementation
+
+uses
+ contactmanager;
+
+
+function EditContact(AData: TContact): Boolean;
+var
+ frm: TContactEditForm;
+begin
+ frm:= TContactEditForm.Create(nil);
+ try
+ frm.SetData(AData);
+ result:= frm.ShowModal = mrOK;
+ finally
+ frm.Free;
+ end;
+end;
+
+
+{@VFD_NEWFORM_IMPL}
+
+procedure TContactEditForm.SetupMediators;
+begin
+ if not Assigned(FMediator) then
+ begin
+ RegisterFallBackMediators;
+ FMediator := TFormMediator.Create(self);
+ FMediator.AddProperty('FirstName', edFName);
+ FMediator.AddProperty('LastName', edLName);
+ FMediator.AddProperty('EMail', edEmail);
+ FMediator.AddProperty('Mobile', edMobile);
+ FMediator.AddProperty('Comments', meComments);
+ end;
+ FMediator.Subject := FData;
+ FMediator.Active := True;
+
+ if not Assigned(FAdrsMediator) then
+ begin
+ FAdrsMediator := TFormMediator.Create(self);
+ FAdrsMediator.AddComposite({'AddressType.Name;}'AddressType4GUI(50,"Type");Nr;Street;Telephone1', lvAddresses);
+ end;
+ FAdrsMediator.Subject := FData.AddressList;
+ FAdrsMediator.Active := True;
+end;
+
+procedure TContactEditForm.SetData(const AValue: TContact);
+begin
+ if FData=AValue then exit;
+ FData:=AValue;
+ SetupMediators;
+end;
+
+procedure TContactEditForm.AfterCreate;
+begin
+ {@VFD_BODY_BEGIN: ContactEditForm}
+ Name := 'ContactEditForm';
+ SetPosition(513, 423, 537, 331);
+ WindowTitle := 'Contact Edit Form';
+
+ lblName1 := TfpgLabel.Create(self);
+ with lblName1 do
+ begin
+ Name := 'lblName1';
+ SetPosition(8, 8, 80, 16);
+ FontDesc := '#Label1';
+ Text := 'Firstname:';
+ end;
+
+ edFName := TfpgEdit.Create(self);
+ with edFName do
+ begin
+ Name := 'edFName';
+ SetPosition(8, 24, 216, 22);
+ TabOrder := 1;
+ Text := '';
+ FontDesc := '#Edit1';
+ end;
+
+ lblName2 := TfpgLabel.Create(self);
+ with lblName2 do
+ begin
+ Name := 'lblName2';
+ SetPosition(8, 52, 80, 16);
+ FontDesc := '#Label1';
+ Text := 'Lastname:';
+ end;
+
+ edLName := TfpgEdit.Create(self);
+ with edLName do
+ begin
+ Name := 'edLName';
+ SetPosition(8, 68, 216, 22);
+ TabOrder := 3;
+ Text := '';
+ FontDesc := '#Edit1';
+ end;
+
+ lblName3 := TfpgLabel.Create(self);
+ with lblName3 do
+ begin
+ Name := 'lblName3';
+ SetPosition(8, 96, 80, 16);
+ FontDesc := '#Label1';
+ Text := 'EMail:';
+ end;
+
+ edEmail := TfpgEdit.Create(self);
+ with edEmail do
+ begin
+ Name := 'edEmail';
+ SetPosition(8, 112, 216, 22);
+ TabOrder := 5;
+ Text := '';
+ FontDesc := '#Edit1';
+ end;
+
+ lblName4 := TfpgLabel.Create(self);
+ with lblName4 do
+ begin
+ Name := 'lblName4';
+ SetPosition(8, 140, 80, 16);
+ FontDesc := '#Label1';
+ Text := 'Mobile:';
+ end;
+
+ edMobile := TfpgEdit.Create(self);
+ with edMobile do
+ begin
+ Name := 'edMobile';
+ SetPosition(8, 156, 216, 22);
+ TabOrder := 7;
+ Text := '';
+ FontDesc := '#Edit1';
+ end;
+
+ lblName5 := TfpgLabel.Create(self);
+ with lblName5 do
+ begin
+ Name := 'lblName5';
+ SetPosition(8, 184, 80, 16);
+ FontDesc := '#Label1';
+ Text := 'Comments:';
+ end;
+
+ meComments := TfpgMemo.Create(self);
+ with meComments do
+ begin
+ Name := 'meComments';
+ SetPosition(8, 200, 216, 80);
+ FontDesc := '#Edit1';
+ TabOrder := 9;
+ end;
+
+ lblName6 := TfpgLabel.Create(self);
+ with lblName6 do
+ begin
+ Name := 'lblName6';
+ SetPosition(264, 8, 80, 16);
+ FontDesc := '#Label1';
+ Text := 'Addresses:';
+ end;
+
+ lvAddresses := TfpgListView.Create(self);
+ with lvAddresses do
+ begin
+ Name := 'lvAddresses';
+ SetPosition(264, 24, 260, 124);
+ ShowHeaders := True;
+ TabOrder := 11;
+ end;
+
+ btnSave := TfpgButton.Create(self);
+ with btnSave do
+ begin
+ Name := 'btnSave';
+ SetPosition(364, 300, 80, 24);
+ Text := 'Save';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 12;
+ ModalResult := mrOK;
+ end;
+
+ btnCancel := TfpgButton.Create(self);
+ with btnCancel do
+ begin
+ Name := 'btnCancel';
+ SetPosition(448, 300, 80, 24);
+ Text := 'Cancel';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 13;
+ ModalResult := mrCancel;
+ end;
+
+ btnAdd := TfpgButton.Create(self);
+ with btnAdd do
+ begin
+ Name := 'btnAdd';
+ SetPosition(264, 152, 52, 24);
+ Text := 'Add';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 14;
+ end;
+
+ btnEdit := TfpgButton.Create(self);
+ with btnEdit do
+ begin
+ Name := 'btnEdit';
+ SetPosition(320, 152, 52, 24);
+ Text := 'Edit';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 15;
+ end;
+
+ btnDelete := TfpgButton.Create(self);
+ with btnDelete do
+ begin
+ Name := 'btnDelete';
+ SetPosition(376, 152, 52, 24);
+ Text := 'Delete';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 16;
+ end;
+
+ {@VFD_BODY_END: ContactEditForm}
+end;
+
+
+end.
diff --git a/extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmmain.pas b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmmain.pas
new file mode 100644
index 00000000..71ed42ca
--- /dev/null
+++ b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/frmmain.pas
@@ -0,0 +1,181 @@
+unit frmmain;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ SysUtils, Classes, gfxbase, fpgfx, gui_edit,
+ gfx_widget, gui_form, gui_label, gui_button,
+ gui_listbox, gui_memo, gui_combobox, gui_basegrid, gui_grid,
+ gui_dialogs, gui_checkbox, gui_tree, gui_trackbar,
+ gui_progressbar, gui_radiobutton, gui_tab, gui_menu,
+ gui_panel, gui_popupcalendar, gui_gauge, tiFormMediator;
+
+type
+
+ TMainForm = class(TfpgForm)
+ private
+ FMediator: TFormMediator;
+
+ {@VFD_HEAD_BEGIN: MainForm}
+ grdContacts: TfpgStringGrid;
+ btnAdd: TfpgButton;
+ btnEdit: TfpgButton;
+ btnDelete: TfpgButton;
+ btnCityList: TfpgButton;
+ btnName5: TfpgButton;
+ {@VFD_HEAD_END: MainForm}
+ procedure FormShow(Sender: TObject);
+ procedure SetupMediators;
+ procedure miEditEditClick(Sender: TObject);
+ procedure btnShowCityList(Sender: TObject);
+ public
+ procedure AfterCreate; override;
+ procedure AfterConstruction; override;
+ constructor Create(AOwner: TComponent); override;
+ end;
+
+{@VFD_NEWFORM_DECL}
+
+implementation
+
+uses
+ model, contactmanager, tiListMediators, tiBaseMediator, frmcontactmaint,
+ frmcitylist, tiDialogs;
+
+{@VFD_NEWFORM_IMPL}
+
+procedure TMainForm.FormShow(Sender: TObject);
+begin
+// do nothing yet
+end;
+
+procedure TMainForm.SetupMediators;
+begin
+ if not Assigned(FMediator) then
+ begin
+ FMediator := TFormMediator.Create(self);
+ FMediator.AddComposite('FirstName;LastName(130);EMail(180);Mobile(130);Comments', grdContacts);
+ end;
+ FMediator.Subject := gContactManager.ContactList;
+ FMediator.Active := True;
+end;
+
+procedure TMainForm.miEditEditClick(Sender: TObject);
+var
+ c: TContact;
+begin
+ c := TContact(TStringGridMediator(FMediator.FindByComponent(grdContacts).Mediator).SelectedObject);
+// tiShowString(c.AsDebugString);
+
+ if not Assigned(c) then
+ Exit; //==>
+
+ if EditContact(c) then
+ begin
+ // we can save contact here
+ end;
+end;
+
+procedure TMainForm.btnShowCityList(Sender: TObject);
+begin
+ ShowCities(gContactManager.CityList);
+end;
+
+procedure TMainForm.AfterCreate;
+begin
+ {@VFD_BODY_BEGIN: MainForm}
+ Name := 'MainForm';
+ SetPosition(373, 273, 708, 456);
+ WindowTitle := 'Demo 21: Address Book Demo using MGM';
+
+ grdContacts := TfpgStringGrid.Create(self);
+ with grdContacts do
+ begin
+ Name := 'grdContacts';
+ SetPosition(20, 36, 516, 336);
+ FontDesc := '#Grid';
+ HeaderFontDesc := '#GridHeader';
+ end;
+
+ btnAdd := TfpgButton.Create(self);
+ with btnAdd do
+ begin
+ Name := 'btnAdd';
+ SetPosition(572, 48, 80, 24);
+ Text := 'Add';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 1;
+ end;
+
+ btnEdit := TfpgButton.Create(self);
+ with btnEdit do
+ begin
+ Name := 'btnEdit';
+ SetPosition(572, 76, 80, 24);
+ Text := 'Edit';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 2;
+ OnClick := @miEditEditClick;
+ end;
+
+ btnDelete := TfpgButton.Create(self);
+ with btnDelete do
+ begin
+ Name := 'btnDelete';
+ SetPosition(572, 104, 80, 24);
+ Text := 'Delete';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 3;
+ end;
+
+ btnCityList := TfpgButton.Create(self);
+ with btnCityList do
+ begin
+ Name := 'btnCityList';
+ SetPosition(576, 164, 80, 24);
+ Text := 'City List';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 4;
+ OnClick := @btnShowCityList;
+ end;
+
+ btnName5 := TfpgButton.Create(self);
+ with btnName5 do
+ begin
+ Name := 'btnName5';
+ SetPosition(576, 192, 80, 24);
+ Text := 'Button';
+ FontDesc := '#Label1';
+ ImageName := '';
+ TabOrder := 5;
+ end;
+
+ {@VFD_BODY_END: MainForm}
+end;
+
+procedure TMainForm.AfterConstruction;
+begin
+ inherited AfterConstruction;
+ SetupMediators;
+end;
+
+constructor TMainForm.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ gContactManager.PopulateContacts;
+ OnShow := @FormShow;
+end;
+
+
+initialization
+ gMediatorManager.RegisterMediator(TStringGridMediator, TContactList);
+ gMediatorManager.RegisterMediator(TListViewMediator, TAddressList);
+ gMediatorManager.RegisterMediator(TStringGridMediator, TCityList);
+
+end.
diff --git a/extras/tiopf/demos/Demo_21_AdrsBook_MGM/model.pas b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/model.pas
new file mode 100644
index 00000000..2e5b52c1
--- /dev/null
+++ b/extras/tiopf/demos/Demo_21_AdrsBook_MGM/model.pas
@@ -0,0 +1,564 @@
+{
+ The business object model
+}
+unit model;
+
+{$IFDEF FPC}
+ {$mode objfpc}{$H+}
+{$ENDIF}
+
+interface
+
+uses
+ Classes, SysUtils, tiObject;
+
+type
+
+ { TMarkObject }
+
+ TMarkObject = class(TtiObject)
+ protected
+ procedure Mark;
+ end;
+
+
+ { TMarkObjectList }
+
+ TMarkObjectList = class(TtiObjectList)
+ protected
+ procedure Mark;
+ end;
+
+
+ { TCountry }
+
+ TCountry = class(TMarkObject)
+ private
+ FISO: string;
+ FName: string;
+ procedure SetISO(const AValue: string);
+ procedure SetName(const AValue: string);
+ protected
+ function GetCaption: string; override;
+ public
+ constructor CreateNew(const AISO: string; const AName: string); overload;
+ published
+ property ISO: string read FISO write SetISO;
+ property Name: string read FName write SetName;
+ end;
+
+
+ { TCountryList }
+
+ TCountryList = class(TMarkObjectList)
+ protected
+ function GetItems(i: integer): TCountry; reintroduce;
+ procedure SetItems(i: integer; const AValue: TCountry); reintroduce;
+ public
+ function Add(const AObject: TCountry): integer; reintroduce;
+ property Items[i: integer]: TCountry read GetItems write SetItems; default;
+ end;
+
+
+ { TCity }
+
+ TCity = class(TMarkObject)
+ private
+ FZIP: string;
+ FName: string;
+ FCountry: TCountry;
+ function GetCountryAsString: string;
+ procedure SetCountry(const AValue: TCountry);
+ procedure SetName(const AValue: string);
+ procedure SetZIP(const AValue: string);
+ public
+ procedure AssignClassProps(ASource: TtiObject); override;
+ published
+ property Country: TCountry read FCountry write SetCountry;
+ property Name: string read FName write SetName;
+ property ZIP: string read FZIP write SetZIP;
+ property CountryAsString: string read GetCountryAsString;
+ end;
+
+
+ { TCityList }
+
+ TCityList = class(TMarkObjectList)
+ protected
+ function GetItems(i: integer): TCity; reintroduce;
+ procedure SetItems(i: integer; const AValue: TCity); reintroduce;
+ public
+ function Add(const AObject: TCity): integer; reintroduce;
+ property Items[i: integer]: TCity read GetItems write SetItems; default;
+ end;
+
+
+ { TAddressType }
+
+ TAddressType = class(TMarkObject)
+ private
+ FName: string;
+ procedure SetName(const AValue: string);
+ published
+ property Name: string read FName write SetName;
+ end;
+
+
+ TAddress = class(TMarkObject)
+ private
+ FAddressType: TAddressType;
+ FCity: TCity;
+ FFax: string;
+ FNr: integer;
+ FStreet: string;
+ FTelephone1: string;
+ FTelephone2: string;
+ function GetAddressType4GUI: string;
+ procedure SetAddressType(const AValue: TAddressType);
+ procedure SetCity(const AValue: TCity);
+ procedure SetFax(const AValue: string);
+ procedure SetNr(const AValue: integer);
+ procedure SetStreet(const AValue: string);
+ procedure SetTelephone1(const AValue: string);
+ procedure SetTelephone2(const AValue: string);
+ public
+ constructor Create; override;
+ destructor Destroy; override;
+ procedure AssignClassProps(ASource: TtiObject); override;
+ published
+ property Street: string read FStreet write SetStreet;
+ property Nr: integer read FNr write SetNr;
+ property Telephone1: string read FTelephone1 write SetTelephone1;
+ property Telephone2: string read FTelephone2 write SetTelephone2;
+ property Fax: string read FFax write SetFax;
+ property AddressType: TAddressType read FAddressType write SetAddressType;
+ property AddressType4GUI: string read GetAddressType4GUI;
+ property City: TCity read FCity write SetCity;
+ end;
+
+
+ { TAddressList }
+
+ TAddressList = class(TMarkObjectList)
+ protected
+ function GetItems(i: integer): TAddress; reintroduce;
+ procedure SetItems(i: integer; const AValue: TAddress); reintroduce;
+ public
+ function Add(const AObject: TAddress): integer; reintroduce;
+ property Items[i: integer]: TAddress read GetItems write SetItems; default;
+ end;
+
+
+ { TContact }
+
+ TContact = class(TMarkObject)
+ private
+ FAddressList: TAddressList;
+ FComments: string;
+ FEmail: string;
+ FFirstName: string;
+ FLastName: string;
+ FMobile: string;
+ procedure SetComments(const AValue: string);
+ procedure SetEmail(const AValue: string);
+ procedure SetFirstName(const AValue: string);
+ procedure SetLastName(const AValue: string);
+ procedure SetMobile(const AValue: string);
+ public
+ constructor Create; override;
+ destructor Destroy; override;
+ published
+ property FirstName: string read FFirstName write SetFirstName;
+ property LastName: string read FLastName write SetLastName;
+ property EMail: string read FEmail write SetEmail;
+ property Mobile: string read FMobile write SetMobile;
+ property Comments: string read FComments write SetComments;
+ property AddressList: TAddressList read FAddressList;
+ end;
+
+
+ { TContactList }
+
+ TContactList = class(TMarkObjectList)
+ protected
+ function GetItems(i: integer): TContact; reintroduce;
+ procedure SetItems(i: integer; const AValue: TContact); reintroduce;
+ public
+ function Add(const AObject: TContact): integer; reintroduce;
+ property Items[i: integer]: TContact read GetItems write SetItems; default;
+ end;
+
+
+ { TContactAddressList }
+
+ TContactAddressList = class(TAddressList)
+ protected
+ function GetOwner: TContact; reintroduce;
+ procedure SetOwner(const AValue: TContact); reintroduce;
+ public
+ property Owner: TContact read GetOwner write SetOwner;
+ end;
+
+
+
+
+implementation
+
+
+{ TMarkObject }
+
+procedure TMarkObject.Mark;
+begin
+ if (ObjectState <> posEmpty) then
+ Dirty:= True;
+end;
+
+{ TMarkObjectList }
+
+procedure TMarkObjectList.Mark;
+begin
+ if (ObjectState <> posEmpty) then
+ Dirty:= True;
+end;
+
+{ TCountry }
+
+procedure TCountry.SetISO(const AValue: string);
+begin
+ if FISO = AValue then
+ Exit; //==>
+
+ BeginUpdate;
+ FISO:= AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TCountry.SetName(const AValue: string);
+begin
+ if FName = AValue then
+ Exit; //==>
+
+ BeginUpdate;
+ FName:= AValue;
+ Mark;
+ EndUpdate;
+end;
+
+function TCountry.GetCaption: string;
+begin
+ Result:= Name;
+end;
+
+constructor TCountry.CreateNew(const AISO: string; const AName: string);
+begin
+ inherited CreateNew;
+ FISO:= AISO;
+ FName:= AName;
+end;
+
+{ TCity }
+
+procedure TCity.SetCountry(const AValue: TCountry);
+begin
+ if FCountry = AValue then
+ Exit; //==>
+
+ BeginUpdate;
+ FCountry:= AValue;
+ Mark;
+ EndUpdate;
+end;
+
+function TCity.GetCountryAsString: string;
+begin
+ result:= Country.Name + ' (' + Country.ISO + ')';
+end;
+
+procedure TCity.SetName(const AValue: string);
+begin
+ if FName = AValue then
+ Exit; //==>
+
+ BeginUpdate;
+ FName:= AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TCity.SetZIP(const AValue: string);
+begin
+ if FZip = AValue then
+ Exit; //==>
+
+ BeginUpdate;
+ FZip:= AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TCity.AssignClassProps(ASource: TtiObject);
+begin
+ FCountry:= TCity(ASource).Country; // reference only
+end;
+
+{ TAddressType }
+
+procedure TAddressType.SetName(const AValue: string);
+begin
+ if FName = AValue then
+ Exit; //==>
+
+ BeginUpdate;
+ FName:= AValue;
+ Mark;
+ EndUpdate;
+end;
+
+{ TAddress }
+
+procedure TAddress.SetStreet(const AValue: string);
+begin
+ if FStreet=AValue then exit;
+
+ BeginUpdate;
+ FStreet:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TAddress.SetTelephone1(const AValue: string);
+begin
+ if FTelephone1=AValue then exit;
+
+ BeginUpdate;
+ FTelephone1:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TAddress.SetTelephone2(const AValue: string);
+begin
+ if FTelephone2=AValue then exit;
+
+ BeginUpdate;
+ FTelephone2:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+constructor TAddress.Create;
+begin
+ inherited Create;
+ FAddressType:= TAddressType.Create;
+ FAddressType.Owner:= self;
+end;
+
+destructor TAddress.Destroy;
+begin
+ FreeAndNil(FAddressType);
+ inherited Destroy;
+end;
+
+procedure TAddress.AssignClassProps(ASource: TtiObject);
+begin
+ FAddressType.Assign(ASource);
+ FCity:= TAddress(ASource).City; // reference only
+end;
+
+procedure TAddress.SetNr(const AValue: integer);
+begin
+ if FNr=AValue then exit;
+
+ BeginUpdate;
+ FNr:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TAddress.SetAddressType(const AValue: TAddressType);
+begin
+ if FAddressType.Name = AValue.Name then
+ Exit; //==>
+
+ BeginUpdate;
+ FAddressType.Assign(AValue);
+ Mark;
+ EndUpdate;
+end;
+
+function TAddress.GetAddressType4GUI: string;
+begin
+ Result := FAddressType.Name;
+end;
+
+procedure TAddress.SetCity(const AValue: TCity);
+begin
+ if FCity=AValue then exit;
+
+ BeginUpdate;
+ FCity:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TAddress.SetFax(const AValue: string);
+begin
+ if FFax=AValue then exit;
+
+ BeginUpdate;
+ FFax:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+{ TContact }
+
+procedure TContact.SetFirstName(const AValue: string);
+begin
+ if FFirstName=AValue then exit;
+
+ BeginUpdate;
+ FFirstName:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TContact.SetEmail(const AValue: string);
+begin
+ if FEmail=AValue then exit;
+
+ BeginUpdate;
+ FEmail:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TContact.SetComments(const AValue: string);
+begin
+ if FComments=AValue then exit;
+
+ BeginUpdate;
+ FComments:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TContact.SetLastName(const AValue: string);
+begin
+ if FLastName=AValue then exit;
+
+ BeginUpdate;
+ FLastName:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+procedure TContact.SetMobile(const AValue: string);
+begin
+ if FMobile=AValue then exit;
+
+ BeginUpdate;
+ FMobile:=AValue;
+ Mark;
+ EndUpdate;
+end;
+
+constructor TContact.Create;
+begin
+ inherited Create;
+ FAddressList:= TAddressList.Create;
+ FAddressList.Owner:= self;
+ // ToDo: Refactor to remove need for ItemOwner. Use Parent instead
+ FAddressList.ItemOwner:= self;
+end;
+
+destructor TContact.Destroy;
+begin
+ FAddressList.Free;
+ inherited Destroy;
+end;
+
+{ TCountryList }
+
+function TCountryList.GetItems(i: integer): TCountry;
+begin
+ Result:= TCountry(inherited GetItems(i));
+end;
+
+procedure TCountryList.SetItems(i: integer; const AValue: TCountry);
+begin
+ inherited SetItems(i, AValue);
+end;
+
+function TCountryList.Add(const AObject: TCountry): integer;
+begin
+ Result:= inherited Add(AObject);
+end;
+
+{ TCityList }
+
+function TCityList.GetItems(i: integer): TCity;
+begin
+ result:= TCity(inherited GetItems(i));
+end;
+
+procedure TCityList.SetItems(i: integer; const AValue: TCity);
+begin
+ inherited SetItems(i, AValue);
+end;
+
+function TCityList.Add(const AObject: TCity): integer;
+begin
+ result:= inherited Add(AObject);
+end;
+
+{ TAddressList }
+
+function TAddressList.GetItems(i: integer): TAddress;
+begin
+ result:= TAddress(inherited GetItems(i));
+end;
+
+procedure TAddressList.SetItems(i: integer; const AValue: TAddress);
+begin
+ inherited SetItems(i, AValue);
+end;
+
+function TAddressList.Add(const AObject: TAddress): integer;
+begin
+ result:= inherited Add(AObject);
+end;
+
+{ TContactList }
+
+function TContactList.GetItems(i: integer): TContact;
+begin
+ result:= TContact(inherited GetItems(i));
+end;
+
+procedure TContactList.SetItems(i: integer; const AValue: TContact);
+begin
+ inherited SetItems(i, AValue);
+end;
+
+function TContactList.Add(const AObject: TContact): integer;
+begin
+ result:= inherited Add(AObject);
+end;
+
+{ TContactAddressList }
+
+function TContactAddressList.GetOwner: TContact;
+begin
+ result:= TContact(inherited GetOwner);
+end;
+
+procedure TContactAddressList.SetOwner(const AValue: TContact);
+begin
+ inherited SetOwner(AValue);
+end;
+
+
+end.
+