DockedFormEditor: Create ModulePageControl in empty SourceEditorWindow at cloning a unit

git-svn-id: trunk@64923 -
This commit is contained in:
michl 2021-04-04 21:06:58 +00:00
parent 14ef04d220
commit 90d5a28700
3 changed files with 151 additions and 56 deletions

View File

@ -102,8 +102,6 @@ type
end;
var
LastActiveSourceEditorWindow: TSourceEditorWindowInterface = nil;
LastActiveSourceEditor: TSourceEditorInterface = nil;
DockedTabMaster: TDockedTabMaster absolute IDETabMaster;
implementation
@ -232,12 +230,12 @@ var
LPageCtrl: TModulePageControl;
LPageIndex: Integer;
begin
LPageCtrl := SourceEditorWindows.FindModulePageControl(LastActiveSourceEditor);
LPageCtrl := SourceEditorWindows.LastActiveModulePageControl;
LPageIndex := LPageCtrl.PageIndex;
DesignForms.RemoveAllAnchorDesigner;
SourceEditorWindows.ShowCodeTabSkipCurrent(nil, nil);
SourceEditorWindows.RefreshActivePageControls;
TDockedMainIDE.EditorActivated(LastActiveSourceEditor);
TDockedMainIDE.EditorActivated(SourceEditorWindows.LastActiveSourceEditor);
if LPageIndex = 0 then Exit;
LPageCtrl.TabIndex := LPageIndex;
LPageCtrl.OnChange(LPageCtrl);
@ -352,8 +350,6 @@ begin
if LDesignForm.LastActiveSourceWindow = Sender then
LDesignForm.LastActiveSourceWindow := nil;
SourceEditorWindows.Remove(Sender as TSourceEditorWindowInterface);
if LastActiveSourceEditorWindow = Sender then
LastActiveSourceEditorWindow := nil;
end;
class procedure TDockedMainIDE.WindowHide(Sender: TObject);
@ -386,35 +382,6 @@ class procedure TDockedMainIDE.EditorActivated(Sender: TObject);
var
LDesigner: TIDesigner;
LSourceEditor: TSourceEditorInterface;
function LastSourceEditorNotFound: Boolean;
var
i: Integer;
LSourceEditorPageControl: TSourceEditorPageControl;
LSourceEditorWindow: TSourceEditorWindow;
begin
if (LastActiveSourceEditorWindow = nil) or (LastActiveSourceEditor = nil) then
Exit(False);
LSourceEditorWindow := SourceEditorWindows.SourceEditorWindow[LastActiveSourceEditorWindow];
for LSourceEditorPageControl in LSourceEditorWindow.PageControlList do
begin
Result := True;
for i := 0 to LastActiveSourceEditorWindow.Count - 1 do
if LSourceEditorPageControl.SourceEditor = LastActiveSourceEditorWindow.Items[i] then
begin
Result := False;
Break;
end;
if Result then
begin
LastActiveSourceEditor := LSourceEditorPageControl.SourceEditor; // after moving code editor into other window, sometimes IDE switch to other tab :\ damn... this line prevent this.
Exit;
end;
end;
Result := False;
end;
var
LPageCtrl: TModulePageControl;
LSourceEditorWindowInterface: TSourceEditorWindowInterface;
@ -422,15 +389,18 @@ var
begin
if Sender is TSourceEditorInterface then
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.EditorActivated');{$ENDIF}
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 LastSourceEditorNotFound then
if SourceEditorWindows.LastSourceEditorNotFound then
EditorDestroyed(nil);
EditorCreate(Sender);
end;
@ -451,8 +421,8 @@ begin
end;
LSourceEditorWindowInterface := TSourceEditorWindowInterface(LPageCtrl.Owner);
LastActiveSourceEditorWindow := LSourceEditorWindowInterface;
LastActiveSourceEditor := LSourceEditor;
SourceEditorWindows.LastActiveSourceEditorWindow := LSourceEditorWindowInterface;
SourceEditorWindows.LastActiveSourceEditor := LSourceEditor;
// when we switch tab, design form should be hidden
if (LDesigner = nil) or (LDesignForm = nil) then
@ -487,9 +457,9 @@ begin
LDesignForm.HideWindow;
LPageCtrl.InitPage;
end;
end
else
SourceEditorWindows.RefreshActivePageControls;
end else begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.EditorActivated [' + DbgSName(Sender) + '] - not a Source Editor!');{$ENDIF}
end;
end;
class procedure TDockedMainIDE.EditorCreate(Sender: TObject);
@ -516,23 +486,20 @@ var
LSourceEditor: TSourceEditorInterface;
LPageCtrl: TModulePageControl;
LSourceEditorWindowInterface: TSourceEditorWindowInterface;
LSourceEditorWindow: TSourceEditorWindow;
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 := LastActiveSourceEditor
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
begin
LSourceEditorWindow := SourceEditorWindows.SourceEditorWindow[LastActiveSourceEditorWindow];
LPageCtrl := LSourceEditorWindow.PageControlList.PageControl[LastActiveSourceEditor]
end else
LPageCtrl := SourceEditorWindows.LastActiveModulePageControl
else
LPageCtrl := SourceEditorWindows.FindModulePageControl(LSourceEditor);
if LPageCtrl = nil then Exit;
@ -541,7 +508,7 @@ begin
// goto first comment (forced destroy)
if Sender = nil then
LSourceEditorWindowInterface := LastActiveSourceEditorWindow
LSourceEditorWindowInterface := SourceEditorWindows.LastActiveSourceEditorWindow
else
LSourceEditorWindowInterface := TSourceEditorWindowInterface(LPageCtrl.Owner);
@ -553,9 +520,6 @@ begin
SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].RemovePageCtrl(LSourceEditor);
LPageCtrl.Free;
if LastActiveSourceEditor = LSourceEditor then
LastActiveSourceEditor := nil;
end;
class procedure TDockedMainIDE.TabChange(Sender: TObject);

