Packager: use the (still improved) ListFilterEdit in PackageEditor. "Code reuse".

git-svn-id: trunk@31463 -
This commit is contained in:
juha 2011-06-29 22:44:15 +00:00
parent 3b3f7703dd
commit f889b1127c
4 changed files with 383 additions and 343 deletions

View File

@ -33,14 +33,17 @@
</Files>
<LazDoc Paths="docs"/>
<Type Value="RunAndDesignTime"/>
<RequiredPkgs Count="2">
<RequiredPkgs Count="3">
<Item1>
<PackageName Value="LCL"/>
<PackageName Value="CodeTools"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
<Item3>
<PackageName Value="FCL"/>
<MinVersion Major="1" Valid="True"/>
</Item2>
</Item3>
</RequiredPkgs>
<UsageOptions>
<UnitPath Value="$(PkgOutDir)\"/>

View File

@ -5,7 +5,8 @@ unit ListFilterEdit;
interface
uses
Classes, SysUtils, Forms, LResources, Graphics, StdCtrls, ComCtrls, EditBtn;
Classes, SysUtils, Forms, LResources, Graphics, StdCtrls, ComCtrls, EditBtn,
CodeToolsStructs;
resourcestring
lisCEFilter = '(Filter)';
@ -23,10 +24,19 @@ type
procedure OnIdle(Sender: TObject; var Done: Boolean);
private
fFilter: string;
fImageIndexDirectory: integer; // Needed if directory structure is shown.
fNeedUpdate: boolean;
fIdleConnected: boolean;
fSelectedPart: TObject; // Select this node on next update
fSelectionList: TStringList; // or store/restore the old selections here.
fShowDirHierarchy: Boolean;
fSortData: Boolean;
fStoreFilenameInNode: boolean;
fFilenameMap: TStringToStringTree;
fTVNodeStack: TFPList;
// Data to be filtered. Objects property can contain data, too.
fData: TStringList;
fRootNode: TTreeNode; // The filtered items are under this node.
fFilteredTreeview: TTreeview;
fFilteredListbox: TListbox;
fOnGetImageIndex: TImageIndexEvent;
@ -34,8 +44,13 @@ type
procedure SetFilteredTreeview(const AValue: TTreeview);
procedure SetFilteredListbox(const AValue: TListBox);
function PassesFilter(Entry: string): boolean;
procedure ApplyFilterToListBox(AListBox: TListBox);
procedure ApplyFilterToTreeview(ATreeView: TTreeView);
procedure ApplyFilterToListBox;
procedure StoreTreeSelection;
procedure RestoreTreeSelection;
procedure FreeTVNodeData(Node: TTreeNode);
procedure TVDeleteUnneededNodes(p: integer);
procedure TVClearUnneededAndCreateHierachy(Filename: string);
procedure ApplyFilterToTreeview;
procedure SetIdleConnected(const AValue: boolean);
protected
function GetDefaultGlyph: TBitmap; override;
@ -44,12 +59,19 @@ type
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure MapShortToFullFilename(ShortFilename, FullFilename: string);
procedure ApplyFilter(Immediately: Boolean = False);
procedure Invalidate;
public
property Filter: string read fFilter write SetFilter;
property ImageIndexDirectory: integer read fImageIndexDirectory write fImageIndexDirectory;
property IdleConnected: boolean read fIdleConnected write SetIdleConnected;
property SelectedPart: TObject read fSelectedPart write fSelectedPart;
property ShowDirHierarchy: Boolean read fShowDirHierarchy write fShowDirHierarchy;
property SortData: Boolean read fSortData write fSortData;
property StoreFilenameInNode: boolean read fStoreFilenameInNode write fStoreFilenameInNode;
property Data: TStringList read fData;
property RootNode: TTreeNode read fRootNode write fRootNode;
published
// TListFilterEdit properties.
property FilteredTreeview: TTreeview read fFilteredTreeview write SetFilteredTreeview;
@ -86,15 +108,15 @@ type
property TabOrder;
property TabStop;
property Visible;
property OnChange;
// property OnChange;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEditingDone;
property OnEndDrag;
property OnEnter;
property OnExit;
// property OnEnter;
// property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
@ -105,6 +127,14 @@ type
property OnUTF8KeyPress;
end;
{ TFileNameItem }
TFileNameItem = class
public
Filename: string;
constructor Create(AFilename: string);
end;
var
ListFilterGlyph: TBitmap;
@ -121,12 +151,20 @@ begin
RegisterComponents('LazControls',[TListFilterEdit]);
end;
constructor TFileNameItem.Create(AFilename: string);
begin
Filename:=AFilename;
end;
{ TListBoxFilterEdit }
constructor TListFilterEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
fData:=TStringList.Create;
fSelectionList:=TStringList.Create;
fFilenameMap:=TStringToStringTree.Create(True);
Button.Enabled:=False;
Font.Color:=clBtnShadow;
Text:=lisCEFilter;
@ -137,6 +175,9 @@ end;
destructor TListFilterEdit.Destroy;
begin
FreeTVNodeData(fRootNode);
fFilenameMap.Free;
fSelectionList.Free;
fData.Free;
inherited Destroy;
end;
@ -169,16 +210,17 @@ begin
NewValue:=LowerCase(AValue);
if AValue=lisCEFilter then
NewValue:='';
fFilter:=NewValue;
Button.Enabled:=Filter<>'';
if (Filter='') and not Focused then begin
Button.Enabled:=NewValue<>'';
if (NewValue='') and not Focused then begin
Text:=lisCEFilter;
Font.Color:=clBtnShadow;
end
else begin
Text:=Filter;
Text:=NewValue;
Font.Color:=clDefault;
end;
if fFilter=NewValue then exit;
fFilter:=NewValue;
ApplyFilter;
end;
@ -228,39 +270,205 @@ begin
Result:=(Filter='') or (System.Pos(Filter,lowercase(Entry))>0);
end;
procedure TListFilterEdit.ApplyFilterToListBox(AListBox: TListBox);
begin
procedure TListFilterEdit.ApplyFilterToListBox;
begin // use fFilteredListbox
raise Exception.Create('Under construction.');
end;
procedure TListFilterEdit.ApplyFilterToTreeview(ATreeView: TTreeView);
procedure TListFilterEdit.MapShortToFullFilename(ShortFilename, FullFilename: string);
begin
fFilenameMap[ShortFilename]:=FullFilename;
end;
procedure TListFilterEdit.StoreTreeSelection;
var
ANode: TTreeNode;
begin
ANode:=fFilteredTreeview.Selected;
while ANode<>nil do begin
fSelectionList.Insert(0,ANode.Text);
ANode:=ANode.Parent;
end;
end;
procedure TListFilterEdit.RestoreTreeSelection;
var
ANode: TTreeNode;
CurText: string;
begin
ANode:=nil;
while fSelectionList.Count>0 do begin
CurText:=fSelectionList[0];
if ANode=nil then
ANode:=fFilteredTreeview.Items.GetFirstNode
else
ANode:=ANode.GetFirstChild;
while (ANode<>nil) and (ANode.Text<>CurText) do
ANode:=ANode.GetNextSibling;
if ANode=nil then break;
fSelectionList.Delete(0);
end;
if ANode<>nil then
fFilteredTreeview.Selected:=ANode;
fSelectionList.Clear;
end;
procedure TListFilterEdit.FreeTVNodeData(Node: TTreeNode);
var
Child: TTreeNode;
begin
if Node=nil then exit;
if (Node.Data<>nil) then begin
TObject(Node.Data).Free;
Node.Data:=nil;
end;
Child:=Node.GetFirstChild;
while Child<>nil do
begin
FreeTVNodeData(Child);
Child:=Child.GetNextSibling;
end;
end;
procedure TListFilterEdit.TVDeleteUnneededNodes(p: integer);
// delete all nodes behind the nodes in the stack, and depth>=p
var
i: Integer;
Node: TTreeNode;
begin
for i:=fTVNodeStack.Count-1 downto p do begin
Node:=TTreeNode(fTVNodeStack[i]);
while Node.GetNextSibling<>nil do
Node.GetNextSibling.Free;
end;
fTVNodeStack.Count:=p;
end;
procedure TListFilterEdit.TVClearUnneededAndCreateHierachy(Filename: string);
// TVNodeStack contains a path of TTreeNode for the last filename
var
DelimPos: Integer;
FilePart: String;
Node: TTreeNode;
p: Integer;
begin
p:=0;
while Filename<>'' do begin
// get the next file name part
if fShowDirHierarchy then
DelimPos:=System.Pos(PathDelim,Filename)
else
DelimPos:=0;
if DelimPos>0 then begin
FilePart:=copy(Filename,1,DelimPos-1);
Filename:=copy(Filename,DelimPos+1,length(Filename));
end else begin
FilePart:=Filename;
Filename:='';
end;
//debugln(['ClearUnneededAndCreateHierachy FilePart=',FilePart,' Filename=',Filename,' p=',p]);
if p < fTVNodeStack.Count then begin
Node:=TTreeNode(fTVNodeStack[p]);
if (FilePart=Node.Text) and (Node.Data=nil) then begin
// same sub directory
end
else begin
// change directory => last directory is complete
// => delete unneeded nodes after last path
TVDeleteUnneededNodes(p+1);
if Node.GetNextSibling<>nil then begin
Node:=Node.GetNextSibling;
Node.Text:=FilePart;
end
else
Node:=fFilteredTreeview.Items.Add(Node,FilePart);
fTVNodeStack[p]:=Node;
end;
end else begin
// new sub node
if p>0 then
Node:=TTreeNode(fTVNodeStack[p-1])
else
Node:=fRootNode;
if Node.GetFirstChild<>nil then begin
Node:=Node.GetFirstChild;
Node.Text:=FilePart;
end
else
Node:=fFilteredTreeview.Items.AddChild(Node,FilePart);
fTVNodeStack.Add(Node);
end;
if (Filename<>'') then begin
Node.ImageIndex:=fImageIndexDirectory;
Node.SelectedIndex:=Node.ImageIndex;
end;
inc(p);
end;
end;
procedure TListFilterEdit.ApplyFilterToTreeview;
var
TVNode: TTreeNode;
ImgIndex, i: Integer;
s: string;
begin
fNeedUpdate:=false;
ImgIndex:=-1;
fData.Sorted:=True;
ATreeView.BeginUpdate;
ATreeView.Items.Clear;
fData.Sorted:=SortData;
fFilteredTreeview.BeginUpdate;
if fSelectedPart=Nil then
StoreTreeSelection;
if Assigned(fRootNode) then begin
if fStoreFilenameInNode then
FreeTVNodeData(fRootNode);
fRootNode.DeleteChildren;
fTVNodeStack:=TFPList.Create;
end
else
fFilteredTreeview.Items.Clear;
for i:=0 to fData.Count-1 do
if PassesFilter(fData[i]) then begin
TVNode:=ATreeView.Items.Add(nil,fData[i]);
if Assigned(fRootNode) then begin
TVClearUnneededAndCreateHierachy(fData[i]);
TVNode:=TTreeNode(fTVNodeStack[fTVNodeStack.Count-1]);
end
else begin
TVNode:=fFilteredTreeview.Items.Add(nil,fData[i]);
end;
if fStoreFilenameInNode then begin
s:=fData[i];
if fFilenameMap.Contains(fData[i]) then
s:=fFilenameMap[fData[i]]; // Full file name.
TVNode.Data:=TFileNameItem.Create(s);
end;
if Assigned(OnGetImageIndex) then
ImgIndex:=OnGetImageIndex(fData[i], fData.Objects[i]);
TVNode.ImageIndex:=ImgIndex;
TVNode.SelectedIndex:=ImgIndex;
if Assigned(fSelectedPart) then
TVNode.Selected:=fSelectedPart=fData.Objects[i];
end;
ATreeView.EndUpdate;
if Assigned(fRootNode) then begin
TVDeleteUnneededNodes(0);
fTVNodeStack.Free;
fRootNode.Expanded:=True;
end;
if fSelectedPart=Nil then
RestoreTreeSelection;
fFilteredTreeview.EndUpdate;
fData.Sorted:=False;
end;
procedure TListFilterEdit.ApplyFilter(Immediately: Boolean);
begin
if Immediately then begin
if Assigned(fFilteredTreeview) then
ApplyFilterToTreeview(fFilteredTreeview)
ApplyFilterToTreeview
else if Assigned(fFilteredListbox) then
ApplyFilterToListBox
else
ApplyFilterToListBox(fFilteredListbox);
raise Exception.Create(
'Set either FilteredTreeview or FilteredListbox before using the filter.');
end
else begin
if csDestroying in ComponentState then exit;

