mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-27 02:53:40 +02:00
921 lines
30 KiB
ObjectPascal
921 lines
30 KiB
ObjectPascal
{
|
|
/***************************************************************************
|
|
projectinspector.pas
|
|
--------------------
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
***************************************************************************
|
|
* *
|
|
* This source is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This code is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
* General Public License for more details. *
|
|
* *
|
|
* A copy of the GNU General Public License is available on the World *
|
|
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
|
* obtain it by writing to the Free Software Foundation, *
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
* *
|
|
***************************************************************************
|
|
|
|
Author: Mattias Gaertner
|
|
|
|
Abstract:
|
|
TProjectInspectorForm is the form of the project inspector.
|
|
|
|
ToDo:
|
|
- show lfm/lrs files as sub items
|
|
- dnd move
|
|
- project groups:
|
|
- activate
|
|
popup menu:
|
|
- add
|
|
- remove
|
|
- copy file name
|
|
- save
|
|
- options
|
|
- activate
|
|
- compile
|
|
- build
|
|
- view source
|
|
- close
|
|
- remove project
|
|
- build sooner Ctrl+Up
|
|
- build later Ctrl+Down
|
|
- compile all from here
|
|
- build all from here
|
|
}
|
|
unit ProjectInspector;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, LCLProc, AvgLvlTree, Forms, Controls, Buttons,
|
|
ComCtrls, StdCtrls, Menus, Dialogs, Graphics, FileUtil, ExtCtrls,
|
|
LazIDEIntf, IDECommands,
|
|
LazarusIDEStrConsts, IDEProcs, IDEOptionDefs, EnvironmentOpts,
|
|
Project, AddToProjectDlg, PackageSystem, PackageDefs, TreeFilterEdit;
|
|
|
|
type
|
|
TOnAddUnitToProject =
|
|
function(Sender: TObject; AnUnitInfo: TUnitInfo): TModalresult of object;
|
|
TRemoveProjInspFileEvent =
|
|
function(Sender: TObject; AnUnitInfo: TUnitInfo): TModalResult of object;
|
|
TRemoveProjInspDepEvent = function(Sender: TObject;
|
|
ADependency: TPkgDependency): TModalResult of object;
|
|
TAddProjInspDepEvent = function(Sender: TObject;
|
|
ADependency: TPkgDependency): TModalResult of object;
|
|
|
|
TProjectInspectorFlag = (
|
|
pifAllChanged,
|
|
pifItemsChanged,
|
|
pifFilesChanged,
|
|
pifButtonsChanged,
|
|
pifTitleChanged
|
|
);
|
|
TProjectInspectorFlags = set of TProjectInspectorFlag;
|
|
|
|
{ TProjectInspectorForm }
|
|
|
|
TProjectInspectorForm = class(TForm)
|
|
AddBitBtn: TSpeedButton;
|
|
BtnPanel: TPanel;
|
|
DirectoryHierarchySpeedButton: TSpeedButton;
|
|
FilterEdit: TTreeFilterEdit;
|
|
OpenBitBtn: TSpeedButton;
|
|
ItemsTreeView: TTreeView;
|
|
ItemsPopupMenu: TPopupMenu;
|
|
OptionsBitBtn: TSpeedButton;
|
|
RemoveBitBtn: TSpeedButton;
|
|
SortAlphabeticallySpeedButton: TSpeedButton;
|
|
DummySpeedButton: TSpeedButton;
|
|
procedure AddBitBtnClick(Sender: TObject);
|
|
procedure DirectoryHierarchySpeedButtonClick(Sender: TObject);
|
|
procedure ItemsPopupMenuPopup(Sender: TObject);
|
|
procedure ItemsTreeViewDblClick(Sender: TObject);
|
|
procedure ItemsTreeViewKeyDown(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
procedure ItemsTreeViewSelectionChanged(Sender: TObject);
|
|
procedure MoveDependencyUpClick(Sender: TObject);
|
|
procedure MoveDependencyDownClick(Sender: TObject);
|
|
procedure SetDependencyDefaultFilenameMenuItemClick(Sender: TObject);
|
|
procedure SetDependencyPreferredFilenameMenuItemClick(Sender: TObject);
|
|
procedure ClearDependencyFilenameMenuItemClick(Sender: TObject);
|
|
procedure OpenBitBtnClick(Sender: TObject);
|
|
procedure OptionsBitBtnClick(Sender: TObject);
|
|
procedure ProjectInspectorFormShow(Sender: TObject);
|
|
procedure ReAddMenuItemClick(Sender: TObject);
|
|
procedure RemoveBitBtnClick(Sender: TObject);
|
|
procedure RemoveNonExistingFilesMenuItemClick(Sender: TObject);
|
|
procedure SortAlphabeticallySpeedButtonClick(Sender: TObject);
|
|
procedure ToggleI18NForLFMMenuItemClick(Sender: TObject);
|
|
private
|
|
FIdleConnected: boolean;
|
|
FOnAddDependency: TAddProjInspDepEvent;
|
|
FOnAddUnitToProject: TOnAddUnitToProject;
|
|
FOnOpen: TNotifyEvent;
|
|
FOnReAddDependency: TAddProjInspDepEvent;
|
|
FOnRemoveDependency: TRemoveProjInspDepEvent;
|
|
FOnRemoveFile: TRemoveProjInspFileEvent;
|
|
FOnShowOptions: TNotifyEvent;
|
|
FShowDirectoryHierarchy: boolean;
|
|
FSortAlphabetically: boolean;
|
|
FUpdateLock: integer;
|
|
FLazProject: TProject;
|
|
FFilesNode: TTreeNode;
|
|
FNextSelectedPart: TObject;// select this file/dependency on next update
|
|
DependenciesNode: TTreeNode;
|
|
RemovedDependenciesNode: TTreeNode;
|
|
ImageIndexFiles: integer;
|
|
ImageIndexRequired: integer;
|
|
ImageIndexConflict: integer;
|
|
ImageIndexRemovedRequired: integer;
|
|
ImageIndexProject: integer;
|
|
ImageIndexUnit: integer;
|
|
ImageIndexRegisterUnit: integer;
|
|
ImageIndexText: integer;
|
|
ImageIndexBinary: integer;
|
|
ImageIndexDirectory: integer;
|
|
FFlags: TProjectInspectorFlags;
|
|
procedure SetDependencyDefaultFilename(AsPreferred: boolean);
|
|
procedure SetIdleConnected(const AValue: boolean);
|
|
procedure SetLazProject(const AValue: TProject);
|
|
procedure SetShowDirectoryHierarchy(const AValue: boolean);
|
|
procedure SetSortAlphabetically(const AValue: boolean);
|
|
procedure SetupComponents;
|
|
function ChooseImageIndex(Str: String; Data: TObject; var AIsEnabled: Boolean): Integer;
|
|
procedure UpdateProjectFiles(Immediately: boolean);
|
|
procedure UpdateRequiredPackages;
|
|
procedure UpdateRemovedRequiredPackages;
|
|
procedure OnProjectBeginUpdate(Sender: TObject);
|
|
procedure OnProjectEndUpdate(Sender: TObject; ProjectChanged: boolean);
|
|
protected
|
|
procedure KeyUp(var Key: Word; Shift: TShiftState); override;
|
|
procedure IdleHandler(Sender: TObject; var Done: Boolean);
|
|
public
|
|
constructor Create(TheOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure BeginUpdate;
|
|
procedure EndUpdate;
|
|
function IsUpdateLocked: boolean;
|
|
procedure UpdateAll(Immediately: boolean);
|
|
procedure UpdateTitle;
|
|
procedure UpdateButtons;
|
|
procedure UpdateItems(Immediately: boolean);
|
|
function GetSelectedFile: TUnitInfo;
|
|
function GetSelectedDependency: TPkgDependency;
|
|
public
|
|
property LazProject: TProject read FLazProject write SetLazProject;
|
|
property OnOpen: TNotifyEvent read FOnOpen write FOnOpen;
|
|
property OnShowOptions: TNotifyEvent read FOnShowOptions write FOnShowOptions;
|
|
property OnAddUnitToProject: TOnAddUnitToProject read FOnAddUnitToProject
|
|
write FOnAddUnitToProject;
|
|
property OnAddDependency: TAddProjInspDepEvent
|
|
read FOnAddDependency write FOnAddDependency;
|
|
property OnRemoveFile: TRemoveProjInspFileEvent read FOnRemoveFile
|
|
write FOnRemoveFile;
|
|
property OnRemoveDependency: TRemoveProjInspDepEvent
|
|
read FOnRemoveDependency write FOnRemoveDependency;
|
|
property OnReAddDependency: TAddProjInspDepEvent
|
|
read FOnReAddDependency write FOnReAddDependency;
|
|
property SortAlphabetically: boolean read FSortAlphabetically write SetSortAlphabetically;
|
|
property ShowDirectoryHierarchy: boolean read FShowDirectoryHierarchy write SetShowDirectoryHierarchy;
|
|
property IdleConnected: boolean read FIdleConnected write SetIdleConnected;
|
|
end;
|
|
|
|
var
|
|
ProjInspector: TProjectInspectorForm = nil;
|
|
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
uses
|
|
IDEImagesIntf;
|
|
|
|
|
|
{ TProjectInspectorForm }
|
|
|
|
procedure TProjectInspectorForm.ItemsTreeViewDblClick(Sender: TObject);
|
|
begin
|
|
OpenBitBtnClick(Self);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.ItemsTreeViewKeyDown(Sender: TObject;
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if Key = 27 then
|
|
begin
|
|
Key:=0;
|
|
Close;
|
|
end;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.ItemsTreeViewSelectionChanged(Sender: TObject);
|
|
begin
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.MoveDependencyUpClick(Sender: TObject);
|
|
var
|
|
Dependency: TPkgDependency;
|
|
begin
|
|
Dependency:=GetSelectedDependency;
|
|
if (Dependency=nil) or (Dependency.Removed)
|
|
or (Dependency.PrevRequiresDependency=nil) then exit;
|
|
LazProject.MoveRequiredDependencyUp(Dependency);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.MoveDependencyDownClick(Sender: TObject);
|
|
var
|
|
Dependency: TPkgDependency;
|
|
begin
|
|
Dependency:=GetSelectedDependency;
|
|
if (Dependency=nil) or (Dependency.Removed)
|
|
or (Dependency.NextRequiresDependency=nil) then exit;
|
|
LazProject.MoveRequiredDependencyDown(Dependency);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.SetDependencyDefaultFilenameMenuItemClick(
|
|
Sender: TObject);
|
|
begin
|
|
SetDependencyDefaultFilename(false);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.SetDependencyPreferredFilenameMenuItemClick(
|
|
Sender: TObject);
|
|
begin
|
|
SetDependencyDefaultFilename(true);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.ClearDependencyFilenameMenuItemClick(
|
|
Sender: TObject);
|
|
var
|
|
CurDependency: TPkgDependency;
|
|
begin
|
|
CurDependency:=GetSelectedDependency;
|
|
if (CurDependency=nil) then exit;
|
|
if CurDependency.RequiredPackage=nil then exit;
|
|
if CurDependency.DefaultFilename='' then exit;
|
|
CurDependency.DefaultFilename:='';
|
|
CurDependency.PreferDefaultFilename:=false;
|
|
LazProject.Modified:=true;
|
|
UpdateRequiredPackages;
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.AddBitBtnClick(Sender: TObject);
|
|
var
|
|
AddResult: TAddToProjectResult;
|
|
i: Integer;
|
|
NewFilename: string;
|
|
NewFile: TUnitInfo;
|
|
begin
|
|
if ShowAddToProjectDlg(LazProject,AddResult)<>mrOk then exit;
|
|
|
|
case AddResult.AddType of
|
|
a2pFiles:
|
|
begin
|
|
BeginUpdate;
|
|
for i:=0 to AddResult.FileNames.Count-1 do begin
|
|
NewFilename:=AddResult.FileNames[i];
|
|
NewFile:=LazProject.UnitInfoWithFilename(NewFilename);
|
|
if NewFile<>nil then begin
|
|
if NewFile.IsPartOfProject then continue;
|
|
end else begin
|
|
NewFile:=TUnitInfo.Create(nil);
|
|
NewFile.Filename:=NewFilename;
|
|
LazProject.AddFile(NewFile,false);
|
|
end;
|
|
NewFile.IsPartOfProject:=true;
|
|
if Assigned(OnAddUnitToProject) then begin
|
|
if OnAddUnitToProject(Self,NewFile)<>mrOk then break;
|
|
end;
|
|
FNextSelectedPart:=NewFile;
|
|
end;
|
|
UpdateAll(false);
|
|
EndUpdate;
|
|
end;
|
|
|
|
a2pRequiredPkg:
|
|
begin
|
|
BeginUpdate;
|
|
if Assigned(OnAddDependency) then
|
|
OnAddDependency(Self,AddResult.Dependency);
|
|
FNextSelectedPart:=AddResult.Dependency;
|
|
UpdateItems(false);
|
|
EndUpdate;
|
|
end;
|
|
|
|
end;
|
|
|
|
AddResult.Free;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.DirectoryHierarchySpeedButtonClick(Sender: TObject);
|
|
begin
|
|
ShowDirectoryHierarchy:=DirectoryHierarchySpeedButton.Down;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.ItemsPopupMenuPopup(Sender: TObject);
|
|
var
|
|
ItemCnt: integer;
|
|
|
|
function AddPopupMenuItem(const ACaption: string; AnEvent: TNotifyEvent;
|
|
EnabledFlag: boolean): TMenuItem;
|
|
begin
|
|
if ItemsPopupMenu.Items.Count<=ItemCnt then begin
|
|
Result:=TMenuItem.Create(Self);
|
|
ItemsPopupMenu.Items.Add(Result);
|
|
end else
|
|
Result:=ItemsPopupMenu.Items[ItemCnt];
|
|
Result.Caption:=ACaption;
|
|
Result.OnClick:=AnEvent;
|
|
Result.Enabled:=EnabledFlag;
|
|
Result.Checked:=false;
|
|
Result.ShowAlwaysCheckable:=false;
|
|
Result.Visible:=true;
|
|
Result.RadioItem:=false;
|
|
Result.ImageIndex:=-1;
|
|
inc(ItemCnt);
|
|
end;
|
|
|
|
var
|
|
CurFile: TUnitInfo;
|
|
CurDependency: TPkgDependency;
|
|
Item: TMenuItem;
|
|
begin
|
|
ItemCnt:=0;
|
|
CurFile:=GetSelectedFile;
|
|
if CurFile<>nil then begin
|
|
AddPopupMenuItem(lisOpenFile, @OpenBitBtnClick, true);
|
|
AddPopupMenuItem(lisPckEditRemoveFile, @RemoveBitBtnClick,
|
|
RemoveBitBtn.Enabled);
|
|
if FilenameIsPascalSource(CurFile.Filename) then begin
|
|
Item:=AddPopupMenuItem(lisDisableI18NForLFM,
|
|
@ToggleI18NForLFMMenuItemClick,true);
|
|
Item.Checked:=CurFile.DisableI18NForLFM;
|
|
Item.ShowAlwaysCheckable:=true;
|
|
end;
|
|
end;
|
|
CurDependency:=GetSelectedDependency;
|
|
if CurDependency<>nil then begin
|
|
if CurDependency.Removed then begin
|
|
AddPopupMenuItem(lisMenuOpenPackage, @OpenBitBtnClick, true);
|
|
AddPopupMenuItem(lisPckEditReAddDependency, @ReAddMenuItemClick,
|
|
AddBitBtn.Enabled);
|
|
end else begin
|
|
AddPopupMenuItem(lisMenuOpenPackage, @OpenBitBtnClick, true);
|
|
AddPopupMenuItem(lisPckEditRemoveDependency, @RemoveBitBtnClick,
|
|
RemoveBitBtn.Enabled);
|
|
AddPopupMenuItem(lisPckEditMoveDependencyUp, @MoveDependencyUpClick,
|
|
(CurDependency.PrevRequiresDependency<>nil));
|
|
AddPopupMenuItem(lisPckEditMoveDependencyDown, @MoveDependencyDownClick,
|
|
(CurDependency.NextRequiresDependency<>nil));
|
|
AddPopupMenuItem(lisPckEditStoreFileNameAsDefaultForThisDependency,
|
|
@SetDependencyDefaultFilenameMenuItemClick,
|
|
(CurDependency.RequiredPackage<>nil));
|
|
AddPopupMenuItem(lisPckEditStoreFileNameAsPreferredForThisDependency,
|
|
@SetDependencyPreferredFilenameMenuItemClick,
|
|
(CurDependency.RequiredPackage<>nil));
|
|
AddPopupMenuItem(lisPckEditClearDefaultPreferredFilenameOfDependency,
|
|
@ClearDependencyFilenameMenuItemClick,
|
|
(CurDependency.DefaultFilename<>''));
|
|
end;
|
|
end;
|
|
|
|
AddPopupMenuItem(lisRemoveNonExistingFiles,@RemoveNonExistingFilesMenuItemClick,
|
|
not LazProject.IsVirtual);
|
|
|
|
while ItemsPopupMenu.Items.Count>ItemCnt do
|
|
ItemsPopupMenu.Items.Delete(ItemsPopupMenu.Items.Count-1);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.OpenBitBtnClick(Sender: TObject);
|
|
begin
|
|
if Assigned(OnOpen) then OnOpen(Self);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.OptionsBitBtnClick(Sender: TObject);
|
|
begin
|
|
if Assigned(OnShowOptions) then OnShowOptions(Self);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.ProjectInspectorFormShow(Sender: TObject);
|
|
begin
|
|
UpdateAll(false);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.ReAddMenuItemClick(Sender: TObject);
|
|
var
|
|
Dependency: TPkgDependency;
|
|
begin
|
|
Dependency:=GetSelectedDependency;
|
|
if (Dependency=nil) or (not Dependency.Removed)
|
|
or (not CheckAddingDependency(LazProject,Dependency)) then exit;
|
|
BeginUpdate;
|
|
if Assigned(OnReAddDependency) then OnReAddDependency(Self,Dependency);
|
|
EndUpdate;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.RemoveBitBtnClick(Sender: TObject);
|
|
var
|
|
CurDependency: TPkgDependency;
|
|
CurFile: TUnitInfo;
|
|
begin
|
|
CurDependency:=GetSelectedDependency;
|
|
if (CurDependency<>nil) and (not CurDependency.Removed) then begin
|
|
if MessageDlg(lisProjInspConfirmDeletingDependency,
|
|
Format(lisProjInspDeleteDependencyFor, [CurDependency.AsString]),
|
|
mtConfirmation,[mbYes,mbNo],0)<>mrYes
|
|
then exit;
|
|
if Assigned(OnRemoveDependency) then OnRemoveDependency(Self,CurDependency);
|
|
exit;
|
|
end;
|
|
|
|
CurFile:=GetSelectedFile;
|
|
if CurFile<>nil then begin
|
|
if (not CurFile.IsPartOfProject) or (CurFile=LazProject.MainUnitInfo)
|
|
then exit;
|
|
if MessageDlg(lisProjInspConfirmRemovingFile,
|
|
Format(lisProjInspRemoveFileFromProject, [CurFile.Filename]),
|
|
mtConfirmation,[mbYes,mbNo],0)<>mrYes
|
|
then exit;
|
|
if Assigned(OnRemoveFile) then OnRemoveFile(Self,CurFile);
|
|
end;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.RemoveNonExistingFilesMenuItemClick(Sender: TObject);
|
|
var
|
|
AnUnitInfo: TUnitInfo;
|
|
NextUnitInfo: TUnitInfo;
|
|
HasChanged: Boolean;
|
|
begin
|
|
if LazProject.IsVirtual then exit;
|
|
HasChanged:=false;
|
|
AnUnitInfo:=LazProject.FirstPartOfProject;
|
|
while AnUnitInfo<>nil do begin
|
|
NextUnitInfo:=AnUnitInfo.NextPartOfProject;
|
|
if (not AnUnitInfo.IsVirtual)
|
|
and (not FileExistsUTF8(AnUnitInfo.Filename)) then begin
|
|
AnUnitInfo.IsPartOfProject:=false;
|
|
HasChanged:=true;
|
|
end;
|
|
AnUnitInfo:=NextUnitInfo;
|
|
end;
|
|
if HasChanged then begin
|
|
LazProject.Modified:=true;
|
|
UpdateProjectFiles(false);
|
|
end;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.SortAlphabeticallySpeedButtonClick(Sender: TObject);
|
|
begin
|
|
SortAlphabetically:=SortAlphabeticallySpeedButton.Down;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.ToggleI18NForLFMMenuItemClick(Sender: TObject);
|
|
var
|
|
CurFile: TUnitInfo;
|
|
begin
|
|
CurFile:=GetSelectedFile;
|
|
if CurFile=nil then exit;
|
|
CurFile.DisableI18NForLFM:=not CurFile.DisableI18NForLFM;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.SetLazProject(const AValue: TProject);
|
|
begin
|
|
if FLazProject=AValue then exit;
|
|
if FLazProject<>nil then begin
|
|
dec(FUpdateLock,LazProject.UpdateLock);
|
|
FLazProject.OnBeginUpdate:=nil;
|
|
FLazProject.OnEndUpdate:=nil;
|
|
end;
|
|
FLazProject:=AValue;
|
|
if FLazProject<>nil then begin
|
|
inc(FUpdateLock,LazProject.UpdateLock);
|
|
FLazProject.OnBeginUpdate:=@OnProjectBeginUpdate;
|
|
FLazProject.OnEndUpdate:=@OnProjectEndUpdate;
|
|
end;
|
|
UpdateAll(false);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.SetShowDirectoryHierarchy(const AValue: boolean);
|
|
begin
|
|
if FShowDirectoryHierarchy=AValue then exit;
|
|
FShowDirectoryHierarchy:=AValue;
|
|
DirectoryHierarchySpeedButton.Down:=FShowDirectoryHierarchy;
|
|
FilterEdit.ShowDirHierarchy:=FShowDirectoryHierarchy;
|
|
FilterEdit.InvalidateFilter;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.SetSortAlphabetically(const AValue: boolean);
|
|
begin
|
|
if FSortAlphabetically=AValue then exit;
|
|
FSortAlphabetically:=AValue;
|
|
SortAlphabeticallySpeedButton.Down:=SortAlphabetically;
|
|
FilterEdit.SortData:=SortAlphabetically;
|
|
FilterEdit.InvalidateFilter;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.SetDependencyDefaultFilename(AsPreferred: boolean);
|
|
var
|
|
NewFilename: String;
|
|
CurDependency: TPkgDependency;
|
|
begin
|
|
CurDependency:=GetSelectedDependency;
|
|
if (CurDependency=nil) then exit;
|
|
if CurDependency.RequiredPackage=nil then exit;
|
|
NewFilename:=CurDependency.RequiredPackage.Filename;
|
|
if (NewFilename=CurDependency.DefaultFilename)
|
|
and (CurDependency.PreferDefaultFilename=AsPreferred) then exit;
|
|
CurDependency.DefaultFilename:=NewFilename;
|
|
CurDependency.PreferDefaultFilename:=AsPreferred;
|
|
LazProject.Modified:=true;
|
|
UpdateRequiredPackages;
|
|
UpdateButtons;
|
|
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;
|
|
begin
|
|
ItemsTreeView.Images := IDEImages.Images_16;
|
|
ImageIndexFiles := IDEImages.LoadImage(16, 'pkg_files');
|
|
ImageIndexRequired := IDEImages.LoadImage(16, 'pkg_required');
|
|
ImageIndexConflict := IDEImages.LoadImage(16, 'pkg_conflict');
|
|
ImageIndexRemovedRequired := IDEImages.LoadImage(16, 'pkg_removedrequired');
|
|
ImageIndexProject := IDEImages.LoadImage(16, 'item_project');
|
|
ImageIndexUnit := IDEImages.LoadImage(16, 'item_unit');
|
|
ImageIndexRegisterUnit := IDEImages.LoadImage(16, 'pkg_registerunit');
|
|
ImageIndexText := IDEImages.LoadImage(16, 'pkg_text');
|
|
ImageIndexBinary := IDEImages.LoadImage(16, 'pkg_binary');
|
|
ImageIndexDirectory := IDEImages.LoadImage(16, 'pkg_files');
|
|
|
|
FilterEdit.OnGetImageIndex:=@ChooseImageIndex;
|
|
OpenBitBtn.LoadGlyphFromLazarusResource('laz_open');
|
|
AddBitBtn.LoadGlyphFromLazarusResource('laz_add');
|
|
RemoveBitBtn.LoadGlyphFromLazarusResource('laz_delete');
|
|
OptionsBitBtn.LoadGlyphFromLazarusResource('menu_environment_options');
|
|
|
|
OpenBitBtn.Caption:='';
|
|
AddBitBtn.Caption:='';
|
|
RemoveBitBtn.Caption:='';
|
|
OptionsBitBtn.Caption:='';
|
|
OpenBitBtn.Hint:=lisOpenFile;
|
|
AddBitBtn.Hint:=lisCodeTemplAdd;
|
|
RemoveBitBtn.Hint:=lisExtToolRemove;
|
|
OptionsBitBtn.Hint:=dlgFROpts;
|
|
SortAlphabeticallySpeedButton.Hint:=lisPESortFilesAlphabetically;
|
|
SortAlphabeticallySpeedButton.LoadGlyphFromLazarusResource('pkg_sortalphabetically');
|
|
DirectoryHierarchySpeedButton.Hint:=lisPEShowDirectoryHierarchy;
|
|
DirectoryHierarchySpeedButton.LoadGlyphFromLazarusResource('pkg_hierarchical');
|
|
|
|
with ItemsTreeView do begin
|
|
FFilesNode:=Items.Add(nil, dlgEnvFiles);
|
|
FFilesNode.ImageIndex:=ImageIndexFiles;
|
|
FFilesNode.SelectedIndex:=FFilesNode.ImageIndex;
|
|
DependenciesNode:=Items.Add(nil, lisPckEditRequiredPackages);
|
|
DependenciesNode.ImageIndex:=ImageIndexRequired;
|
|
DependenciesNode.SelectedIndex:=DependenciesNode.ImageIndex;
|
|
end;
|
|
end;
|
|
|
|
function TProjectInspectorForm.ChooseImageIndex(Str: String; Data: TObject;
|
|
var AIsEnabled: Boolean): Integer;
|
|
begin
|
|
if FilenameIsPascalUnit((Data as TUnitInfo).Filename) then
|
|
Result:=ImageIndexUnit
|
|
else if (LazProject<>nil) and (LazProject.MainUnitinfo=Data) then
|
|
Result:=ImageIndexProject
|
|
else
|
|
Result:=ImageIndexText;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.UpdateProjectFiles(Immediately: boolean);
|
|
var
|
|
CurFile: TUnitInfo;
|
|
Filename: String;
|
|
begin
|
|
if (not Immediately) or (FUpdateLock>0) or (not Visible) then begin
|
|
Include(FFlags,pifFilesChanged);
|
|
IdleConnected:=true;
|
|
exit;
|
|
end;
|
|
Exclude(FFlags,pifFilesChanged);
|
|
if LazProject=nil then Exit;
|
|
FilterEdit.RootNode:=FFilesNode;
|
|
FilterEdit.SelectedPart:=FNextSelectedPart;
|
|
FilterEdit.ShowDirHierarchy:=ShowDirectoryHierarchy;
|
|
FilterEdit.SortData:=SortAlphabetically;
|
|
FilterEdit.ImageIndexDirectory:=ImageIndexDirectory;
|
|
FilterEdit.Data.Clear;
|
|
// collect and sort files
|
|
CurFile:=LazProject.FirstPartOfProject;
|
|
while CurFile<>nil do begin
|
|
Filename:=CurFile.GetShortFilename(true);
|
|
if Filename<>'' then begin
|
|
FilterEdit.Data.AddObject(Filename, CurFile);
|
|
FilterEdit.MapShortToFullFilename(Filename, CurFile.Filename);
|
|
end;
|
|
CurFile:=CurFile.NextPartOfProject;
|
|
end;
|
|
FilterEdit.InvalidateFilter; // Data is shown by FilterEdit.
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.UpdateRequiredPackages;
|
|
var
|
|
Dependency: TPkgDependency;
|
|
NodeText, AFilename: String;
|
|
CurNode: TTreeNode;
|
|
NextNode: TTreeNode;
|
|
begin
|
|
ItemsTreeView.BeginUpdate;
|
|
if LazProject<>nil then begin
|
|
Dependency:=LazProject.FirstRequiredDependency;
|
|
CurNode:=DependenciesNode.GetFirstChild;
|
|
while Dependency<>nil do begin
|
|
NodeText:=Dependency.AsString;
|
|
if Dependency.DefaultFilename<>'' then begin
|
|
AFilename:=Dependency.MakeFilenameRelativeToOwner(Dependency.DefaultFilename);
|
|
if Dependency.PreferDefaultFilename then
|
|
NodeText:=Format(lisCEIn, [NodeText,AFilename]) // like the 'in' keyword in the uses section
|
|
else
|
|
NodeText:=Format(lisPckEditDefault, [NodeText, AFilename]);
|
|
end;
|
|
if CurNode=nil then
|
|
CurNode:=ItemsTreeView.Items.AddChild(DependenciesNode,NodeText)
|
|
else
|
|
CurNode.Text:=NodeText;
|
|
if Dependency.LoadPackageResult=lprSuccess then
|
|
CurNode.ImageIndex:=ImageIndexRequired
|
|
else
|
|
CurNode.ImageIndex:=ImageIndexConflict;
|
|
CurNode.SelectedIndex:=CurNode.ImageIndex;
|
|
Dependency:=Dependency.NextRequiresDependency;
|
|
CurNode:=CurNode.GetNextSibling;
|
|
end;
|
|
while CurNode<>nil do begin
|
|
NextNode:=CurNode.GetNextSibling;
|
|
CurNode.Free;
|
|
CurNode:=NextNode;
|
|
end;
|
|
DependenciesNode.Expanded:=true;
|
|
end else begin
|
|
// delete dependency nodes
|
|
DependenciesNode.HasChildren:=false;
|
|
end;
|
|
ItemsTreeView.EndUpdate;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.UpdateRemovedRequiredPackages;
|
|
var
|
|
Dependency: TPkgDependency;
|
|
NodeText: String;
|
|
CurNode: TTreeNode;
|
|
NextNode: TTreeNode;
|
|
begin
|
|
ItemsTreeView.BeginUpdate;
|
|
if (LazProject<>nil) and (LazProject.FirstRemovedDependency<>nil) then begin
|
|
Dependency:=LazProject.FirstRemovedDependency;
|
|
if RemovedDependenciesNode=nil then begin
|
|
RemovedDependenciesNode:=ItemsTreeView.Items.Add(DependenciesNode,
|
|
lisProjInspRemovedRequiredPackages);
|
|
RemovedDependenciesNode.ImageIndex:=ImageIndexRemovedRequired;
|
|
RemovedDependenciesNode.SelectedIndex:=RemovedDependenciesNode.ImageIndex;
|
|
end;
|
|
CurNode:=RemovedDependenciesNode.GetFirstChild;
|
|
while Dependency<>nil do begin
|
|
NodeText:=Dependency.AsString;
|
|
if CurNode=nil then
|
|
CurNode:=ItemsTreeView.Items.AddChild(RemovedDependenciesNode,NodeText)
|
|
else
|
|
CurNode.Text:=NodeText;
|
|
CurNode.ImageIndex:=RemovedDependenciesNode.ImageIndex;
|
|
CurNode.SelectedIndex:=CurNode.ImageIndex;
|
|
Dependency:=Dependency.NextRequiresDependency;
|
|
CurNode:=CurNode.GetNextSibling;
|
|
end;
|
|
while CurNode<>nil do begin
|
|
NextNode:=CurNode.GetNextSibling;
|
|
CurNode.Free;
|
|
CurNode:=NextNode;
|
|
end;
|
|
RemovedDependenciesNode.Expanded:=true;
|
|
end else begin
|
|
// delete removed dependency nodes
|
|
if RemovedDependenciesNode<>nil then
|
|
FreeThenNil(RemovedDependenciesNode);
|
|
end;
|
|
ItemsTreeView.EndUpdate;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.OnProjectBeginUpdate(Sender: TObject);
|
|
begin
|
|
BeginUpdate;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.OnProjectEndUpdate(Sender: TObject;
|
|
ProjectChanged: boolean);
|
|
begin
|
|
UpdateAll(false);
|
|
EndUpdate;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.KeyUp(var Key: Word; Shift: TShiftState);
|
|
begin
|
|
inherited KeyDown(Key, Shift);
|
|
ExecuteIDEShortCut(Self,Key,Shift,nil);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.IdleHandler(Sender: TObject; var Done: Boolean);
|
|
begin
|
|
if (not Visible) or (FUpdateLock>0) then begin
|
|
IdleConnected:=false;
|
|
exit;
|
|
end;
|
|
if pifAllChanged in FFlags then
|
|
UpdateAll(true)
|
|
else if pifItemsChanged in FFlags then
|
|
UpdateItems(true)
|
|
else if pifFilesChanged in FFlags then
|
|
UpdateProjectFiles(true)
|
|
else if pifTitleChanged in FFlags then
|
|
UpdateTitle
|
|
else if pifButtonsChanged in FFlags then
|
|
UpdateButtons
|
|
else
|
|
IdleConnected:=false;
|
|
end;
|
|
|
|
function TProjectInspectorForm.GetSelectedFile: TUnitInfo;
|
|
var
|
|
CurNode: TTreeNode;
|
|
Item: TFileNameItem;
|
|
begin
|
|
Result:=nil;
|
|
if LazProject=nil then exit;
|
|
CurNode:=ItemsTreeView.Selected;
|
|
if (CurNode=nil) then exit;
|
|
//debugln(['TProjectInspectorForm.GetCurrentFile ',DbgSName(TObject(CurNode.Data)),' ',CurNode.Text]);
|
|
if TObject(CurNode.Data) is TFileNameItem then
|
|
begin
|
|
Item:=TFileNameItem(CurNode.Data);
|
|
//debugln(['TProjectInspectorForm.GetCurrentFile Item=',Item.Filename,' ',Item.IsDirectory]);
|
|
Result:=LazProject.UnitInfoWithFilename(Item.Filename);
|
|
end;
|
|
end;
|
|
|
|
function TProjectInspectorForm.GetSelectedDependency: TPkgDependency;
|
|
var
|
|
CurNode: TTreeNode;
|
|
NodeIndex: Integer;
|
|
begin
|
|
Result:=nil;
|
|
if LazProject=nil then exit;
|
|
CurNode:=ItemsTreeView.Selected;
|
|
if (CurNode=nil) then exit;
|
|
NodeIndex:=CurNode.Index;
|
|
if (CurNode.Parent=DependenciesNode) then begin
|
|
Result:=GetDependencyWithIndex(LazProject.FirstRequiredDependency,
|
|
pdlRequires,NodeIndex);
|
|
end;
|
|
if (CurNode.Parent=RemovedDependenciesNode) then begin
|
|
Result:=GetDependencyWithIndex(LazProject.FirstRemovedDependency,
|
|
pdlRequires,NodeIndex);
|
|
end;
|
|
end;
|
|
|
|
constructor TProjectInspectorForm.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
Name:=NonModalIDEWindowNames[nmiwProjectInspector];
|
|
Caption:=lisMenuProjectInspector;
|
|
KeyPreview:=true;
|
|
|
|
SetupComponents;
|
|
KeyPreview:=true;
|
|
end;
|
|
|
|
destructor TProjectInspectorForm.Destroy;
|
|
begin
|
|
IdleConnected:=false;
|
|
LazProject:=nil;
|
|
inherited Destroy;
|
|
if ProjInspector=Self then
|
|
ProjInspector:=nil;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.BeginUpdate;
|
|
begin
|
|
inc(FUpdateLock);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.EndUpdate;
|
|
begin
|
|
if FUpdateLock=0 then RaiseException('TProjectInspectorForm.EndUpdate');
|
|
dec(FUpdateLock);
|
|
end;
|
|
|
|
function TProjectInspectorForm.IsUpdateLocked: boolean;
|
|
begin
|
|
Result:=FUpdateLock>0;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.UpdateAll(Immediately: boolean);
|
|
begin
|
|
if (FUpdateLock>0) or (not Visible) then begin
|
|
Include(FFlags,pifAllChanged);
|
|
IdleConnected:=true;
|
|
exit;
|
|
end;
|
|
Exclude(FFlags,pifAllChanged);
|
|
UpdateTitle;
|
|
UpdateButtons;
|
|
UpdateItems(true);
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.UpdateTitle;
|
|
var
|
|
NewCaption: String;
|
|
begin
|
|
if (FUpdateLock>0) or (not Visible) then begin
|
|
Include(FFlags,pifTitleChanged);
|
|
IdleConnected:=true;
|
|
exit;
|
|
end;
|
|
Exclude(FFlags,pifTitleChanged);
|
|
if LazProject=nil then
|
|
Caption:=lisMenuProjectInspector
|
|
else begin
|
|
NewCaption:=LazProject.Title;
|
|
if NewCaption='' then
|
|
NewCaption:=ExtractFilenameOnly(LazProject.ProjectInfoFile);
|
|
Caption:=Format(lisProjInspProjectInspector, [NewCaption]);
|
|
end;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.UpdateButtons;
|
|
var
|
|
CurFile: TUnitInfo;
|
|
CurDependency: TPkgDependency;
|
|
begin
|
|
if (FUpdateLock>0) or (not Visible) then begin
|
|
Include(FFlags,pifButtonsChanged);
|
|
IdleConnected:=true;
|
|
exit;
|
|
end;
|
|
Exclude(FFlags,pifButtonsChanged);
|
|
if LazProject<>nil then begin
|
|
AddBitBtn.Enabled:=true;
|
|
CurFile:=GetSelectedFile;
|
|
CurDependency:=GetSelectedDependency;
|
|
RemoveBitBtn.Enabled:=((CurFile<>nil) and (CurFile<>LazProject.MainUnitInfo))
|
|
or ((CurDependency<>nil) and (not CurDependency.Removed));
|
|
OpenBitBtn.Enabled:=((CurFile<>nil)
|
|
or ((CurDependency<>nil) and (not CurDependency.Removed)));
|
|
OptionsBitBtn.Enabled:=true;
|
|
end else begin
|
|
AddBitBtn.Enabled:=false;
|
|
RemoveBitBtn.Enabled:=false;
|
|
OpenBitBtn.Enabled:=false;
|
|
OptionsBitBtn.Enabled:=false;
|
|
end;
|
|
end;
|
|
|
|
procedure TProjectInspectorForm.UpdateItems(Immediately: boolean);
|
|
begin
|
|
if (FUpdateLock>0) or (not Visible) then begin
|
|
Include(FFlags,pifItemsChanged);
|
|
IdleConnected:=true;
|
|
exit;
|
|
end;
|
|
Exclude(FFlags,pifItemsChanged);
|
|
ItemsTreeView.BeginUpdate;
|
|
UpdateProjectFiles(true);
|
|
UpdateRequiredPackages;
|
|
UpdateRemovedRequiredPackages;
|
|
ItemsTreeView.EndUpdate;
|
|
end;
|
|
|
|
end.
|
|
|