diff --git a/ide/main.pp b/ide/main.pp index 62e5e14ccb..fb5219c763 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -127,10 +127,10 @@ type //procedure FormShow(Sender: TObject); procedure MainIDEFormClose(Sender: TObject; var CloseAction: TCloseAction); procedure MainIDEFormCloseQuery(Sender: TObject; var CanClose: boolean); - procedure MainIDEFormActivate(Sender: TObject); //procedure FormPaint(Sender: TObject); procedure OnApplicationUserInput(Sender: TObject; Msg: Cardinal); procedure OnApplicationIdle(Sender: TObject); + procedure OnApplicationActivate(Sender: TObject); procedure OnScreenRemoveForm(Sender: TObject; AForm: TCustomForm); // file menu @@ -451,6 +451,8 @@ type FDisplayState: TDisplayState; FLastFormActivated: TCustomForm;// used to find the last form so you can // display the correct tab + FCheckingFilesOnDisk: boolean; + FCheckFilesOnDiskNeeded: boolean; FOpenEditorsOnCodeToolChange: boolean; FRunProcess: TProcess; // temp solution, will be replaced by dummydebugger @@ -693,7 +695,7 @@ type IsPartOfProject:boolean): TModalResult; override; function DoRenameUnitLowerCase(AnUnitInfo: TUnitInfo; AskUser: boolean): TModalresult; - function DoCheckFilesOnDisk: TModalResult; override; + function DoCheckFilesOnDisk(Instantaneous: boolean = false): TModalResult; override; function DoPublishModule(Options: TPublishModuleOptions; const SrcDirectory, DestDirectory: string ): TModalResult; override; @@ -1061,6 +1063,7 @@ begin // set OnIdle handlers Application.AddOnUserInputHandler(@OnApplicationUserInput,true); Application.AddOnIdleHandler(@OnApplicationIdle,true); + Application.AddOnActivateHandler(@OnApplicationActivate,true); Screen.AddHandlerRemoveForm(@OnScreenRemoveForm,true); SetupHints; @@ -1248,11 +1251,6 @@ begin CanClose:=(DoCloseProject <> mrAbort); end; -procedure TMainIDE.MainIDEFormActivate(Sender: TObject); -begin - DoCheckFilesOnDisk; -end; - {------------------------------------------------------------------------------} type TMoveFlags = set of (mfTop, mfLeft); @@ -1974,7 +1972,6 @@ procedure TMainIDE.ConnectMainBarEvents; begin MainIDEBar.OnClose := @MainIDEFormClose; MainIDEBar.OnCloseQuery := @MainIDEFormCloseQuery; - MainIDEBar.OnActivate := @MainIDEFormActivate; end; {------------------------------------------------------------------------------} @@ -6046,7 +6043,7 @@ begin writeln('TMainIDE.DoSaveProject A SaveAs=',sfSaveAs in Flags,' SaveToTestDir=',sfSaveToTestDir in Flags,' ProjectInfoFile=',Project1.ProjectInfoFile); {$ENDIF} - if DoCheckFilesOnDisk in [mrCancel,mrAbort] then exit; + if DoCheckFilesOnDisk(true) in [mrCancel,mrAbort] then exit; // check that all new units are saved first to get valid filenames // (this can alter the mainunit: e.g. used unit names) @@ -8209,36 +8206,51 @@ begin Result:=DoRenameUnit(AnUnitInfo,NewFilename,NewUnitName,ResourceCode); end; -function TMainIDE.DoCheckFilesOnDisk: TModalResult; +function TMainIDE.DoCheckFilesOnDisk(Instantaneous: boolean): TModalResult; var AnUnitList: TList; // list of TUnitInfo i: integer; CurUnit: TUnitInfo; begin Result:=mrOk; + if FCheckingFilesOnDisk then exit; if Project1=nil then exit; - InvalidateFileStateCache; - Project1.GetUnitsChangedOnDisk(AnUnitList); - if AnUnitList=nil then exit; - Result:=ShowDiskDiffsDialog(AnUnitList); - if Result in [mrYesToAll] then - Result:=mrOk; - for i:=0 to AnUnitList.Count-1 do begin - CurUnit:=TUnitInfo(AnUnitList[i]); - if Result=mrOk then begin - if CurUnit.EditorIndex>=0 then begin - Result:=DoOpenEditorFile('',CurUnit.EditorIndex,[ofRevert]); - end else if CurUnit.IsMainUnit then begin - Result:=DoRevertMainUnit; - end else - Result:=mrIgnore; - if Result=mrAbort then exit; - end else begin - CurUnit.IgnoreCurrentFileDateOnDisk; - end; - Result:=mrOk; + if Screen.GetCurrentModalForm<>nil then exit; + + if not Instantaneous then begin + FCheckFilesOnDiskNeeded:=true; + exit; + end; + FCheckFilesOnDiskNeeded:=false; + + //debugln('TMainIDE.DoCheckFilesOnDisk'); + FCheckingFilesOnDisk:=true; + try + InvalidateFileStateCache; + Project1.GetUnitsChangedOnDisk(AnUnitList); + if AnUnitList=nil then exit; + Result:=ShowDiskDiffsDialog(AnUnitList); + if Result in [mrYesToAll] then + Result:=mrOk; + for i:=0 to AnUnitList.Count-1 do begin + CurUnit:=TUnitInfo(AnUnitList[i]); + if Result=mrOk then begin + if CurUnit.EditorIndex>=0 then begin + Result:=DoOpenEditorFile('',CurUnit.EditorIndex,[ofRevert]); + end else if CurUnit.IsMainUnit then begin + Result:=DoRevertMainUnit; + end else + Result:=mrIgnore; + if Result=mrAbort then exit; + end else begin + CurUnit.IgnoreCurrentFileDateOnDisk; + end; + Result:=mrOk; + end; + AnUnitList.Free; + finally + FCheckingFilesOnDisk:=false; end; - AnUnitList.Free; end; function TMainIDE.DoPublishModule(Options: TPublishModuleOptions; @@ -10928,7 +10940,6 @@ end; procedure TMainIDE.OnSrcNoteBookActivated(Sender: TObject); begin FDisplayState:= dsSource; - DoCheckFilesOnDisk; end; Procedure TMainIDE.OnDesignerActivated(Sender: TObject); @@ -11287,6 +11298,14 @@ begin and AnUnitInfo.HasResources; end; end; + + if FCheckFilesOnDiskNeeded then + DoCheckFilesOnDisk(true); +end; + +procedure TMainIDE.OnApplicationActivate(Sender: TObject); +begin + DoCheckFilesOnDisk; end; procedure TMainIDE.OnScreenRemoveForm(Sender: TObject; AForm: TCustomForm); diff --git a/ide/mainintf.pas b/ide/mainintf.pas index b0192c79d4..f0a62db911 100644 --- a/ide/mainintf.pas +++ b/ide/mainintf.pas @@ -179,7 +179,7 @@ type const WorkingDir, ToolTitle: string ): TModalResult; virtual; abstract; function DoSaveForBuild: TModalResult; virtual; abstract; - function DoCheckFilesOnDisk: TModalResult; virtual; abstract; + function DoCheckFilesOnDisk(Instantaneous: boolean = false): TModalResult; virtual; abstract; function DoPublishModule(Options: TPublishModuleOptions; const SrcDirectory, DestDirectory: string ): TModalResult; virtual; abstract; diff --git a/lcl/forms.pp b/lcl/forms.pp index 3058e8c2e6..fbd6293917 100644 --- a/lcl/forms.pp +++ b/lcl/forms.pp @@ -833,6 +833,7 @@ type AppIdleEndSent, AppHandlingException, AppNoExceptionMessages, + AppActive, // application has focus AppDestroying, AppDoNotReleaseComponents ); @@ -850,6 +851,8 @@ type ahtIdleEnd, ahtKeyDownBefore, // before interface and LCL ahtKeyDownAfter, // after interface and LCL + ahtActivate, + ahtDeactivate, ahtUserInput ); @@ -885,6 +888,8 @@ type FOldExitProc: Pointer; FOnActionExecute: TActionEvent; FOnActionUpdate: TActionEvent; + FOnActivate: TNotifyEvent; + FOnDeactivate: TNotifyEvent; FOnDestroy: TNotifyEvent; FOnHelp: THelpEvent; FOnHint: TNotifyEvent; @@ -922,10 +927,14 @@ type procedure RemoveHandler(HandlerType: TApplicationHandlerType; const Handler: TMethod); procedure RunLoop; + procedure Activate; + procedure Deactivate; protected function GetConsoleApplication: boolean; override; procedure NotifyIdleHandler; procedure NotifyIdleEndHandler; + procedure NotifyActivateHandler; + procedure NotifyDeactivateHandler; function IsHintMsg(var Msg: TMsg): Boolean; procedure DoOnMouseMove; virtual; procedure ShowHintWindow(const Info: THintInfoAtMouse); @@ -975,21 +984,22 @@ type var Key: Word; Shift: TShiftState); procedure ControlKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure ControlKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); - procedure AddOnIdleHandler(Handler: TNotifyEvent; - AsLast: Boolean{$IFDEF HasDefaultValues}=true{$ENDIF}); + procedure AddOnIdleHandler(Handler: TNotifyEvent; AsLast: Boolean=true); procedure RemoveOnIdleHandler(Handler: TNotifyEvent); - procedure AddOnIdleEndHandler(Handler: TNotifyEvent; - AsLast: Boolean{$IFDEF HasDefaultValues}=true{$ENDIF}); + procedure AddOnIdleEndHandler(Handler: TNotifyEvent; AsLast: Boolean=true); procedure RemoveOnIdleEndHandler(Handler: TNotifyEvent); procedure AddOnUserInputHandler(Handler: TOnUserInputEvent; - AsLast: Boolean{$IFDEF HasDefaultValues}=true{$ENDIF}); + AsLast: Boolean=true); procedure RemoveOnUserInputHandler(Handler: TOnUserInputEvent); procedure AddOnKeyDownBeforeHandler(Handler: TKeyEvent; - AsLast: Boolean{$IFDEF HasDefaultValues}=true{$ENDIF}); + AsLast: Boolean=true); procedure RemoveOnKeyDownBeforeHandler(Handler: TKeyEvent); - procedure AddOnKeyDownHandler(Handler: TKeyEvent; - AsLast: Boolean{$IFDEF HasDefaultValues}=true{$ENDIF}); + procedure AddOnKeyDownHandler(Handler: TKeyEvent; AsLast: Boolean=true); procedure RemoveOnKeyDownHandler(Handler: TKeyEvent); + procedure AddOnActivateHandler(Handler: TNotifyEvent; AsLast: Boolean=true); + procedure RemoveOnActivateHandler(Handler: TNotifyEvent); + procedure AddOnDeactivateHandler(Handler: TNotifyEvent; AsLast: Boolean=true); + procedure RemoveOnDeactivateHandler(Handler: TNotifyEvent); procedure RemoveAllHandlersOfObject(AnObject: TObject); virtual; procedure DoBeforeMouseMessage(CurMouseControl: TControl); function IsShortcut(var Message: TLMKey): boolean; @@ -1015,6 +1025,8 @@ type property MainForm: TForm read FMainForm; property OnActionExecute: TActionEvent read FOnActionExecute write FOnActionExecute; property OnActionUpdate: TActionEvent read FOnActionUpdate write FOnActionUpdate; + property OnActivate: TNotifyEvent read FOnActivate write FOnActivate; + property OnDeactivate: TNotifyEvent read FOnDeactivate write FOnDeactivate; property OnIdle: TIdleEvent read FOnIdle write FOnIdle; property OnIdleEnd: TNotifyEvent read FOnIdleEnd write FOnIdleEnd; property OnHelp: THelpEvent read FOnHelp write FOnHelp; diff --git a/lcl/include/application.inc b/lcl/include/application.inc index 9491e4880c..3f5dd75aed 100644 --- a/lcl/include/application.inc +++ b/lcl/include/application.inc @@ -337,8 +337,10 @@ begin MouseIdle(GetControlAtMouse); Done := True; - if (FIdleLockCount=0) and Assigned(FOnIdle) then FOnIdle(Self, Done); - NotifyIdleHandler; + if (FIdleLockCount=0) then begin + if Assigned(FOnIdle) then FOnIdle(Self, Done); + NotifyIdleHandler; + end; if Done then begin // wait till something happens @@ -492,7 +494,7 @@ begin end; {------------------------------------------------------------------------------ - procedure TApplication.NotifyIdleHandler; + procedure TApplication.ValidateHelpSystem; ------------------------------------------------------------------------------} function TApplication.ValidateHelpSystem: Boolean; begin @@ -524,6 +526,26 @@ begin TNotifyEvent(FApplicationHandlers[ahtIdleEnd][i])(Self); end; +procedure TApplication.NotifyActivateHandler; +var + i: integer; +begin + if Assigned(OnActivate) then OnActivate(Self); + i:=FApplicationHandlers[ahtActivate].Count; + while FApplicationHandlers[ahtActivate].NextDownIndex(i) do + TNotifyEvent(FApplicationHandlers[ahtActivate][i])(Self); +end; + +procedure TApplication.NotifyDeactivateHandler; +var + i: integer; +begin + if Assigned(OnDeactivate) then OnDeactivate(Self); + i:=FApplicationHandlers[ahtDeactivate].Count; + while FApplicationHandlers[ahtDeactivate].NextDownIndex(i) do + TNotifyEvent(FApplicationHandlers[ahtDeactivate][i])(Self); +end; + {------------------------------------------------------------------------------ function TApplication.IsHintMsg(var Msg: TMsg): Boolean; @@ -1011,6 +1033,24 @@ begin until Terminated; end; +procedure TApplication.Activate; +begin + if AppActive in FFlags then exit; + Include(FFlags,AppActive); + NotifyActivateHandler; +end; + +procedure TApplication.Deactivate; +begin + if (not (AppActive in FFlags)) then exit; + if (FindControl(GetFocus)<>nil) then begin + // another control of this application has got the focus + exit; + end; + Exclude(FFlags,AppActive); + NotifyDeactivateHandler; +end; + {------------------------------------------------------------------------------} { TApplication WndPRoc } { } @@ -1304,6 +1344,28 @@ begin RemoveHandler(ahtKeyDownAfter,TMethod(Handler)); end; +procedure TApplication.AddOnActivateHandler(Handler: TNotifyEvent; + AsLast: Boolean); +begin + AddHandler(ahtActivate,TMethod(Handler),AsLast); +end; + +procedure TApplication.RemoveOnActivateHandler(Handler: TNotifyEvent); +begin + RemoveHandler(ahtActivate,TMethod(Handler)); +end; + +procedure TApplication.AddOnDeactivateHandler(Handler: TNotifyEvent; + AsLast: Boolean); +begin + AddHandler(ahtDeactivate,TMethod(Handler),AsLast); +end; + +procedure TApplication.RemoveOnDeactivateHandler(Handler: TNotifyEvent); +begin + RemoveHandler(ahtDeactivate,TMethod(Handler)); +end; + procedure TApplication.RemoveAllHandlersOfObject(AnObject: TObject); var HandlerType: TApplicationHandlerType; diff --git a/lcl/include/customform.inc b/lcl/include/customform.inc index 0dce0e7a47..9b666237ec 100644 --- a/lcl/include/customform.inc +++ b/lcl/include/customform.inc @@ -463,6 +463,7 @@ begin SetActive(Message.Active {<> WA_INACTIVE}); FActive:=true; Activate; + if Application<>nil then Application.Activate; end; {------------------------------------------------------------------------------ @@ -475,6 +476,7 @@ end; procedure TCustomForm.WMDeactivate(var Message : TLMActivate); begin FActive:=false; + if Application<>nil then Application.Deactivate; Deactivate; end;