From 561a94889fa9e9d127620b2c73399fd99a062847 Mon Sep 17 00:00:00 2001 From: mattias Date: Mon, 14 Nov 2011 17:20:51 +0000 Subject: [PATCH] IDE: added file filter options page git-svn-id: trunk@33530 - --- .gitattributes | 2 + ide/environmentopts.pp | 6 + ide/frames/env_file_filters.lfm | 56 ++++++++ ide/frames/env_file_filters.pas | 226 ++++++++++++++++++++++++++++++++ ide/lazarus.lpi | 9 +- ide/lazarusidestrconsts.pas | 9 ++ ide/main.pp | 68 +++++----- ideintf/ideoptionsintf.pas | 17 +-- lcl/include/filedialog.inc | 3 +- 9 files changed, 356 insertions(+), 40 deletions(-) create mode 100644 ide/frames/env_file_filters.lfm create mode 100644 ide/frames/env_file_filters.pas diff --git a/.gitattributes b/.gitattributes index 089aff86c6..980e91788b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4116,6 +4116,8 @@ ide/frames/editor_mouseaction_options_advanced.lfm svneol=native#text/plain ide/frames/editor_mouseaction_options_advanced.pas svneol=native#text/pascal ide/frames/editor_multiwindow_options.lfm svneol=native#text/plain ide/frames/editor_multiwindow_options.pas svneol=native#text/pascal +ide/frames/env_file_filters.lfm svneol=native#text/plain +ide/frames/env_file_filters.pas svneol=native#text/plain ide/frames/files_options.lfm svneol=native#text/plain ide/frames/files_options.pas svneol=native#text/pascal ide/frames/formed_options.lfm svneol=native#text/plain diff --git a/ide/environmentopts.pp b/ide/environmentopts.pp index 08ff55d151..c549001c32 100644 --- a/ide/environmentopts.pp +++ b/ide/environmentopts.pp @@ -314,6 +314,7 @@ type // 'new items' FNewFormTemplate: string; FNewUnitTemplate: string; + FFileFilters: TStringList; function GetDebuggerEventLogColors(AIndex: TDBGEventType): TDebuggerEventLogColor; procedure SetCompilerFilename(const AValue: string); @@ -571,6 +572,8 @@ type // default template for each 'new item' category: Name=Path, Value=TemplateName property NewUnitTemplate: string read FNewUnitTemplate write FNewUnitTemplate; property NewFormTemplate: string read FNewFormTemplate write FNewFormTemplate; + + property FileFilters: TStringList read FFileFilters write FFileFilters; end; var @@ -833,12 +836,15 @@ begin // lazdoc FLazDocPaths:=SetDirSeparators(DefaultLazDocPath); + + FFileFilters := TStringList.Create; end; destructor TEnvironmentOptions.Destroy; var i: Integer; begin + FreeAndNil(FFileFilters); FreeAndNil(fExternalTools); FreeAndNil(FRecentOpenFiles); FreeAndNil(FRecentProjectFiles); diff --git a/ide/frames/env_file_filters.lfm b/ide/frames/env_file_filters.lfm new file mode 100644 index 0000000000..0f42c004e1 --- /dev/null +++ b/ide/frames/env_file_filters.lfm @@ -0,0 +1,56 @@ +inherited FileFiltersOptionsFrame: TFileFiltersOptionsFrame + Height = 319 + Width = 455 + ClientHeight = 319 + ClientWidth = 455 + TabOrder = 0 + DesignLeft = 367 + DesignTop = 168 + object grdFileFilters: TStringGrid[0] + Left = 8 + Height = 281 + Top = 32 + Width = 440 + AlternateColor = 15592941 + Anchors = [akTop, akLeft, akRight, akBottom] + ColCount = 3 + Columns = < + item + Title.Caption = 'Name' + Width = 130 + end + item + Title.Caption = 'File mask' + Width = 300 + end> + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goEditing, goThumbTracking, goSmoothScroll, goFixedRowNumbering] + PopupMenu = pmGrid + RowCount = 1 + TabOrder = 0 + OnKeyDown = grdFileFiltersKeyDown + end + object lblTitle: TLabel[1] + Left = 8 + Height = 18 + Top = 9 + Width = 41 + Caption = 'lblTitle' + ParentColor = False + end + object pmGrid: TPopupMenu[2] + left = 205 + top = 75 + object pmiAddRow: TMenuItem + Caption = 'Add row' + OnClick = pmiAddRowClick + end + object pmiDelRow: TMenuItem + Caption = 'Delete row' + OnClick = pmiDelRowClick + end + object pmiInsRow: TMenuItem + Caption = 'Insert row' + OnClick = pmiInsRowClick + end + end +end diff --git a/ide/frames/env_file_filters.pas b/ide/frames/env_file_filters.pas new file mode 100644 index 0000000000..4395a60ba8 --- /dev/null +++ b/ide/frames/env_file_filters.pas @@ -0,0 +1,226 @@ +unit env_file_filters; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, LResources, Forms, Grids, + EnvironmentOpts, IDEOptionDefs, + IDEOptionsIntf, Controls, Menus, StdCtrls; + +type + TFileFiltersOptionsFrame = class(TAbstractIDEOptionsEditor) + grdFileFilters: TStringGrid; + pmGrid: TPopupMenu; + pmiAddRow: TMenuItem; + pmiDelRow: TMenuItem; + pmiInsRow: TMenuItem; + lblTitle: TLabel; + procedure grdFileFiltersKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); + procedure pmiAddRowClick(Sender: TObject); + procedure pmiDelRowClick(Sender: TObject); + procedure pmiInsRowClick(Sender: TObject); + private + FList: TStringList; + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + function GetTitle: String; override; + procedure Setup(ADialog: TAbstractOptionsEditorDialog); override; + procedure ReadSettings(AOptions: TAbstractIDEOptions); override; + procedure WriteSettings(AOptions: TAbstractIDEOptions); override; + class function SupportedOptionsClass: TAbstractIDEOptionsClass; override; + end; + + +procedure LoadFileFiltersList; + + +implementation + +{$R *.lfm} + +uses + LazarusIDEStrConsts, + BaseIDEIntf, + LazConfigStorage, + LCLType; + +const + cSettingsFile = 'filefilters.xml'; + KeyFilter = 'Filter%2.2d'; + KeyFilterCount = 'Count'; + KeyFilterName = 'Name'; + KeyFilterMask = 'Mask'; + + +procedure LoadFileFiltersList; +const + cFilter = '%s (%s)|%s|'; // each filter is seperated by another | sign +var + cfg: TConfigStorage; + c: integer; + i: integer; + lName, lMask: string; +begin + EnvironmentOptions.FileFilters.Clear; + cfg := GetIDEConfigStorage(cSettingsFile, True); + try + c := cfg.GetValue(KeyFilterCount, 0); + if c = 0 then + begin + // create default values + EnvironmentOptions.FileFilters.Text:= + lisLazarusUnit + ' (*.pas;*.pp)|*.pas;*.pp' + + '|' + lisLazarusProject + ' (*.lpi)|*.lpi' + + '|' + lisLazarusForm + ' (*.lfm;*.dfm)|*.lfm;*.dfm' + + '|' + lisLazarusPackage + ' (*.lpk)|*.lpk' + + '|' + lisLazarusProjectSource + ' (*.lpr)|*.lpr'; + end + else + begin + // read values + for i := 1 to c do + begin + lName := cfg.GetValue(Format(KeyFilter, [i]) + '/' + KeyFilterName, ''); + lMask := cfg.GetValue(Format(KeyFilter, [i]) + '/' + KeyFilterMask, '*'); + EnvironmentOptions.FileFilters.Add(Format(cFilter, [lName, lMask, lMask])); + end; + end; + finally + cfg.Free; + end; +end; + +{ TFileFiltersOptionsFrame } + +procedure TFileFiltersOptionsFrame.grdFileFiltersKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +begin + if Key = VK_INSERT then + grdFileFilters.RowCount := grdFileFilters.RowCount + 1; +end; + +procedure TFileFiltersOptionsFrame.pmiAddRowClick(Sender: TObject); +begin + grdFileFilters.RowCount := grdFileFilters.RowCount + 1; +end; + +procedure TFileFiltersOptionsFrame.pmiDelRowClick(Sender: TObject); +begin + grdFileFilters.DeleteColRow(False, grdFileFilters.Row); +end; + +procedure TFileFiltersOptionsFrame.pmiInsRowClick(Sender: TObject); +begin + grdFileFilters.InsertColRow(False, grdFileFilters.Row); +end; + +constructor TFileFiltersOptionsFrame.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + FList := TStringList.Create; +end; + +destructor TFileFiltersOptionsFrame.Destroy; +begin + FList.Free; + inherited Destroy; +end; + +function TFileFiltersOptionsFrame.GetTitle: String; +begin + Result := lisFileFilters; +end; + +procedure TFileFiltersOptionsFrame.Setup(ADialog: TAbstractOptionsEditorDialog); +begin + lblTitle.Caption := lisFileFiltersTitle; + grdFileFilters.DefaultColWidth := 40; + grdFileFilters.RowCount := 1; + + grdFileFilters.Columns[0].Title.Caption := lisFileFiltersName; + grdFileFilters.Columns[1].Title.Caption := lisFileFiltersMask; + + pmiAddRow.Caption := lisFileFiltersAddRow; + pmiDelRow.Caption := lisFileFiltersDeleteRow; + pmiInsRow.Caption := lisFileFiltersInsertRow; +end; + +procedure TFileFiltersOptionsFrame.ReadSettings(AOptions: TAbstractIDEOptions); +var + cfg: TConfigStorage; + c: integer; + i: integer; + lName, lMask: string; + + procedure AddRowItem(const ARow: integer; const AName, AMask: String); + begin + grdFileFilters.Cells[1, ARow] := AName; + grdFileFilters.Cells[2, ARow] := AMask; + end; + +begin + grdFileFilters.RowCount := 1; { don't call Clear because it will remove fixed columns too } + cfg := GetIDEConfigStorage(cSettingsFile, True); + try + c := cfg.GetValue(KeyFilterCount, 0); + if c = 0 then + begin + // create default vaulues + grdFileFilters.RowCount := grdFileFilters.RowCount + 7; + AddRowItem(1, lisLazarusFile, '*.lpi;*.lpr;*.lpk;*.pas;*.pp;*.inc;*.lfm;*.dfm'); + AddRowItem(2, lisLazarusUnit, '*.pas;*.pp'); + AddRowItem(3, lisLazarusProject, '*.lpi'); + AddRowItem(4, lisLazarusForm, '*.lfm;*.dfm'); + AddRowItem(5, lisLazarusPackage, '*.lpk'); + AddRowItem(6, lisLazarusProjectSource, '*.lpr'); + end + else + begin + // read values + grdFileFilters.RowCount := c+1; + for i := 1 to c do + begin + lName := cfg.GetValue(Format(KeyFilter, [i]) + '/' + KeyFilterName, 'N' + IntToStr(i)); // N1, N2 etc if no name specified + lMask := cfg.GetValue(Format(KeyFilter, [i]) + '/' + KeyFilterMask, AllFilesMask); + AddRowItem(i, lName, lMask); + end; + end; + finally + cfg.Free; + end; + LoadFileFiltersList; +end; + +procedure TFileFiltersOptionsFrame.WriteSettings(AOptions: TAbstractIDEOptions); +var + cfg: TConfigStorage; + i: integer; +begin + cfg := GetIDEConfigStorage(cSettingsFile, False); + try + cfg.SetValue(KeyFilterCount, grdFileFilters.RowCount-1); + for i := 1 to grdFileFilters.RowCount-1 do + begin + cfg.SetValue(Format(KeyFilter, [i]) + '/' + KeyFilterName, grdFileFilters.Cells[1, i]); + cfg.SetValue(Format(KeyFilter, [i]) + '/' + KeyFilterMask, grdFileFilters.Cells[2, i]); + end; + cfg.WriteToDisk; + finally + cfg.Free; + end; + LoadFileFiltersList; +end; + +class function TFileFiltersOptionsFrame.SupportedOptionsClass: TAbstractIDEOptionsClass; +begin + Result := TEnvironmentOptions; +end; + +initialization + RegisterIDEOptionsEditor(GroupEnvironment, TFileFiltersOptionsFrame, EnvOptionsFileFilters); + +end. + diff --git a/ide/lazarus.lpi b/ide/lazarus.lpi index a82b40214d..17c2941497 100644 --- a/ide/lazarus.lpi +++ b/ide/lazarus.lpi @@ -63,7 +63,7 @@ - + @@ -641,6 +641,13 @@ + + + + + + + diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index 21e4e30f8f..d5c945a445 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -5372,6 +5372,15 @@ resourcestring lisUnableToCreateNewFileBecauseThereIsAlreadyADirecto = 'Unable to create ' +'new file, because there is already a directory with this name.'; + // File Filters - Environment options + lisFileFiltersTitle ='These are file filters that will appear in all File Open dialogs'; + lisFileFilters = 'File Filters'; + lisFileFiltersName = 'Name'; + lisFileFiltersMask = 'File mask'; + lisFileFiltersAddRow = 'Add Row'; + lisFileFiltersDeleteRow = 'Delete Row'; + lisFileFiltersInsertRow = 'Insert Row'; + implementation end. diff --git a/ide/main.pp b/ide/main.pp index a05a887bc4..a58de66a64 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -123,6 +123,8 @@ uses codeobserver_options, help_general_options, // project option frames + env_file_filters, + // project options project_application_options, project_forms_options, project_lazdoc_options, project_save_options, project_versioninfo_options, project_i18n_options, project_misc_options, @@ -807,7 +809,7 @@ type NewFlags: TNewFlags; NewOwner: TObject): TModalResult; override; function DoNewOther: TModalResult; procedure CreateFileDialogFilterForSourceEditorFiles(Filter: string; - out AllEditorExt, AllFilter: string); + out AllEditorMask, AllMask: string); function DoSaveEditorFile(PageIndex:integer; Flags: TSaveFlags): TModalResult; override; @@ -1115,6 +1117,7 @@ var implementation + var SkipAutoLoadingLastProject: boolean = false; StartedByStartLazarus: boolean = false; @@ -1309,6 +1312,7 @@ begin ExternalTools.OnNeedsOutputFilter := @OnExtToolNeedsOutputFilter; ExternalTools.OnFreeOutputFilter := @OnExtToolFreeOutputFilter; UpdateDefaultPascalFileExtensions; + LoadFileFiltersList; EditorOpts := TEditorOptions.Create; EditorOpts.OnBeforeRead := @DoEditorOptionsBeforeRead; @@ -2826,8 +2830,8 @@ var I: Integer; OpenFlags: TOpenFlags; Filter: String; - AllEditorExt: String; - AllFilter: String; + AllEditorMask: String; + AllMask: String; ASrcEdit: TSourceEditor; AnUnitInfo: TUnitInfo; begin @@ -2837,28 +2841,26 @@ begin OpenDialog.Title:=lisOpenFile; OpenDialog.Options:=OpenDialog.Options+[ofAllowMultiSelect]; + // set InitialDir to GetCurrentUnit(ASrcEdit,AnUnitInfo); - if Assigned(AnUnitInfo) then + if Assigned(AnUnitInfo) and (not AnUnitInfo.IsVirtual) then OpenDialog.InitialDir:=ExtractFilePath(AnUnitInfo.Filename); - // create default filter list - Filter := lisLazarusUnit + ' (*.pas;*.pp)|*.pas;*.pp' - + '|' + lisLazarusProject + ' (*.lpi)|*.lpi' - + '|' + lisLazarusForm + ' (*.lfm;*.dfm)|*.lfm;*.dfm' - + '|' + lisLazarusPackage + ' (*.lpk)|*.lpk' - + '|' + lisLazarusProjectSource + ' (*.lpr)|*.lpr'; + Filter := EnvironmentOptions.FileFilters.Text; // append a filter for all file types of the open files in the source editor - CreateFileDialogFilterForSourceEditorFiles(Filter,AllEditorExt,AllFilter); - if (AllEditorExt<>'|') then - Filter:=Filter+ '|' + lisEditorFileTypes + ' (' + AllEditorExt + ')|' + - AllEditorExt; + CreateFileDialogFilterForSourceEditorFiles(Filter,AllEditorMask,AllMask); + if (AllEditorMask<>'') then + Filter:=Filter+ '|' + lisEditorFileTypes + ' (' + AllEditorMask + ')|' + + AllEditorMask; - // append an any file filter *.* - Filter:=Filter+ '|' + dlgAllFiles + ' (' + GetAllFilesMask + ')|' + GetAllFilesMask; + // prepend an all normal files filter + Filter:=lisLazarusFile + ' ('+AllMask+')|' + AllMask + '|' + Filter; + + // append an any files filter + if TFileDialog.FindMaskInFilter(Filter,GetAllFilesMask)<1 then + Filter:=Filter+ '|' + dlgAllFiles + ' (' + GetAllFilesMask + ')|' + GetAllFilesMask; - // prepend an all filter - Filter:= lisLazarusFile + ' ('+AllFilter+')|' + AllFilter + '|' + Filter; OpenDialog.Filter := Filter; if OpenDialog.Execute and (OpenDialog.Files.Count>0) then begin @@ -8781,31 +8783,37 @@ begin end; procedure TMainIDE.CreateFileDialogFilterForSourceEditorFiles(Filter: string; - out AllEditorExt, AllFilter: string); + out AllEditorMask, AllMask: string); +// Filter: a TFileDialog filter, e.g. Pascal|*.pas;*.pp|Text|*.txt +// AllEditorExt: a mask for all open files in the source editor, that are not +// in Filter, e.g. '*.txt;*.xml' +// AllFilter: all masks of Filter and AllEditorExt, e.g. '*.pas;*.pp;*.inc' var i: Integer; SrcEdit: TSourceEditor; Ext: String; begin - AllFilter:='|'+TFileDialog.ExtractAllFilterMasks(Filter)+';*.inc'; - AllEditorExt:='|'; + AllMask:='|'+TFileDialog.ExtractAllFilterMasks(Filter); + AllEditorMask:='|'; for i:=0 to SourceEditorManager.SourceEditorCount-1 do begin SrcEdit:=SourceEditorManager.SourceEditors[i]; Ext:=ExtractFileExt(SrcEdit.FileName); if Ext<>'' then begin Ext:='*'+Ext; - if (TFileDialog.FindMaskInFilter(AllFilter,Ext)>0) - or (TFileDialog.FindMaskInFilter(AllEditorExt,Ext)>0) then continue; - if AllEditorExt<>'|' then - AllEditorExt:=AllEditorExt+';'; - AllEditorExt:=AllEditorExt+Ext; + if (TFileDialog.FindMaskInFilter(AllMask,Ext)>0) + or (TFileDialog.FindMaskInFilter(AllEditorMask,Ext)>0) then continue; + if AllEditorMask<>'|' then + AllEditorMask:=AllEditorMask+';'; + AllEditorMask:=AllEditorMask+Ext; end; end; - if AllEditorExt<>'|' then begin - System.Delete(AllEditorExt,1,1); - AllFilter:=AllFilter+';'+AllEditorExt; + System.Delete(AllMask,1,1); + System.Delete(AllEditorMask,1,1); + if AllEditorMask<>'' then begin + if AllMask<>'' then + AllMask:=AllMask+';'; + AllMask:=AllMask+AllEditorMask; end; - System.Delete(AllFilter,1,1); end; function TMainIDE.DoSaveEditorFile(PageIndex:integer; diff --git a/ideintf/ideoptionsintf.pas b/ideintf/ideoptionsintf.pas index 2b6ba7f599..2f01f375fb 100644 --- a/ideintf/ideoptionsintf.pas +++ b/ideintf/ideoptionsintf.pas @@ -205,14 +205,15 @@ function IDEEditorGroups: TIDEOptionsGroupList; const // predefined environment options groups GroupEnvironment = 100; - EnvOptionsFiles = 100; - EnvOptionsDesktop = 200; - EnvOptionsWindow = 300; - EnvOptionsFormEd = 400; - EnvOptionsOI = 500; - EnvOptionsBackup = 600; - EnvOptionsNaming = 700; - EnvOptionsFpDoc = 800; + EnvOptionsFiles = 100; + EnvOptionsDesktop = 200; + EnvOptionsWindow = 300; + EnvOptionsFormEd = 400; + EnvOptionsOI = 500; + EnvOptionsBackup = 600; + EnvOptionsNaming = 700; + EnvOptionsFpDoc = 800; + EnvOptionsFileFilters = 900; GroupEditor = 200; EdtOptionsGeneral = 100; diff --git a/lcl/include/filedialog.inc b/lcl/include/filedialog.inc index bfabb9907a..4bfd22d4b0 100644 --- a/lcl/include/filedialog.inc +++ b/lcl/include/filedialog.inc @@ -115,7 +115,8 @@ class function TFileDialog.ExtractAllFilterMasks(aFilter: string; { The filter is a list of pairs of captions and masks separated by pipe | The masks are separated by semicolon ; For example: - Pascal Files|*.pas;*.pp|All files|*.* + Pascal Files|*.pas;*.pp|Include Files|*.inc|All files|*.* + Result: *.pas;*.pp;*.inc } var AllFilesMask: string;