frmmain.pp 19 KB

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