View File

@ -20,18 +20,20 @@ unit DockedSourceEditorWindow;
{$modeswitch advancedrecords}
{$modeswitch typehelpers}
{ $define DEBUGDOCKEDFORMEDITOR}
interface
uses
// RTL
Classes, SysUtils, fgl,
// LCL
Forms, Controls,
Forms, Controls, LCLProc,
// IDEIntf
SrcEditorIntf, LazIDEIntf, FormEditingIntf, ExtendedNotebook,
// DockedFormEditor
DockedSourceEditorPageControls, DockedDesignForm, DockedModulePageControl,
DockedOptionsIDE;
DockedOptionsIDE, DockedTools;
type
@ -40,6 +42,7 @@ type
TSourceEditorWindow = class
private
FActiveDesignForm: TDesignForm;
FLastActiveSourceEditor: TSourceEditorInterface;
FLastTopParent: TControl;
FNotebookPageChanged: TNotifyEvent;
FPageControlList: TSourceEditorPageControls;
@ -49,6 +52,7 @@ type
procedure HookIntoOnPageChanged;
procedure SetActiveDesignForm(const AValue: TDesignForm);
procedure SourceEditorPageChanged(Sender: TObject);
procedure UpdateEditorPageCaption(Sender: TObject);
public
constructor Create(ASourceEditorWindowInterface: TSourceEditorWindowInterface);
destructor Destroy; override;
@ -60,6 +64,7 @@ type
public
property ActiveDesignForm: TDesignForm read FActiveDesignForm write SetActiveDesignForm;
property ActiveEditor: TSourceEditorInterface read GetActiveEditor;
property LastActiveSourceEditor: TSourceEditorInterface read FLastActiveSourceEditor write FLastActiveSourceEditor;
property LastTopParent: TControl read FLastTopParent write FLastTopParent;
property PageControlList: TSourceEditorPageControls read FPageControlList;
property SourceEditorWindowInterface: TSourceEditorWindowInterface read FSourceEditorWindowInterface;
@ -69,9 +74,14 @@ type
TSourceEditorWindows = class(specialize TFPGList<TSourceEditorWindow>)
private
FLastActiveSourceEditorWindow: TSourceEditorWindowInterface;
function GetLastActiveModulePageControl: TModulePageControl;
function GetLastActiveSourceEditor: TSourceEditorInterface;
function GetWindowInterface(ASrcEditor: TSourceEditorWindow): TSourceEditorWindowInterface;
function GetSourceEditorWindow(AWindowInterface: TSourceEditorWindowInterface): TSourceEditorWindow;
procedure SetLastActiveSourceEditor(AValue: TSourceEditorInterface);
public
constructor CreateNew;
destructor Destroy; override;
function Contains(AWindowInterface: TSourceEditorWindowInterface): Boolean;
function Contains(ASrcEditor: TSourceEditorWindow): Boolean;
@ -79,11 +89,15 @@ type
function FindDesignForm(AModulePageCtrl: TModulePageControl): TDesignForm;
function FindModulePageControl(ASrcEditor: TSourceEditorInterface): TModulePageControl;
function IndexOf(AWindowInterface: TSourceEditorWindowInterface): Integer; overload;
function LastSourceEditorNotFound: Boolean;
procedure RefreshActivePageControls;
procedure RefreshAllPageControls;
procedure Remove(AWindowInterface: TSourceEditorWindowInterface); overload;
procedure ShowCodeTabSkipCurrent(CurrentPageCtrl: TModulePageControl; ADesignForm: TDesignForm);
public
property LastActiveSourceEditorWindow: TSourceEditorWindowInterface read FLastActiveSourceEditorWindow write FLastActiveSourceEditorWindow;
property LastActiveSourceEditor: TSourceEditorInterface read GetLastActiveSourceEditor write SetLastActiveSourceEditor;
property LastActiveModulePageControl: TModulePageControl read GetLastActiveModulePageControl;
property WindowInterface[ASrcEditor: TSourceEditorWindow]: TSourceEditorWindowInterface read GetWindowInterface;
property SourceEditorWindow[AWindowInterface: TSourceEditorWindowInterface]: TSourceEditorWindow read GetSourceEditorWindow;
end;
@ -139,6 +153,7 @@ procedure TSourceEditorWindow.SourceEditorPageChanged(Sender: TObject);
var
LPageCtrl: TModulePageControl;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TSourceEditorWindow.SourceEditorPageChanged SourceEditorWindow[' + FSourceEditorWindowInterface.Caption + ']'); {$ENDIF}
FNotebookPageChanged(Sender);
LPageCtrl := FindModulePageControl(ActiveEditor);
if not Assigned(LPageCtrl) then Exit;
@ -153,12 +168,34 @@ begin
end;
end;
procedure TSourceEditorWindow.UpdateEditorPageCaption(Sender: TObject);
var
LSourceEditor: TSourceEditorInterface;
LSourceEditorWindow: TSourceEditorWindowInterface;
begin
// if a unit is cloned to undocked empty source editor window, the ModulePageControl
// is not created, the only workaround I found is, to activate the new created
// source editor in this window
if not (Sender is TSourceEditorInterface) then Exit;
LSourceEditor := TSourceEditorInterface(Sender);
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TSourceEditorWindow.UpdateEditorPageCaption [' + SourceEditorWindowCaption(LSourceEditor) + ']'); {$ENDIF}
LSourceEditorWindow := SourceEditorWindow(LSourceEditor);
if not Assigned(LSourceEditorWindow)
or (LSourceEditorWindow.ActiveEditor <> nil)
or (SourceEditorWindows.LastActiveSourceEditorWindow = LSourceEditorWindow)
then
Exit;
LSourceEditorWindow.ActiveEditor := LSourceEditor;
end;
constructor TSourceEditorWindow.Create(ASourceEditorWindowInterface: TSourceEditorWindowInterface);
begin
FLastActiveSourceEditor := nil;
FSourceEditorWindowInterface := ASourceEditorWindowInterface;
FPageControlList := TSourceEditorPageControls.Create;
FSourceEditorNotebook := nil;
HookIntoOnPageChanged;
FSourceEditorWindowInterface.AddUpdateEditorPageCaptionHandler(@UpdateEditorPageCaption);
end;
destructor TSourceEditorWindow.Destroy;
@ -207,6 +244,8 @@ end;
procedure TSourceEditorWindow.RemovePageCtrl(ASourceEditor: TSourceEditorInterface);
begin
FPageControlList.Remove(ASourceEditor);
if LastActiveSourceEditor = ASourceEditor then
LastActiveSourceEditor := nil;
end;
{ TSourceEditorWindows }
@ -222,6 +261,22 @@ begin
Result := nil;
end;
function TSourceEditorWindows.GetLastActiveModulePageControl: TModulePageControl;
begin
Result := FindModulePageControl(LastActiveSourceEditor);
end;
function TSourceEditorWindows.GetLastActiveSourceEditor: TSourceEditorInterface;
var
LSourceEditorWindow: TSourceEditorWindow;
begin
Result := nil;
if not Assigned(LastActiveSourceEditorWindow) then Exit;
LSourceEditorWindow := SourceEditorWindow[LastActiveSourceEditorWindow];
if not Assigned(LSourceEditorWindow) then Exit;
Result := LSourceEditorWindow.LastActiveSourceEditor;
end;
function TSourceEditorWindows.GetSourceEditorWindow(AWindowInterface: TSourceEditorWindowInterface): TSourceEditorWindow;
var
LIndex: Integer;
@ -233,6 +288,22 @@ begin
Result := nil;
end;
procedure TSourceEditorWindows.SetLastActiveSourceEditor(AValue: TSourceEditorInterface);
var
LSourceEditorWindow: TSourceEditorWindow;
begin
if not Assigned(LastActiveSourceEditorWindow) then Exit;
LSourceEditorWindow := SourceEditorWindow[LastActiveSourceEditorWindow];
if not Assigned(LSourceEditorWindow) then Exit;
LSourceEditorWindow.LastActiveSourceEditor := AValue;
end;
constructor TSourceEditorWindows.CreateNew;
begin
inherited Create;
FLastActiveSourceEditorWindow := nil;
end;
destructor TSourceEditorWindows.Destroy;
begin
while Count > 0 do
@ -298,6 +369,36 @@ begin
Exit(i);
end;
function TSourceEditorWindows.LastSourceEditorNotFound: Boolean;
var
i: Integer;
LSourceEditorPageControl: TSourceEditorPageControl;
LSourceEditorWindow: TSourceEditorWindow;
begin
if (LastActiveSourceEditorWindow = nil) or (LastActiveSourceEditor = nil) then
Exit(False);
LSourceEditorWindow := SourceEditorWindow[LastActiveSourceEditorWindow];
for LSourceEditorPageControl in LSourceEditorWindow.PageControlList do
begin
Result := True;
for i := 0 to LastActiveSourceEditorWindow.Count - 1 do
if LSourceEditorPageControl.SourceEditor = LastActiveSourceEditorWindow.Items[i] then
begin
Result := False;
Break;
end;
if Result then
begin
// after moving code editor into other window, sometimes IDE switch to other tab
// this line prevent this.
LSourceEditorWindow.LastActiveSourceEditor := LSourceEditorPageControl.SourceEditor;
Exit;
end;
end;
Result := False;
end;
procedure TSourceEditorWindows.RefreshActivePageControls;
var
LWindow: TSourceEditorWindow;
@ -343,6 +444,8 @@ begin
LIndex := IndexOf(AWindowInterface);
if LIndex < 0 then Exit;
DeleteItem(LIndex);
if LastActiveSourceEditorWindow = AWindowInterface then
LastActiveSourceEditorWindow := nil;
end;
procedure TSourceEditorWindows.ShowCodeTabSkipCurrent(CurrentPageCtrl: TModulePageControl; ADesignForm: TDesignForm);
@ -362,7 +465,7 @@ begin
end;
initialization
SourceEditorWindows := TSourceEditorWindows.Create;
SourceEditorWindows := TSourceEditorWindows.CreateNew;
finalization
SourceEditorWindows.Free;

