{ ***************************************************************************** See the file COPYING.modifiedLGPL.txt, included in this distribution, for details about the license. ***************************************************************************** Authors: Maciej Izak Michael W. Vogel DaThoX 2004-2015 FreeSparta.com Known Issues: - when form / frame is moved out of screen, there the form has no designer grid (dots) - ObjectInspector eats focus of AnchorDesigner (bug or feature?) - Qt5 shows own menu in form, this isn't shown in anchor editor - designer: mouse wheel to scroll content doesn't work - csDesigning is set and form doesn't get a LM_MOUSEWHEEL message TODO: - Undo } unit DockedMainIDE; {$mode objfpc}{$H+} { $define DEBUGDOCKEDFORMEDITOR} interface uses // RTL Classes, SysUtils, Contnrs, // LCL LCLIntf, Controls, Forms, // IdeIntf SrcEditorIntf, LazIDEIntf, FormEditingIntf, PropEdits, LazLoggerBase, // DockedFormEditor DockedResizer, DockedModulePageControl, DockedTools, DockedSourceEditorPageControls, DockedOptionsIDE, DockedDesignForm, DockedSourceEditorWindow; type { TDockedTabMaster } TDockedTabMaster = class(TIDETabMaster) private // enable autosizing for docked form editor forms, see issue #32207 - disabled // in SourceFileManager per PreventAutoSize FAutoSizeControlList: TObjectList; protected function GetTabDisplayState: TTabDisplayState; override; function GetTabDisplayStateEditor(ASourceEditor: TSourceEditorInterface): TTabDisplayState; override; public constructor Create; destructor Destroy; override; function AutoSizeInShowDesigner(AControl: TControl): Boolean; override; procedure EnableAutoSizing(AControl: TControl); procedure ToggleFormUnit; override; procedure JumpToCompilerMessage(ASourceEditor: TSourceEditorInterface); override; procedure ShowCode(ASourceEditor: TSourceEditorInterface); override; procedure ShowDesigner(ASourceEditor: TSourceEditorInterface; AIndex: Integer = 0); override; procedure ShowForm(AForm: TCustomForm); override; procedure OptionsModified; end; { TDockedMainIDE } TDockedMainIDE = class(TObject) public class function GetCurrentPageControl: TModulePageControl; class procedure Screen_FormAdded(Sender: TObject; AForm: TCustomForm); class procedure Screen_FormDel(Sender: TObject; AForm: TCustomForm); class procedure WindowCreate(Sender: TObject); class procedure WindowDestroy(Sender: TObject); class procedure WindowHide(Sender: TObject); class procedure WindowShow(Sender: TObject); class procedure EditorActivated(Sender: TObject); class procedure EditorCreate(Sender: TObject); class procedure EditorDestroyed(Sender: TObject); class procedure TabChange(Sender: TObject); class procedure GlobalSNOnChangeBounds(Sender: TObject); class procedure OnShowDesignerForm(Sender: TObject; {%H-}AEditor: TSourceEditorInterface; AComponentPaletteClassSelected: Boolean); class procedure OnShowSrcEditor(Sender: TObject); class procedure OnDesignShowMethod(const Name: String); class procedure OnDesignRefreshPropertyValues; class procedure OnDesignModified(Sender: TObject); class procedure OnDesignPersistentAdded({%H-}APersistent: TPersistent; {%H-}Select: Boolean); class procedure OnDesignPersistentDeleted({%H-}APersistent: TPersistent); class procedure OnDesignMouseDown(Sender: TObject; {%H-}Button: TMouseButton; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer); class procedure OnDesignSetSelection(const ASelection: TPersistentSelectionList); end; var DockedTabMaster: TDockedTabMaster absolute IDETabMaster; implementation { TDockedTabMaster } function TDockedTabMaster.GetTabDisplayState: TTabDisplayState; begin Result := GetTabDisplayStateEditor(SourceEditorManagerIntf.ActiveEditor); end; function TDockedTabMaster.GetTabDisplayStateEditor(ASourceEditor: TSourceEditorInterface): TTabDisplayState; var LPageCtrl: TModulePageControl; begin if ASourceEditor = nil then Exit(tdsNone); LPageCtrl := SourceEditorWindows.FindModulePageControl(ASourceEditor); if LPageCtrl = nil then Exit(tdsNone); case LPageCtrl.PageIndex of 0: Exit(tdsCode); 1: Exit(tdsDesign); 2: Exit(tdsDesign); else Exit(tdsNone); end; end; constructor TDockedTabMaster.Create; begin FAutoSizeControlList := TObjectList.Create(False); end; destructor TDockedTabMaster.Destroy; begin FAutoSizeControlList.Free; inherited Destroy; end; function TDockedTabMaster.AutoSizeInShowDesigner(AControl: TControl): Boolean; begin // enable autosizing for docked form editor forms, see issue #32207 - disabled // in SourceFileManager per PreventAutoSize FAutoSizeControlList.Add(AControl); Result := True; end; procedure TDockedTabMaster.EnableAutoSizing(AControl: TControl); var AIndex: Integer; AutoSizeControl: TControl; begin // enable autosizing for docked form editor forms, see issue #32207 - disabled // in SourceFileManager per PreventAutoSize {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.EnableAutoSizing: ', DbgSName(AControl)); {$ENDIF} if not Assigned(AControl) then Exit; AutoSizeControl := nil; if AControl is TNonFormProxyDesignerForm then begin if (TNonFormProxyDesignerForm(AControl).LookupRoot is TControl) then AutoSizeControl := TControl(TNonFormProxyDesignerForm(AControl).LookupRoot); end else AutoSizeControl := AControl; AIndex := FAutoSizeControlList.IndexOf(AutoSizeControl); if (AIndex >= 0) then begin FAutoSizeControlList.Delete(AIndex); AutoSizeControl.EnableAutoSizing{$IFDEF DebugDisableAutoSizing}('TAnchorDockMaster Delayed'){$ENDIF}; end; end; procedure TDockedTabMaster.ToggleFormUnit; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.ToggleFormUnit'); {$ENDIF} case TabDisplayState of tdsCode: ShowDesigner(SourceEditorManagerIntf.ActiveEditor); tdsDesign: ShowCode(SourceEditorManagerIntf.ActiveEditor); end; end; procedure TDockedTabMaster.JumpToCompilerMessage( ASourceEditor: TSourceEditorInterface); begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.JumpToCompilerMessage'); {$ENDIF} SourceEditorManagerIntf.ActiveEditor := ASourceEditor; ShowCode(ASourceEditor); end; procedure TDockedTabMaster.ShowCode(ASourceEditor: TSourceEditorInterface); var LPageCtrl: TModulePageControl; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.ShowCode'); {$ENDIF} if ASourceEditor = nil then Exit; LPageCtrl := SourceEditorWindows.FindModulePageControl(ASourceEditor); LPageCtrl.ShowCode; ASourceEditor.EditorControl.SetFocus; end; procedure TDockedTabMaster.ShowDesigner(ASourceEditor: TSourceEditorInterface; AIndex: Integer); var LPageCtrl: TModulePageControl; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.ShowDesigner'); {$ENDIF} if ASourceEditor = nil then Exit; LPageCtrl := SourceEditorWindows.FindModulePageControl(ASourceEditor); LPageCtrl.ShowDesigner(AIndex); end; procedure TDockedTabMaster.ShowForm(AForm: TCustomForm); var LEditor: TSourceEditorInterface; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.ShowForm'); {$ENDIF} LEditor := FindSourceEditorForDesigner(AForm.Designer); SourceEditorManagerIntf.ActiveEditor := LEditor; ShowDesigner(LEditor); end; procedure TDockedTabMaster.OptionsModified; var LPageCtrl: TModulePageControl; LPageIndex: Integer; begin LPageCtrl := SourceEditorWindows.LastActiveModulePageControl; LPageIndex := LPageCtrl.PageIndex; DesignForms.RemoveAllAnchorDesigner; SourceEditorWindows.ShowCodeTabSkipCurrent(nil, nil); SourceEditorWindows.RefreshActivePageControls; TDockedMainIDE.EditorActivated(SourceEditorWindows.LastActiveSourceEditor); if LPageIndex = 0 then Exit; LPageCtrl.TabIndex := LPageIndex; LPageCtrl.OnChange(LPageCtrl); end; { TDockedMainIDE } class function TDockedMainIDE.GetCurrentPageControl: TModulePageControl; var LForm: TCustomForm; LDesignForm: TDesignForm; LSourceEditorWindowInterface: TSourceEditorWindowInterface; begin Result := nil; if (FormEditingHook = nil) or (GlobalDesignHook = nil) then Exit; LForm := FormEditingHook.GetDesignerForm(GlobalDesignHook.LookupRoot); LDesignForm := DesignForms.Find(LForm); if LDesignForm = nil then Exit; LSourceEditorWindowInterface := LDesignForm.LastActiveSourceWindow; if not Assigned(LSourceEditorWindowInterface) then Exit; Result := SourceEditorWindows.FindModulePageControl(LSourceEditorWindowInterface.ActiveEditor); end; class procedure TDockedMainIDE.Screen_FormAdded(Sender: TObject; AForm: TCustomForm); var LSourceEditor: TSourceEditorInterface; LDesignForm: TDesignForm; LPageCtrl: TModulePageControl; begin if IsFormDesign(AForm) then begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.Screen_FormAdded ', DbgSName(AForm)); {$ENDIF} // AForm like TForm1 etc... if not (csDesignInstance in AForm.ComponentState) and not (AForm is TNonFormProxyDesignerForm) then Exit; LDesignForm := TDesignForm.Create(AForm); LDesignForm.Hiding := True; DesignForms.Add(LDesignForm); LSourceEditor := FindSourceEditorForDesigner(AForm.Designer); if LSourceEditor <> nil then begin LPageCtrl := SourceEditorWindows.FindModulePageControl(LSourceEditor); if LPageCtrl <> nil then begin LPageCtrl.DesignForm := LDesignForm; LPageCtrl.CreateTabSheetDesigner; if LDesignForm.IsAnchorDesign then LPageCtrl.CreateTabSheetAnchors; end; end; SetTimer(AForm.Handle, WM_SETNOFRAME, 10, nil); end else begin if AForm is TSourceEditorWindowInterface then AForm.AddHandlerOnChangeBounds(@GlobalSNOnChangeBounds); end; end; class procedure TDockedMainIDE.Screen_FormDel(Sender: TObject; AForm: TCustomForm); var LSourceEditorWindow: TSourceEditorWindow; LSourceEditorPageControl: TSourceEditorPageControl; begin if IsFormDesign(AForm) then begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.Screen_FormDel ', DbgSName(AForm)); {$ENDIF} AForm.Parent := nil; for LSourceEditorWindow in SourceEditorWindows do begin if LSourceEditorWindow.ActiveDesignForm <> nil then if LSourceEditorWindow.ActiveDesignForm.Form = AForm then // don't set ActiveDesignForm := nil! we can't call OnChange tab, because tab don't exist anymore LSourceEditorWindow.RemoveActiveDesignForm; for LSourceEditorPageControl in LSourceEditorWindow.PageControlList do if LSourceEditorPageControl.PageControl.DesignForm <> nil then if LSourceEditorPageControl.PageControl.DesignForm.Form = AForm then begin LSourceEditorPageControl.PageControl.DesignForm := nil; LSourceEditorPageControl.PageControl.PageIndex := 0; end; end; DesignForms.Remove(AForm); end else if AForm is TSourceEditorWindowInterface then AForm.RemoveHandlerOnChangeBounds(@GlobalSNOnChangeBounds); end; class procedure TDockedMainIDE.WindowCreate(Sender: TObject); var LSourceEditorWindow: TSourceEditorWindowInterface; begin if not (Sender is TSourceEditorWindowInterface) then Exit; if Sender.ClassNameIs('TSourceNotebook') then begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.WindowCreate SourceEditor created'); {$ENDIF} LSourceEditorWindow := Sender as TSourceEditorWindowInterface; SourceEditorWindows.Add(TSourceEditorWindow.Create(LSourceEditorWindow)); end; end; class procedure TDockedMainIDE.WindowDestroy(Sender: TObject); var LDesignForm: TDesignForm; begin if not (Sender is TSourceEditorWindowInterface) then Exit; {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.WindowDestroy'); {$ENDIF} for LDesignForm in DesignForms do if LDesignForm.LastActiveSourceWindow = Sender then LDesignForm.LastActiveSourceWindow := nil; SourceEditorWindows.Remove(Sender as TSourceEditorWindowInterface); end; class procedure TDockedMainIDE.WindowHide(Sender: TObject); var LSourceEditorWindow: TSourceEditorWindow; LDesignForm: TDesignForm; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.WindowHide'); {$ENDIF} LSourceEditorWindow := SourceEditorWindows.SourceEditorWindow[Sender as TSourceEditorWindowInterface]; if not Assigned(LSourceEditorWindow) or (LSourceEditorWindow.ActiveDesignForm = nil) then Exit; LDesignForm := LSourceEditorWindow.ActiveDesignForm; LDesignForm.HideWindow; end; class procedure TDockedMainIDE.WindowShow(Sender: TObject); var LSourceEditorWindow: TSourceEditorWindow; LDesignForm: TDesignForm; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.WindowShow'); {$ENDIF} LSourceEditorWindow := SourceEditorWindows.SourceEditorWindow[Sender as TSourceEditorWindowInterface]; if not Assigned(LSourceEditorWindow) or (LSourceEditorWindow.ActiveDesignForm = nil) then Exit; LDesignForm := LSourceEditorWindow.ActiveDesignForm; LDesignForm.ShowWindow; end; class procedure TDockedMainIDE.EditorActivated(Sender: TObject); var LDesigner: TIDesigner; LSourceEditor: TSourceEditorInterface; var LPageCtrl: TModulePageControl; LSourceEditorWindowInterface: TSourceEditorWindowInterface; LDesignForm: TDesignForm; begin if Sender is TSourceEditorInterface then begin LSourceEditor := TSourceEditorInterface(Sender); {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.EditorActivated [' + LSourceEditor.PageCaption + '] SourceEditorWindow[' + SourceEditorWindowCaption(LSourceEditor) + ']'); {$ENDIF} // if we create directly new project then Activate is called without EditorCreate... if not (LSourceEditor.EditorControl.Parent.Parent is TModulePageControl) then begin // possible is situation when we moved tab into other window // then was not called event EditorDestroy - that generates problems with switching tabs // or when we moving tab to first window ( then is raising : duplicates not allowed in dictionary). if SourceEditorWindows.LastSourceEditorNotFound then EditorDestroyed(nil); EditorCreate(Sender); end; LDesigner := LSourceEditor.GetDesigner(True); // should be performed during EditorCreate (parent of parent is module page ctrl) LPageCtrl := TModulePageControl(LSourceEditor.EditorControl.Parent.Parent); if LPageCtrl = nil then Exit; LDesignForm := SourceEditorWindows.FindDesignForm(LPageCtrl); if LDesigner = nil then LPageCtrl.RemoveDesignPages else begin if not Assigned(LPageCtrl.Resizer) then LPageCtrl.CreateResizer; LPageCtrl.CreateTabSheetDesigner; if LDesignForm.IsAnchorDesign then LPageCtrl.CreateTabSheetAnchors; end; LSourceEditorWindowInterface := TSourceEditorWindowInterface(LPageCtrl.Owner); SourceEditorWindows.LastActiveSourceEditorWindow := LSourceEditorWindowInterface; SourceEditorWindows.LastActiveSourceEditor := LSourceEditor; // when we switch tab, design form should be hidden if (LDesigner = nil) or (LDesignForm = nil) then SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].ActiveDesignForm := nil else begin // during form loading for example from package, ActiveDesignForm assignment, // blocks the message queue responsible for hiding form // We can't check it because there are some forms where designing is not handled yet. // (for that kind of forms is returned empty designform data) // maybe we can fix this in future if not LDesignForm.Hiding then // Prevent unexpected events (when is deactivated some control outside designed form) if (LDesignForm.LastActiveSourceWindow = LSourceEditorWindowInterface) // important!!! for many error - switching between editors... and LPageCtrl.DesignerPageActive then SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].ActiveDesignForm := LDesignForm else SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].ActiveDesignForm := nil; end; if LPageCtrl.DesignerPageActive then begin if not LDesignForm.Hiding then begin SourceEditorWindows.ShowCodeTabSkipCurrent(LPageCtrl, LDesignForm); LPageCtrl.AdjustPage; // don't focus designer here, focus can be on ObjectInspector, then // in OI Events deletes component instead event handler end; end else begin if LDesignForm <> nil then LDesignForm.HideWindow; LPageCtrl.InitPage; end; end else begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.EditorActivated [' + DbgSName(Sender) + '] - not a Source Editor!');{$ENDIF} end; end; class procedure TDockedMainIDE.EditorCreate(Sender: TObject); var LSourceEditor: TSourceEditorInterface; LSourceEditorWindowInterface: TSourceEditorWindowInterface; LParent: TWinControl; LPageCtrl: TModulePageControl; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.EditorCreate'); {$ENDIF} LSourceEditor := Sender as TSourceEditorInterface; if LSourceEditor.EditorControl.Parent.Parent is TModulePageControl then Exit; LParent := LSourceEditor.EditorControl.Parent; LPageCtrl := TModulePageControl.Create(LSourceEditor.EditorControl.Owner); LSourceEditor.EditorControl.Parent := LPageCtrl.Pages[0]; // ! SynEdit :) LPageCtrl.OnChange := @TabChange; LPageCtrl.Parent := LParent; LSourceEditorWindowInterface := TSourceEditorWindowInterface(LPageCtrl.Owner); SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].AddPageCtrl(LSourceEditor, LPageCtrl); end; class procedure TDockedMainIDE.EditorDestroyed(Sender: TObject); var LSourceEditor: TSourceEditorInterface; LPageCtrl: TModulePageControl; LSourceEditorWindowInterface: TSourceEditorWindowInterface; LDesignForm: TDesignForm; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.EditorDestroyed'); {$ENDIF} // sender is here as special parameter, because is possible situation where is moved editor // to another window and was not triggered EditorDestroy - for more info goto editoractivate if Sender = nil then LSourceEditor := SourceEditorWindows.LastActiveSourceEditor else LSourceEditor := TSourceEditorInterface(Sender); // parent don't exist anymore and we must search in each window... if Sender = nil then // but not for Sender = nil :P LPageCtrl := SourceEditorWindows.LastActiveModulePageControl else LPageCtrl := SourceEditorWindows.FindModulePageControl(LSourceEditor); if LPageCtrl = nil then Exit; LDesignForm := DesignForms.Find(LSourceEditor.GetDesigner(False)); // goto first comment (forced destroy) if Sender = nil then LSourceEditorWindowInterface := SourceEditorWindows.LastActiveSourceEditorWindow else LSourceEditorWindowInterface := TSourceEditorWindowInterface(LPageCtrl.Owner); if LDesignForm <> nil then begin SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].ActiveDesignForm := nil; LDesignForm.LastActiveSourceWindow := nil; end; SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].RemovePageCtrl(LSourceEditor); LPageCtrl.Free; end; class procedure TDockedMainIDE.TabChange(Sender: TObject); var LActiveSourceWindowInterface: TSourceEditorWindowInterface; LSourceEditorWindow: TSourceEditorWindow; LDesigner: TIDesigner; LDesignForm: TDesignForm; LPageCtrl: TModulePageControl; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.TabChange'); {$ENDIF} // activate proper source editor window when user is clicking on page. // (at clicking time can be active other source window) LActiveSourceWindowInterface := TComponent(Sender).Owner as TSourceEditorWindowInterface; if LActiveSourceWindowInterface <> SourceEditorManagerIntf.ActiveSourceWindow then SourceEditorManagerIntf.ActiveSourceWindow := LActiveSourceWindowInterface; LPageCtrl := TModulePageControl(Sender); if LActiveSourceWindowInterface.ActiveEditor = nil then Exit; if LPageCtrl = nil then Exit; // in case there is no module and is visible page other than code page. LDesigner := LActiveSourceWindowInterface.ActiveEditor.GetDesigner(True); LDesignForm := DesignForms.Find(LDesigner); if LDesignForm = nil then Exit; LSourceEditorWindow := SourceEditorWindows.SourceEditorWindow[LActiveSourceWindowInterface]; if LSourceEditorWindow = nil then Exit; if not LPageCtrl.DesignerPageActive then begin LSourceEditorWindow.ActiveDesignForm := nil; LPageCtrl.InitPage; LActiveSourceWindowInterface.ActiveEditor.EditorControl.SetFocus; end else begin LSourceEditorWindow.ActiveDesignForm := LDesignForm; // enable autosizing after creating a new form DockedTabMaster.EnableAutoSizing(LDesignForm.Form); SourceEditorWindows.ShowCodeTabSkipCurrent(LPageCtrl, LDesignForm); LPageCtrl.DesignerSetFocus; end; end; class procedure TDockedMainIDE.GlobalSNOnChangeBounds(Sender: TObject); var LSourceEditorWindowInterface: TSourceEditorWindowInterface; LSourceEditorWindow: TSourceEditorWindow; LDesignForm: TDesignForm; LPageCtrl: TModulePageControl; LResizer: TResizer; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.GlobalSNOnChangeBounds'); {$ENDIF} // Check parent. Maybe is different? If yes then window changed state (docked/undocked) and we need to perform few actions LSourceEditorWindowInterface := Sender as TSourceEditorWindowInterface; // dock/undock event :) LSourceEditorWindow := SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface]; if LSourceEditorWindow = nil then Exit; if LSourceEditorWindow.LastTopParent <> LSourceEditorWindowInterface.GetTopParent then begin LSourceEditorWindow.LastTopParent := LSourceEditorWindowInterface.GetTopParent; // refresh for popupparent LDesignForm := LSourceEditorWindow.ActiveDesignForm; LSourceEditorWindow.ActiveDesignForm := nil; LSourceEditorWindow.ActiveDesignForm := LDesignForm; if LDesignForm <> nil then begin LPageCtrl := SourceEditorWindows.FindModulePageControl(LSourceEditorWindowInterface.ActiveEditor); if not Assigned(LPageCtrl) then Exit; LResizer := LPageCtrl.Resizer; if not Assigned(LResizer) then Exit; LDesignForm.Form.Parent := LResizer.FormContainer; SetTimer(LDesignForm.Form.Handle, WM_BOUNDTODESIGNTABSHEET, 10, nil); end; end; end; class procedure TDockedMainIDE.OnShowDesignerForm(Sender: TObject; AEditor: TSourceEditorInterface; AComponentPaletteClassSelected: Boolean); var LDesignForm: TDesignForm; LPageCtrl: TModulePageControl; LSourceEditorWindow: TSourceEditorWindow; LSourceEditorInterface: TSourceEditorInterface; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnShowDesignerForm'); {$ENDIF} LDesignForm := DesignForms.Find(TCustomForm(Sender).Designer); if (LDesignForm = nil) or LDesignForm.Hiding then Exit; LPageCtrl := SourceEditorWindows.FindModulePageControl(SourceEditorManagerIntf.ActiveEditor); if LPageCtrl = nil then Exit; if AComponentPaletteClassSelected then begin // if form is already opened do nothing, if not then show form for active module. for LSourceEditorWindow in SourceEditorWindows do begin LSourceEditorInterface := LSourceEditorWindow.SourceEditorWindowInterface.ActiveEditor; if (LSourceEditorInterface = nil) or (LSourceEditorInterface.GetDesigner(True) <> LDesignForm.Designer) then Continue; LPageCtrl := SourceEditorWindows.FindModulePageControl(LSourceEditorInterface); if LPageCtrl.FormPageActive then Exit; end; end; DockedTabMaster.ShowDesigner(SourceEditorManagerIntf.ActiveEditor); end; class procedure TDockedMainIDE.OnShowSrcEditor(Sender: TObject); begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnShowSrcEditor'); {$ENDIF} DockedTabMaster.ShowCode(Sender as TSourceEditorInterface); end; class procedure TDockedMainIDE.OnDesignShowMethod(const Name: String); var LDesignForm: TDesignForm; LSecondEditor: TSourceEditorInterface = nil; LSourceEditorWindowInterface: TSourceEditorWindowInterface; i: Integer; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignShowMethod'); {$ENDIF} if FormEditingHook = nil then Exit; LDesignForm := DesignForms.Find(FormEditingHook.GetCurrentDesigner); if LDesignForm = nil then Exit; for i := 0 to SourceEditorManagerIntf.SourceWindowCount - 1 do begin LSourceEditorWindowInterface := SourceEditorManagerIntf.SourceWindows[i]; if LDesignForm.LastActiveSourceWindow = LSourceEditorWindowInterface then Continue; if LSourceEditorWindowInterface.ActiveEditor <> nil then if LSourceEditorWindowInterface.ActiveEditor.GetDesigner(True) = LDesignForm.Designer then begin LSecondEditor := LSourceEditorWindowInterface.ActiveEditor; Break; end; end; if Assigned(LSecondEditor) then begin DockedTabMaster.ShowCode(LSecondEditor); LazarusIDE.DoShowMethod(LSecondEditor, Name); end else if Assigned(LDesignForm.LastActiveSourceWindow) then DockedTabMaster.ShowCode(LDesignForm.LastActiveSourceWindow.ActiveEditor); end; class procedure TDockedMainIDE.OnDesignRefreshPropertyValues; var LPageCtrl: TModulePageControl; function RootIsSelected: Boolean; var LSelection: TPersistentSelectionList; i: Integer; begin Result := False; LSelection := TPersistentSelectionList.Create; try GlobalDesignHook.GetSelection(LSelection); for i := 0 to LSelection.Count - 1 do if LSelection.Items[i] = GlobalDesignHook.LookupRoot then begin Result := True; Break; end; finally LSelection.Free; end; end; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignRefreshPropertyValues'); {$ENDIF} if not (GlobalDesignHook.LookupRoot is TCustomFrame) and not (GlobalDesignHook.LookupRoot is TCustomForm) then Exit; LPageCtrl := GetCurrentPageControl; if not Assigned(LPageCtrl) then Exit; if not ((LPageCtrl.PageIndex = 2) or RootIsSelected) then Exit; LPageCtrl.AdjustPage; end; class procedure TDockedMainIDE.OnDesignModified(Sender: TObject); var LPageCtrl: TModulePageControl; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignModified'); {$ENDIF} LPageCtrl := GetCurrentPageControl; if not Assigned(LPageCtrl) then Exit; if not Assigned(LPageCtrl.Resizer) then Exit; LPageCtrl.Resizer.ResizeFrame.OnModified; end; class procedure TDockedMainIDE.OnDesignPersistentAdded(APersistent: TPersistent; Select: Boolean); begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignPersistentAdded'); {$ENDIF} OnDesignModified(nil); end; class procedure TDockedMainIDE.OnDesignPersistentDeleted(APersistent: TPersistent); begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignPersistentDeleted'); {$ENDIF} OnDesignModified(nil); end; class procedure TDockedMainIDE.OnDesignMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var LPageCtrl: TModulePageControl; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} writeln('TDockedMainIDE.OnDesignMouseDown'); {$ENDIF} LPageCtrl := GetCurrentPageControl; if not Assigned(LPageCtrl) then Exit; LPageCtrl.DesignerSetFocus; end; class procedure TDockedMainIDE.OnDesignSetSelection( const ASelection: TPersistentSelectionList); var LDesignForm: TDesignForm; LSelectedControl: TControl; begin {$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignSetSelection'); {$ENDIF} LDesignForm := DesignForms.Find(FormEditingHook.GetCurrentDesigner); if LDesignForm = nil then Exit; if (ASelection.Count = 1) and (ASelection[0] is TControl) then LSelectedControl := TControl(ASelection[0]); if LSelectedControl = LDesignForm.SelectedControl then Exit; LDesignForm.SelectedControl := LSelectedControl; OnDesignModified(nil); end; end.