/ide/makeresstrdlg.pas
http://github.com/graemeg/lazarus · Pascal · 636 lines · 513 code · 58 blank · 65 comment · 46 complexity · 9f245b269efac2c7050a320303012f7d MD5 · raw file
- {
- /***************************************************************************
- makeresstrdlg.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:
- TMakeResStrDialog is the dialog to setup how to convert a string constant
- into a pascal resourcestring.
-
- }
- unit MakeResStrDlg;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, LCLProc, Forms, Controls, Buttons, StdCtrls,
- Dialogs, ExtCtrls, ButtonPanel, IDEWindowIntf,
- SynHighlighterPas, SynEdit,
- CodeToolManager, CodeToolsStructs, CodeCache,
- IDEHelpIntf, IDEDialogs,
- LazarusIDEStrConsts,
- EditorOptions, InputHistory, MiscOptions, IDEProcs;
- type
- { TMakeResStrDialog }
- TMakeResStrDialog = class(TForm)
- ButtonPanel1: TButtonPanel;
- CustomIdentifierCheckBox: TCheckBox;
- IdentifierGroupBox: TGroupBox;
- IdentifierEdit: TEdit;
- IdentLengthComboBox: TComboBox;
- IdentLengthLabel: TLabel;
- IdentPrefixComboBox: TComboBox;
- IdentPrefixLabel: TLabel;
-
- // options
- ConversionGroupBox: TGroupBox;
- CodePanel: TPanel;
- // resourcestring section
- ResStrSectionLabel: TLabel;
- ResStrSectionComboBox: TComboBox;
- // resourcestrings with same value
- ResStrWithSameValueLabel: TLabel;
- ResStrWithSameValuesCombobox: TComboBox;
- // insert position type
- AppendResStrRadioButton: TRadioButton;
- InsertAlphabeticallyResStrRadioButton: TRadioButton;
- InsertContextSensitiveRadioButton: TRadioButton;
- Splitter1: TSplitter;
- SrcPreviewGroupBox: TGroupBox;
- SrcPreviewSynEdit: TSynEdit;
- StringConstGroupBox: TGroupBox;
- StringConstSynEdit: TSynEdit;
- // highlighter
- SynPasSyn: TSynPasSyn;
- procedure CustomIdentifierCheckBoxClick(Sender: TObject);
- procedure HelpButtonClick(Sender: TObject);
- procedure IdentLengthComboBoxChange(Sender: TObject);
- procedure IdentPrefixComboBoxChange(Sender: TObject);
- procedure IdentifierEditChange(Sender: TObject);
- procedure OkButtonClick(Sender: TObject);
- procedure ResStrSectionComboBoxChange(Sender: TObject);
- procedure ResStrWithSameValuesComboboxChange(Sender: TObject);
- private
- procedure SetupComponents;
- public
- DefaultIdentifier: string;
- Code: TCodeBuffer;
- StartPos, EndPos: TPoint;
- Positions: TCodeXYPositions;
- constructor Create(TheOwner: TComponent); override;
- destructor Destroy; override;
- procedure FillResourceStringSections(NewPositions: TCodeXYPositions);
- procedure FillIdentPrefixes;
- procedure FillIdentLengths;
- procedure FillStringsWithSameValue;
- procedure UpdateIdentifier;
- procedure UpdateSourcePreview;
- function GetIdentifier: string;
- function GetDefaultIdentifier: string;
- procedure SetSource(NewCode: TCodeBuffer;
- const NewStartPos, NewEndPos: TPoint);
- function ResStrExistsInCurrentSection(const Identifier: string): boolean;
- function ResStrExistsInAnySection(const Identifier: string): boolean;
- function ResStrExistsWithSameValue(const Identifier: string): boolean;
- procedure GetNewSource(out NewSource, ResourceStringValue: string);
- procedure Init;
- procedure SaveHistories;
- procedure SaveIdentPrefixes;
- procedure SaveIdentLengths;
- procedure Save;
- end;
-
- function ShowMakeResStrDialog(
- const StartPos, EndPos: TPoint; Code: TCodeBuffer;
- out NewIdentifier, NewIdentifierValue: string;
- out NewSourceLines: string;
- out ResStrSectionCode: TCodeBuffer;
- out ResStrSectionXY: TPoint;
- out InsertPolicy: TResourcestringInsertPolicy): TModalResult;
- implementation
- {$R *.lfm}
- function ShowMakeResStrDialog(const StartPos, EndPos: TPoint;
- Code: TCodeBuffer; out NewIdentifier, NewIdentifierValue: string; out
- NewSourceLines: string; out ResStrSectionCode: TCodeBuffer; out
- ResStrSectionXY: TPoint; out InsertPolicy: TResourcestringInsertPolicy
- ): TModalResult;
- var
- MakeResStrDialog: TMakeResStrDialog;
- Section: PCodeXYPosition;
- ResourcestringSectionID: Integer;
- begin
- //debugln('ShowMakeResStrDialog StartPos=',dbgs(StartPos),' EndPos=',dbgs(EndPos),' ');
- NewIdentifier:='';
- NewIdentifierValue:='';
- NewSourceLines:='';
- ResStrSectionCode:=nil;
- ResStrSectionXY:=Point(0,0);
- InsertPolicy:=rsipNone;
- MakeResStrDialog:=TMakeResStrDialog.Create(nil);
- MakeResStrDialog.Positions:=CodeToolBoss.Positions.CreateCopy;
- MakeResStrDialog.SetSource(Code,StartPos,EndPos);
- MakeResStrDialog.Init;
- // show dialog
- Result:=MakeResStrDialog.ShowModal;
- if Result=mrOk then begin
- // return results
- NewIdentifier:=MakeResStrDialog.GetIdentifier;
- MakeResStrDialog.GetNewSource(NewSourceLines,NewIdentifierValue);
- if MakeResStrDialog.ResStrExistsWithSameValue(NewIdentifier) then
- InsertPolicy:=rsipNone
- else begin
- if MakeResStrDialog.InsertAlphabeticallyResStrRadioButton.Checked then
- InsertPolicy:=rsipAlphabetically
- else if MakeResStrDialog.InsertContextSensitiveRadioButton.Checked then
- InsertPolicy:=rsipContext
- else
- InsertPolicy:=rsipAppend;
- end;
- ResourcestringSectionID:=MakeResStrDialog.ResStrSectionComboBox.ItemIndex;
- Section:=CodeToolBoss.Positions[ResourcestringSectionID];
- ResStrSectionCode:=Section^.Code;
- ResStrSectionXY:=Point(Section^.X,Section^.Y);
- end;
- // save settings and clean up
- IDEDialogLayoutList.SaveLayout(MakeResStrDialog);
- MakeResStrDialog.Positions.Free;
- MakeResStrDialog.Free;
- end;
- { TMakeResStrDialog }
- procedure TMakeResStrDialog.CustomIdentifierCheckBoxClick(Sender: TObject);
- begin
- UpdateIdentifier;
- end;
- procedure TMakeResStrDialog.HelpButtonClick(Sender: TObject);
- begin
- LazarusHelp.ShowHelpForIDEControl(Self);
- end;
- procedure TMakeResStrDialog.IdentLengthComboBoxChange(Sender: TObject);
- begin
- UpdateIdentifier;
- UpdateSourcePreview;
- end;
- procedure TMakeResStrDialog.IdentPrefixComboBoxChange(Sender: TObject);
- begin
- UpdateIdentifier;
- UpdateSourcePreview;
- end;
- procedure TMakeResStrDialog.IdentifierEditChange(Sender: TObject);
- begin
- UpdateIdentifier;
- UpdateSourcePreview;
- end;
- procedure TMakeResStrDialog.OkButtonClick(Sender: TObject);
- var
- Index: Integer;
- begin
- Index:=ResStrSectionComboBox.ItemIndex;
- if (Index<0) or (Index>=Positions.Count) then begin
- IDEMessageDialog(lisMakeResStrInvalidResourcestringSect,
- lisMakeResStrPleaseChooseAResourcestring,
- mtError,[mbCancel]);
- exit;
- end;
- if ResStrExistsInAnySection(IdentifierEdit.Text)
- and (not ResStrExistsWithSameValue(IdentifierEdit.Text)) then begin
- if IDEMessageDialog(lisMakeResStrResourcestringAlreadyExis,
- Format(lisMakeResStrChooseAnotherName,[IdentifierEdit.Text,LineEnding,LineEnding]),
- mtWarning,[mbOk,mbIgnore]) = mrOk
- then
- exit;
- end;
- Save;
- ModalResult:=mrOk;
- end;
- procedure TMakeResStrDialog.ResStrSectionComboBoxChange(Sender: TObject);
- begin
- UpdateIdentifier;
- UpdateSourcePreview;
- end;
- procedure TMakeResStrDialog.ResStrWithSameValuesComboboxChange(Sender: TObject);
- var
- NewIdentifier: String;
- i: Integer;
- begin
- NewIdentifier:=ResStrWithSameValuesCombobox.Text;
- i:=ResStrWithSameValuesCombobox.Items.IndexOf(NewIdentifier);
- if i<0 then exit;
- IdentifierEdit.Text:=NewIdentifier;
- end;
- procedure TMakeResStrDialog.SetupComponents;
- begin
- // source
- AppendResStrRadioButton.Caption:=lisMakeResStrAppendToSection;
- ConversionGroupBox.Caption:=lisMakeResStrConversionOptions;
- CustomIdentifierCheckBox.Caption:=lisMakeResStrCustomIdentifier;
- IdentifierGroupBox.Caption := lisMakeResStrDialogIdentifier;
- IdentLengthLabel.Caption:=lisMakeResStrIdentifierLength;
- IdentPrefixLabel.Caption:=lisMakeResStrIdentifierPrefix;
- InsertAlphabeticallyResStrRadioButton.Caption:=lisMakeResStrInsertAlphabetically;
- InsertContextSensitiveRadioButton.Caption:=lisMakeResStrInsertContexttSensitive;
- ResStrSectionLabel.Caption:=lisMakeResStrResourcestringSection;
- ResStrWithSameValueLabel.Caption:=lisMakeResStrStringsWithSameValue;
- SrcPreviewGroupBox.Caption:=lisMakeResStrSourcePreview;
- StringConstGroupBox.Caption:=lisMakeResStrStringConstantInSource;
- // OK, Cancel, Help buttons
- ButtonPanel1.OkButton.Caption:=lisMenuOk;
- ButtonPanel1.CancelButton.Caption:=lisCancel;
- ButtonPanel1.HelpButton.Caption:=lisMenuHelp;
- end;
- constructor TMakeResStrDialog.Create(TheOwner: TComponent);
- begin
- inherited Create(TheOwner);
- Caption := lisMakeResourceString;
- SetupComponents;
- IDEDialogLayoutList.ApplyLayout(Self,550,400);
- EditorOpts.GetHighlighterSettings(SynPasSyn);
- EditorOpts.GetSynEditSettings(StringConstSynEdit);
- StringConstSynEdit.ReadOnly:=true;
- StringConstSynEdit.Gutter.Visible:=false;
- EditorOpts.GetSynEditSettings(SrcPreviewSynEdit);
- SrcPreviewSynEdit.ReadOnly:=true;
- SrcPreviewSynEdit.Gutter.Visible:=false;
- end;
- destructor TMakeResStrDialog.Destroy;
- begin
- inherited Destroy;
- end;
- procedure TMakeResStrDialog.FillResourceStringSections(
- NewPositions: TCodeXYPositions);
- var
- i: Integer;
- p: PCodeXYPosition;
- s: String;
- begin
- Positions:=NewPositions;
- // the history list contains the filenames plus the
- with ResStrSectionComboBox do begin
- Text:='';
- Items.BeginUpdate;
- for i:=0 to Positions.Count-1 do begin
- p:=Positions[i];
- s:=p^.Code.Filename+' ('+IntToStr(p^.Y)+','+IntToStr(p^.X)+')';
- if i<Items.Count then
- Items[i]:=s
- else
- Items.Add(s);
- end;
- while Items.Count>Positions.Count do
- Items.Delete(Items.Count-1);
- Items.EndUpdate;
- ItemIndex:=0;
- end;
- end;
- procedure TMakeResStrDialog.FillIdentPrefixes;
- var
- HistoryList: THistoryList;
- begin
- // get the Prefixes history list
- HistoryList:=
- InputHistories.HistoryLists.GetList(hlMakeResourceStringPrefixes,true,
- rltCaseSensitive);
- IdentPrefixComboBox.Items.Assign(HistoryList);
- if IdentPrefixComboBox.Items.Count>0 then
- IdentPrefixComboBox.Text:=IdentPrefixComboBox.Items[0]
- else
- IdentPrefixComboBox.Text:='rs';
- end;
- procedure TMakeResStrDialog.FillIdentLengths;
- var
- HistoryList: THistoryList;
- begin
- // get the Length history list
- HistoryList:=
- InputHistories.HistoryLists.GetList(hlMakeResourceStringLengths,true,
- rltCaseSensitive);
- IdentLengthComboBox.Items.Assign(HistoryList);
- if IdentLengthComboBox.Items.Count>0 then
- IdentLengthComboBox.Text:=IdentLengthComboBox.Items[0]
- else begin
- with IdentLengthComboBox.Items do begin
- Add('8');
- Add('12');
- Add('20');
- Add('50');
- end;
- IdentLengthComboBox.Text:='12';
- end;
- end;
- procedure TMakeResStrDialog.FillStringsWithSameValue;
- var
- i: Integer;
- CurSection: TCodeXYPosition;
- NewSource, ResourceStringValue: string;
- StringConstPositions: TCodeXYPositions;
- ExistingIdentifier: string;
- begin
- // get value of the new resourcestring
- GetNewSource(NewSource, ResourceStringValue);
- // get all existing resourcestrings with same value
- StringConstPositions:=TCodeXYPositions.Create;
- for i:=0 to Positions.Count-1 do begin
- CurSection:=Positions[i]^;
- CodeToolBoss.GatherResourceStringsWithValue(
- CurSection.Code,CurSection.X,CurSection.Y,
- ResourceStringValue,StringConstPositions);
- end;
- // fill combobox
- ResStrWithSameValuesCombobox.Items.Clear;
- for i:=0 to StringConstPositions.Count-1 do begin
- CurSection:=StringConstPositions[i]^;
- CodeToolBoss.GetIdentifierAt(CurSection.Code,CurSection.X,CurSection.Y,
- ExistingIdentifier);
- if ExistingIdentifier<>'' then
- ResStrWithSameValuesCombobox.Items.Add(ExistingIdentifier);
- end;
- // enable components for selection
- if ResStrWithSameValuesCombobox.Items.Count>0 then begin
- ResStrWithSameValuesCombobox.Text:=ResStrWithSameValuesCombobox.Items[0];
- ResStrWithSameValuesCombobox.Enabled:=true;
- end else begin
- ResStrWithSameValuesCombobox.Text:='';
- ResStrWithSameValuesCombobox.Enabled:=false;
- end;
- ResStrWithSameValueLabel.Enabled:=ResStrWithSameValuesCombobox.Enabled;
- // clean up
- StringConstPositions.Free;
- end;
- procedure TMakeResStrDialog.UpdateIdentifier;
- var
- CustomIdent: Boolean;
- begin
- CustomIdent:=CustomIdentifierCheckBox.Checked;
- IdentifierEdit.Enabled:=CustomIdent;
- IdentPrefixLabel.Enabled:=not CustomIdent;
- IdentPrefixComboBox.Enabled:=not CustomIdent;
- IdentLengthLabel.Enabled:=not CustomIdent;
- IdentLengthComboBox.Enabled:=not CustomIdent;
- if not CustomIdent then
- IdentifierEdit.Text:=GetDefaultIdentifier;
- end;
- procedure TMakeResStrDialog.UpdateSourcePreview;
- var
- NewSource, NewValue: string;
- begin
- GetNewSource(NewSource,NewValue);
- SrcPreviewSynEdit.Text:=NewSource+LineEnding
- +StringOfChar('-',
- CodeToolBoss.SourceChangeCache.BeautifyCodeOptions.LineLength)
- +LineEnding
- +CodeToolBoss.SourceChangeCache.BeautifyCodeOptions.BeautifyStatement(
- GetIdentifier+' = '''+NewValue+'''',0);
- end;
- function TMakeResStrDialog.GetIdentifier: string;
- begin
- Result:=IdentifierEdit.Text;
- if Result='' then Result:=GetDefaultIdentifier;
- end;
- function TMakeResStrDialog.GetDefaultIdentifier: string;
- var
- DefIdenLength: Integer;
- i: Integer;
- begin
- if ResStrWithSameValuesCombobox.Items.Count>0 then begin
- Result:=ResStrWithSameValuesCombobox.Items[0];
- exit;
- end;
- DefIdenLength:=StrToIntDef(IdentLengthComboBox.Text,8);
- if DefIdenLength<1 then DefIdenLength:=1;
- if DefIdenLength>80 then DefIdenLength:=80;
- Result:=IdentPrefixComboBox.Text+copy(DefaultIdentifier,1,DefIdenLength);
- if ResStrExistsInCurrentSection(Result) then begin
- i:=2;
- while ResStrExistsInCurrentSection(Result+IntToStr(i)) do inc(i);
- Result:=Result+IntToStr(i);
- end;
- end;
- procedure TMakeResStrDialog.SetSource(NewCode: TCodeBuffer; const NewStartPos,
- NewEndPos: TPoint);
- begin
- Code:=NewCode;
- StartPos:=NewStartPos;
- EndPos:=NewEndPos;
- end;
- function TMakeResStrDialog.ResStrExistsInCurrentSection(const Identifier: string
- ): boolean;
- var
- CodeXY: PCodeXYPosition;
- Index: Integer;
- begin
- Result:=false;
- Index:=ResStrSectionComboBox.ItemIndex;
- if (Index<0) or (Index>=Positions.Count) then exit;
- CodeXY:=Positions.Items[Index];
- Result:=CodeToolBoss.IdentifierExistsInResourceStringSection(
- CodeXY^.Code,CodeXY^.X,CodeXY^.Y,Identifier);
- end;
- function TMakeResStrDialog.ResStrExistsInAnySection(const Identifier: string
- ): boolean;
- var
- CodeXY: PCodeXYPosition;
- Index: Integer;
- begin
- Result:=false;
- for Index:=0 to Positions.Count-1 do begin
- CodeXY:=Positions.Items[Index];
- Result:=CodeToolBoss.IdentifierExistsInResourceStringSection(
- CodeXY^.Code,CodeXY^.X,CodeXY^.Y,Identifier);
- if Result then exit;
- end;
- end;
- function TMakeResStrDialog.ResStrExistsWithSameValue(const Identifier: string
- ): boolean;
- var
- i: Integer;
- begin
- if Identifier<>'' then begin
- for i:=0 to ResStrWithSameValuesCombobox.Items.Count-1 do begin
- if CompareText(Identifier,ResStrWithSameValuesCombobox.Items[i])=0
- then begin
- Result:=true;
- exit;
- end;
- end;
- end;
- Result:=false;
- end;
- procedure TMakeResStrDialog.GetNewSource(out NewSource,
- ResourceStringValue: string);
- var
- FormatStringConstant: string;
- FormatParameters: string;
- LeftSide: String;
- LastLine: string;
- NewString: String;
- RightSide: String;
- StartInStringConst, EndInStringConst: boolean;
- begin
- NewSource:='';
- ResourceStringValue:='';
- if not CodeToolBoss.StringConstToFormatString(Code,StartPos.X,StartPos.Y,
- Code,EndPos.X,EndPos.Y,FormatStringConstant,FormatParameters,
- StartInStringConst,EndInStringConst)
- then begin
- SrcPreviewSynEdit.Text:=lisCCOErrorCaption+':'#13+CodeToolBoss.ErrorMessage;
- exit;
- end;
- if FormatParameters='' then
- NewString:=GetIdentifier
- else
- NewString:='Format('+GetIdentifier+',['+FormatParameters+'])';
- if StartInStringConst then
- NewString:='''+'+NewString;
- if EndInStringConst then
- NewString:=NewString+'+''';
- LeftSide:=copy(StringConstSynEdit.Lines[0],1,StartPos.X-1);
- LastLine:=StringConstSynEdit.Lines[EndPos.Y-StartPos.Y];
- RightSide:=copy(LastLine,EndPos.X,length(LastLine)-EndPos.X+1);
- NewSource:=LeftSide+NewString+RightSide;
- with CodeToolBoss.SourceChangeCache.BeautifyCodeOptions do
- NewSource:=BeautifyStatement(NewSource,0);
- ResourceStringValue:=FormatStringConstant;
- end;
- procedure TMakeResStrDialog.Init;
- var
- InsertPolicy: TResourcestringInsertPolicy;
- begin
- // string constant
- StringConstSynEdit.Text:=Code.GetLines(StartPos.Y,EndPos.Y);
- // reachable resourcestring sections
- FillResourceStringSections(Positions);
- // identifier prefixes
- FillIdentPrefixes;
- // identifier lengths
- FillIdentLengths;
- // existing resource strings with same value
- FillStringsWithSameValue;
- // identifier
- CustomIdentifierCheckBox.Checked:=false;
- CodeToolBoss.CreateIdentifierFromStringConst(Code,StartPos.X,StartPos.Y,
- Code,EndPos.X,EndPos.Y,DefaultIdentifier,50);
- UpdateIdentifier;
- // insert policy
- InsertPolicy:=MiscellaneousOptions.MakeResourceStringInsertPolicy;
- case InsertPolicy of
- rsipAlphabetically: InsertAlphabeticallyResStrRadioButton.Checked:=true;
- rsipContext: InsertContextSensitiveRadioButton.Checked:=true;
- else AppendResStrRadioButton.Checked:=true;
- end;
- // show new source
- UpdateSourcePreview;
- end;
- procedure TMakeResStrDialog.SaveHistories;
- begin
- SaveIdentPrefixes;
- SaveIdentLengths;
- end;
- procedure TMakeResStrDialog.SaveIdentPrefixes;
- var
- HistoryList: THistoryList;
- begin
- if CustomIdentifierCheckBox.Checked
- or (IdentPrefixComboBox.Text='') then
- exit;
- HistoryList:=
- InputHistories.HistoryLists.GetList(hlMakeResourceStringPrefixes,true,rltCaseSensitive);
- if HistoryList.Count=0 then
- HistoryList.Assign(IdentPrefixComboBox.Items);
- HistoryList.Push(IdentPrefixComboBox.Text);
- end;
- procedure TMakeResStrDialog.SaveIdentLengths;
- var
- HistoryList: THistoryList;
- begin
- if CustomIdentifierCheckBox.Checked
- or (IdentLengthComboBox.Text='') then
- exit;
- HistoryList:=
- InputHistories.HistoryLists.GetList(hlMakeResourceStringLengths,true,rltCaseSensitive);
- if HistoryList.Count=0 then
- HistoryList.Assign(IdentLengthComboBox.Items);
- HistoryList.Push(IdentLengthComboBox.Text);
- end;
- procedure TMakeResStrDialog.Save;
- var
- InsertPolicy: TResourcestringInsertPolicy;
- begin
- SaveHistories;
- if InsertContextSensitiveRadioButton.Checked then
- InsertPolicy:=rsipContext
- else if InsertAlphabeticallyResStrRadioButton.Checked then
- InsertPolicy:=rsipAlphabetically
- else
- InsertPolicy:=rsipAppend;
- MiscellaneousOptions.MakeResourceStringInsertPolicy:=InsertPolicy;
- MiscellaneousOptions.Save;
- end;
- end.