diff --git a/.gitattributes b/.gitattributes index 78ea07cd23..235226f537 100644 --- a/.gitattributes +++ b/.gitattributes @@ -421,7 +421,6 @@ designer/changeclassdialog.lfm svneol=native#text/plain designer/changeclassdialog.lrs svneol=native#text/pascal designer/changeclassdialog.pas svneol=native#text/pascal designer/controlselection.pp svneol=native#text/pascal -designer/customeditor.pp svneol=native#text/pascal designer/designer.pp svneol=native#text/pascal designer/designermenu.pp svneol=native#text/pascal designer/designerprocs.pas svneol=native#text/pascal @@ -431,6 +430,7 @@ designer/jitforms.pp svneol=native#text/pascal designer/menueditorform.pas svneol=native#text/pascal designer/menupropedit.pp svneol=native#text/pascal designer/noncontrolforms.pas svneol=native#text/pascal +designer/objinspext.pas svneol=native#text/pascal designer/scalecompsdlg.pp svneol=native#text/pascal designer/sizecompsdlg.pp svneol=native#text/pascal designer/taborderdlg.lfm svneol=native#text/plain diff --git a/components/codetools/codetoolmanager.pas b/components/codetools/codetoolmanager.pas index 4955a73b07..53cd5435a7 100644 --- a/components/codetools/codetoolmanager.pas +++ b/components/codetools/codetoolmanager.pas @@ -65,6 +65,8 @@ type const PersistentClassName, AncestorClassName, Identifier: string; var IsDefined: boolean) of object; + { TCodeToolManager } + TCodeToolManager = class private FAbortable: boolean; @@ -304,6 +306,7 @@ type function GatherIdentifiers(Code: TCodeBuffer; X,Y: integer): boolean; function GetIdentifierAt(Code: TCodeBuffer; X,Y: integer; var Identifier: string): boolean; + function IdentItemCheckHasChilds(IdentItem: TIdentifierListItem): boolean; // rename identifier function FindReferences(IdentifierCode: TCodeBuffer; @@ -1461,6 +1464,21 @@ begin end; end; +function TCodeToolManager.IdentItemCheckHasChilds(IdentItem: TIdentifierListItem + ): boolean; +begin + Result:=false; + {$IFDEF CTDEBUG} + DebugLn('TCodeToolManager.IdentItemCheckHasChilds A '); + {$ENDIF} + try + IdentItem.CheckHasChilds; + Result:=true; + except + on e: Exception do HandleException(e); + end; +end; + function TCodeToolManager.FindReferences(IdentifierCode: TCodeBuffer; X, Y: integer; TargetCode: TCodeBuffer; SkipComments: boolean; var ListOfPCodeXYPosition: TList): boolean; diff --git a/components/codetools/identcompletiontool.pas b/components/codetools/identcompletiontool.pas index d01f76cc8c..7c8bfb7eaf 100644 --- a/components/codetools/identcompletiontool.pas +++ b/components/codetools/identcompletiontool.pas @@ -1078,6 +1078,7 @@ var Params: TFindDeclarationParams; begin if (iliBaseExprTypeValid in Flags) then exit; + BaseExprType:=CleanExpressionType; BaseExprType.Desc:=xtNone; if (Node<>nil) and (Tool<>nil) then begin Tool.ActivateGlobalWriteLock; diff --git a/components/synedit/synedit.pp b/components/synedit/synedit.pp index 443b868bd8..4f4e002e75 100644 --- a/components/synedit/synedit.pp +++ b/components/synedit/synedit.pp @@ -2018,7 +2018,7 @@ begin // don't fire the event if key is to be ignored if not (sfIgnoreNextChar in fStateFlags) then begin {$IFDEF VerboseKeyboard} - DebugLn('TCustomSynEdit.UTF8KeyPress ',DbgSName(Self),' Key="',DbgStr(Key),'" UseUTF8=',dbgs(UseUTF8)); + DebugLn('TCustomSynEdit.KeyPress ',DbgSName(Self),' Key="',DbgStr(Key),'" UseUTF8=',dbgs(UseUTF8)); {$ENDIF} if Assigned(OnKeyPress) then OnKeyPress(Self, Key); CommandProcessor(ecChar, Key, nil); diff --git a/designer/customeditor.pp b/designer/customeditor.pp deleted file mode 100644 index 4a9ae0c88b..0000000000 --- a/designer/customeditor.pp +++ /dev/null @@ -1,64 +0,0 @@ -{ - /*************************************************************************** - CustomEditor.pp - ------------------- - - ***************************************************************************/ - - *************************************************************************** - * * - * This source is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This code is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * A copy of the GNU General Public License is available on the World * - * Wide Web at . You can also * - * obtain it by writing to the Free Software Foundation, * - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - *************************************************************************** -} -unit CustomEditor; - -{$mode objfpc} - -interface - -uses - classes,AbstractEditor, FileSystem; - -type - - TCustomEditor = class(TAbstractEditor) - private - FSource : TStrings; //Holds the source retrieved from TFileSystem - Function GetSource: TStrings; //Returns the source from TFileSystem - Procedure SetSource(value : TStrings); //Set's the source in the TFileSystem - public - constructor Create; - destructor destroy; - Function Filename : String; override; - property Source: TStrings read GetSource write SetSource; //Holds the source retrieved from TFileSystem - end; - - -implementation - -constructor TCustomEditor.Create; -Begin -//Create the TFileSystem -end; - -Function TCustomEditor.GetSource : TStrings; -Begin -Result := nil; -End; - - -end. diff --git a/designer/objinspext.pas b/designer/objinspext.pas new file mode 100644 index 0000000000..f40c0e454d --- /dev/null +++ b/designer/objinspext.pas @@ -0,0 +1,244 @@ +{ + ***************************************************************************** + * * + * See the file COPYING.modifiedLGPL, included in this distribution, * + * for details about the copyright. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * * + ***************************************************************************** + + Author: Mattias Gaertner + + Abstract: + Extension for the Object Inspector. + - Favourites properties +} +unit ObjInspExt; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, ObjectInspector, Forms, Controls, Buttons, StdCtrls, + ExtCtrls, Dialogs, + ConfigStorage, LazarusIDEStrConsts; + +type + + { TOIAddRemoveFavouriteDlg } + + TOIAddRemoveFavouriteDlg = class(TForm) + NoteLabel: TLabel; + ClassCombobox: TComboBox; + OkButton: TButton; + CancelButton: TButton; + procedure OkButtonClick(Sender: TObject); + private + FAddMode: Boolean; + FObjectInspector: TObjectInspector; + FPropertyName: string; + procedure SetAddMode(const AValue: Boolean); + procedure SetObjectInspector(const AValue: TObjectInspector); + procedure UpdateLabel; + procedure UpdateComboBox; + procedure UpdateMode; + public + constructor Create(TheOwner: TComponent); override; + public + property ObjectInspector: TObjectInspector read FObjectInspector + write SetObjectInspector; + property PropertyName: string read FPropertyName; + property AddMode: Boolean read FAddMode write SetAddMode; + end; + +function CreateDefaultOIFavouriteProperties: TOIFavouriteProperties; +function ShowAddRemoveFavouriteDialog(ObjInspector: TObjectInspector; + Add: Boolean): TModalResult; +function LoadOIFavouriteProperties: TOIFavouriteProperties; +procedure SaveOIFavouriteProperties(ObjInspector: TObjectInspector); + +implementation + +function CreateDefaultOIFavouriteProperties: TOIFavouriteProperties; + + procedure Add(ABaseClass: TPersistentClass; const APropertyName: string); + begin + Result.Add(TOIFavouriteProperty.Create(ABaseClass,APropertyName,true)); + end; + +begin + Result:=TOIFavouriteProperties.Create; + // TControl + Add(TControl,'Name'); + Add(TControl,'Anchors'); + Add(TControl,'Caption'); + Add(TControl,'OnClick'); + // miscellaneous + Add(TGroupBox,'Align'); + Add(TImage,'Align'); +end; + +function ShowAddRemoveFavouriteDialog(ObjInspector: TObjectInspector; + Add: Boolean): TModalResult; +var + OIAddRemoveFavouriteDlg: TOIAddRemoveFavouriteDlg; +begin + OIAddRemoveFavouriteDlg:=TOIAddRemoveFavouriteDlg.Create(nil); + OIAddRemoveFavouriteDlg.ObjectInspector:=ObjInspector; + OIAddRemoveFavouriteDlg.AddMode:=Add; + Result:=OIAddRemoveFavouriteDlg.ShowModal; + OIAddRemoveFavouriteDlg.Free; +end; + +function LoadOIFavouriteProperties: TOIFavouriteProperties; +begin + Result:=CreateDefaultOIFavouriteProperties; + // TODO: load and merge +end; + +procedure SaveOIFavouriteProperties(ObjInspector: TObjectInspector); +begin + // TODO save only changes +end; + +{ TOIAddRemoveFavouriteDlg } + +procedure TOIAddRemoveFavouriteDlg.OkButtonClick(Sender: TObject); +var + NewClassName: String; + CurClass: TClass; + NewFavourite: TOIFavouriteProperty; +begin + NewClassName:=ClassCombobox.Text; + if (ObjectInspector<>nil) and (ObjectInspector.Selection<>nil) + and (ObjectInspector.Selection.Count>0) then begin + CurClass:=ObjectInspector.Selection[0].ClassType; + while CurClass.InheritsFrom(TPersistent) do begin + if CompareText(NewClassName,CurClass.ClassName)=0 then begin + NewFavourite:=TOIFavouriteProperty.Create(TPersistentClass(CurClass), + PropertyName,AddMode); + ObjectInspector.Favourites.DeleteConstraints(NewFavourite); + ObjectInspector.Favourites.Add(NewFavourite); + ObjectInspector.FavouriteGrid.BuildPropertyList; + ModalResult:=mrOk; + exit; + end; + CurClass:=CurClass.ClassParent; + end; + end; + MessageDlg('Class not found','Class "'+NewClassName+'" not found.',mtError, + [mbOk],0); +end; + +procedure TOIAddRemoveFavouriteDlg.SetObjectInspector(const AValue: TObjectInspector + ); +var + CurRow: TOIPropertyGridRow; +begin + if FObjectInspector=AValue then exit; + FObjectInspector:=AValue; + CurRow:=ObjectInspector.GetActivePropertyRow; + if (CurRow<>nil) and (CurRow.Editor<>nil) then + FPropertyName:=CurRow.Editor.GetName; + UpdateLabel; + UpdateComboBox; +end; + +procedure TOIAddRemoveFavouriteDlg.SetAddMode(const AValue: Boolean); +begin + if FAddMode=AValue then exit; + FAddMode:=AValue; + UpdateMode; +end; + +procedure TOIAddRemoveFavouriteDlg.UpdateLabel; +begin + NoteLabel.Caption:='Choose a base class for the favourite ' + +'property "'+PropertyName+'".'; +end; + +procedure TOIAddRemoveFavouriteDlg.UpdateComboBox; +var + CurClass: TClass; + NewItems: TStringList; +begin + NewItems:=TStringList.Create; + if (ObjectInspector<>nil) and (ObjectInspector.Selection<>nil) + and (ObjectInspector.Selection.Count>0) then begin + CurClass:=ObjectInspector.Selection[0].ClassType; + // add only classes, that are TPersistent and have a registered class + while CurClass.InheritsFrom(TPersistent) do begin + NewItems.Add(CurClass.ClassName); + CurClass:=CurClass.ClassParent; + end; + end; + ClassCombobox.Items.Assign(NewItems); + if ClassCombobox.Items.Count>0 then + ClassCombobox.ItemIndex:=0; + NewItems.Free; +end; + +procedure TOIAddRemoveFavouriteDlg.UpdateMode; +begin + if AddMode then begin + Caption:='Add to favourite properties'; + OkButton.Caption:='Add'; + end else begin + Caption:='Remove from favourite properties'; + OkButton.Caption:='Remove'; + end; +end; + +constructor TOIAddRemoveFavouriteDlg.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + + Name:='OIAddToFavouriteDlg'; + Width:=300; + Height:=150; + Position:=poDesktopCenter; + + NoteLabel:=TLabel.Create(Self); + with NoteLabel do begin + Name:='NoteLabel'; + SetBounds(5,5,Self.ClientWidth-10,50); + WordWrap:=true; + Parent:=Self; + end; + + ClassCombobox:=TComboBox.Create(Self); + with ClassCombobox do begin + Name:='ClassCombobox'; + SetBounds(5,60,200,Height); + Parent:=Self; + end; + + OkButton:=TButton.Create(Self); + with OkButton do begin + Name:='AddButton'; + SetBounds(5,100,80,25); + Caption:='Add'; + Parent:=Self; + OnClick:=@OkButtonClick; + end; + DefaultControl:=OkButton; + + CancelButton:=TButton.Create(Self); + with CancelButton do begin + Name:='CancelButton'; + SetBounds(120,100,80,25); + Caption:='Cancel'; + Parent:=Self; + ModalResult:=mrCancel; + end; + CancelControl:=CancelButton; + + UpdateMode; +end; + +end. + diff --git a/ide/main.pp b/ide/main.pp index 471d85121c..001868b0f6 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -84,7 +84,7 @@ uses // help manager HelpManager, // designer - ComponentPalette, ComponentReg, + ComponentPalette, ComponentReg, ObjInspExt, Designer, FormEditor, CustomFormEditor, ControlSelection, AnchorEditor, {$DEFINE UseNewMenuEditor} @@ -333,11 +333,13 @@ type procedure OIOnShowOptions(Sender: TObject); procedure OIRemainingKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); - procedure OnPropHookGetMethods(TypeData:PTypeData; Proc:TGetStringProc); - function OnPropHookMethodExists(const AMethodName:ShortString; + procedure OIOnAddToFavourites(Sender: TObject); + procedure OIOnRemoveFromFavourites(Sender: TObject); + procedure OnPropHookGetMethods(TypeData: PTypeData; Proc:TGetStringProc); + function OnPropHookMethodExists(const AMethodName: ShortString; TypeData: PTypeData; var MethodIsCompatible, MethodIsPublished, - IdentIsMethod: boolean): boolean; + IdentIsMethod: boolean): boolean; function OnPropHookCreateMethod(const AMethodName:ShortString; ATypeInfo:PTypeInfo): TMethod; procedure OnPropHookShowMethod(const AMethodName:ShortString); @@ -451,7 +453,6 @@ type procedure Notification(AComponent: TComponent; Operation: TOperation); override; - procedure ToolButtonClick(Sender: TObject); procedure OnApplyWindowLayout(ALayout: TIDEWindowLayout); procedure AddRecentProjectFileToEnvironment(const AFilename: string); @@ -1123,6 +1124,16 @@ begin OnExecuteIDECommand(Sender,Key,Shift,caDesign); end; +procedure TMainIDE.OIOnAddToFavourites(Sender: TObject); +begin + ShowAddRemoveFavouriteDialog(ObjectInspector1,true); +end; + +procedure TMainIDE.OIOnRemoveFromFavourites(Sender: TObject); +begin + ShowAddRemoveFavouriteDialog(ObjectInspector1,false); +end; + procedure TMainIDE.OnPropHookGetMethods(TypeData:PTypeData; Proc:TGetStringProc); var ActiveSrcEdit: TSourceEditor; @@ -1141,12 +1152,6 @@ begin end; end; -Procedure TMainIDE.ToolButtonClick(Sender: TObject); -Begin - Assert(False, 'Trace:TOOL BUTTON CLICK!'); - -end; - {------------------------------------------------------------------------------} procedure TMainIDE.MainIDEFormClose(Sender: TObject; var CloseAction: TCloseAction); @@ -1333,6 +1338,12 @@ begin ObjectInspector1.OnSelectPersistentsInOI:=@OIOnSelectPersistents; ObjectInspector1.OnShowOptions:=@OIOnShowOptions; ObjectInspector1.OnRemainingKeyUp:=@OIRemainingKeyUp; + {$IFDEF EnableOIFavourites} + ObjectInspector1.ShowFavouritePage:=true; + {$ENDIF} + ObjectInspector1.Favourites:=LoadOIFavouriteProperties; + ObjectInspector1.OnAddToFavourites:=@OIOnAddToFavourites; + ObjectInspector1.OnRemoveFromFavourites:=@OIOnRemoveFromFavourites; GlobalDesignHook:=TPropertyEditorHook.Create; GlobalDesignHook.GetPrivateDirectory:=AppendPathDelim(GetPrimaryConfigPath); @@ -11533,6 +11544,9 @@ end. { ============================================================================= $Log$ + Revision 1.863 2005/03/29 09:30:14 mattias + started OI favourites + Revision 1.862 2005/03/23 10:45:05 mattias fixed ambigious with ambiguous diff --git a/ide/sourceeditprocs.pas b/ide/sourceeditprocs.pas index 8c618ca0b0..16efe7cfda 100644 --- a/ide/sourceeditprocs.pas +++ b/ide/sourceeditprocs.pas @@ -36,7 +36,7 @@ interface uses Classes, SysUtils, LCLProc, BasicCodeTools, CodeTree, CodeToolManager, PascalParserTool, IdentCompletionTool, GraphType, Graphics, EditorOptions, - SynEdit, SynCompletion; + SynEdit, SynCompletion, MainIntf; type TCompletionType = ( @@ -283,13 +283,18 @@ begin Result:=''; CursorToLeft:=0; CursorAtEnd:=true; + ValueType:=icvIdentifier; Index:=aCompletion.Position; IdentList:=CodeToolBoss.IdentifierList; + IdentItem:=IdentList.FilteredItems[Index]; - IdentItem.CheckHasChilds; - ValueType:=icvIdentifier; if IdentItem=nil then exit; + if not CodeToolBoss.IdentItemCheckHasChilds(IdentItem) then begin + MainIDEInterface.DoJumpToCodeToolBossError; + exit; + end; + Result:=GetIdentifier(IdentItem.Identifier); case IdentItem.GetDesc of diff --git a/ideintf/objectinspector.pp b/ideintf/objectinspector.pp index b9b9057386..3708c14dd3 100644 --- a/ideintf/objectinspector.pp +++ b/ideintf/objectinspector.pp @@ -42,12 +42,63 @@ uses PropEdits, GraphPropEdits, ListViewPropEdit, ImageListEditor, ComponentTreeView; +const + OIOptionsFileVersion = 2; type EObjectInspectorException = class(Exception); TObjectInspector = class; + // standard ObjectInspector pages + TObjectInspectorPage = ( + oipgpProperties, + oipgpEvents, + oipgpFavourite + ); + TObjectInspectorPages = set of TObjectInspectorPage; + + + { TOIFavouriteProperty + BaseClassName } + TOIFavouriteProperty = class + public + BaseClass: TPersistentClass; + BaseClassname: string; + PropertyName: string; + Include: boolean; // include or exclude + constructor Create(ABaseClass: TPersistentClass; + const APropertyName: string; TheInclude: boolean); + function Constrains(AnItem: TOIFavouriteProperty): boolean; + function IsFavourite(AClass: TPersistentClass; + const APropertyName: string): boolean; + end; + + { TOIFavouriteProperties } + + TOIFavouriteProperties = class + private + FItems: TList; + FCount: integer; + function GetItems(Index: integer): TOIFavouriteProperty; + public + constructor Create; + destructor Destroy; override; + procedure Clear; + procedure Add(NewItem: TOIFavouriteProperty); + procedure Remove(AnItem: TOIFavouriteProperty); + procedure DeleteConstraints(AnItem: TOIFavouriteProperty); + function IsFavourite(AClass: TPersistentClass; + const PropertyName: string): boolean; + function AreFavourites(Selection: TPersistentSelectionList; + const PropertyName: string): boolean; + procedure LoadFromConfig(ConfigStore: TConfigStorage; const Path: string); + procedure SaveToConfig(ConfigStore: TConfigStorage; const Path: string); + public + property Items[Index: integer]: TOIFavouriteProperty read GetItems; default; + property Count: integer read FCount; + end; + { TOIOptions } @@ -63,11 +114,13 @@ type FTop: integer; FWidth: integer; FHeight: integer; - FPropertyGridSplitterX: integer; - FEventGridSplitterX: integer; + FGridSplitterX: array[TObjectInspectorPage] of integer; FGridBackgroundColor: TColor; FShowHints: boolean; + function FPropertyGridSplitterX(Page: TObjectInspectorPage): integer; + procedure FPropertyGridSplitterX(Page: TObjectInspectorPage; + const AValue: integer); public constructor Create; function Load: boolean; @@ -82,10 +135,8 @@ type property Top:integer read FTop write FTop; property Width:integer read FWidth write FWidth; property Height:integer read FHeight write FHeight; - property PropertyGridSplitterX:integer read FPropertyGridSplitterX - write FPropertyGridSplitterX; - property EventGridSplitterX:integer read FEventGridSplitterX - write FEventGridSplitterX; + property GridSplitterX[Page: TObjectInspectorPage]:integer + read FPropertyGridSplitterX write FPropertyGridSplitterX; property DefaultItemHeight: integer read FDefaultItemHeight write FDefaultItemHeight; property ShowComponentTree: boolean read FShowComponentTree @@ -168,6 +219,7 @@ type FDragging: boolean; FExpandedProperties: TStringList; FExpandingRow: TOIPropertyGridRow; + FFavourites: TOIFavouriteProperties; FFilter: TTypeKinds; FIndent: integer; FItemIndex: integer; @@ -176,7 +228,7 @@ type FOnModified: TNotifyEvent; FPreferredSplitterX: integer; // best splitter position FPropertyEditorHook: TPropertyEditorHook; - FRows:TList; + FRows: TList; FSelection: TPersistentSelectionList; FSplitterX: integer; // current splitter position FStates: TOIPropertyGridStates; @@ -196,6 +248,7 @@ type procedure ClearRows; function GetCurrentEditValue: string; procedure SetCurrentEditValue(const NewValue: string); + procedure SetFavourites(const AValue: TOIFavouriteProperties); procedure SetItemIndex(NewIndex:integer); procedure SetItemsTops; @@ -274,17 +327,17 @@ type function GetActiveRow: TOIPropertyGridRow; function GetHintTypeAt(RowIndex: integer; X: integer): TPropEditHint; - function GetRowByPath(const PropPath:string): TOIPropertyGridRow; - function GridHeight:integer; - function MouseToIndex(y:integer;MustExist:boolean):integer; - function PropertyPath(Index:integer):string; - function TopMax:integer; + function GetRowByPath(const PropPath: string): TOIPropertyGridRow; + function GridHeight: integer; + function MouseToIndex(y: integer; MustExist: boolean):integer; + function PropertyPath(Index: integer):string; + function TopMax: integer; procedure BuildPropertyList; procedure Clear; procedure Paint; override; procedure PropEditLookupRootChange; procedure RefreshPropertyValues; - procedure SetBounds(aLeft,aTop,aWidth,aHeight:integer); override; + procedure SetBounds(aLeft, aTop, aWidth, aHeight: integer); override; procedure SetCurrentRowValue(const NewValue: string); public property BackgroundColor: TColor read FBackgroundColor @@ -294,24 +347,26 @@ type write SetCurrentEditValue; property DefaultItemHeight:integer read FDefaultItemHeight write FDefaultItemHeight default 25; - property DefaultValueFont:TFont read FDefaultValueFont write FDefaultValueFont; - property ExpandedProperties:TStringList read FExpandedProperties + property DefaultValueFont: TFont read FDefaultValueFont write FDefaultValueFont; + property ExpandedProperties: TStringList read FExpandedProperties write FExpandedProperties; - property Indent:integer read FIndent write FIndent default 9; - property ItemIndex:integer read FItemIndex write SetItemIndex; - property NameFont:TFont read FNameFont write FNameFont; + property Indent: integer read FIndent write FIndent default 9; + property ItemIndex: integer read FItemIndex write SetItemIndex; + property NameFont: TFont read FNameFont write FNameFont; property OnModified: TNotifyEvent read FOnModified write FOnModified; property PrefferedSplitterX: integer read FPreferredSplitterX write FPreferredSplitterX default 100; property PropertyEditorHook: TPropertyEditorHook read FPropertyEditorHook write SetPropertyEditorHook; - property RowCount:integer read GetRowCount; - property Rows[Index:integer]:TOIPropertyGridRow read GetRow; + property RowCount: integer read GetRowCount; + property Rows[Index: integer]:TOIPropertyGridRow read GetRow; property Selection: TPersistentSelectionList read FSelection write SetSelection; - property SplitterX:integer read FSplitterX write SetSplitterX default 100; - property TopY:integer read FTopY write SetTopY default 0; - property ValueFont:TFont read FValueFont write FValueFont; + property SplitterX: integer read FSplitterX write SetSplitterX default 100; + property TopY: integer read FTopY write SetTopY default 0; + property ValueFont: TFont read FValueFont write FValueFont; + property Favourites: TOIFavouriteProperties read FFavourites + write SetFavourites; end; @@ -383,6 +438,8 @@ type oifRebuildPropListsNeeded ); TOIFlags = set of TOIFlag; + + { TObjectInspector } TObjectInspector = class (TForm) AvailPersistentComboBox: TComboBox; @@ -391,10 +448,13 @@ type NoteBook: TNoteBook; PropertyGrid: TOICustomPropertyGrid; EventGrid: TOICustomPropertyGrid; + FavouriteGrid: TOICustomPropertyGrid; StatusBar: TStatusBar; MainPopupMenu: TPopupMenu; ColorsPopupMenuItem: TMenuItem; SetDefaultPopupMenuItem: TMenuItem; + AddToFavouritesPopupMenuItem: TMenuItem; + RemoveFromFavouritesPopupMenuItem: TMenuItem; UndoPropertyPopupMenuItem: TMenuItem; BackgroundColPopupMenuItem: TMenuItem; ShowHintsPopupMenuItem: TMenuItem; @@ -405,15 +465,19 @@ type procedure ObjectInspectorResize(Sender: TObject); procedure OnGriddKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure OnSetDefaultPopupmenuItemClick(Sender: TObject); + procedure OnAddToFavouritesPopupmenuItemClick(Sender: TObject); + procedure OnRemoveFromFavouritesPopupmenuItemClick(Sender: TObject); procedure OnUndoPopupmenuItemClick(Sender: TObject); procedure OnBackgroundColPopupMenuItemClick(Sender: TObject); procedure OnShowHintPopupMenuItemClick(Sender: TObject); procedure OnShowOptionsPopupMenuItemClick(Sender: TObject); procedure OnShowComponentTreePopupMenuItemClick(Sender: TObject); procedure OnMainPopupMenuPopup(Sender: TObject); - procedure HookRefreshPropertyValues; private + FFavourites: TOIFavouriteProperties; + FOnAddToFavourites: TNotifyEvent; FOnRemainingKeyUp: TKeyEvent; + FOnRemoveFromFavourites: TNotifyEvent; FSelection: TPersistentSelectionList; FComponentTreeHeight: integer; FDefaultItemHeight: integer; @@ -424,27 +488,32 @@ type FOnSelectPersistentsInOI: TNotifyEvent; FOnModified: TNotifyEvent; FShowComponentTree: boolean; + FShowFavouritePage: boolean; FUpdateLock: integer; FUpdatingAvailComboBox: boolean; FUsePairSplitter: boolean; - protected - function PersistentToString(APersistent: TPersistent): string; + function GetGridControl(Page: TObjectInspectorPage): TOICustomPropertyGrid; + procedure SetFavourites(const AValue: TOIFavouriteProperties); + procedure SetShowFavouritePage(const AValue: boolean); procedure SetComponentTreeHeight(const AValue: integer); procedure SetDefaultItemHeight(const AValue: integer); procedure SetOnShowOptions(const AValue: TNotifyEvent); procedure SetPropertyEditorHook(NewValue: TPropertyEditorHook); procedure SetSelection(const ASelection: TPersistentSelectionList); + procedure SetShowComponentTree(const AValue: boolean); + procedure SetUsePairSplitter(const AValue: boolean); + protected + function PersistentToString(APersistent: TPersistent): string; procedure AddPersistentToList(APersistent: TPersistent; List: TStrings); procedure HookLookupRootChange; procedure OnGridModified(Sender: TObject); procedure SetAvailComboBoxText; procedure HookGetSelection(const ASelection: TPersistentSelectionList); procedure HookSetSelection(const ASelection: TPersistentSelectionList); - procedure SetShowComponentTree(const AValue: boolean); - procedure SetUsePairSplitter(const AValue: boolean); procedure CreatePairSplitter; procedure DestroyNoteBook; procedure CreateNoteBook; + procedure CreateFavouritePage; procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure KeyUp(var Key: Word; Shift: TShiftState); override; public @@ -459,6 +528,7 @@ type function GetActivePropertyGrid: TOICustomPropertyGrid; function GetActivePropertyRow: TOIPropertyGridRow; function GetCurRowDefaultValue(var DefaultStr: string): boolean; + procedure HookRefreshPropertyValues; public property DefaultItemHeight: integer read FDefaultItemHeight write SetDefaultItemHeight; @@ -471,15 +541,41 @@ type property PropertyEditorHook: TPropertyEditorHook read FPropertyEditorHook write SetPropertyEditorHook; property OnModified: TNotifyEvent read FOnModified write FOnModified; - property OnShowOptions: TNotifyEvent read FOnShowOptions write SetOnShowOptions; - property OnRemainingKeyUp: TKeyEvent read FOnRemainingKeyUp write FOnRemainingKeyUp; - property ShowComponentTree: boolean read FShowComponentTree write SetShowComponentTree; - property ComponentTreeHeight: integer read FComponentTreeHeight write SetComponentTreeHeight; - property UsePairSplitter: boolean read FUsePairSplitter write SetUsePairSplitter; + property OnShowOptions: TNotifyEvent read FOnShowOptions + write SetOnShowOptions; + property OnRemainingKeyUp: TKeyEvent read FOnRemainingKeyUp + write FOnRemainingKeyUp; + property ShowComponentTree: boolean read FShowComponentTree + write SetShowComponentTree; + property ComponentTreeHeight: integer read FComponentTreeHeight + write SetComponentTreeHeight; + property UsePairSplitter: boolean read FUsePairSplitter + write SetUsePairSplitter; + property ShowFavouritePage: boolean read FShowFavouritePage + write SetShowFavouritePage; + property GridControl[Page: TObjectInspectorPage]: TOICustomPropertyGrid + read GetGridControl; + property Favourites: TOIFavouriteProperties read FFavourites write SetFavourites; + property OnAddToFavourites: TNotifyEvent read FOnAddToFavourites + write FOnAddToFavourites; + property OnRemoveFromFavourites: TNotifyEvent read FOnRemoveFromFavourites + write FOnRemoveFromFavourites; end; const DefaultObjectInspectorName: string = 'ObjectInspector'; + + DefaultOIPageNames: array[TObjectInspectorPage] of shortstring = ( + 'PropertyPage', + 'EventPage', + 'FavouritePage' + ); + DefaultOIGridNames: array[TObjectInspectorPage] of shortstring = ( + 'PropertyGrid', + 'EventGrid', + 'FavouriteGrid' + ); + //****************************************************************************** @@ -1118,8 +1214,16 @@ begin end; procedure TOICustomPropertyGrid.AddPropertyEditor(PropEditor: TPropertyEditor); -var NewRow:TOIPropertyGridRow; +var + NewRow: TOIPropertyGridRow; begin + if Favourites<>nil then begin + //debugln('TOICustomPropertyGrid.AddPropertyEditor A ',PropEditor.GetName); + if not Favourites.AreFavourites(Selection,PropEditor.GetName) then begin + PropEditor.Free; + exit; + end; + end; NewRow:=TOIPropertyGridRow.Create(Self,PropEditor,nil); FRows.Add(NewRow); if FRows.Count>1 then begin @@ -1830,6 +1934,15 @@ begin ValueComboBox.Text:=NewValue; end; +procedure TOICustomPropertyGrid.SetFavourites( + const AValue: TOIFavouriteProperties); +begin + //debugln('TOICustomPropertyGrid.SetFavourites ',dbgsName(Self)); + if FFavourites=AValue then exit; + FFavourites:=AValue; + BuildPropertyList; +end; + procedure TOICustomPropertyGrid.Clear; begin ClearRows; @@ -2230,7 +2343,20 @@ end; { TOIOptions } +function TOIOptions.FPropertyGridSplitterX(Page: TObjectInspectorPage): integer; +begin + Result:=FGridSplitterX[Page]; +end; + +procedure TOIOptions.FPropertyGridSplitterX(Page: TObjectInspectorPage; + const AValue: integer); +begin + FGridSplitterX[Page]:=AValue; +end; + constructor TOIOptions.Create; +var + p: TObjectInspectorPage; begin inherited Create; @@ -2239,8 +2365,8 @@ begin FTop:=0; FWidth:=250; FHeight:=400; - FPropertyGridSplitterX:=110; - FEventGridSplitterX:=110; + for p:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + FGridSplitterX[p]:=110; FDefaultItemHeight:=20; FShowComponentTree:=true; FComponentTreeHeight:=100; @@ -2249,36 +2375,51 @@ begin end; function TOIOptions.Load: boolean; +var + Path: String; + FileVersion: integer; + Page: TObjectInspectorPage; begin Result:=false; if ConfigStore=nil then exit; try - FSaveBounds:=ConfigStore.GetValue('ObjectInspectorOptions/Bounds/Valid' + Path:='ObjectInspectorOptions/'; + FileVersion:=ConfigStore.GetValue(Path+'Version/Value',0); + + FSaveBounds:=ConfigStore.GetValue(Path+'Bounds/Valid' ,false); if FSaveBounds then begin - FLeft:=ConfigStore.GetValue('ObjectInspectorOptions/Bounds/Left',0); - FTop:=ConfigStore.GetValue('ObjectInspectorOptions/Bounds/Top',0); - FWidth:=ConfigStore.GetValue('ObjectInspectorOptions/Bounds/Width',250); - FHeight:=ConfigStore.GetValue('ObjectInspectorOptions/Bounds/Height',400); + FLeft:=ConfigStore.GetValue(Path+'Bounds/Left',0); + FTop:=ConfigStore.GetValue(Path+'Bounds/Top',0); + FWidth:=ConfigStore.GetValue(Path+'Bounds/Width',250); + FHeight:=ConfigStore.GetValue(Path+'Bounds/Height',400); end; - FPropertyGridSplitterX:=ConfigStore.GetValue( - 'ObjectInspectorOptions/Bounds/PropertyGridSplitterX',110); - if FPropertyGridSplitterX<10 then FPropertyGridSplitterX:=10; - FEventGridSplitterX:=ConfigStore.GetValue( - 'ObjectInspectorOptions/Bounds/EventGridSplitterX',110); - if FEventGridSplitterX<10 then FEventGridSplitterX:=10; + + if FileVersion>=2 then begin + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + FGridSplitterX[oipgpProperties]:=ConfigStore.GetValue( + Path+'Bounds/'+DefaultOIPageNames[Page]+'/SplitterX',110); + end else begin + FGridSplitterX[oipgpProperties]:=ConfigStore.GetValue( + Path+'Bounds/PropertyGridSplitterX',110); + FGridSplitterX[oipgpEvents]:=ConfigStore.GetValue( + Path+'Bounds/EventGridSplitterX',110); + end; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + if FGridSplitterX[Page]<10 then FGridSplitterX[Page]:=10; + FDefaultItemHeight:=ConfigStore.GetValue( - 'ObjectInspectorOptions/Bounds/DefaultItemHeight',20); + Path+'Bounds/DefaultItemHeight',20); if FDefaultItemHeight<0 then FDefaultItemHeight:=20; FShowComponentTree:=ConfigStore.GetValue( - 'ObjectInspectorOptions/ComponentTree/Show/Value',true); + Path+'ComponentTree/Show/Value',true); FComponentTreeHeight:=ConfigStore.GetValue( - 'ObjectInspectorOptions/ComponentTree/Height/Value',100); + Path+'ComponentTree/Height/Value',100); FGridBackgroundColor:=ConfigStore.GetValue( - 'ObjectInspectorOptions/GridBackgroundColor',clBtnFace); + Path+'GridBackgroundColor',clBtnFace); FShowHints:=ConfigStore.GetValue( - 'ObjectInspectorOptions/ShowHints',false); + Path+'ShowHints',false); except on E: Exception do begin DebugLn('ERROR: TOIOptions.Load: ',E.Message); @@ -2289,34 +2430,41 @@ begin end; function TOIOptions.Save: boolean; +var + Page: TObjectInspectorPage; + Path: String; begin Result:=false; if ConfigStore=nil then exit; try - ConfigStore.SetDeleteValue('ObjectInspectorOptions/Bounds/Valid',FSaveBounds, + Path:='ObjectInspectorOptions/'; + ConfigStore.SetValue(Path+'Version/Value',OIOptionsFileVersion); + + ConfigStore.SetDeleteValue(Path+'Bounds/Valid',FSaveBounds, + false); + + ConfigStore.SetDeleteValue(Path+'Bounds/Valid',FSaveBounds, false); if FSaveBounds then begin - ConfigStore.SetValue('ObjectInspectorOptions/Bounds/Left',FLeft); - ConfigStore.SetValue('ObjectInspectorOptions/Bounds/Top',FTop); - ConfigStore.SetValue('ObjectInspectorOptions/Bounds/Width',FWidth); - ConfigStore.SetValue('ObjectInspectorOptions/Bounds/Height',FHeight); + ConfigStore.SetValue(Path+'Bounds/Left',FLeft); + ConfigStore.SetValue(Path+'Bounds/Top',FTop); + ConfigStore.SetValue(Path+'Bounds/Width',FWidth); + ConfigStore.SetValue(Path+'Bounds/Height',FHeight); end; - ConfigStore.SetDeleteValue( - 'ObjectInspectorOptions/Bounds/PropertyGridSplitterX', - FPropertyGridSplitterX, 110); - ConfigStore.SetDeleteValue( - 'ObjectInspectorOptions/Bounds/EventGridSplitterX', - FEventGridSplitterX, 110); - ConfigStore.SetDeleteValue('ObjectInspectorOptions/Bounds/DefaultItemHeight', + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + ConfigStore.SetDeleteValue( + Path+'Bounds/'+DefaultOIPageNames[Page]+'/SplitterX', + FGridSplitterX[Page],110); + ConfigStore.SetDeleteValue(Path+'Bounds/DefaultItemHeight', FDefaultItemHeight,20); - ConfigStore.SetDeleteValue('ObjectInspectorOptions/ComponentTree/Show/Value', + ConfigStore.SetDeleteValue(Path+'ComponentTree/Show/Value', FShowComponentTree,true); - ConfigStore.SetDeleteValue('ObjectInspectorOptions/ComponentTree/Height/Value', + ConfigStore.SetDeleteValue(Path+'ComponentTree/Height/Value', FComponentTreeHeight,100); - ConfigStore.SetDeleteValue('ObjectInspectorOptions/GridBackgroundColor', + ConfigStore.SetDeleteValue(Path+'GridBackgroundColor', FGridBackgroundColor,clBackground); - ConfigStore.SetDeleteValue('ObjectInspectorOptions/ShowHints',FShowHints, + ConfigStore.SetDeleteValue(Path+'ShowHints',FShowHints, false); except on E: Exception do begin @@ -2328,13 +2476,16 @@ begin end; procedure TOIOptions.Assign(AnObjInspector: TObjectInspector); +var + Page: TObjectInspectorPage; begin FLeft:=AnObjInspector.Left; FTop:=AnObjInspector.Top; FWidth:=AnObjInspector.Width; FHeight:=AnObjInspector.Height; - FPropertyGridSplitterX:=AnObjInspector.PropertyGrid.PrefferedSplitterX; - FEventGridSplitterX:=AnObjInspector.EventGrid.PrefferedSplitterX; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + if AnObjInspector.GridControl[Page]<>nil then + FGridSplitterX[Page]:=AnObjInspector.GridControl[Page].PrefferedSplitterX; FDefaultItemHeight:=AnObjInspector.DefaultItemHeight; FShowComponentTree:=AnObjInspector.ShowComponentTree; FComponentTreeHeight:=AnObjInspector.ComponentTreeHeight; @@ -2343,21 +2494,24 @@ begin end; procedure TOIOptions.AssignTo(AnObjInspector: TObjectInspector); +var + Page: TObjectInspectorPage; + Grid: TOICustomPropertyGrid; begin if FSaveBounds then begin AnObjInspector.SetBounds(FLeft,FTop,FWidth,FHeight); end; - AnObjInspector.PropertyGrid.PrefferedSplitterX:=FPropertyGridSplitterX; - AnObjInspector.PropertyGrid.SplitterX:=FPropertyGridSplitterX; - AnObjInspector.EventGrid.PrefferedSplitterX:=FEventGridSplitterX; - AnObjInspector.EventGrid.SplitterX:=FEventGridSplitterX; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do begin + Grid:=AnObjInspector.GridControl[Page]; + if Grid=nil then continue; + Grid.PrefferedSplitterX:=FGridSplitterX[Page]; + Grid.SplitterX:=FGridSplitterX[Page]; + Grid.BackgroundColor:=FGridBackgroundColor; + Grid.ShowHint:=FShowHints; + end; AnObjInspector.DefaultItemHeight:=FDefaultItemHeight; AnObjInspector.ShowComponentTree:=FShowComponentTree; AnObjInspector.ComponentTreeHeight:=FComponentTreeHeight; - AnObjInspector.PropertyGrid.BackgroundColor:=FGridBackgroundColor; - AnObjInspector.PropertyGrid.ShowHint:=FShowHints; - AnObjInspector.EventGrid.BackgroundColor:=FGridBackgroundColor; - AnObjInspector.EventGrid.ShowHint:=FShowHints; end; @@ -2414,6 +2568,7 @@ begin FComponentTreeHeight:=100; FShowComponentTree:=true; FUsePairSplitter:=TPairSplitter.IsSupportedByInterface; + FShowFavouritePage:=false; Caption := oisObjectInspector; Name := DefaultObjectInspectorName; @@ -2436,8 +2591,15 @@ begin AutoPopup:=true; end; AddPopupMenuItem(SetDefaultPopupmenuItem,nil,'SetDefaultPopupMenuItem', - 'Set to Default Value','Set property value to Default', + 'Set to Default value','Set property value to Default', @OnSetDefaultPopupmenuItemClick,false,true,true); + AddPopupMenuItem(AddToFavouritesPopupMenuItem,nil,'AddToFavouritePopupMenuItem', + 'Add to favourites','Add property to favourites properties', + @OnAddToFavouritesPopupmenuItemClick,false,true,true); + AddPopupMenuItem(RemoveFromFavouritesPopupMenuItem,nil, + 'RemoveFromFavouritesPopupMenuItem', + 'Remove from favourites','Remove property from favourites properties', + @OnRemoveFromFavouritesPopupmenuItemClick,false,true,true); AddPopupMenuItem(UndoPropertyPopupMenuItem,nil,'UndoPropertyPopupMenuItem', 'Undo','Set property value to last valid value', @OnUndoPopupmenuItemClick,false,true,true); @@ -2502,9 +2664,12 @@ destructor TObjectInspector.Destroy; begin FreeAndNil(FSelection); inherited Destroy; + FreeAndNil(FFavourites); end; procedure TObjectInspector.SetPropertyEditorHook(NewValue:TPropertyEditorHook); +var + Page: TObjectInspectorPage; begin if FPropertyEditorHook=NewValue then exit; if FPropertyEditorHook<>nil then begin @@ -2523,8 +2688,9 @@ begin and (FPropertyEditorHook.LookupRoot is TComponent) then FSelection.Add(TComponent(FPropertyEditorHook.LookupRoot)); FillPersistentComboBox; - PropertyGrid.PropertyEditorHook:=FPropertyEditorHook; - EventGrid.PropertyEditorHook:=FPropertyEditorHook; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + if GridControl[Page]<>nil then + GridControl[Page].PropertyEditorHook:=FPropertyEditorHook; ComponentTree.PropertyEditorHook:=FPropertyEditorHook; RefreshSelection; end; @@ -2547,6 +2713,7 @@ end; procedure TObjectInspector.SetDefaultItemHeight(const AValue: integer); var NewValue: Integer; + Page: TObjectInspectorPage; begin NewValue:=AValue; if NewValue<0 then @@ -2558,8 +2725,9 @@ begin else if NewValue>100 then NewValue:=100; if FDefaultItemHeight=NewValue then exit; FDefaultItemHeight:=NewValue; - PropertyGrid.DefaultItemHeight:=FDefaultItemHeight; - EventGrid.DefaultItemHeight:=FDefaultItemHeight; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + if GridControl[Page]<>nil then + GridControl[Page].DefaultItemHeight:=FDefaultItemHeight; RebuildPropertyLists; end; @@ -2585,9 +2753,12 @@ begin end; procedure TObjectInspector.HookLookupRootChange; +var + Page: TObjectInspectorPage; begin - PropertyGrid.PropEditLookupRootChange; - EventGrid.PropEditLookupRootChange; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + if GridControl[Page]<>nil then + GridControl[Page].PropEditLookupRootChange; FillPersistentComboBox; end; @@ -2658,10 +2829,11 @@ function TObjectInspector.GetActivePropertyGrid: TOICustomPropertyGrid; begin Result:=nil; if NoteBook=nil then exit; - if NoteBook.PageIndex=0 then - Result:=PropertyGrid - else if NoteBook.PageIndex=1 then - Result:=EventGrid; + case NoteBook.PageIndex of + 0: Result:=PropertyGrid; + 1: Result:=EventGrid; + 2: Result:=FavouriteGrid; + end; end; function TObjectInspector.GetActivePropertyRow: TOIPropertyGridRow; @@ -2705,9 +2877,12 @@ begin end; procedure TObjectInspector.RefreshSelection; +var + Page: TObjectInspectorPage; begin - PropertyGrid.Selection := FSelection; - EventGrid.Selection := FSelection; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + if GridControl[Page]<>nil then + GridControl[Page].Selection := FSelection; ComponentTree.Selection := FSelection; ComponentTree.MakeSelectionVisible; if (not Visible) and (FSelection.Count>0) then @@ -2715,19 +2890,25 @@ begin end; procedure TObjectInspector.RefreshPropertyValues; +var + Page: TObjectInspectorPage; begin - PropertyGrid.RefreshPropertyValues; - EventGrid.RefreshPropertyValues; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + if GridControl[Page]<>nil then + GridControl[Page].RefreshPropertyValues; end; procedure TObjectInspector.RebuildPropertyLists; +var + Page: TObjectInspectorPage; begin if FUpdateLock>0 then Include(FFLags,oifRebuildPropListsNeeded) else begin Exclude(FFLags,oifRebuildPropListsNeeded); - PropertyGrid.BuildPropertyList; - EventGrid.BuildPropertyList; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + if GridControl[Page]<>nil then + GridControl[Page].BuildPropertyList; end; end; @@ -2805,6 +2986,18 @@ begin RefreshPropertyValues; end; +procedure TObjectInspector.OnAddToFavouritesPopupmenuItemClick(Sender: TObject); +begin + //debugln('TObjectInspector.OnAddToFavouritePopupmenuItemClick'); + if Assigned(OnAddToFavourites) then OnAddToFavourites(Self); +end; + +procedure TObjectInspector.OnRemoveFromFavouritesPopupmenuItemClick( + Sender: TObject); +begin + if Assigned(OnRemoveFromFavourites) then OnRemoveFromFavourites(Self); +end; + procedure TObjectInspector.OnUndoPopupmenuItemClick(Sender: TObject); var CurGrid: TOICustomPropertyGrid; @@ -2817,15 +3010,18 @@ begin end; procedure TObjectInspector.OnBackgroundColPopupMenuItemClick(Sender :TObject); -var ColorDialog:TColorDialog; +var + ColorDialog:TColorDialog; + Page: TObjectInspectorPage; begin ColorDialog:=TColorDialog.Create(nil); try with ColorDialog do begin Color:=PropertyGrid.BackgroundColor; if Execute then begin - PropertyGrid.BackgroundColor:=Color; - EventGrid.BackgroundColor:=Color; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + if GridControl[Page]<>nil then + GridControl[Page].BackgroundColor:=Color; end; end; finally @@ -2925,18 +3121,10 @@ procedure TObjectInspector.DestroyNoteBook; begin if NoteBook<>nil then NoteBook.Visible:=false; - if PropertyGrid<>nil then begin - PropertyGrid.Free; - PropertyGrid:=nil; - end; - if EventGrid<>nil then begin - EventGrid.Free; - EventGrid:=nil; - end; - if NoteBook<>nil then begin - NoteBook.Free; - NoteBook:=nil; - end; + FreeAndNil(PropertyGrid); + FreeAndNil(EventGrid); + FreeAndNil(FavouriteGrid); + FreeAndNil(NoteBook); end; procedure TObjectInspector.CreateNoteBook; @@ -2957,9 +3145,9 @@ begin Pages.Strings[0]:=oisProperties else Pages.Add(oisProperties); - Page[0].Name:='PropertyPage'; + Page[0].Name:=DefaultOIPageNames[oipgpProperties]; Pages.Add(oisEvents); - Page[1].Name:='EventPage'; + Page[1].Name:=DefaultOIPageNames[oipgpEvents]; PageIndex:=0; PopupMenu:=MainPopupMenu; end; @@ -2972,13 +3160,8 @@ begin , tkInt64, tkQWord], FDefaultItemHeight); with PropertyGrid do begin - Name:='PropertyGrid'; + Name:=DefaultOIGridNames[oipgpProperties]; Parent:=NoteBook.Page[0]; -{ - ValueEdit.Parent:=Parent; - ValueComboBox.Parent:=Parent; - ValueButton.Parent:=Parent; -} Selection:=Self.FSelection; Align:=alClient; PopupMenu:=MainPopupMenu; @@ -2990,19 +3173,57 @@ begin EventGrid:=TOICustomPropertyGrid.CreateWithParams(Self,PropertyEditorHook, [tkMethod],FDefaultItemHeight); with EventGrid do begin - Name:='EventGrid'; + Name:=DefaultOIGridNames[oipgpEvents]; Parent:=NoteBook.Page[1]; -{ - ValueEdit.Parent:=Parent; - ValueComboBox.Parent:=Parent; - ValueButton.Parent:=Parent; -} Selection:=Self.FSelection; Align:=alClient; PopupMenu:=MainPopupMenu; OnModified:=@OnGridModified; OnKeyUp:=@OnGriddKeyUp; end; + + CreateFavouritePage; +end; + +procedure TObjectInspector.CreateFavouritePage; +var + NewPage: TPage; + i: LongInt; +begin + if FShowFavouritePage then begin + if FavouriteGrid=nil then begin + // create favourite page + NoteBook.Pages.Add(oisFavourites); + NewPage:=NoteBook.Page[NoteBook.PageCount-1]; + NewPage.Name:=DefaultOIPageNames[oipgpFavourite]; + + // create favourite property grid + FavouriteGrid:=TOICustomPropertyGrid.CreateWithParams(Self,PropertyEditorHook + ,[tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkSet, tkMethod + , tkSString, tkLString, tkAString, tkWString, tkVariant + {, tkArray, tkRecord, tkInterface}, tkClass, tkObject, tkWChar, tkBool + , tkInt64, tkQWord], + FDefaultItemHeight); + with FavouriteGrid do begin + Name:=DefaultOIGridNames[oipgpFavourite]; + Parent:=NewPage; + Selection:=Self.FSelection; + Align:=alClient; + PopupMenu:=MainPopupMenu; + OnModified:=@OnGridModified; + OnKeyUp:=@OnGriddKeyUp; + end; + FavouriteGrid.Favourites:=FFavourites; + end; + end else begin + if FavouriteGrid<>nil then begin + // free and remove favourite page + i:=NoteBook.PageList.IndexOf(FavouriteGrid.Parent); + FreeAndNil(FavouriteGrid); + if i>=0 then + NoteBook.Pages.Delete(i); + end; + end; end; procedure TObjectInspector.KeyDown(var Key: Word; Shift: TShiftState); @@ -3025,9 +3246,12 @@ begin end; procedure TObjectInspector.OnShowHintPopupMenuItemClick(Sender : TObject); +var + Page: TObjectInspectorPage; begin - PropertyGrid.ShowHint:=not PropertyGrid.ShowHint; - EventGrid.ShowHint:=not EventGrid.ShowHint; + for Page:=Low(TObjectInspectorPage) to High(TObjectInspectorPage) do + if GridControl[Page]<>nil then + GridControl[Page].ShowHint:=not GridControl[Page].ShowHint; end; procedure TObjectInspector.OnShowOptionsPopupMenuItemClick(Sender: TObject); @@ -3053,6 +3277,13 @@ begin else SetDefaultPopupMenuItem.Caption:=oisSetToDefaultValue; + AddToFavouritesPopupMenuItem.Visible:=(Favourites<>nil) + and (GetActivePropertyGrid<>FavouriteGrid) + and Assigned(OnAddToFavourites) and (GetActivePropertyRow<>nil); + RemoveFromFavouritesPopupMenuItem.Visible:=(Favourites<>nil) + and (GetActivePropertyGrid=FavouriteGrid) + and Assigned(OnRemoveFromFavourites) and (GetActivePropertyRow<>nil); + CurGrid:=GetActivePropertyGrid; CurRow:=GetActivePropertyRow; if (CurRow<>nil) and (CurRow.Editor.GetVisualValue<>CurGrid.CurrentEditValue) @@ -3068,6 +3299,32 @@ begin RefreshPropertyValues; end; +procedure TObjectInspector.SetShowFavouritePage(const AValue: boolean); +begin + if FShowFavouritePage=AValue then exit; + FShowFavouritePage:=AValue; + CreateFavouritePage; +end; + +function TObjectInspector.GetGridControl(Page: TObjectInspectorPage + ): TOICustomPropertyGrid; +begin + case Page of + oipgpFavourite: Result:=FavouriteGrid; + oipgpEvents: Result:=EventGrid; + else Result:=PropertyGrid; + end; +end; + +procedure TObjectInspector.SetFavourites(const AValue: TOIFavouriteProperties); +begin + //debugln('TObjectInspector.SetFavourites ',dbgsName(Self)); + if FFavourites=AValue then exit; + FFavourites:=AValue; + if FavouriteGrid<>nil then + FavouriteGrid.Favourites:=FFavourites; +end; + { TCustomPropertiesGrid } function TCustomPropertiesGrid.GetTIObject: TPersistent; @@ -3125,5 +3382,177 @@ begin inherited Destroy; end; +{ TOIFavouriteProperties } + +function TOIFavouriteProperties.GetItems(Index: integer): TOIFavouriteProperty; +begin + Result:=TOIFavouriteProperty(FItems[Index]); +end; + +constructor TOIFavouriteProperties.Create; +begin + FItems:=TList.Create; +end; + +destructor TOIFavouriteProperties.Destroy; +begin + Clear; + FreeAndNil(FItems); + inherited Destroy; +end; + +procedure TOIFavouriteProperties.Clear; +var + i: Integer; +begin + for i:=0 to FItems.Count-1 do + TObject(FItems[i]).Free; + FItems.Clear; +end; + +procedure TOIFavouriteProperties.Add(NewItem: TOIFavouriteProperty); +begin + FItems.Add(NewItem); + FCount:=FItems.Count; +end; + +procedure TOIFavouriteProperties.Remove(AnItem: TOIFavouriteProperty); +begin + FItems.Remove(AnItem); + FCount:=FItems.Count; +end; + +procedure TOIFavouriteProperties.DeleteConstraints( + AnItem: TOIFavouriteProperty); +// delete all items, that would constrain AnItem +var + i: Integer; + CurItem: TOIFavouriteProperty; +begin + for i:=Count-1 downto 0 do begin + CurItem:=Items[i]; + if CurItem.Constrains(AnItem) then begin + FItems.Delete(i); + CurItem.Free; + end; + end; +end; + +function TOIFavouriteProperties.IsFavourite(AClass: TPersistentClass; + const PropertyName: string): boolean; +var + i: Integer; + CurItem: TOIFavouriteProperty; + BestItem: TOIFavouriteProperty; +begin + if (AClass=nil) or (PropertyName='') then begin + Result:=false; + exit; + end; + BestItem:=nil; + for i:=0 to FCount-1 do begin + CurItem:=Items[i]; + if not CurItem.IsFavourite(AClass,PropertyName) then continue; + if (BestItem=nil) + or (AClass.InheritsFrom(BestItem.BaseClass)) then begin + //debugln('TOIFavouriteProperties.IsFavourite ',AClass.ClassName,' ',PropertyName); + BestItem:=CurItem; + end; + end; + Result:=(BestItem<>nil) and BestItem.Include; +end; + +function TOIFavouriteProperties.AreFavourites( + Selection: TPersistentSelectionList; const PropertyName: string): boolean; +var + i: Integer; +begin + Result:=(Selection<>nil) and (Selection.Count>0); + if not Result then exit; + for i:=0 to Selection.Count-1 do begin + if not IsFavourite(TPersistentClass(Selection[i].ClassType),PropertyName) + then begin + Result:=false; + exit; + end; + end; +end; + +procedure TOIFavouriteProperties.LoadFromConfig(ConfigStore: TConfigStorage; + const Path: string); +var + NewCount: LongInt; + i: Integer; + NewItem: TOIFavouriteProperty; + p: String; + NewPropertyName: String; + NewInclude: Boolean; + NewBaseClassname: String; + NewBaseClass: TPersistentClass; +begin + Clear; + NewCount:=ConfigStore.GetValue(Path+'Count',0); + for i:=0 to NewCount-1 do begin + p:=Path+'Item'+IntToStr(i)+'/'; + NewPropertyName:=ConfigStore.GetValue(p+'PropertyName',''); + if (NewPropertyName='') or (not IsValidIdent(NewPropertyName)) then + continue; + NewInclude:=ConfigStore.GetValue(p+'Include',true); + NewBaseClassname:=ConfigStore.GetValue(p+'BaseClass',''); + if (NewBaseClassname='') or (not IsValidIdent(NewBaseClassname)) then + continue; + NewBaseClass:=GetClass(NewBaseClassname); + NewItem:=TOIFavouriteProperty.Create(NewBaseClass,NewPropertyName, + NewInclude); + NewItem.BaseClassName:=NewBaseClassname; + Add(NewItem); + end; +end; + +procedure TOIFavouriteProperties.SaveToConfig(ConfigStore: TConfigStorage; + const Path: string); +var + i: Integer; + p: String; + CurItem: TOIFavouriteProperty; +begin + ConfigStore.SetDeleteValue(Path+'Count',Count,0); + for i:=0 to Count-1 do begin + CurItem:=Items[i]; + p:=Path+'Item'+IntToStr(i)+'/'; + ConfigStore.SetDeleteValue(p+'BaseClass',CurItem.BaseClass.ClassName,''); + ConfigStore.SetDeleteValue(p+'PropertyName',CurItem.PropertyName,''); + ConfigStore.SetDeleteValue(p+'Include',CurItem.Include,true); + end; +end; + +{ TOIFavouriteProperty } + +constructor TOIFavouriteProperty.Create(ABaseClass: TPersistentClass; + const APropertyName: string; TheInclude: boolean); +begin + BaseClass:=ABaseClass; + PropertyName:=APropertyName; + Include:=TheInclude; +end; + +function TOIFavouriteProperty.Constrains(AnItem: TOIFavouriteProperty + ): boolean; +// true if this item constrains AnItem +// This item constrains AnItem, if this is the opposite (Include) and +// AnItem has the same or greater scope +begin + Result:=(Include<>AnItem.Include) + and (CompareText(PropertyName,AnItem.PropertyName)=0) + and (BaseClass.InheritsFrom(AnItem.BaseClass)); +end; + +function TOIFavouriteProperty.IsFavourite(AClass: TPersistentClass; + const APropertyName: string): boolean; +begin + Result:=(CompareText(PropertyName,APropertyName)=0) + and (AClass.InheritsFrom(BaseClass)); +end; + end. diff --git a/ideintf/objinspstrconsts.pas b/ideintf/objinspstrconsts.pas index c01d4d61f5..6830ebb032 100644 --- a/ideintf/objinspstrconsts.pas +++ b/ideintf/objinspstrconsts.pas @@ -43,6 +43,7 @@ resourcestring oisProperties='Properties'; oisEvents='Events'; + oisFavourites = 'Favourites'; oisSetToDefault = 'Set to default: %s'; oisSetToDefaultValue = 'Set to default value';