PageRenderTime 21ms CodeModel.GetById 8ms app.highlight 6ms RepoModel.GetById 2ms app.codeStats 0ms

/components/messagecomposer/messagecomposer.pas

http://github.com/graemeg/lazarus
Pascal | 993 lines | 865 code | 57 blank | 71 comment | 110 complexity | 26bb5453c0df23f2b8a6adad05cbb8dd MD5 | raw file
  1{ Copyright (C) 2007 Salvatore Coppola
  2
  3  This library is free software; you can redistribute it and/or modify it
  4  under the terms of the GNU Library General Public License as published by
  5  the Free Software Foundation; either version 2 of the License, or (at your
  6  option) any later version.
  7
  8  This program is distributed in the hope that it will be useful, but WITHOUT
  9  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 10  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
 11  for more details.
 12
 13  You should have received a copy of the GNU Library General Public License
 14  along with this library; if not, write to the Free Software Foundation,
 15  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 16
 17  Abstract:
 18  This unit is a message dialog composer for Lazarus/FPC.
 19  It takes into account all message dialogs platform indpendently.
 20}
 21
 22unit MessageComposer;
 23
 24{$mode objfpc}{$H+}
 25
 26interface
 27
 28uses
 29  Classes, SysUtils, LResources, LCLType, Forms, Controls, Graphics, Dialogs,
 30  StdCtrls, ExtCtrls, Spin, Grids, ActnList, Buttons, EditBtn,
 31  IDECommands, MenuIntf, LazIDEIntf, SrcEditorIntf;
 32
 33type
 34
 35  { TFormMessagesComposer }
 36
 37  TFormMessagesComposer = class(TForm)
 38    KindMessageComboBox: TComboBox;
 39    KindMessageLabel: TLabel;
 40    MsgMemo: TMemo;
 41    ButtonsNotebook: TNotebook;
 42    PageString: TPage;
 43    ButtonPanel: TPanel;
 44    SourceNotebook: TNotebook;
 45    Page1: TPage;
 46    Page2: TPage;
 47    PageIf: TPage;
 48    PageCase: TPage;
 49    UpdateQuestioDlgResult: TAction;
 50    SetIfOrCase: TAction;
 51    PositionBevel: TBevel;
 52    Bevel2: TBevel;
 53    HelpCtxBevel: TBevel;
 54    CaseResultCheckGroup: TCheckGroup;
 55    BeginEndCheckBox: TCheckBox;
 56    IfResultComboBox: TComboBox;
 57    StringResultEdit: TEdit;
 58    GetParamsFmt: TAction;
 59    OkButton: TBitBtn;
 60    CancelButton: TBitBtn;
 61    GetMessageForSource: TAction;
 62    Label1: TLabel;
 63    StringResultLabel: TLabel;
 64    IfThenRadioButton: TRadioButton;
 65    IfThenElseRadioButton: TRadioButton;
 66    CaseOfEndRadioButton: TRadioButton;
 67    CaseOfEndElseRadioButton: TRadioButton;
 68    SourceWrapperGroupBox: TGroupBox;
 69    Test: TAction;
 70    TestButton: TButton;
 71    MaskInputCheckBox: TCheckBox;
 72    PromptEdit: TEdit;
 73    ValueEdit: TEdit;
 74    PromptLabel: TLabel;
 75    HelpFileNameEdit: TFileNameEdit;
 76    HelpFileNameLabel: TLabel;
 77    MessagesInit: TAction;
 78    DefaultEdit: TEdit;
 79    ValueLabel: TLabel;
 80    DefaultValue: TLabel;
 81    XLabel: TLabel;
 82    YLabel: TLabel;
 83    MessageSetup: TAction;
 84    BitBtn1: TBitBtn;
 85    BitBtn2: TBitBtn;
 86    DelConst: TAction;
 87    AddConst: TAction;
 88    ActionList1: TActionList;
 89    CaptionEdit: TEdit;
 90    ButtonsCheckGroup: TCheckGroup;
 91    DlgTypeComboBox: TComboBox;
 92    DlgTypeLabel: TLabel;
 93    HelpKeyWordEdit: TEdit;
 94    HelpContextLabel: TLabel;
 95    HelpKeyWordLabel: TLabel;
 96    CaptionLabel: TLabel;
 97    MsgLabel: TLabel;
 98    HelpContextSpinEdit: TSpinEdit;
 99    ButtonsStringGrid: TStringGrid;
