frmmain.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2003 by the Free Pascal development team
  5. Main form of GTK debugserver
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$mode objfpc}
  13. {$h+}
  14. unit frmmain;
  15. Interface
  16. uses
  17. fpgtk,fpgtkext,glib,gtk,gdk,debugserverintf,sysutils,msgintf,classes,inifiles;
  18. Type
  19. TClientCList = Class(TFPGtkScrollClist)
  20. Protected
  21. FTabLabel : TFPgtkLabel;
  22. FClient : TClient;
  23. Public
  24. Constructor Create (AClient : TClient);
  25. Property Client : TClient Read FClient Write FClient;
  26. Property TabLabel : TFPgtkLabel Read FTabLabel Write FTabLabel;
  27. end;
  28. TMainForm = Class (TFPGtkWindow)
  29. Private
  30. // 'real' Variables
  31. FCreating,
  32. FPaused,
  33. FInsertNew,
  34. FCloseOnDisconnect,
  35. FLoadSinglePage,
  36. FSinglePage : Boolean;
  37. FIdleHandle : gint;
  38. FMsgImages : Array[-1..3] of PgdkPixmap;
  39. FMsgMasks : Array[-1..3] of Pgdkbitmap;
  40. // Widgets
  41. FVBox : TFPGtkVBox;
  42. FMainMenu : TFpGtkMenuBar;
  43. FFile, // File menu
  44. FFileClear,
  45. FFileSave,
  46. FFileExit,
  47. FFileClose,
  48. FOptions,
  49. FHelp, // Help menu
  50. FHelpAbout : TFPGtkMenuItem;
  51. FOptionsInsertNew,
  52. FOptionsSinglePage,
  53. FOptionsCloseOnDisconnect,
  54. FFilePause : TFPGtkCheckMenuItem;
  55. FConnectImage,
  56. FDisconnectImage,
  57. FInfoImage,
  58. FWarningImage,
  59. FErrorImage,
  60. FClearImage,
  61. FSaveImage,
  62. FCloseImage,
  63. FPauseImage,
  64. FRunImage,
  65. FRunButtonImage : TFPGtkPixmap;
  66. FMainToolbar : TFPGtkToolbar;
  67. FToolbarFrame : TFPGtkFrame;
  68. FPages : TfpGTKNotebook;
  69. FList : TClientCList;
  70. FRunButton : TFPgtkButton;
  71. FRunImages : Array[Boolean] of PgdkPixmap;
  72. FRunMasks : Array[Boolean] of Pgdkbitmap;
  73. Public
  74. // General
  75. Constructor Create;
  76. Procedure CreateWindow;
  77. Procedure LoadSettings;
  78. Procedure SaveSettings;
  79. Function SettingsFilename : String;
  80. Procedure SetupDebugServer;
  81. Procedure ShutdownDebugServer;
  82. // List/Client management
  83. Procedure SaveToFile(C : TClientCList; FN : String);
  84. Function NewList(Client : TClient) : TClientCList;
  85. Function GetList(Client : TClient) : TClientClist;
  86. Procedure HaveData(Handle : Gint);
  87. Procedure AddEventToList(Event : TDebugEvent);
  88. Function CheckForNewClient : TClient;
  89. Function CurrentList : TClientCList;
  90. Function GetClientPageIndex(Client : TClient) : Integer;
  91. Procedure ConnectionClosed(C : TCLient);
  92. Procedure SetRunButtonBitmaps;
  93. Function GetFileName(ATitle : String) : String;
  94. Procedure DialogSetFilename(Sender : TFPGtkWindow;Data : Pointer; Action : Integer;Initiator : TFPGtkObject);
  95. // User callbacks
  96. Procedure FileClearClick(Sender : TFPGtkObject; Data : Pointer);
  97. Procedure FileSaveClick(Sender : TFPGtkObject; Data : Pointer);
  98. Procedure FileCopyClick(Sender : TFPGtkObject; Data : Pointer);
  99. Procedure FilePauseClick(Sender : TFPGtkObject; Data : Pointer);
  100. Procedure FileCloseClick(Sender : TFPGtkObject; Data : Pointer);
  101. Procedure FileExitClick(Sender : TFPGtkObject; Data : Pointer);
  102. Procedure OptionsClick(Sender : TFPGtkObject; Data : Pointer);
  103. Procedure HelpAboutClick(Sender : TFPGtkObject; Data : Pointer);
  104. Function OnDeleteEvent(Sender:TFPgtkWidget; Event:PGdkEvent; data:pointer): boolean;
  105. end;
  106. Implementation
  107. uses frmabout,bitmapdata;
  108. ResourceString
  109. SCaption = 'FPC Debug server';
  110. SMenuFile = '_File';
  111. SMenuFileClear = 'Clea_r';
  112. SMenuFileSave = '_Save';
  113. SMenuFileCopy = '_Copy';
  114. SMenuFilePause = '_Pause';
  115. SMenuFileClose = 'C_lose';
  116. SMenuFileExit = 'E_xit';
  117. SMenuOptions = '_Options';
  118. SMenuOptionsInsertNew = '_New messages first';
  119. SMenuOptionsSinglePage = '_All clients on 1 page';
  120. SMenuOptionsCloseOnDisconnect = '_Close client on disconnect';
  121. SMenuHelp = '_Help';
  122. SMenuHelpAbout = '_About';
  123. SHintFileClear = 'Clear current list';
  124. SHintFileSave = 'Save current list to disk';
  125. SHintFilePause = 'Discard new messages';
  126. SHintFileClose = 'Close current list';
  127. SNewClient = 'New client';
  128. SMessageFrom = '[%s] : %s';
  129. SSaveFileTitle = 'Save list to file:';
  130. SNeedsRestart = 'Restart debugserver for this option to take effect.';
  131. Const
  132. SKeyParameters = 'Parameters';
  133. SKeySinglePage = 'SinglePage';
  134. SKeyCloseOnDisconnect = 'CloseOnDisconnect';
  135. SkeyInsertNew = 'InsertNewMessages';
  136. SConfigFile = 'debugserver.cnf';
  137. DefaultSinglePage = True;
  138. DefaultCloseOnConnect = False;
  139. DefaultInsertNew = True;
  140. Const
  141. DefaultTooltips = True;
  142. DefaultToolBarStyle = GTK_TOOLBAR_ICONS;
  143. DefaultToolbarRelief = GTK_RELIEF_NONE;
  144. { ---------------------------------------------------------------------
  145. TClientCList
  146. ---------------------------------------------------------------------}
  147. Constructor TClientCList.Create(Aclient : TClient);
  148. begin
  149. Inherited Create(3);
  150. FClient:=AClient;
  151. Clist.ShowTitles;
  152. CList.PassiveTitles;
  153. Clist.ColumnTitle[0]:='*';
  154. Clist.ColumnTitle[1]:='Time';
  155. Clist.ColumnTitle[2]:='Message';
  156. CLIST.SetColumnWidth(0,20);
  157. CList.SetColumnResizeable(0,False);
  158. CLIST.SetColumnWidth(1,120);
  159. end;
  160. { ---------------------------------------------------------------------
  161. MainForm - General
  162. ---------------------------------------------------------------------}
  163. // Cludge to go around TFPgtkBin.Child not being public...
  164. Type
  165. TMyBin = Class(TFPgtkBin)
  166. Public
  167. Property Child;
  168. end;
  169. Procedure TMainForm.CreateWindow;
  170. Var
  171. V : TFPGtkHBox;
  172. FAccelGroup: Integer;
  173. begin
  174. { File Menu }
  175. Title:=SCaption;
  176. FAccelGroup:=AccelGroupNew;
  177. FFileClear := NewMenuItem(SMenuFileClear ,'','',MakeAccelKeyDef(Self,FaccelGroup,GDK_L,[amcontrol]),@FileClearClick,Nil);
  178. FFileSave := NewMenuItem(SMenuFileSave ,'','',MakeAccelKeyDef(Self,FaccelGroup,GDK_S,[amcontrol]),@FileSaveClick,Nil);
  179. FFilePause := NewCheckMenuItem(SMenuFilePause ,'','',MakeAccelKeyDef(Self,FaccelGroup,GDK_P,[amcontrol]),@FilePauseClick,Nil);
  180. If Not FSinglePage then
  181. FFileClose := NewMenuItem(SMenuFileClose ,'','',MakeAccelKeyDef(Self,FaccelGroup,GDK_W,[amcontrol]),@FileCloseClick,Nil);
  182. FFileExit := NewMenuItem(SMenuFileExit ,'','',MakeAccelKeyDef(Self,FaccelGroup,GDK_Q,[amcontrol]),@FileExitClick,Nil);
  183. If FSinglePage then
  184. FFile := NewSubMenu(SMenuFile,'','',[FFileClear,FFileSave,FFilePause,NewLine,FFileExit])
  185. else
  186. FFile := NewSubMenu(SMenuFile,'','',[FFileClear,FFileSave,FFilePause,FFileClose,NewLine,FFileExit]);
  187. { Options menu }
  188. FOptionsInsertNew := NewCheckMenuItem(SMenuOptionsInsertNew,'','', @OptionsClick,@FInsertNew);
  189. FOptionsInsertNew.Active:=FInsertNew;
  190. FOptionsSinglePage := NewCheckMenuItem(SMenuOptionsSinglePage,'','', @OptionsClick,@FLoadSinglePage);
  191. FOptionsSinglePage.Active:=FSinglePage;
  192. FOptionsCloseOnDisconnect := NewCheckMenuItem(SMenuOptionsCloseOnDisconnect,'','', @OptionsClick,@FCloseOnDisconnect);
  193. FOptionsCloseOnDisconnect.active:=FCloseOnDisconnect;
  194. FOptions := NewSubMenu(SMenuOptions,'','',[FOptionsInsertNew,FOptionsSinglePage,FOptionsCloseOnDisconnect]);
  195. { Help Menu }
  196. FHelpAbout:=NewMenuItem(SMenuHelpAbout ,'','',@HelpAboutClick,Nil);
  197. FHelp := NewSubMenu(SMenuHelp,'','',[FHelpAbout]);
  198. { Menu bar }
  199. FMainMenu:=NewMenuBar([FFile,FOptions,FHelp]);
  200. { Toolbar images }
  201. FClearImage:=PixmapFromFile('clear');
  202. FPauseImage:=PixmapFromFile('pause');
  203. FRunImage:=PixmapFromFile('run');
  204. FCloseImage:=PixMapFromFile('close');
  205. FSaveImage:=PixmapFromFile('save');
  206. FRunButtonImage:=TFPGtkPixmap.Create;
  207. FRunImages[False]:=FPauseImage.PixMap;
  208. FRunMasks[False]:=FPauseImage.Mask;
  209. FRunImages[True]:=FRunImage.PixMap;
  210. FRunMasks[True]:=FRunImage.Mask;
  211. SetRunButtonBitmaps;
  212. { Message images }
  213. FConnectImage:=PixMapFromFile('connect');
  214. FDisConnectImage:=PixMapFromFile('disconnect');
  215. FinfoImage:=PixmapFromFile('info');
  216. FWarningImage:=PixmapFromFile('warning');
  217. FErrorImage:=PixmapFromFile('error');
  218. { Save references for quick lookup}
  219. FMsgImages[-1]:=FDisconnectImage.PixMap;
  220. FMsgImages[0]:=FinfoImage.PixMap;
  221. FMsgImages[1]:=FWarningImage.PixMap;
  222. FMsgImages[2]:=FErrorImage.PixMap;
  223. FMsgImages[3]:=FConnectImage.PixMap;
  224. FMsgMasks[-1]:=FDisconnectImage.Mask;
  225. FMsgMasks[0]:=FinfoImage.Mask;
  226. FMsgMasks[1]:=FWarningImage.Mask;
  227. FMsgMasks[2]:=FErrorImage.Mask;
  228. FMsgMasks[3]:=FConnectImage.Mask;
  229. { Toolbar }
  230. FMainToolBar:=TFPGtkToolbar.Create;
  231. With FMainToolbar do
  232. begin
  233. Style:=DefaultToolbarStyle;
  234. ButtonRelief:=DefaultToolbarRelief;
  235. EnableTooltips:=DefaultTooltips;
  236. AppendItem(SMenuFileClear,SHintFileClear,'',FClearImage,@FileClearClick,Nil);
  237. AppendItem(SMenuFileSave,SHintFileSave,'',FSaveImage,@FileSaveClick,Nil);
  238. FRunButton:=AppendItem(SMenuFilePause,SHintFilePause,'',FRunButtonImage,@FilePauseClick,Nil) as TFPgtkButton;
  239. AppendItem(SMenuFileClose,SHintFileClose,'',FCloseImage,@FileCloseClick,Nil);
  240. end;
  241. { place left aligned on frame }
  242. V:=TFPGtkHBox.Create;
  243. V.PackStart(FMainToolbar,False,False,2);
  244. FToolbarFrame:=TFPGtkFrame.Create;
  245. FtoolbarFrame.Add(V);
  246. { For Pages }
  247. // FPages:=TFPGtkNoteBook.Create;
  248. If FSinglePage then
  249. FList:=NewList(Nil)
  250. else
  251. FPages:=TFPGtkNoteBook.Create;
  252. { Place on form }
  253. FVBox:=TFPGTKVBox.create;
  254. FVBox.PackStart(FMainMenu,false, true, 0);
  255. FVBox.PackStart(FToolBarFrame,false, true, 0);
  256. If FSinglePage then
  257. FVBox.PackStart(FList,true, true, 0)
  258. else
  259. FVBox.PackStart(FPages,true, true, 0);
  260. Self.add(FVBox);
  261. Setusize(640,480);
  262. ConnectDeleteEvent(@OnDeleteEvent,Nil);
  263. end;
  264. Constructor TMainForm.Create;
  265. begin
  266. Inherited Create(gtk_window_dialog);
  267. LoadSettings;
  268. FSinglePage:=FLoadSinglePage;
  269. FPaused:=False;
  270. FCreating:=True;
  271. Try
  272. CreateWindow;
  273. Finally
  274. FCreating:=False;
  275. end;
  276. SetUpDebugServer;
  277. end;
  278. Procedure TMainForm.SetRunButtonBitmaps;
  279. begin
  280. FRunButtonImage.SetPixMap(FRunImages[FPaused],FRunMasks[FPaused]);
  281. end;
  282. Function TMainForm.SettingsFileName : String;
  283. Var
  284. Home : String;
  285. begin
  286. Home:=GetEnvironmentVariable('HOME');
  287. If (Home<>'') then
  288. Result:=IncludeTrailingBackslash(Home)+'.'+SConfigFile
  289. else
  290. Result:=SConfigFile;
  291. end;
  292. Procedure TMainForm.LoadSettings;
  293. begin
  294. With TIniFile.Create(SettingsFileName) do
  295. Try
  296. FLoadSinglePage:=ReadBool(SKeyParameters,SkeySinglePage,DefaultSinglePage);
  297. FCloseOnDisconnect:=ReadBool(SKeyParameters,SkeyCloseOnDisconnect,DefaultCloseOnConnect);
  298. FInsertNew:=ReadBool(SKeyParameters,SKeyInsertNew,DefaultInsertNew);
  299. finally
  300. Free;
  301. end;
  302. end;
  303. Procedure TMainForm.SaveSettings;
  304. begin
  305. With TIniFile.Create(SettingsFileName) do
  306. Try
  307. WriteBool(SKeyParameters,SkeySinglePage,FLoadSinglePage);
  308. WriteBool(SKeyParameters,SkeyCloseOnDisconnect,FCloseOnDisconnect);
  309. WriteBool(SKeyParameters,SKeyInsertNew,FinsertNew);
  310. UpdateFile;
  311. finally
  312. Free;
  313. end;
  314. end;
  315. { ---------------------------------------------------------------------
  316. Event handling.
  317. ---------------------------------------------------------------------}
  318. // GTK idle callback, to check for new connections during idle time.
  319. function GtkIdle (Data:pointer) : gint; Cdecl;
  320. begin
  321. With (TObject(Data) as TMainForm) do
  322. CheckForNewClient;
  323. end;
  324. // When input appears on one of the handles, we come here through the gtk
  325. // input watch.
  326. Procedure GtkHaveInput (Data : GPointer; Source : gint; Condition : TGDKInputCondition);cdecl;
  327. begin
  328. With (TObject(Data) as TMainForm) do
  329. HaveData(Source);
  330. end;
  331. // Real methods.
  332. Procedure TMainForm.SetupDebugServer;
  333. begin
  334. OpenDebugServer;
  335. FIdleHandle:=gtk_idle_add(@GtkIdle,Self);
  336. CloseObjConnectionCallBack:[email protected];
  337. end;
  338. Procedure TMainForm.ShutdownDebugServer;
  339. begin
  340. CloseObjConnectionCallBack:=Nil;
  341. gtk_idle_remove(FIdleHandle);
  342. CloseDebugServer;
  343. end;
  344. // tell gdk not to watch this handle any more.
  345. // Clean up of the associated page happens in log event.
  346. Procedure TMainForm.ConnectionClosed(C : TCLient);
  347. begin
  348. gdk_input_remove(gint(C.Data));
  349. end;
  350. // We get here when data is present on socket.
  351. Procedure TMainForm.HaveData(Handle : Gint);
  352. Var
  353. Event : TDebugEvent;
  354. begin
  355. ReadMessageEvent(Handle,Event);
  356. AddEventToList(Event);
  357. end;
  358. // Check if a new client has reported ?
  359. Function TMainForm.CheckForNewClient : TClient;
  360. Var
  361. IHandle : gint;
  362. L : TClientCList;
  363. begin
  364. // Writeln('Checking new client');
  365. Result:=CheckNewConnection;
  366. If Result<>Nil then
  367. begin
  368. If Not FSinglePage then
  369. begin
  370. L:=NewList(Result);
  371. FPages.AppendPage(L,L.TabLabel);
  372. FPages.Page:=L;
  373. // Force draw.
  374. Fpages.Draw(Nil);
  375. L.ShowNow;
  376. L.Draw(Nil);
  377. L.Clist.draw(Nil);
  378. end;
  379. IHandle:=gdk_input_add(Result.Handle,GDK_INPUT_READ,@GtkHaveInput,self);
  380. Result.Data:=Pointer(IHandle);
  381. end;
  382. end;
  383. // Add event data to the appropriate list.
  384. Procedure TMainForm.AddEventToList(Event : TDebugEvent);
  385. Const
  386. MsgTypeStrings : Array[-1..3] of String = ('*','?','!','!','.');
  387. Var
  388. T,D,S : String;
  389. L : TClientCList;
  390. TL : TFPgtkWidget;
  391. SL : TStringList;
  392. Index : Integer;
  393. begin
  394. With Event do
  395. begin
  396. T:=MsgTypeStrings[LogCode];
  397. D:=DateTimeToStr(TimeStamp);
  398. If FSinglePage or (logcode<>lctIdentify) then
  399. S:=Format(SMessageFrom,[Client.Peer,Event])
  400. else
  401. S:=Event;
  402. L:=Nil;
  403. If Assigned(Client) then
  404. L:=GetList(Client);
  405. If L=Nil then
  406. Writeln('No list found for event ',s)
  407. else
  408. begin
  409. If (LogCode=lctIdentify) then
  410. If Not FSinglePage then
  411. L.TabLabel.Text:=Event;
  412. If Not FPaused then
  413. begin
  414. If FInsertNew then
  415. begin
  416. Index:=0;
  417. L.CList.Prepend([T,D,S]);
  418. end
  419. else
  420. Index:=L.CList.Append([T,D,S]);
  421. L.Clist.SetPixMap(Index,0,FMsgImages[logCode],FmsgMasks[LogCode]);
  422. end;
  423. If LogCode=lctStop then
  424. begin
  425. L.Client:=Nil; // New clients MAY have the same addresspointer as existing;
  426. If (Not FSinglePage) and FCloseOnDisconnect then
  427. L.Free;
  428. end;
  429. end;
  430. end;
  431. CheckForNewClient;
  432. end;
  433. // Create new list.
  434. Function TMainForm.NewList(Client : TClient) : TClientCList;
  435. begin
  436. Result:=TClientCList.Create(Client);
  437. If Client<>Nil then
  438. Result.TabLabel:=TfpGtkLabel.Create(SNewClient);
  439. end;
  440. // Get page index on which messages for client are shown.
  441. // Only call when FSinglePage is not true
  442. Function TMainForm.GetClientPageIndex(Client : TClient) : Integer;
  443. Var
  444. P : TFPgtkWidget;
  445. begin
  446. With FPages,Children do
  447. begin
  448. Result:=Count-1;
  449. While Result>=0 do
  450. begin
  451. P:=GetChildOnPage(Result);
  452. if Not(P is TClientClist) or
  453. (TClientClist(P).Client<>Client) Then
  454. Dec(Result)
  455. end
  456. end;
  457. end;
  458. // Get list on which messages for client are shown.
  459. // Only call when FSinglePage is not true
  460. Function TMainForm.GetList(Client : TClient) : TClientCList;
  461. Var
  462. I : Integer;
  463. P : TFPgtkWidget;
  464. begin
  465. If FSinglePage then
  466. Result:=FList
  467. else
  468. begin
  469. With FPages,Children do
  470. For I:=0 to Count-1 do
  471. begin
  472. P:=GetChildOnPage(i);
  473. if P is TClientClist then
  474. If TClientClist(P).Client=Client Then
  475. begin
  476. Result:=TClientClist(P);
  477. exit
  478. end;
  479. end;
  480. end;
  481. end;
  482. // Return current list.
  483. Function TMainForm.CurrentList : TClientClist;
  484. begin
  485. If FSinglePage then
  486. Result:=FList
  487. else
  488. Result:=FPages.Page as TClientCList;
  489. end;
  490. // Write list contents to file.
  491. Procedure TMainForm.SaveToFile(C : TClientCList; FN : String);
  492. Var
  493. F : System.text;
  494. I,J : Integer;
  495. S,T : String;
  496. P : PGdkPixmap;
  497. M : PGdkBitmap;
  498. begin
  499. Assign(F,FN);
  500. rewrite(F);
  501. Try
  502. With C.Clist do
  503. For I:=0 To count-1 do
  504. begin
  505. GetPixmap(I,0,P,M);
  506. For J:=-1 to 3 do
  507. If (FMsgImages[J]=P) then
  508. T:=MsgTypes[J];
  509. S:=T+' '+CellText[i,1]+' '+Celltext[I,2];
  510. Writeln(F,S);
  511. end;
  512. finally
  513. System.Close(f);
  514. end;
  515. end;
  516. { ---------------------------------------------------------------------
  517. Callbacks for user events.
  518. ---------------------------------------------------------------------}
  519. Procedure TMainForm.FileClearClick(Sender : TFPGtkObject; Data : Pointer);
  520. Var
  521. L:TClientClist;
  522. begin
  523. L:=CurrentList;
  524. If L<>Nil then
  525. L.Clist.Clear;
  526. end;
  527. Procedure TMainForm.DialogSetFilename(Sender : TFPGtkWindow;Data : Pointer; Action : Integer;Initiator : TFPGtkObject);
  528. type
  529. PString = ^AnsiString;
  530. begin
  531. PString(Data)^:=(Sender as TFPgtkFileSelection).Filename;
  532. end;
  533. Function TMainForm.GetFileName(ATitle : String) : String;
  534. var
  535. FS : TFPgtkFileSelection;
  536. begin
  537. FS := TFPgtkFileSelection.Create (gtk_window_dialog);
  538. Result:='';
  539. with FS do
  540. begin
  541. Title:=ATitle;
  542. OKButton.ConnectClicked (@(CloseWithResult), inttopointer(drOk));
  543. CancelButton.ConnectClicked (@(CloseWindow), nil);
  544. if Not execute (nil, @Result, @DialogSetFilename) = drOk then
  545. Result:='';
  546. end;
  547. end;
  548. Procedure TMainForm.FileSaveClick(Sender : TFPGtkObject; Data : Pointer);
  549. Var
  550. L:TClientClist;
  551. FN : String;
  552. begin
  553. L:=CurrentList;
  554. If L<>Nil then
  555. begin
  556. FN:=GetFileName(SSaveFileTitle);
  557. If (FN<>'') then
  558. SaveToFile(L,Fn);
  559. end;
  560. end;
  561. Procedure TMainForm.FileCopyClick(Sender : TFPGtkObject; Data : Pointer);
  562. // not used for the moment; need to figure out a way to do this.
  563. begin
  564. end;
  565. Procedure TMainForm.FilePauseClick(Sender : TFPGtkObject; Data : Pointer);
  566. begin
  567. If (Sender<>FFilePause) then
  568. With FFilePause do
  569. Active:=Not Active;
  570. FPaused:=FFilePause.Active;
  571. SetRunButtonBitmaps;
  572. end;
  573. Procedure TMainForm.FileCloseClick(Sender : TFPGtkObject; Data : Pointer);
  574. Var
  575. L : TClientCList;
  576. begin
  577. L:=CurrentList;
  578. If (L<>Nil) and (L.Client=Nil) then
  579. L.Free;
  580. end;
  581. Procedure TMainForm.FileExitClick(Sender : TFPGtkObject; Data : Pointer);
  582. begin
  583. ShutdownDebugServer;
  584. Close;
  585. end;
  586. Procedure TMainForm.OptionsClick(Sender : TFPGtkObject; Data : Pointer);
  587. Type
  588. PBoolean = ^boolean;
  589. begin
  590. If not FCreating then
  591. begin
  592. PBoolean(data)^:=Not PBoolean(data)^;
  593. SaveSettings;
  594. If (@FLoadSinglePage=Data) then
  595. ShowMessage(SCaption,SNeedsRestart);
  596. end;
  597. end;
  598. Procedure TMainForm.HelpAboutClick(Sender : TFPGtkObject; Data : Pointer);
  599. begin
  600. With TAboutForm.Create do
  601. Execute(Nil,Nil,Nil);
  602. end;
  603. Function TMainForm.OnDeleteEvent(Sender:TFPgtkWidget; Event:PGdkEvent; data:pointer): boolean;
  604. begin
  605. ShutdownDebugServer;
  606. Result:=True;
  607. end;
  608. end.
  609. {
  610. $Log$
  611. Revision 1.1 2003-01-02 14:36:25 michael
  612. + Initial implementation
  613. }