IDE: project inspector: filter, directory hierarchy, show sorted alphabetically

git-svn-id: trunk@30055 -
This commit is contained in:
mattias 2011-03-28 21:12:14 +00:00
parent 81c93dc90f
commit c0594332b5
12 changed files with 538 additions and 271 deletions

View File

@ -2328,7 +2328,7 @@ begin
FBreakPointGroups.LoadFromXMLConfig(XMLConfig, FBreakPointGroups.LoadFromXMLConfig(XMLConfig,
'Debugging/'+XMLBreakPointGroupsNode+'/'); 'Debugging/'+XMLBreakPointGroupsNode+'/');
FBreakPoints.LoadFromXMLConfig(XMLConfig,'Debugging/'+XMLBreakPointsNode+'/', FBreakPoints.LoadFromXMLConfig(XMLConfig,'Debugging/'+XMLBreakPointsNode+'/',
@Project1.LongenFilename, @Project1.ConvertFromLPIFilename,
@FBreakPointGroups.GetGroupByName); @FBreakPointGroups.GetGroupByName);
FWatches.LoadFromXMLConfig(XMLConfig,'Debugging/'+XMLWatchesNode+'/'); FWatches.LoadFromXMLConfig(XMLConfig,'Debugging/'+XMLWatchesNode+'/');
end; end;
@ -2347,7 +2347,7 @@ begin
FBreakPointGroups.SaveToXMLConfig(XMLConfig, FBreakPointGroups.SaveToXMLConfig(XMLConfig,
'Debugging/'+XMLBreakPointGroupsNode+'/'); 'Debugging/'+XMLBreakPointGroupsNode+'/');
FBreakPoints.SaveToXMLConfig(XMLConfig,'Debugging/'+XMLBreakPointsNode+'/', FBreakPoints.SaveToXMLConfig(XMLConfig,'Debugging/'+XMLBreakPointsNode+'/',
@Project1.ShortenFilename); @Project1.ConvertToLPIFilename);
FWatches.SaveToXMLConfig(XMLConfig,'Debugging/'+XMLWatchesNode+'/'); FWatches.SaveToXMLConfig(XMLConfig,'Debugging/'+XMLWatchesNode+'/');
end; end;
if not (pwfDoNotSaveProjectInfo in Flags) then if not (pwfDoNotSaveProjectInfo in Flags) then

View File

@ -692,7 +692,7 @@ begin
if DocFile<>nil then begin if DocFile<>nil then begin
Filename:=DocFile.Filename; Filename:=DocFile.Filename;
if (LazarusIDE.ActiveProject<>nil) then if (LazarusIDE.ActiveProject<>nil) then
LazarusIDE.ActiveProject.ShortenFilename(Filename); Filename:=LazarusIDE.ActiveProject.GetShortFilename(Filename,true);
Caption := strCaption + Filename; Caption := strCaption + Filename;
end else end else
Caption := strCaption + lisCodeHelpNoTagCaption; Caption := strCaption + lisCodeHelpNoTagCaption;

View File

