|
From: <sr...@us...> - 2007-02-01 04:27:01
|
Revision: 757
http://svn.sourceforge.net/instantobjects/revision/?rev=757&view=rev
Author: srmitch
Date: 2007-01-31 20:27:01 -0800 (Wed, 31 Jan 2007)
Log Message:
-----------
Update to allow the InstantObjects Model Explorer Expert (IMEE) to use the newer Delphi ToolsAPI for D7+. Changes include the following:
- Copy the current 'InstantModelExpert.pas' and 'InstantOTA.pas' units to 'InstantModelExpertOld.pas' and 'InstantOTAOld.pas' respectively and continue to use these for D5 and D6 IDEs by modifying their package files;
- Update the current 'InstantModelExpert.pas' and 'InstantOTA.pas' units for the newer Delphi ToolsAPI (no '*Inf.pas' dependencies) and use these for D7 and later IDEs;
- Adjust any other unit uses clauses as required to implement these changes.
Modified Paths:
--------------
trunk/Source/Design/D5/DclIOCore_D5.dpk
trunk/Source/Design/D6/DclIOCore.dpk
trunk/Source/Design/InstantModelExpert.pas
trunk/Source/Design/InstantModelExplorer.pas
trunk/Source/Design/InstantOTA.pas
Added Paths:
-----------
trunk/Source/Design/InstantModelExpertOld.pas
trunk/Source/Design/InstantOTAOld.pas
Modified: trunk/Source/Design/D5/DclIOCore_D5.dpk
===================================================================
--- trunk/Source/Design/D5/DclIOCore_D5.dpk 2007-02-01 03:39:40 UTC (rev 756)
+++ trunk/Source/Design/D5/DclIOCore_D5.dpk 2007-02-01 04:27:01 UTC (rev 757)
@@ -47,9 +47,9 @@
InstantDialog in '..\InstantDialog.pas' {InstantDialogForm},
InstantDualList in '..\InstantDualList.pas' {InstantDualListForm},
InstantEdit in '..\InstantEdit.pas' {InstantEditForm},
- InstantModelExpert in '..\InstantModelExpert.pas',
+ InstantModelExpertOld in '..\InstantModelExpertOld.pas',
InstantModelExplorer in '..\InstantModelExplorer.pas' {InstantModelExplorerForm},
- InstantOTA in '..\InstantOTA.pas',
+ InstantOTAOld in '..\InstantOTAOld.pas',
InstantReg in '..\InstantReg.pas',
InstantUnitSelect in '..\InstantUnitSelect.pas' {InstantUnitSelectForm},
InstantAttributeEditor in '..\InstantAttributeEditor.pas' {InstantAttributeEditorForm},
Modified: trunk/Source/Design/D6/DclIOCore.dpk
===================================================================
--- trunk/Source/Design/D6/DclIOCore.dpk 2007-02-01 03:39:40 UTC (rev 756)
+++ trunk/Source/Design/D6/DclIOCore.dpk 2007-02-01 04:27:01 UTC (rev 757)
@@ -52,9 +52,9 @@
InstantDialog in '..\InstantDialog.pas' {InstantDialogForm},
InstantDualList in '..\InstantDualList.pas' {InstantDualListForm},
InstantEdit in '..\InstantEdit.pas' {InstantEditForm},
- InstantModelExpert in '..\InstantModelExpert.pas',
+ InstantModelExpertOld in '..\InstantModelExpertOld.pas',
InstantModelExplorer in '..\InstantModelExplorer.pas' {InstantModelExplorerForm},
- InstantOTA in '..\InstantOTA.pas',
+ InstantOTAOld in '..\InstantOTAOld.pas',
InstantReg in '..\InstantReg.pas',
InstantUnitSelect in '..\InstantUnitSelect.pas' {InstantUnitSelectForm},
InstantAttributeEditor in '..\InstantAttributeEditor.pas' {InstantAttributeEditorForm},
Modified: trunk/Source/Design/InstantModelExpert.pas
===================================================================
--- trunk/Source/Design/InstantModelExpert.pas 2007-02-01 03:39:40 UTC (rev 756)
+++ trunk/Source/Design/InstantModelExpert.pas 2007-02-01 04:27:01 UTC (rev 757)
@@ -1,6 +1,6 @@
(*
* InstantObjects
- * IDE Model Expert
+ * IDE Model Expert for D7+
*)
(* ***** BEGIN LICENSE BLOCK *****
@@ -36,15 +36,11 @@
{$I '..\InstantDefines.inc'}
{$ENDIF}
-{$IFDEF D7+}
-{$WARN UNIT_DEPRECATED OFF}
-{$ENDIF}
-
interface
uses
- Classes, ToolsAPI, ToolIntf, EditIntf, InstantOTA, Menus, ImgList,
- InstantDesignResources, InstantModelExplorer, InstantCode, ExtCtrls, Forms,
+ Classes, ToolsAPI, InstantOTA, Menus, ImgList, ExtCtrls, Forms,
+ InstantDesignResources, InstantModelExplorer, InstantCode,
InstantConsts;
type
@@ -122,15 +118,14 @@
procedure CheckIOMetadataKeyword(const FileName, Source: string);
procedure ExplorerItemClick(Sender: TObject);
procedure GetModelModules(Modules: TInterfaceList);
- procedure IDEAfterCompilation(Sender: TObject; Succeeded: Boolean);
+ procedure IDEAfterCompilation(Sender: TObject; const Project: IOTAProject;
+ Succeeded: Boolean; IsCodeInsight: Boolean);
procedure IDEBeforeCompilation(Sender: TObject; Project: IOTAProject;
IsCodeInsight: Boolean; var Cancel: Boolean);
- procedure IDEEventNotification(Sender: TObject;
- NotifyCode: TEventNotification; var Cancel: Boolean);
procedure IDEFileNotification(Sender: TObject;
- NotifyCode: TFileNotification; const FileName: string;
+ NotifyCode: TOTAFileNotification; const FileName: string;
var Cancel: Boolean);
- procedure IDEModuleNotification(Sender: TObject; NotifyCode: TNotifyCode;
+ procedure IDEModuleNotification(Sender: TObject; NotifyCode: TModuleNotifyCode;
const FileName: string);
function IsProjectUnit(FileName: string): Boolean;
function IsModelUnit(FileName: string): Boolean;
@@ -666,9 +661,8 @@
Result := TInstantOTAIDEInterface.Create;
with Result do
begin
- AfterCompilation := IDEAfterCompilation;
- BeforeCompilation := IDEBeforeCompilation;
- OnEventNotification := IDEEventNotification;
+ OnAfterCompilation := IDEAfterCompilation;
+ OnBeforeCompilation := IDEBeforeCompilation;
OnFileNotification := IDEFileNotification;
OnModuleNotification := IDEModuleNotification;
end;
@@ -857,8 +851,11 @@
Result := [];
end;
-procedure TInstantModelExpert.IDEAfterCompilation(Sender: TObject; Succeeded: Boolean);
+procedure TInstantModelExpert.IDEAfterCompilation(Sender: TObject; const
+ Project: IOTAProject; Succeeded: Boolean; IsCodeInsight: Boolean);
begin
+ if IsCodeInsight then
+ Exit;
if FMustUpdateAfterCompile then
begin
FMustUpdateAfterCompile := False;
@@ -888,34 +885,28 @@
end;
end;
-procedure TInstantModelExpert.IDEEventNotification(Sender: TObject;
- NotifyCode: TEventNotification; var Cancel: Boolean);
-begin
-end;
-
procedure TInstantModelExpert.IDEFileNotification(Sender: TObject;
- NotifyCode: TFileNotification; const FileName: string; var Cancel: Boolean);
+ NotifyCode: TOTAFileNotification; const FileName: string; var Cancel: Boolean);
begin
case NotifyCode of
- fnFileOpened:
+ ofnFileOpened:
if IsProjectUnit(FileName) then
MetaDataCheckState := mcNeverChecked;
- fnFileClosing:
+ ofnFileClosing:
if IsModelUnit(FileName) then
IsDirty := True;
end;
end;
procedure TInstantModelExpert.IDEModuleNotification(Sender: TObject;
- NotifyCode: TNotifyCode; const FileName: string);
+ NotifyCode: TModuleNotifyCode; const FileName: string);
begin
case NotifyCode of
- ncAfterSave,
- ncEditorModified:
+ mncAfterSave,
+ mncEditorModified:
if IsModelUnit(FileName) then
IsDirty := True;
- ncEditorSelected:
- Exit;
+ mncEditorSelected: ;
end;
end;
Added: trunk/Source/Design/InstantModelExpertOld.pas
===================================================================
--- trunk/Source/Design/InstantModelExpertOld.pas (rev 0)
+++ trunk/Source/Design/InstantModelExpertOld.pas 2007-02-01 04:27:01 UTC (rev 757)
@@ -0,0 +1,1205 @@
+(*
+ * InstantObjects
+ * IDE Model Expert for D5 and D6
+ *)
+
+(* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is: Seleqt InstantObjects
+ *
+ * The Initial Developer of the Original Code is: Seleqt
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2001-2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Nando Dessena, Steven Mitchell
+ *
+ * ***** END LICENSE BLOCK ***** *)
+
+unit InstantModelExpertOld;
+
+{$IFDEF LINUX}
+{$I '../InstantDefines.inc'}
+{$ELSE}
+{$I '..\InstantDefines.inc'}
+{$ENDIF}
+
+interface
+
+uses
+ Classes, ToolsAPI, ToolIntf, EditIntf, InstantOTAOld, Menus, ImgList,
+ InstantDesignResources, InstantModelExplorer, InstantCode, ExtCtrls, Forms,
+ InstantConsts;
+
+type
+ TIOMetaDataCheckState = (mcNeverChecked, mcCheckError, mcCheckCorrect);
+
+ { When the IDE is being shut down, items in the Database-menu are
+ destroyed even if they don't belong to the menu. Since we want to
+ detach our items in the Database-menu when the expert is removed,
+ we need to know if they have already been destroyed by the IDE
+ before doing so. TReferencedMenuItem knows about our reference to
+ the item and will clear this reference when it is destroyed.
+ This ensures that we do not try to free items that are already
+ destroyed by the IDE. }
+
+ PReferencedMenuItem = ^TReferencedMenuItem;
+ TReferencedMenuItem = class(TMenuItem)
+ private
+ FReferee: PReferencedMenuItem;
+ public
+ constructor Create(AOwner: TComponent;
+ var AReferee: TReferencedMenuItem); reintroduce;
+ destructor Destroy; override;
+ end;
+
+ TSourceEnumerator = procedure(const FileName, Source: string) of object;
+
+ TInstantModelExpert = class(TNotifierObject, IOTAWizard)
+ private
+ FActiveProjectName: string;
+ FBuilderItem: TReferencedMenuItem;
+ FExplorerItem: TMenuItem;
+ FIDEInterface: TInstantOTAIDEInterface;
+ FIsChanged: Boolean;
+ FMustUpdateAfterCompile: Boolean;
+ FResourceModule: TInstantDesignResourceModule;
+ FSaveApplicationIdle: TIdleEvent;
+ FToolImageCount: Integer;
+ FToolImageOffset: Integer;
+ FUpdateDisableCount: Integer;
+ FUpdateTimer: TTimer;
+ MetaDataCheckState : TIOMetaDataCheckState;
+ MetaDataCheckUnits : string;
+ procedure ExplorerApplyClass(Sender: TObject; AClass: TInstantCodeClass;
+ ChangeInfo: TInstantCodeClassChangeInfo);
+ procedure ExplorerGotoSource(Sender: TObject; const FileName: string;
+ Pos: TInstantCodePos);
+ procedure ExplorerLoadModel(Sender: TObject; Model: TInstantCodeModel);
+ function GetActiveProject: IOTAProject;
+ function GetAllowContinue: Boolean;
+ function GetCurrentSource: string;
+ function GetExplorer: TInstantModelExplorerForm;
+ function GetIDString: string;
+ function GetIsDirty: Boolean;
+ function GetName: string;
+ function GetState: TWizardState;
+ procedure SetIsDirty(const Value: Boolean);
+ protected
+ procedure ApplicationIdle(Sender: TObject; var Done: Boolean);
+ procedure AccessModelUnits(Project: IOTAProject; Units: TStrings;
+ Write: Boolean);
+ procedure AddToolError(const FileName, Msg: string; Line, Column: Integer);
+ procedure AddToolMessage(const FileName, Msg, Prefix: string; Line, Column: Integer);
+ procedure AddToolText(const Text: string);
+ procedure AttachMenus;
+ procedure BuilderItemClick(Sender: TObject);
+ procedure CheckProjectChanged;
+ procedure CompileProject(Project: IOTAProject);
+ procedure CollectModules(Project: IOTAProject; Modules: TInterfaceList;
+ Names: TStrings);
+ function CreateIDEInterface: TInstantOTAIDEInterface;
+ function CreateUpdateTimer: TTimer;
+ procedure DetachMenus;
+ procedure EnumSources(Modules: TInterfaceList;
+ Enumerator: TSourceEnumerator);
+ procedure CheckIOMetadataKeyword(const FileName, Source: string);
+ procedure ExplorerItemClick(Sender: TObject);
+ procedure GetModelModules(Modules: TInterfaceList);
+ procedure IDEAfterCompilation(Sender: TObject; Succeeded: Boolean);
+ procedure IDEBeforeCompilation(Sender: TObject; Project: IOTAProject;
+ IsCodeInsight: Boolean; var Cancel: Boolean);
+ procedure IDEEventNotification(Sender: TObject;
+ NotifyCode: TEventNotification; var Cancel: Boolean);
+ procedure IDEFileNotification(Sender: TObject;
+ NotifyCode: TFileNotification; const FileName: string;
+ var Cancel: Boolean);
+ procedure IDEModuleNotification(Sender: TObject; NotifyCode: TNotifyCode;
+ const FileName: string);
+ function IsProjectUnit(FileName: string): Boolean;
+ function IsModelUnit(FileName: string): Boolean;
+ procedure ShowExplorer;
+ procedure UpdateModel;
+ procedure UpdateTimerTick(Sender: TObject);
+ property CurrentSource: string read GetCurrentSource;
+ property Explorer: TInstantModelExplorerForm read GetExplorer;
+ public
+ constructor Create;
+ destructor Destroy; override;
+ procedure DisableUpdate;
+ procedure EnableUpdate;
+ procedure ApplyClass(AClass: TInstantCodeClass;
+ ChangeInfo: TInstantCodeClassChangeInfo);
+ procedure BuildDatabase(CodeModel: TInstantCodeModel);
+ procedure Execute;
+ function LoadModel(Model: TInstantCodeModel; Project: IOTAProject = nil;
+ CheckTime: TDateTime = 0): Boolean;
+ procedure SelectUnits;
+ function UpdateEnabled: Boolean;
+ procedure UpdateModelUnits;
+ property ActiveProject: IOTAProject read GetActiveProject;
+ property AllowContinue: Boolean read GetAllowContinue;
+ property IsDirty: Boolean read GetIsDirty write SetIsDirty;
+ end;
+
+var
+ ModelExpert: TInstantModelExpert;
+
+procedure Register;
+
+implementation
+
+uses
+ SysUtils, TypInfo, InstantDesignUtils, InstantUtils, InstantUnitSelect,
+ InstantConnectionManager, Dialogs;
+
+const
+ SBuilderItemCaption = 'InstantObjects Database &Builder...';
+ SBuilderItemName = 'InstantBuilderItem';
+ SExplorerItemCaption = 'InstantObjects &Model Explorer';
+ SExplorerItemName = 'InstantExplorerItem';
+ SModelCompiler = 'Model Compiler';
+ SResFileExt = '.mdr';
+ UpdateInterval = 500;
+
+procedure ReaderIdle(Reader: TInstantCodeReader; var Continue: Boolean);
+begin
+ Application.ProcessMessages;
+ Continue := ModelExpert.AllowContinue;
+end;
+
+procedure Register;
+begin
+ ModelExpert := TInstantModelExpert.Create;
+ RegisterPackageWizard(ModelExpert);
+ InstantCodeReaderIdle := ReaderIdle;
+end;
+
+function FindText(const SubStr, Str: string;
+ var Pos, Line, Column: Integer): Boolean;
+var
+ I, J: Integer;
+begin
+ J := 1;
+ if Pos = 0 then
+ Inc(Pos);
+ if Pos = 1 then
+ begin
+ Line := 1;
+ Column := 1;
+ end;
+ I := Pos;
+ while I <= Length(Str) do
+ begin
+ case Str[I] of
+ #10:begin
+ Inc(Line);
+ Column := 1;
+ end;
+ else
+ Inc(Column);
+ end;
+ if UpperCase(Str[I]) = UpperCase(SubStr[J]) then
+ begin
+ if J = Length(SubStr) then
+ begin
+ Pos := I - J + 1;
+ Result := True;
+ Exit;
+ end;
+ Inc(J);
+ Inc(I);
+ end else if J = 1 then
+ Inc(I)
+ else
+ J := 1;
+ end;
+ Result := False;
+end;
+
+{ TReferencedMenuItem }
+
+constructor TReferencedMenuItem.Create(AOwner: TComponent;
+ var AReferee: TReferencedMenuItem);
+begin
+ inherited Create(AOwner);
+ FReferee := @AReferee;
+end;
+
+destructor TReferencedMenuItem.Destroy;
+begin
+ inherited;
+ FReferee^ := nil;
+end;
+
+{ TInstantModelExpert}
+
+procedure TInstantModelExpert.AccessModelUnits(Project: IOTAProject;
+ Units: TStrings; Write: Boolean);
+const
+
+ ModelTag = #10'{$R *' + SResFileExt + '}';
+ ResourceTag = #10'{$R *.res}';
+
+ function ListToStr(List: TStrings): string;
+ var
+ I: Integer;
+ S: string;
+ begin
+ S := '';
+ for I := 0 to Pred(List.Count) do
+ begin
+ Result := Result + S + List[I];
+ S := ', ' + sLineBreak + ' ';
+ end;
+ end;
+
+ function FindModelDef(const Source: string; out ModelDef: string;
+ var Line, Column: Integer): Integer;
+ var
+ I: Integer;
+ begin
+ Result := 1;
+ if FindText(ModelTag, Source, Result, Line, Column) then
+ begin
+ I := Result + Length(ModelTag);
+ while I <= Length(Source) do
+ begin
+ case Source[I] of
+ ' ': Inc(I);
+ '{':
+ while I < Length(Source) do
+ begin
+ Inc(I);
+ if Source[I] = '}' then
+ begin
+ ModelDef := Copy(Source, Result, I - Result + 1);
+ Exit;
+ end;
+ end;
+ else
+ Break;
+ end;
+ end;
+ ModelDef := Copy(Source, Result, Length(ModelTag));
+ end else
+ Result := 0;
+ end;
+
+ function RemoveBrackets(const Str: string): string;
+ begin
+ Result := Trim(Str);
+ if (Length(Result) > 0) and (Result[1] = '{') then
+ Delete(Result, 1, 1);
+ if (Length(Result) > 0) and (Result[Length(Result)] = '}') then
+ Delete(Result, Length(Result), 1);
+ Result := Trim(Result);
+ end;
+
+ procedure WriteUses(var Source: string; UnitNames: array of string;
+ Include: Boolean);
+ var
+ UsesClause: TInstantCodeUsesClause;
+ UsesItem: TInstantCodeUses;
+ Found: Boolean;
+ I: Integer;
+ S: string;
+ begin
+ with TInstantCodeModifier.Create(Source, nil) do
+ try
+ if Module.ModuleType = mtProgram then
+ begin
+ UsesClause := Module.ProgramSection.FindUsesClause;
+ if Assigned(UsesClause) and (UsesClause.Count > 0) then
+ begin
+ Found := False;
+ for I := Low(UnitNames) to High(UnitNames) do
+ begin
+ UsesItem := UsesClause.Find(UnitNames[I]);
+ Found := Assigned(UsesItem);
+ if Found then
+ begin
+ if not Include then
+ begin
+ EraseObject(UsesItem);
+ if NextChar = ',' then
+ DeleteText(1);
+ CloseGap;
+ end else
+ Break;
+ end;
+ end;
+ if Include and not Found then
+ begin
+ CursorPos := UsesClause[0].StartPos;
+ InsertMode := imBefore;
+ S := '';
+ for I := Low(UnitNames) to High(UnitNames) do
+ S := S + UnitNames[I] + ','#10' ';
+ InsertText(S);
+ end;
+ end;
+ end;
+ finally
+ Free;
+ end;
+ end;
+
+var
+ Editor: IOTASourceEditor;
+ Source: string;
+ Pos, Line, Column, SourceLen: Integer;
+ CurModelDef, NewModelDef: string;
+begin
+ Editor := FIDEInterface.SourceEditor(Project);
+ Source := FIDEInterface.ReadEditorSource(Editor);
+ Pos := FindModelDef(Source, CurModelDef, Line, Column);
+ if Write then
+ begin
+ SourceLen := Length(Source);
+ if Units.Count > 0 then
+ NewModelDef := Format('%s {%s}', [ModelTag, ListToStr(Units)])
+ else
+ NewModelDef := '';
+ if CurModelDef = NewModelDef then
+ Exit
+ else if Pos > 0 then
+ Delete(Source, Pos, Length(CurModelDef))
+ else if not FindText(ResourceTag, Source, Pos, Line, Column) then
+ Exit
+ else
+ Inc(Pos, Length(ResourceTag));
+ Insert(NewModelDef, Source, Pos);
+ FIDEInterface.WriteEditorSource(Editor, Source, SourceLen);
+ end else if Pos > 0 then
+ begin
+ Delete(CurModelDef, 1, Length(ModelTag));
+ CurModelDef := RemoveBrackets(CurModelDef);
+ if CurModelDef = '' then
+ AddToolError(Editor.FileName, 'No model units specified', Line, Column);
+ InstantStrToList(CurModelDef, Units, [',']);
+ end;
+end;
+
+procedure TInstantModelExpert.AddToolError(const FileName, Msg: string; Line,
+ Column: Integer);
+begin
+ AddToolMessage(FileName, Msg, 'Error', Line, Column);
+end;
+
+procedure TInstantModelExpert.AddToolMessage(const FileName, Msg, Prefix: string;
+ Line, Column: Integer);
+begin
+ FIDEInterface.MessageServices.AddToolMessage(FileName, Msg, Prefix,
+ Line, Column);
+end;
+
+procedure TInstantModelExpert.AddToolText(const Text: string);
+begin
+ AddToolMessage('', Text, '', 0, 0);
+end;
+
+procedure TInstantModelExpert.ApplicationIdle(Sender: TObject;
+ var Done: Boolean);
+begin
+ CheckProjectChanged;
+ if Assigned(FSaveApplicationIdle) then
+ FSaveApplicationIdle(Sender, Done);
+end;
+
+procedure TInstantModelExpert.ApplyClass(AClass: TInstantCodeClass;
+ ChangeInfo: TInstantCodeClassChangeInfo);
+var
+ Source: string;
+ Module: IOTAModule;
+ Editor: IOTASourceEditor;
+ OldLen: Integer;
+begin
+ Module := FIDEInterface.FindModule(AClass.Module.UnitName);
+ if not Assigned(Module) then
+ Exit;
+ Editor := FIDEInterface.SourceEditor(Module);
+ if not Assigned(Editor) then
+ Exit;
+ Source := FIDEInterface.ReadEditorSource(Editor);
+ OldLen := Length(Source);
+ AClass.ApplyToSource(Source, ChangeInfo);
+ DisableUpdate;
+ try
+ FIDEInterface.WriteEditorSource(Editor, Source, OldLen);
+ finally
+ EnableUpdate;
+ end;
+end;
+
+procedure TInstantModelExpert.AttachMenus;
+
+ function ItemByName(Items: TMenuItem; Name: string): TMenuItem;
+ var
+ I: Integer;
+ begin
+ Result := nil;
+ if Assigned(Items) then
+ for I := 0 to Pred(Items.Count) do
+ begin
+ if Items[I].Name = Name then
+ begin
+ Result := Items[I];
+ Break;
+ end;
+ end;
+ end;
+
+ procedure CreateBuilderMenuItem;
+ begin
+ FBuilderItem := TReferencedMenuItem.Create(nil, FBuilderItem);
+ with FBuilderItem do
+ begin
+ Name := SBuilderItemName;
+ Caption := SBuilderItemCaption;
+ Action := Explorer.BuildDatabaseAction;
+ ImageIndex := FToolImageOffset + 1;
+ end;
+ end;
+
+var
+ MainMenu: TMainMenu;
+ Menu, Item: TMenuItem;
+begin
+ if not Assigned(BorlandIDEServices) then
+ Exit;
+ MainMenu := (BorlandIDEServices as INTAServices40).MainMenu;
+ if not Assigned(MainMenu) then
+ Exit;
+
+ { Add images }
+ with MainMenu.Images do
+ begin
+ FToolImageOffset := Count;
+ FToolImageCount := FResourceModule.ToolImages.Count;
+ AddImages(TCustomImageList(FResourceModule.ToolImages));
+ end;
+
+ { Add 'Model Explorer' to View-menu }
+ Menu := ItemByName(MainMenu.Items, 'ViewsMenu');
+ if Assigned(Menu) then
+ begin
+ FExplorerItem := TMenuItem.Create(nil);
+ with FExplorerItem do
+ begin
+ Name := SExplorerItemName;
+ Caption := SExplorerItemCaption;
+ ShortCut := Menus.ShortCut(Word('M'), [ssCtrl, ssShift]);
+ ImageIndex := FToolImageOffset;
+ OnClick := ExplorerItemClick;
+ end;
+{$IFDEF D9+}
+ Item := ItemByName(Menu, 'ViewStructureItem');
+{$ELSE}
+ Item := ItemByName(Menu, 'CodeExplorer');
+{$ENDIF}
+ if Assigned(Item) then
+ Menu.Insert(Item.MenuIndex + 1, FExplorerItem)
+ else
+ Menu.Add(FExplorerItem);
+
+{$IFDEF D9+}
+ { Add Database InstantObjects Builder to View-menu }
+ CreateBuilderMenuItem;
+ Item := ItemByName(Menu, 'mnuViewDataExplorer');
+ if Assigned(Item) then
+ Menu.Insert(Item.MenuIndex + 1, FBuilderItem)
+ else
+ Menu.Add(FBuilderItem);
+{$ENDIF}
+ end;
+
+{$IFNDEF D9+}
+ { Add Database InstantObjects Builder to Database-menu }
+ Menu := ItemByName(MainMenu.Items, 'DatabaseMenu');
+ if Assigned(Menu) then
+ begin
+ CreateBuilderMenuItem;
+ Menu.Add(FBuilderItem);
+ end;
+{$ENDIF}
+
+end;
+
+procedure TInstantModelExpert.BuildDatabase(CodeModel: TInstantCodeModel);
+var
+ Project: IOTAProject;
+begin
+ Project := ActiveProject;
+ if not Assigned(Project) then
+ Exit;
+ with TInstantConnectionManager.Create(nil) do
+ try
+ Caption := 'Database Builder';
+ Model := CodeModel.Model;
+ FileName := ChangeFileExt(Project.FileName, '.con');
+ VisibleActions := [atNew, atEdit, atDelete, atRename, atBuild, atEvolve, atOpen];
+ Execute;
+ finally
+ Free;
+ end;
+end;
+
+procedure TInstantModelExpert.BuilderItemClick(Sender: TObject);
+begin
+ BuildDatabase(Explorer.Model);
+end;
+
+procedure TInstantModelExpert.CheckProjectChanged;
+var
+ Project: IOTAProject;
+begin
+ with FIDEInterface do
+ if Assigned(ProjectGroup) then
+ begin
+ Project := ProjectGroup.ActiveProject;
+ if Assigned(Project) and not SameText(Project.FileName,
+ FActiveProjectName) then
+ begin
+ FActiveProjectName := Project.FileName;
+ UpdateModel;
+ end;
+ end else if FActiveProjectName <> '' then
+ begin
+ UpdateModel;
+ FActiveProjectName := '';
+ end;
+end;
+
+procedure TInstantModelExpert.CollectModules(Project: IOTAProject;
+ Modules: TInterfaceList; Names: TStrings);
+
+ function NameInNames(Name: string): Boolean;
+ var
+ I: Integer;
+ begin
+ for I := 0 to Pred(Names.Count) do
+ if SameText(Name, Names[I]) then
+ begin
+ Result := True;
+ Exit;
+ end;
+ Result := False;
+ end;
+
+var
+ I: Integer;
+ ModuleInfo: IOTAModuleInfo;
+begin
+ for I := 0 to Pred(Project.GetModuleCount) do
+ begin
+ ModuleInfo := Project.GetModule(I);
+ if NameInNames(ModuleInfo.Name) then
+ Modules.Add(ModuleInfo.OpenModule);
+ end;
+end;
+
+procedure TInstantModelExpert.CompileProject(Project: IOTAProject);
+var
+ Model: TInstantCodeModel;
+ ResFileName: string;
+ ResFileAge: Integer;
+ ResFileTime: TDateTime;
+begin
+ DisableUpdate;
+ Model := TInstantCodeModel.Create;
+ try
+ ResFileName := ChangeFileExt(Project.FileName, SResFileExt);
+ ResFileAge := FileAge(ResFileName);
+ if ResFileAge = -1 then
+ ResFileTime := 0 else
+ ResFileTime := FileDateToDateTime(ResFileAge);
+ try
+ if LoadModel(Model, Project, ResFileTime) then
+ Model.SaveToResFile(ResFileName);
+ except
+ on E: EInstantCodeError do
+ begin
+ AddToolError(E.FileName, E.Message, E.Position.Line,
+ E.Position.Column);
+ Abort;
+ end
+ else
+ raise;
+ end;
+ finally
+ Model.Free;
+ EnableUpdate;
+ end;
+end;
+
+constructor TInstantModelExpert.Create;
+begin
+ //CheckExpiration;
+ FResourceModule := TInstantDesignResourceModule.Create(nil);
+ FIDEInterface := CreateIDEInterface;
+ FUpdateTimer := CreateUpdateTimer;
+ AttachMenus;
+ FSaveApplicationIdle := Application.OnIdle;
+ Application.OnIdle := ApplicationIdle;
+ ModelExplorer := Explorer;
+end;
+
+function TInstantModelExpert.CreateIDEInterface: TInstantOTAIDEInterface;
+begin
+ Result := TInstantOTAIDEInterface.Create;
+ with Result do
+ begin
+ AfterCompilation := IDEAfterCompilation;
+ BeforeCompilation := IDEBeforeCompilation;
+ OnEventNotification := IDEEventNotification;
+ OnFileNotification := IDEFileNotification;
+ OnModuleNotification := IDEModuleNotification;
+ end;
+end;
+
+function TInstantModelExpert.CreateUpdateTimer: TTimer;
+begin
+ Result := TTimer.Create(nil);
+ with Result do
+ begin
+ Enabled := False;
+ Interval := UpdateInterval;
+ OnTimer := UpdateTimerTick;
+ end;
+end;
+
+destructor TInstantModelExpert.Destroy;
+begin
+ Application.OnIdle := FSaveApplicationIdle;
+ DetachMenus;
+ FUpdateTimer.Free;
+ ModelExplorer.Free;
+ FIDEInterface.Free;
+ FResourceModule.Free;
+ inherited;
+end;
+
+procedure TInstantModelExpert.DetachMenus;
+var
+ MainMenu: TMainMenu;
+ I: Integer;
+begin
+ if not Application.Terminated then
+ begin
+ { Remove images }
+ MainMenu := (BorlandIDEServices as INTAServices40).MainMenu;
+ if Assigned(MainMenu) and Assigned(MainMenu.Images) then
+ with MainMenu.Images do
+ for I := 0 to Pred(FToolImageCount) do
+ Delete(FToolImageOffset);
+ end;
+
+ { Remove items }
+ FBuilderItem.Free;
+ FExplorerItem.Free;
+end;
+
+procedure TInstantModelExpert.DisableUpdate;
+begin
+ Inc(FUpdateDisableCount);
+end;
+
+procedure TInstantModelExpert.EnableUpdate;
+begin
+ if FUpdateDisableCount > 0 then
+ Dec(FUpdateDisableCount);
+end;
+
+procedure TInstantModelExpert.EnumSources(Modules: TInterfaceList;
+ Enumerator: TSourceEnumerator);
+var
+ I: Integer;
+ Module: IOTAModule;
+ Editor: IOTASourceEditor;
+ Source: string;
+begin
+ if not Assigned(Enumerator) then
+ Exit;
+ Busy(True);
+ try
+ for I := 0 to Pred(Modules.Count) do
+ begin
+ Module := Modules[I] as IOTAModule;
+ if Module.GetModuleFileCount = 1 then
+ begin
+ Editor := FIDEInterface.SourceEditor(Module);
+ Source := FIDEInterface.ReadEditorSource(Editor);
+ Enumerator(Editor.FileName, Source);
+ end;
+ end;
+ finally
+ Busy(False);
+ end;
+end;
+
+procedure TInstantModelExpert.Execute;
+begin
+ ShowExplorer;
+end;
+
+procedure TInstantModelExpert.ExplorerApplyClass(Sender: TObject;
+ AClass: TInstantCodeClass; ChangeInfo: TInstantCodeClassChangeInfo);
+begin
+ ApplyClass(AClass, ChangeInfo);
+end;
+
+procedure TInstantModelExpert.ExplorerGotoSource(Sender: TObject;
+ const FileName: string; Pos: TInstantCodePos);
+begin
+ FIDEInterface.GotoFilePos(FileName, Pos.Line, Pos.Column);
+end;
+
+procedure TInstantModelExpert.ExplorerItemClick(Sender: TObject);
+begin
+ ShowExplorer;
+end;
+
+procedure TInstantModelExpert.ExplorerLoadModel(Sender: TObject;
+ Model: TInstantCodeModel);
+begin
+ LoadModel(Model);
+end;
+
+function TInstantModelExpert.GetActiveProject: IOTAProject;
+begin
+ with FIDEInterface do
+ if Assigned(ProjectGroup) then
+ Result := ProjectGroup.ActiveProject
+ else
+ Result := nil;
+end;
+
+function TInstantModelExpert.GetAllowContinue: Boolean;
+begin
+ Result := not FIsChanged;
+end;
+
+function TInstantModelExpert.GetCurrentSource: string;
+var
+ Editor: IOTASourceEditor;
+begin
+ with FIDEInterface do
+ begin
+ Editor := SourceEditor(CurrentModule);
+ Result := ReadEditorSource(Editor);
+ end;
+end;
+
+function TInstantModelExpert.GetExplorer: TInstantModelExplorerForm;
+begin
+ if not Assigned(ModelExplorer) then
+ begin
+ ModelExplorer := TInstantModelExplorerForm.Create(nil);
+ with ModelExplorer do
+ begin
+ OnApplyClass := ExplorerApplyClass;
+ OnGotoSource := ExplorerGotoSource;
+ OnLoadModel := ExplorerLoadModel;
+ end;
+ end;
+ Result := ModelExplorer;
+end;
+
+function TInstantModelExpert.GetIDString: string;
+begin
+ Result := 'Instant.Model.Expert';
+end;
+
+function TInstantModelExpert.GetIsDirty: Boolean;
+begin
+ Result := FUpdateTimer.Enabled;
+end;
+
+procedure TInstantModelExpert.GetModelModules(Modules: TInterfaceList);
+var
+ Project: IOTAProject;
+ UnitNames: TStringList;
+begin
+ Project := ActiveProject;
+ UnitNames := TStringList.Create;
+ try
+ AccessModelUnits(Project, UnitNames, False);
+ CollectModules(Project, Modules, UnitNames);
+ finally
+ UnitNames.Free;
+ end;
+end;
+
+function TInstantModelExpert.GetName: string;
+begin
+ Result := 'Instant Model Expert';
+end;
+
+function TInstantModelExpert.GetState: TWizardState;
+begin
+ Result := [];
+end;
+
+procedure TInstantModelExpert.IDEAfterCompilation(Sender: TObject; Succeeded: Boolean);
+begin
+ if FMustUpdateAfterCompile then
+ begin
+ FMustUpdateAfterCompile := False;
+ UpdateModel;
+ end;
+end;
+
+procedure TInstantModelExpert.IDEBeforeCompilation(Sender: TObject;
+ Project: IOTAProject; IsCodeInsight: Boolean; var Cancel: Boolean);
+begin
+ if IsCodeInsight then
+ Exit;
+ FMustUpdateAfterCompile := IsDirty;
+ IsDirty := False;
+ FIDEInterface.MessageServices.ClearAllMessages;
+ try
+ CompileProject(Project);
+ except
+ on E: EAbort do
+ begin
+ Cancel := True;
+ FIDEInterface.ShowMessages;
+ FMustUpdateAfterCompile := False;
+ end;
+ else
+ raise;
+ end;
+end;
+
+procedure TInstantModelExpert.IDEEventNotification(Sender: TObject;
+ NotifyCode: TEventNotification; var Cancel: Boolean);
+begin
+end;
+
+procedure TInstantModelExpert.IDEFileNotification(Sender: TObject;
+ NotifyCode: TFileNotification; const FileName: string; var Cancel: Boolean);
+begin
+ case NotifyCode of
+ fnFileOpened:
+ if IsProjectUnit(FileName) then
+ MetaDataCheckState := mcNeverChecked;
+ fnFileClosing:
+ if IsModelUnit(FileName) then
+ IsDirty := True;
+ end;
+end;
+
+procedure TInstantModelExpert.IDEModuleNotification(Sender: TObject;
+ NotifyCode: TNotifyCode; const FileName: string);
+begin
+ case NotifyCode of
+ ncAfterSave,
+ ncEditorModified:
+ if IsModelUnit(FileName) then
+ IsDirty := True;
+ ncEditorSelected:
+ Exit;
+ end;
+end;
+
+function TInstantModelExpert.IsProjectUnit(FileName: string): Boolean;
+begin
+ Result := Assigned(ActiveProject) and SameText(ActiveProject.FileName, FileName);
+end;
+
+function TInstantModelExpert.IsModelUnit(FileName: string): Boolean;
+var
+ Project: IOTAProject;
+ Units: TStringList;
+ I: Integer;
+begin
+ Result := False;
+ Project := ActiveProject;
+ if not Assigned(Project) then
+ Exit;
+ if SameText(Project.FileName, FileName) then
+ begin
+ Result := True;
+ Exit;
+ end;
+ Units := TStringList.Create;
+ try
+ AccessModelUnits(Project, Units, False);
+ for I := 0 to Pred(Units.Count) do
+ if SameText(Units[I], ChangeFileExt(ExtractFileName(FileName), '')) then
+ begin
+ Result := True;
+ Break;
+ end;
+ finally
+ Units.Free;
+ end;
+end;
+
+function TInstantModelExpert.LoadModel(Model: TInstantCodeModel;
+ Project: IOTAProject; CheckTime: TDateTime): Boolean;
+
+ function EditorModified(Module: IOTAModule): Boolean;
+ var
+ Editor: IOTASourceEditor;
+ begin
+ Editor := FIDEInterface.SourceEditor(Module);
+ Result := Editor.Modified;
+ end;
+
+ function FileModified(const FileName: string; Since: TDateTime): Boolean;
+ var
+ Age: Integer;
+ begin
+ Age := FileAge(FileName);
+ if Age = -1 then
+ Result := False
+ else
+ Result := FileDateToDateTime(Age) > Since;
+ end;
+
+ function ModuleModified(Module: IOTAModule; Since: TDateTime): Boolean;
+ begin
+ Result := EditorModified(Module) or FileModified(Module.FileName, Since);
+ end;
+
+ function ModulesModified(Modules: TInterfaceList; Since: TDateTime): Boolean;
+ var
+ I: Integer;
+ Module: IOTAModule;
+ begin
+ for I := 0 to Pred(Modules.Count) do
+ begin
+ Module := Modules[I] as IOTAModule;
+ Result := ModuleModified(Module, Since);
+ if Result then
+ Exit;
+ end;
+ Result := False;
+ end;
+
+ procedure ReadModel(Modules: TInterfaceList);
+ var
+ I: Integer;
+ Module: IOTAModule;
+ Editor: IOTASourceEditor;
+ Source: string;
+ Stream: TStringStream;
+ begin
+ for I := 0 to Pred(Modules.Count) do
+ begin
+ Module := Modules[I] as IOTAModule;
+ Editor := FIDEInterface.SourceEditor(Module);
+ Source := FIDEInterface.ReadEditorSource(Editor);
+ Stream := TStringStream.Create(Source);
+ try
+ Model.LoadModule(Stream, Editor.FileName);
+ finally
+ Stream.Free;
+ end;
+ end;
+ end;
+
+var
+ Units: TStringList;
+ Modules: TInterfaceList;
+begin
+ if not Assigned(Project) then
+ Project := ActiveProject;
+ Units := TStringList.Create;
+ try
+ AccessModelUnits(Project, Units, False);
+ if Units.Count > 0 then
+ begin
+ Modules := TInterfaceList.Create;
+ try
+ CollectModules(Project, Modules, Units);
+ if MetaDataCheckState = mcNeverChecked then
+ begin
+ MetadataCheckUnits := '';
+ MetaDataCheckState := mcCheckCorrect;
+ EnumSources(Modules, CheckIOMetadataKeyword);
+ if MetaDataCheckState = mcCheckError then
+ MessageDlg(Format('WARNING: Project %s contains some class metadata without IOMETADATA keyword:'+
+ '%s'+sLineBreak+'Please refer to IOMETADATA_keyword.txt in instantobjects\doc folder.',
+ [FActiveProjectName, MetadataCheckUnits]), mtWarning, [mbOK], 0);
+ end;
+ Result := (CheckTime = 0) or
+ ModuleModified(Project, CheckTime) or
+ ModulesModified(Modules, CheckTime);
+ if Result then
+ ReadModel(Modules);
+ finally
+ Modules.Free;
+ end;
+ end else
+ Result := False;
+ finally
+ Units.Free;
+ end;
+end;
+
+procedure TInstantModelExpert.SelectUnits;
+
+ procedure GetUnitNames(Project: IOTAProject; Names: TStrings);
+ var
+ I: Integer;
+ Module: IOTAModuleInfo;
+ begin
+ for I := 0 to Pred(Project.GetModuleCount) do
+ begin
+ Module := Project.GetModule(I);
+ if (Module.FileName <> '') and (Module.ModuleType = 0) then
+ Names.Add(Module.Name);
+ end;
+ end;
+
+ procedure SubtractList(List, Subtract: TStrings);
+ var
+ I, Index: Integer;
+ begin
+ for I := 0 to Pred(Subtract.Count) do
+ begin
+ Index := List.IndexOf(Subtract[I]);
+ if Index <> -1 then
+ List.Delete(Index);
+ end;
+ end;
+
+var
+ Project: IOTAProject;
+ ModelUnits, OtherUnits: TStringList;
+begin
+ if not Assigned(FIDEInterface.ProjectGroup) then
+ Exit;
+ ModelUnits := TStringList.Create;
+ OtherUnits := TStringList.Create;
+ try
+ Project := ActiveProject;
+ AccessModelUnits(Project, ModelUnits, False);
+ GetUnitNames(Project, OtherUnits);
+ SubtractList(OtherUnits, ModelUnits);
+ with TInstantUnitSelectForm.Create(nil) do
+ try
+ if Execute(ModelUnits, OtherUnits) then
+ begin
+ AccessModelUnits(Project, ModelUnits, True);
+ UpdateModel;
+ end;
+ finally
+ Free;
+ end;
+ finally
+ ModelUnits.Free;
+ OtherUnits.Free;
+ end;
+end;
+
+procedure TInstantModelExpert.SetIsDirty(const Value: Boolean);
+begin
+ if not UpdateEnabled then
+ Exit;
+ FIsChanged := Value;
+ with FUpdateTimer do
+ begin
+ Enabled := False;
+ Enabled := Value;
+ end;
+end;
+
+procedure TInstantModelExpert.ShowExplorer;
+begin
+ with Explorer do
+ begin
+ Refresh;
+ Show;
+ ModelView.SetFocus;
+ end;
+end;
+
+function TInstantModelExpert.UpdateEnabled: Boolean;
+begin
+ Result := FUpdateDisableCount = 0;
+end;
+
+procedure TInstantModelExpert.UpdateModel;
+begin
+ IsDirty := False;
+ DisableUpdate;
+ try
+ Explorer.Refresh;
+ finally
+ EnableUpdate;
+ end;
+end;
+
+procedure TInstantModelExpert.UpdateModelUnits;
+
+ procedure UpdateModelUnit(Module: IOTAModule);
+ var
+ Editor: IOTASourceEditor;
+ Source, OldSource: string;
+ begin
+ Editor := FIDEInterface.SourceEditor(Module);
+ Source := FIDEInterface.ReadEditorSource(Editor);
+ OldSource := Source;
+ with TInstantCodeModifier.Create(Source, nil) do
+ try
+ UpdateUnit;
+ finally
+ Free;
+ end;
+ if Source <> OldSource then
+ begin
+ DisableUpdate;
+ try
+ FIDEInterface.WriteEditorSource(Editor, Source, Length(Source));
+ finally
+ EnableUpdate;
+ end;
+ end;
+ end;
+
+var
+ Modules: TInterfaceList;
+ I: Integer;
+begin
+ Modules := TInterfaceList.Create;
+ try
+ GetModelModules(Modules);
+ for I := 0 to Pred(Modules.Count) do
+ UpdateModelUnit(Modules[I] as IOTAModule);
+ finally
+ Modules.Free;
+ end;
+end;
+
+procedure TInstantModelExpert.UpdateTimerTick(Sender: TObject);
+begin
+ if UpdateEnabled then
+ UpdateModel;
+end;
+
+procedure TInstantModelExpert.CheckIOMetadataKeyword(const FileName, Source: string);
+begin
+ if pos('{ stored', Source) > 0 then
+ begin
+ MetaDataCheckUnits := MetaDataCheckUnits + sLineBreak+FileName+';';
+ MetaDataCheckState := mcCheckError;
+ end;
+end;
+
+end.
Modified: trunk/Source/Design/InstantModelExplorer.pas
===================================================================
--- trunk/Source/Design/InstantModelExplorer.pas 2007-02-01 03:39:40 UTC (rev 756)
+++ trunk/Source/Design/InstantModelExplorer.pas 2007-02-01 04:27:01 UTC (rev 757)
@@ -188,7 +188,12 @@
{$IFDEF LINUX}
QDialogs,
{$ENDIF}
- TypInfo, InstantClassEditor, InstantClasses, DeskUtil, InstantModelExpert,
+ TypInfo, InstantClassEditor, InstantClasses, DeskUtil,
+{$IFNDEF D7+}
+ InstantModelExpertOld,
+{$ELSE}
+ InstantModelExpert,
+{$ENDIF}
InstantDesignUtils, InstantPersistence, InstantDesignHook, InstantAbout,
InstantImageUtils;
Modified: trunk/Source/Design/InstantOTA.pas
===================================================================
--- trunk/Source/Design/InstantOTA.pas 2007-02-01 03:39:40 UTC (rev 756)
+++ trunk/Source/Design/InstantOTA.pas 2007-02-01 04:27:01 UTC (rev 757)
@@ -1,6 +1,6 @@
(*
* InstantObjects
- * Borland OTA Interface (Open Tools API)
+ * Borland OTA Interface (Open Tools API) for D7+
*)
(* ***** BEGIN LICENSE BLOCK *****
@@ -24,7 +24,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- * Nando Dessena
+ * Nando Dessena, Steven Mitchell
*
* ***** END LICENSE BLOCK ***** *)
@@ -38,60 +38,68 @@
{$I '..\InstantDefines.inc'}
{$ENDIF}
-{$IFDEF D7+}
-{$WARN UNIT_DEPRECATED OFF}
-{$ENDIF}
-
uses
- Classes, ToolsAPI, ExptIntf, ToolIntf, EditIntf, Forms;
+ Classes, ToolsAPI, InstantTypes, Forms;
type
TInstantOTAIDEInterface = class;
+{$IFDEF D9+}
+ TInstantOTAIDENotifier8 = class;
+{$ENDIF}
TInstantOTAIDENotifier5 = class;
- TInstantOTAIDENotifier3 = class;
TInstantOTAModuleNotifier = class;
+ TInstantOTAEditorNotifier = class;
+ TInstantOTAFormNotifier = class;
+ TModuleNotifyCode = (mncModuleDeleted, mncModuleRenamed, mncEditorModified,
+ mncFormModified, mncEditorSelected, mncFormSelected, mncBeforeSave,
+ mncAfterSave, mncFormSaving, mncProjResModified);
+
TInstantOTAAfterCompilationEvent = procedure(Sender: TObject;
- Succeeded: Boolean) of object;
+ const Project: IOTAProject; Succeeded: Boolean;
+ IsCodeInsight: Boolean) of object;
TInstantOTABeforeCompilationEvent = procedure(Sender: TObject;
Project: IOTAProject; IsCodeInsight: Boolean;
var Cancel: Boolean) of object;
- TInstantOTAEventNotificationEvent = procedure(Sender: TObject;
- NotifyCode: TEventNotification; var Cancel: Boolean) of object;
+ TInstantOTAModuleNotificationEvent = procedure(Sender: TObject;
+ NotifyCode: TModuleNotifyCode; const FileName: string) of object;
TInstantOTAFileNotificationEvent = procedure(Sender: TObject;
- NotifyCode: TFileNotification; const FileName: string;
+ NotifyCode: TOTAFileNotification; const FileName: string;
var Cancel: Boolean) of object;
- TInstantOTAModuleNotificationEvent = procedure(Sender: TObject;
- NotifyCode: TNotifyCode; const FileName: string) of object;
+ TInstantOTAModuleRenamedNotificationEvent = procedure(Sender: TObject;
+ const OldName, NewName: string) of object;
+ IInstantOTANotifierUninstallation = interface(IInterface)
+ ['{D5690321-5365-4BD1-B149-AE1B3A4AE371}']
+ procedure UninstallNotifier;
+ end;
+
TInstantOTAIDEInterface = class(TObject)
private
- FIDENotifier3: TInstantOTAIDENotifier3;
FIDENotifier5: TInstantOTAIDENotifier5;
- function GetAfterCompilation: TInstantOTAAfterCompilationEvent;
- function GetBeforeCompilation: TInstantOTABeforeCompilationEvent;
- function GetEditActions: IOTAEditActions;
- function GetIDENotifier3: TInstantOTAIDENotifier3;
- function GetIDENotifier5: TInstantOTAIDENotifier5;
- function GetMessageServices: IOTAMessageServices;
- function GetModuleServices: IOTAModuleServices;
- function GetOnEventNotification: TInstantOTAEventNotificationEvent;
+ function GetOnModuleRenamedNotification:
+ TInstantOTAModuleRenamedNotificationEvent;
+ procedure SetOnModuleRenamedNotification(const Value:
+ TInstantOTAModuleRenamedNotificationEvent);
function GetOnFileNotification: TInstantOTAFileNotificationEvent;
function GetOnModuleNotification: TInstantOTAModuleNotificationEvent;
- function GetProjectGroup: IOTAProjectGroup;
- function GetServices3: TIToolServices;
- function GetServices5: IOTAServices;
- procedure SetAfterCompilation(const Value: TInstantOTAAfterCompilationEvent);
- procedure SetBeforeCompilation(const Value: TInstantOTABeforeCompilationEvent);
- procedure SetOnEventNotification(
- const Value: TInstantOTAEventNotificationEvent);
procedure SetOnFileNotification(
const Value: TInstantOTAFileNotificationEvent);
procedure SetOnModuleNotification(
const Value: TInstantOTAModuleNotificationEvent);
+ function GetOnAfterCompilation: TInstantOTAAfterCompilationEvent;
+ function GetOnBeforeCompilation: TInstantOTABeforeCompilationEvent;
+ function GetEditActions: IOTAEditActions;
+ function GetIDENotifier5: TInstantOTAIDENotifier5;
+ function GetMessageServices: IOTAMessageServices;
+ function GetModuleServices: IOTAModuleServices;
+ function GetProjectGroup: IOTAProjectGroup;
+ function GetServices: IOTAServices;
+ procedure SetOnAfterCompilation(const Value: TInstantOTAAfterCompilationEvent);
+ procedure SetOnBeforeCompilation(const Value:
+ TInstantOTABeforeCompilationEvent);
protected
function FindForm(Name, ClassName: string): TForm;
- property IDENotifier3: TInstantOTAIDENotifier3 read GetIDENotifier3;
property IDENotifier5: TInstantOTAIDENotifier5 read GetIDENotifier5;
public
destructor Destroy; override;
@@ -104,98 +112,131 @@
function SourceEditor(Module: IOTAModule): IOTASourceEditor;
procedure WriteEditorSource(Editor: IOTASourceEditor; const Source: string;
ReplaceLen: Integer; Undoable: Boolean = False);
- property AfterCompilation: TInstantOTAAfterCompilationEvent read GetAfterCompilation write SetAfterCompilation;
- property BeforeCompilation: TInstantOTABeforeCompilationEvent read GetBeforeCompilation write SetBeforeCompilation;
property EditActions: IOTAEditActions read GetEditActions;
property MessageServices: IOTAMessageServices read GetMessageServices;
property ModuleServices: IOTAModuleServices read GetModuleServices;
property ProjectGroup: IOTAProjectGroup read GetProjectGroup;
- property Services3: TIToolServices read GetServices3;
- property Services5: IOTAServices read GetServices5;
- property OnEventNotification: TInstantOTAEventNotificationEvent
- read GetOnEventNotification write SetOnEventNotification;
+ property Services: IOTAServices read GetServices;
+ property OnAfterCompilation: TInstantOTAAfterCompilationEvent read
+ GetOnAfterCompilation write SetOnAfterCompilation;
+ property OnBeforeCompilation: TInstantOTABeforeCompilationEvent read
+ GetOnBeforeCompilation write SetOnBeforeCompilation;
property OnFileNotification: TInstantOTAFileNotificationEvent
read GetOnFileNotification write SetOnFileNotification;
property OnModuleNotification: TInstantOTAModuleNotificationEvent
read GetOnModuleNotification write SetOnModuleNotification;
+ property OnModuleRenamedNotification: TInstantOTAModuleRenamedNotificationEvent
+ read GetOnModuleRenamedNotification write SetOnModuleRenamedNotification;
end;
TInstantOTAIDENotifier5 = class(TNotifierObject, IOTANotifier, IOTAIDENotifier50)
private
FNotifierIndex: Integer;
FOwner: TInstantOTAIDEInterface;
- FAfterCompilation: TInstantOTAAfterCompilationEvent;
- FBeforeCompilation: TInstantOTABeforeCompilationEvent;
+ FOnAfterCompilation: TInstantOTAAfterCompilationEvent;
+ FOnBeforeCompilation: TInstantOTABeforeCompilationEvent;
+ FModuleNotifierList: TList;
+ FOnFileNotification: TInstantOTAFileNotificationEvent;
+ FOnModuleNotification: TInstantOTAModuleNotificationEvent;
+ FOnModuleRenamedNotification: TInstantOTAModuleRenamedNotificationEvent;
+ procedure ClearModuleNotifiers;
+ function GetModuleNotifierCount: Integer;
+ function GetModuleNotifierList: TList;
+ function GetModuleNotifiers(Index: Integer): TInstantOTAModuleNotifier;
+ function HasNotifierBeenInstalled(const AFileName: string): Boolean;
+ procedure InstallModuleNotifier(Module: IOTAModule); overload;
+ procedure RemoveModuleNotifiers;
protected
- procedure DoAfterCompilation(Succeeded, IsCodeInsight: Boolean);
+ procedure DoAfterCompilation(Succeeded, IsCodeInsight: Boolean); overload;
+ procedure DoAfterCompilation(Succeeded: Boolean); overload;
procedure DoBeforeCompilation(const Project: IOTAProject;
IsCodeInsight: Boolean; var Cancel: Boolean);
+ function IsValidModuleFileName(const AFileName: string): Boolean;
+ procedure RegisterNotifier; virtual;
+ procedure UnregisterNotifier; virtual;
+ property ModuleNotifierList: TList read GetModuleNotifierList;
+ property NotifierIndex: Integer read FNotifierIndex write FNotifierIndex;
public
constructor Create(AOwner: TInstantOTAIDEInterface);
destructor Destroy; override;
+ // IOTAIDENotifier
procedure AfterCompile(Succeeded: Boolean); overload;
- procedure AfterCompile(Succeeded: Boolean; IsCodeInsight: Boolean); overload;
- procedure AfterConstruction; override;
procedure BeforeCompile(const Project: IOTAProject; var Cancel: Boolean); overload;
- procedure BeforeCompile(const Project: IOTAProject; IsCodeInsight: Boolean; var Cancel: Boolean); overload;
- procedure BeforeDestruction; override;
procedure FileNotification(NotifyCode: TOTAFileNotification;
const FileName: string; var Cancel: Boolean);
- property AfterCompilation: TInstantOTAAfterCompilationEvent read FAfterCompilation write FAfterCompilation;
- property BeforeCompilation: TInstantOTABeforeCompilationEvent read FBeforeCompilation write FBeforeCompilation;
+ // IOTAIDENotifier50
+ procedure AfterCompile(Succeeded, IsCodeInsight: Boolean); overload;
+ procedure BeforeCompile(const Project: IOTAProject; IsCodeInsight: Boolean;
+ var Cancel: Boolean); overload;
+
+ procedure AddModuleNotifier(Notifier: TInstantOTAModuleNotifier);
+ procedure AfterConstruction; override;
+ procedure BeforeDestruction; override;
+ procedure InstallModuleNotifier(const FileName: string); overload;
+ procedure ModuleNotification(const FileName: string; NotifyCode:
+ TModuleNotifyCode);
+ procedure ModuleRenamed(const OldName, NewName: string);
+ function RemoveModuleNotifier(Notifier: TInstantOTAModuleNotifier): Integer;
+ property ModuleNotifierCount: Integer read GetModuleNotifierCount;
+ property ModuleNotifiers[Index: Integer]: TInstantOTAModuleNotifier read
+ GetModuleNotifiers;
+ property OnAfterCompilation: TInstantOTAAfterCompilationEvent read
+ FOnAfterCompilation write FOnAfterCompilation;
+ property OnBeforeCompilation: TInstantOTABeforeCompilationEvent read
+ FOnBeforeCompilation write FOnBeforeCompilation;
+ property OnFileNotification: TInstantOTAFileNotificationEvent read
+ FOnFileNotification write FOnFileNotification;
+ property OnModuleNotification: TInstantOTAModuleNotificationEvent read
+ FOnModuleNotification write FOnModuleNotification;
+ property OnModuleRenamedNotification: TInstantOTAModuleRenamedNotificationEvent
+ read FOnModuleRenamedNotification write FOnModuleRenamedNotification;
end;
- TInstantOTAIDENotifier3 = class(TIAddInNotifier)
- private
- FModuleNotifierList: TList;
- FOwner: TInstantOTAIDEInterface;
- FOnEventNotification: TInstantOTAEventNotificationEvent;
- FOnFileNotification: TInstantOTAFileNotificationEvent;
- FOnModuleNotification: TInstantOTAModuleNotificationEvent;
- function GetModuleNotifierCount: Integer;
- function GetModuleNotifiers(Index: Integer): TInstantOTAModuleNotifier;
- function GetModuleNotifierList: TList;
+ {$IFDEF D9+}
+ TInstantOTAIDENotifier8 = class(TInstantOTAIDENotifier5, IOTANotifier,
+ IOTAIDENotifier50, IOTAIDENotifier80)
protected
- procedure ModuleNotification(FileName: string; NotifyCode: TNotifyCode);
- property ModuleNotifierList: TList read GetModuleNotifierList;
+ procedure DoAfterCompilation(const Project: IOTAProject; Succeeded,
+ IsCodeInsight: Boolean); overload;
public
- constructor Create(AOwner: TInstantOTAIDEInterface);
- destructor Destroy; override;
- procedure AddModuleNotifier(Notifier: TInstantOTAModuleNotifier);
- procedure EventNotification(NotifyCode: TEventNotification;
- var Cancel: Boolean); override;
- procedure FileNotification(NotifyCode: TFileNotification;
- const FileName: string; var Cancel: Boolean); override;
- function InstallModuleNotifier(FileName: string): TInstantOTAModuleNotifier;
- procedure RemoveModuleNotifier(Notifier: TInstantOTAModuleNotifier);
- property ModuleNotifiers[Index: Integer]: TInstantOTAModuleNotifier
- read GetModuleNotifiers;
- property ModuleNotifierCount: Integer read GetModuleNotifierCount;
- property OnEventNotification: TInstantOTAEventNotificationEvent
- read FOnEventNotification write FOnEventNotification;
- property OnFileNotification: TInstantOTAFileNotificationEvent
- read FOnFileNotification write FOnFileNotification;
- property OnModuleNotification: TInstantOTAModuleNotificationEvent
- read FOnModuleNotification write FOnModuleNotification;
+ // IOTAIDENotifier80
+ procedure AfterCompile(const Project: IOTAProject; Succeeded: Boolean;
+ IsCodeInsight: Boolean); overload;
end;
+ {$ENDIF}
- TInstantOTAModuleNotifier = class(TIModuleNotifier)
+ TInstantOTAModuleNotifier = class(TNotifierObject, IOTANotifier,
+ IOTAModuleNotifier, IInstantOTANotifierUninstallation)
private
FFileName: string;
- FModuleInterface: TIModuleInterface;
- FOwner: TInstantOTAIDENotifier3;
+ FEditorNotifierList: TInterfaceList;
+ FModuleInterface: IOTAModule;
+ FNotifierIndex: Integer;
+ FOwner: TInstantOTAIDENotifier5;
+ function GetEditorNotifierCount: Integer;
+ function GetEditorNotifierList: TInterfaceList;
+ procedure InstallEditorNotifiers;
+ procedure RemoveEditorNotifiers;
+ procedure RemoveSelfFromOwner;
+ procedure RemoveSelfNotifier;
+ protected
+ property EditorNotifierList: TInterfaceList read GetEditorNotifierList;
+ property EditorNotifierCount: Integer read GetEditorNotifierCount;
+ function GetModuleInterface: IOTAModule;
+ property ModuleInterface: IOTAModule read GetModuleInterface;
+ // IOTANotifier
+ procedure Destroyed;
+ // IOTAModuleNotifier
+ function CheckOverwrite: Boolean;
+ procedure ModuleNotification(const AFileName: string; NotifyCode:
+ TModuleNotifyCode);
+ procedure ModuleRenamed(const NewName: string);
+ // IInstantOTANotifierUninstallation
+ procedure UnInstallNotifier;
public
- constructor Create(AOwner: TInstantOTAIDENotifier3;
- AModuleInterface: TIModuleInterface; AFileName: string);
+ constructor Create(AOwner: TInstantOTAIDENotifier5; AModuleInterface:
+ IOTAModule);
destructor Destroy; override;
- procedure Notify(NotifyCode: TNotifyCode); override;
- {$IFDEF D6+}
- procedure ComponentRenamed(const AComponent: TComponent;
- const OldName, NewName: string); override;
- {$ELSE}
- procedure ComponentRenamed(ComponentHandle: Pointer;
- const OldName, NewName: string); override;
- {$ENDIF}
end;
TInstantOTAMessage = class(TInterfacedObject, IOTACustomMessage)
@@ -216,11 +257,74 @@
property ToolName: string read FToolName;
end;
+ TInstantOTABaseEditorNotifier = class(TNotifierObject, IOTANotifier,
+ IInstantOTANotifierUninstallation)
+ private
+ FNotifierIndex: Integer;
+ FOwner: TInstantOTAModuleNotifier;
+ protected
+ FFileName: string;
+ // IOTANotifier
+ procedure AfterSave;
+ procedure BeforeSave;
+ // IInstantOTANotifierUninstallation
+ procedure UnInstallNotifier;
+
+ procedure RemoveSelfFromOwner;
+ procedure RemoveSelfNotifier; virtual; abstract;
+ end;
+
+ TInstantOTAEditorNotifier = class(TInstantOTABaseEditorNotifier, IOTANotifier,
+ IOTAEditorNotifier, IInstantOTANotifierUninstallation)
+ private
+ FSourceInterface: IOTASourceEditor;
+ protected
+ procedure Destroyed;
+ procedure Modified;
+ // IOTAEditorNotifier
+ procedure ViewNotification(const View: IOTAEditView; Operation: TOperation);
+ procedure ViewActivated(const View: IOTAEditView);
+
+ procedure RemoveSelfNotifier; override;
+ public
+ constructor Create(AOwner: TInstantOTAModuleNotifier; ASourceEditorInterface:
+ IOTASourceEditor);
+ destructor Destroy; override;
+ end;
+
+ TInstantOTAFormNotifier = class(TInstantOTABaseEditorNotifier, IOTANotifier,
+ IOTAFormNotifier, IInstantOTANotifierUninstallation)
+ private
+ FFormInterface: IOTAFormEditor;
+ protected
+ procedure Destroyed;
+ procedure Modified;
+ // IOTAFormNotifier
+ procedure FormActivated;
+ procedure FormSaving;
+ procedure ComponentRenamed(ComponentHandle: TOTAHandle; const OldName, NewName:
+ string);
+
+ procedure RemoveSelfNotifier; override;
+ public
+ constructor Create(AOwner: TInstantOTAModuleNotifier; AFormEditorInterface:
+ IOTAFormEditor);
+ destructor Destroy; override;
+ end;
+
implementation
uses
Windows, SysUtils, Dialogs, Controls;
+type
+ // Use the PNoRefCnt type to assign interface instances without invoking
+ // reference counting. Only use this if you have a very good reason.
+ PNoRefCnt = Pointer;
+
+const
+ InvalidNotifierIndex = -1;
+
{ TInstantOTAIDEInterface }
function TInstantOTAIDEInterface.CurrentModule: IOTAModule;
@@ -231,7 +335,6 @@
destructor TInstantOTAIDEInterface.Destroy;
begin
MessageServices.ClearAllMessages;
- FIDENotifier3.Free;
FIDENotifier5.Free;
inherited;
end;
@@ -271,14 +374,16 @@
Result := nil;
end;
-function TInstantOTAIDEInterface.GetAfterCompilation: TInstantOTAAfterCompilationEvent;
+function TInstantOTAIDEInterface.GetOnAfterCompilation:
+ TInstantOTAAfterCompilationEvent;
begin
- Result := IDENotifier5.AfterCompilation;
+ Result := IDENotifier5.OnAfterCompilation;
end;
-function TInstantOTAIDEInterface.GetBeforeCompilation: TInstantOTABeforeCompilationEvent;
+function TInstantOTAIDEInterface.GetOnBeforeCompilation:
+ TInstantOTABeforeCompilationEvent;
begin
- Result := IDENotifier5.BeforeCompilation;
+ Result := IDENotifier5.OnBeforeCompilation;
end;
function TInstantOTAIDEInterface.GetEditActions: IOTAEditActions;
@@ -309,17 +414,14 @@
Result := nil;
end;
-function TInstantOTAIDEInterface.GetIDENotifier3: TInstantOTAIDENotifier3;
-begin
- if not Assigned(FIDENotifier3) then
- FIDENotifier3 := TInstantOTAIDENotifier3.Create(Self);
- Result := FIDENotifier3;
-end;
-
function TInstantOTAIDEInterface.GetIDENotifier5: TInstantOTAIDENotifier5;
begin
if not Assigned(FIDENotifier5) then
+ {$IFDEF D9+}
+ FIDENotifier5 := TInstantOTAIDENotifier8.Create(Self);
+ {$ELSE}
FIDENotifier5 := TInstantOTAIDENotifier5.Create(Self);
+ {$ENDIF}
Result := FIDENotifier5;
end;
@@ -330,22 +432,23 @@
function TInstantOTAIDEInterface.GetModuleServices: IOTAModuleServices;
begin
- Result := Services5 as IOTAModuleServices;
+ Result := Services as IOTAModuleServices;
end;
-function TInstantOTAIDEInterface.GetOnEventNotification: TInstantOTAEventNotificationEvent;
+function TInstantOTAIDEInterface.GetOnFileNotification: TInstantOTAFileNotificationEvent;
begin
- Result := IDENotifier3.OnEventNotification;
+ Result := IDENotifier5.OnFileNotification;
end;
-function TInstantOTAIDEInterface.GetOnFileNotification: TInstantOTAFileNotificationEvent;
+function TInstantOTAIDEInterface.GetOnModuleNotification: TInstantOTAModuleNotificationEvent;
begin
- Result := IDENotifier3.OnFileNotification;
+ Result := IDENotifier5.OnModuleNotification;
end;
-function TInstantOTAIDEInterface.GetOnModuleNotification: TInstantOTAModuleNotificationEvent;
+function TInstantOTAIDEInterface.GetOnModuleRenamedNotification:
+ TInstantOTAModuleRenamedNotificationEvent;
begin
- Result := IDENotifier3.OnModuleNotification;
+ Result := IDENotifier5.OnModuleRenamedNotification;
end;
function TInstantOTAIDEInterface.GetProjectGroup: IOTAProjectGroup;
@@ -359,18 +462,11 @@
Result := nil;
end;
-function TInstantOTAIDEInterface.GetServices3: TIToolServices;
+function TInstantOTAIDEInterface.GetServices: IOTAServices;
begin
- Result := ToolServices;
- if not Assigned(Result) then
-...
[truncated message content] |