1 unit main;
2 
3 {
4     GPSBabelGUI main unit/formular
5 
6     Copyright (C) 2005-2008 Olaf Klein, o.b.klein@gpsbabel.org
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
21 }
22 
23 interface
24 
25 uses
26   gnugettext, TypInfo, delphi,
27   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
28   StdCtrls, Buttons, ExtCtrls,
29   common, utils, ImgList, ActnList, Menus, ComCtrls, ToolWin, ActnMan,
30   ActnColorMaps;
31 
32 type
33   TfrmMain = class(TForm)
34     pnTop: TPanel;
35     pnBottom: TPanel;
36     cbWaypoints: TCheckBox;
37     cbRoutes: TCheckBox;
38     cbTracks: TCheckBox;
39     lbWhat: TLabel;
40     dlgFileOpen: TOpenDialog;
41     dlgFileSave: TSaveDialog;
42     wptInputOK: TSpeedButton;
43     ImageList1: TImageList;
44     wptOutputOK: TSpeedButton;
45     rteInputOK: TSpeedButton;
46     rteOutputOK: TSpeedButton;
47     trkInputOK: TSpeedButton;
48     trkOutputOK: TSpeedButton;
49     ActionList1: TActionList;
50     acLetsGo: TAction;
51     acFilterSelect: TAction;
52     stbMain: TStatusBar;
53     mnuMain: TMainMenu;
54     mnuFile: TMenuItem;
55     mnuExit: TMenuItem;
56     acFileExit: TAction;
57     mnuHelp: TMenuItem;
58     acHelpAbout: TAction;
59     acHelpIntro: TAction;
60     Intro1: TMenuItem;
61     About1: TMenuItem;
62     mnuReadme: TMenuItem;
63     acHelpDoc: TAction;
64     N1: TMenuItem;
65     mnuOptions: TMenuItem;
66     mnuSynthesizeShortNames: TMenuItem;
67     Filter1: TMenuItem;
68     N2: TMenuItem;
69     acOptionsSourceFormat: TAction;
70     acOptionsTargetFormat: TAction;
71     forsourceformat1: TMenuItem;
72     fortargetformat1: TMenuItem;
73     acFileClearMemo: TAction;
74     N3: TMenuItem;
75     Clearoutput1: TMenuItem;
76     acFinalizeDropDowns: TAction;
77     N4: TMenuItem;
78     mnuOptionsForceDataType: TMenuItem;
79     acOptionsEnableCharactersetTransformation: TAction;
80     Enablecharactersettransformation1: TMenuItem;
81     gbInput: TGroupBox;
82     sbOpenFile: TSpeedButton;
83     lbInputOpts: TLabel;
84     lbInputFormat: TLabel;
85     lbInputFile: TLabel;
86     edInputOpts: TComboBox;
87     edInputFile: TComboBox;
88     chbInputDevice: TCheckBox;
89     cbInputLang: TComboBox;
90     cbInputFormatDevice: TComboBox;
91     cbInputFormat: TComboBox;
92     cbInputDevice: TComboBox;
93     btnInputOpts: TSpeedButton;
94     gbOutput: TGroupBox;
95     cbOutputFormatDevice: TComboBox;
96     chbOutputDevice: TCheckBox;
97     lbOutputOpts: TLabel;
98     edOutputOpts: TComboBox;
99     btnOutputOpts: TSpeedButton;
100     lbOutputFormat: TLabel;
101     cbOutputFormat: TComboBox;
102     lbOutputFile: TLabel;
103     edOutputFile: TComboBox;
104     sbSaveFile: TSpeedButton;
105     cbOutputLang: TComboBox;
106     cbOutputDevice: TComboBox;
107     acFileOutputToScreen: TAction;
108     Outputtoscreen1: TMenuItem;
109     acDebugCreatePo: TAction;
110     mnuDebug: TMenuItem;
111     Createoptionspo1: TMenuItem;
112     acFileChangeLanguage: TAction;
113     mnuChangeLanguage: TMenuItem;
114     N5: TMenuItem;
115     acFileExportCSV: TAction;
116     Createoptionscsv1: TMenuItem;
117     File1: TMenuItem;
118     Createoptionscsv2: TMenuItem;
119     sdOptional: TSaveDialog;
120     PopupMenu: TPopupMenu;
121     acSelectAll: TAction;
122     pmnuSelectAll: TMenuItem;
123     acCopySelected: TAction;
124     pmnuCopySelected: TMenuItem;
125     pmnuClearOutput: TMenuItem;
126     pmnuOutputtoscreen: TMenuItem;
127     acOptionsSynthesizeShortNames: TAction;
128     pmnuSynthesizeshortnames: TMenuItem;
129     pmnu6: TMenuItem;
130     pmnu7: TMenuItem;
131     pmnuForsourceformat: TMenuItem;
132     pmuFortargetformat: TMenuItem;
133     pmnu8: TMenuItem;
134     pmnuLetsgo: TMenuItem;
135     memoOutput: TMemo;
136     pmnuEnablecharactersettransformation: TMenuItem;
137     acOptionsNukeTypes: TAction;
138     pmnuForceselectedGPSdatatypesnuketypesfilter: TMenuItem;
139     pmnu9: TMenuItem;
140     pmnuFilter: TMenuItem;
141     btnFilter: TBitBtn;
142     btnProcess: TBitBtn;
143     XPColorMap1: TXPColorMap;
144     procedure FormShow(Sender: TObject);
145     procedure FormCreate(Sender: TObject);
146     procedure OpenButtonClick(Sender: TObject);
147     procedure edInputFileChange(Sender: TObject);
148     procedure CheckInput;
149     procedure edOutputFileChange(Sender: TObject);
150     procedure cbWaypointsClick(Sender: TObject);
151     procedure cbRoutesClick(Sender: TObject);
152     procedure cbTracksClick(Sender: TObject);
153     procedure sbSaveFileClick(Sender: TObject);
154     procedure acLetsGoExecute(Sender: TObject);
155     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
156     procedure acFilterSelectExecute(Sender: TObject);
157     procedure acFileExitExecute(Sender: TObject);
158     procedure acHelpAboutExecute(Sender: TObject);
159     procedure chbInputDeviceClick(Sender: TObject);
160     procedure FormClose(Sender: TObject; var Action: TCloseAction);
161     procedure chbOutputDeviceClick(Sender: TObject);
162     procedure acHelpDocExecute(Sender: TObject);
163     procedure edOutputFileKeyPress(Sender: TObject; var Key: Char);
164     procedure cbInputFormatDeviceChange(Sender: TObject);
165     procedure cbOutputFormatDeviceChange(Sender: TObject);
166     procedure cbInputFormatChange(Sender: TObject);
167     procedure cbOutputFormatChange(Sender: TObject);
168     procedure acOptionsSourceFormatExecute(Sender: TObject);
169     procedure acOptionsTargetFormatExecute(Sender: TObject);
170     procedure btnInputOptsClick(Sender: TObject);
171     procedure acFileClearMemoExecute(Sender: TObject);
172     procedure acFinalizeDropDownsExecute(Sender: TObject);
173     procedure acOptionsEnableCharactersetTransformationExecute(
174       Sender: TObject);
175     procedure acFileOutputToScreenExecute(Sender: TObject);
176     procedure acDebugCreatePoExecute(Sender: TObject);
177     procedure acFileChangeLanguageExecute(Sender: TObject);
178     procedure acFileExportCSVExecute(Sender: TObject);
179     procedure cbOutputDeviceChange(Sender: TObject);
180     procedure cbInputDeviceChange(Sender: TObject);
181     procedure acSelectAllExecute(Sender: TObject);
182     procedure acCopySelectedExecute(Sender: TObject);
183     procedure PopupMenuPopup(Sender: TObject);
184     procedure acOptionsSynthesizeShortNamesExecute(Sender: TObject);
185     procedure acOptionsNukeTypesExecute(Sender: TObject);
186     procedure cbInputFormatExit(Sender: TObject);
187     procedure cbOutputFormatExit(Sender: TObject);
188   private
189     { Private-Deklarationen }
190     FCaps: TCapabilities;
191     FOpts: TOptions;
192     FLang: TStringList;
193     FFirstShow: Boolean;
194     FOutHandmade: Boolean;
195     FFmtIn, FFmtOut: string;
196     procedure AddToOutput(const Str: string);
197     procedure AddToOutputFmt(const Format: string; const Args: array of const);
198     procedure ComboBoxChanged(Source : TComboBox; IsInput, IsFile: Boolean);
199     procedure DoOnIdle(Sender: TObject; var Done: Boolean);
200     procedure EnableOptions(const Version: string);
HandleOptionsnull201     function HandleOptions(const Format: string; AObject: TObject; IsInput: Boolean): Boolean;
HandleOptionsDlgnull202     function HandleOptionsDlg(const Format: string; var str: string; IsInput: Boolean): Boolean;
203     procedure HandleParams;
204     procedure HistoryChanged(Box: TComboBox; Swap: Boolean = False);
205     procedure InitCombo(Target: TComboBox; IsInput, ForDevice: Boolean);
206     procedure InitializeSerialPorts;
207     procedure LoadLanguages;
208     procedure LoadFileFormats;
209     procedure LoadFilters;
210     procedure LoadVersion;
211     procedure RefreshDesign(FirstTime: Boolean = False);
212     procedure WMOPTIONSCHANGED(var Msg: TMessage); message WM_OPTIONS_CHANGED;
213     procedure WMSTARTUP(var Msg: TMessage); message WM_STARTUP;
214     procedure StoreProfiles;
215   public
216     { Public-Deklarationen }
217   end;
218 
219 var
220   frmMain: TfrmMain;
221 
222 implementation
223 
224 uses
225   filter, about, options, select;
226 
227 {$R *.DFM}
228 
229 procedure FixAlign(Control: TControl; ShiftLeft: Integer;
230   RightOfMe: TControl = nil);
231 var
232   Right: Integer;
233 begin
234   Right := Control.Parent.Left + Control.Parent.Width;
235 
236   if Assigned(RightOfMe) then
237     ShiftLeft := ShiftLeft + RightOfMe.Width;
238 
239   if (akLeft in Control.Anchors) then
240     Control.Width := Right - Control.Left - ShiftLeft
241   else if (akRight in Control.Anchors) then
242     Control.Left := Right - Control.Width - ShiftLeft;
243 end;
244 
ComboBoxSelectnull245 function ComboBoxSelect(AComboBox: TComboBox; const Item: string): Boolean;
246 var
247   i: Integer;
248 begin
249   i := AComboBox.Items.IndexOf(Item);
250   AComboBox.ItemIndex := i;
251   Result := (i >= 0);
252 end;
253 
254 { TfrmMain }
255 
256 procedure TfrmMain.RefreshDesign(FirstTime: Boolean);
257 begin
258   if not(FirstTime) then
259     ReTranslateComponent(SELF);
260 
261 // VS_FF_DEBUG	The file contains debugging information or is compiled with debugging features enabled.
262 // VS_FF_INFOINFERRED	The file's version structure was created dynamically;
263 //                      therefore, some of the members in this structure may be empty or incorrect.
264 //                      This flag should never be set in a file's VS_VERSION_INFO data.
265 // VS_FF_PATCHED	The file has been modified and is not identical to the original shipping file of the same version number.
266 // VS_FF_PRERELEASE	The file is a development version, not a commercially released product.
267 // VS_FF_PRIVATEBUILD	The file was not built using standard release procedures. If this flag is set,
268 //                      the StringFileInfo structure should contain a PrivateBuild entry.
269 // VS_FF_SPECIALBUILD	The file was built by the original company using standard release procedures
270 //                      but is a variation of the normal file of the same version number.
271 //                      If this flag is set, the StringFileInfo structure should contain a SpecialBuild
272 
273   if (CFixedFileinfo.dwFileFlags and VS_FF_DEBUG <> 0) then
274     Caption := Format('%s (%s)', [Caption, _('Internal development release')])
275   else if (CFixedFileinfo.dwFileFlags and VS_FF_PRERELEASE <> 0) then
276     Caption := Format('%s (%s)', [Caption, _('BETA')])
277   else if (CFixedFileinfo.dwFileFlags and VS_FF_PRIVATEBUILD <> 0) then
278     Caption := Format('%s (%s)', [Caption, _('Private release')])
279   else if (CFixedFileinfo.dwFileFlags and VS_FF_SPECIALBUILD <> 0) then
280     Caption := Format('%s (%s)', [Caption, _('Special release')]);
281 
282   FixAlign(sbOpenFile, 8);
283   FixAlign(sbSaveFile, 8);
284   FixAlign(edInputFile, 8, sbOpenFile);
285   FixAlign(edOutputFile, 8, sbSaveFile);
286 
287   FixAlign(cbInputLang, 8);
288   btnInputOpts.Left := lbInputOpts.Left + lbInputOpts.Width + 8;
289   edInputOpts.Left := btnInputOpts.Left + btnInputOpts.Width + 4;
290   edInputOpts.Width := cbInputLang.Left - edInputOpts.Left - 4;
291 
292   FixAlign(cbOutputLang, 8);
293   btnOutputOpts.Left := lbOutputOpts.Left + lbOutputOpts.Width + 8;
294   edOutputOpts.Left := btnOutputOpts.Left + btnOutputOpts.Width + 4;
295   edOutputOpts.Width := cbOutputLang.Left - edOutputOpts.Left - 4;
296 
297   FixAlign(btnProcess, 8);
298   FixAlign(btnFilter, 16, btnProcess);
299 
300   gbInput.Caption := '>>> ' + _('Input');
301   gbOutput.Caption := '<<< ' + _('Output');
302   chbInputDevice.Caption := '[' + chbInputDevice.Caption + ']';
303   chbOutputDevice.Caption := '[' + chbOutputDevice.Caption + ']';
304 
305   acOptionsSourceFormat.Caption := _('Input') + ': ' + FFmtIn;
306   acOptionsTargetFormat.Caption := _('Output') + ': ' + FFmtOut;
307 
308   btnInputOpts.Caption := '';
309   btnOutputOpts.Caption := '';
310 end;
311 
312 procedure TfrmMain.FormCreate(Sender: TObject);
313 begin
314   MakeFirstTranslation(Self);
315   FFirstShow := True;
316 
317   RestoreBounds('main_form', Self);
318 
319   TP_Ignore(mnuDebug, 'mnuDebug');
320 {$IFOPT D-}
321   mnuDebug.Visible := False;
322 {$ENDIF}
323   LoadLanguages;
324 
325   memoOutput.Lines.Clear;
326 
327   FCaps := TCapabilities.Create;
328   FOpts := TOptions.Create(FCaps);
329 
330   dlgFileOpen.InitialDir := ReadProfile(dlgFileOpen.Tag);
331   dlgFileSave.InitialDir := ReadProfile(dlgFileSave.Tag);
332 
333   if not ComboBoxSelect(cbInputDevice, ReadProfile(cbInputDevice.Tag)) then
334     cbInputDevice.ItemIndex := 0;
335 
336   if not ComboBoxSelect(cbOutputDevice, ReadProfile(cbOutputDevice.Tag)) then
337     cbOutputDevice.ItemIndex := 0;
338 
339   edInputFile.Text := ReadProfile(edInputFile.Tag);
340 
341   cbInputLang.ItemIndex := 0;
342   cbOutputLang.ItemIndex := 0;
343 
344   try
345     cbWaypoints.Checked := StrToBool(ReadProfile(cbWaypoints.Tag));
346   except
347     cbWaypoints.Checked := True;
348   end;
349   try
350     cbTracks.Checked := StrToBool(ReadProfile(cbTracks.Tag));
351   except
352     cbTracks.Checked := False;
353   end;
354   try
355     cbRoutes.Checked := StrToBool(ReadProfile(cbRoutes.Tag));
356   except
357     cbRoutes.Checked := False;
358   end;
359 
360   acCopySelected.Enabled := False;
361   acSelectAll.Enabled := False;
362 
363   Application.OnIdle := Self.DoOnIdle;
364 
365   RefreshDesign(True);
366   HandleParams;
367 end;
368 
369 procedure TfrmMain.LoadLanguages;
370 begin
371   FLang := TStringList.Create;
372 
373   DefaultInstance.GetListOfLanguages('default', FLang);
374   if (FLang.IndexOf('en') < 0) then
375     FLang.Add('en');
376   acFileChangeLanguage.Visible := (FLang.Count > 1);
377 end;
378 
379 procedure TfrmMain.LoadFileFormats;
380 var
381   l: TStrings;
382 begin
383   l := TStringList.Create;
384   try
385 
386     if (gpsbabel_vfmt >= '001.002.008') then
387       gpsbabel('-^3', l)
388     else if (gpsbabel_vfmt >= '001.002.005') then
389       gpsbabel('-^2', l)
390     else begin
391       MessageBox(0, PChar(gpsbabel_vfmt), 'Release info', MB_OK);
392       MessageDlg(_('The file "gpsbabel.exe" found in current directory is too old!'),
393         mtError, [mbOK], 0);
394       Halt(1);
395     end;
396 
397     FCaps.List := l;
398     FOpts.List := l;
399     InitCombo(cbInputFormatDevice, True, True);
400     InitCombo(cbOutputFormatDevice, False, True);
401     InitCombo(cbInputFormat, True, False);
402     InitCombo(cbOutputFormat, False, False);
403   finally
404     l.Free;
405   end;
406 end;
407 
408 procedure TfrmMain.LoadFilters;
409 var
410   l: TStrings;
411   i: Integer;
412   s: string;
413 begin
414   l := TStringList.Create;
415   try
416 
417     gpsbabel('-%0', l);
418 
419     for i := 0 to l.Count - 1 do
420     begin
421       s := l.Strings[i];
422       if (Trim(Copy(s, 1, 5)) = 'swap') then gpsbabel_knows_swap_filter := True;
423     end;
424 
425   finally
426     l.Free;
427   end;
428 end;
429 
430 procedure TfrmMain.FormShow(Sender: TObject);
431 begin
432   if not(FFirstShow) then Exit;
433 
434 {$IFDEF VER120}
435   // --------------------
436   // Bug (?) Delphi4-Std./Sp3
437   FixAlign(btnProcess, 8);
438   FixAlign(btnFilter, 16, btnProcess);
439   // --------------------
440 {$ENDIF}
441 
442   FFirstShow := False;
443   PostMessage(SELF.Handle, WM_STARTUP, 0, 0); // keep sure our window is visible
444 end;
445 
446 procedure TfrmMain.WMSTARTUP(var Msg: TMessage);
447 var
448   s: string;
449 begin
450 //  gpsbabel_ini := TIniFile.Create('gpsbabel.ini');
451   LoadVersion;
452   EnableOptions(gpsbabel_vfmt);
453   LoadFilters;
454   LoadFileFormats;
455 
456   // ? valid README form
457   s := ExtractFilePath(ParamStr(0)) + 'gpsbabel.html';
458   acHelpDoc.Enabled := FileExists(s);
459 
460   InitializeSerialPorts;
461 end;
462 
463 procedure TfrmMain.InitCombo(Target: TComboBox; IsInput, ForDevice: Boolean);
464 var
465   i: Integer;
466   OK: Boolean;
467   s: string;
468   cap : TCapability;
469 begin
470   for i := 0 to FCaps.Count - 1 do
471   begin
472     cap:=FCaps.Capability[i];
473     if (ForDevice and not cap.IsDevice) then Continue;
474     if not(ForDevice) and not cap.IsFile then Continue;
475 
476     if (IsInput) then
477       OK := Cap.ReadAny
478     else
479       OK := Cap.WriteAny;
480     if OK then
481     begin
482       if (Cap.Ext <> '') and (AnsiPos('.' + Cap.Ext, Cap.Description) = 0) then
483       begin
484         Cap.Description := Cap.Description + ' (.' + Cap.Ext + ')';
485       end;
486 
487       Target.Items.AddObject(Cap.Description, Cap);
488     end;
489   end;
490 
491   s := ReadProfile(Target.Tag);
492   ComboBoxSelect(Target, s);
493 
494   ComboBoxChanged(Target, IsInput, not(ForDevice));
495 end;
496 
497 procedure TfrmMain.OpenButtonClick(Sender: TObject);
498 var
499   s,ext: string;
500   i: Integer;
501   cap : TCapability;
502 begin
503   edInputFile.SetFocus;
504   dlgFileOpen.Filter := '';
505   dlgFileOpen.DefaultExt := '';
506 
507   s := '';
508   if (cbInputFormat.ItemIndex <> -1 ) then
509   begin
510     cap := FCaps.GetCapabilityByName(cbInputFormat.Text);
511     if (cap.Ext <> '') then
512     begin
513       s := Format('%s|*.%s|', [cbInputFormat.Text, cap.Ext]);
514       dlgFileOpen.DefaultExt := '*.' + cap.Ext;
515     end;
516   end;
517   s := s + _('All files (*.*)|*.*');
518 
519   dlgFileOpen.Filter := s;
520 
521   if (dlgFileOpen.InitialDir = '') then
522   begin
523     dlgFileOpen.InitialDir := SysUtils.ExtractFilePath(dlgFileSave.FileName);
524     if (dlgFileOpen.InitialDir = '') then
525       dlgFileOpen.InitialDir := dlgFileSave.InitialDir;
526     if (dlgFileOpen.InitialDir = '') then
527       dlgFileOpen.InitialDir := GetCurrentDir;
528   end;
529 
530   if not SELF.dlgFileOpen.Execute then Exit;
531 
532   edInputFile.Text := '';
533   for i := 0 to dlgFileOpen.Files.Count - 1 do
534   begin
535     s := dlgFileOpen.Files[i];
536     if (i = 0) then
537       dlgFileSave.InitialDir := ExtractFilePath(s);
538     if (s[1] <> '"') or (s[Length(s)] <> '"') then
539       s := AnsiQuotedStr(s, '"');
540     if (edInputFile.Text <> '') then edInputFile.Text := edInputFile.Text + ', ';
541     edInputFile.Text := edInputFile.Text + s;
542   end;
543 
544   CheckInput;
545 end;
546 
547 procedure TfrmMain.ComboBoxChanged(Source : TComboBox; IsInput, IsFile: Boolean);
548 var
549   caps: Integer;
550   ext: string;
551   ac: TAction;
552   capability : TCapability;
553 begin
554   if (Source.ItemIndex<0) then exit;
555   capability:=TCapability(Source.Items.Objects[Source.ItemIndex]);
556   ext := capability.Ext;
557   if IsFile and FOutHandmade and (ext = '') then
558   begin
559     ext := SysUtils.ExtractFileExt(edOutputFile.Text);
560     if (ext <> '') and (ext[1] = '.') then Delete(ext, 1, 1);
561   end;
562 
563   caps := capability.Capas;
564   if IsInput then
565   begin
566     FFmtIn := capability.Name;
567     wptInputOK.Enabled := (caps and 1 <> 0);
568     trkInputOK.Enabled := (caps and 4 <> 0);
569     rteInputOK.Enabled := (caps and 16 <> 0);
570   end
571     else
572   begin
573     FFmtOut := capability.Name;
574     wptOutputOK.Enabled := (caps and 2 <> 0);
575     trkOutputOK.Enabled := (caps and 8 <> 0);
576     rteOutputOK.Enabled := (caps and 32 <> 0);
577     if IsFile and (edOutputFile.Text <> '') and (edOutputFile.Text <> '-') then
578     begin
579       if (ext <> '') then FOutHandmade := False;
580       edOutputFile.Text := SysUtils.ChangeFileExt(edOutputFile.Text, '.' + ext);
581     end;
582   end;
583 
584   CheckInput;
585 
586   if IsInput then
587   begin
588     edInputOpts.Text := '';
589     edInputOpts.Items.Clear;
590 
591     ac := acOptionsSourceFormat;
592     acOptionsSourceFormat.Caption := _('Input') + ': ' + capability.Name;
593     btnInputOpts.Caption := '';
594   end
595   else begin
596     edOutputOpts.Text := '';
597     edOutputOpts.Items.Clear;
598 
599     ac := acOptionsTargetFormat;
600     acOptionsTargetFormat.Caption := _('Output') + ': ' + capability.Name;
601     btnOutputOpts.Caption := '';
602   end;
603 
604   ac.Enabled := FOpts.HasFormatOpts(capability);
605   if ac.Enabled then
606   begin
607     ac.Hint := SysUtils.Format(_('Select and edit options for "%s"'), [capability.Name]);
608   end
609     else
610   begin
611     ac.Hint := SysUtils.Format(_('No options available for "%s"'), [capability.Name]);
612   end;
613 end;
614 
615 procedure TfrmMain.edInputFileChange(Sender: TObject);
616 begin
617   CheckInput;
618 end;
619 
620 procedure TfrmMain.CheckInput;
621 begin
622   acLetsGo.Enabled :=
623   (cbWaypoints.Checked or cbRoutes.Checked or cbTracks.Checked)
624   and
625    (
626     ((chbInputDevice.Checked and
627     (cbInputDevice.Text <> '') and
628     (cbInputFormatDevice.Text <> ''))
629   or
630     (not(chbInputDevice.Checked) and
631     (edInputFile.Text <> '') and
632     (cbInputFormat.Text <> '')))
633   and
634     ((chbOutputDevice.Checked and
635     (cbOutputDevice.Text <> '') and
636     (cbOutputFormatDevice.Text <> ''))
637   or
638     (not(chbOutputDevice.Checked) and
639     (edOutputFile.Text <> '') and
640     (cbOutputFormat.Text <> '')))
641    );
642 end;
643 
644 procedure TfrmMain.edOutputFileChange(Sender: TObject);
645 begin
646   CheckInput;
647 end;
648 
649 procedure TfrmMain.cbWaypointsClick(Sender: TObject);
650 begin
651   CheckInput;
652 end;
653 
654 procedure TfrmMain.cbRoutesClick(Sender: TObject);
655 begin
656   CheckInput;
657 end;
658 
659 procedure TfrmMain.cbTracksClick(Sender: TObject);
660 begin
661   CheckInput;
662 end;
663 
664 procedure TfrmMain.sbSaveFileClick(Sender: TObject);
665 var
666   s: string;
667   cap: TCapability;
668 begin
669   edOutputFile.SetFocus;
670   dlgFileSave.Filter := '';
671   dlgFileSave.DefaultExt := '';
672 
673   s := '';
674   if (cbOutputFormat.ItemIndex <> -1) then
675   begin
676     cap := FCaps.GetCapabilityByName(cbOutputFormat.Text);
677     if (cap.Ext <> '') then
678     begin
679       s := Format('%s|*.%s|',[cbOutputFormat.Text, cap.Ext]);
680       dlgFileSave.DefaultExt := '*.' + cap.Ext;
681     end;
682   end;
683   s := s + _('All files|*.*');
684 
685   dlgFileSave.Filter := s;
686 
687 
688   if (dlgFileSave.InitialDir = '') then
689   begin
690     dlgFileSave.InitialDir := SysUtils.ExtractFilePath(dlgFileOpen.FileName);
691     if (dlgFileSave.InitialDir = '') then
692       dlgFileSave.InitialDir := dlgFileOpen.InitialDir;
693     if (dlgFileSave.InitialDir = '') then
694       dlgFileSave.InitialDir := GetCurrentDir;
695   end;
696 
697   if not SELF.dlgFileSave.Execute then Exit;
698 
699   edOutputFile.Text := dlgFileSave.FileName;
700   dlgFileSave.InitialDir := SysUtils.ExtractFilePath(dlgFileSave.FileName);
701 
702   CheckInput;
703 end;
704 
705 procedure TfrmMain.acLetsGoExecute(Sender: TObject);
706 var
707   cmdline: string;
708   list, files: TStrings;
709   CSave: TCursor;
710   str: TStream;
711   s, tmp: string;
712   i: Integer;
713   IFormat, OFormat, IFiles: string;
714   Fatal: Boolean;
715   sp: PChar;
716   cap : TCapability;
717 begin
718   memoOutput.SetFocus;
719   acLetsGo.Enabled := False;
720   try
721     acFinalizeDropDownsExecute(nil);
722 
723     cmdline := '';
724     if gpsbabel_knows_inifile then cmdline := '-p ""';
725 
726     if chbInputDevice.Checked then
727       cap:= TCapability(cbInputFormatDevice.Items.Objects[cbInputFormatDevice.ItemIndex])
728     else
729       cap:= TCapability(cbInputFormat.Items.Objects[cbInputFormat.ItemIndex]);
730     IFormat :=cap.Name;
731 
732     if chbOutputDevice.Checked then
733       cap:= TCapability(cbOutputFormatDevice.Items.Objects[cbOutputFormatDevice.ItemIndex])
734     else
735       cap:= TCapability(cbOutputFormat.Items.Objects[cbOutputFormat.ItemIndex]);
736     OFormat := cap.Name;
737     if cbWaypoints.Checked then cmdline := cmdline + ' -w';
738     if cbRoutes.Checked then cmdline := cmdline + ' -r';
739     if cbTracks.Checked then cmdline := cmdline + ' -t';
740 
741     if acOptionsSynthesizeShortNames.Checked then cmdline := cmdline + ' -s';
742 
743     if chbInputDevice.Checked then
744     begin
745       IFiles := '-f ' + SysUtils.AnsiLowerCase(cbInputDevice.Text) + ':';
746 //    if (s = 'usb:') then
747 //      s := s + '-1';
748     end
749       else
750     begin
751      IFiles := '';
752      files := TStringList.Create;
753       try
754         if (edInputFile.Text[1] <> '"') then
755           files.CommaText := AnsiQuotedStr(edInputFile.Text, '"')
756         else
757           files.CommaText := edInputFile.Text;
758         for i := 0 to files.Count - 1 do
759         begin
760           s := files.Strings[i];
761           if not(FileExists(s)) then
762             raise eGPSBabelError.CreateFmt(_('File %s not found.'), [s]);
763           if (IFiles <> '') then IFiles := IFiles + ' ';
764           IFiles := IFiles + '-f ' + AnsiQuotedStr(s, '"');
765         end;
766       finally
767         files.Free;
768       end;
769     end;
770 
771     // Input character set
772 
773     if acOptionsEnableCharactersetTransformation.Checked and
774        (cbInputLang.ItemIndex > 0) then
775       cmdline := Format('%s -c %s',
776         [cmdline, cbInputLang.Text]);
777 
778     if (Trim(edInputOpts.Text) <> '') then
779       cmdline := Format('%s -i %s,%s %s',
780         [cmdline, IFormat, Trim(edInputOpts.Text), IFiles])
781     else
782       cmdline := Format('%s -i %s %s',
783         [cmdline, IFormat, IFiles]);
784 
785     if mnuOptionsForceDataType.Checked then
786     begin
787       s := '';
788       if not(cbWaypoints.Checked) then
789         s := s + ',waypoints';
790       if not(cbRoutes.Checked) then
791         s := s + ',routes';
792       if not(cbTracks.Checked) then
793         s := s + ',tracks';
794       if (s <> '') then
795         cmdline := Format('%s -x nuketypes%s', [cmdline, s]);
796     end;
797 
798     // Add filter options
799 
800     if (frmFilter <> nil) then
801       cmdline := cmdline + frmFilter.CmdLine;
802 
803     // Output character set
804 
805     if acOptionsEnableCharactersetTransformation.Checked and
806        (cbOutputLang.ItemIndex > 0) then
807       cmdline := Format('%s -c %s',
808         [cmdline, cbOutputLang.Text]);
809 
810     if (chbOutputDevice.Checked) then
811     begin
812       if (cbOutputDevice.Text = 'SCREEN') then
813         s := '-'
814       else begin
815         s := AnsiLowerCase(cbOutputDevice.Text + ':');
816 //      if (s = 'usb:') then
817 //        s := s + '-1';
818       end;
819     end
820     else begin
821       s := Trim(edOutputFile.Text);
822       if (s <> '') and (s[1] <> '"') then s := AnsiQuotedStr(s, '"');
823       if (CharCount(s, '"') mod 2 <> 0) then
824       begin
825         MessageDlg(_('Invalid usage of character ''"''!'), mtError, [mbOK], 0);
826         Exit;
827       end;
828       sp := PChar(s);
829       tmp := AnsiExtractQuotedStr(sp, '"');
830       if (tmp <> '') then s := tmp;
831 
832       if (s <> '-') then
833       begin
834         if FileExists(s) then
835         begin
836           if (MessageDlg(Format(_('File "%s" exists ! Overwrite ?'), [s]),
837             mtWarning, [mbYes, mbNO], 0) <> mrYes) then Exit;
838         end
839           else
840         begin
841           str := TFileStream.Create(s, fmCreate);
842           str.Free;
843         end;
844         s := AnsiQuotedStr(s, '"');
845       end
846       else
847         s := '-';
848     end;
849 
850     if (Trim(edOutputOpts.Text) <> '') then
851       cmdline := Format('%s -o %s,%s -F %s',
852         [cmdline, OFormat, Trim(edOutputOpts.Text), s])
853     else
854       cmdline := Format('%s -o %s -F %s',
855         [cmdline, OFormat, s]);
856 
857     while (cmdline[1] = ' ') do System.Delete(cmdline, 1, 1);
858 
859     s := 'gpsbabel.exe ' + cmdline;
860     AddToOutput(s);
861 
862     CSave := Cursor;
863     list := TStringList.Create;
864     try
865       Cursor := crHourGlass;       // doesn't work ???
866       Application.ProcessMessages; // doesn't work ???
867       Sleep(50);
868 
869       if not gpsbabel(cmdline, list, @Fatal, False) then
870         raise eGPSBabelError.Create(_('Could not run "gpsbabel.exe"!'));
871 
872       if (list.Count > 0) then
873       begin
874         AddToOutput('');
875         AddToOutput(string(list.GetText));
876       end;
877 
878       if (Fatal) then
879         MessageDlg(_('Sorry, gpsbabel.exe reported problems!'), mtError, [mbOK], 0)
880       else
881         MessageDlg(Format(_('Converted successfully from "%s" to "%s".'), [IFormat, OFormat]),
882           mtInformation, [mbOK], 0);
883 
884     finally
885 
886       Cursor := CSave;
887       list.Free;
888 
889     end;
890 
891   finally
892     acLetsGo.Enabled := True;
893   end;
894 end;
895 
896 procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
897 begin
898   CanClose := True;
899 end;
900 
901 procedure TfrmMain.acFilterSelectExecute(Sender: TObject);
902 begin
903   if (frmFilter = nil) then
904     Application.CreateForm(TfrmFilter, frmFilter);
905   if not(frmFilter.ShowModal = mrOk) then Exit;
906 end;
907 
908 procedure TfrmMain.AddToOutput(const Str: string);
909 begin
910   memoOutput.Lines.Add(Str);
911 end;
912 
913 procedure TfrmMain.AddToOutputFmt(const Format: string;
914   const Args: array of const);
915 begin
916   AddToOutput(SysUtils.Format(Format, Args));
917 end;
918 
919 procedure TfrmMain.acFileExitExecute(Sender: TObject);
920 begin
921   PostMessage(SELF.Handle, WM_CLOSE, 0, 0);
922 end;
923 
924 procedure TfrmMain.LoadVersion;
925 var
926   l, l2: TStringList;
927   i: Integer;
928   s: string;
929   cx: PChar;
930 
931   procedure SpaceDelimited(const str: string; list: TStrings);
932   var
933     s: string;
934     cin, cend, cx: PChar;
935   begin
936     s := Trim(str);
937     cin := PChar(s);
938     cend := cin + StrLen(cin);
939     while (cin < cend) do
940     begin
941       while (cin^ = ' ') do cin := cin + 1;
942       cx := StrScan(cin, ' ');
943       if (cx = nil) then cx := cend;
944       cx^ := #0;
945       list.Add(string(cin));
946       cin := cx + 1;
947     end;
948   end;
949 
950 begin
951   gpsbabel_major := 0;
952   gpsbabel_minor := 0;
953   gpsbabel_release := 0;
954 
955   l := TStringList.Create;
956   try
957 
958     try
959       if not gpsbabel('-p "" -V', l) then
960         PostMessage(Self.Handle, WM_QUIT, 0, 0);
961     except
962       on E: Exception do
963       begin
964         ShowException(E, nil);
965         PostMessage(Self.Handle, WM_QUIT, 0, 0);
966       end;
967     end;
968 
969     for i := 0 to l.Count - 1 do
970     begin
971       s := Trim(l.Strings[i]);
972       if (Copy(AnsiUpperCase(s), 1, 8) = 'GPSBABEL') then
973       begin
974         l2 := TStringList.Create;
975         try
976           SpaceDelimited(s, l2);
977           gpsbabel_version := l2[2];
978           cx := PChar(gpsbabel_version);
979           gpsbabel_major := atoi(cx);
980           cx := StrScan(cx, '.');
981           if (cx <> nil) then
982           begin
983             gpsbabel_minor := atoi(cx + 1);
984             cx := StrScan(cx + 1, '.');
985             if (cx <> nil) then
986               gpsbabel_release := atoi(cx + 1);
987           end;
988 
989           gpsbabel_vfmt := Format('%3.3d.%3.3d.%3.3d', [
990             gpsbabel_major, gpsbabel_minor, gpsbabel_release]);
991 
992           s := Format(_('GPSBabel, version %s'), [gpsbabel_version]);
993           stbMain.Panels[0].Text := s;
994           stbMain.Panels[0].Width := stbMain.Canvas.TextWidth(s) +
995             Trunc((Length(s)* 1.5));
996           Break;
997         finally
998           l2.Free;
999         end;
1000       end;
1001     end;
1002 
1003   finally
1004     l.Free;
1005   end;
1006 end;
1007 
1008 procedure TfrmMain.acHelpAboutExecute(Sender: TObject);
1009 begin
1010   if (frmAbout = nil) then
1011     Application.CreateForm(TfrmAbout, frmAbout);
1012   frmAbout.ShowModal;
1013 end;
1014 
1015 procedure TfrmMain.chbInputDeviceClick(Sender: TObject);
1016 begin
1017   if not(Sender is TCheckBox) then Exit;
1018 
1019   if TCheckBox(Sender).Checked then
1020   begin
1021     edInputFile.Visible := False;
1022     sbOpenFile.Visible := False;
1023     cbInputFormat.Visible := False;
1024     cbInputDevice.Visible := True;
1025     cbInputFormatDevice.Visible := True;
1026     lbInputFile.Caption := _('Port');
1027     FFmtIn := cbInputFormatDevice.Text;
1028   end
1029     else
1030   begin
1031     cbInputFormat.Visible := True;
1032     cbInputFormatDevice.Visible := False;
1033     cbInputDevice.Visible := False;
1034     edInputFile.Visible := True;
1035     cbInputDevice.Visible := False;
1036     sbOpenFile.Visible := True;
1037     lbInputFile.Caption := _('File');
1038     FFmtIn := cbInputFormat.Text;
1039   end;
1040   acOptionsSourceFormat.Caption := _('Input') + ': ' + FFmtIn;
1041   acOptionsSourceFormat.Enabled := (FOpts.FormatOpts(FFmtIn) <> nil);
1042   CheckInput;
1043 end;
1044 
1045 procedure TfrmMain.StoreProfiles;
1046 var
1047   s: string;
1048 begin
1049   if (dlgFileOpen.Files.Count > 0) then
1050     s := SysUtils.ExtractFilePath(dlgFileOpen.Files[0])
1051   else
1052     s := SysUtils.ExtractFilePath(dlgFileOpen.FileName);
1053   if (s <> '') then
1054     StoreProfile(dlgFileOpen.Tag, s);
1055   if (edOutputFile.Text = '-') then
1056     s := dlgFileSave.InitialDir
1057   else
1058     s := SysUtils.ExtractFilePath(edOutputFile.Text);
1059   if (s <> '') then
1060     StoreProfile(dlgFileSave.Tag, s);
1061   StoreProfile(cbInputFormat.Tag, cbInputFormat.Text);
1062   StoreProfile(cbOutputFormat.Tag, cbOutputFormat.Text);
1063   StoreProfile(cbInputDevice.Tag, cbInputDevice.Text);
1064   StoreProfile(cbInputFormatDevice.Tag, cbInputFormatDevice.Text);
1065   StoreProfile(cbOutputDevice.Tag, cbOutputDevice.Text);
1066   StoreProfile(cbOutputFormatDevice.Tag, cbOutputFormatDevice.Text);
1067   StoreProfile(edInputFile.Tag, edInputFile.Text);
1068   StoreProfile(cbWayPoints.Tag, BoolToStr(cbWayPoints.Checked,true));
1069   StoreProfile(cbRoutes.Tag, BoolToStr(cbRoutes.Checked,true));
1070   StoreProfile(cbTracks.Tag, BoolToStr(cbTracks.Checked,true));
1071 end;
1072 
1073 procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
1074 begin
1075   StoreProfiles;
1076   StoreBounds('main_form', Self);
1077 end;
1078 
1079 procedure TfrmMain.chbOutputDeviceClick(Sender: TObject);
1080 begin
1081   if not(Sender is TCheckBox) then Exit;
1082 
1083   if TCheckBox(Sender).Checked then
1084   begin
1085     cbOutputFormatDevice.Visible := True;
1086     cbOutputDevice.Visible := True;
1087     edOutputFile.Visible := False;
1088     sbSaveFile.Visible := False;
1089     cbOutputFormat.Visible := False;
1090     lbOutputFile.Caption := _('Port');
1091     FFmtOut := cbOutputFormatDevice.Text;
1092   end
1093     else
1094   begin
1095     cbOutputFormat.Visible := True;
1096     sbSaveFile.Visible := True;
1097     edOutputFile.Visible := True;
1098     cbOutputDevice.Visible := False;
1099     cbOutputFormatDevice.Visible := False;
1100     lbOutputFile.Caption := _('File');
1101     FFmtOut := cbOutputFormat.Text;
1102   end;
1103   acOptionsTargetFormat.Caption := _('Output') + ': ' + FFmtOut;
1104   acOptionsTargetFormat.Enabled := (FOpts.FormatOpts(FFmtOut) <> nil);
1105   CheckInput;
1106 end;
1107 
1108 procedure TfrmMain.acHelpDocExecute(Sender: TObject);
1109 var
1110   s: string;
1111 begin
1112   s := ExtractFilePath(ParamStr(0)) + 'gpsbabel.html';
1113   if FileExists(s) then
1114     WinOpenFile(s, '')   // new gpsbabel.html
1115 end;
1116 
1117 procedure TfrmMain.edOutputFileKeyPress(Sender: TObject; var Key: Char);
1118 begin
1119   FOutHandmade := True;
1120 end;
1121 
1122 procedure TfrmMain.cbInputFormatDeviceChange(Sender: TObject);
1123 begin
1124   ComboBoxChanged(cbInputFormatDevice, True, False);
1125 end;
1126 
1127 procedure TfrmMain.cbInputFormatExit(Sender: TObject);
1128 begin
1129   if (cbInputFormat.ItemIndex=-1) then cbInputFormat.ItemIndex:=0;
1130 end;
1131 
1132 procedure TfrmMain.cbOutputFormatDeviceChange(Sender: TObject);
1133 begin
1134   ComboBoxChanged(cbOutputFormatDevice, False, False);
1135 end;
1136 
1137 procedure TfrmMain.cbOutputFormatExit(Sender: TObject);
1138 begin
1139   if (cbOutputFormat.ItemIndex=-1) then cbOutputFormat.ItemIndex:=0;
1140 end;
1141 
1142 procedure TfrmMain.cbInputFormatChange(Sender: TObject);
1143 begin
1144   ComboBoxChanged(cbInputFormat, True, True);
1145 end;
1146 
1147 procedure TfrmMain.cbOutputFormatChange(Sender: TObject);
1148 begin
1149   ComboBoxChanged(cbOutputFormat, False, True);
1150 end;
1151 
1152 procedure TfrmMain.acOptionsSourceFormatExecute(Sender: TObject);
1153 begin
1154   if chbInputDevice.Checked then
1155     HandleOptions(cbInputFormatDevice.Text, edInputOpts, True)
1156   else
1157     HandleOptions(cbInputFormat.Text, edInputOpts, True)
1158 end;
1159 
1160 procedure TfrmMain.DoOnIdle(Sender: TObject; var Done: Boolean);
1161 begin
1162   inherited;
1163   acFileClearMemo.Enabled := (memoOutput.Lines.Count > 0);
1164   Done := True;
1165 end;
1166 
1167 procedure TfrmMain.EnableOptions(const Version: string);
1168 begin
1169     if (Version >= '001.002.008') then
1170       mnuOptionsForceDataType.Enabled := True;
1171     if (version >= '001.002.007') then
1172       acOptionsEnableCharactersetTransformation.Enabled := True;
1173 end;
1174 
HandleOptionsnull1175 function TfrmMain.HandleOptions(const Format: string; AObject: TObject; IsInput: Boolean): Boolean;
1176 var
1177   s: string;
1178   ok: Boolean;
1179 begin
1180   s := GetStrProp(AObject, 'Text');
1181   if HandleOptionsDlg(Format, s, IsInput) then
1182   begin
1183     SetStrProp(AObject, 'Text', s);
1184     Result := True;
1185   end
1186   else
1187     Result := False;
1188 end;
1189 
HandleOptionsDlgnull1190 function TfrmMain.HandleOptionsDlg(const Format: string; var str: string; IsInput: Boolean): Boolean;
1191 begin
1192   Application.CreateForm(TfrmOptions, frmOptions);
1193   try
1194     frmOptions.Caption := SysUtils.Format(_('Options for "%s"'), [Format]);
1195     frmOptions.FIsInput := IsInput;
1196     frmOptions.Opts := FOpts.FormatOpts(Format);
1197     frmOptions.OptsStr := str;
1198     Result := (frmOptions.ShowModal = mrOk);
1199     if (Result) then
1200     begin
1201       str := frmOptions.OptsStr;
1202       PostMessage(Self.Handle, WM_OPTIONS_CHANGED, 0, 0);
1203     end;
1204   finally
1205     frmOptions.Release;
1206   end;
1207 end;
1208 
1209 procedure TfrmMain.acOptionsTargetFormatExecute(Sender: TObject);
1210 begin
1211   if chbOutputDevice.Checked then
1212     HandleOptions(cbOutputFormatDevice.Text, edOutputOpts, False)
1213   else
1214     HandleOptions(cbOutputFormat.Text, edOutputOpts, False);
1215 end;
1216 
1217 procedure TfrmMain.btnInputOptsClick(Sender: TObject);
1218 begin
1219   acOptionsSourceFormat.Execute;
1220 end;
1221 
1222 procedure TfrmMain.acFileClearMemoExecute(Sender: TObject);
1223 begin
1224   memoOutput.Clear;
1225 end;
1226 
1227 procedure TfrmMain.acFinalizeDropDownsExecute(Sender: TObject);
1228 var
1229  i, j: Integer;
1230  c: TComponent;
1231  cb: TComboBox;
1232 begin
1233   for i := 0 to ComponentCount - 1 do
1234   begin
1235     c := Components[i];
1236     if not(c is TComboBox) then Continue;
1237     cb := Pointer(c);
1238     if (cb.Style <> csDropDown) or (cb.Text = '') then Continue;
1239     j := cb.Items.IndexOf(cb.Text);
1240     if (j < 0) then
1241       cb.Items.Insert(0, cb.Text);
1242   end;
1243 end;
1244 
1245 procedure TfrmMain.WMOPTIONSCHANGED(var Msg: TMessage);
1246 begin
1247   acFinalizeDropDowns.Execute;
1248 end;
1249 
1250 procedure TfrmMain.acOptionsEnableCharactersetTransformationExecute(
1251   Sender: TObject);
1252 begin
1253   acOptionsEnableCharactersetTransformation.Checked := not (
1254     acOptionsEnableCharactersetTransformation.Checked);
1255 
1256   cbInputLang.Enabled := acOptionsEnableCharactersetTransformation.Checked;
1257   cbOutputLang.Enabled := acOptionsEnableCharactersetTransformation.Checked;
1258 end;
1259 
1260 procedure TfrmMain.acFileOutputToScreenExecute(Sender: TObject);
1261 begin
1262   if (chbOutputDevice.Checked) then
1263   begin
1264     chbOutputDevice.Checked := False;
1265     chbOutputDeviceClick(chbOutputDevice);
1266     Application.ProcessMessages;
1267   end;
1268 
1269   acFileOutputToScreen.Checked := not (acFileOutputToScreen.Checked);
1270   if acFileOutputToScreen.Checked then
1271   begin
1272     chbOutputDevice.Enabled := False;
1273     HistoryChanged(edOutputFile);
1274     edOutputFile.Text := '-';
1275     edOutputFile.Enabled := False;
1276     edOutputFile.Color := clInactiveBorder;
1277     sbSaveFile.Enabled := False;
1278   end
1279     else
1280   begin
1281     edOutputFile.Color := edInputFile.Color;
1282     chbOutputDevice.Enabled := True;
1283     edOutputFile.Enabled := True;
1284     edOutputFile.Text := '';
1285     HistoryChanged(edOutputFile, True);
1286     sbSaveFile.Enabled := True;
1287   end;
1288   CheckInput;
1289 end;
1290 
1291 procedure TfrmMain.HandleParams;
1292 var
1293   i: Integer;
1294   s: string;
1295 begin
1296   for i := 1 to ParamCount do
1297   begin
1298     s := ParamStr(i);
1299     if (i = 0) then
1300       edInputFile.Text := s
1301     else begin
1302       if (i = 1) then
1303         edInputFile.Items.Add(edInputFile.Text);
1304       edInputFile.Items.Add(s);
1305     end;
1306   end;
1307 end;
1308 
1309 procedure TfrmMain.HistoryChanged(Box: TComboBox; Swap: Boolean);
1310 var
1311   index: Integer;
1312   item: string;
1313 begin
1314   item := Trim(Box.Text);
1315   if (item <> '') then
1316   begin
1317     index := Box.Items.IndexOf(item);
1318     if (index < 0) then
1319       Box.Items.Insert(0, item)
1320     else
1321       Box.Items.Move(index, 0);
1322   end;
1323   if (swap and (Box.Items.Count > 1)) then
1324     Box.ItemIndex := 1;
1325 end;
1326 
1327 procedure TfrmMain.acDebugCreatePoExecute(Sender: TObject);
1328 var
1329   l: TStringList;
1330   i, j, len: Integer;
1331   s: string;
1332   f: TFileStream;
1333 
1334   procedure WriteLn(Str: string);
1335   begin
1336     Str := Str + #13#10;
1337     f.Write(PChar(Str)^, Length(Str));
1338   end;
1339 
1340 begin
1341   l := TStringList.Create;
1342   try
1343     FOpts.DebugGetHints(l);
1344     f := TFileStream.Create('..\gpsbabel.po', fmCreate);
1345     try
1346       WriteLn('msgid ""');
1347       WriteLn('msgstr ""');
1348       WriteLn('');
1349 
1350       for i := 0 to l.Count - 1 do
1351       begin
1352         s := l.Strings[i];
1353         len := Length(s);
1354         for j := len downto 1 do
1355         begin
1356           if (s[j] = '"') then
1357           begin
1358             Insert('\', s, j);
1359           end;
1360         end;
1361         WriteLn('msgid "' + s + '"');
1362         WriteLn('msgstr ""');
1363         WriteLn('');
1364       end;
1365       MessageDlg('..\gpsbabel.po created!', mtInformation, [mbok], 0);
1366     finally
1367       f.Free;
1368     end;
1369   finally
1370     l.Free;
1371   end;
1372 end;
1373 
1374 procedure TfrmMain.acFileChangeLanguageExecute(Sender: TObject);
1375 var
1376   lang: string;
1377   form: TForm;
1378   title: string;
1379 begin
1380   Title := _('Choose language') + ' ' + _('for GUIBabelGUI');
1381   if SelectLanguage(Title, FLang, lang) and
1382     (CompareText(lang, Copy(GetCurrentLanguage, 1, 2)) <> 0) then
1383   begin
1384     StoreProfile(11, lang);
1385     UseLanguage(lang);
1386     RefreshDesign;
1387     form := frmFilter;
1388     frmFilter := nil;
1389     if (Form <> nil) then Form.Release;
1390     form := frmAbout;
1391     frmAbout := nil;
1392     if (Form <> nil) then Form.Release;
1393   end;
1394 end;
1395 
1396 procedure TfrmMain.acFileExportCSVExecute(Sender: TObject);
1397 const
1398   init_dir: string = '';
1399   file_name: string = 'gpsbabel.csv';
1400 var
1401   i, j, len: Integer;
1402   s, lang, curr_lang: string;
1403   o: POption;
1404   f: TFileStream;
1405   l: TStrings;
1406 
_translatenull1407   function _translate(const Domain, MsgID: string): WideString;
1408   var
1409     i: Integer;
1410     tmp: WideString;
1411     boo: Boolean;
1412   begin
1413     tmp := MsgID;
1414     Result := dgettext(Domain, tmp);
1415     if (Result = tmp) then
1416       Result := _(MsgID);
1417     if (Result = tmp) then
1418       Result := ''
1419     else begin
1420       boo := False;
1421       i := Length(Result);
1422       while (i >= 1) do
1423       begin
1424         if (Result[i] = '"') then
1425         begin
1426           Insert('"', Result, i);
1427           boo := True;
1428         end;
1429         Dec(i);
1430       end;
1431       if (boo) then
1432       begin
1433         memoOutput.Lines.Add('Warning: ''"'' found in translation!');
1434         memoOutput.Lines.Add(Result);
1435       end;
1436     end;
1437   end;
1438 
1439   procedure _line(const Prefix, MsgID: string);
1440   begin
1441     UniWriteLn(f, Prefix + ',"' + MsgID + '","' +
1442                   _translate(GPSBabel_Domain, MsgID) + '"');
1443   end;
1444 
1445 var
1446   cap : TCapability;
1447 
1448 begin
1449   if not SelectLanguage(
1450     _('Choose language') + ' ' + _('for export'),
1451     FLang, lang) then Exit;
1452 
1453   if (sdOptional.InitialDir = '') then
1454     GetDir(0, init_dir);
1455 
1456   sdOptional.InitialDir := init_dir;
1457   sdOptional.FileName := file_name;
1458 
1459   if not(sdOptional.Execute) then Exit;
1460 
1461   init_dir := sdOptional.InitialDir;
1462   file_name := sdOptional.FileName;
1463 
1464   curr_lang := GetCurrentLanguage;
1465   try
1466 
1467     UseLanguage(lang);
1468 
1469     f := TFileStream.Create(sdOptional.FileName, fmCreate);
1470     try
1471 
1472       UniWriteLn(f, Format('code,en,%s', [lang]));
1473 
1474       _line('options:-w', 'Process waypoint information');
1475       _line('options:-r', 'Process route information');
1476       _line('options:-t', 'Process track information');
1477 
1478       _line('options:-s', 'Synthesize shortnames');
1479       _line('options:-c', 'Character set for next operation');
1480 
1481 
1482       for i := 0 to FCaps.Count - 1 do
1483       begin
1484         cap:=FCaps.Capability[i];
1485         if not Cap.IsFile then Continue;
1486 
1487         s := Cap.Description;
1488         UniWrite(f, Format('format:%s,', [Cap.Name]));
1489         UniWriteLn(f, '"' + s + '","' + _translate(GPSBabel_Domain, s) + '"');
1490 
1491         l := FOpts.FormatOpts(s);
1492         if (l = nil) then Continue;
1493 
1494         for j := 0 to l.Count - 1 do
1495         begin
1496           o := Pointer(l.Objects[j]);
1497           UniWrite(f, Format('format:%s:%s,', [o.format, o.name]));
1498           UniWriteLn(f, '"' + o.hint + '","' + _translate(GPSBabel_Domain, o.hint) + '"');
1499         end;
1500       end;
1501 
1502     finally
1503       f.Free;
1504     end;
1505 
1506   finally
1507     UseLanguage(curr_lang);
1508   end;
1509 end;
1510 
1511 procedure TfrmMain.cbOutputDeviceChange(Sender: TObject);
1512 begin
1513   CheckInput;
1514 end;
1515 
1516 procedure TfrmMain.cbInputDeviceChange(Sender: TObject);
1517 begin
1518   CheckInput;
1519 end;
1520 
1521 procedure TfrmMain.InitializeSerialPorts;
1522 var
1523   port: string;
1524   i: Integer;
1525   config: TCommConfig;
1526   cfsize: DWORD;
1527 begin
1528   for i := 1 to MAX_NO_OF_SERIAL_PORTS do
1529   begin
1530     port := Format('COM%d', [i]);
1531     cfsize := sizeof(config);
1532     if GetDefaultCommConfig(PChar(port), config, cfsize) then
1533     begin
1534       cbInputDevice.Items.Add(Format('COM%d', [i]));
1535       cbOutputDevice.Items.Add(Format('COM%d', [i]));
1536     end;
1537   end;
1538 end;
1539 
1540 procedure TfrmMain.acSelectAllExecute(Sender: TObject);
1541 begin
1542   memoOutput.SetFocus;
1543   memoOutput.SelectAll;
1544   acSelectAll.Enabled := False;
1545 end;
1546 
1547 procedure TfrmMain.acCopySelectedExecute(Sender: TObject);
1548 begin
1549   memoOutput.SetFocus;
1550   memoOutput.CopyToClipboard;
1551   acCopySelected.Enabled := False;
1552 end;
1553 
1554 procedure TfrmMain.PopupMenuPopup(Sender: TObject);
1555 begin
1556   pmnuSelectAll.Caption := dgettext('delphi', pmnuSelectAll.Caption);
1557   pmnuCopySelected.Caption := dgettext('delphi', pmnuCopySelected.Caption);
1558   pmnuClearOutput.Caption := dgettext('delphi', pmnuClearOutput.Caption);
1559 
1560   acSelectAll.Enabled := (memoOutput.Lines.Count > 0);
1561   acCopySelected.Enabled := (memoOutput.Lines.Count > 0);
1562 
1563   pmnuClearOutput.Enabled := (memoOutput.Lines.Count > 0);
1564 end;
1565 
1566 procedure TfrmMain.acOptionsSynthesizeShortNamesExecute(Sender: TObject);
1567 begin
1568   acOptionsSynthesizeShortNames.Checked := not(acOptionsSynthesizeShortNames.Checked);
1569 end;
1570 
1571 procedure TfrmMain.acOptionsNukeTypesExecute(Sender: TObject);
1572 begin
1573   acOptionsNukeTypes.Checked := not(acOptionsNukeTypes.Checked);
1574 end;
1575 
1576 end.
1577