100    ButtonsPanel: TPanel;
101    Panel2: TPanel;
102    XSpinEdit: TSpinEdit;
103    YSpinEdit: TSpinEdit;
104    procedure AddConstExecute(Sender: TObject);
105    procedure ButtonsCheckGroupItemClick(Sender: TObject; {%H-}Index: integer);
106    procedure ButtonsStringGridSelectEditor(Sender: TObject; aCol,
107      {%H-}aRow: Integer; var Editor: TWinControl);
108    procedure DelConstExecute(Sender: TObject);
109    procedure GetMessageForSourceExecute(Sender: TObject);
110    procedure GetParamsFmtExecute(Sender: TObject);
111    procedure MessageSetupExecute(Sender: TObject);
112    procedure MessagesInitExecute(Sender: TObject);
113    procedure SetIfOrCaseExecute(Sender: TObject);
114    procedure TestExecute(Sender: TObject);
115    procedure UpdateQuestioDlgResultExecute(Sender: TObject);
116  private
117    { private declarations }
118  public
119    { public declarations }
120  end;
121
122procedure Register;
123
124var
125  srcMessage: string;
126
127implementation
128
129{$R *.lfm}
130
131const
132  cMessageComposer = 'Message Composer';
133  DoubleSpace = '  ';
134  idxPageIf = 0;
135  idxPageCase = 1;
136  idxPageString = 2;
137
138type
139  TComposedMsgKind = (
140    cmkMsgDlgSimple,             //MessageDlg[Msg, DlgType, Buttons(TMsgDlgButtons), HelpCtx]
141    cmkMsgDlgCaption,            //MessageDlg[Caption, Msg, DlgType, Buttons(TMsgDlgButtons), HelpCtx]
142    cmkMsgDlgCaptionHelpKeyWord, //MessageDlg[Caption, Msg, DlgType, Buttons(TMsgDlgButtons), HelpKeyword]
143    cmkMsgDlgPosSimple,          //MessageDlgPos[Msg, DlgType, Buttons(TMsgDlgButtons), HelpCtx, X, Y]
144    cmkMsgDlgPosHelpSimple,      //MessageDlgPosHelp[Msg, DlgType, Buttons(TMsgDlgButtons), HelpCtx, X, Y, HelpFileName]
145    cmkQDlgHelpCtx,              //QuestionDlg[Caption, Msg, DlgType, Buttons(array of const), HelpCtx]
146    cmkQDlgHelpKeyword,          //QuestionDlg[Caption, Msg, DlgType, Buttons(array of const), HelpKeyword]
147    cmkShowMsg,                  //ShowMessage[Msg: string];
148    cmkShowMsgFmt,               //ShowMessageFmt[Msg, Params(array of const)];
149    cmkShowMsgPos,               //ShowMessagePos[Msg, X, Y];
150    cmkInpQMask,                 //InputQuery[Caption, Prompt, MaskInput(Boolean), Value(String)]
151    cmkInpQSimple,               //InputQuery[Caption, Prompt, Value(String)]
152    cmkInpBox,                   //InputBox[Caption, Prompt, Default]
153    cmkPasswBox                  //PasswordBox[Caption, Prompt]
154  );
155
156  const ComposedMsgStrings: array[TComposedMsgKind] of string = (
157    'MessageDlg[Msg, DlgType, Buttons(TMsgDlgButtons), HelpCtx]',
158    'MessageDlg[Caption, Msg, DlgType, Buttons(TMsgDlgButtons), HelpCtx]',
159    'MessageDlg[Caption, Msg, DlgType, Buttons(TMsgDlgButtons), HelpKeyword]',
160    'MessageDlgPos[Msg, DlgType, Buttons(TMsgDlgButtons), HelpCtx, X, Y]',
161    'MessageDlgPosHelp[Msg, DlgType, Buttons(TMsgDlgButtons), HelpCtx, X, Y, HelpFileName]',
162    'QuestionDlg[Caption, Msg, DlgType, Buttons(array of const), HelpCtx]',
163    'QuestionDlg[Caption, Msg, DlgType, Buttons(array of const), HelpKeyword]',
164    'ShowMessage[Msg: string];',
165    'ShowMessageFmt[Msg, Params(array of const)];',
166    'ShowMessagePos[Msg, X, Y];',
167    'InputQuery[Caption, Prompt, MaskInput(Boolean), Value(String)]',
168    'InputQuery[Caption, Prompt, Value(String)]',
169    'InputBox[Caption, Prompt, Default]',
170    'PasswordBox[Caption, Prompt]'
171  );
172
173
174
175
176resourcestring
177  SMessageComposerMenuCaption = 'Message Composer ...';
178  SMessageComposerCaption = 'Message Composer';
179  SMsgCaption = 'The message to be shown';
180  SDlgCaption = 'Dialog caption';
181  SDlgType = 'Dialog type';
182  SPromptCaption = 'Text asking the user for input';
183  SMaskInput = 'Mask input';
184  SSourceWrapper = 'Source wrapper';
185  SKindofMessage = 'Kind of message';
186  SNotImplementedYet = 'Not implemented yet';
187  rsTest = 'Test';
188  rsOk = 'OK';
189  rsCancel = 'Cancel';
190  SHelpContext = 'Help context';
191  SHelpKeyword = 'Help keyword';
192  SHelpFilename = 'Help filename';
193  SValueVar = 'Value (var)';
194  SDefault = 'Default';
195  SButtonsTMsgDlgButtons = 'Buttons (TMsgDlgButtons)';
196  SAdd = 'Add';
197  SDelete = 'Delete';
198  SButtonsArrayOfConst = 'Buttons (array of const)';
199  SModalResult = 'Modal result';
200  SIfResult = '"If" result';
201  SCaseResult = '"Case" result';
202
203var
204  CmdMessageComposer: TIDECommand;
205
206
207
208{ This is where it all starts. Gets called from Lazarus. }
209procedure ExecuteMessagesComposer(Sender: TObject);
210var FormMessagesComposer: TFormMessagesComposer;
211
212  procedure FormatSrcMessage;
213  var ListSrcMessages: TStringList;
214      indx: integer;
215      BaseStart: string;
216  begin
217    BaseStart := EmptyStr;
218    for indx := 1 to SourceEditorManagerIntf.ActiveEditor.CursorTextXY.x-
219                     Length(SourceEditorManagerIntf.ActiveEditor.Selection)-1 do
220      BaseStart := BaseStart+#32;
221
222    ListSrcMessages := TStringList.Create;
223    ListSrcMessages.Text := srcMessage;
224    if (Pos('if ',srcMessage) = 1)or(Pos('case ',srcMessage) = 1) then
225      for indx := 1 to ListSrcMessages.Count-1 do
226        ListSrcMessages.Strings[indx] := BaseStart+ListSrcMessages.Strings[indx];
227
228    if Pos('case ',srcMessage) = 1 then
229      for indx := 1 to ListSrcMessages.Count-2 do
230        ListSrcMessages.Strings[indx] := DoubleSpace+ListSrcMessages.Strings[indx];
231
232    srcMessage := ListSrcMessages.Text;
233    ListSrcMessages.Free;
234  end;
235
236begin
237  Assert(Sender <> nil);  // removes compiler warning
238  if SourceEditorManagerIntf.ActiveEditor = nil then exit;
239  FormMessagesComposer := TFormMessagesComposer.Create(nil);
240  try
241    FormMessagesComposer.ShowModal;
242    if FormMessagesComposer.ModalResult = mrOK then  begin
243      FormMessagesComposer.GetMessageForSource.Execute;
244      FormatSrcMessage;
245      SourceEditorManagerIntf.ActiveEditor.Selection := srcMessage;
246    end;
247  finally
248    FormMessagesComposer.Free;
249  end;
250end;
251
252{ TFormMessagesComposer }
253
254procedure TFormMessagesComposer.AddConstExecute(Sender: TObject);
255begin
256  ButtonsStringGrid.RowCount := ButtonsStringGrid.RowCount+1;
257  ButtonsStringGrid.AutoAdjustColumns;
258  UpdateQuestioDlgResult.Execute;
259end;
260
261procedure TFormMessagesComposer.ButtonsCheckGroupItemClick(Sender: TObject;
262  Index: integer);
263begin
264  MessageSetup.Execute;
265end;
266
267procedure TFormMessagesComposer.ButtonsStringGridSelectEditor(Sender: TObject; aCol,
268  aRow: Integer; var Editor: TWinControl);
269var
270  ComposedMsgKind: TComposedMsgKind;
271begin
272  if aCol<>1 then exit;
273  ComposedMsgKind := TComposedMsgKind(KindMessageComboBox.ItemIndex);
274  case ComposedMsgKind of
275    cmkQDlgHelpCtx, cmkQDlgHelpKeyword: begin
276      Editor := TStringGrid(Sender).EditorByStyle(cbsPickList);
277      TPickListCellEditor(Editor).Style := csDropDownList;
278      TPickListCellEditor(Editor).Clear;
279      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrNone]);
280      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrOK]);
281      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrCancel]);
282      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrAbort]);
283      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrRetry]);
284      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrIgnore]);
285      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrYes]);
286      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrNo]);
287      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrAll]);
288      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrNoToAll]);
289      TPickListCellEditor(Editor).Items.Add(ModalResultStr[mrYesToAll]);
290    end;
291    cmkShowMsgFmt: begin
292      Editor := TStringGrid(Sender).EditorByStyle(cbsAuto);
293//D Decimal format. Precision digits in it
294//E Scientific format. Args is a Floating point value. Precision is used to specify the total number of decimals (exponent is3 digits)
295//F Fixed point format. Args is a floating point value. Precision indicates the number of digits following the decimal point.
296//G General number format. Args is a floating point value. The argument is converted to a decimal string using fixed point notation or scientific notation, depending on which gives the shortest result. Precision is used to determine the number of digits after the decimal point.
297//M Currency format. Args must be a floating point value. The argument is converted to a decimal string using currency notation. This means that fixed-point notation is used, but that the currency symbol is appended. If precision is specified, then then it overrides the CurrencyDecimals global variable used in the FloatToStrF
298//N Number format. This is the same as fixed point format, except that thousand separators are inserted in the resulting string.
299//P Pointer format. The next argument in the Args array must be a pointer (typed or untyped). The pointer value is converted to a string of length 8, representing the hexadecimal value of the pointer.
300//S String format. The next argument in the Args array must be a string. The argument is simply copied to the result string. If Precision is specified, then only Precision characters are copied to the result string.
301//U Unsigned decimal format. The next argument in the Args array should be an unsigned integer. The argument is converted to a decimal string. If precision is specified, then the string will have at least Precision digits in it. If needed, the string is (left) padded with zeroes.
302//X hexadecimal format. The next argument in the Args array must be an integer. The argument is converted to a hexadecimal string with just enough characters to contain the value of the integer. If Precision is specified then the resulting hexadecimal representation will have at least Precision characters in it (with a maximum value of 32).
303    end;
304  end;
305  ButtonsStringGrid.AutoAdjustColumns;
306end;
307
308procedure TFormMessagesComposer.DelConstExecute(Sender: TObject);
309begin
310  if ButtonsStringGrid.RowCount = 1 then exit;
311  ButtonsStringGrid.RowCount := ButtonsStringGrid.RowCount-1;
312  ButtonsStringGrid.AutoAdjustColumns;
313  UpdateQuestioDlgResult.Execute;
314end;
315
316procedure TFormMessagesComposer.GetMessageForSourceExecute(Sender: TObject);
317var Msg, MsgCaption, MsgHelpKeyword, HelpFileName, Prompt, MsgDefault,
318    Value, DlgType, MsgButtons, HelpCtx, X, Y, strParam: string;
319    i: integer;
320    intParam: integer;
321    floatParam: double;
322    ComposedMsgKind: TComposedMsgKind;
323const
324  BoolS: Array[Boolean] of String = ('False','True');
325begin
326  ComposedMsgKind := TComposedMsgKind(KindMessageComboBox.ItemIndex);
327  Msg := QuotedStr(MsgMemo.Lines.Text);
328
329  if Copy(Msg,Length(Msg)-Length(LineEnding),Length(LineEnding))=LineEnding then
330    Delete(Msg,Length(Msg)-Length(LineEnding),Length(LineEnding));
331  i := pos(LineEnding,Msg);
332  while i>0 do begin
333    Delete(Msg,i,Length(LineEnding));
334    system.Insert(QuotedStr('+LineEnding+'),Msg,i);
335    i := pos(LineEnding,Msg)
336  end;
337
338  DlgType := DlgTypeComboBox.Text;
339  MsgButtons := EmptyStr;
340  if ButtonsNotebook.PageIndex = 0 then begin  //MessageDlg();
341    if ButtonsCheckGroup.Checked[0] then
342      MsgButtons := MsgButtons+' mbYes,';
343    if ButtonsCheckGroup.Checked[1] then
344      MsgButtons := MsgButtons+' mbNo,';
345    if ButtonsCheckGroup.Checked[2] then
346      MsgButtons := MsgButtons+' mbOK,';
347    if ButtonsCheckGroup.Checked[3] then
348      MsgButtons := MsgButtons+' mbCancel,';
349    if ButtonsCheckGroup.Checked[4] then
350      MsgButtons := MsgButtons+' mbAbort,';
351    if ButtonsCheckGroup.Checked[5] then
352      MsgButtons := MsgButtons+' mbRetry,';
353    if ButtonsCheckGroup.Checked[6] then
354      MsgButtons := MsgButtons+' mbIgnore,';
355    if ButtonsCheckGroup.Checked[7] then
356      MsgButtons := MsgButtons+' mbAll,';
357    if ButtonsCheckGroup.Checked[8] then
358      MsgButtons := MsgButtons+' mbNoToAll,';
359    if ButtonsCheckGroup.Checked[9] then
360      MsgButtons := MsgButtons+' mbYesToAll,';
361    if ButtonsCheckGroup.Checked[10] then
362      MsgButtons := MsgButtons+' mbHelp,';
363    if ButtonsCheckGroup.Checked[11] then
364      MsgButtons := MsgButtons+' mbClose,';
365  end else begin //maybe QuestionDlg() or ShowMessageFmt();
366    if ComposedMsgKind=cmkShowMsgFmt then begin //ShowMessageFmt();
367      for i := 1 to ButtonsStringGrid.RowCount-1 do begin
368      //'D', 'E', 'F', 'G', 'M', 'N', 'P', 'S', 'U', 'X' format
369        strParam := #32;
370        if (ButtonsStringGrid.Cells[0, i] = '%D') then begin
371          intParam := StrToIntDef(ButtonsStringGrid.Cells[1, i], 0);
372          strParam := IntToStr(intParam);
373        end;
374        if (ButtonsStringGrid.Cells[0, i] = '%E')or
375           (ButtonsStringGrid.Cells[0, i] = '%F')or
376           (ButtonsStringGrid.Cells[0, i] = '%G')or
377           (ButtonsStringGrid.Cells[0, i] = '%M')or
378           (ButtonsStringGrid.Cells[0, i] = '%N') then begin
379          floatParam := StrToFloatDef(ButtonsStringGrid.Cells[1, i], 0.0);
380          strParam := FloatToStr(floatParam);
381          if pos('.',strParam) = 0 then
382            strParam := strParam+'.0';
383        end;
384        if (ButtonsStringGrid.Cells[0, i] = '%P') then
385          strParam := ButtonsStringGrid.Cells[1, i];//user must knows pointer var in his source
386        if (ButtonsStringGrid.Cells[0, i] = '%S') then
387          strParam := QuotedStr(ButtonsStringGrid.Cells[1, i]);
388        if (ButtonsStringGrid.Cells[0, i] = '%U') then begin
389          intParam := abs(StrToIntDef(ButtonsStringGrid.Cells[1, i], 0));
390          strParam := IntToStr(intParam);
391        end;
392        if (ButtonsStringGrid.Cells[0, i] = '%X') then begin
393          intParam := StrToIntDef(ButtonsStringGrid.Cells[1, i], 0);
394          strParam := IntToStr(intParam);
395        end;
396        if strParam<>#32 then
397          MsgButtons := MsgButtons+#32+strParam+',';
398      end;
399      if strParam=#32 then
400        MsgButtons := strParam+',';
401    end else
402      for i := 1 to ButtonsStringGrid.RowCount-1 do begin
403        if (ButtonsStringGrid.Cells[1, i] = EmptyStr)or
404           (ButtonsStringGrid.Cells[0, i] = EmptyStr) then continue;
405        MsgButtons := MsgButtons+#32+ButtonsStringGrid.Cells[1, i]+', '+
406                      QuotedStr(ButtonsStringGrid.Cells[0, i])+',';
407      end;
408  end;
409  if MsgButtons<>EmptyStr then begin
410    MsgButtons[1] := '[';
411    MsgButtons[Length(MsgButtons)] := ']';
412  end else
413    MsgButtons:='[]';
414  MsgCaption := QuotedStr(CaptionEdit.Text);
415  HelpCtx := HelpContextSpinEdit.Text;
416  MsgHelpKeyword := QuotedStr(HelpKeyWordEdit.Text);
417  HelpFileName := QuotedStr(HelpFileNameEdit.Text);
418  X := XSpinEdit.Text;
419  Y := YSpinEdit.Text;
420  Prompt := QuotedStr(PromptEdit.Text);
421  MsgDefault := QuotedStr(DefaultEdit.Text);
422  Value := ValueEdit.Text;//user must knows Value var in his source
423  case ComposedMsgKind of
424    cmkMsgDlgSimple: srcMessage := 'MessageDlg('+Msg+', '+DlgType+', '+MsgButtons+','+HelpCtx+')';
425    cmkMsgDlgCaption: srcMessage := 'MessageDlg('+MsgCaption+', '+Msg+', '+DlgType+', '+
426                                   MsgButtons+', '+HelpCtx+')';
427    cmkMsgDlgCaptionHelpKeyWord: srcMessage := 'MessageDlg('+MsgCaption+', '+Msg+', '+DlgType+', '+
428                                   MsgButtons+', '+MsgHelpKeyword+')';
429    cmkMsgDlgPosSimple: srcMessage := 'MessageDlgPos('+Msg+', '+DlgType+', '+MsgButtons+', '+
430                                      HelpCtx+', '+X+', '+Y+')';
431    cmkMsgDlgPosHelpSimple: srcMessage := 'MessageDlgPosHelp('+Msg+', '+DlgType+', '+MsgButtons+', '+
432                                          HelpCtx+', '+X+', '+Y+', '+HelpFileName+')';
433    cmkQDlgHelpCtx: srcMessage := 'QuestionDlg('+MsgCaption+', '+Msg+', '+DlgType+', '+
434                                    MsgButtons+', '+HelpCtx+')';
435    cmkQDlgHelpKeyword: srcMessage := 'QuestionDlg('+MsgCaption+', '+Msg+', '+DlgType+', '+
436                                    MsgButtons+', '+MsgHelpKeyword+')';
437    cmkShowMsg: srcMessage := 'ShowMessage('+Msg+')';
438    cmkShowMsgFmt: srcMessage := 'ShowMessageFmt('+Msg+', '+MsgButtons+')';
439    cmkShowMsgPos: srcMessage := 'ShowMessagePos('+Msg+', '+X+', '+Y+')';
440    cmkInpQMask: srcMessage := 'InputQuery('+MsgCaption+', '+Prompt+', '+
441                                BoolS[MaskInputCheckBox.Checked]+', '+Value+')';
442    cmkInpQSimple: srcMessage := 'InputQuery('+MsgCaption+', '+Prompt+', '+Value+')';
443    cmkInpBox: srcMessage := 'InputBox('+MsgCaption+', '+Prompt+', '+MsgDefault+')';
444    cmkPasswBox: srcMessage := 'PasswordBox('+MsgCaption+', '+Prompt+')'
445  end;
446
447  if SourceWrapperGroupBox.Enabled then begin //no showmessages
448    if (IfThenRadioButton.Checked)or(IfThenElseRadioButton.Checked) then begin
449      srcMessage := 'if '+srcMessage+' = ';
450      if SourceNoteBook.PageIndex <> idxPageString then
451        srcMessage := srcMessage+IfResultComboBox.Text
452      else
453        srcMessage := srcMessage+QuotedStr(StringResultEdit.Text);
454      srcMessage := srcMessage+' then';
455      if BeginEndCheckBox.Checked then
456        srcMessage := srcMessage+' begin '+LineEnding+'end';
457    end;
458    if IfThenElseRadioButton.Checked then begin
459      srcMessage := srcMessage+LineEnding+'else';
460      if BeginEndCheckBox.Checked then
461        srcMessage := srcMessage+' begin '+LineEnding+'end';
462    end;
463    if CaseOfEndRadioButton.Checked then begin
464      srcMessage := 'case '+srcMessage+' of'+LineEnding;
465      for i := 0 to CaseResultCheckGroup.Items.Count-1 do begin
466        if not CaseResultCheckGroup.Checked[i] then continue;
467        if BeginEndCheckBox.Checked then
468          srcMessage := srcMessage+CaseResultCheckGroup.Items[i]+
469                        ': begin'+LineEnding+'end;'+LineEnding
470        else
471          srcMessage := srcMessage+CaseResultCheckGroup.Items[i]+
472                        ': ;'+LineEnding;
473      end;
474      srcMessage := srcMessage+'end;'
475    end;
476    if CaseOfEndElseRadioButton.Checked then begin
477      srcMessage := 'case '+srcMessage+' of'+LineEnding;
478      for i := 0 to CaseResultCheckGroup.Items.Count-1 do begin
479        if not CaseResultCheckGroup.Checked[i] then continue;
480        if BeginEndCheckBox.Checked then
481          srcMessage := srcMessage+CaseResultCheckGroup.Items[i]+
482                        ': begin'+LineEnding+'end;'+LineEnding
483        else
484          srcMessage := srcMessage+CaseResultCheckGroup.Items[i]+
485                        ': ;'+LineEnding;
486      end;
487      if BeginEndCheckBox.Checked then
488        srcMessage := srcMessage+'else begin'+LineEnding+'end;'+LineEnding
489      else
490        srcMessage := srcMessage+'else'+LineEnding;
491      srcMessage := srcMessage+'end;'
492    end;
493  end;
494end;
495
496procedure TFormMessagesComposer.GetParamsFmtExecute(Sender: TObject);
497const FormatParams = ['D', 'E', 'F', 'G', 'M', 'N', 'P', 'S', 'U', 'X'];
498var strtmp: string;
499    ListParams: TStringList;
500    indx: integer;
501    chrtmp: Char;
502    ComposedMsgKind: TComposedMsgKind;
503begin
504  ComposedMsgKind := TComposedMsgKind(KindMessageComboBox.ItemIndex);
505  if ComposedMsgKind<>cmkShowMsgFmt then exit;
506  ButtonsStringGrid.Cells[0, 0] := 'Params (array of const)';
507  ButtonsStringGrid.Cells[1, 0] := 'Values';
508  ButtonsStringGrid.FixedCols := 1;
509  Panel2.Visible := false;
510
511  ListParams := TStringList.Create;
512  strtmp := UpperCase(MsgMemo.Lines.Text);
513
514  indx := pos('%', strtmp);
515  while (indx>0)and(indx<Length(strtmp)) do begin
516    chrtmp := strtmp[indx+1];
517    if chrtmp in FormatParams then
518      ListParams.Add('%'+chrtmp);
519    Delete(strtmp, indx, 1);
520    indx := pos('%',strtmp);
521  end;
522
523  if ListParams.Count>0 then begin
524    ListParams.Insert(0,'Params (array of const)');
525    ButtonsStringGrid.RowCount := ListParams.Count;
526    if ButtonsStringGrid.Cols[0].Text<>ListParams.Text then
527      ButtonsStringGrid.Cols[0] := ListParams;
528  end;
529  ListParams.Free;
530  ButtonsStringGrid.AutoAdjustColumns;
531end;
532
533procedure TFormMessagesComposer.MessageSetupExecute(Sender: TObject);
534var indx: integer;
535    ListResult: TStringList;
536    ComposedMsgKind: TComposedMsgKind;
537begin
538  ComposedMsgKind := TComposedMsgKind(KindMessageComboBox.ItemIndex);
539  if ComposedMsgKind in [cmkMsgDlgSimple,cmkMsgDlgCaption,cmkMsgDlgCaptionHelpKeyWord,
540                         cmkMsgDlgPosSimple,cmkMsgDlgPosHelpSimple] then
541    ButtonsNotebook.PageIndex := 0 // ButtonsCheckGroup
542  else
543    ButtonsNotebook.PageIndex := 1; // ButtonsPanel
544//Msg
545  case ComposedMsgKind of
546    cmkMsgDlgSimple,cmkMsgDlgCaption,cmkMsgDlgCaptionHelpKeyWord,
547    cmkMsgDlgPosSimple,cmkMsgDlgPosHelpSimple,
548    cmkQDlgHelpCtx,cmkQDlgHelpKeyword,cmkShowMsg,
549    cmkShowMsgFmt,cmkShowMsgPos:
550    begin
551      MsgMemo.Color := clWindow;
552      MsgMemo.Enabled := true;
553    end;
554    else begin
555      MsgMemo.Color := clBtnFace;
556      MsgMemo.Enabled := false;
557    end;
558  end;
559//Caption
560  case ComposedMsgKind of
561    cmkMsgDlgCaption,
562    cmkMsgDlgCaptionHelpKeyWord,
563    cmkQDlgHelpCtx,
564    cmkQDlgHelpKeyword,
565    cmkInpQMask,
566    cmkInpQSimple,
567    cmkInpBox,
568    cmkPasswBox: begin
569      CaptionEdit.Color := clWindow;
570      CaptionEdit.Enabled := true;
571    end;
572    else begin
573      CaptionEdit.Color := clBtnFace;
574      CaptionEdit.Enabled := false;
575    end;
576  end;
577//DlgType;
578  case ComposedMsgKind of
579    cmkMsgDlgSimple,
580    cmkMsgDlgCaption,
581    cmkMsgDlgCaptionHelpKeyWord,
582    cmkMsgDlgPosSimple,
583    cmkMsgDlgPosHelpSimple,
584    cmkQDlgHelpCtx,
585    cmkQDlgHelpKeyword: begin
586      DlgTypeComboBox.Color := clWindow;
587      DlgTypeComboBox.Enabled := true;
588    end;
589    else begin
590      DlgTypeComboBox.Color := clBtnFace;
591      DlgTypeComboBox.Enabled := false;
592    end;
593  end;
594//HelpContext
595  case ComposedMsgKind of
596    cmkMsgDlgSimple,
597    cmkMsgDlgCaption,
598    cmkMsgDlgPosSimple,
599    cmkMsgDlgPosHelpSimple,
600    cmkQDlgHelpCtx: begin
601      HelpContextSpinEdit.Color := clWindow;
602      HelpContextSpinEdit.Enabled := true;
603    end;
604    else begin
605      HelpContextSpinEdit.Color := clBtnFace;
606      HelpContextSpinEdit.Enabled := false;
607    end;
608  end;
609//HelpKeyword
610  case ComposedMsgKind of
611    cmkMsgDlgCaptionHelpKeyWord,
612    cmkQDlgHelpKeyword: begin
613      HelpKeyWordEdit.Color := clWindow;
614      HelpKeyWordEdit.Enabled := true;
615    end;
616    else begin
617      HelpKeyWordEdit.Color := clBtnFace;
618      HelpKeyWordEdit.Enabled := false;
619    end;
620  end;
621//Position X Y
622  case ComposedMsgKind of
623    cmkMsgDlgPosSimple,
624    cmkMsgDlgPosHelpSimple,
625    cmkShowMsgPos: begin
626      XSpinEdit.Color := clWindow;
627      XSpinEdit.Enabled := true;
628      YSpinEdit.Color := clWindow;
629      YSpinEdit.Enabled := true;
630    end;
631    else begin
632      XSpinEdit.Color := clBtnFace;
633      XSpinEdit.Enabled := false;
634      YSpinEdit.Color := clBtnFace;
635      YSpinEdit.Enabled := false;
636    end;
637  end;
638//HelpFileName
639  case ComposedMsgKind of
640    cmkMsgDlgPosHelpSimple: begin
641      HelpFileNameEdit.Color := clWindow;
642      HelpFileNameEdit.Enabled := true;
643    end;
644    else begin
645      HelpFileNameEdit.Color := clBtnFace;
646      HelpFileNameEdit.Enabled := false;
647    end;
648  end;
649//Params (array of const)
650  case ComposedMsgKind of
651    cmkShowMsgFmt: begin
652      GetParamsFmt.Execute;
653    end;
654    else begin
655      ButtonsStringGrid.Cells[0, 0] := SButtonsArrayOfConst;
656      ButtonsStringGrid.Cells[1, 0] := SModalResult;
657      ButtonsStringGrid.FixedCols := 0;
658      Panel2.Visible := true;
659    end;
660  end;
661//Prompt
662  case ComposedMsgKind of
663    cmkInpQMask,
664    cmkInpQSimple,
665    cmkInpBox,
666    cmkPasswBox: begin
667      PromptEdit.Color := clWindow;
668      PromptEdit.Enabled := true;
669    end;
670    else begin
671      PromptEdit.Color := clBtnFace;
672      PromptEdit.Enabled := false;
673    end;
674  end;
675//MaskInput
676  case ComposedMsgKind of
677    cmkInpQMask: begin
678      MaskInputCheckBox.Enabled := true;
679    end;
680    else begin
681      MaskInputCheckBox.Enabled := false;
682    end;
683  end;
684//Value
685  case ComposedMsgKind of
686    cmkInpQMask,
687    cmkInpQSimple: begin
688      ValueEdit.Color := clWindow;
689      ValueEdit.Enabled := true;
690    end;
691    else begin
692      ValueEdit.Color := clBtnFace;
693      ValueEdit.Enabled := false;
694    end;
695  end;
696//Default
697  case ComposedMsgKind of
698    cmkInpBox: begin
699      DefaultEdit.Color := clWindow;
700      DefaultEdit.Enabled := true;
701    end;
702    else begin
703      DefaultEdit.Color := clBtnFace;
704      DefaultEdit.Enabled := false;
705    end;
706  end;
707
708/////  Results and Source Wrapper for message //////
709
710//InputBox(); PasswordBox();
711  case ComposedMsgKind of
712    cmkInpBox,
713    cmkPasswBox: begin
714      SourceNotebook.PageIndex := idxPageString;
715      if CaseOfEndRadioButton.Checked then IfThenRadioButton.Checked := True;
716      if CaseOfEndElseRadioButton.Checked then IfThenElseRadioButton.Checked := True;
717      CaseOfEndRadioButton.Enabled := False;
718      CaseOfEndElseRadioButton.Enabled := False;
719      //StringResultEdit.Enabled := true;
720      //StringResultEdit.Color := clWindow;
721      //IfResultComboBox.Enabled := false;
722      //IfResultComboBox.Color := clBtnFace;
723      //CaseResultCheckGroup.Enabled := false;
724      //CaseOfEndElseRadioButton.Enabled := false;
725      //CaseOfEndRadioButton.Enabled := false;
726    end;
727    else begin
728      CaseOfEndRadioButton.Enabled := True;
729      CaseOfEndElseRadioButton.Enabled := True;
730      if IfThenRadioButton.Checked or IfThenElseRadioButton.Checked then
731        SourceNotebook.PageIndex := idxPageIf
732      else
733        SourceNotebook.PageIndex := idxPageCase;
734      //StringResultEdit.Enabled := false;
735      //StringResultEdit.Color := clBtnFace;
736      //IfResultComboBox.Enabled := true;
737      //IfResultComboBox.Color := clWindow;
738      //CaseResultCheckGroup.Enabled := true;
739      //CaseOfEndElseRadioButton.Enabled := true;
740      //CaseOfEndRadioButton.Enabled := true;
741    end;
742  end;
743
744//ShowMessage(); ShowMessageFmt(); ShowMessagePos();
745  case ComposedMsgKind of
746    cmkShowMsg,
747    cmkShowMsgFmt,
748    cmkShowMsgPos: SourceWrapperGroupBox.Enabled := false;
749    else
750      SourceWrapperGroupBox.Enabled := true;
751  end;
752
753//MessageDlg() Result
754  case ComposedMsgKind of
755    cmkMsgDlgSimple,
756    cmkMsgDlgCaption,
757    cmkMsgDlgCaptionHelpKeyWord,
758    cmkMsgDlgPosSimple,
759    cmkMsgDlgPosHelpSimple: begin
760      ListResult := TStringList.Create;
761      for indx := 0 to ButtonsCheckGroup.Items.Count-1 do
762        if ButtonsCheckGroup.Checked[indx] then begin
763          if ButtonsCheckGroup.Items[indx] = 'mbOK' then
764            ListResult.Add(ModalResultStr[mrOK]);
765          if ButtonsCheckGroup.Items[indx] = 'mbCancel' then
766            ListResult.Add(ModalResultStr[mrCancel]);
767          if ButtonsCheckGroup.Items[indx] = 'mbYes' then
768            ListResult.Add(ModalResultStr[mrYes]);
769          if ButtonsCheckGroup.Items[indx] = 'mbNo' then
770            ListResult.Add(ModalResultStr[mrNo]);
771          if ButtonsCheckGroup.Items[indx] = 'mbAbort' then
772            ListResult.Add(ModalResultStr[mrAbort]);
773          if ButtonsCheckGroup.Items[indx] = 'mbRetry' then
774            ListResult.Add(ModalResultStr[mrRetry]);
775          if ButtonsCheckGroup.Items[indx] = 'mbIgnore' then
776            ListResult.Add(ModalResultStr[mrIgnore]);
777          if ButtonsCheckGroup.Items[indx] = 'mbAll' then
778            ListResult.Add(ModalResultStr[mrAll]);
779          if ButtonsCheckGroup.Items[indx] = 'mbNoToAll' then
780            ListResult.Add(ModalResultStr[mrNoToAll]);
781          if ButtonsCheckGroup.Items[indx] = 'mbYesToAll' then
782            ListResult.Add(ModalResultStr[mrYesToAll]);
783          if (ButtonsCheckGroup.Items[indx] = 'mbClose')and
784             (ListResult.IndexOf(ModalResultStr[mrCancel]) = -1) then
785            ListResult.Add(ModalResultStr[mrCancel]);
786        end;
787      if ListResult.Text<>IfResultComboBox.Items.Text then begin
788        IfResultComboBox.Items := ListResult;
789        CaseResultCheckGroup.Items := ListResult;
790        if ListResult.Count>0 then begin
791          IfResultComboBox.ItemIndex := 0;
792          CaseResultCheckGroup.Checked[0] := true;
793        end;
794      end;
795      ListResult.Free;
796    end;
797  end;
798
799//QuestionDlg() Result
800  case ComposedMsgKind of
801    cmkQDlgHelpCtx,
802    cmkQDlgHelpKeyword: begin
803      ListResult := TStringList.Create;
804      ListResult.Assign(ButtonsStringGrid.Cols[1]);
805      ListResult.Delete(0);
806      if ListResult.Text<>IfResultComboBox.Items.Text then begin
807        IfResultComboBox.Items := ListResult;
808        CaseResultCheckGroup.Items := ListResult;
809        if ListResult.Count>0 then begin
810          IfResultComboBox.ItemIndex := 0;
811          CaseResultCheckGroup.Checked[0] := true;
812        end;
813      end;
814      ListResult.Free;
815    end;
816  end;
817
818//InputQuery() Result
819  case ComposedMsgKind of
820    cmkInpQMask,
821    cmkInpQSimple: if (CaseResultCheckGroup.Items.Count=0) or (CaseResultCheckGroup.Items[0]<>'false') then begin
822      CaseResultCheckGroup.Items.Clear;
823      CaseResultCheckGroup.Items.Add('false');
824      CaseResultCheckGroup.Items.Add('true');
825      IfResultComboBox.Items := CaseResultCheckGroup.Items;
826      IfResultComboBox.ItemIndex := 0;
827      CaseResultCheckGroup.Checked[0] := true;
828    end;
829  end;
830  ButtonsStringGrid.AutoAdjustColumns;
831  ButtonsPanel.Visible := not (ComposedMsgKind in [cmkShowMsg,cmkShowMsgPos,
832                                 cmkInpQMask,cmkInpQSimple,cmkInpBox,cmkPasswBox]);
833end;
834
835procedure TFormMessagesComposer.MessagesInitExecute(Sender: TObject);
836begin
837  XSpinEdit.MaxValue := Screen.Width;
838  XLabel.Caption := 'X ('+IntToStr(Screen.Width)+')';
839  YSpinEdit.MaxValue := Screen.Height;
840  YLabel.Caption := 'Y ('+IntToStr(Screen.Height)+')';
841  HelpContextSpinEdit.Width := 80;
842  XSpinEdit.Width := 60;
843  YSpinEdit.Width := 60;
844
845  KindMessageComboBox.Clear;
846  KindMessageCombobox.Items.AddStrings(ComposedMsgStrings);
847  KindMessageComboBox.ItemIndex := 0;
848  Caption := SMessageComposerCaption;
849  CaptionLabel.Caption := SDlgCaption;
850  DlgTypeLabel.Caption := SDlgType;
851  MsgLabel.Caption := SMsgCaption;
852  ButtonsCheckGroup.Caption := SButtonsTMsgDlgButtons;
853  ButtonsStringGrid.Cells[0,0] := SButtonsArrayOfConst;
854  ButtonsStringGrid.Cells[1,0] := SModalResult;
855  BitBtn1.Caption := SAdd;
856  BitBtn2.Caption := SDelete;
857  PromptLabel.Caption := SPromptCaption;
858  MaskInputCheckBox.Caption := SMaskInput;
859  ValueLabel.Caption := SValueVar;
860  DefaultValue.Caption := SDefault;
861  SourceWrapperGroupBox.Caption := SSourceWrapper;
862  KindMessageLabel.Caption := SKindofMessage;
863  Label1.Caption := SIfResult;
864  CaseResultCheckGroup.Caption := SCaseResult;
865  TestButton.Caption:=rsTest;
866  OkButton.Caption:=rsOk;
867  CancelButton.Caption:=rsCancel;
868  HelpContextLabel.Caption := SHelpContext;
869  HelpKeyWordLabel.Caption := SHelpKeyword;
870  HelpFileNameLabel.Caption := SHelpFilename;
871  MessageSetup.Execute;
872end;
873
874procedure TFormMessagesComposer.SetIfOrCaseExecute(Sender: TObject);
875var
876  ComposedMsgKind: TComposedMsgKind;
877begin
878  ComposedMsgKind := TComposedMsgKind(KindMessageComboBox.ItemIndex);
879  if (ComposedMsgKind in [cmkInpBox, cmkPasswBox]) then exit;
880  if IfThenRadioButton.Checked or IfThenElseRadioButton.Checked then
881    SourceNotebook.PageIndex := idxPageIf
882  else
883    SourceNotebook.PageIndex := idxPageCase;
884end;
885
886procedure TFormMessagesComposer.TestExecute(Sender: TObject);
887var Msg, MsgCaption, MsgHelpKeyword, HelpFileName, Prompt,
888    MsgDefault, Value: string;
889    DlgType: TMsgDlgType;
890    MsgButtons: TMsgDlgButtons;
891    HelpCtx: Longint;
892    X, Y: integer;
893    ComposedMsgKind: TComposedMsgKind;
894begin
895  Msg := MsgMemo.Lines.Text;
896  DlgType := TMsgDlgType(DlgTypeComboBox.ItemIndex);
897  MsgButtons := [];
898  if ButtonsCheckGroup.Checked[0] then
899    MsgButtons := MsgButtons+[mbYes];
900  if ButtonsCheckGroup.Checked[1] then
901    MsgButtons := MsgButtons+[mbNo];
902  if ButtonsCheckGroup.Checked[2] then
903    MsgButtons := MsgButtons+[mbOK];
904  if ButtonsCheckGroup.Checked[3] then
905    MsgButtons := MsgButtons+[mbCancel];
906  if ButtonsCheckGroup.Checked[4] then
907    MsgButtons := MsgButtons+[mbAbort];
908  if ButtonsCheckGroup.Checked[5] then
909    MsgButtons := MsgButtons+[mbRetry];
910  if ButtonsCheckGroup.Checked[6] then
911    MsgButtons := MsgButtons+[mbIgnore];
912  if ButtonsCheckGroup.Checked[7] then
913    MsgButtons := MsgButtons+[mbAll];
914  if ButtonsCheckGroup.Checked[8] then
915    MsgButtons := MsgButtons+[mbNoToAll];
916  if ButtonsCheckGroup.Checked[9] then
917    MsgButtons := MsgButtons+[mbYesToAll];
918  if ButtonsCheckGroup.Checked[10] then
919    MsgButtons := MsgButtons+[mbHelp];
920  if ButtonsCheckGroup.Checked[11] then
921    MsgButtons := MsgButtons+[mbClose];
922  MsgCaption := CaptionEdit.Text;
923  HelpCtx := HelpContextSpinEdit.Value;
924  HelpKeyword := HelpKeyWordEdit.Text;
925  X := XSpinEdit.Value;
926  Y := YSpinEdit.Value;
927  Prompt := PromptEdit.Text;
928  MsgDefault := DefaultEdit.Text;
929  Value := ValueEdit.Text;
930  HelpFileName:='';
931  MsgHelpKeyword:='';
932  ComposedMsgKind := TComposedMsgKind(KindMessageComboBox.ItemIndex);
933  case ComposedMsgKind of
934    cmkMsgDlgSimple: MessageDlg(Msg, DlgType, MsgButtons, HelpCtx);
935    cmkMsgDlgCaption: MessageDlg(MsgCaption, Msg, DlgType, MsgButtons, HelpCtx);
936    cmkMsgDlgCaptionHelpKeyWord: MessageDlg(MsgCaption, Msg, DlgType, MsgButtons, MsgHelpKeyword);
937    cmkMsgDlgPosSimple: MessageDlgPos(Msg, DlgType, MsgButtons, HelpCtx, X, Y);
938    cmkMsgDlgPosHelpSimple: MessageDlgPosHelp(Msg, DlgType, MsgButtons, HelpCtx, X, Y, HelpFileName);
939    cmkQDlgHelpCtx: QuestionDlg(MsgCaption, Msg+' ('+SNotImplementedYet+')', DlgType, [mrYes, 'Yes', mrNo, 'No',
940       mrCancel, 'Cancel'], HelpCtx);
941    cmkQDlgHelpKeyword: QuestionDlg(MsgCaption, Msg+' ('+SNotImplementedYet+')', DlgType, [mrYes, 'Yes', mrNo, 'No',
942       mrCancel, 'Cancel'], HelpKeyword);
943    cmkShowMsg: ShowMessage(Msg);
944    cmkShowMsgFmt: ShowMessageFmt(Msg+' ('+SNotImplementedYet+')', ['Yes','No','Cancel']);
945    cmkShowMsgPos: ShowMessagePos(Msg, X, Y);
946    cmkInpQMask: InputQuery(MsgCaption, Prompt, MaskInputCheckBox.Checked, Value);
947    cmkInpQSimple: InputQuery(MsgCaption, Prompt, Value);
948    cmkInpBox: InputBox(Caption, Prompt, MsgDefault);
949    cmkPasswBox: PasswordBox(MsgCaption, Prompt)
950  end;
951end;
952
953procedure TFormMessagesComposer.UpdateQuestioDlgResultExecute(Sender: TObject);
954var ListResult: TStringList;
955begin
956  ListResult := TStringList.Create;
957  ListResult.Assign(ButtonsStringGrid.Cols[1]);
958  ListResult.Delete(0);
959  if ListResult.Text<>IfResultComboBox.Items.Text then begin
960    IfResultComboBox.Items := ListResult;
961    CaseResultCheckGroup.Items := ListResult;
962    if ListResult.Count>0 then begin
963      IfResultComboBox.ItemIndex := 0;
964      CaseResultCheckGroup.Checked[0] := true;
965    end;
966  end;
967  ListResult.Free;
968end;
969
970{ Registers a keyboard shortcut and menu item in Lazarus}
971procedure Register;
972var
973  Key1,Key2: TIDEShortCut;
974  Cat: TIDECommandCategory;
975begin
976  Key1 := IDEShortCut(VK_M, [ssCtrl], VK_UNKNOWN, []);
977  Key2 := IDEShortCut(VK_UNKNOWN, [], VK_UNKNOWN, []);
978  Cat := IDECommandList.CreateCategory(Nil, cMessageComposer,
979                                       SMessageComposerCaption,
980                                       IDECmdScopeSrcEditOnly);
981
982  CmdMessageComposer := RegisterIDECommand(Cat, cMessageComposer,
983                                          SMessageComposerCaption,
984                                          Key1, Key2,nil,
985                                          @ExecuteMessagesComposer);
986
987  RegisterIDEMenuCommand(itmSourceTools, cMessageComposer,
988                         SMessageComposerMenuCaption,
989                         nil, nil, CmdMessageComposer);
990end;
991
992end.
993