diff --git a/components/ideintf/componentreg.pas b/components/ideintf/componentreg.pas index a8d86b7983..37db8bf5ac 100644 --- a/components/ideintf/componentreg.pas +++ b/components/ideintf/componentreg.pas @@ -24,7 +24,7 @@ interface uses Classes, SysUtils, typinfo, Controls, ComCtrls, Forms, - LazarusPackageIntf, LazConfigStorage, LCLProc; + LazarusPackageIntf, LazConfigStorage, LCLProc, fgl; type TComponentPriorityCategory = ( @@ -92,7 +92,6 @@ type FVisible: boolean; protected procedure SetVisible(const AValue: boolean); virtual; - procedure FreeButton; public constructor Create(TheComponentClass: TComponentClass; const ThePageName: string); destructor Destroy; override; @@ -119,33 +118,23 @@ type TBaseComponentPage = class private - FComps: TList; // list of TRegisteredComponent FPageComponent: TCustomPage; FPageName: string; FPalette: TBaseComponentPalette; FPriority: TComponentPriority; FSelectButton: TComponent; FVisible: boolean; - function GetItems(Index: integer): TRegisteredComponent; protected procedure SetVisible(const AValue: boolean); virtual; procedure OnComponentVisibleChanged(AComponent: TRegisteredComponent); virtual; public constructor Create(const ThePageName: string); destructor Destroy; override; - procedure Clear; - procedure ClearButtons; - procedure ConsistencyCheck; - function Count: integer; - procedure Add(NewComponent: TRegisteredComponent); - procedure Remove(AComponent: TRegisteredComponent); function FindComponent(const CompClassName: string): TRegisteredComponent; function FindButton(Button: TComponent): TRegisteredComponent; procedure UpdateVisible; - function GetMaxComponentPriority: TComponentPriority; function GetScrollBox: TScrollBox; public - property Comps[Index: integer]: TRegisteredComponent read GetItems; default; property PageName: string read FPageName; property Palette: TBaseComponentPalette read FPalette; property Priority: TComponentPriority read FPriority write FPriority; @@ -170,10 +159,12 @@ type TComponentAddedEvent = procedure of object; RegisterUnitComponentProc = procedure(const Page, UnitName: ShortString; ComponentClass: TComponentClass); + TPagePriorityList = specialize TFPGMap; TBaseComponentPalette = class private FPages: TList; // list of TBaseComponentPage + FComps: TList; // list of all TRegisteredComponent in all pages FHandlers: array[TComponentPaletteHandlerType] of TMethodList; FBaseComponentPageClass: TBaseComponentPageClass; FRegisteredComponentClass: TRegisteredComponentClass; @@ -183,13 +174,15 @@ type FUpdateLock: integer; fChanged: boolean; function GetPages(Index: integer): TBaseComponentPage; + function GetComps(Index: integer): TRegisteredComponent; procedure AddHandler(HandlerType: TComponentPaletteHandlerType; const AMethod: TMethod; AsLast: boolean = false); procedure RemoveHandler(HandlerType: TComponentPaletteHandlerType; const AMethod: TMethod); procedure SetHideControls(const AValue: boolean); protected - fPagesDefaultOrder: TList; // Pages list ordered by package priorities + // New pages added and their priorities, ordered by priority. + fOrigPagePriorities: TPagePriorityList; // Pages ordered by user. Contains page name + another StringList // for component names, just like TCompPaletteOptions.ComponentPages. fPagesUserOrder: TStringList; @@ -202,29 +195,29 @@ type procedure OnComponentVisibleChanged({%H-}AComponent: TRegisteredComponent); virtual; procedure OnPageVisibleChanged({%H-}APage: TBaseComponentPage); virtual; procedure Update; virtual; - procedure UpdateVisible(AComponent: TRegisteredComponent); virtual; + function UpdateVisible(AComponent: TRegisteredComponent): Boolean; virtual; function GetSelected: TRegisteredComponent; virtual; procedure SetBaseComponentPageClass(const AValue: TBaseComponentPageClass); virtual; procedure SetRegisteredComponentClass(const AValue: TRegisteredComponentClass); virtual; procedure SetSelected(const AValue: TRegisteredComponent); virtual; abstract; - function SortPagesDefaultOrder: Boolean; public constructor Create; destructor Destroy; override; procedure Clear; - procedure ClearButtons; virtual; + procedure ClearButtons; virtual; abstract; procedure BeginUpdate(Change: boolean); procedure EndUpdate; function IsUpdateLocked: boolean; procedure DoAfterComponentAdded; virtual; - procedure ConsistencyCheck; - function Count: integer; + function PageCount: integer; function GetPage(const APageName: string; aCaseSens: Boolean = False): TBaseComponentPage; function IndexOfPageName(const APageName: string): integer; function IndexOfPageWithName(const APageName: string): integer; + function CompCount: integer; procedure AddComponent(NewComponent: TRegisteredComponent); function CreateNewPage(const NewPageName: string; const Priority: TComponentPriority): TBaseComponentPage; + procedure RemoveComponent(AComponent: TRegisteredComponent); function FindComponent(const CompClassName: string): TRegisteredComponent; virtual; function FindButton(Button: TComponent): TRegisteredComponent; function CreateNewClassName(const Prefix: string): string; @@ -245,18 +238,15 @@ type const OnComponentAddedEvent: TComponentAddedEvent); public property Pages[Index: integer]: TBaseComponentPage read GetPages; default; - property BaseComponentPageClass: TBaseComponentPageClass - read FBaseComponentPageClass; + property Comps[Index: integer]: TRegisteredComponent read GetComps; + property BaseComponentPageClass: TBaseComponentPageClass read FBaseComponentPageClass; property RegisteredComponentClass: TRegisteredComponentClass read FRegisteredComponentClass; property UpdateLock: integer read FUpdateLock; - property OnBeginUpdate: TNotifyEvent read FOnBeginUpdate - write FOnBeginUpdate; - property OnEndUpdate: TEndUpdatePaletteEvent read FOnEndUpdate - write FOnEndUpdate; + property OnBeginUpdate: TNotifyEvent read FOnBeginUpdate write FOnBeginUpdate; + property OnEndUpdate: TEndUpdatePaletteEvent read FOnEndUpdate write FOnEndUpdate; property HideControls: boolean read FHideControls write SetHideControls; property Selected: TRegisteredComponent read GetSelected write SetSelected; - property PagesDefaultOrder: TList read fPagesDefaultOrder; property PagesUserOrder: TStringList read fPagesUserOrder; end; @@ -454,12 +444,6 @@ begin FRealPage.OnComponentVisibleChanged(Self); end; -procedure TRegisteredComponent.FreeButton; -begin - FButton.Free; - FButton:=nil; -end; - constructor TRegisteredComponent.Create(TheComponentClass: TComponentClass; const ThePageName: string); begin @@ -470,9 +454,9 @@ end; destructor TRegisteredComponent.Destroy; begin - if FRealPage<>nil then - FRealPage.Remove(Self); - FreeButton; + if Assigned(FRealPage) and Assigned(FRealPage.Palette) then + FRealPage.Palette.RemoveComponent(Self); + FreeAndNil(FButton); inherited Destroy; end; @@ -513,11 +497,6 @@ end; { TBaseComponentPage } -function TBaseComponentPage.GetItems(Index: integer): TRegisteredComponent; -begin - Result:=TRegisteredComponent(FComps[Index]); -end; - procedure TBaseComponentPage.SetVisible(const AValue: boolean); begin if FVisible=AValue then exit; @@ -535,80 +514,24 @@ end; constructor TBaseComponentPage.Create(const ThePageName: string); begin FPageName:=ThePageName; - FComps:=TList.Create; FVisible:=FPageName<>''; end; destructor TBaseComponentPage.Destroy; begin - Clear; FreeAndNil(FPageComponent); FreeAndNil(FSelectButton); - FreeAndNil(FComps); inherited Destroy; end; -procedure TBaseComponentPage.Clear; -var - i: Integer; -begin - ClearButtons; - for i:=0 to FComps.Count-1 do - Comps[i].RealPage:=nil; - FComps.Clear; -end; - -procedure TBaseComponentPage.ClearButtons; -var - i, Cnt: Integer; -begin - Cnt:=Count; - for i:=0 to Cnt-1 do - Comps[i].FreeButton; - FreeAndNil(FSelectButton); -end; - -procedure TBaseComponentPage.ConsistencyCheck; -begin - -end; - -function TBaseComponentPage.Count: integer; -begin - Result:=FComps.Count; -end; - -procedure TBaseComponentPage.Add(NewComponent: TRegisteredComponent); -var - InsertIndex: Integer; - NewPriority: TComponentPriority; -begin - NewPriority:=NewComponent.GetPriority; - InsertIndex:=0; - while (InsertIndexnil then - FPalette.OnPageAddedComponent(NewComponent); -end; - -procedure TBaseComponentPage.Remove(AComponent: TRegisteredComponent); -begin - FComps.Remove(AComponent); - AComponent.RealPage:=nil; - if FPalette<>nil then - FPalette.OnPageRemovedComponent(Self,AComponent); -end; - function TBaseComponentPage.FindComponent(const CompClassName: string): TRegisteredComponent; var i: Integer; begin - for i:=0 to Count-1 do begin - Result:=Comps[i]; - if CompareText(Result.ComponentClass.ClassName,CompClassName)=0 then + for i:=0 to Palette.CompCount-1 do begin + Result:=Palette.Comps[i]; + if (Result.RealPage = Self) + and (CompareText(Result.ComponentClass.ClassName,CompClassName) = 0) then exit; end; Result:=nil; @@ -618,8 +541,8 @@ function TBaseComponentPage.FindButton(Button: TComponent): TRegisteredComponent var i: Integer; begin - for i:=0 to Count-1 do begin - Result:=Comps[i]; + for i:=0 to Palette.CompCount-1 do begin + Result:=Palette.Comps[i]; if Result.Button=Button then exit; end; Result:=nil; @@ -630,28 +553,13 @@ var i: Integer; HasVisibleComponents: Boolean; begin - if Palette<>nil then begin - HasVisibleComponents:=false; - for i:=0 to Count-1 do begin - Palette.UpdateVisible(Comps[i]); - if Comps[i].Visible then HasVisibleComponents:=true; - end; - Visible:=HasVisibleComponents and (PageName<>''); - end; -end; - -function TBaseComponentPage.GetMaxComponentPriority: TComponentPriority; -var - i: Integer; -begin - if Count=0 then - Result:=ComponentPriorityNormal - else begin - Result:=Comps[0].GetPriority; - for i:=1 to Count-1 do - if ComparePriority(Comps[i].GetPriority,Result)>0 then - Result:=Comps[i].GetPriority; - end; + if Palette = nil then Exit; + HasVisibleComponents:=false; + for i:=0 to Palette.CompCount-1 do + if (Palette.Comps[i].RealPage = Self) then + if Palette.UpdateVisible(Palette.Comps[i]) then + HasVisibleComponents:=true; + Visible:=HasVisibleComponents and (PageName<>''); end; function TBaseComponentPage.GetScrollBox: TScrollBox; @@ -670,6 +578,11 @@ begin Result:=TBaseComponentPage(FPages[Index]); end; +function TBaseComponentPalette.GetComps(Index: integer): TRegisteredComponent; +begin + Result:=TRegisteredComponent(FComps[Index]) +end; + procedure TBaseComponentPalette.AddHandler(HandlerType: TComponentPaletteHandlerType; const AMethod: TMethod; AsLast: boolean); begin @@ -719,8 +632,8 @@ begin DoChange; end; -procedure TBaseComponentPalette.OnPageRemovedComponent( - Page: TBaseComponentPage; Component: TRegisteredComponent); +procedure TBaseComponentPalette.OnPageRemovedComponent(Page: TBaseComponentPage; + Component: TRegisteredComponent); begin DoChange; end; @@ -740,7 +653,7 @@ begin end; -procedure TBaseComponentPalette.UpdateVisible(AComponent: TRegisteredComponent); +function TBaseComponentPalette.UpdateVisible(AComponent: TRegisteredComponent): Boolean; var i, Vote: Integer; begin @@ -750,7 +663,8 @@ begin i:=FHandlers[cphtUpdateVisible].Count; while FHandlers[cphtUpdateVisible].NextDownIndex(i) do TUpdateCompVisibleEvent(FHandlers[cphtUpdateVisible][i])(AComponent,Vote); - AComponent.Visible:=Vote>0; + Result:=Vote>0; + AComponent.Visible:=Result; end; procedure TBaseComponentPalette.SetBaseComponentPageClass( @@ -768,7 +682,8 @@ end; constructor TBaseComponentPalette.Create; begin FPages:=TList.Create; - fPagesDefaultOrder:=TList.Create; + FComps:=TList.Create; + fOrigPagePriorities:=TPagePriorityList.Create; fPagesUserOrder:=TStringList.Create; end; @@ -781,7 +696,8 @@ begin for i := 0 to fPagesUserOrder.Count-1 do fPagesUserOrder.Objects[i].Free; // Free also contained StringLists. FreeAndNil(fPagesUserOrder); - FreeAndNil(fPagesDefaultOrder); + FreeAndNil(fOrigPagePriorities); + FreeAndNil(FComps); FreeAndNil(FPages); for HandlerType:=Low(HandlerType) to High(HandlerType) do FHandlers[HandlerType].Free; @@ -792,21 +708,15 @@ procedure TBaseComponentPalette.Clear; var i: Integer; begin + ClearButtons; + for i:=0 to FComps.Count-1 do + Comps[i].RealPage:=nil; + FComps.Clear; for i:=0 to FPages.Count-1 do Pages[i].Free; FPages.Clear; end; -procedure TBaseComponentPalette.ClearButtons; -var - Cnt: Integer; - i: Integer; -begin - Cnt:=Count; - for i:=0 to Cnt-1 do - Pages[i].ClearButtons; -end; - procedure TBaseComponentPalette.BeginUpdate(Change: boolean); begin inc(FUpdateLock); @@ -839,12 +749,7 @@ begin TComponentAddedEvent(FHandlers[cphtComponentAdded][i])(); end; -procedure TBaseComponentPalette.ConsistencyCheck; -begin - -end; - -function TBaseComponentPalette.Count: integer; +function TBaseComponentPalette.PageCount: integer; begin Result:=FPages.Count; end; @@ -866,26 +771,46 @@ end; function TBaseComponentPalette.IndexOfPageName(const APageName: string): integer; begin - Result:=Count-1; // Case sensitive search + Result:=PageCount-1; // Case sensitive search while (Result>=0) and (Pages[Result].PageName <> APageName) do dec(Result); end; function TBaseComponentPalette.IndexOfPageWithName(const APageName: string): integer; begin - Result:=Count-1; // Case in-sensitive search + Result:=PageCount-1; // Case in-sensitive search while (Result>=0) and (AnsiCompareText(Pages[Result].PageName,APageName)<>0) do dec(Result); end; +function TBaseComponentPalette.CompCount: integer; +begin + Result:=FComps.Count; +end; + procedure TBaseComponentPalette.AddComponent(NewComponent: TRegisteredComponent); var - CurPage: TBaseComponentPage; + NewPriority: TComponentPriority; + InsertIndex: Integer; begin - CurPage:=GetPage(NewComponent.OrigPageName); - if CurPage=nil then - CurPage:=CreateNewPage(NewComponent.OrigPageName,NewComponent.GetPriority); - CurPage.Add(NewComponent); + // Store components to FComps, sorting them by priority. + NewPriority:=NewComponent.GetPriority; + InsertIndex:=0; + while (InsertIndex '') + and (fOrigPagePriorities.IndexOf(NewComponent.OrigPageName) = -1) then begin + InsertIndex:=0; + while (InsertIndexnil then exit; end; @@ -920,7 +852,7 @@ function TBaseComponentPalette.FindButton(Button: TComponent): TRegisteredCompon var i: Integer; begin - for i:=0 to Count-1 do begin + for i:=0 to PageCount-1 do begin Result:=Pages[i].FindButton(Button); if Result<>nil then exit; end; @@ -945,58 +877,29 @@ end; function TBaseComponentPalette.IndexOfPageComponent(AComponent: TComponent): integer; begin if AComponent<>nil then begin - Result:=Count-1; + Result:=PageCount-1; while (Result>=0) and (Pages[Result].PageComponent<>AComponent) do dec(Result); end else Result:=-1; end; -function TBaseComponentPalette.SortPagesDefaultOrder: Boolean; -// Calculate default page order by using component priorities (without user config). -// Note: components inside a page already have right default order after they are added. -var - Pg: TBaseComponentPage; - CurPrio, ListPrio: TComponentPriority; - i, PageCnt: Integer; -begin - Result := True; - fPagesDefaultOrder.Clear; - for PageCnt:=0 to Count-1 do - begin - Pg := Pages[PageCnt]; - if Pg.PageName = '' then Continue; - i := fPagesDefaultOrder.Count-1; - while (i >= 0) do begin - CurPrio := Pg.GetMaxComponentPriority; - ListPrio := TBaseComponentPage(fPagesDefaultOrder[i]).GetMaxComponentPriority; - if ComparePriority(CurPrio, ListPrio) <= 0 then Break; - dec(i); - end; - fPagesDefaultOrder.Insert(i+1, Pg); - end; -end; - procedure TBaseComponentPalette.UpdateVisible; var i: Integer; begin BeginUpdate(false); - for i:=0 to Count-1 do + for i:=0 to PageCount-1 do Pages[i].UpdateVisible; EndUpdate; end; procedure TBaseComponentPalette.IterateRegisteredClasses(Proc: TGetComponentClassEvent); var - i, j: Integer; - APage: TBaseComponentPage; + i: Integer; begin - for i:=0 to Count-1 do begin - APage:=Pages[i]; - for j:=0 to APage.Count-1 do - Proc(APage[j].ComponentClass); - end; + for i:=0 to CompCount-1 do + Proc(Comps[i].ComponentClass); end; procedure TBaseComponentPalette.RemoveAllHandlersOfObject(AnObject: TObject); diff --git a/ide/componentlist.pas b/ide/componentlist.pas index 530eb59354..926e31c762 100644 --- a/ide/componentlist.pas +++ b/ide/componentlist.pas @@ -191,14 +191,16 @@ var begin if Assigned(IDEComponentPalette) then begin - for i := 0 to IDEComponentPalette.Count-1 do + for i := 0 to IDEComponentPalette.PageCount-1 do begin APage := IDEComponentPalette.Pages[i]; if APage.Visible then - for j := 0 to APage.Count-1 do + for j := 0 to IDEComponentPalette.CompCount-1 do begin - AComponent := APage.Comps[j]; - if AComponent.Visible and (AComponent.OrigPageName<>'') then + AComponent := IDEComponentPalette.Comps[j]; + if (AComponent.RealPage = APage) + and AComponent.Visible + and (AComponent.OrigPageName <> '') then FComponentList.Add(AComponent); end; end; diff --git a/ide/componentpalette.pas b/ide/componentpalette.pas index 74090e2946..a37886caa1 100644 --- a/ide/componentpalette.pas +++ b/ide/componentpalette.pas @@ -354,7 +354,7 @@ var CurPage: TBaseComponentPage; SelectButtonOnPage: TSpeedButton; begin - for i:=0 to Count-1 do begin + for i:=0 to PageCount-1 do begin CurPage:=Pages[i]; if (FSelected=nil) or (FSelected.RealPage<>CurPage) then begin SelectButtonOnPage:=TSpeedButton(CurPage.SelectButton); @@ -511,7 +511,7 @@ begin Selected := nil; end; -function TComponentPalette.GetUnregisteredIcon: TCustomBitMap; +function TComponentPalette.GetUnregisteredIcon: TCustomBitmap; begin if fUnregisteredIcon = nil then begin @@ -539,7 +539,7 @@ begin PopupMenu:=nil; OpenPackageMenuItem:=nil; end; - inherited ClearButtons; + //inherited ClearButtons; if FPageControl<>nil then FPageControl.EnableAlign; end; @@ -641,22 +641,22 @@ begin // First add user defined page order from EnvironmentOptions, fPagesUserOrder.Assign(ComponentPaletteOptions.PageNames); // then add other pages which don't have user configuration - for DefPgInd := 0 to fPagesDefaultOrder.Count-1 do + for DefPgInd := 0 to fOrigPagePriorities.Count-1 do begin - Pg:=TBaseComponentPage(fPagesDefaultOrder[DefPgInd]); - if (fPagesUserOrder.IndexOf(Pg.PageName) = -1) - and (ComponentPaletteOptions.HiddenPageNames.IndexOf(Pg.PageName) = -1) then - fPagesUserOrder.Add(Pg.PageName); + PgName:=fOrigPagePriorities.Keys[DefPgInd]; + if (fPagesUserOrder.IndexOf(PgName) = -1) + and (ComponentPaletteOptions.HiddenPageNames.IndexOf(PgName) = -1) then + fPagesUserOrder.Add(PgName); end; - // Add components for every page + // Add pages and components for them for i := 0 to fPagesUserOrder.Count-1 do begin PgName := fPagesUserOrder[i]; - DefPgInd := IndexOfPageName(PgName); + DefPgInd := IndexOfPageWithName(PgName); if DefPgInd >= 0 then Pg:=Pages[DefPgInd] else begin - // ToDo + Pg:=CreateNewPage(PgName, ComponentPriorityNormal); end; DstComps := TStringList.Create; fPagesUserOrder.Objects[i] := DstComps; @@ -670,14 +670,20 @@ begin begin CompName := DstComps[CompInd]; Comp := FindComponent(CompName); - Comp.RealPage := Pages[DefPgInd]; -// (Comp.Button as TSpeedButton).Parent := Pg.GetScrollBox; + Comp.RealPage := Pg; end; end // Add components that were not reordered. - else - for CompInd := 0 to Pg.Count-1 do - DstComps.Add(Pg[CompInd].ComponentClass.ClassName); + else begin + OptPgInd := CompCount; + for CompInd := 0 to CompCount-1 do begin + Comp := Comps[CompInd]; + if SameText(Comp.OrigPageName, Pg.PageName) then begin + Comp.RealPage:=Pg; + DstComps.Add(Comp.ComponentClass.ClassName); + end; + end; + end; end; end; end; @@ -827,7 +833,6 @@ var end else if aComp.Button<>nil then begin //debugln(['TComponentPalette.UpdateNoteBookButtons Destroy Button: ',aComp.ComponentClass.ClassName,' ',aComp.Button.Name]); - //TControl(aComp.Button).Visible:=false; Not needed! Application.ReleaseComponent(aComp.Button); aComp.Button:=nil; end; @@ -837,15 +842,12 @@ var // Create speedbuttons for every visible component var i, BtnIndex: Integer; - //NoteBookPg: TCustomPage; ScrollBox: TScrollBox; Pg: TBaseComponentPage; Comp: TPkgComponent; begin Pg := Pages[aPageIndex]; if not Pg.Visible then Exit; - //NoteBookPg := Pg.PageComponent; - //Pg.PageComponent.OnResize := @OnPageResize; ScrollBox := Pg.GetScrollBox; ScrollBox.OnResize := @OnScrollBoxResize; Assert(Assigned(ScrollBox), 'CreateButtons: ScrollBox not assigned.'); @@ -879,7 +881,6 @@ begin FPageControl.DisableAlign; try OldActivePage:=FPageControl.ActivePage; - SortPagesDefaultOrder; // Updates fPagesDefaultOrder SortPagesAndCompsUserOrder; // Updates fPagesUserOrder // remove every page in the PageControl without a visible page for i:=FPageControl.PageCount-1 downto 0 do diff --git a/ide/frames/componentpalette_options.pas b/ide/frames/componentpalette_options.pas index a68427d2a4..69530f070d 100644 --- a/ide/frames/componentpalette_options.pas +++ b/ide/frames/componentpalette_options.pas @@ -217,10 +217,11 @@ begin if Assigned(Pg) then // Can be Nil if this page was added or renamed. begin // Collect original components from this page - for CompCnt := 0 to Pg.Count-1 do + for CompCnt := 0 to IDEComponentPalette.PageCount-1 do begin - Comp := Pg.Comps[CompCnt]; - OrigComps.Add(Comp.ComponentClass.ClassName); + Comp := IDEComponentPalette.Comps[CompCnt]; + if Comp.RealPage = Pg then + OrigComps.Add(Comp.ComponentClass.ClassName); end; end; // Differs from original order -> add configuration for components diff --git a/packager/addtopackagedlg.pas b/packager/addtopackagedlg.pas index 841b3886e6..10f829df4a 100644 --- a/packager/addtopackagedlg.pas +++ b/packager/addtopackagedlg.pas @@ -1343,7 +1343,7 @@ var begin // get all current pagenames (excluding the hidden page) sl:=TStringList.Create; - for i:=0 to IDEComponentPalette.Count-1 do begin + for i:=0 to IDEComponentPalette.PageCount-1 do begin APageName:=IDEComponentPalette[i].PageName; if APageName<>'' then sl.Add(APageName);