View File

@ -1,7 +1,7 @@
inherited PackageEditorForm: TPackageEditorForm
Left = 267
Left = 344
Height = 450
Top = 194
Top = 119
Width = 577
Caption = 'PackageEditorForm'
ClientHeight = 450
@ -25,18 +25,18 @@ inherited PackageEditorForm: TPackageEditorForm
object FilePropsGroupBox: TGroupBox[1]
Left = 0
Height = 118
Top = 310
Top = 314
Width = 577
Align = alBottom
Caption = 'FilePropsGroupBox'
ClientHeight = 97
ClientWidth = 569
ClientHeight = 101
ClientWidth = 573
TabOrder = 1
object CallRegisterProcCheckBox: TCheckBox
Left = 0
Height = 22
Height = 18
Top = 0
Width = 209
Width = 173
Caption = 'CallRegisterProcCheckBox'
OnChange = CallRegisterProcCheckBoxChange
ParentShowHint = False
@ -46,10 +46,10 @@ inherited PackageEditorForm: TPackageEditorForm
object AddToUsesPkgSectionCheckBox: TCheckBox
AnchorSideLeft.Control = CallRegisterProcCheckBox
AnchorSideLeft.Side = asrBottom
Left = 219
Height = 22
Left = 183
Height = 18
Top = 0
Width = 248
Width = 204
BorderSpacing.Left = 10
Caption = 'AddToUsesPkgSectionCheckBox'
OnChange = AddToUsesPkgSectionCheckBoxChange
@ -62,9 +62,9 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideTop.Control = MinVersionEdit
AnchorSideTop.Side = asrCenter
Left = 0
Height = 22
Top = 2
Width = 197
Height = 18
Top = 1
Width = 163
Caption = 'UseMinVersionCheckBox'
OnChange = UseMinVersionCheckBoxChange
TabOrder = 2
@ -73,8 +73,8 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideLeft.Control = UseMinVersionCheckBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = FilePropsGroupBox
Left = 207
Height = 27
Left = 173
Height = 20
Top = 0
Width = 100
BorderSpacing.Left = 10
@ -87,9 +87,9 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideTop.Control = MaxVersionEdit
AnchorSideTop.Side = asrCenter
Left = 0
Height = 22
Top = 31
Width = 201
Height = 18
Top = 23
Width = 166
Caption = 'UseMaxVersionCheckBox'
OnChange = UseMaxVersionCheckBoxChange
TabOrder = 4
@ -99,9 +99,9 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = MinVersionEdit
AnchorSideTop.Side = asrBottom
Left = 211
Height = 27
Top = 29
Left = 176
Height = 20
Top = 22
Width = 100
BorderSpacing.Left = 10
BorderSpacing.Top = 2
@ -114,9 +114,9 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideTop.Control = MaxVersionEdit
AnchorSideTop.Side = asrBottom
Left = 0
Height = 27
Top = 62
Width = 188
Height = 23
Top = 48
Width = 146
AutoSize = True
BorderSpacing.Top = 6
Caption = 'ApplyDependencyButton'
@ -127,21 +127,21 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideTop.Control = CallRegisterProcCheckBox
AnchorSideTop.Side = asrBottom
Left = 0
Height = 60
Top = 37
Width = 569
Height = 77
Top = 24
Width = 573
Align = alBottom
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Top = 6
Caption = 'RegisteredPluginsGroupBox'
ClientHeight = 39
ClientWidth = 561
ClientHeight = 60
ClientWidth = 569
TabOrder = 7
object RegisteredListBox: TListBox
Left = 0
Height = 39
Height = 60
Top = 0
Width = 561
Width = 569
Align = alClient
ItemHeight = 0
OnDrawItem = RegisteredListBoxDrawItem
@ -152,8 +152,8 @@ inherited PackageEditorForm: TPackageEditorForm
end
object StatusBar: TStatusBar[2]
Left = 0
Height = 22
Top = 428
Height = 18
Top = 432
Width = 577
Panels = <>
end
@ -161,31 +161,30 @@ inherited PackageEditorForm: TPackageEditorForm
Cursor = crVSplit
Left = 0
Height = 5
Top = 305
Top = 309
Width = 577
Align = alBottom
ResizeAnchor = akBottom
end
object ItemsPanel: TPanel[4]
Left = 0
Height = 257
Height = 261
Top = 48
Width = 577
Align = alClient
BevelOuter = bvNone
ClientHeight = 257
ClientHeight = 261
ClientWidth = 577
TabOrder = 4
object FilesTreeView: TTreeView
AnchorSideTop.Control = FilterEdit
AnchorSideTop.Side = asrBottom
Left = 0
Height = 230
Top = 27
Height = 237
Top = 24
Width = 577
Align = alBottom
Anchors = [akTop, akLeft, akRight, akBottom]
DefaultItemHeight = 19
DefaultItemHeight = 15
PopupMenu = FilesPopupMenu
ReadOnly = True
TabOrder = 0
@ -194,34 +193,14 @@ inherited PackageEditorForm: TPackageEditorForm
OnSelectionChanged = FilesTreeViewSelectionChanged
Options = [tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
end
object FilterEdit: TEdit
AnchorSideLeft.Control = SortAlphabeticallySpeedButton
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = ItemsPanel
AnchorSideRight.Control = ItemsPanel
AnchorSideRight.Side = asrBottom
Left = 46
Height = 27
Top = 0
Width = 531
Anchors = [akTop, akLeft, akRight]
OnChange = FilterEditChange
OnEnter = FilterEditEnter
OnExit = FilterEditExit
TabOrder = 1
Text = 'FilterEdit'
end
object DirectoryHierarchySpeedButton: TSpeedButton
AnchorSideLeft.Control = ItemsPanel
AnchorSideTop.Control = FilterEdit
AnchorSideBottom.Control = FilterEdit
AnchorSideBottom.Side = asrBottom
Left = 0
Height = 27
Height = 20
Top = 0
Width = 23
AllowAllUp = True
Anchors = [akTop, akLeft, akBottom]
AutoSize = True
GroupIndex = 1
NumGlyphs = 0
@ -232,15 +211,12 @@ inherited PackageEditorForm: TPackageEditorForm
object SortAlphabeticallySpeedButton: TSpeedButton
AnchorSideLeft.Control = DirectoryHierarchySpeedButton
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = FilterEdit
AnchorSideBottom.Control = FilterEdit
AnchorSideBottom.Side = asrBottom
Left = 23
Height = 27
Height = 20
Top = 0
Width = 23
AllowAllUp = True
Anchors = [akTop, akLeft, akBottom]
AutoSize = True
GroupIndex = 2
NumGlyphs = 0
@ -248,6 +224,24 @@ inherited PackageEditorForm: TPackageEditorForm
ShowHint = True
ParentShowHint = False
end
object FilterEdit: TListFilterEdit
AnchorSideLeft.Control = SortAlphabeticallySpeedButton
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = ItemsPanel
AnchorSideRight.Side = asrBottom
Left = 46
Height = 20
Top = 0
Width = 508
FilteredTreeview = FilesTreeView
ButtonWidth = 23
NumGlyphs = 0
Anchors = [akTop, akLeft, akRight]
Font.Color = clBtnShadow
MaxLength = 0
ParentFont = False
TabOrder = 1
end
end
object FilesPopupMenu: TPopupMenu[5]
OnPopup = FilesPopupMenuPopup

View File

@ -42,8 +42,8 @@ uses
LResources, Graphics, LCLType, LCLProc, Menus, Dialogs, FileUtil, AVL_Tree,
// IDEIntf CodeTools
IDEImagesIntf, MenuIntf, HelpIntfs, ExtCtrls, LazIDEIntf, ProjectIntf,
CodeToolsStructs, FormEditingIntf, Laz_XMLCfg, PackageIntf, IDEDialogs,
IDEHelpIntf, IDEOptionsIntf,
CodeToolsStructs, FormEditingIntf, Laz_XMLCfg, ListFilterEdit, PackageIntf,
IDEDialogs, IDEHelpIntf, IDEOptionsIntf,
// IDE
MainIntf, IDEProcs, LazConf, LazarusIDEStrConsts, IDEOptionDefs, IDEDefs,
IDEContextHelpEdit, CompilerOptions, ComponentReg,
@ -137,19 +137,11 @@ type
const Filename: string): TModalResult of object;
TOnFreePkgEditor = procedure(APackage: TLazPackage) of object;
{ TPkgEditFileItem }
TPkgEditFileItem = class
public
Filename: string;
constructor Create(AFilename: string);
end;
{ TPackageEditorForm }
TPackageEditorForm = class(TBasePackageEditor)
DirectoryHierarchySpeedButton: TSpeedButton;
FilterEdit: TEdit;
FilterEdit: TListFilterEdit;
ItemsPanel: TPanel;
SortAlphabeticallySpeedButton: TSpeedButton;
Splitter1: TSplitter;
@ -203,9 +195,6 @@ type
procedure FilesTreeViewDblClick(Sender: TObject);
procedure FilesTreeViewKeyPress(Sender: TObject; var Key: Char);
procedure FilesTreeViewSelectionChanged(Sender: TObject);
procedure FilterEditChange(Sender: TObject);
procedure FilterEditEnter(Sender: TObject);
procedure FilterEditExit(Sender: TObject);
procedure FixFilesCaseMenuItemClick(Sender: TObject);
procedure HelpBitBtnClick(Sender: TObject);
procedure InstallClick(Sender: TObject);
@ -241,8 +230,6 @@ type
procedure ViewPkgSourceClick(Sender: TObject);
procedure ViewPkgTodosClick(Sender: TObject);
private
FFilter: string;
FIdleConnected: boolean;
FLazPackage: TLazPackage;
FNextSelectedPart: TObject;// select this file/dependency on next update
FFilesNode: TTreeNode;
@ -250,20 +237,17 @@ type
FRemovedFilesNode: TTreeNode;
FRemovedRequiredNode: TTreeNode;
FPlugins: TStringList;
FNeedUpdateAll: boolean;
FNeedUpdateFiles: boolean;
FShowDirectoryHierarchy: boolean;
FSortAlphabetically: boolean;
FDirSummaryLabel: TLabel;
procedure SetDependencyDefaultFilename(AsPreferred: boolean);
procedure SetFilter(const AValue: string);
procedure SetIdleConnected(const AValue: boolean);
procedure SetShowDirectoryHierarchy(const AValue: boolean);
procedure SetSortAlphabetically(const AValue: boolean);
procedure SetupComponents;
function ChooseImageIndex(Str: String; Data: TObject): Integer;
procedure UpdateTitle;
procedure UpdateButtons;
procedure UpdateFiles(Immediately: boolean);
procedure UpdateFiles;
procedure UpdateRequiredPkgs;
procedure UpdateSelectedFile;
procedure UpdateApplyDependencyButton;
@ -280,10 +264,7 @@ type
procedure ExtendIncPathForNewIncludeFile(const AnIncludeFile: string;
var IgnoreIncPaths: TFilenameToStringTree);
function CanBeAddedToProject: boolean;
procedure IdleHandler(Sender: TObject; var Done: Boolean);
function FitsFilter(aFilename: string): boolean;
function ComparePkgFilenames(AFilename1, AFilename2: string): integer;
procedure FreeTVNodeData(Node: TTreeNode);
protected
procedure SetLazPackage(const AValue: TLazPackage); override;
public
@ -305,10 +286,8 @@ type
procedure UpdateAll(Immediately: boolean); override;
public
property LazPackage: TLazPackage read FLazPackage write SetLazPackage;
property Filter: string read FFilter write SetFilter;
property SortAlphabetically: boolean read FSortAlphabetically write SetSortAlphabetically;
property ShowDirectoryHierarchy: boolean read FShowDirectoryHierarchy write SetShowDirectoryHierarchy;
property IdleConnected: boolean read FIdleConnected write SetIdleConnected;
end;
@ -517,13 +496,6 @@ begin
PkgEditMenuViewPackageSource:=RegisterIDEMenuCommand(AParent,'View Package Source',lisPckEditViewPackageSource);
end;
{ TPkgEditFileItem }
constructor TPkgEditFileItem.Create(AFilename: string);
begin
Filename:=AFilename;
end;
{ TPackageEditorForm }
procedure TPackageEditorForm.PublishClick(Sender: TObject);
@ -719,23 +691,6 @@ begin
//debugln(['TPackageEditorForm.FilesPopupMenuPopup END ',FilesPopupMenu.Items.Count]); PackageEditorMenuRoot.WriteDebugReport(' ',true);
end;
procedure TPackageEditorForm.FilterEditChange(Sender: TObject);
begin
Filter:=FilterEdit.Text;
end;
procedure TPackageEditorForm.FilterEditEnter(Sender: TObject);
begin
if FilterEdit.Text=lisCEFilter then
FilterEdit.Text:='';
end;
procedure TPackageEditorForm.FilterEditExit(Sender: TObject);
begin
if FilterEdit.Text='' then
FilterEdit.Text:=lisCEFilter;
end;
procedure TPackageEditorForm.SortAlphabeticallySpeedButtonClick(Sender: TObject);
begin
SortAlphabetically:=SortAlphabeticallySpeedButton.Down;
@ -899,7 +854,7 @@ begin
if CurNode=nil then exit;
NodeIndex:=CurNode.Index;
if CurNode.Parent<>nil then begin
if TObject(CurNode.Data) is TPkgEditFileItem then begin
if TObject(CurNode.Data) is TFileNameItem then begin
CurFile:=GetCurrentFile(Removed);
if CurFile=nil then exit;
DoOpenPkgFile(CurFile);
@ -1016,7 +971,7 @@ begin
exit;
end;
NodeIndex:=ANode.Index;
if TObject(ANode.Data) is TPkgEditFileItem then begin
if TObject(ANode.Data) is TFileNameItem then begin
// get current package file
CurFile:=GetCurrentFile(Removed);
if CurFile<>nil then begin
@ -1474,7 +1429,7 @@ begin
// update components
UpdateAll(true);
// show files
FFilesNode.Expanded:=true;
// FFilesNode.Expanded:=true;
end;
procedure TPackageEditorForm.SetupComponents;
@ -1517,7 +1472,7 @@ begin
ImageIndexConflict := IDEImages.LoadImage(16, 'pkg_conflict');
ImageIndexDirectory := IDEImages.LoadImage(16, 'pkg_files');
FilterEdit.Text:=lisCEFilter;
FilterEdit.OnGetImageIndex:=@ChooseImageIndex;
SortAlphabeticallySpeedButton.Hint:=lisPESortFilesAlphabetically;
SortAlphabeticallySpeedButton.LoadGlyphFromLazarusResource('pkg_sortalphabetically');
DirectoryHierarchySpeedButton.Hint:=lisPEShowDirectoryHierarchy;
@ -1592,41 +1547,13 @@ begin
UpdateButtons;
end;
procedure TPackageEditorForm.SetFilter(const AValue: string);
var
NewValue: String;
begin
NewValue:=AValue;
if NewValue=lisCEFilter then NewValue:='';
NewValue:=LowerCase(NewValue);
//debugln(['TPackageEditorForm.SetFilter Old="',Filter,'" New="',NewValue,'"']);
if FFilter=NewValue then exit;
FFilter:=NewValue;
if not FilterEdit.Focused then
if Filter='' then
FilterEdit.Text:=lisCEFilter
else
FilterEdit.Text:=Filter;
UpdateFiles(false);
end;
procedure TPackageEditorForm.SetIdleConnected(const AValue: boolean);
begin
if FIdleConnected=AValue then exit;
FIdleConnected:=AValue;
if FIdleConnected then
Application.AddOnIdleHandler(@IdleHandler)
else
Application.RemoveOnIdleHandler(@IdleHandler);
end;
procedure TPackageEditorForm.SetShowDirectoryHierarchy(const AValue: boolean);
begin
//debugln(['TPackageEditorForm.SetShowDirectoryHierachy Old=',FShowDirectoryHierarchy,' New=',AValue]);
if FShowDirectoryHierarchy=AValue then exit;
FShowDirectoryHierarchy:=AValue;
DirectoryHierarchySpeedButton.Down:=ShowDirectoryHierarchy;
UpdateFiles(false);
UpdateFiles;
end;
procedure TPackageEditorForm.SetSortAlphabetically(const AValue: boolean);
@ -1634,28 +1561,21 @@ begin
if FSortAlphabetically=AValue then exit;
FSortAlphabetically:=AValue;
SortAlphabeticallySpeedButton.Down:=SortAlphabetically;
UpdateFiles(false);
UpdateFiles;
end;
procedure TPackageEditorForm.UpdateAll(Immediately: boolean);
begin
if LazPackage=nil then exit;
Name:=PackageEditorWindowPrefix+LazPackage.Name;
if not Immediately then begin
if FNeedUpdateAll then exit;
FNeedUpdateAll:=true;
IdleConnected:=true;
exit;
end;
FNeedUpdateAll:=false;
FilesTreeView.BeginUpdate;
// FilesTreeView.BeginUpdate;
UpdateTitle;
UpdateButtons;
UpdateFiles(true);
UpdateFiles;
UpdateRequiredPkgs;
UpdateSelectedFile;
UpdateStatusBar;
FilesTreeView.EndUpdate;
// FilesTreeView.EndUpdate;
end;
procedure TPackageEditorForm.UpdateTitle;
@ -1678,7 +1598,7 @@ begin
AddBitBtn.Enabled:=not LazPackage.ReadOnly;
RemoveBitBtn.Enabled:=(not LazPackage.ReadOnly)
and (FilesTreeView.Selected<>nil)
and ((TObject(FilesTreeView.Selected.Data) is TPkgEditFileItem)
and ((TObject(FilesTreeView.Selected.Data) is TFileNameItem)
or (FilesTreeView.Selected.Parent=FRequiredPackagesNode));
UseBitBtn.Caption:=lisUse;
UseBitBtn.Hint:=lisClickToSeeThePossibleUses;
@ -1687,138 +1607,86 @@ begin
OptionsBitBtn.Enabled:=true;
end;
procedure TPackageEditorForm.UpdateFiles(Immediately: boolean);
procedure SetImageIndex(ANode: TTreeNode; PkgFile: TPkgFile);
begin
case PkgFile.FileType of
function TPackageEditorForm.ChooseImageIndex(Str: String; Data: TObject): Integer;
begin
case TPkgFile(Data).FileType of
pftUnit,pftVirtualUnit,pftMainUnit:
if PkgFile.HasRegisterProc then
ANode.ImageIndex:=ImageIndexRegisterUnit
if TPkgFile(Data).HasRegisterProc then
Result:=ImageIndexRegisterUnit
else
ANode.ImageIndex:=ImageIndexUnit;
pftLFM: ANode.ImageIndex:=ImageIndexLFM;
pftLRS: ANode.ImageIndex:=ImageIndexLRS;
pftInclude: ANode.ImageIndex:=ImageIndexInclude;
pftIssues: ANode.ImageIndex:=ImageIndexIssues;
pftText: ANode.ImageIndex:=ImageIndexText;
pftBinary: ANode.ImageIndex:=ImageIndexBinary;
Result:=ImageIndexUnit;
pftLFM: Result:=ImageIndexLFM;
pftLRS: Result:=ImageIndexLRS;
pftInclude: Result:=ImageIndexInclude;
pftIssues: Result:=ImageIndexIssues;
pftText: Result:=ImageIndexText;
pftBinary: Result:=ImageIndexBinary;
else
ANode.ImageIndex:=-1;
end;
ANode.SelectedIndex:=ANode.ImageIndex;
Result:=-1;
end;
end;
procedure TPackageEditorForm.UpdateFiles;
var
Cnt: Integer;
i: Integer;
Cnt, i, j: Integer;
CurFile: TPkgFile;
CurNode: TTreeNode;
NextNode: TTreeNode;
OldSelection: TStringList;
Files: TStringList;
j: Integer;
Filename: String;
TVNodeStack: TFPList;
ExpandedState: TTreeNodeExpandedState;
begin
if LazPackage=nil then exit;
//debugln(['TPackageEditorForm.UpdateFiles Immediately=',Immediately]);
if not Immediately then begin
FNeedUpdateFiles:=true;
IdleConnected:=true;
exit;
FilterEdit.RootNode:=FFilesNode;
FilterEdit.SelectedPart:=FNextSelectedPart;
FilterEdit.StoreFilenameInNode:=True;
FilterEdit.ShowDirHierarchy:=ShowDirectoryHierarchy;
FilterEdit.SortData:=SortAlphabetically;
FilterEdit.ImageIndexDirectory:=ImageIndexDirectory;
FilterEdit.Data.Clear;
// collect and sort files
for i:=0 to LazPackage.FileCount-1 do begin
CurFile:=LazPackage.Files[i];
Filename:=CurFile.GetShortFilename(true);
if Filename='' then continue;
j:=FilterEdit.Data.Count-1;
while j>=0 do begin
if ComparePkgFilenames(Filename,FilterEdit.Data[j])>=0 then break;
dec(j);
end;
FilterEdit.MapShortToFullFilename(Filename, CurFile.Filename);
FilterEdit.Data.Insert(j+1,Filename);
FilterEdit.Data.Objects[j+1]:=CurFile;
end;
FNeedUpdateFiles:=false;
FilterEdit.Invalidate; // Shown by FilterEdit.
FilesTreeView.BeginUpdate;
if FNextSelectedPart=nil then
OldSelection:=StoreCurrentTreeSelection
else
OldSelection:=nil;
// files
Files:=TStringList.Create;
TVNodeStack:=TFPList.Create;
ExpandedState:=TTreeNodeExpandedState.Create(FilesTreeView);
try
// collect and sort files
for i:=0 to LazPackage.FileCount-1 do begin
CurFile:=LazPackage.Files[i];
Filename:=CurFile.GetShortFilename(true);
if Filename='' then continue;
if not FitsFilter(Filename) then continue;
j:=Files.Count-1;
while j>=0 do begin
if ComparePkgFilenames(Filename,Files[j])>=0 then break;
dec(j);
end;
Files.Insert(j+1,Filename);
Files.Objects[j+1]:=CurFile;
// removed files
if LazPackage.RemovedFilesCount>0 then begin
if FRemovedFilesNode=nil then begin
FRemovedFilesNode:=
FilesTreeView.Items.Add(FRequiredPackagesNode,
lisPckEditRemovedFilesTheseEntriesAreNotSavedToTheLpkFile);
FRemovedFilesNode.ImageIndex:=ImageIndexRemovedFiles;
FRemovedFilesNode.SelectedIndex:=FRemovedFilesNode.ImageIndex;
end;
//debugln(['TPackageEditorForm.UpdateFiles filtered=',Files.Count,' of ',LazPackage.FileCount,' Filter="',Filter,'" Hierachy=',ShowDirectoryHierarchy,' SortAlpha=',SortAlphabetically]);
// update treeview nodes
FreeTVNodeData(FFilesNode);
if Files.Count=0 then
FFilesNode.DeleteChildren
else begin
CurNode:=FFilesNode.GetFirstChild;
for i:=0 to Files.Count-1 do begin
Filename:=Files[i];
CurFile:=TPkgFile(Files.Objects[i]);
TVClearUnneededAndCreateHierachy(FilesTreeView,FFilesNode,Filename,
TVNodeStack,ShowDirectoryHierarchy,ImageIndexDirectory);
CurNode:=TTreeNode(TVNodeStack[TVNodeStack.Count-1]);
if FNextSelectedPart<>nil then
CurNode.Selected:=FNextSelectedPart=CurFile;
CurNode.Data:=TPkgEditFileItem.Create(CurFile.Filename);
SetImageIndex(CurNode,CurFile);
CurNode.DeleteChildren;
end;
TVDeleteUnneededNodes(TVNodeStack,0);
CurNode:=FRemovedFilesNode.GetFirstChild;
Cnt:=LazPackage.RemovedFilesCount;
for i:=0 to Cnt-1 do begin
if CurNode=nil then
CurNode:=FilesTreeView.Items.AddChild(FRemovedFilesNode,'');
CurFile:=LazPackage.RemovedFiles[i];
CurNode.Text:=CurFile.GetShortFilename(true);
CurNode.ImageIndex:=ChooseImageIndex('', CurFile); // SetImageIndex(CurNode,CurFile);
CurNode:=CurNode.GetNextSibling;
end;
// removed files
if LazPackage.RemovedFilesCount>0 then begin
if FRemovedFilesNode=nil then begin
FRemovedFilesNode:=
FilesTreeView.Items.Add(FRequiredPackagesNode,
lisPckEditRemovedFilesTheseEntriesAreNotSavedToTheLpkFile);
FRemovedFilesNode.ImageIndex:=ImageIndexRemovedFiles;
FRemovedFilesNode.SelectedIndex:=FRemovedFilesNode.ImageIndex;
end;
CurNode:=FRemovedFilesNode.GetFirstChild;
Cnt:=LazPackage.RemovedFilesCount;
for i:=0 to Cnt-1 do begin
if CurNode=nil then
CurNode:=FilesTreeView.Items.AddChild(FRemovedFilesNode,'');
CurFile:=LazPackage.RemovedFiles[i];
CurNode.Text:=CurFile.GetShortFilename(true);
SetImageIndex(CurNode,CurFile);
CurNode:=CurNode.GetNextSibling;
end;
while CurNode<>nil do begin
NextNode:=CurNode.GetNextSibling;
CurNode.Free;
CurNode:=NextNode;
end;
FRemovedFilesNode.Expanded:=true;
end else begin
FreeAndNil(FRemovedFilesNode);
while CurNode<>nil do begin
NextNode:=CurNode.GetNextSibling;
CurNode.Free;
CurNode:=NextNode;
end;
ExpandedState.Apply(FilesTreeView);
finally
ExpandedState.Free;
TVNodeStack.Free;
Files.Free;
FRemovedFilesNode.Expanded:=true;
end else begin
FreeAndNil(FRemovedFilesNode);
end;
if OldSelection<>nil then
ApplyTreeSelection(OldSelection,true);
FilesTreeView.EndUpdate;
end;
procedure TPackageEditorForm.UpdateRequiredPkgs;
@ -2063,7 +1931,7 @@ function TPackageEditorForm.GetCurrentFile(out Removed: boolean): TPkgFile;
var
CurNode: TTreeNode;
NodeIndex: Integer;
Item: TPkgEditFileItem;
Item: TFileNameItem;
i: Integer;
begin
Result:=nil;
@ -2078,9 +1946,9 @@ begin
exit;
end;
//debugln(['TPackageEditorForm.GetCurrentFile ',DbgSName(TObject(CurNode.Data)),' ',CurNode.Text]);
if TObject(CurNode.Data) is TPkgEditFileItem then
if TObject(CurNode.Data) is TFileNameItem then
begin
Item:=TPkgEditFileItem(CurNode.Data);
Item:=TFileNameItem(CurNode.Data);
//debugln(['TPackageEditorForm.GetCurrentFile Item=',Item.Filename,' ',Item.IsDirectory]);
for i:=0 to LazPackage.FileCount-1 do
begin
@ -2106,11 +1974,11 @@ procedure TPackageEditorForm.GetDirectorySummary(DirNode: TTreeNode; out
procedure Traverse(Node: TTreeNode);
var
Item: TPkgEditFileItem;
Item: TFileNameItem;
CurFile: TPkgFile;
begin
if TObject(Node.Data) is TPkgEditFileItem then begin
Item:=TPkgEditFileItem(Node.Data);
if TObject(Node.Data) is TFileNameItem then begin
Item:=TFileNameItem(Node.Data);
CurFile:=LazPackage.FindPkgFile(Item.Filename,true,true);
if CurFile<>nil then begin
inc(FileCount);
@ -2163,7 +2031,8 @@ begin
ASelection.Delete(0);
end;
if ANode<>nil then FilesTreeView.Selected:=ANode;
if FreeList then ASelection.Free;
if FreeList then
ASelection.Free;
end;
procedure TPackageEditorForm.ExtendUnitIncPathForNewUnit(const AnUnitFilename,
@ -2271,37 +2140,6 @@ begin
Result:=PackageEditors.AddToProject(LazPackage,true)=mrOk;
end;
procedure TPackageEditorForm.IdleHandler(Sender: TObject; var Done: Boolean);
begin
if FNeedUpdateAll then
UpdateAll(true)
else if FNeedUpdateFiles then
UpdateFiles(true);
IdleConnected:=false;
end;
function TPackageEditorForm.FitsFilter(aFilename: string): boolean;
begin
Result:=(Filter='') or (System.Pos(Filter,lowercase(aFilename))>0);
end;
procedure TPackageEditorForm.FreeTVNodeData(Node: TTreeNode);
var
Child: TTreeNode;
begin
if Node=nil then exit;
if (Node.Data<>nil) then begin
TObject(Node.Data).Free;
Node.Data:=nil;
end;
Child:=Node.GetFirstChild;
while Child<>nil do
begin
FreeTVNodeData(Child);
Child:=Child.GetNextSibling;
end;
end;
function TPackageEditorForm.ComparePkgFilenames(AFilename1, AFilename2: string
): integer;
begin
@ -2393,9 +2231,9 @@ procedure TPackageEditorForm.DoUseUnitsInDirectory(Use: boolean);
var
PkgFile: TPkgFile;
begin
if TObject(Node.Data) is TPkgEditFileItem then
if TObject(Node.Data) is TFileNameItem then
begin
PkgFile:=LazPackage.FindPkgFile(TPkgEditFileItem(Node.Data).Filename,true,true);
PkgFile:=LazPackage.FindPkgFile(TFileNameItem(Node.Data).Filename,true,true);
if (PkgFile<>nil) and (PkgFile.FileType in [pftUnit,pftVirtualUnit]) then
begin
if PkgFile.AddToUsesPkgSection<>Use then
@ -2438,7 +2276,7 @@ begin
if (NewIndex<0) or (NewIndex>=LazPackage.FileCount) then exit;
TreeSelection:=StoreCurrentTreeSelection;
LazPackage.MoveFile(OldIndex,NewIndex);
UpdateFiles(true);
UpdateFiles;
ApplyTreeSelection(TreeSelection,true);
UpdateButtons;
UpdateStatusBar;
@ -2463,14 +2301,14 @@ procedure TPackageEditorForm.DoFixFilesCase;
begin
if LazPackage.FixFilesCaseSensitivity then
LazPackage.Modified:=true;
UpdateFiles(false);
UpdateFiles;
UpdateButtons;
end;
procedure TPackageEditorForm.DoShowMissingFiles;
begin
ShowMissingPkgFilesDialog(LazPackage);
UpdateFiles(false);
UpdateFiles;
end;
constructor TPackageEditorForm.Create(TheOwner: TComponent);
@ -2482,8 +2320,6 @@ end;
destructor TPackageEditorForm.Destroy;
begin
IdleConnected:=false;
FreeTVNodeData(FFilesNode);
if PackageEditorMenuRoot.MenuItem=FilesPopupMenu.Items then
PackageEditorMenuRoot.MenuItem:=nil;
PackageEditors.DoFreeEditor(LazPackage);
@ -2654,8 +2490,7 @@ begin
Result:=mrCancel;
end;
function TPackageEditors.ViewPkgSource(APackage: TLazPackage
): TModalResult;
function TPackageEditors.ViewPkgSource(APackage: TLazPackage): TModalResult;
begin
if Assigned(OnViewPackageSource) then
Result:=OnViewPackageSource(Self,APackage)