View File

@ -19,7 +19,7 @@ uses
// RTL, FCL
Classes, SysUtils,
// LCL
LCLProc, Forms,
LCLProc, Forms, Controls,
// IDEIntf
IDEMsgIntf, SrcEditorIntf, IDEExternToolIntf,
// DockedFormEditor
@ -35,6 +35,8 @@ function EnumerationString(Str1, Str2: String): String;
function FindSourceEditorForDesigner(ADesigner: TIDesigner): TSourceEditorInterface;
procedure IDEMessage(AString: String);
function LinedString(Str1, Str2: String): String;
function SourceEditorWindow(ASourceEditor: TSourceEditorInterface): TSourceEditorWindowInterface;
function SourceEditorWindowCaption(ASourceEditor: TSourceEditorInterface): String;
implementation
@ -88,5 +90,31 @@ begin
Result := Str1 + LineEnding + Str2;
end;
function SourceEditorWindow(ASourceEditor: TSourceEditorInterface): TSourceEditorWindowInterface;
var
LWinControl: TWinControl;
begin
Result := nil;
if not Assigned(ASourceEditor) then Exit;
LWinControl := ASourceEditor.EditorControl;
while Assigned(LWinControl) do
begin
if LWinControl is TSourceEditorWindowInterface then
Exit(TSourceEditorWindowInterface(LWinControl));
LWinControl := LWinControl.Parent;
end;
end;
function SourceEditorWindowCaption(ASourceEditor: TSourceEditorInterface): String;
var
LSourceEditorWindowInterface: TSourceEditorWindowInterface;
begin
LSourceEditorWindowInterface := SourceEditorWindow(ASourceEditor);
if Assigned(LSourceEditorWindowInterface) then
Result := LSourceEditorWindowInterface.Caption
else
Result := 'nil';
end;
end.