IDE: Refactoring and optimization of UseProjUnit dialog.

git-svn-id: trunk@31443 -
This commit is contained in:
juha 2011-06-29 00:04:44 +00:00
parent b17df7eb9e
commit e9d3046acb
2 changed files with 124 additions and 139 deletions

View File

@ -1,12 +1,12 @@
object UseUnitDialog: TUseUnitDialog object UseUnitDialog: TUseUnitDialog
Left = 315 Left = 315
Height = 346 Height = 422
Top = 177 Top = 177
Width = 276 Width = 344
BorderIcons = [biSystemMenu, biMaximize] BorderIcons = [biSystemMenu, biMaximize]
Caption = 'Add unit to uses section' Caption = 'Add unit to uses section'
ClientHeight = 346 ClientHeight = 422
ClientWidth = 276 ClientWidth = 344
Constraints.MinHeight = 150 Constraints.MinHeight = 150
Constraints.MinWidth = 200 Constraints.MinWidth = 200
OnCreate = FormCreate OnCreate = FormCreate
@ -15,9 +15,9 @@ object UseUnitDialog: TUseUnitDialog
LCLVersion = '0.9.31' LCLVersion = '0.9.31'
object ButtonPanel1: TButtonPanel object ButtonPanel1: TButtonPanel
Left = 6 Left = 6
Height = 26 Height = 32
Top = 314 Top = 384
Width = 264 Width = 332
OKButton.Name = 'OKButton' OKButton.Name = 'OKButton'
OKButton.Caption = '&OK' OKButton.Caption = '&OK'
HelpButton.Name = 'HelpButton' HelpButton.Name = 'HelpButton'
@ -41,8 +41,8 @@ object UseUnitDialog: TUseUnitDialog
AnchorSideBottom.Control = ButtonPanel1 AnchorSideBottom.Control = ButtonPanel1
Left = 6 Left = 6
Height = 49 Height = 49
Top = 259 Top = 329
Width = 264 Width = 332
Anchors = [akLeft, akRight, akBottom] Anchors = [akLeft, akRight, akBottom]
AutoFill = True AutoFill = True
BorderSpacing.Top = 3 BorderSpacing.Top = 3
@ -56,8 +56,8 @@ object UseUnitDialog: TUseUnitDialog
ChildSizing.ShrinkVertical = crsScaleChilds ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 2 ChildSizing.ControlsPerLine = 2
ClientHeight = 31 ClientHeight = 32
ClientWidth = 260 ClientWidth = 328
Columns = 2 Columns = 2
ItemIndex = 1 ItemIndex = 1
Items.Strings = ( Items.Strings = (
@ -73,9 +73,9 @@ object UseUnitDialog: TUseUnitDialog
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = AllUnitsCheckBox AnchorSideBottom.Control = AllUnitsCheckBox
Left = 6 Left = 6
Height = 198 Height = 267
Top = 32 Top = 32
Width = 264 Width = 332
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Around = 6 BorderSpacing.Around = 6
ItemHeight = 0 ItemHeight = 0
@ -91,9 +91,9 @@ object UseUnitDialog: TUseUnitDialog
AnchorSideRight.Control = Owner AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 6 Left = 6
Height = 21 Height = 20
Top = 6 Top = 6
Width = 264 Width = 332
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Around = 6 BorderSpacing.Around = 6
OnKeyDown = UnitnameEditKeyDown OnKeyDown = UnitnameEditKeyDown
@ -104,9 +104,9 @@ object UseUnitDialog: TUseUnitDialog
AnchorSideLeft.Control = Owner AnchorSideLeft.Control = Owner
AnchorSideBottom.Control = SectionRadioGroup AnchorSideBottom.Control = SectionRadioGroup
Left = 12 Left = 12
Height = 17 Height = 18
Top = 236 Top = 305
Width = 85 Width = 104
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
BorderSpacing.Left = 6 BorderSpacing.Left = 6
BorderSpacing.Around = 6 BorderSpacing.Around = 6

View File

@ -21,6 +21,7 @@
Original version by Juha Manninen Original version by Juha Manninen
Icons added by Marcelo B Paula Icons added by Marcelo B Paula
All available units added to the list by Anton
} }
unit UseProjUnitDlg; unit UseProjUnitDlg;
@ -30,9 +31,9 @@ interface
uses uses
Classes, SysUtils, Forms, Controls, ComCtrls, StdCtrls, ExtCtrls, Buttons, Classes, SysUtils, Forms, Controls, ComCtrls, StdCtrls, ExtCtrls, Buttons,
ButtonPanel, Dialogs, LCLProc, FileProcs, Graphics, LCLType, ButtonPanel, Dialogs, LCLProc, FileProcs, Graphics, LCLType, EditBtn, StrUtils,
SourceEditor, LazIDEIntf, IDEImagesIntf, LazarusIDEStrConsts, SourceEditor, LazIDEIntf, IDEImagesIntf, LazarusIDEStrConsts, ProjectIntf,
ProjectIntf, Project, CodeCache, CodeToolManager, IdentCompletionTool; Project, CodeCache, CodeToolManager, IdentCompletionTool, ListFilterEdit;
type type
@ -56,10 +57,14 @@ type
ARect: TRect; State: TOwnerDrawState); ARect: TRect; State: TOwnerDrawState);
private private
UnitImgInd: Integer; UnitImgInd: Integer;
FMainUsedUnits: TStrings;
FImplUsedUnits: TStrings;
FProjUnits: TStringList;
FOtherUnits: TStringList; FOtherUnits: TStringList;
procedure AddItems(AItems: TStrings); procedure AddItems(AItems: TStrings);
procedure AddOtherUnits; procedure AddOtherUnits;
procedure RemoveOtherUnits; procedure RemoveOtherUnits;
function GetAvailableProjUnits(SrcEdit: TSourceEditor): TModalResult;
procedure CreateOtherUnitsList; procedure CreateOtherUnitsList;
function SelectedUnit: string; function SelectedUnit: string;
function InterfaceSelected: Boolean; function InterfaceSelected: Boolean;
@ -71,14 +76,10 @@ type
end; end;
function GetProjAvailableUnits(SrcEdit: TSourceEditor; out CurrentUnitName: String;
IgnoreErrors: boolean): TStringList;
function ShowUseUnitDialog: TModalResult; function ShowUseUnitDialog: TModalResult;
implementation implementation
uses StrUtils, math;
{$R *.lfm} {$R *.lfm}
type type
@ -104,91 +105,30 @@ begin
Result := f.IdentItem.Identifier; Result := f.IdentItem.Identifier;
end; end;
function GetProjAvailableUnits(SrcEdit: TSourceEditor; out CurrentUnitName: String;
IgnoreErrors: boolean): TStringList;
var
MainUsedUnits, ImplUsedUnits: TStrings;
ProjFile: TUnitInfo;
s: String;
begin
MainUsedUnits:=nil;
ImplUsedUnits:=nil;
Result:=nil;
try
if SrcEdit=nil then exit;
Assert(Assigned(SrcEdit.CodeBuffer));
if not CodeToolBoss.FindUsedUnitNames(SrcEdit.CodeBuffer,
MainUsedUnits,ImplUsedUnits)
then begin
if not IgnoreErrors then
begin
DebugLn(['ShowUseProjUnitDialog CodeToolBoss.FindUsedUnitNames failed']);
LazarusIDE.DoJumpToCodeToolBossError;
end;
exit;
end;
Result:=TStringList.Create; // Result TStringList must be freed by caller.
TStringList(MainUsedUnits).CaseSensitive:=False;
TStringList(ImplUsedUnits).CaseSensitive:=False;
// Debug message will be cleaned soon!!!
if SrcEdit.GetProjectFile is TUnitInfo then
CurrentUnitName:=TUnitInfo(SrcEdit.GetProjectFile).Unit_Name
else
CurrentUnitName:='';
//DebugLn('ShowUseProjUnitDialog: CurrentUnitName before loop = '+CurrentUnitName);
// Add available unit names to Result.
ProjFile:=Project1.FirstPartOfProject;
while ProjFile<>nil do begin
s:=ProjFile.Unit_Name;
if s=CurrentUnitName then begin // current unit
{if SrcEdit.GetProjectFile is TUnitInfo then // Debug!
DebugLn('ShowUseProjUnitDialog: CurrentUnitName in loop = ' +
TUnitInfo(SrcEdit.GetProjectFile).Unit_Name);}
s:='';
end;
if (ProjFile<>Project1.MainUnitInfo) and (s<>'') then
if (MainUsedUnits.IndexOf(s)<0) and (ImplUsedUnits.IndexOf(s)<0) then
Result.Add(s);
ProjFile:=ProjFile.NextPartOfProject;
end;
finally
ImplUsedUnits.Free;
MainUsedUnits.Free;
end;
end;
function ShowUseUnitDialog: TModalResult; function ShowUseUnitDialog: TModalResult;
var var
UseProjUnitDlg: TUseUnitDialog; UseProjUnitDlg: TUseUnitDialog;
SrcEdit: TSourceEditor; SrcEdit: TSourceEditor;
AvailUnits: TStringList; s: String;
CurrentUnitName, s: String;
CTRes: Boolean; CTRes: Boolean;
begin begin
Result:=mrOk; Result:=mrOk;
if not LazarusIDE.BeginCodeTools then exit; if not LazarusIDE.BeginCodeTools then exit;
// get cursor position // get cursor position
SrcEdit:=SourceEditorManager.ActiveEditor; SrcEdit:=SourceEditorManager.ActiveEditor;
try
AvailUnits:=GetProjAvailableUnits(SrcEdit, CurrentUnitName, false);
// Show the dialog.
AvailUnits.Sorted:=True;
UseProjUnitDlg:=TUseUnitDialog.Create(nil); UseProjUnitDlg:=TUseUnitDialog.Create(nil);
try try
if Assigned(AvailUnits) then UseProjUnitDlg.AddItems(AvailUnits); Result:=UseProjUnitDlg.GetAvailableProjUnits(SrcEdit);
if UseProjUnitDlg.UnitsListBox.Count = 0 then if Result<>mrOK then exit;
begin
UseProjUnitDlg.AllUnitsCheckBox.Checked := True;
if UseProjUnitDlg.UnitsListBox.Count = 0 then Exit(mrCancel);
end;
// there is only main uses section in program/library/package // there is only main uses section in program/library/package
if SrcEdit.GetProjectFile=Project1.MainUnitInfo then if SrcEdit.GetProjectFile=Project1.MainUnitInfo then
UseProjUnitDlg.EnableOnlyInterface; UseProjUnitDlg.EnableOnlyInterface;
// Show the dialog.
if UseProjUnitDlg.ShowModal=mrOk then begin if UseProjUnitDlg.ShowModal=mrOk then begin
s:=UseProjUnitDlg.SelectedUnit; s:=UseProjUnitDlg.SelectedUnit;
if s <> '' then begin if s <> '' then begin
if not UseProjUnitDlg.UnitExists(s) and if not UseProjUnitDlg.UnitExists(s) and
(MessageDlg(Format('Unit "%s" seems not to be exist. Do you still want to add it?', [s]), (MessageDlg(Format('Unit "%s" seems not to exist. Do you still want to add it?', [s]),
mtConfirmation, mbYesNo, 0) = mrNo) then Exit(mrCancel); mtConfirmation, mbYesNo, 0) = mrNo) then Exit(mrCancel);
if UseProjUnitDlg.InterfaceSelected then if UseProjUnitDlg.InterfaceSelected then
CTRes:=CodeToolBoss.AddUnitToMainUsesSection(SrcEdit.CodeBuffer, s, '') CTRes:=CodeToolBoss.AddUnitToMainUsesSection(SrcEdit.CodeBuffer, s, '')
@ -202,10 +142,7 @@ begin
end; end;
finally finally
UseProjUnitDlg.Free; UseProjUnitDlg.Free;
end;
finally
CodeToolBoss.SourceCache.ClearAllSourceLogEntries; CodeToolBoss.SourceCache.ClearAllSourceLogEntries;
AvailUnits.Free;
end; end;
end; end;
@ -233,6 +170,20 @@ begin
ButtonPanel1.OKButton.Caption:=lisOk; ButtonPanel1.OKButton.Caption:=lisOk;
ButtonPanel1.CancelButton.Caption:=dlgCancel; ButtonPanel1.CancelButton.Caption:=dlgCancel;
UnitImgInd := IDEImages.LoadImage(16, 'item_unit'); UnitImgInd := IDEImages.LoadImage(16, 'item_unit');
FProjUnits:=TStringList.Create;
end;
procedure TUseUnitDialog.FormDestroy(Sender: TObject);
var
i: Integer;
begin
if Assigned(FOtherUnits) then
for i := 0 to FOtherUnits.Count - 1 do
FOtherUnits.Objects[i].Free;
FOtherUnits.Free;
FProjUnits.Free;
FImplUsedUnits.Free;
FMainUsedUnits.Free;
end; end;
procedure TUseUnitDialog.AllUnitsCheckBoxChange(Sender: TObject); procedure TUseUnitDialog.AllUnitsCheckBoxChange(Sender: TObject);
@ -244,15 +195,6 @@ begin
if Visible then UnitnameEdit.SetFocus; if Visible then UnitnameEdit.SetFocus;
end; end;
procedure TUseUnitDialog.FormDestroy(Sender: TObject);
var i: Integer;
begin
if Assigned(FOtherUnits) then
for i := 0 to FOtherUnits.Count - 1 do
FOtherUnits.Objects[i].Free;
FOtherUnits.Free;
end;
procedure TUseUnitDialog.UnitnameEditKeyDown(Sender: TObject; var Key: Word; procedure TUseUnitDialog.UnitnameEditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState); Shift: TShiftState);
begin begin
@ -328,12 +270,13 @@ end;
procedure TUseUnitDialog.AddOtherUnits; procedure TUseUnitDialog.AddOtherUnits;
begin begin
if not Assigned(FOtherUnits) then CreateOtherUnitsList; CreateOtherUnitsList;
UnitsListBox.Items.AddStrings(FOtherUnits); UnitsListBox.Items.AddStrings(FOtherUnits);
end; end;
procedure TUseUnitDialog.RemoveOtherUnits; procedure TUseUnitDialog.RemoveOtherUnits;
var i: Integer; var
i: Integer;
begin begin
with UnitsListBox.Items do with UnitsListBox.Items do
begin begin
@ -347,36 +290,78 @@ begin
end; end;
end; end;
function TUseUnitDialog.GetAvailableProjUnits(SrcEdit: TSourceEditor): TModalResult;
var
ProjFile: TUnitInfo;
CurrentUnitName, s: String;
begin
Result:=mrOk;
FMainUsedUnits:=nil;
FImplUsedUnits:=nil;
if SrcEdit=nil then exit;
Assert(Assigned(SrcEdit.CodeBuffer));
if not CodeToolBoss.FindUsedUnitNames(SrcEdit.CodeBuffer,
FMainUsedUnits,FImplUsedUnits)
then begin
DebugLn(['ShowUseProjUnitDialog CodeToolBoss.FindUsedUnitNames failed']);
LazarusIDE.DoJumpToCodeToolBossError;
exit(mrCancel);
end;
TStringList(FMainUsedUnits).CaseSensitive:=False;
TStringList(FImplUsedUnits).CaseSensitive:=False;
if SrcEdit.GetProjectFile is TUnitInfo then
CurrentUnitName:=TUnitInfo(SrcEdit.GetProjectFile).Unit_Name
else
CurrentUnitName:='';
// Add available unit names to FProjUnits.
ProjFile:=Project1.FirstPartOfProject;
while ProjFile<>nil do begin
s:=ProjFile.Unit_Name;
if s=CurrentUnitName then // current unit
s:='';
if (ProjFile<>Project1.MainUnitInfo) and (s<>'') then
if (FMainUsedUnits.IndexOf(s) < 0) and (FImplUsedUnits.IndexOf(s) < 0) then
FProjUnits.Add(s);
ProjFile:=ProjFile.NextPartOfProject;
end;
FProjUnits.Sorted:=True;
if Assigned(FProjUnits) then
AddItems(FProjUnits);
if UnitsListBox.Count = 0 then
begin
AllUnitsCheckBox.Checked := True;
if UnitsListBox.Count = 0 then Exit(mrCancel);
end;
end;
procedure TUseUnitDialog.CreateOtherUnitsList; procedure TUseUnitDialog.CreateOtherUnitsList;
var var
i: Integer; curUnit: string; i: Integer; curUnit: string;
SrcEdit: TSourceEditor; SrcEdit: TSourceEditor;
MainUsedUnits, ImplUsedUnits: TStrings;
begin begin
if Assigned(FOtherUnits) then Exit; if Assigned(FOtherUnits) then Exit;
Screen.Cursor:=crHourGlass;
try
FOtherUnits := TStringList.Create; FOtherUnits := TStringList.Create;
SrcEdit := SourceEditorManager.ActiveEditor; SrcEdit := SourceEditorManager.ActiveEditor;
MainUsedUnits := nil; ImplUsedUnits := nil; with CodeToolBoss do
CodeToolBoss.FindUsedUnitNames(SrcEdit.CodeBuffer, MainUsedUnits, ImplUsedUnits); if GatherUnitNames(SrcEdit.CodeBuffer) then
try
if CodeToolBoss.GatherUnitNames(SrcEdit.CodeBuffer) then
with CodeToolBoss.IdentifierList, FOtherUnits do
begin begin
Prefix := ''; IdentifierList.Prefix := '';
for i := 0 to GetFilteredCount - 1 do Assert(Assigned(FMainUsedUnits) and Assigned(FImplUsedUnits));
for i := 0 to IdentifierList.GetFilteredCount - 1 do
begin begin
curUnit := FilteredItems[i].Identifier; curUnit := IdentifierList.FilteredItems[i].Identifier;
if (MainUsedUnits.IndexOf(curUnit) < 0) if (FMainUsedUnits.IndexOf(curUnit) < 0)
and (ImplUsedUnits.IndexOf(curUnit) < 0) and (FImplUsedUnits.IndexOf(curUnit) < 0)
and (IndexOf(curUnit) < 0) then and (FOtherUnits.IndexOf(curUnit) < 0) then
AddObject(FilteredItems[i].Identifier, FOtherUnits.AddObject(IdentifierList.FilteredItems[i].Identifier,
TUnitsListBoxObject.Create(CodeToolBoss.IdentifierList, FilteredItems[i])); TUnitsListBoxObject.Create(IdentifierList, IdentifierList.FilteredItems[i]));
end; end;
end; end;
FOtherUnits.Sort; FOtherUnits.Sort;
finally finally
MainUsedUnits.Free; Screen.Cursor:=crDefault;
ImplUsedUnits.Free;
end; end;
end; end;
@ -446,7 +431,7 @@ begin
if Result then Exit; if Result then Exit;
if not AllUnitsCheckBox.Checked then if not AllUnitsCheckBox.Checked then
begin begin
if not Assigned(FOtherUnits) then CreateOtherUnitsList; CreateOtherUnitsList;
Result := FOtherUnits.IndexOf(AUnitName) >= 0; Result := FOtherUnits.IndexOf(AUnitName) >= 0;
end; end;
end; end;