1 {
2  /***************************************************************************
3                           mainbar.pp  -  Toolbar
4                           ----------------------
5   TMainIDEBar is the main window of the IDE, containing the menu and the
6   component palette.
7 
8  ***************************************************************************/
9 
10  ***************************************************************************
11  *                                                                         *
12  *   This source is free software; you can redistribute it and/or modify   *
13  *   it under the terms of the GNU General Public License as published by  *
14  *   the Free Software Foundation; either version 2 of the License, or     *
15  *   (at your option) any later version.                                   *
16  *                                                                         *
17  *   This code is distributed in the hope that it will be useful, but      *
18  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
19  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
20  *   General Public License for more details.                              *
21  *                                                                         *
22  *   A copy of the GNU General Public License is available on the World    *
23  *   Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also      *
24  *   obtain it by writing to the Free Software Foundation,                 *
25  *   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA.   *
26  *                                                                         *
27  ***************************************************************************
28 }
29 unit MainBar;
30 
31 {$mode objfpc}{$H+}
32 
33 interface
34 
35 {$I ide.inc}
36 
37 uses
38 {$IFDEF IDE_MEM_CHECK}
39   MemCheck,
40 {$ENDIF}
41   Classes, SysUtils, Math,
42   // LCL
43   Forms, Controls, Menus, ComCtrls, ExtCtrls, LMessages, LCLIntf, LCLType, LCLProc,
44   // LazUtils
45   LazFileCache,
46   // IDEIntf
47   MenuIntf, LazIDEIntf, IDEWindowIntf, IDEImagesIntf, ComponentReg,
48   // IDE
49   EnvironmentOpts, LazarusIDEStrConsts, IdeCoolbarData;
50 
51 type
52   { TMainIDEBar }
53 
54   TMainIDEBar = class(TForm)
55   private
56     OptionsPopupMenu: TPopupMenu;
57     FMainOwningComponent: TComponent;
58     FOldWindowState: TWindowState;
59     FOnActive: TNotifyEvent;
60     procedure CreatePopupMenus(TheOwner: TComponent);
CalcMainIDEHeightnull61     function CalcMainIDEHeight: Integer;
CalcNonClientHeightnull62     function CalcNonClientHeight: Integer;
FindCompScrollBoxnull63     function FindCompScrollBox: TScrollBox;
64   protected
65     procedure DoActive;
66     procedure WndProc(var Message: TLMessage); override;
67     procedure Resizing(State: TWindowState); override;
68   public
69     ApplicationIsActivate: boolean;
70     LastCompPaletteForm: TCustomForm;
71     //Coolbar and PopUpMenus
72     CoolBar: TCoolBar;
73     OptionsMenuItem: TMenuItem;
74     NewUFSetDefaultMenuItem: TMenuItem;
75     ComponentPageControl: TPageControl; // component palette
76     //GlobalMouseSpeedButton: TSpeedButton; <- what is this
77     MainSplitter: TSplitter;        // splitter between the Coolbar and MainMenu
78     // MainMenu
79     mnuMainMenu: TMainMenu;
80     //mnuMain: TIDEMenuSection;
81 
82     // file menu
83     //mnuFile: TIDEMenuSection;
84       //itmFileNew: TIDEMenuSection;
85         itmFileNewUnit: TIDEMenuCommand;
86         itmFileNewForm: TIDEMenuCommand;
87         itmFileNewOther: TIDEMenuCommand;
88       //itmFileOpenSave: TIDEMenuSection;
89         itmFileOpen: TIDEMenuCommand;
90         itmFileRevert: TIDEMenuCommand;
91         itmFileOpenUnit: TIDEMenuCommand;
92         //itmFileRecentOpen: TIDEMenuSection;
93         itmFileSave: TIDEMenuCommand;
94         itmFileSaveAs: TIDEMenuCommand;
95         itmFileSaveAll: TIDEMenuCommand;
96         itmFileExportHtml: TIDEMenuCommand;
97         itmFileClose: TIDEMenuCommand;
98         itmFileCloseAll: TIDEMenuCommand;
99       //itmFileDirectories: TIDEMenuSection;
100         itmFileCleanDirectory: TIDEMenuCommand;
101       //itmFileIDEStart: TIDEMenuSection;
102         itmFileRestart: TIDEMenuCommand;
103         itmFileQuit: TIDEMenuCommand;
104 
105     // edit menu
106     //mnuEdit: TIDEMenuSection;
107       //itmEditReUndo: TIDEMenuSection;
108         itmEditUndo: TIDEMenuCommand;
109         itmEditRedo: TIDEMenuCommand;
110       //itmEditClipboard: TIDEMenuSection;
111         itmEditCut: TIDEMenuCommand;
112         itmEditCopy: TIDEMenuCommand;
113         itmEditPaste: TIDEMenuCommand;
114         itmEditMultiPaste: TIDEMenuCommand;
115       //itmEditSelect: TIDEMenuSection;
116         itmEditSelectAll: TIDEMenuCommand;
117         itmEditSelectToBrace: TIDEMenuCommand;
118         itmEditSelectCodeBlock: TIDEMenuCommand;
119         itmEditSelectWord: TIDEMenuCommand;
120         itmEditSelectLine: TIDEMenuCommand;
121         itmEditSelectParagraph: TIDEMenuCommand;
122       //itmEditBlockActions: TIDEMenuSection;
123         itmEditIndentBlock: TIDEMenuCommand;
124         itmEditUnindentBlock: TIDEMenuCommand;
125         itmEditUpperCaseBlock: TIDEMenuCommand;
126         itmEditLowerCaseBlock: TIDEMenuCommand;
127         itmEditSwapCaseBlock: TIDEMenuCommand;
128         itmEditSortBlock: TIDEMenuCommand;
129         itmEditTabsToSpacesBlock: TIDEMenuCommand;
130         itmEditSelectionBreakLines: TIDEMenuCommand;
131       //itmEditInsertions: TIDEMenuSection;
132         itmEditInsertCharacter: TIDEMenuCommand;
133 
134     // search menu
135     //mnuSearch: TIDEMenuSection;
136       //itmSearchFindReplace: TIDEMenuSection;
137         itmSearchFind: TIDEMenuCommand;
138         itmSearchFindNext: TIDEMenuCommand;
139         itmSearchFindPrevious: TIDEMenuCommand;
140         itmSearchFindInFiles: TIDEMenuCommand;
141         itmSearchReplace: TIDEMenuCommand;
142         itmIncrementalFind: TIDEMenuCommand;
143       //itmJumpings: TIDEMenuSection;
144         itmGotoLine: TIDEMenuCommand;
145         itmJumpBack: TIDEMenuCommand;
146         itmJumpForward: TIDEMenuCommand;
147         itmAddJumpPoint: TIDEMenuCommand;
148         itmJumpToNextError: TIDEMenuCommand;
149         itmJumpToPrevError: TIDEMenuCommand;
150         itmJumpToInterface: TIDEMenuCommand;
151         itmJumpToInterfaceUses: TIDEMenuCommand;
152         itmJumpToImplementation: TIDEMenuCommand;
153         itmJumpToImplementationUses: TIDEMenuCommand;
154         itmJumpToInitialization: TIDEMenuCommand;
155       //itmBookmarks: TIDEMenuSection;
156         itmSetFreeBookmark: TIDEMenuCommand;
157         itmJumpToNextBookmark: TIDEMenuCommand;
158         itmJumpToPrevBookmark: TIDEMenuCommand;
159       //itmCodeToolSearches: TIDEMenuSection;
160         itmFindDeclaration: TIDEMenuCommand;
161         itmFindBlockOtherEnd: TIDEMenuCommand;
162         itmFindBlockStart: TIDEMenuCommand;
163         itmOpenFileAtCursor: TIDEMenuCommand;
164         itmGotoIncludeDirective: TIDEMenuCommand;
165         itmSearchFindIdentifierRefs: TIDEMenuCommand;
166         itmSearchProcedureList: TIDEMenuCommand;
167 
168     // view menu
169     //mnuView: TIDEMenuSection;
170       //itmViewMainWindows: TIDEMenuSection;
171         itmViewToggleFormUnit: TIDEMenuCommand;
172         itmViewInspector: TIDEMenuCommand;
173         itmViewSourceEditor: TIDEMenuCommand;
174         itmViewCodeExplorer: TIDEMenuCommand;
175         itmViewFPDocEditor: TIDEMenuCommand;
176         itmViewCodeBrowser: TIDEMenuCommand;
177         itmSourceUnitDependencies: TIDEMenuCommand;
178         itmViewRestrictionBrowser: TIDEMenuCommand;
179         itmViewComponents: TIDEMenuCommand;
180         itmJumpHistory: TIDEMenuCommand;
181         itmMacroListView: TIDEMenuCommand;
182       //itmViewSecondaryWindows: TIDEMenuSection;
183         itmViewAnchorEditor: TIDEMenuCommand;
184         itmViewTabOrder: TIDEMenuCommand;
185         itmViewMessage: TIDEMenuCommand;
186         itmViewSearchResults: TIDEMenuCommand;
187         //itmViewDebugWindows: TIDEMenuSection;
188           itmViewWatches: TIDEMenuCommand;
189           itmViewBreakpoints: TIDEMenuCommand;
190           itmViewLocals: TIDEMenuCommand;
191           itmViewRegisters: TIDEMenuCommand;
192           itmViewCallStack: TIDEMenuCommand;
193           itmViewThreads: TIDEMenuCommand;
194           itmViewAssembler: TIDEMenuCommand;
195           itmViewDebugOutput: TIDEMenuCommand;
196           itmViewDebugEvents: TIDEMenuCommand;
197           itmViewPseudoTerminal: TIDEMenuCommand;
198           itmViewDbgHistory: TIDEMenuCommand;
199         //itmViewIDEInternalsWindows: TIDEMenuSection;
200           itmViewFPCInfo: TIDEMenuCommand;
201           itmViewIDEInfo: TIDEMenuCommand;
202           itmViewNeedBuild: TIDEMenuCommand;
203           itmSearchInFPDocFiles: TIDEMenuCommand;
204 
205     // source menu
206     //mnuSource: TIDEMenuSection;
207       //itmSourceBlockActions: TIDEMenuSection;
208         itmSourceCommentBlock: TIDEMenuCommand;
209         itmSourceUncommentBlock: TIDEMenuCommand;
210         itmSourceToggleComment: TIDEMenuCommand;
211         itmSourceEncloseBlock: TIDEMenuCommand;
212         itmSourceEncloseInIFDEF: TIDEMenuCommand;
213         itmSourceCompleteCodeInteractive: TIDEMenuCommand;
214         itmSourceUseUnit: TIDEMenuCommand;
215       //itmSourceCodeToolChecks: TIDEMenuSection;
216         itmSourceSyntaxCheck: TIDEMenuCommand;
217         itmSourceGuessUnclosedBlock: TIDEMenuCommand;
218         {$IFDEF GuessMisplacedIfdef}
219         itmSourceGuessMisplacedIFDEF: TIDEMenuCommand;
220         {$ENDIF}
221       //itmSourceInsertCVSKeyWord: TIDEMenuSection;
222         itmSourceInsertCVSAuthor: TIDEMenuCommand;
223         itmSourceInsertCVSDate: TIDEMenuCommand;
224         itmSourceInsertCVSHeader: TIDEMenuCommand;
225         itmSourceInsertCVSID: TIDEMenuCommand;
226         itmSourceInsertCVSLog: TIDEMenuCommand;
227         itmSourceInsertCVSName: TIDEMenuCommand;
228         itmSourceInsertCVSRevision: TIDEMenuCommand;
229         itmSourceInsertCVSSource: TIDEMenuCommand;
230       //itmSourceInsertGeneral: TIDEMenuSection;
231         itmSourceInsertGPLNotice: TIDEMenuCommand;
232         itmSourceInsertGPLNoticeTranslated: TIDEMenuCommand;
233         itmSourceInsertLGPLNotice: TIDEMenuCommand;
234         itmSourceInsertLGPLNoticeTranslated: TIDEMenuCommand;
235         itmSourceInsertModifiedLGPLNotice: TIDEMenuCommand;
236         itmSourceInsertModifiedLGPLNoticeTranslated: TIDEMenuCommand;
237         itmSourceInsertMITNotice: TIDEMenuCommand;
238         itmSourceInsertMITNoticeTranslated: TIDEMenuCommand;
239         itmSourceInsertUsername: TIDEMenuCommand;
240         itmSourceInsertDateTime: TIDEMenuCommand;
241         itmSourceInsertChangeLogEntry: TIDEMenuCommand;
242         itmSourceInsertGUID: TIDEMenuCommand;
243         itmSourceInsertTodo: TIDEMenuCommand;
244       itmSourceInsertFilename: TIDEMenuCommand;
245     // itmSourceTools
246       itmSourceUnitInfo: TIDEMenuCommand;
247 
248     // refactor menu
249     //mnuRefactor: TIDEMenuSection;
250       //itmRefactorCodeTools: TIDEMenuSection;
251         itmRefactorRenameIdentifier: TIDEMenuCommand;
252         itmRefactorExtractProc: TIDEMenuCommand;
253         itmRefactorInvertAssignment: TIDEMenuCommand;
254       //itmRefactorAdvanced: TIDEMenuSection;
255         itmRefactorShowAbstractMethods: TIDEMenuCommand;
256         itmRefactorShowEmptyMethods: TIDEMenuCommand;
257         itmRefactorShowUnusedUnits: TIDEMenuCommand;
258         itmRefactorFindOverloads: TIDEMenuCommand;
259       //itmRefactorTools: TIDEMenuSection;
260         itmRefactorMakeResourceString: TIDEMenuCommand;
261 
262     // project menu
263     //mnuProject: TIDEMenuSection;
264       //itmProjectNewSection: TIDEMenuSection;
265         itmProjectNew: TIDEMenuCommand;
266         itmProjectNewFromFile: TIDEMenuCommand;
267       //itmProjectOpenSection: TIDEMenuSection;
268         itmProjectOpen: TIDEMenuCommand;
269         //itmProjectRecentOpen: TIDEMenuSection;
270         itmProjectClose: TIDEMenuCommand;
271       //itmProjectSaveSection: TIDEMenuSection;
272         itmProjectSave: TIDEMenuCommand;
273         itmProjectSaveAs: TIDEMenuCommand;
274         itmProjectResaveFormsWithI18n: TIDEMenuCommand;
275         itmProjectPublish: TIDEMenuCommand;
276       //itmProjectWindowSection: TIDEMenuSection;
277         itmProjectInspector: TIDEMenuCommand;
278         itmProjectOptions: TIDEMenuCommand;
279         //itmProjectCompilerOptions: TIDEMenuCommand;
280       //itmProjectAddRemoveSection: TIDEMenuSection;
281         itmProjectAddTo: TIDEMenuCommand;
282         itmProjectRemoveFrom: TIDEMenuCommand;
283         itmProjectViewUnits: TIDEMenuCommand;
284         itmProjectViewForms: TIDEMenuCommand;
285         itmProjectViewSource: TIDEMenuCommand;
286 
287     // run menu
288     //mnuRun: TIDEMenuSection;
289       //itmRunBuilding: TIDEMenuSection;
290         itmRunMenuCompile: TIDEMenuCommand;
291         itmRunMenuBuild: TIDEMenuCommand;
292         itmRunMenuQuickCompile: TIDEMenuCommand;
293         itmRunMenuCleanUpAndBuild: TIDEMenuCommand;
294         itmRunMenuBuildManyModes: TIDEMenuCommand;
295         itmRunMenuAbortBuild: TIDEMenuCommand;
296       //itmRunnning: TIDEMenuSection;
297         itmRunMenuRunWithoutDebugging: TIDEMenuCommand;
298         itmRunMenuRun: TIDEMenuCommand;
299         itmRunMenuPause: TIDEMenuCommand;
300         itmRunMenuShowExecutionPoint: TIDEMenuCommand;
301         itmRunMenuStepInto: TIDEMenuCommand;
302         itmRunMenuStepOver: TIDEMenuCommand;
303         itmRunMenuStepOut: TIDEMenuCommand;
304         itmRunMenuStepToCursor: TIDEMenuCommand;
305         itmRunMenuRunToCursor: TIDEMenuCommand;
306         itmRunMenuStop: TIDEMenuCommand;
307         itmRunMenuAttach: TIDEMenuCommand;
308         itmRunMenuDetach: TIDEMenuCommand;
309         itmRunMenuRunParameters: TIDEMenuCommand;
310         itmRunMenuResetDebugger: TIDEMenuCommand;
311       //itmRunBuildingFile: TIDEMenuSection;
312         itmRunMenuBuildFile: TIDEMenuCommand;
313         itmRunMenuRunFile: TIDEMenuCommand;
314         itmRunMenuConfigBuildFile: TIDEMenuCommand;
315       //itmRunDebugging: TIDEMenuSection;
316         itmRunMenuInspect: TIDEMenuCommand;
317         itmRunMenuEvaluate: TIDEMenuCommand;
318         itmRunMenuAddWatch: TIDEMenuCommand;
319         //itmRunMenuAddBreakpoint: TIDEMenuSection;
320           itmRunMenuAddBpSource: TIDEMenuCommand;
321           itmRunMenuAddBpAddress: TIDEMenuCommand;
322           itmRunMenuAddBpWatchPoint: TIDEMenuCommand;
323 
324     // packages menu
325     //mnuComponents: TIDEMenuSection;
326       //itmPkgOpening: TIDEMenuSection;
327         itmPkgNewPackage: TIDEMenuCommand;
328         itmPkgOpenLoadedPackage: TIDEMenuCommand;
329         itmPkgOpenPackageFile: TIDEMenuCommand;
330         itmPkgOpenPackageOfCurUnit: TIDEMenuCommand;
331         //itmPkgOpenRecent: TIDEMenuSection;
332       //itmPkgUnits: TIDEMenuSection;
333         itmPkgAddCurFileToPkg: TIDEMenuCommand;
334         itmPkgAddNewComponentToPkg: TIDEMenuCommand;
335       //itmPkgGraphSection: TIDEMenuSection;
336         itmPkgPkgGraph: TIDEMenuCommand;
337         itmPkgPackageLinks: TIDEMenuCommand;
338         itmPkgEditInstallPkgs: TIDEMenuCommand;
339 
340     // tools menu
341     //mnuTools: TIDEMenuSection;
342       //itmOptionsDialogs: TIDEMenuSection;
343         itmEnvGeneralOptions: TIDEMenuCommand;
344         itmToolRescanFPCSrcDir: TIDEMenuCommand;
345         itmEnvCodeTemplates: TIDEMenuCommand;
346         itmEnvCodeToolsDefinesEditor: TIDEMenuCommand;
347       //itmCustomTools: TIDEMenuSection;
348         itmToolConfigure: TIDEMenuCommand;
349       //itmSecondaryTools: TIDEMenuSection;
350         itmToolManageDesktops: TIDEMenuCommand;
351         itmToolManageExamples: TIDEMenuCommand;
352         itmToolDiff: TIDEMenuCommand;
353       //itmDelphiConversion: TIDEMenuSection;
354         itmToolCheckLFM: TIDEMenuCommand;
355         itmToolConvertDelphiUnit: TIDEMenuCommand;
356         itmToolConvertDelphiProject: TIDEMenuCommand;
357         itmToolConvertDelphiPackage: TIDEMenuCommand;
358         itmToolConvertDFMtoLFM: TIDEMenuCommand;
359         itmToolConvertEncoding: TIDEMenuCommand;
360       //itmBuildingLazarus: TIDEMenuSection;
361         itmToolBuildLazarus: TIDEMenuCommand;
362         itmToolConfigureBuildLazarus: TIDEMenuCommand;
363 
364     // windows menu
365     //mnuWindow: TIDEMenuSection;
366       //itmWindowManagers: TIDEMenuSection;
367         itmWindowManager: TIDEMenuCommand;
368 
369     // help menu
370     //mnuHelp: TIDEMenuSection;
371       //itmOnlineHelps: TIDEMenuSection;
372         itmHelpOnlineHelp: TIDEMenuCommand;
373         itmHelpReportingBug: TIDEMenuCommand;
374         //itmHelpConfigureHelp: TIDEMenuCommand;
375       //itmInfoHelps: TIDEMenuSection;
376         itmHelpAboutLazarus: TIDEMenuCommand;
377       //itmHelpTools: TIDEMenuSection;
378 
379     constructor Create(TheOwner: TComponent); override;
380     procedure MainIDEBarDropFiles(Sender: TObject; const FileNames: array of String);
381     procedure CoolBarOnChange(Sender: TObject);
382     procedure MainSplitterMoved(Sender: TObject);
383     procedure SetMainIDEHeightEvent(Sender: TObject);
384     procedure OnMainBarActive(Sender: TObject);
385     procedure Setup(TheOwner: TComponent);
386     procedure SetupHints;
387     procedure UpdateIDEComponentPalette(IfFormChanged: boolean);
388     procedure HideIDE;
389     procedure UnhideIDE;
390     property OnActive: TNotifyEvent read FOnActive write FOnActive;
391     procedure UpdateDockCaption({%H-}Exclude: TControl); override;
392     procedure RefreshCoolbar;
393     procedure SetMainIDEHeight;
394     procedure DoSetMainIDEHeight(const AIDEIsMaximized: Boolean; ANewHeight: Integer = 0);
395     procedure DoSetViewComponentPalette(aVisible: Boolean);
396     procedure AllowCompilation(aAllow: Boolean);
397     procedure InitPaletteAndCoolBar;
398   end;
399 
400 var
401   MainIDEBar: TMainIDEBar = nil;
402 
403 implementation
404 
405 { TMainIDEBar }
406 
407 procedure TMainIDEBar.MainIDEBarDropFiles(Sender: TObject;
408   const FileNames: array of String);
409 begin
410   // the Drop event comes before the Application activate event
411   // => invalidate file state
412   InvalidateFileStateCache;
413   LazarusIDE.DoDropFiles(Sender,FileNames);
414 end;
415 
416 procedure TMainIDEBar.DoActive;
417 begin
418   if Assigned(FOnActive) then
419     FOnActive(Self);
420 end;
421 
422 procedure TMainIDEBar.DoSetMainIDEHeight(const AIDEIsMaximized: Boolean; ANewHeight: Integer);
423 begin
424   if not Showing then Exit;
425 
426   //DebugLn(['TMainIDEBar.DoSetMainIDEHeight: IDEStarted=', LazarusIDE.IDEStarted]);
427 
428   DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TMainIDEBar.DoSetMainIDEHeight'){$ENDIF};
429   try
430     if Assigned(IDEDockMaster) then
431     begin
432       if EnvironmentOptions.Desktop.AutoAdjustIDEHeight then
433       begin
434         if ANewHeight <= 0 then
435           ANewHeight := CalcMainIDEHeight;
436         IDEDockMaster.AdjustMainIDEWindowHeight(Self, True, ANewHeight)
437       end
438       else
439         IDEDockMaster.AdjustMainIDEWindowHeight(Self, False, 0);
440     end else
441     begin
442       if (AIDEIsMaximized or EnvironmentOptions.Desktop.AutoAdjustIDEHeight) then
443       begin
444         if ANewHeight <= 0 then
445           ANewHeight := CalcMainIDEHeight;
446         Inc(ANewHeight, CalcNonClientHeight);
447         if ANewHeight <> Constraints.MaxHeight then
448         begin
449           Constraints.MaxHeight := ANewHeight;
450           Constraints.MinHeight := ANewHeight;
451           ClientHeight := ANewHeight; // <- Value is -28 when issue #34377 happens.
452         end else if ClientHeight <> ANewHeight then
453           ClientHeight := ANewHeight;
454       end else
455       if Constraints.MaxHeight <> 0 then
456       begin
457         Constraints.MaxHeight := 0;
458         Constraints.MinHeight := 0;
459       end;
460     end;
461   finally
462     EnableAutoSizing{$IFDEF DebugDisableAutoSizing}('TMainIDEBar.DoSetMainIDEHeight'){$ENDIF};
463   end;
464 end;
465 
CalcMainIDEHeightnull466 function TMainIDEBar.CalcMainIDEHeight: Integer;
467 var
468   NewHeight: Integer;
469   I: Integer;
470   CompScrollBox: TScrollBox;
471   SBControl: TControl;
472 begin
473   Result := 0;
474   if (EnvironmentOptions=Nil) or (CoolBar=Nil) or (ComponentPageControl=Nil) then
475     Exit;
476 
477   // IDE Coolbar height
478   if EnvironmentOptions.Desktop.IDECoolBarOptions.Visible then
479   begin
480     for I := 0 to CoolBar.Bands.Count-1 do
481     begin
482       NewHeight := CoolBar.Bands[I].Top + CoolBar.Bands[I].Height;
483       Assert(NewHeight >= 0, Format('TMainIDEBar.CalcMainIDEHeight, IDE Coolbar: '+
484         'NewHeight %d < 0. Band Top=%d, Band Height=%d.',
485         [NewHeight, CoolBar.Bands[I].Top, CoolBar.Bands[I].Height]) );
486       Result := Max(Result, NewHeight);
487     end;
488   end;
489 
490   // Component palette height
491   if EnvironmentOptions.Desktop.ComponentPaletteOptions.Visible
492   and Assigned(ComponentPageControl.ActivePage) then
493   begin
494     CompScrollBox := FindCompScrollBox;
495     if CompScrollBox=Nil then Exit;
496     for I := 0 to CompScrollBox.ControlCount-1 do
497     begin
498       SBControl := CompScrollBox.Controls[I];
499       NewHeight := SBControl.Top + SBControl.Height +  //button height
500         //page control non-client height (tabs, borders).
501         ComponentPageControl.Height - CompScrollBox.ClientHeight;
502       Assert(NewHeight >= 0, Format('TMainIDEBar.CalcMainIDEHeight, Component palette : '+
503         'NewHeight %d < 0. Cntrl.Top=%d, Cntrl.Height=%d, '+
504         'PageControl.Height=%d, ScrollBox.ClientHeight=%d.',
505         [NewHeight, SBControl.Top, SBControl.Height,
506          ComponentPageControl.Height, CompScrollBox.ClientHeight]) );
507       Result := Max(Result, NewHeight);
508 
509       if not EnvironmentOptions.Desktop.AutoAdjustIDEHeightFullCompPal then
510         Break;  //we need only one button (we calculate one line only)
511     end;
512   end;
513 end;
514 
CalcNonClientHeightnull515 function TMainIDEBar.CalcNonClientHeight: Integer;
516 {$IF DEFINED(LCLWin32) OR DEFINED(LCLGtk2) OR DEFINED(LCLQt) OR DEFINED(LCLQt5)}
517 var
518   WindowRect, WindowClientRect: TRect;
519 {$ENDIF}
520 begin
521   {
522     This function is a bug-workaround for various LCL widgetsets.
523     Every widgetset handles constrained height differently.
524     In an ideal word (when the bugs are fixed), this function shouldn't be
525     needed at all - it should return always 0.
526 
527     Currently tested: Win32, Gtk2, Carbon, Qt.
528 
529     List of bugs related to this workaround:
530       http://bugs.freepascal.org/view.php?id=28033
531       http://bugs.freepascal.org/view.php?id=28034
532       http://bugs.freepascal.org/view.php?id=28036
533   }
534   if not Showing then
535     Exit(0);
536 
537   {$IF DEFINED(LCLWin32) OR DEFINED(LCLGtk2) OR DEFINED(LCLQt) OR DEFINED(LCLQt5)}
538   //Gtk2 + Win32 + Qt
539   //retrieve real main menu height because
540   // - Win32: multi-line is possible (SM_CYMENU reflects only single line)
541   // - Gtk2, Qt:  SM_CYMENU does not work
542   LclIntf.GetWindowRect(Handle, WindowRect{%H-});
543   LclIntf.GetClientRect(Handle, WindowClientRect{%H-});
544   LclIntf.ClientToScreen(Handle, WindowClientRect.TopLeft);
545 
546   Result := WindowClientRect.Top - WindowRect.Top;
547 
548   Assert(Result >= 0, 'TMainIDEBar.CalcNonClientHeight: Result '+IntToStr(Result)+' is below zero.');
549 
550   {$IFDEF LCLWin32}
551   //Win32 the constrained height has to be without SM_CYSIZEFRAME and SM_CYCAPTION;
552   Result := Result - (LCLIntf.GetSystemMetrics(SM_CYSIZEFRAME) + LCLIntf.GetSystemMetrics(SM_CYCAPTION));
553   {$ENDIF LCLWin32}
554 
555   {$ELSE}
556   //other widgetsets
557   //Carbon tested - behaves correctly
558   Result := 0;
559   {$ENDIF}
560 end;
561 
TMainIDEBar.FindCompScrollBoxnull562 function TMainIDEBar.FindCompScrollBox: TScrollBox;
563 var
564   I: Integer;
565 begin
566   for I := 0 to ComponentPageControl.ActivePage.ControlCount-1 do
567     if (ComponentPageControl.ActivePage.Controls[I] is TScrollBox) then
568       Exit(TScrollBox(ComponentPageControl.ActivePage.Controls[I]));
569   Result := nil;
570 end;
571 
572 procedure TMainIDEBar.SetMainIDEHeightEvent(Sender: TObject);
573 begin
574   SetMainIDEHeight;
575 end;
576 
577 procedure TMainIDEBar.OnMainBarActive(Sender: TObject);
578 var
579   i, FormCount: integer;
580   AForm: TCustomForm;
581 begin
582   if EnvironmentOptions.Desktop.SingleTaskBarButton and not ApplicationIsActivate
583   and (WindowState=wsNormal) then
584   begin
585     ApplicationIsActivate:=true;
586     FormCount:=0;
587     for i:=Screen.CustomFormCount-1 downto 0 do
588     begin
589       AForm:=Screen.CustomForms[i];
590       if (AForm.Parent=nil) and (AForm<>Self) and (AForm.IsVisible)
591       and not IsFormDesign(AForm)
592       and not (fsModal in AForm.FormState) then
593         inc(FormCount);
594     end;
595     while LazarusIDE.LastActivatedWindows.Count>0 do
596     begin
597       AForm:=TCustomForm(LazarusIDE.LastActivatedWindows[0]);
598       if Assigned(AForm) and (not (CsDestroying in AForm.ComponentState)) and
599       AForm.IsVisible then
600         AForm.BringToFront;
601       LazarusIDE.LastActivatedWindows.Delete(0);
602     end;
603     Self.BringToFront;
604   end;
605 end;
606 
607 procedure TMainIDEBar.WndProc(var Message: TLMessage);
608 begin
609   inherited WndProc(Message);
610   if (Message.Msg=LM_ACTIVATE) and (Message.Result=0) then
611     DoActive;
612 end;
613 
614 procedure TMainIDEBar.UpdateDockCaption(Exclude: TControl);
615 begin
616   // keep IDE caption
617 end;
618 
619 constructor TMainIDEBar.Create(TheOwner: TComponent);
620 begin
621   // This form has no resource => must be constructed using CreateNew
622   inherited CreateNew(TheOwner, 1);
623   AllowDropFiles:=true;
624   Scaled:=true;
625   OnDropFiles:=@MainIDEBarDropFiles;
626   if Assigned(IDEDockMaster) then
627     IDEDockMaster.SetMainDockWindow(Self);
628   {$IFNDEF LCLGtk2}
629   try
630     Icon.LoadFromResourceName(HInstance, 'WIN_MAIN');
631   except
632   end;
633   {$ENDIF}
634 end;
635 
636 procedure TMainIDEBar.HideIDE;
637 begin
638   if WindowState=wsMinimized then exit;
639   FOldWindowState:=WindowState;
640   WindowState:=wsMinimized;
641 end;
642 
643 procedure TMainIDEBar.UnhideIDE;
644 begin
645   WindowState:=FOldWindowState;
646 end;
647 
648 procedure TMainIDEBar.CreatePopupMenus(TheOwner: TComponent);
649 begin
650   OptionsPopupMenu := TPopupMenu.Create(TheOwner);
651   OptionsPopupMenu.Images := IDEImages.Images_16;
652   OptionsMenuItem := TMenuItem.Create(TheOwner);
653   OptionsMenuItem.Name := 'miToolbarOption';
654   OptionsMenuItem.Caption := lisMenuGeneralOptions;
655   OptionsMenuItem.Enabled := True;
656   OptionsMenuItem.Visible := True;
657   OptionsMenuItem.ImageIndex := IDEImages.LoadImage('menu_environment_options');
658   OptionsPopupMenu.Items.Add(OptionsMenuItem);
659 end;
660 
661 procedure TMainIDEBar.Setup(TheOwner: TComponent);
662 begin
663   FMainOwningComponent := TheOwner;
664   OnActive:=@OnMainBarActive;
665 
666   MainSplitter := TSplitter.Create(TheOwner);
667   MainSplitter.Parent := Self;
668   MainSplitter.Align := alLeft;
669   MainSplitter.MinSize := 50;
670   MainSplitter.OnMoved := @MainSplitterMoved;
671 
672   // IDE Coolbar
673   CoolBar := TCoolBar.Create(TheOwner);
674   CoolBar.Parent := Self;
675   if EnvironmentOptions.Desktop.ComponentPaletteOptions.Visible then
676   begin
677     CoolBar.Align := alLeft;
678     CoolBar.Width := Scale96ToForm(EnvironmentOptions.Desktop.IDECoolBarOptions.Width);
679   end
680   else
681     CoolBar.Align := alClient;
682 
683   // IDE Coolbar object wraps the actual CoolBar.
684   IDECoolBar := TIDECoolBar.Create(CoolBar);
685   IDECoolBar.IsVisible := EnvironmentOptions.Desktop.IDECoolBarOptions.Visible;
686   CoolBar.OnChange := @CoolBarOnChange;
687   CreatePopupMenus(TheOwner);
688   CoolBar.PopupMenu := OptionsPopupMenu;
689 
690   // Component palette
691   ComponentPageControl := TPageControl.Create(TheOwner);
692   ComponentPageControl.Name := 'ComponentPageControl';
693   ComponentPageControl.Align := alClient;
694   ComponentPageControl.Visible := EnvironmentOptions.Desktop.ComponentPaletteOptions.Visible;
695   ComponentPageControl.Parent := Self;
696 end;
697 
698 procedure TMainIDEBar.SetupHints;
699 var
700   CurShowHint: boolean;
701   AControl: TControl;
702   i, j: integer;
703 begin
704   if EnvironmentOptions=nil then exit;
705   // update all hints in the component palette
706   CurShowHint:=EnvironmentOptions.ShowHintsForComponentPalette;
707   for i:=0 to ComponentPageControl.PageCount-1 do begin
708     for j:=0 to ComponentPageControl.Page[i].ControlCount-1 do begin
709       AControl:=ComponentPageControl.Page[i].Controls[j];
710       AControl.ShowHint:=CurShowHint;
711     end;
712   end;
713   // update all hints in main ide toolbars
714   //??? CurShowHint:=EnvironmentOptions.ShowHintsForMainSpeedButtons;
715 end;
716 
717 procedure TMainIDEBar.UpdateIDEComponentPalette(IfFormChanged: boolean);
718 var
719   LastActiveForm: TCustomForm;
720 begin
721   // Package manager updates the palette initially.
722   LastActiveForm := LazarusIDE.LastFormActivated;
723   if not LazarusIDE.IDEStarted
724   or (IfFormChanged and (LastCompPaletteForm=LastActiveForm)) then
725     exit;
726   LastCompPaletteForm := LastActiveForm;
727   IDEComponentPalette.HideControls :=
728     (LastActiveForm<>nil) and (LastActiveForm.Designer<>nil)
729     and (LastActiveForm.Designer.LookupRoot<>nil)
730     and not (LastActiveForm.Designer.LookupRoot is TControl);
731   {$IFDEF VerboseComponentPalette}
732   DebugLn(['* TMainIDEBar.UpdateIDEComponentPalette: Updating palette *',
733            ', HideControls=', IDEComponentPalette.HideControls]);
734   {$ENDIF}
735   IDEComponentPalette.Update(False);
736   SetupHints;
737 end;
738 
739 procedure TMainIDEBar.InitPaletteAndCoolBar;
740 begin
741   RefreshCoolbar;
742   ComponentPageControl.OnChange(Self);//refresh component palette with button reposition
743   SetMainIDEHeight;
744   if IDEDockMaster<>nil then
745     IDEDockMaster.ResetSplitters;
746 end;
747 
748 procedure TMainIDEBar.RefreshCoolbar;
749 var
750   I: Integer;
751   CoolBand: TCoolBand;
752   CoolBarOpts: TIDECoolBarOptions;
753   CurToolBar: TIDEToolBar;
754 begin
755   CoolBarOpts := EnvironmentOptions.Desktop.IDECoolBarOptions;
756   //read general settings
757   if not (CoolBarOpts.GrabStyle in [0..5]) then
758     CoolBarOpts.GrabStyle := 4;
759   Coolbar.GrabStyle := TGrabStyle(CoolBarOpts.GrabStyle);
760   if not (CoolBarOpts.GrabWidth in [1..50]) then
761     CoolBarOpts.GrabWidth := 5;
762   Coolbar.GrabWidth := CoolBarOpts.GrabWidth;
763   Coolbar.BandBorderStyle := TBorderStyle(CoolBarOpts.BorderStyle);
764   Coolbar.Width := CoolBarOpts.Width;
765   //read toolbars
766   CoolBar.Bands.Clear;
767   IDECoolBar.CopyFromOptions(CoolBarOpts);
768   IDECoolBar.Sort;
769   for I := 0 to IDECoolBar.ToolBars.Count - 1 do
770   begin
771     CurToolBar:=IDECoolBar.ToolBars[I];
772     CurToolBar.ToolBar.BeginUpdate;
773     try
774       CoolBand := CoolBar.Bands.Add;
775       CoolBand.Break := CurToolBar.CurrentOptions.Break;
776       CoolBand.Control := CurToolBar.ToolBar;
777       CoolBand.MinWidth := 25;
778       CoolBand.MinHeight := 22;
779       CoolBand.FixedSize := True;
780       CurToolBar.UseCurrentOptions;
781     finally
782       CurToolBar.ToolBar.EndUpdate;
783     end;
784   end;
785   CoolBar.AutoAdjustLayout(lapAutoAdjustForDPI, 96, PixelsPerInch, 0, 0);
786   CoolBar.AutosizeBands;
787 
788   CoolBar.Visible := CoolBarOpts.Visible;
789   MainSplitter.Align := alLeft;
790   MainSplitter.Visible := Coolbar.Visible and ComponentPageControl.Visible;
791 end;
792 
793 procedure TMainIDEBar.Resizing(State: TWindowState);
794 begin
795   if LazarusIDE.IDEStarted then
796     case State of
797       wsMaximized, wsNormal: begin
798         //DebugLn('TMainIDEBar.Resizing: Setting main IDE height');
799         DoSetMainIDEHeight(State = wsMaximized);
800       end;
801     end;
802 
803   inherited Resizing(State);
804 end;
805 
806 procedure TMainIDEBar.MainSplitterMoved(Sender: TObject);
807 begin
808   EnvironmentOptions.Desktop.IDECoolBarOptions.Width := ScaleFormTo96(CoolBar.Width);
809   SetMainIDEHeight;
810 end;
811 
812 procedure TMainIDEBar.CoolBarOnChange(Sender: TObject);
813 begin
814   IDECoolBar.CopyFromRealCoolbar(Coolbar);
815   IDECoolBar.CopyToOptions(EnvironmentOptions.Desktop.IDECoolBarOptions);
816   SetMainIDEHeight;
817 end;
818 
819 procedure TMainIDEBar.SetMainIDEHeight;
820 begin
821   DoSetMainIDEHeight(WindowState = wsMaximized);
822 end;
823 
824 procedure TMainIDEBar.DoSetViewComponentPalette(aVisible: Boolean);
825 begin
826   if aVisible = ComponentPageControl.Visible then Exit;
827   ComponentPageControl.Visible := aVisible;
828   EnvironmentOptions.Desktop.ComponentPaletteOptions.Visible := aVisible;
829   if aVisible then
830   begin
831     if CoolBar.Align = alClient then
832     begin
833       CoolBar.Width := 230;
834       EnvironmentOptions.Desktop.IDECoolBarOptions.Width := 230;
835     end;
836     CoolBar.Align := alLeft;
837     CoolBar.Vertical := False;
838     MainSplitter.Align := alLeft;
839   end
840   else
841     CoolBar.Align := alClient;
842   MainSplitter.Visible := Coolbar.Visible and aVisible;
843 
844   if aVisible then//when showing component palette, it must be visible to calculate it correctly
845     //this will cause the IDE to flicker, but it's better than to have wrongly calculated IDE height
846     DoSetMainIDEHeight(WindowState = wsMaximized, 55);
847   SetMainIDEHeight;
848 end;
849 
850 procedure TMainIDEBar.AllowCompilation(aAllow: Boolean);
851 // Enables or disables IDE GUI controls associated with compiling and building.
852 // Does it interfere with DebugBoss.UpdateButtonsAndMenuItems? Maybe should be refactored and combined.
853 begin
854   itmRunMenuRunWithoutDebugging.Enabled:=aAllow;
855   itmRunMenuRun.Enabled:=aAllow;
856   itmRunMenuCompile.Enabled:=aAllow;
857   itmRunMenuBuild.Enabled:=aAllow;
858   itmRunMenuQuickCompile.Enabled:=aAllow;
859   itmRunMenuCleanUpAndBuild.Enabled:=aAllow;
860   itmPkgEditInstallPkgs.Enabled:=aAllow;
861   itmToolRescanFPCSrcDir.Enabled:=aAllow;
862   itmToolBuildLazarus.Enabled:=aAllow;
863   //itmToolConfigureBuildLazarus.Enabled:=aAllow;
864 end;
865 
866 end.
867 
868