lazarus/ide/condef.pas
mattias 51e1742910 IDE: clean up
git-svn-id: trunk@31329 -
2011-06-22 07:52:10 +00:00

376 lines
11 KiB
ObjectPascal

{
/***************************************************************************
condef.pas - Conditional Defines
----------------------------------
***************************************************************************/
***************************************************************************
* *
* 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. *
* *
***************************************************************************
}
unit ConDef;
{$mode objfpc}{$H+}
interface
(* Utility to assist in inserting conditional defines. For example, to convert
OnCreate := @CreateHandler
to:
OnCreate := {$IFDEF FPC} @ {$ENDIF} CreateHandler
select @ and then use Edit, Insert $IFDEF (default shortcut Ctrl+Shift+D),
select "FPC,NONE" and hit return. If you select one or more complete lines
then the conditional defines are put on sepearate lines as in:
{$IFDEF DEBUG}
Writeln('State= ', State)
{$ENDIF}
The choices are listed in abbreviated form so:
MSWINDOWS,UNIX => {$IFDEF MSWINDOWS} ... {$ENDIF} {$IFDEF UNIX} ... {$ENDIF}
FPC,ELSE => {$IFDEF FPC} ... {$ELSE} ... {$ENDIF}
DEBUG,NONE => {$IFDEF DEBUG} ... {$ENDIF}
This tool is most useful when you need to put several identical conditionals
in a file, You can add to the possible conditionals by selecting or typing
the required symbols in "First test" and /or "Second test" and using the
Add button. Your additons are saved in the condef.xml file in the lazarus
configuration directory.
*)
uses
Classes, SysUtils, Graphics, Controls, Forms, LCLProc, Dialogs,
StdCtrls, Buttons, FileUtil, ButtonPanel,
Laz_XMLCfg,
IDEHelpIntf,
LazarusIDEStrConsts, IDEProcs;
type
{ TCondForm }
TCondForm = class(TForm)
AddBtn: TBitBtn;
AddInverse: TButton;
ButtonPanel: TButtonPanel;
FirstLabel: TLabel;
FirstTest: TComboBox;
ListBox: TListBox;
NewTestGroupBox: TGroupBox;
RemoveBtn: TBitBtn;
SecondLabel: TLabel;
SecondTest: TComboBox;
procedure AddBtnClick(Sender: TObject);
procedure AddInverseCLICK(Sender: TObject);
procedure HelpButtonClick(Sender: TObject);
procedure CondFormCLOSE(Sender: TObject; var CloseAction: TCloseAction);
procedure CondFormCREATE(Sender: TObject);
procedure ListBoxDblClick(Sender: TObject);
procedure RemoveBtnClick(Sender: TObject);
procedure ListBoxKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormShow(Sender: TObject);
public
Choice, First, Second, FS: string;
procedure DeleteSelected;
procedure SaveChoices;
function CreateXMLConfig: TXMLConfig;
end;
function ShowConDefDlg: string;
function AddConditional(Text: string; IsPascal: Boolean):string;
implementation
{$R *.lfm}
uses
LCLType, LazConf;
function ShowConDefDlg: string;
var
DialogResult: Integer;
CondForm: TCondForm;
begin
Result := '';
CondForm := TCondForm.Create(nil);
try
CondForm.ActiveControl := CondForm.ListBox;
DialogResult := CondForm.ShowModal;
if DialogResult <> mrOK then
Result := ''
else
Result := CondForm.FS;
finally
CondForm.Free;
end
end;
procedure TCondForm.AddBtnClick(Sender: TObject);
begin
ListBox.Items.Add(FirstTest.Text+','+SecondTest.Text);
end;
procedure TCondForm.AddInverseCLICK(Sender: TObject);
begin
ListBox.Items.Add('!'+FirstTest.Text+','+SecondTest.Text);
end;
procedure TCondForm.HelpButtonClick(Sender: TObject);
begin
LazarusHelp.ShowHelpForIDEControl(Self);
end;
procedure TCondForm.CondFormCLOSE(Sender: TObject; var CloseAction: TCloseAction);
var
SChanged: Boolean;
i: Integer;
procedure SUpdate(var s: string; n: string);
begin
if s <> n then begin
SChanged := True;
s := n;
end;
end;
begin
SChanged := False;
with ListBox do begin
SUpdate(Choice,Items.CommaText);
if ItemIndex >= 0 then begin
FS := Items[ItemIndex];
i := Pos(',', FS);
if i > 0 then begin
SUpdate(First, Copy(FS, 1, i-1));
SUpdate(Second, Copy(FS, i+1, Length(FS)));
end
end;
end;
if SChanged then
SaveChoices;
end;
procedure TCondForm.CondFormCREATE(Sender: TObject);
var
i: Integer;
XMLConfig: TXMLConfig;
begin
NewTestGroupBox.Caption := rsCreateNewDefine;
Caption := rsConditionalDefines;
AddBtn.Caption := liswlAdd;
AddInverse.Caption := rsAddInverse;
RemoveBtn.Caption := rsRemove;
ButtonPanel.HelpButton.OnClick := @HelpButtonClick;
try
XMLConfig:=CreateXMLConfig;
try
Choice := XMLConfig.GetValue('condef/Choice', '"MSWINDOWS,UNIX","MSWINDOWS,ELSE","FPC,NONE","FPC,ELSE","DEBUG,NONE"');
First := XMLConfig.GetValue('condef/First', 'MSWINDOWS');
Second := XMLConfig.GetValue('condef/Second', 'UNIX');
finally
XMLConfig.Free;
end;
except
on E: Exception do begin
debugln('TCondForm.CondFormCREATE ',E.Message);
end;
end;
with ListBox do begin
Items.CommaText := Choice;
i := Items.IndexOf(First+','+Second);
if i < 0 then begin
Items.Add(First+','+Second);
ItemIndex := 0;
end else
ItemIndex := i;
end;
end;
procedure TCondForm.ListBoxDblClick(Sender: TObject);
begin
ModalResult := mrOK;
end;
procedure TCondForm.RemoveBtnClick(Sender: TObject);
begin
DeleteSelected;
end;
procedure TCondForm.ListBoxKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_DELETE then begin
DeleteSelected;
Key := 0;
end;
end;
procedure TCondForm.FormShow(Sender: TObject);
begin
if SecondTest.Items.Count < 10 then
SecondTest.Items.AddStrings(FirstTest.Items);
end;
procedure TCondForm.DeleteSelected;
var
i: Integer;
begin
with ListBox.Items do
for i := Count-1 downto 0 do
if ListBox.Selected[i] then
Delete(i);
end;
procedure TCondForm.SaveChoices;
var
XMLConfig: TXMLConfig;
begin
try
InvalidateFileStateCache;
XMLConfig:=CreateXMLConfig;
try
XMLConfig.SetValue('condef/Choice', Choice);
XMLConfig.SetValue('condef/First', First);
XMLConfig.SetValue('condef/Second', Second);
XMLConfig.Flush;
finally
XMLConfig.Free;
end;
except
on E: Exception do begin
debugln('TCondForm.SaveChoices ',E.Message);
end;
end;
end;
function TCondForm.CreateXMLConfig: TXMLConfig;
var
ConfFileName: String;
begin
Result:=nil;
ConfFileName:=SetDirSeparators(GetPrimaryConfigPath+'/condef.xml');
try
if (not FileExistsUTF8(ConfFileName)) then
Result:=TXMLConfig.CreateClean(ConfFileName)
else
Result:=TXMLConfig.Create(ConfFileName);
except
on E: Exception do begin
debugln('TCondForm.CreateXMLConfig ',E.Message);
end;
end;
end;
function AddConditional(Text: string; IsPascal: Boolean):string;
var
cond, s, f: string;
p, p1: Integer;
IsElse, IsTwo, HasNewline: Boolean;
Tail, Indent: string;
function ifdef(s:string):string;
begin
if (s <>'') and (s[1] = '!') then begin
if IsPascal then
Result := 'N'
else
Result := 'n';
s := Copy(s,2,Length(s)-1);
end;
if IsPascal then
Result := '{$IF' + Result + 'DEF ' + s + '}'
else
Result := '#if' + Result + 'def ' + s;
end;
begin
Result := Text;
cond := ShowConDefDlg;
p := Pos(',',cond);
if p <= 0 then Exit;
f := Copy(Cond, 1, p-1);
s := Copy(Cond, p+1, Length(Cond));
IsElse := CompareText(s, 'ELSE') = 0;
IsTwo := CompareText(s, 'NONE') <> 0;
HasNewline := Pos(#10, Text) > 0;
if HasNewline then begin
p := 1;
{ leave leading newlines unchanged (outside $IFDEF) }
while (p <= Length(Text)) and (Text[p] in [#10,#13]) do Inc(p);
Result := Copy(Text,1,p-1);
p1 := p;
{ Work out current indentation, to line up $IFDEFS }
while (p <= Length(Text)) and (Text[p] in [#9,' ']) do Inc(p);
Indent := Copy(Text, p1, p-p1);
Text := Copy(Text,p,Length(Text));
p := Length(Text);
{ Tailing whitespace is left outside $IFDEF }
while (p>0) and (Text[p] in [' ',#9,#10,#13]) do Dec(p);
Tail := Copy(Text, p+1, Length(Text));
SetLength(Text,p);
end else begin
Result := '';
Tail := '';
Indent := '';
end;
if IsPascal then begin
f := ifdef(f);
s := ifdef(s);
if HasNewline then begin
Result := Result + Indent + f + LineEnding + Indent + Text + LineEnding;
if IsElse then
Result := Result + Indent + '{$ELSE}' + LineEnding
else begin
Result := Result + Indent + '{$ENDIF}';
if IsTwo then
Result := Result + LineEnding + Indent + s + LineEnding;
end;
if IsTwo then
Result := Result + Indent + Text + LineEnding + Indent + '{$ENDIF}';
Result := Result + Tail;
end else begin
Result := Result + f + ' ' + Text;
if IsElse then
Result := Result + ' {$ELSE} '
else begin
Result := Result + ' {$ENDIF}';
if IsTwo then
Result := Result + ' ' + s + ' ';
end;
if IsTwo then
Result := Result + Text + ' {$ENDIF}';
end;
end else begin
Result := Result + ifdef(f) + LineEnding + indent + Text + LineEnding;
if IsElse then
Result := Result + '#else' + LineEnding
else begin
Result := Result + '#endif /* ' + f + ' */' + LineEnding;
if IsTwo then
Result := Result + ifdef(s) + LineEnding;
end;
if IsTwo then begin
Result := Result + indent + Text + LineEnding + '#endif /* ';
if IsElse then
Result := Result + f
else
Result := Result + s;
Result := Result + ' */' + LineEnding;
end;
Result := Result + Tail;
end;
end;
end.