1 unit fMiniIde;
2 (* IDE main bar (rudimentary)
3 
4 Problems:
5   View window names are not derived from class name.
6   EditBooks are not managed sites(?)
7 *)
8 
9 {$mode objfpc}{$H+}
10 
11 interface
12 
13 uses
14   Classes, SysUtils, Forms, Controls, Dialogs, Menus, StdCtrls;
15 
16 type
17   TMainBar = class(TForm)
18     buSave: TButton;
19     buRestore: TButton;
20     cbLayouts: TComboBox;
21     Label1: TLabel;
22     MainMenu1: TMainMenu;
23     MenuItem1: TMenuItem;
24     MenuItem10: TMenuItem;
25     MenuItem11: TMenuItem;
26     MenuItem12: TMenuItem;
27     MenuItem13: TMenuItem;
28     MenuItem14: TMenuItem;
29     MenuItem2: TMenuItem;
30     MenuItem3: TMenuItem;
31     MenuItem4: TMenuItem;
32     MenuItem5: TMenuItem;
33     MenuItem6: TMenuItem;
34     MenuItem7: TMenuItem;
35     MenuItem8: TMenuItem;
36     MenuItem9: TMenuItem;
37     mnExit: TMenuItem;
38     mnFile: TMenuItem;
39     mnMinimize: TMenuItem;
40     mnOpen: TMenuItem;
41     mnRestore: TMenuItem;
42     mnView: TMenuItem;
43     mnWindowDump: TMenuItem;
44     OpenDialog1: TOpenDialog;
45     dlgLayout: TSaveDialog;
46     procedure buRestoreClick(Sender: TObject);
47     procedure buSaveClick(Sender: TObject);
48     procedure FormCreate(Sender: TObject);
49     procedure mnExitClick(Sender: TObject);
50     procedure mnOpenClick(Sender: TObject);
51     procedure mnWindowDumpClick(Sender: TObject);
52     procedure ViewMenuClick(Sender: TObject);
53   private
54     procedure GetLayouts;
55     procedure OpenFile(const AName: string);
56   private //DockMaster callbacks
OnReloadControlnull57     function  OnReloadControl(const CtrlName: string; ASite: TWinControl): TControl;
OnSaveControlnull58     function  OnSaveControl(ACtrl: TControl): string;
59   public
CreateDockablenull60     function CreateDockable(const cap: string; fWrap: boolean = True): TWinControl;
61   end;
62 
63 var
64   MainBar: TMainBar;
65 
66 implementation
67 
68 uses
69   LCLProc,
70   EasyDockSite,
71   uMakeSite, fEditBook, fClientForm;
72 
73 { TMainBar }
74 
75 procedure TMainBar.FormCreate(Sender: TObject);
76 begin
77   TDockMaster.Create(self);
78   DockMaster.OnSave := @OnSaveControl;
79   DockMaster.OnRestore := @OnReloadControl;
80   DockMaster.AddElasticSites(self, [alBottom]);
81   GetLayouts;
82 end;
83 
84 procedure TMainBar.GetLayouts;
85 var
86   sr: TSearchRec;
87 begin
88   if FindFirst('*.lyt', faAnyFile, sr) = 0 then begin
89     repeat
90       cbLayouts.Items.Add(sr.Name);
91     until FindNext(sr) <> 0;
92     FindClose(sr);
93   end;
94 end;
95 
96 procedure TMainBar.mnExitClick(Sender: TObject);
97 begin
98   Close;
99 end;
100 
101 procedure TMainBar.mnOpenClick(Sender: TObject);
102 begin
103   if OpenDialog1.Execute then begin
104     OpenFile(OpenDialog1.FileName);
105   end;
106 end;
107 
108 procedure TMainBar.mnWindowDumpClick(Sender: TObject);
109 
110   procedure DumpOwner(fo: TComponent);
111   var
112     i: integer;
113     cmp: TComponent;
114   begin
115     for i := 0 to fo.ComponentCount - 1 do begin
116       cmp := fo.Components[i];
117       //if cmp.Name <> '' then
118       begin
119         DebugLn(cmp.Name, ': ', cmp.ClassName);
120       end;
121     end;
122   end;
123 
124   procedure DumpForms;
125   var
126     i: integer;
127     cmp: TComponent;
128   begin
129     DebugLn('- Forms');
130     for i := 0 to Screen.FormCount - 1 do begin
131       cmp := Screen.Forms[i];
132       //if cmp.Name <> '' then
133       begin
134         DebugLn(cmp.Name, ': ', cmp.ClassName);
135       end;
136     end;
137   end;
138 
139 begin
140 //debug only
141   DebugLn('--- Screen');
142   DumpOwner(Screen);
143   DumpForms;
144 {
145   DebugLn('--- Owner');
146   DumpOwner(DockMaster.Owner);
147 }
148   DebugLn('--- end dump');
149 end;
150 
151 procedure TMainBar.OpenFile(const AName: string);
152 var
153   frm: TEditBook;
154   ctl: TControl;
155 begin
156 (* Translate into layout Reload format
157 *)
158 //get editor form
159   frm := nil;
160   if MRUEdit <> nil then begin
161   //use parent of last edit page
162     ctl := MRUEdit.Parent;
163     while ctl.Parent <> nil do
164       ctl := ctl.Parent;
165     if ctl is TEditBook then
166       frm := TEditBook(ctl);
167   end;
168   if frm = nil then begin
169     frm := TEditBook.Create(Application);
170     frm.Visible := True;
171   end;
172   frm.OpenFile(AName);
173 end;
174 
175 procedure TMainBar.ViewMenuClick(Sender: TObject);
176 var
177   item: TMenuItem absolute Sender;
178 begin
179 (* Create a dummy window from the menu item name.
180 *)
181   CreateDockable(item.Caption);
182 end;
183 
184 procedure TMainBar.buRestoreClick(Sender: TObject);
185 var
186   i: integer;
187   s: string;
188   f: TFileStream;
189 begin
190   i := cbLayouts.ItemIndex;
191   if i < 0 then begin
192     beep;
193     exit;
194   end;
195   s := cbLayouts.Items[i];
196   f := TFileStream.Create(s, fmOpenRead);
197   try
198     DockMaster.LoadFromStream(f);
199   finally
200     f.Free;
201   end;
202 end;
203 
204 procedure TMainBar.buSaveClick(Sender: TObject);
205 var
206   strm: TFileStream;
207 begin
208 (* Save layout.
209   This should inlude ALL forms, not only the dockable ones!
210 *)
211   if dlgLayout.Execute then begin
212     strm := TFileStream.Create(dlgLayout.FileName, fmCreate);
213     try
214     //save non-dockable forms
215     //save dockable forms and sites
216       DockMaster.SaveToStream(strm);
217     finally
218       strm.Free;
219     end;
220     cbLayouts.AddItem(dlgLayout.FileName, nil); //Extract?
221   end;
222 end;
223 
TMainBar.CreateDockablenull224 function TMainBar.CreateDockable(const cap: string; fWrap: boolean): TWinControl;
225 var
226   Client: TViewWindow;
227   n: string;
228 begin
229 (* Create a client form, and dock it into a floating dock host site.
230   We must force docking here, later the client will dock itself into
231   a float host site, when it becomes floating.
232 
233   Should use: DockMaster.CreateDockable(TViewWindow) - RegisterClass!
234 *)
235 //lookup existing (assume single instance forms)
236   n := StringReplace(cap, ' ', '', [rfReplaceAll]);
237   Result := Screen.FindForm(n);
238   if Result = nil then begin
239   //create the form
240     Client := TViewWindow.Create(Self);
241     Client.Label1.Caption := cap;
242   //name it
243     Client.Caption := cap;
244     TryRename(Client, n);
245     DockMaster.MakeDockable(Client, fWrap, True);
246     Client.Visible := True;
247     Result := Client;
248   end else begin
249   //activate the existing form
250     Result.Show; //might be invisible
251     Result.SetFocus;
252   end;
253 end;
254 
255 (* Special load/store cases:
256   ViewWindow: @<caption>
257   EditForm/Book: special load/save
258   EditPage?
259 *)
OnReloadControlnull260 function TMainBar.OnReloadControl(const CtrlName: string;
261   ASite: TWinControl): TControl;
262 var
263   i: integer;
264   lst: TStringList;
265   s: string;
266   eb: TEditBook absolute Result;
267   ss: TStringStream;
268 begin
269 (* Handle special cases:
270   ViewWindow
271   EditBook
272 *)
273   if CtrlName[1] = '@' then begin
274     s := copy(CtrlName, 2, Length(CtrlName));
275     Result := CreateDockable(s, False);
276     //if Result <> nil then Result.Visible := True; //edit forms without pages are hidden?
277   end else if ord(CtrlName[1]) = EditBookID then begin
278     eb := TEditBook.Create(Application);
279     ss := TStringStream.Create(CtrlName);
280     try
281       eb.LoadFromStream(ss);
282     finally
283       ss.Free;
284     end;
285   end else
286     Result := nil; //for now
287 end;
288 
OnSaveControlnull289 function TMainBar.OnSaveControl(ACtrl: TControl): string;
290 var
291   i: integer;
292   ep: TEditPage;
293   ss: TStringStream;
294 begin
295 (* handle special cases:
296   ViewWindow
297   EditBook
298 *)
299   if ACtrl is TViewWindow then begin
300     Result := '@' + ACtrl.Caption
301   end else if ACtrl is TEditBook then begin
302     ss := TStringStream.Create('');
303     try
304       TEditBook(ACtrl).SaveToStream(ss);
305       Result := ss.DataString;
306     finally
307       ss.Free;
308     end;
309     //Result := ',' + TWinControl(ACtrl).GetDockCaption(ACtrl);
310   end else
311     Result := ''; //unhandled
312     //Result := ACtrl.HostDockSite.GetDockCaption(ACtrl);
313 end;
314 
315 {$R *.lfm}
316 
317 end.
318 
319