@ -32,7 +32,7 @@ interface
uses uses
Classes, SysUtils, Laz_XMLCfg, FileUtil, LCLProc, AvgLvlTree, SourceLog, Classes, SysUtils, Laz_XMLCfg, FileUtil, LCLProc, AvgLvlTree, SourceLog,
FileProcs, CodeToolManager, CodeToolsConfig, CodeCache, LazConf, FileProcs, CodeToolManager, CodeToolsConfig, CodeCache, LazConf,
StdCtrls, ExtCtrls; StdCtrls, ExtCtrls, ComCtrls;
type type
// comments // comments
@ -265,6 +265,14 @@ procedure SetComboBoxText(AComboBox:TComboBox; const AText: String;
Cmp: TCmpStrType; MaxCount: integer); Cmp: TCmpStrType; MaxCount: integer);
function CheckGroupItemChecked(CheckGroup: TCheckGroup; const Caption: string): Boolean; function CheckGroupItemChecked(CheckGroup: TCheckGroup; const Caption: string): Boolean;
// treeview
procedure TVDeleteUnneededNodes(TVNodeStack: TFPList; p: integer);
procedure TVClearUnneededAndCreateHierachy(TV: TTreeView; FilesNode: TTreeNode;
Filename: string; TVNodeStack: TFPList;
ShowDirectoryHierarchy: boolean; ImageIndexDirectory: integer);
implementation implementation
@ -2729,6 +2737,84 @@ begin
Result := CheckGroup.Checked[CheckGroup.Items.IndexOf(Caption)]; Result := CheckGroup.Checked[CheckGroup.Items.IndexOf(Caption)];
end; end;
procedure TVDeleteUnneededNodes(TVNodeStack: TFPList; p: integer);
// delete all nodes behind the nodes in the stack, and depth>=p
var
i: Integer;
Node: TTreeNode;
begin
for i:=TVNodeStack.Count-1 downto p do begin
Node:=TTreeNode(TVNodeStack[i]);
while Node.GetNextSibling<>nil do
Node.GetNextSibling.Free;
end;
TVNodeStack.Count:=p;
end;
procedure TVClearUnneededAndCreateHierachy(TV: TTreeView; FilesNode: TTreeNode;
Filename: string; TVNodeStack: TFPList;
ShowDirectoryHierarchy: boolean; ImageIndexDirectory: integer);
// 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 ShowDirectoryHierarchy 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<TVNodeStack.Count then begin
Node:=TTreeNode(TVNodeStack[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(TVNodeStack,p+1);
if Node.GetNextSibling<>nil then begin
Node:=Node.GetNextSibling;
Node.Text:=FilePart;
end
else
Node:=TV.Items.Add(Node,FilePart);
TVNodeStack[p]:=Node;
end;
end else begin
// new sub node
if p>0 then
Node:=TTreeNode(TVNodeStack[p-1])
else
Node:=FilesNode;
if Node.GetFirstChild<>nil then begin
Node:=Node.GetFirstChild;
Node.Text:=FilePart;
end
else
Node:=TV.Items.AddChild(Node,FilePart);
TVNodeStack.Add(Node);
end;
if (Filename<>'') then begin
Node.ImageIndex:=ImageIndexDirectory;
Node.SelectedIndex:=Node.ImageIndex;
end;
inc(p);
end;
end;
procedure CTDbgOut(const s: string); procedure CTDbgOut(const s: string);
begin begin
LCLProc.DbgOut(s); LCLProc.DbgOut(s);

View File

@ -135,7 +135,7 @@ begin
SrcLine:=CodeBuf.GetLine(jh_item.CaretXY.Y-1); SrcLine:=CodeBuf.GetLine(jh_item.CaretXY.Y-1);
Filename:=jh_item.Filename; Filename:=jh_item.Filename;
if Project1<>nil then if Project1<>nil then
Project1.ShortenFilename(Filename); Filename:=Project1.GetShortFilename(Filename,true);
listHistory.Items.Append listHistory.Items.Append
(BeautifyLine(Filename, (BeautifyLine(Filename,
jh_item.CaretXY.X, jh_item.CaretXY.X,
@ -144,7 +144,7 @@ begin
) )
); );
end; end;
DebugLn(['TJumpHistoryViewWin.InitDisplay Project1.JumpHistory.HistoryIndex=',Project1.JumpHistory.HistoryIndex]); //DebugLn(['TJumpHistoryViewWin.InitDisplay Project1.JumpHistory.HistoryIndex=',Project1.JumpHistory.HistoryIndex]);
listHistory.ItemIndex := Project1.JumpHistory.HistoryIndex; listHistory.ItemIndex := Project1.JumpHistory.HistoryIndex;
end; end;
listHistory.Items.EndUpdate; listHistory.Items.EndUpdate;

View File

@ -7098,9 +7098,9 @@ var
LFMFilename:=ChangeFileExt(UnitCode.Filename,'.lfm'); LFMFilename:=ChangeFileExt(UnitCode.Filename,'.lfm');
if FileExistsUTF8(LFMFilename) then begin if FileExistsUTF8(LFMFilename) then begin
UsingFilename:=AnUnitInfo.Filename; UsingFilename:=AnUnitInfo.Filename;
Project1.ShortenFilename(UsingFilename); Project1.ConvertToLPIFilename(UsingFilename);
UsedFilename:=UnitCode.Filename; UsedFilename:=UnitCode.Filename;
Project1.ShortenFilename(UsedFilename); Project1.ConvertToLPIFilename(UsedFilename);
TheModalResult:=QuestionDlg(lisCodeTemplError, TheModalResult:=QuestionDlg(lisCodeTemplError,
Format(lisClassConflictsWithLfmFileTheUnitUsesTheUnitWhic, [#13, Format(lisClassConflictsWithLfmFileTheUnitUsesTheUnitWhic, [#13,
UsingFilename, #13, UsedFilename, #13, AComponentClassName, #13, #13, UsingFilename, #13, UsedFilename, #13, AComponentClassName, #13, #13,

View File

@ -342,6 +342,7 @@ type
function IsMainUnit: boolean; function IsMainUnit: boolean;
function IsVirtual: boolean; function IsVirtual: boolean;
function GetDirectory: string; function GetDirectory: string;
function GetShortFilename(UseUp: boolean): string;
function NeedsSaveToDisk: boolean; function NeedsSaveToDisk: boolean;
function ReadOnly: boolean; function ReadOnly: boolean;
function ReadUnitSource(ReadUnitName,Revert:boolean): TModalResult; function ReadUnitSource(ReadUnitName,Revert:boolean): TModalResult;
@ -958,8 +959,9 @@ type
function FileIsInProjectDir(const AFilename: string): boolean; function FileIsInProjectDir(const AFilename: string): boolean;
procedure GetVirtualDefines(DefTree: TDefineTree; DirDef: TDirectoryDefines); procedure GetVirtualDefines(DefTree: TDefineTree; DirDef: TDirectoryDefines);
function SearchFile(const Filename,SearchPaths,InitialDir:string):string; function SearchFile(const Filename,SearchPaths,InitialDir:string):string;
procedure ShortenFilename(var AFilename: string); override; // for lpi file function GetShortFilename(const Filename: string; UseUp: boolean): string; override;
procedure LongenFilename(var AFilename: string); override; // for lpi file procedure ConvertToLPIFilename(var AFilename: string); override;
procedure ConvertFromLPIFilename(var AFilename: string); override;
// package dependencies // package dependencies
function FindDependencyByName(const PackageName: string): TPkgDependency; function FindDependencyByName(const PackageName: string): TPkgDependency;
@ -1967,6 +1969,14 @@ begin
end; end;
end; end;
function TUnitInfo.GetShortFilename(UseUp: boolean): string;
begin
if Project<>nil then
Result:=Project.GetShortFilename(Filename,UseUp)
else
Result:=Filename;
end;
function TUnitInfo.IsMainUnit: boolean; function TUnitInfo.IsMainUnit: boolean;
begin begin
Result:=(Project<>nil) and (Project.MainUnitInfo=Self); Result:=(Project<>nil) and (Project.MainUnitInfo=Self);
@ -4068,12 +4078,29 @@ begin
Result:=''; Result:='';
end; end;
procedure TProject.ShortenFilename(var AFilename: string); function TProject.GetShortFilename(const Filename: string; UseUp: boolean
): string;
var
BaseDir: String;
CurPath: String;
begin
Result:=Filename;
BaseDir:=AppendPathDelim(ProjectDirectory);
if (BaseDir<>'') and FilenameIsAbsolute(BaseDir) and UseUp then
Result:=CreateRelativePath(Result,BaseDir)
else begin
CurPath:=copy(ExtractFilePath(Result),1,length(BaseDir));
if CompareFilenames(BaseDir,CurPath)=0 then
Result:=copy(Result,length(CurPath)+1,length(Result));
end;
end;
procedure TProject.ConvertToLPIFilename(var AFilename: string);
begin begin
OnLoadSaveFilename(AFilename,false); OnLoadSaveFilename(AFilename,false);
end; end;
procedure TProject.LongenFilename(var AFilename: string); procedure TProject.ConvertFromLPIFilename(var AFilename: string);
begin begin
OnLoadSaveFilename(AFilename,true); OnLoadSaveFilename(AFilename,true);
end; end;
@ -5017,7 +5044,7 @@ begin
Result:=POOutputDirectory; Result:=POOutputDirectory;
IDEMacros.SubstituteMacros(Result); IDEMacros.SubstituteMacros(Result);
Result:=TrimFilename(Result); Result:=TrimFilename(Result);
LongenFilename(Result); ConvertFromLPIFilename(Result);
end; end;
function TProject.GetAutoCreatedFormsList: TStrings; function TProject.GetAutoCreatedFormsList: TStrings;

View File

@ -1,20 +1,19 @@
object ProjectInspectorForm: TProjectInspectorForm object ProjectInspectorForm: TProjectInspectorForm
Left = 457 Left = 457
Height = 309 Height = 335
Top = 399 Top = 399
Width = 223 Width = 279
ActiveControl = ItemsTreeView ActiveControl = ItemsTreeView
Caption = 'ProjectInspectorForm' Caption = 'ProjectInspectorForm'
ClientHeight = 309 ClientHeight = 335
ClientWidth = 223 ClientWidth = 279
OnShow = ProjectInspectorFormShow OnShow = ProjectInspectorFormShow
LCLVersion = '0.9.29' LCLVersion = '0.9.31'
object ItemsTreeView: TTreeView object ItemsTreeView: TTreeView
AnchorSideTop.Side = asrBottom
Left = 0 Left = 0
Height = 283 Height = 304
Top = 26 Top = 31
Width = 223 Width = 279
Align = alClient Align = alClient
BorderSpacing.Top = 2 BorderSpacing.Top = 2
DefaultItemHeight = 19 DefaultItemHeight = 19
@ -29,72 +28,110 @@ object ProjectInspectorForm: TProjectInspectorForm
end end
object BtnPanel: TPanel object BtnPanel: TPanel
Left = 0 Left = 0
Height = 24 Height = 29
Top = 0 Top = 0
Width = 223 Width = 279
Align = alTop Align = alTop
AutoSize = True AutoSize = True
ChildSizing.EnlargeHorizontal = crsScaleChilds ClientHeight = 29
ChildSizing.Layout = cclLeftToRightThenTopToBottom ClientWidth = 279
ChildSizing.ControlsPerLine = 10
ClientHeight = 24
ClientWidth = 223
TabOrder = 1 TabOrder = 1
object OpenBitBtn: TSpeedButton object OpenBitBtn: TSpeedButton
Left = 0 Left = 1
Height = 23 Height = 27
Top = 0 Top = 1
Width = 53 Width = 40
Align = alLeft
AutoSize = True
Constraints.MinWidth = 25 Constraints.MinWidth = 25
Color = clBtnFace
NumGlyphs = 0 NumGlyphs = 0
OnClick = OpenBitBtnClick OnClick = OpenBitBtnClick
ShowHint = True ShowHint = True
ParentShowHint = False ParentShowHint = False
end end
object AddBitBtn: TSpeedButton object AddBitBtn: TSpeedButton
AnchorSideLeft.Side = asrBottom Left = 41
Left = 53 Height = 27
Height = 23 Top = 1
Top = 0 Width = 40
Width = 53 Align = alLeft
AutoSize = True
Constraints.MinWidth = 25 Constraints.MinWidth = 25
Color = clBtnFace
NumGlyphs = 0 NumGlyphs = 0
OnClick = AddBitBtnClick OnClick = AddBitBtnClick
ShowHint = True ShowHint = True
ParentShowHint = False ParentShowHint = False
end end
object RemoveBitBtn: TSpeedButton object RemoveBitBtn: TSpeedButton
AnchorSideLeft.Side = asrBottom Left = 81
Left = 106 Height = 27
Height = 23 Top = 1
Top = 0 Width = 40
Width = 53 Align = alLeft
AutoSize = True
Constraints.MinWidth = 25 Constraints.MinWidth = 25
Color = clBtnFace
NumGlyphs = 0 NumGlyphs = 0
OnClick = RemoveBitBtnClick OnClick = RemoveBitBtnClick
ShowHint = True ShowHint = True
ParentShowHint = False ParentShowHint = False
end end
object OptionsBitBtn: TSpeedButton object OptionsBitBtn: TSpeedButton
AnchorSideLeft.Side = asrBottom Left = 121
Left = 159 Height = 27
Height = 23 Top = 1
Top = 0 Width = 40
Width = 53 Align = alLeft
AutoSize = True
Constraints.MinWidth = 25 Constraints.MinWidth = 25
Color = clBtnFace
NumGlyphs = 0 NumGlyphs = 0
OnClick = OptionsBitBtnClick OnClick = OptionsBitBtnClick
ShowHint = True ShowHint = True
ParentShowHint = False ParentShowHint = False
end end
object DirectoryHierarchySpeedButton: TSpeedButton
Left = 232
Height = 27
Top = 1
Width = 23
Align = alRight
AllowAllUp = True
AutoSize = True
GroupIndex = 1
NumGlyphs = 0
OnClick = DirectoryHierarchySpeedButtonClick
ShowHint = True
ParentShowHint = False
end
object SortAlphabeticallySpeedButton: TSpeedButton
Left = 255
Height = 27
Top = 1
Width = 23
Align = alRight
AllowAllUp = True
AutoSize = True
GroupIndex = 2
NumGlyphs = 0
OnClick = SortAlphabeticallySpeedButtonClick
ShowHint = True
ParentShowHint = False
end
object FilterEdit: TEdit
Left = 161
Height = 27
Top = 1
Width = 71
Align = alClient
OnChange = FilterEditChange
OnEnter = FilterEditEnter
OnExit = FilterEditExit
TabOrder = 0
Text = 'FilterEdit'
end
end end
object ItemsPopupMenu: TPopupMenu object ItemsPopupMenu: TPopupMenu
OnPopup = ItemsPopupMenuPopup OnPopup = ItemsPopupMenuPopup
left = 40 left = 65
top = 59 top = 59
end end
end end

View File

@ -32,9 +32,6 @@
TProjectInspectorForm is the form of the project inspector. TProjectInspectorForm is the form of the project inspector.
ToDo: ToDo:
- hierachical view
- alpha sort
- filter
- show lfm/lrs files as sub items - show lfm/lrs files as sub items
- dnd move - dnd move
- project groups: - project groups:
@ -80,23 +77,40 @@ type
ADependency: TPkgDependency): TModalResult of object; ADependency: TPkgDependency): TModalResult of object;
TProjectInspectorFlag = ( TProjectInspectorFlag = (
pifAllChanged,
pifItemsChanged, pifItemsChanged,
pifFilesChanged,
pifButtonsChanged, pifButtonsChanged,
pifTitleChanged pifTitleChanged
); );
TProjectInspectorFlags = set of TProjectInspectorFlag; TProjectInspectorFlags = set of TProjectInspectorFlag;
{ TProjInspFileItem }
TProjInspFileItem = class
public
Filename: string;
constructor Create(AFilename: string);
end;
{ TProjectInspectorForm } { TProjectInspectorForm }
TProjectInspectorForm = class(TForm) TProjectInspectorForm = class(TForm)
AddBitBtn: TSpeedButton; AddBitBtn: TSpeedButton;
BtnPanel: TPanel; BtnPanel: TPanel;
DirectoryHierarchySpeedButton: TSpeedButton;
FilterEdit: TEdit;
OpenBitBtn: TSpeedButton; OpenBitBtn: TSpeedButton;
ItemsTreeView: TTreeView; ItemsTreeView: TTreeView;
ItemsPopupMenu: TPopupMenu; ItemsPopupMenu: TPopupMenu;
OptionsBitBtn: TSpeedButton; OptionsBitBtn: TSpeedButton;
RemoveBitBtn: TSpeedButton; RemoveBitBtn: TSpeedButton;
SortAlphabeticallySpeedButton: TSpeedButton;
procedure AddBitBtnClick(Sender: TObject); procedure AddBitBtnClick(Sender: TObject);
procedure DirectoryHierarchySpeedButtonClick(Sender: TObject);
procedure FilterEditChange(Sender: TObject);
procedure FilterEditEnter(Sender: TObject);
procedure FilterEditExit(Sender: TObject);
procedure ItemsPopupMenuPopup(Sender: TObject); procedure ItemsPopupMenuPopup(Sender: TObject);
procedure ItemsTreeViewDblClick(Sender: TObject); procedure ItemsTreeViewDblClick(Sender: TObject);
procedure ItemsTreeViewKeyDown(Sender: TObject; var Key: Word; procedure ItemsTreeViewKeyDown(Sender: TObject; var Key: Word;
@ -113,8 +127,11 @@ type
procedure ReAddMenuItemClick(Sender: TObject); procedure ReAddMenuItemClick(Sender: TObject);
procedure RemoveBitBtnClick(Sender: TObject); procedure RemoveBitBtnClick(Sender: TObject);
procedure RemoveNonExistingFilesMenuItemClick(Sender: TObject); procedure RemoveNonExistingFilesMenuItemClick(Sender: TObject);
procedure SortAlphabeticallySpeedButtonClick(Sender: TObject);
procedure ToggleI18NForLFMMenuItemClick(Sender: TObject); procedure ToggleI18NForLFMMenuItemClick(Sender: TObject);
private private
FFilter: string;
FIdleConnected: boolean;
FOnAddDependency: TAddProjInspDepEvent; FOnAddDependency: TAddProjInspDepEvent;
FOnAddUnitToProject: TOnAddUnitToProject; FOnAddUnitToProject: TOnAddUnitToProject;
FOnOpen: TNotifyEvent; FOnOpen: TNotifyEvent;
@ -122,9 +139,12 @@ type
FOnRemoveDependency: TRemoveProjInspDepEvent; FOnRemoveDependency: TRemoveProjInspDepEvent;
FOnRemoveFile: TRemoveProjInspFileEvent; FOnRemoveFile: TRemoveProjInspFileEvent;
FOnShowOptions: TNotifyEvent; FOnShowOptions: TNotifyEvent;
FShowDirectoryHierarchy: boolean;
FSortAlphabetically: boolean;
FUpdateLock: integer; FUpdateLock: integer;
FLazProject: TProject; FLazProject: TProject;
FilesNode: TTreeNode; FFilesNode: TTreeNode;
FNextSelectedPart: TObject;// select this file/dependency on next update
DependenciesNode: TTreeNode; DependenciesNode: TTreeNode;
RemovedDependenciesNode: TTreeNode; RemovedDependenciesNode: TTreeNode;
ImageIndexFiles: integer; ImageIndexFiles: integer;
@ -136,30 +156,37 @@ type
ImageIndexRegisterUnit: integer; ImageIndexRegisterUnit: integer;
ImageIndexText: integer; ImageIndexText: integer;
ImageIndexBinary: integer; ImageIndexBinary: integer;
ImageIndexDirectory: integer;
FFlags: TProjectInspectorFlags; FFlags: TProjectInspectorFlags;
procedure SetDependencyDefaultFilename(AsPreferred: boolean); procedure SetDependencyDefaultFilename(AsPreferred: boolean);
procedure SetFilter(const AValue: string);
procedure SetIdleConnected(const AValue: boolean);
procedure SetLazProject(const AValue: TProject); procedure SetLazProject(const AValue: TProject);
procedure SetShowDirectoryHierarchy(const AValue: boolean);
procedure SetSortAlphabetically(const AValue: boolean);
procedure SetupComponents; procedure SetupComponents;
procedure UpdateProjectItems; procedure UpdateProjectFiles(Immediately: boolean);
procedure UpdateRequiredPackages; procedure UpdateRequiredPackages;
procedure UpdateRemovedRequiredPackages; procedure UpdateRemovedRequiredPackages;
function GetImageIndexOfFile(AFile: TUnitInfo): integer; function GetImageIndexOfFile(AFile: TUnitInfo): integer;
procedure OnProjectBeginUpdate(Sender: TObject); procedure OnProjectBeginUpdate(Sender: TObject);
procedure OnProjectEndUpdate(Sender: TObject; ProjectChanged: boolean); procedure OnProjectEndUpdate(Sender: TObject; ProjectChanged: boolean);
function FitsFilter(aFilename: string): boolean;
function CompareProjFilenames(AFilename1, AFilename2: string): integer;
procedure FreeTVNodeData(Node: TTreeNode);
protected protected
procedure KeyUp(var Key: Word; Shift: TShiftState); override; procedure KeyUp(var Key: Word; Shift: TShiftState); override;
function ProjectFileToNodeText(AFile: TUnitInfo): string; procedure IdleHandler(Sender: TObject; var Done: Boolean);
function CompareUnitInfos(Tree: TAvgLvlTree; UnitInfo1, UnitInfo2: Pointer): integer;
public public
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
procedure BeginUpdate; procedure BeginUpdate;
procedure EndUpdate; procedure EndUpdate;
function IsUpdateLocked: boolean; function IsUpdateLocked: boolean;
procedure UpdateAll; procedure UpdateAll(Immediately: boolean);
procedure UpdateTitle; procedure UpdateTitle;
procedure UpdateButtons; procedure UpdateButtons;
procedure UpdateItems; procedure UpdateItems(Immediately: boolean);
function GetSelectedFile: TUnitInfo; function GetSelectedFile: TUnitInfo;
function GetSelectedDependency: TPkgDependency; function GetSelectedDependency: TPkgDependency;
function StoreCurrentTreeSelection: TStringList; function StoreCurrentTreeSelection: TStringList;
@ -178,6 +205,10 @@ type
read FOnRemoveDependency write FOnRemoveDependency; read FOnRemoveDependency write FOnRemoveDependency;
property OnReAddDependency: TAddProjInspDepEvent property OnReAddDependency: TAddProjInspDepEvent
read FOnReAddDependency write FOnReAddDependency; read FOnReAddDependency write FOnReAddDependency;
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; end;
var var
@ -191,6 +222,13 @@ implementation
uses uses
IDEImagesIntf; IDEImagesIntf;
{ TProjInspFileItem }
constructor TProjInspFileItem.Create(AFilename: string);
begin
Filename:=AFilename;
end;
{ TProjectInspectorForm } { TProjectInspectorForm }
procedure TProjectInspectorForm.ItemsTreeViewDblClick(Sender: TObject); procedure TProjectInspectorForm.ItemsTreeViewDblClick(Sender: TObject);
@ -216,31 +254,21 @@ end;
procedure TProjectInspectorForm.MoveDependencyUpClick(Sender: TObject); procedure TProjectInspectorForm.MoveDependencyUpClick(Sender: TObject);
var var
Dependency: TPkgDependency; Dependency: TPkgDependency;
OldSelection: TStringList;
begin begin
Dependency:=GetSelectedDependency; Dependency:=GetSelectedDependency;
if (Dependency=nil) or (Dependency.Removed) if (Dependency=nil) or (Dependency.Removed)
or (Dependency.PrevRequiresDependency=nil) then exit; or (Dependency.PrevRequiresDependency=nil) then exit;
ItemsTreeView.BeginUpdate;
OldSelection:=StoreCurrentTreeSelection;
LazProject.MoveRequiredDependencyUp(Dependency); LazProject.MoveRequiredDependencyUp(Dependency);
ApplyTreeSelection(OldSelection,true);
ItemsTreeView.EndUpdate;
end; end;
procedure TProjectInspectorForm.MoveDependencyDownClick(Sender: TObject); procedure TProjectInspectorForm.MoveDependencyDownClick(Sender: TObject);
var var
Dependency: TPkgDependency; Dependency: TPkgDependency;
OldSelection: TStringList;
begin begin
Dependency:=GetSelectedDependency; Dependency:=GetSelectedDependency;
if (Dependency=nil) or (Dependency.Removed) if (Dependency=nil) or (Dependency.Removed)
or (Dependency.NextRequiresDependency=nil) then exit; or (Dependency.NextRequiresDependency=nil) then exit;
ItemsTreeView.BeginUpdate;
OldSelection:=StoreCurrentTreeSelection;
LazProject.MoveRequiredDependencyDown(Dependency); LazProject.MoveRequiredDependencyDown(Dependency);
ApplyTreeSelection(OldSelection,true);
ItemsTreeView.EndUpdate;
end; end;
procedure TProjectInspectorForm.SetDependencyDefaultFilenameMenuItemClick( procedure TProjectInspectorForm.SetDependencyDefaultFilenameMenuItemClick(
@ -298,8 +326,9 @@ begin
if Assigned(OnAddUnitToProject) then begin if Assigned(OnAddUnitToProject) then begin
if OnAddUnitToProject(Self,NewFile)<>mrOk then break; if OnAddUnitToProject(Self,NewFile)<>mrOk then break;
end; end;
FNextSelectedPart:=NewFile;
end; end;
UpdateAll; UpdateAll(false);
EndUpdate; EndUpdate;
end; end;
@ -308,7 +337,8 @@ begin
BeginUpdate; BeginUpdate;
if Assigned(OnAddDependency) then if Assigned(OnAddDependency) then
OnAddDependency(Self,AddResult.Dependency); OnAddDependency(Self,AddResult.Dependency);
UpdateItems; FNextSelectedPart:=AddResult.Dependency;
UpdateItems(false);
EndUpdate; EndUpdate;
end; end;
@ -317,6 +347,29 @@ begin
AddResult.Free; AddResult.Free;
end; end;
procedure TProjectInspectorForm.DirectoryHierarchySpeedButtonClick(
Sender: TObject);
begin
ShowDirectoryHierarchy:=DirectoryHierarchySpeedButton.Down;
end;
procedure TProjectInspectorForm.FilterEditChange(Sender: TObject);
begin
Filter:=FilterEdit.Text;
end;
procedure TProjectInspectorForm.FilterEditEnter(Sender: TObject);
begin
if FilterEdit.Text=lisCEFilter then
FilterEdit.Text:='';
end;
procedure TProjectInspectorForm.FilterEditExit(Sender: TObject);
begin
if FilterEdit.Text=lisCEFilter then
FilterEdit.Text:='';
end;
procedure TProjectInspectorForm.ItemsPopupMenuPopup(Sender: TObject); procedure TProjectInspectorForm.ItemsPopupMenuPopup(Sender: TObject);
var var
ItemCnt: integer; ItemCnt: integer;
@ -403,7 +456,7 @@ end;
procedure TProjectInspectorForm.ProjectInspectorFormShow(Sender: TObject); procedure TProjectInspectorForm.ProjectInspectorFormShow(Sender: TObject);
begin begin
UpdateAll; UpdateAll(false);
end; end;
procedure TProjectInspectorForm.ReAddMenuItemClick(Sender: TObject); procedure TProjectInspectorForm.ReAddMenuItemClick(Sender: TObject);
@ -466,10 +519,16 @@ begin
end; end;
if HasChanged then begin if HasChanged then begin
LazProject.Modified:=true; LazProject.Modified:=true;
UpdateAll; UpdateProjectFiles(false);
end; end;
end; end;
procedure TProjectInspectorForm.SortAlphabeticallySpeedButtonClick(
Sender: TObject);
begin
SortAlphabetically:=SortAlphabeticallySpeedButton.Down;
end;
procedure TProjectInspectorForm.ToggleI18NForLFMMenuItemClick(Sender: TObject); procedure TProjectInspectorForm.ToggleI18NForLFMMenuItemClick(Sender: TObject);
var var
CurFile: TUnitInfo; CurFile: TUnitInfo;
@ -493,7 +552,24 @@ begin
FLazProject.OnBeginUpdate:=@OnProjectBeginUpdate; FLazProject.OnBeginUpdate:=@OnProjectBeginUpdate;
FLazProject.OnEndUpdate:=@OnProjectEndUpdate; FLazProject.OnEndUpdate:=@OnProjectEndUpdate;
end; end;
UpdateAll; UpdateAll(false);
end;
procedure TProjectInspectorForm.SetShowDirectoryHierarchy(const AValue: boolean
);
begin
if FShowDirectoryHierarchy=AValue then exit;
FShowDirectoryHierarchy:=AValue;
DirectoryHierarchySpeedButton.Down:=ShowDirectoryHierarchy;
UpdateProjectFiles(false);
end;
procedure TProjectInspectorForm.SetSortAlphabetically(const AValue: boolean);
begin
if FSortAlphabetically=AValue then exit;
FSortAlphabetically:=AValue;
SortAlphabeticallySpeedButton.Down:=SortAlphabetically;
UpdateProjectFiles(false);
end; end;
procedure TProjectInspectorForm.SetDependencyDefaultFilename( procedure TProjectInspectorForm.SetDependencyDefaultFilename(
@ -515,6 +591,34 @@ begin
UpdateButtons; UpdateButtons;
end; end;
procedure TProjectInspectorForm.SetFilter(const AValue: string);
var
NewValue: String;
begin
NewValue:=AValue;
if NewValue=lisCEFilter then NewValue:='';
NewValue:=LowerCase(NewValue);
//debugln(['TProjectInspectorForm.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;
UpdateProjectFiles(false);
end;
procedure TProjectInspectorForm.SetIdleConnected(const AValue: boolean);
begin
if FIdleConnected=AValue then exit;
FIdleConnected:=AValue;
if FIdleConnected then
Application.AddOnIdleHandler(@IdleHandler)
else
Application.RemoveOnIdleHandler(@IdleHandler);
end;
procedure TProjectInspectorForm.SetupComponents; procedure TProjectInspectorForm.SetupComponents;
begin begin
ItemsTreeView.Images := IDEImages.Images_16; ItemsTreeView.Images := IDEImages.Images_16;
@ -527,6 +631,7 @@ begin
ImageIndexRegisterUnit := IDEImages.LoadImage(16, 'pkg_registerunit'); ImageIndexRegisterUnit := IDEImages.LoadImage(16, 'pkg_registerunit');
ImageIndexText := IDEImages.LoadImage(16, 'pkg_text'); ImageIndexText := IDEImages.LoadImage(16, 'pkg_text');
ImageIndexBinary := IDEImages.LoadImage(16, 'pkg_binary'); ImageIndexBinary := IDEImages.LoadImage(16, 'pkg_binary');
ImageIndexDirectory := IDEImages.LoadImage(16, 'pkg_files');
OpenBitBtn.LoadGlyphFromLazarusResource('laz_open'); OpenBitBtn.LoadGlyphFromLazarusResource('laz_open');
AddBitBtn.LoadGlyphFromLazarusResource('laz_add'); AddBitBtn.LoadGlyphFromLazarusResource('laz_add');
@ -541,59 +646,104 @@ begin
AddBitBtn.Hint:=lisCodeTemplAdd; AddBitBtn.Hint:=lisCodeTemplAdd;
RemoveBitBtn.Hint:=lisExtToolRemove; RemoveBitBtn.Hint:=lisExtToolRemove;
OptionsBitBtn.Hint:=dlgFROpts; OptionsBitBtn.Hint:=dlgFROpts;
FilterEdit.Text:=lisCEFilter;
SortAlphabeticallySpeedButton.Hint:=lisPESortFilesAlphabetically;
SortAlphabeticallySpeedButton.LoadGlyphFromLazarusResource('pkg_sortalphabetically');
DirectoryHierarchySpeedButton.Hint:=lisPEShowDirectoryHierarchy;
DirectoryHierarchySpeedButton.LoadGlyphFromLazarusResource('pkg_hierarchical');
with ItemsTreeView do begin with ItemsTreeView do begin
FilesNode:=Items.Add(nil, dlgEnvFiles); FFilesNode:=Items.Add(nil, dlgEnvFiles);
FilesNode.ImageIndex:=ImageIndexFiles; FFilesNode.ImageIndex:=ImageIndexFiles;
FilesNode.SelectedIndex:=FilesNode.ImageIndex; FFilesNode.SelectedIndex:=FFilesNode.ImageIndex;
DependenciesNode:=Items.Add(nil, lisPckEditRequiredPackages); DependenciesNode:=Items.Add(nil, lisPckEditRequiredPackages);
DependenciesNode.ImageIndex:=ImageIndexRequired; DependenciesNode.ImageIndex:=ImageIndexRequired;
DependenciesNode.SelectedIndex:=DependenciesNode.ImageIndex; DependenciesNode.SelectedIndex:=DependenciesNode.ImageIndex;
end; end;
end; end;
procedure TProjectInspectorForm.UpdateProjectItems; procedure TProjectInspectorForm.UpdateProjectFiles(Immediately: boolean);
var var
CurFile: TUnitInfo; CurFile: TUnitInfo;
CurNode: TTreeNode; CurNode: TTreeNode;
NodeText: String; OldSelection: TStringList;
NextNode: TTreeNode; Files: TStringList;
Tree: TAvgLvlTree; TVNodeStack: TFPList;
AVLNode: TAvgLvlTreeNode; ExpandedState: TTreeNodeExpandedState;
Filename: String;
i: Integer;
begin begin
if (not Immediately) or (FUpdateLock>0) or (not Visible) then begin
Include(FFlags,pifFilesChanged);
IdleConnected:=true;
exit;
end;
Exclude(FFlags,pifFilesChanged);
ItemsTreeView.BeginUpdate; ItemsTreeView.BeginUpdate;
if FNextSelectedPart=nil then
OldSelection:=StoreCurrentTreeSelection
else
OldSelection:=nil;
Files:=TStringList.Create;
TVNodeStack:=TFPList.Create;
ExpandedState:=TTreeNodeExpandedState.Create(ItemsTreeView);
try
if LazProject<>nil then begin if LazProject<>nil then begin
Tree:=TAvgLvlTree.CreateObjectCompare(@CompareUnitInfos); // collect and sort files
CurFile:=LazProject.FirstPartOfProject; CurFile:=LazProject.FirstPartOfProject;
while CurFile<>nil do begin while CurFile<>nil do begin
Tree.Add(CurFile); Filename:=CurFile.GetShortFilename(true);
if (Filename<>'') and FitsFilter(Filename) then begin
i:=Files.Count-1;
while i>=0 do begin
if CompareProjFilenames(Filename,Files[i])>=0 then break;
dec(i);
end;
Files.Insert(i+1,Filename);
Files.Objects[i+1]:=CurFile;
end;
CurFile:=CurFile.NextPartOfProject; CurFile:=CurFile.NextPartOfProject;
end; end;
AVLNode:=Tree.FindLowest; //debugln(['TProjectInspectorForm.UpdateFiles filtered=',Files.Count,' of ',LazProject.FileCount,' Filter="',Filter,'" Hierachy=',ShowDirectoryHierarchy,' SortAlpha=',SortAlphabetically]);
CurNode:=FilesNode.GetFirstChild;
while AVLNode<>nil do begin // update treeview nodes
CurFile:=TUnitInfo(AVLNode.Data); FreeTVNodeData(FFilesNode);
NodeText:=ProjectFileToNodeText(CurFile); if Files.Count=0 then
if CurNode=nil then FFilesNode.DeleteChildren
CurNode:=ItemsTreeView.Items.AddChild(FilesNode,NodeText) else begin
else CurNode:=FFilesNode.GetFirstChild;
CurNode.Text:=NodeText; for i:=0 to Files.Count-1 do begin
Filename:=Files[i];
CurFile:=TUnitInfo(Files.Objects[i]);
TVClearUnneededAndCreateHierachy(ItemsTreeView,FFilesNode,Filename,
TVNodeStack,ShowDirectoryHierarchy,ImageIndexDirectory);
CurNode:=TTreeNode(TVNodeStack[TVNodeStack.Count-1]);
if FNextSelectedPart<>nil then begin
CurNode.Selected:=FNextSelectedPart=CurFile;
FNextSelectedPart:=nil;
end;
CurNode.Data:=TProjInspFileItem.Create(CurFile.Filename);
CurNode.ImageIndex:=GetImageIndexOfFile(CurFile); CurNode.ImageIndex:=GetImageIndexOfFile(CurFile);
CurNode.SelectedIndex:=CurNode.ImageIndex; CurNode.SelectedIndex:=CurNode.ImageIndex;
CurNode:=CurNode.GetNextSibling; CurNode.DeleteChildren;
AVLNode:=Tree.FindSuccessor(AVLNode);
end; end;
while CurNode<>nil do begin TVDeleteUnneededNodes(TVNodeStack,0);
NextNode:=CurNode.GetNextSibling;
CurNode.Free;
CurNode:=NextNode;
end; end;
FilesNode.Expanded:=true;
Tree.Free;
end else begin end else begin
// delete file nodes // delete file nodes
FilesNode.HasChildren:=false; FFilesNode.DeleteChildren;
end; end;
ExpandedState.Apply(ItemsTreeView);
FFilesNode.Expanded:=true;
finally
ExpandedState.Free;
TVNodeStack.Free;
Files.Free;
end;
if OldSelection<>nil then
ApplyTreeSelection(OldSelection,true);
ItemsTreeView.EndUpdate; ItemsTreeView.EndUpdate;
end; end;
@ -704,48 +854,85 @@ end;
procedure TProjectInspectorForm.OnProjectEndUpdate(Sender: TObject; procedure TProjectInspectorForm.OnProjectEndUpdate(Sender: TObject;
ProjectChanged: boolean); ProjectChanged: boolean);
begin begin
UpdateAll; UpdateAll(false);
EndUpdate; EndUpdate;
end; end;
function TProjectInspectorForm.FitsFilter(aFilename: string): boolean;
begin
Result:=(Filter='') or (System.Pos(Filter,lowercase(aFilename))>0);
end;
function TProjectInspectorForm.CompareProjFilenames(AFilename1,
AFilename2: string): integer;
begin
if SortAlphabetically then
Result:=CompareFilenames(AFilename1, AFilename2)
else if ShowDirectoryHierarchy then
Result:=CompareFilenames(ExtractFilePath(AFilename1), ExtractFilePath(AFilename2))
else
Result:=0;
end;
procedure TProjectInspectorForm.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 TProjectInspectorForm.KeyUp(var Key: Word; Shift: TShiftState); procedure TProjectInspectorForm.KeyUp(var Key: Word; Shift: TShiftState);
begin begin
inherited KeyDown(Key, Shift); inherited KeyDown(Key, Shift);
ExecuteIDEShortCut(Self,Key,Shift,nil); ExecuteIDEShortCut(Self,Key,Shift,nil);
end; end;
function TProjectInspectorForm.ProjectFileToNodeText(AFile: TUnitInfo): string; procedure TProjectInspectorForm.IdleHandler(Sender: TObject; var Done: Boolean
);
begin begin
Result:=CreateRelativePath(AFile.Filename,LazProject.ProjectDirectory); if (not Visible) or (FUpdateLock>0) then begin
IdleConnected:=false;
exit;
end; end;
if pifAllChanged in FFlags then
function TProjectInspectorForm.CompareUnitInfos(Tree: TAvgLvlTree; UpdateAll(true)
UnitInfo1, UnitInfo2: Pointer): integer; else if pifItemsChanged in FFlags then
var UpdateItems(true)
ShortFilename1: String; else if pifFilesChanged in FFlags then
ShortFilename2: String; UpdateProjectFiles(true)
begin else if pifTitleChanged in FFlags then
ShortFilename1:=CreateRelativePath(TUnitInfo(UnitInfo1).Filename, UpdateTitle
LazProject.ProjectDirectory); else if pifButtonsChanged in FFlags then
ShortFilename2:=CreateRelativePath(TUnitInfo(UnitInfo2).Filename, UpdateButtons
LazProject.ProjectDirectory); else
Result:=CompareFilenames(ShortFilename1,ShortFilename2); IdleConnected:=false;
end; end;
function TProjectInspectorForm.GetSelectedFile: TUnitInfo; function TProjectInspectorForm.GetSelectedFile: TUnitInfo;
var var
CurNode: TTreeNode; CurNode: TTreeNode;
NodeText: String; Item: TProjInspFileItem;
begin begin
Result:=nil; Result:=nil;
if LazProject=nil then exit; if LazProject=nil then exit;
CurNode:=ItemsTreeView.Selected; CurNode:=ItemsTreeView.Selected;
if (CurNode=nil) or (CurNode.Parent<>FilesNode) then exit; if (CurNode=nil) or (CurNode.Parent<>FFilesNode) then exit;
Result:=LazProject.FirstPartOfProject; //debugln(['TProjectInspectorForm.GetCurrentFile ',DbgSName(TObject(CurNode.Data)),' ',CurNode.Text]);
while (Result<>nil) do begin if TObject(CurNode.Data) is TProjInspFileItem then
NodeText:=ProjectFileToNodeText(Result); begin
if NodeText=CurNode.Text then exit; Item:=TProjInspFileItem(CurNode.Data);
Result:=Result.NextPartOfProject; //debugln(['TProjectInspectorForm.GetCurrentFile Item=',Item.Filename,' ',Item.IsDirectory]);
Result:=LazProject.UnitInfoWithFilename(Item.Filename);
end; end;
end; end;
@ -815,7 +1002,9 @@ end;
destructor TProjectInspectorForm.Destroy; destructor TProjectInspectorForm.Destroy;
begin begin
IdleConnected:=false;
BeginUpdate; BeginUpdate;
FreeTVNodeData(FFilesNode);
LazProject:=nil; LazProject:=nil;
inherited Destroy; inherited Destroy;
if ProjInspector=Self then ProjInspector:=nil; if ProjInspector=Self then ProjInspector:=nil;
@ -830,11 +1019,6 @@ procedure TProjectInspectorForm.EndUpdate;
begin begin
if FUpdateLock=0 then RaiseException('TProjectInspectorForm.EndUpdate'); if FUpdateLock=0 then RaiseException('TProjectInspectorForm.EndUpdate');
dec(FUpdateLock); dec(FUpdateLock);
if FUpdateLock=0 then begin
if pifTitleChanged in FFlags then UpdateTitle;
if pifItemsChanged in FFlags then UpdateItems;
if pifButtonsChanged in FFlags then UpdateButtons;
end;
end; end;
function TProjectInspectorForm.IsUpdateLocked: boolean; function TProjectInspectorForm.IsUpdateLocked: boolean;
@ -842,11 +1026,17 @@ begin
Result:=FUpdateLock>0; Result:=FUpdateLock>0;
end; end;
procedure TProjectInspectorForm.UpdateAll; procedure TProjectInspectorForm.UpdateAll(Immediately: boolean);
begin begin
if (FUpdateLock>0) or (not Visible) then begin
Include(FFlags,pifAllChanged);
IdleConnected:=true;
exit;
end;
Exclude(FFlags,pifAllChanged);
UpdateTitle; UpdateTitle;
UpdateButtons; UpdateButtons;
UpdateItems; UpdateItems(true);
end; end;
procedure TProjectInspectorForm.UpdateTitle; procedure TProjectInspectorForm.UpdateTitle;
@ -855,6 +1045,7 @@ var
begin begin
if (FUpdateLock>0) or (not Visible) then begin if (FUpdateLock>0) or (not Visible) then begin
Include(FFlags,pifTitleChanged); Include(FFlags,pifTitleChanged);
IdleConnected:=true;
exit; exit;
end; end;
Exclude(FFlags,pifTitleChanged); Exclude(FFlags,pifTitleChanged);
@ -875,6 +1066,7 @@ var
begin begin
if (FUpdateLock>0) or (not Visible) then begin if (FUpdateLock>0) or (not Visible) then begin
Include(FFlags,pifButtonsChanged); Include(FFlags,pifButtonsChanged);
IdleConnected:=true;
exit; exit;
end; end;
Exclude(FFlags,pifButtonsChanged); Exclude(FFlags,pifButtonsChanged);
@ -895,15 +1087,16 @@ begin
end; end;
end; end;
procedure TProjectInspectorForm.UpdateItems; procedure TProjectInspectorForm.UpdateItems(Immediately: boolean);
begin begin
if (FUpdateLock>0) or (not Visible) then begin if (FUpdateLock>0) or (not Visible) then begin
Include(FFlags,pifItemsChanged); Include(FFlags,pifItemsChanged);
IdleConnected:=true;
exit; exit;
end; end;
Exclude(FFlags,pifItemsChanged); Exclude(FFlags,pifItemsChanged);
ItemsTreeView.BeginUpdate; ItemsTreeView.BeginUpdate;
UpdateProjectItems; UpdateProjectFiles(true);
UpdateRequiredPackages; UpdateRequiredPackages;
UpdateRemovedRequiredPackages; UpdateRemovedRequiredPackages;
ItemsTreeView.EndUpdate; ItemsTreeView.EndUpdate;

View File

@ -372,8 +372,9 @@ type
function FindFile(const AFilename: string; function FindFile(const AFilename: string;
SearchFlags: TProjectFileSearchFlags): TLazProjectFile; virtual; abstract; SearchFlags: TProjectFileSearchFlags): TLazProjectFile; virtual; abstract;
procedure UpdateExecutableType; virtual; abstract; procedure UpdateExecutableType; virtual; abstract;
procedure ShortenFilename(var AFilename: string); virtual; abstract; function GetShortFilename(const Filename: string; UseUp: boolean): string; virtual; abstract;
procedure LongenFilename(var AFilename: string); virtual; abstract; procedure ConvertToLPIFilename(var AFilename: string); virtual; abstract;
procedure ConvertFromLPIFilename(var AFilename: string); virtual; abstract;
public public
property MainFileID: Integer read GetMainFileID write SetMainFileID; property MainFileID: Integer read GetMainFileID write SetMainFileID;
property Files[Index: integer]: TLazProjectFile read GetFiles; property Files[Index: integer]: TLazProjectFile read GetFiles;

View File

@ -25,18 +25,18 @@ inherited PackageEditorForm: TPackageEditorForm
object FilePropsGroupBox: TGroupBox[1] object FilePropsGroupBox: TGroupBox[1]
Left = 0 Left = 0
Height = 118 Height = 118
Top = 309 Top = 310
Width = 577 Width = 577
Align = alBottom Align = alBottom
Caption = 'FilePropsGroupBox' Caption = 'FilePropsGroupBox'
ClientHeight = 100 ClientHeight = 97
ClientWidth = 573 ClientWidth = 569
TabOrder = 1 TabOrder = 1
object CallRegisterProcCheckBox: TCheckBox object CallRegisterProcCheckBox: TCheckBox
Left = 0 Left = 0
Height = 19 Height = 22
Top = 0 Top = 0
Width = 158 Width = 209
Caption = 'CallRegisterProcCheckBox' Caption = 'CallRegisterProcCheckBox'
OnChange = CallRegisterProcCheckBoxChange OnChange = CallRegisterProcCheckBoxChange
ParentShowHint = False ParentShowHint = False
@ -46,10 +46,10 @@ inherited PackageEditorForm: TPackageEditorForm
object AddToUsesPkgSectionCheckBox: TCheckBox object AddToUsesPkgSectionCheckBox: TCheckBox
AnchorSideLeft.Control = CallRegisterProcCheckBox AnchorSideLeft.Control = CallRegisterProcCheckBox
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
Left = 168 Left = 219
Height = 19 Height = 22
Top = 0 Top = 0
Width = 191 Width = 248
BorderSpacing.Left = 10 BorderSpacing.Left = 10
Caption = 'AddToUsesPkgSectionCheckBox' Caption = 'AddToUsesPkgSectionCheckBox'
OnChange = AddToUsesPkgSectionCheckBoxChange OnChange = AddToUsesPkgSectionCheckBoxChange
@ -62,9 +62,9 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideTop.Control = MinVersionEdit AnchorSideTop.Control = MinVersionEdit
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 0 Left = 0
Height = 19 Height = 22
Top = 2 Top = 2
Width = 151 Width = 197
Caption = 'UseMinVersionCheckBox' Caption = 'UseMinVersionCheckBox'
OnChange = UseMinVersionCheckBoxChange OnChange = UseMinVersionCheckBoxChange
TabOrder = 2 TabOrder = 2
@ -73,8 +73,8 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideLeft.Control = UseMinVersionCheckBox AnchorSideLeft.Control = UseMinVersionCheckBox
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = FilePropsGroupBox AnchorSideTop.Control = FilePropsGroupBox
Left = 161 Left = 207
Height = 23 Height = 27
Top = 0 Top = 0
Width = 100 Width = 100
BorderSpacing.Left = 10 BorderSpacing.Left = 10
@ -87,9 +87,9 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideTop.Control = MaxVersionEdit AnchorSideTop.Control = MaxVersionEdit
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 0 Left = 0
Height = 19 Height = 22
Top = 27 Top = 31
Width = 152 Width = 201
Caption = 'UseMaxVersionCheckBox' Caption = 'UseMaxVersionCheckBox'
OnChange = UseMaxVersionCheckBoxChange OnChange = UseMaxVersionCheckBoxChange
TabOrder = 4 TabOrder = 4
@ -99,9 +99,9 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = MinVersionEdit AnchorSideTop.Control = MinVersionEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 162 Left = 211
Height = 23 Height = 27
Top = 25 Top = 29
Width = 100 Width = 100
BorderSpacing.Left = 10 BorderSpacing.Left = 10
BorderSpacing.Top = 2 BorderSpacing.Top = 2
@ -114,9 +114,9 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideTop.Control = MaxVersionEdit AnchorSideTop.Control = MaxVersionEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 0 Left = 0
Height = 25 Height = 27
Top = 54 Top = 62
Width = 159 Width = 188
AutoSize = True AutoSize = True
BorderSpacing.Top = 6 BorderSpacing.Top = 6
Caption = 'ApplyDependencyButton' Caption = 'ApplyDependencyButton'
@ -128,19 +128,19 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 0 Left = 0
Height = 60 Height = 60
Top = 40 Top = 37
Width = 573 Width = 569
Align = alBottom Align = alBottom
BorderSpacing.Top = 6 BorderSpacing.Top = 6
Caption = 'RegisteredPluginsGroupBox' Caption = 'RegisteredPluginsGroupBox'
ClientHeight = 42 ClientHeight = 39
ClientWidth = 569 ClientWidth = 561
TabOrder = 7 TabOrder = 7
object RegisteredListBox: TListBox object RegisteredListBox: TListBox
Left = 0 Left = 0
Height = 42 Height = 39
Top = 0 Top = 0
Width = 569 Width = 561
Align = alClient Align = alClient
ItemHeight = 0 ItemHeight = 0
OnDrawItem = RegisteredListBoxDrawItem OnDrawItem = RegisteredListBoxDrawItem
@ -151,8 +151,8 @@ inherited PackageEditorForm: TPackageEditorForm
end end
object StatusBar: TStatusBar[2] object StatusBar: TStatusBar[2]
Left = 0 Left = 0
Height = 23 Height = 22
Top = 427 Top = 428
Width = 577 Width = 577
Panels = <> Panels = <>
end end
@ -160,31 +160,31 @@ inherited PackageEditorForm: TPackageEditorForm
Cursor = crVSplit Cursor = crVSplit
Left = 0 Left = 0
Height = 5 Height = 5
Top = 304 Top = 305
Width = 577 Width = 577
Align = alBottom Align = alBottom
ResizeAnchor = akBottom ResizeAnchor = akBottom
end end
object ItemsPanel: TPanel[4] object ItemsPanel: TPanel[4]
Left = 0 Left = 0
Height = 256 Height = 257
Top = 48 Top = 48
Width = 577 Width = 577
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 256 ClientHeight = 257
ClientWidth = 577 ClientWidth = 577
TabOrder = 4 TabOrder = 4
object FilesTreeView: TTreeView object FilesTreeView: TTreeView
AnchorSideTop.Control = FilterEdit AnchorSideTop.Control = FilterEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 0 Left = 0
Height = 233 Height = 230
Top = 23 Top = 27
Width = 577 Width = 577
Align = alBottom Align = alBottom
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
DefaultItemHeight = 17 DefaultItemHeight = 19
PopupMenu = FilesPopupMenu PopupMenu = FilesPopupMenu
ReadOnly = True ReadOnly = True
TabOrder = 0 TabOrder = 0
@ -200,7 +200,7 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideRight.Control = ItemsPanel AnchorSideRight.Control = ItemsPanel
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 46 Left = 46
Height = 23 Height = 27
Top = 0 Top = 0
Width = 531 Width = 531
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
@ -216,7 +216,7 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideBottom.Control = FilterEdit AnchorSideBottom.Control = FilterEdit
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 0 Left = 0
Height = 23 Height = 27
Top = 0 Top = 0
Width = 23 Width = 23
AllowAllUp = True AllowAllUp = True
@ -235,7 +235,7 @@ inherited PackageEditorForm: TPackageEditorForm
AnchorSideBottom.Control = FilterEdit AnchorSideBottom.Control = FilterEdit
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 23 Left = 23
Height = 23 Height = 27
Top = 0 Top = 0
Width = 23 Width = 23
AllowAllUp = True AllowAllUp = True

View File

@ -282,8 +282,8 @@ type
function CanBeAddedToProject: boolean; function CanBeAddedToProject: boolean;
procedure IdleHandler(Sender: TObject; var Done: Boolean); procedure IdleHandler(Sender: TObject; var Done: Boolean);
function FitsFilter(aFilename: string): boolean; function FitsFilter(aFilename: string): boolean;
procedure FreeTVNodeData(Node: TTreeNode);
function ComparePkgFilenames(AFilename1, AFilename2: string): integer; function ComparePkgFilenames(AFilename1, AFilename2: string): integer;
procedure FreeTVNodeData(Node: TTreeNode);
protected protected
procedure SetLazPackage(const AValue: TLazPackage); override; procedure SetLazPackage(const AValue: TLazPackage); override;
public public
@ -1510,10 +1510,8 @@ begin
ImageIndexDirectory := IDEImages.LoadImage(16, 'pkg_files'); ImageIndexDirectory := IDEImages.LoadImage(16, 'pkg_files');
FilterEdit.Text:=lisCEFilter; FilterEdit.Text:=lisCEFilter;
//SortAlphabeticallySpeedButton.Caption:=dlgAlphabetically;
SortAlphabeticallySpeedButton.Hint:=lisPESortFilesAlphabetically; SortAlphabeticallySpeedButton.Hint:=lisPESortFilesAlphabetically;
SortAlphabeticallySpeedButton.LoadGlyphFromLazarusResource('pkg_sortalphabetically'); SortAlphabeticallySpeedButton.LoadGlyphFromLazarusResource('pkg_sortalphabetically');
//DirectoryHierarchySpeedButton.Caption:=lisPEDirectories;
DirectoryHierarchySpeedButton.Hint:=lisPEShowDirectoryHierarchy; DirectoryHierarchySpeedButton.Hint:=lisPEShowDirectoryHierarchy;
DirectoryHierarchySpeedButton.LoadGlyphFromLazarusResource('pkg_hierarchical'); DirectoryHierarchySpeedButton.LoadGlyphFromLazarusResource('pkg_hierarchical');
@ -1715,82 +1713,6 @@ procedure TPackageEditorForm.UpdateFiles(Immediately: boolean);
ANode.SelectedIndex:=ANode.ImageIndex; ANode.SelectedIndex:=ANode.ImageIndex;
end; end;
procedure DeleteUnneededNodes(TVNodeStack: TFPList; p: integer);
// delete all nodes behind the nodes in the stack, and depth>=p
var
i: Integer;
Node: TTreeNode;
begin
for i:=TVNodeStack.Count-1 downto p do begin
Node:=TTreeNode(TVNodeStack[i]);
while Node.GetNextSibling<>nil do
Node.GetNextSibling.Free;
end;
TVNodeStack.Count:=p;
end;
procedure ClearUnneededAndCreateHierachy(Filename: string; TVNodeStack: TFPList);
// 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 ShowDirectoryHierarchy 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<TVNodeStack.Count then begin
Node:=TTreeNode(TVNodeStack[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
DeleteUnneededNodes(TVNodeStack,p+1);
if Node.GetNextSibling<>nil then begin
Node:=Node.GetNextSibling;
Node.Text:=FilePart;
end
else
Node:=FilesTreeView.Items.Add(Node,FilePart);
TVNodeStack[p]:=Node;
end;
end else begin
// new sub node
if p>0 then
Node:=TTreeNode(TVNodeStack[p-1])
else
Node:=FFilesNode;
if Node.GetFirstChild<>nil then begin
Node:=Node.GetFirstChild;
Node.Text:=FilePart;
end
else
Node:=FilesTreeView.Items.AddChild(Node,FilePart);
TVNodeStack.Add(Node);
end;
if (Filename<>'') then begin
Node.ImageIndex:=ImageIndexDirectory;
Node.SelectedIndex:=Node.ImageIndex;
end;
inc(p);
end;
end;
var var
Cnt: Integer; Cnt: Integer;
i: Integer; i: Integer;
@ -1850,7 +1772,8 @@ begin
for i:=0 to Files.Count-1 do begin for i:=0 to Files.Count-1 do begin
Filename:=Files[i]; Filename:=Files[i];
CurFile:=TPkgFile(Files.Objects[i]); CurFile:=TPkgFile(Files.Objects[i]);
ClearUnneededAndCreateHierachy(Filename,TVNodeStack); TVClearUnneededAndCreateHierachy(FilesTreeView,FFilesNode,Filename,
TVNodeStack,ShowDirectoryHierarchy,ImageIndexDirectory);
CurNode:=TTreeNode(TVNodeStack[TVNodeStack.Count-1]); CurNode:=TTreeNode(TVNodeStack[TVNodeStack.Count-1]);
if FNextSelectedPart<>nil then if FNextSelectedPart<>nil then
CurNode.Selected:=FNextSelectedPart=CurFile; CurNode.Selected:=FNextSelectedPart=CurFile;
@ -1858,7 +1781,7 @@ begin
SetImageIndex(CurNode,CurFile); SetImageIndex(CurNode,CurFile);
CurNode.DeleteChildren; CurNode.DeleteChildren;
end; end;
DeleteUnneededNodes(TVNodeStack,0); TVDeleteUnneededNodes(TVNodeStack,0);
end; end;
// removed files // removed files

View File

@ -895,7 +895,7 @@ begin
if PackageEditors<>nil then if PackageEditors<>nil then
PackageEditors.UpdateAllEditors(false); PackageEditors.UpdateAllEditors(false);
if ProjInspector<>nil then if ProjInspector<>nil then
ProjInspector.UpdateItems; ProjInspector.UpdateItems(false);
DoCallNotifyHandler(pihtGraphChanged,Self); DoCallNotifyHandler(pihtGraphChanged,Self);
end; end;
end; end;