fpdesk.pas 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Desktop loading/saving routines
  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. unit FPDesk;
  12. {$H-}
  13. interface
  14. const
  15. MinDesktopVersion = $000A;
  16. DesktopVersion = $000A; { <- if you change any Load&Store methods,
  17. default object properties (Options,State)
  18. then you should also change this }
  19. ResDesktopFlags = 'FLAGS';
  20. ResVideo = 'VIDEOMODE';
  21. ResHistory = 'HISTORY';
  22. ResClipboard = 'CLIPBOARD';
  23. ResWatches = 'WATCHES';
  24. ResBreakpoints = 'BREAKPOINTS';
  25. ResDesktop = 'DESKTOP';
  26. ResSymbols = 'SYMBOLS';
  27. ResCodeComplete = 'CODECOMPLETE';
  28. ResCodeTemplates = 'CODETEMPLATES';
  29. ResKeys = 'KEYS';
  30. procedure InitDesktopFile;
  31. function LoadDesktop: boolean;
  32. function SaveDesktop: boolean;
  33. procedure DoneDesktopFile;
  34. function WriteSymbolsFile(const filename : string): boolean;
  35. function ReadSymbolsFile(const filename : string): boolean;
  36. implementation
  37. uses Dos,
  38. Objects,Drivers,
  39. Video,
  40. Views,App,HistList,BrowCol,
  41. WUtils,WResourc,WViews,WEditor,
  42. fpdebug, wcedit,
  43. {$ifdef Unix}
  44. FPKeys,
  45. {$endif Unix}
  46. FPConst,FPVars,FPTools,FPUtils,FPViews,FPHelp,
  47. FPCompil,FPCodCmp,FPCodTmp;
  48. type
  49. TWindowInfo =
  50. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  51. packed
  52. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  53. record
  54. HelpCtx : word;
  55. Bounds : TRect;
  56. Visible : boolean;
  57. WinNb : byte;
  58. ExtraDataSize : word;
  59. TitleLen : word;
  60. Title : packed record end;
  61. end;
  62. {$ifdef useresstrings}
  63. resourcestring
  64. {$else}
  65. const
  66. {$endif}
  67. { Desktop file messages }
  68. msg_readingdesktopfile = 'Reading desktop file...';
  69. msg_writingdesktopfile = 'Writing desktop file...';
  70. msg_readingdesktopcontents = 'Reading desktop contents...';
  71. msg_storingdesktopcontents = 'Storing desktop contents...';
  72. msg_readinghistory = 'Reading history...';
  73. msg_storinghistory = 'Storing history...';
  74. msg_readingwatches = 'Reading watches...';
  75. msg_storingwatches = 'Storing watches...';
  76. msg_readingbreakpoints = 'Reading breakpoints...';
  77. msg_storingbreakpoints = 'Storing breakpoints...';
  78. msg_readingcodecompletewordlist = 'Reading CodeComplete wordlist...';
  79. msg_storingcodecompletewordlist = 'Writing CodeComplete wordlist...';
  80. msg_readingcodetemplates = 'Reading CodeTemplates...';
  81. msg_storingcodetemplates = 'Writing CodeTemplates...';
  82. msg_readingsymbolinformation = 'Reading symbol information...';
  83. msg_storingsymbolinformation = 'Storing symbol information...';
  84. msg_failedtoreplacedesktopfile = 'Failed to replace desktop file.';
  85. msg_errorloadinghistory = 'Error loading history';
  86. msg_errorstoringhistory = 'Error storing history';
  87. msg_errorloadingkeys = 'Error loading custom keys';
  88. msg_errorstoringkeys = 'Error storing custom keys';
  89. msg_errorloadingwatches = 'Error loading watches';
  90. msg_errorstoringwatches = 'Error storing watches';
  91. msg_errorloadingbreakpoints = 'Error loading breakpoints';
  92. msg_errorstoringbreakpoints = 'Error storing breakpoints';
  93. msg_errorloadingdesktop = 'Error loading desktop';
  94. msg_errorstoringdesktop = 'Error storing desktop';
  95. msg_errorreadingflags = 'Error loading flags';
  96. msg_errorwritingflags = 'Error writing flags';
  97. msg_errorreadingvideomode = 'Error reading video mode';
  98. msg_errorstoringvideomode = 'Error storing video mode';
  99. msg_errorloadingcodetemplates = 'Error loading CodeTemplates';
  100. msg_errorstoringcodetemplates = 'Error writing CodeTemplates';
  101. msg_errorloadingsymbolinformation = 'Error loading symbol information';
  102. msg_errorstoringsymbolinformation = 'Error storing symbol information';
  103. msg_errorloadingcodecompletewordlist = 'Error loading CodeComplete wordlist';
  104. msg_errorstoringcodecompletewordlist = 'Error writing CodeComplete wordlist';
  105. msg_invaliddesktopversionlayoutlost = 'Invalid desktop version. Desktop layout lost.';
  106. msg_saveansifile = 'Save previous screen as Ansi File';
  107. msg_click_upper_left = 'Click to select upper left corner; Escape to cancel; Enter to select (0,0)';
  108. msg_click_lower_right = 'Click to select lower right corner; Escape to cancel; Enter to select (maxX,maxY)';
  109. msg_cantopenfile = 'Can''t open %s';
  110. msg_cantcreatefile = 'Can''t create %s';
  111. msg_cantfindfile = 'Can''t find %s';
  112. msg_errorreadingfile = 'Error reading file %s';
  113. msg_loadingfile = 'Loading %s';
  114. msg_storingfile = 'Storing %s';
  115. msg_closingfile = 'Closing %s';
  116. msg_openingsourcefile = 'Opening source file... (%s)';
  117. msg_readingfileineditor = 'Reading %s into editor...';
  118. procedure InitDesktopFile;
  119. begin
  120. if DesktopLocation=dlCurrentDir then
  121. DesktopPath:=FExpand(DesktopName)
  122. else
  123. DesktopPath:=FExpand(DirOf(IniFileName)+DesktopName);
  124. end;
  125. procedure DoneDesktopFile;
  126. begin
  127. end;
  128. function ReadHistory(F: PResourceFile): boolean;
  129. var S: PMemoryStream;
  130. OK: boolean;
  131. begin
  132. PushStatus(msg_readinghistory);
  133. New(S, Init(32*1024,4096));
  134. OK:=F^.ReadResourceEntryToStream(resHistory,langDefault,S^);
  135. S^.Seek(0);
  136. if OK then
  137. LoadHistory(S^);
  138. Dispose(S, Done);
  139. if OK=false then
  140. ErrorBox(msg_errorloadinghistory,nil);
  141. PopStatus;
  142. ReadHistory:=OK;
  143. end;
  144. function WriteHistory(F: PResourceFile): boolean;
  145. var S: PMemoryStream;
  146. OK: boolean;
  147. begin
  148. PushStatus(msg_storinghistory);
  149. New(S, Init(10*1024,4096));
  150. StoreHistory(S^);
  151. S^.Seek(0);
  152. F^.CreateResource(resHistory,rcBinary,0);
  153. OK:=F^.AddResourceEntryFromStream(resHistory,langDefault,0,S^,S^.GetSize);
  154. Dispose(S, Done);
  155. if OK=false then
  156. ErrorBox(msg_errorstoringhistory,nil);
  157. PopStatus;
  158. WriteHistory:=OK;
  159. end;
  160. {$ifdef Unix}
  161. function ReadKeys(F: PResourceFile): boolean;
  162. var S: PMemoryStream;
  163. OK: boolean;
  164. begin
  165. New(S, Init(32*1024,4096));
  166. OK:=F^.ReadResourceEntryToStream(resKeys,langDefault,S^);
  167. S^.Seek(0);
  168. if OK then
  169. LoadKeys(S^);
  170. Dispose(S, Done);
  171. if OK=false then
  172. ErrorBox(msg_errorloadingkeys,nil);
  173. ReadKeys:=OK;
  174. end;
  175. function WriteKeys(F: PResourceFile): boolean;
  176. var S: PMemoryStream;
  177. OK: boolean;
  178. begin
  179. New(S, Init(10*1024,4096));
  180. StoreKeys(S^);
  181. S^.Seek(0);
  182. F^.CreateResource(resKeys,rcBinary,0);
  183. OK:=F^.AddResourceEntryFromStream(resKeys,langDefault,0,S^,S^.GetSize);
  184. Dispose(S, Done);
  185. if OK=false then
  186. ErrorBox(msg_errorstoringkeys,nil);
  187. WriteKeys:=OK;
  188. end;
  189. {$endif Unix}
  190. (*function ReadClipboard(F: PResourceFile): boolean;
  191. begin
  192. ReadClipboard:=true;
  193. end;
  194. function WriteClipboard(F: PResourceFile): boolean;
  195. var S: PMemoryStream;
  196. begin
  197. if Assigned(Clipboard) then
  198. begin
  199. PushStatus('Storing clipboard content...');
  200. New(S, Init(10*1024,4096));
  201. Clipboard^.SaveToStream(S^);
  202. S^.Seek(0);
  203. F^.CreateResource(resClipboard,rcBinary,0);
  204. F^.AddResourceEntryFromStream(resClipboard,langDefault,0,S^,S^.GetSize);
  205. Dispose(S, Done);
  206. PopStatus;
  207. end;
  208. WriteClipboard:=true;
  209. end;*)
  210. function ReadWatches(F: PResourceFile): boolean;
  211. {$ifndef NODEBUG}
  212. var S: PMemoryStream;
  213. OK: boolean;
  214. OWC : PWatchesCollection;
  215. {$endif}
  216. begin
  217. {$ifndef NODEBUG}
  218. PushStatus(msg_readingwatches);
  219. New(S, Init(32*1024,4096));
  220. OK:=F^.ReadResourceEntryToStream(resWatches,langDefault,S^);
  221. S^.Seek(0);
  222. if OK then
  223. begin
  224. OWC:=WatchesCollection;
  225. WatchesCollection:=PWatchesCollection(S^.Get);
  226. OK:=(S^.Status=stOK);
  227. if OK and assigned(OWC) and assigned(WatchesCollection) then
  228. Dispose(OWC,Done)
  229. else if assigned(OWC) then
  230. WatchesCollection:=OWC;
  231. end;
  232. if OK=false then
  233. ErrorBox(msg_errorloadingwatches,nil);
  234. ReadWatches:=OK;
  235. Dispose(S, Done);
  236. PopStatus;
  237. {$else NODEBUG}
  238. ReadWatches:=true;
  239. {$endif NODEBUG}
  240. end;
  241. function WriteWatches(F: PResourceFile): boolean;
  242. var
  243. S : PMemoryStream;
  244. OK : boolean;
  245. begin
  246. {$ifndef NODEBUG}
  247. if not assigned(WatchesCollection) then
  248. {$endif NODEBUG}
  249. WriteWatches:=true
  250. {$ifndef NODEBUG}
  251. else
  252. begin
  253. PushStatus(msg_storingwatches);
  254. New(S, Init(30*1024,4096));
  255. S^.Put(WatchesCollection);
  256. S^.Seek(0);
  257. F^.CreateResource(resWatches,rcBinary,0);
  258. OK:=F^.AddResourceEntryFromStream(resWatches,langDefault,0,S^,S^.GetSize);
  259. Dispose(S, Done);
  260. if OK=false then
  261. ErrorBox(msg_errorstoringwatches,nil);
  262. PopStatus;
  263. WriteWatches:=OK;
  264. end;
  265. {$endif NODEBUG}
  266. end;
  267. function ReadBreakpoints(F: PResourceFile): boolean;
  268. {$ifndef NODEBUG}
  269. var S: PMemoryStream;
  270. OK: boolean;
  271. OBC : PBreakpointCollection;
  272. {$endif}
  273. begin
  274. {$ifndef NODEBUG}
  275. PushStatus(msg_readingbreakpoints);
  276. New(S, Init(32*1024,4096));
  277. OK:=F^.ReadResourceEntryToStream(resBreakpoints,langDefault,S^);
  278. S^.Seek(0);
  279. if OK then
  280. begin
  281. OBC:=BreakpointsCollection;
  282. BreakpointsCollection:=PBreakpointCollection(S^.get);
  283. OK:=(S^.Status=stOK);
  284. If OK and assigned(OBC) and assigned(BreakpointsCollection) then
  285. Begin
  286. Dispose(OBC,Done);
  287. BreakpointsCollection^.ShowAllBreakpoints;
  288. end
  289. else if assigned(OBC) then
  290. BreakpointsCollection:=OBC;
  291. end;
  292. if OK=false then
  293. ErrorBox(msg_errorloadingbreakpoints,nil);
  294. ReadBreakpoints:=OK;
  295. Dispose(S, Done);
  296. PopStatus;
  297. {$else NODEBUG}
  298. ReadBreakpoints:=true;
  299. {$endif NODEBUG}
  300. end;
  301. function WriteBreakpoints(F: PResourceFile): boolean;
  302. var
  303. S : PMemoryStream;
  304. OK : boolean;
  305. begin
  306. {$ifndef NODEBUG}
  307. if not assigned(BreakpointsCollection) then
  308. {$endif NODEBUG}
  309. WriteBreakPoints:=true
  310. {$ifndef NODEBUG}
  311. else
  312. begin
  313. PushStatus(msg_storingbreakpoints);
  314. New(S, Init(30*1024,4096));
  315. S^.Put(BreakpointsCollection);
  316. S^.Seek(0);
  317. F^.CreateResource(resBreakpoints,rcBinary,0);
  318. OK:=F^.AddResourceEntryFromStream(resBreakpoints,langDefault,0,S^,S^.GetSize);
  319. Dispose(S, Done);
  320. if OK=false then
  321. ErrorBox(msg_errorstoringbreakpoints,nil);
  322. WriteBreakPoints:=OK;
  323. PopStatus;
  324. end;
  325. {$endif NODEBUG}
  326. end;
  327. function DeskUseSyntaxHighlight(Editor: PFileEditor): boolean;
  328. var b : boolean;
  329. begin
  330. b:= (*(Editor^.IsFlagSet(efSyntaxHighlight)) and *) ((Editor^.FileName='') or
  331. MatchesMaskList(NameAndExtOf(Editor^.FileName),HighlightExts));
  332. DeskUseSyntaxHighlight:=b;
  333. end;
  334. function ReadOpenWindows(F: PResourceFile): boolean;
  335. var S: PMemoryStream;
  336. OK: boolean;
  337. DV: word;
  338. WI: TWindowInfo;
  339. Title: string;
  340. XDataOfs: word;
  341. XData: array[0..1024] of byte;
  342. procedure GetData(var B; Size: word);
  343. begin
  344. if Size>0 Then
  345. Begin
  346. Move(XData[XDataOfs],B,Size);
  347. Inc(XDataOfs,Size);
  348. End;
  349. end;
  350. procedure ProcessWindowInfo;
  351. var W: PWindow;
  352. SW: PSourceWindow absolute W;
  353. St: string;
  354. Ch: AnsiChar;
  355. TP,TP2: TPoint;
  356. L: longint;
  357. R: TRect;
  358. ZZ: byte;
  359. Z: TRect;
  360. Len : Byte;
  361. begin
  362. XDataOfs:=0;
  363. Desktop^.Lock;
  364. W:=SearchWindow(Title);
  365. case WI.HelpCtx of
  366. hcSourceWindow :
  367. begin
  368. GetData(len,1);
  369. SetLength(St,Len);
  370. GetData(St[1],Len);
  371. W:=ITryToOpenFile(@WI.Bounds,St,0,0,false,false,true);
  372. if Assigned(W)=false then
  373. begin
  374. ClearFormatParams;
  375. AddFormatParamStr(St);
  376. Desktop^.Unlock;
  377. ErrorBox(msg_cantopenfile,@FormatParams);
  378. Desktop^.Lock;
  379. end
  380. else
  381. begin
  382. GetData(L,sizeof(L));
  383. If DeskUseSyntaxHighlight(SW^.Editor) Then
  384. L:=L or efSyntaxHighlight
  385. else
  386. L:=L and not efSyntaxHighlight;
  387. SW^.Editor^.SetFlags(L);
  388. GetData(TP,sizeof(TP)); GetData(TP2,sizeof(TP2));
  389. SW^.Editor^.SetSelection(TP,TP2);
  390. GetData(TP,sizeof(TP)); SW^.Editor^.SetCurPtr(TP.X,TP.Y);
  391. GetData(TP,sizeof(TP)); SW^.Editor^.ScrollTo(TP.X,TP.Y);
  392. end;
  393. end;
  394. hcClipboardWindow:
  395. W:=ClipboardWindow;
  396. hcCalcWindow:
  397. W:=CalcWindow;
  398. hcMessagesWindow:
  399. begin
  400. if MessagesWindow=nil then
  401. Desktop^.Insert(New(PMessagesWindow, Init));
  402. W:=MessagesWindow;
  403. end;
  404. hcCompilerMessagesWindow:
  405. W:=CompilerMessageWindow;
  406. {$ifndef NODEBUG}
  407. hcGDBWindow:
  408. begin
  409. InitGDBWindow;
  410. W:=GDBWindow;
  411. end;
  412. hcDisassemblyWindow:
  413. begin
  414. InitDisassemblyWindow;
  415. W:=DisassemblyWindow;
  416. end;
  417. hcWatchesWindow:
  418. begin
  419. if WatchesWindow=nil then
  420. begin
  421. New(WatchesWindow,Init);
  422. Desktop^.Insert(WatchesWindow);
  423. end;
  424. W:=WatchesWindow;
  425. end;
  426. hcStackWindow:
  427. begin
  428. if StackWindow=nil then
  429. begin
  430. New(StackWindow,Init);
  431. Desktop^.Insert(StackWindow);
  432. end;
  433. W:=StackWindow;
  434. end;
  435. hcFPURegisters:
  436. begin
  437. if FPUWindow=nil then
  438. begin
  439. New(FPUWindow,Init);
  440. Desktop^.Insert(FPUWindow);
  441. end;
  442. W:=FPUWindow;
  443. end;
  444. hcVectorRegisters:
  445. begin
  446. if VectorWindow=nil then
  447. begin
  448. New(VectorWindow,Init);
  449. Desktop^.Insert(VectorWindow);
  450. end;
  451. W:=VectorWindow;
  452. end;
  453. hcRegistersWindow:
  454. begin
  455. if RegistersWindow=nil then
  456. begin
  457. New(RegistersWindow,Init);
  458. Desktop^.Insert(RegistersWindow);
  459. end;
  460. W:=RegistersWindow;
  461. end;
  462. hcBreakpointListWindow:
  463. begin
  464. if BreakpointsWindow=nil then
  465. begin
  466. New(BreakpointsWindow,Init);
  467. Desktop^.Insert(BreakpointsWindow);
  468. end;
  469. W:=BreakpointsWindow;
  470. end;
  471. {$endif NODEBUG}
  472. hcASCIITableWindow:
  473. begin
  474. if ASCIIChart=nil then
  475. begin
  476. New(ASCIIChart, Init);
  477. Desktop^.Insert(ASCIIChart);
  478. end;
  479. W:=ASCIIChart;
  480. if DV>=$A then
  481. begin
  482. GetData(ch,sizeof(AnsiChar));
  483. AsciiChart^.Report^.AsciiChar:=ord(ch);
  484. AsciiChart^.Table^.SetCursor(
  485. ord(ch) mod AsciiChart^.Table^.Size.X,
  486. ord(ch) div AsciiChart^.Table^.Size.X);
  487. end;
  488. end;
  489. end;
  490. if W=nil then
  491. begin
  492. Desktop^.Unlock;
  493. Exit;
  494. end;
  495. W^.GetBounds(R);
  496. if (R.A.X<>WI.Bounds.A.X) or (R.A.Y<>WI.Bounds.A.Y) then
  497. R.Move(WI.Bounds.A.X-R.A.X,WI.Bounds.A.Y-R.A.Y);
  498. if (W^.Flags and wfGrow)<>0 then
  499. begin
  500. R.B.X:=R.A.X+(WI.Bounds.B.X-WI.Bounds.A.X);
  501. R.B.Y:=R.A.Y+(WI.Bounds.B.Y-WI.Bounds.A.Y);
  502. end;
  503. W^.Locate(R);
  504. if W^.GetState(sfVisible)<>WI.Visible then
  505. if WI.Visible then
  506. begin
  507. W^.Show;
  508. W^.MakeFirst;
  509. end
  510. else
  511. W^.Hide;
  512. ZZ:=0;
  513. Desktop^.GetExtent(Z);
  514. if R.A.Y>Z.B.Y-7 then
  515. begin
  516. R.A.Y:=Z.B.Y-7;
  517. ZZ:=1;
  518. end;
  519. if R.A.X>Z.B.X-4 then
  520. begin
  521. R.A.X:=Z.B.X-4;
  522. ZZ:=1;
  523. end;
  524. if R.A.Y<0 then
  525. begin
  526. R.A.Y:=0;
  527. ZZ:=1;
  528. end;
  529. if R.A.X<0 then
  530. begin
  531. R.A.X:=0;
  532. ZZ:=1;
  533. end;
  534. if ZZ<>0 then W^.MoveTo(R.A.X,R.A.Y);
  535. W^.Number:=WI.WinNb;
  536. Desktop^.Unlock;
  537. end;
  538. begin
  539. PushStatus(msg_readingdesktopcontents);
  540. New(S, Init(32*1024,4096));
  541. OK:=F^.ReadResourceEntryToStream(resDesktop,langDefault,S^);
  542. S^.Seek(0);
  543. if OK then
  544. begin
  545. S^.Read(DV,SizeOf(DV));
  546. OK:=(DV=DesktopVersion) or (DV>=MinDesktopVersion);
  547. if OK=false then
  548. ErrorBox(msg_invaliddesktopversionlayoutlost,nil);
  549. end;
  550. if OK then
  551. begin
  552. XDataOfs:=0;
  553. repeat
  554. S^.Read(WI,sizeof(WI));
  555. if S^.Status=stOK then
  556. begin
  557. SetLength(Title,WI.TitleLen);
  558. S^.Read(Title[1],WI.TitleLen);
  559. if WI.ExtraDataSize>0 then
  560. S^.Read(XData,WI.ExtraDataSize);
  561. ProcessWindowInfo;
  562. end;
  563. until (S^.Status<>stOK) or (S^.GetPos=S^.GetSize);
  564. (* TempDesk:=PFPDesktop(S^.Get);
  565. OK:=Assigned(TempDesk);
  566. if OK then
  567. begin
  568. Dispose(Desktop, Done);
  569. Desktop:=TempDesk;
  570. with Desktop^ do
  571. begin
  572. GetSubViewPtr(S^,CompilerMessageWindow);
  573. GetSubViewPtr(S^,CompilerStatusDialog);
  574. GetSubViewPtr(S^,ClipboardWindow);
  575. if Assigned(ClipboardWindow) then Clipboard:=ClipboardWindow^.Editor;
  576. GetSubViewPtr(S^,CalcWindow);
  577. GetSubViewPtr(S^,GDBWindow);
  578. GetSubViewPtr(S^,BreakpointsWindow);
  579. GetSubViewPtr(S^,WatchesWindow);
  580. GetSubViewPtr(S^,UserScreenWindow);
  581. GetSubViewPtr(S^,ASCIIChart);
  582. GetSubViewPtr(S^,MessagesWindow); LastToolMessageFocused:=nil;
  583. end;
  584. Application^.GetExtent(R);
  585. Inc(R.A.Y);Dec(R.B.Y);
  586. DeskTop^.Locate(R);
  587. Application^.Insert(Desktop);
  588. Desktop^.ReDraw;
  589. Message(Application,evBroadcast,cmUpdate,nil);
  590. end;*)
  591. if OK=false then
  592. ErrorBox(msg_errorloadingdesktop,nil);
  593. end;
  594. Dispose(S, Done);
  595. PopStatus;
  596. ReadOpenWindows:=OK;
  597. end;
  598. function WriteOpenWindows(F: PResourceFile): boolean;
  599. var S: PMemoryStream;
  600. procedure CollectInfo(P: PView);
  601. var W: PWindow;
  602. SW: PSourceWindow absolute W;
  603. WI: TWindowInfo;
  604. Title: string;
  605. XDataOfs: word;
  606. XData: array[0..1024] of byte;
  607. St: string;
  608. Ch: AnsiChar;
  609. TP: TPoint;
  610. L: longint;
  611. procedure AddData(const B; Size: word);
  612. begin
  613. Move(B,XData[XDataOfs],Size);
  614. Inc(XDataOfs,Size);
  615. end;
  616. begin
  617. XDataOfs:=0;
  618. W:=nil;
  619. if (P^.HelpCtx=hcSourceWindow) or
  620. (P^.HelpCtx=hcHelpWindow) or
  621. (P^.HelpCtx=hcClipboardWindow) or
  622. (P^.HelpCtx=hcCalcWindow) or
  623. (P^.HelpCtx=hcInfoWindow) or
  624. (P^.HelpCtx=hcBrowserWindow) or
  625. (P^.HelpCtx=hcMessagesWindow) or
  626. (P^.HelpCtx=hcCompilerMessagesWindow) or
  627. (P^.HelpCtx=hcGDBWindow) or
  628. (P^.HelpCtx=hcDisassemblyWindow) or
  629. (P^.HelpCtx=hcStackWindow) or
  630. (P^.HelpCtx=hcRegistersWindow) or
  631. (P^.HelpCtx=hcFPURegisters) or
  632. (P^.HelpCtx=hcVectorRegisters) or
  633. (P^.HelpCtx=hcWatchesWindow) or
  634. (P^.HelpCtx=hcBreakpointListWindow) or
  635. (P^.HelpCtx=hcASCIITableWindow)
  636. then
  637. W:=PWindow(P);
  638. if Assigned(W) and (P^.HelpCtx=hcSourceWindow) then
  639. if SW^.Editor^.FileName='' then
  640. W:=nil;
  641. if W=nil then Exit;
  642. FillChar(WI,sizeof(WI),0);
  643. Title:=W^.GetTitle(255);
  644. WI.HelpCtx:=W^.HelpCtx;
  645. W^.GetBounds(WI.Bounds);
  646. WI.Visible:=W^.GetState(sfVisible);
  647. WI.WinNb:=W^.Number;
  648. case WI.HelpCtx of
  649. hcSourceWindow :
  650. begin
  651. St:=SW^.Editor^.FileName; AddData(St,length(St)+1);
  652. L:=SW^.Editor^.GetFlags; AddData(L,sizeof(L));
  653. TP:=SW^.Editor^.SelStart; AddData(TP,sizeof(TP));
  654. TP:=SW^.Editor^.SelEnd; AddData(TP,sizeof(TP));
  655. TP:=SW^.Editor^.CurPos; AddData(TP,sizeof(TP));
  656. TP:=SW^.Editor^.Delta; AddData(TP,sizeof(TP));
  657. end;
  658. hcAsciiTableWindow :
  659. begin
  660. ch:=chr(PFPAsciiChart(P)^.Report^.AsciiChar);
  661. AddData(ch,sizeof(AnsiChar));
  662. end;
  663. end;
  664. WI.TitleLen:=length(Title);
  665. WI.ExtraDataSize:=XDataOfs;
  666. S^.Write(WI,sizeof(WI));
  667. S^.Write(Title[1],WI.TitleLen);
  668. if WI.ExtraDataSize>0 then
  669. S^.Write(XData,WI.ExtraDataSize);
  670. end;
  671. var W: word;
  672. OK: boolean;
  673. PV: PView;
  674. begin
  675. PushStatus(msg_storingdesktopcontents);
  676. New(S, Init(30*1024,4096));
  677. OK:=Assigned(S);
  678. if OK then
  679. begin
  680. W:=DesktopVersion;
  681. S^.Write(W,SizeOf(W));
  682. { S^.Put(Desktop);
  683. with Desktop^ do
  684. begin
  685. PutSubViewPtr(S^,CompilerMessageWindow);
  686. PutSubViewPtr(S^,CompilerStatusDialog);
  687. PutSubViewPtr(S^,ClipboardWindow);
  688. PutSubViewPtr(S^,CalcWindow);
  689. PutSubViewPtr(S^,GDBWindow);
  690. PutSubViewPtr(S^,BreakpointsWindow);
  691. PutSubViewPtr(S^,WatchesWindow);
  692. PutSubViewPtr(S^,UserScreenWindow);
  693. PutSubViewPtr(S^,ASCIIChart);
  694. PutSubViewPtr(S^,MessagesWindow);
  695. end;}
  696. { PV:=Application^.Last;
  697. while PV<>nil do
  698. begin
  699. CollectInfo(PV);
  700. PV:=PV^.PrevView;
  701. end;}
  702. PV:=Desktop^.Last;
  703. while PV<>nil do
  704. begin
  705. CollectInfo(PV);
  706. PV:=PV^.PrevView;
  707. end;
  708. OK:=(S^.Status=stOK);
  709. if OK then
  710. begin
  711. S^.Seek(0);
  712. OK:=F^.CreateResource(resDesktop,rcBinary,0);
  713. OK:=OK and F^.AddResourceEntryFromStream(resDesktop,langDefault,0,S^,S^.GetSize);
  714. end;
  715. Dispose(S, Done);
  716. end;
  717. if OK=false then
  718. ErrorBox(msg_errorstoringdesktop,nil);
  719. PopStatus;
  720. WriteOpenWindows:=OK;
  721. end;
  722. function WriteFlags(F: PResourceFile): boolean;
  723. var
  724. OK: boolean;
  725. begin
  726. F^.CreateResource(resDesktopFlags,rcBinary,0);
  727. OK:=F^.AddResourceEntry(resDesktopFlags,langDefault,0,DesktopFileFlags,
  728. SizeOf(DesktopFileFlags));
  729. if OK=false then
  730. ErrorBox(msg_errorwritingflags,nil);
  731. WriteFlags:=OK;
  732. end;
  733. function ReadCodeComplete(F: PResourceFile): boolean;
  734. var S: PMemoryStream;
  735. OK: boolean;
  736. begin
  737. PushStatus(msg_readingcodecompletewordlist);
  738. New(S, Init(1024,1024));
  739. OK:=F^.ReadResourceEntryToStream(resCodeComplete,langDefault,S^);
  740. S^.Seek(0);
  741. if OK then
  742. OK:=LoadCodeComplete(S^);
  743. Dispose(S, Done);
  744. if OK=false then
  745. ErrorBox(msg_errorloadingcodecompletewordlist,nil);
  746. PopStatus;
  747. ReadCodeComplete:=OK;
  748. end;
  749. function WriteCodeComplete(F: PResourceFile): boolean;
  750. var OK: boolean;
  751. S: PMemoryStream;
  752. begin
  753. PushStatus(msg_storingcodecompletewordlist);
  754. New(S, Init(1024,1024));
  755. OK:=StoreCodeComplete(S^);
  756. if OK then
  757. begin
  758. S^.Seek(0);
  759. F^.CreateResource(resCodeComplete,rcBinary,0);
  760. OK:=F^.AddResourceEntryFromStream(resCodeComplete,langDefault,0,S^,S^.GetSize);
  761. end;
  762. Dispose(S, Done);
  763. if OK=false then
  764. ErrorBox(msg_errorstoringcodecompletewordlist,nil);
  765. PopStatus;
  766. WriteCodeComplete:=OK;
  767. end;
  768. function ReadCodeTemplates(F: PResourceFile): boolean;
  769. var S: PMemoryStream;
  770. OK: boolean;
  771. begin
  772. PushStatus(msg_readingcodetemplates);
  773. New(S, Init(1024,4096));
  774. OK:=F^.ReadResourceEntryToStream(resCodeTemplates,langDefault,S^);
  775. S^.Seek(0);
  776. if OK then
  777. OK:=LoadCodeTemplates(S^);
  778. Dispose(S, Done);
  779. if OK=false then
  780. ErrorBox(msg_errorloadingcodetemplates,nil);
  781. PopStatus;
  782. ReadCodeTemplates:=OK;
  783. end;
  784. function WriteCodeTemplates(F: PResourceFile): boolean;
  785. var OK: boolean;
  786. S: PMemoryStream;
  787. begin
  788. PushStatus(msg_storingcodetemplates);
  789. New(S, Init(1024,4096));
  790. OK:=StoreCodeTemplates(S^);
  791. if OK then
  792. begin
  793. S^.Seek(0);
  794. F^.CreateResource(resCodeTemplates,rcBinary,0);
  795. OK:=F^.AddResourceEntryFromStream(resCodeTemplates,langDefault,0,S^,S^.GetSize);
  796. end;
  797. Dispose(S, Done);
  798. if OK=false then
  799. ErrorBox(msg_errorstoringcodetemplates,nil);
  800. PopStatus;
  801. WriteCodeTemplates:=OK;
  802. end;
  803. function ReadFlags(F: PResourceFile): boolean;
  804. var
  805. OK: boolean;
  806. begin
  807. OK:=F^.ReadResourceEntry(resDesktopFlags,langDefault,DesktopFileFlags,
  808. sizeof(DesktopFileFlags));
  809. if OK=false then
  810. ErrorBox(msg_errorreadingflags,nil);
  811. ReadFlags:=OK;
  812. end;
  813. function WriteVideoMode(F: PResourceFile): boolean;
  814. var
  815. OK: boolean;
  816. begin
  817. F^.CreateResource(resVideo,rcBinary,0);
  818. OK:=F^.AddResourceEntry(resVideo,langDefault,0,ScreenMode,
  819. SizeOf(TVideoMode));
  820. if OK=false then
  821. ErrorBox(msg_errorstoringvideomode,nil);
  822. WriteVideoMode:=OK;
  823. end;
  824. function ReadVideoMode(F: PResourceFile;var NewScreenMode : TVideoMode): boolean;
  825. var
  826. OK,test : boolean;
  827. begin
  828. test:=F^.ReadResourceEntry(resVideo,langDefault,NewScreenMode,
  829. sizeof(NewScreenMode));
  830. if not test then
  831. NewScreenMode:=ScreenMode;
  832. OK:=test;
  833. if OK=false then
  834. ErrorBox(msg_errorreadingvideomode,nil);
  835. ReadVideoMode:=OK;
  836. end;
  837. function ReadSymbols(F: PResourceFile): boolean;
  838. var S: PMemoryStream;
  839. OK: boolean;
  840. R: PResource;
  841. begin
  842. ReadSymbols:=false; { if no symbols stored ... no problems }
  843. R:=F^.FindResource(resSymbols);
  844. if not Assigned(R) then
  845. exit;
  846. PushStatus(msg_readingsymbolinformation);
  847. New(S, Init(32*1024,4096));
  848. OK:=F^.ReadResourceEntryToStream(resSymbols,langDefault,S^);
  849. S^.Seek(0);
  850. if OK then
  851. OK:=LoadBrowserCol(S);
  852. Dispose(S, Done);
  853. if OK=false then
  854. ErrorBox(msg_errorloadingsymbolinformation,nil);
  855. PopStatus;
  856. ReadSymbols:=OK;
  857. end;
  858. function WriteSymbols(F: PResourceFile): boolean;
  859. var S: PMemoryStream;
  860. OK: boolean;
  861. begin
  862. OK:=Assigned(Modules);
  863. if OK then
  864. begin
  865. PushStatus(msg_storingsymbolinformation);
  866. New(S, Init(200*1024,4096));
  867. OK:=Assigned(S);
  868. if OK then
  869. OK:=StoreBrowserCol(S);
  870. if OK then
  871. begin
  872. S^.Seek(0);
  873. F^.CreateResource(resSymbols,rcBinary,0);
  874. OK:=F^.AddResourceEntryFromStream(resSymbols,langDefault,0,S^,S^.GetSize);
  875. end;
  876. Dispose(S, Done);
  877. if OK=false then
  878. ErrorBox(msg_errorstoringsymbolinformation,nil);
  879. PopStatus;
  880. end;
  881. WriteSymbols:=OK;
  882. end;
  883. function LoadDesktop: boolean;
  884. var OK,VOK: boolean;
  885. F: PResourceFile;
  886. VM : TVideoMode;
  887. begin
  888. PushStatus(msg_readingdesktopfile);
  889. New(F, LoadFile(DesktopPath));
  890. OK:=false;
  891. if Assigned(F) then
  892. begin
  893. OK:=ReadFlags(F);
  894. VOK:=ReadVideoMode(F,VM);
  895. if VOK and ((VM.Col<>ScreenMode.Col) or
  896. (VM.Row<>ScreenMode.Row) or (VM.Color<>ScreenMode.Color)) then
  897. begin
  898. if Assigned(Application) then
  899. Application^.SetScreenVideoMode(VM);
  900. end;
  901. if ((DesktopFileFlags and dfHistoryLists)<>0) then
  902. OK:=ReadHistory(F) and OK;
  903. if ((DesktopFileFlags and dfWatches)<>0) then
  904. OK:=ReadWatches(F) and OK;
  905. if ((DesktopFileFlags and dfBreakpoints)<>0) then
  906. OK:=ReadBreakpoints(F) and OK;
  907. if ((DesktopFileFlags and dfOpenWindows)<>0) then
  908. OK:=ReadOpenWindows(F) and OK;
  909. { no errors if no browser info available PM }
  910. if ((DesktopFileFlags and dfSymbolInformation)<>0) then
  911. OK:=ReadSymbols(F) and OK;
  912. if ((DesktopFileFlags and dfCodeCompleteWords)<>0) then
  913. OK:=ReadCodeComplete(F) and OK;
  914. if ((DesktopFileFlags and dfCodeTemplates)<>0) then
  915. OK:=ReadCodeTemplates(F) and OK;
  916. {$ifdef Unix}
  917. OK:=ReadKeys(F) and OK;
  918. {$endif Unix}
  919. Dispose(F, Done);
  920. end;
  921. PopStatus;
  922. LoadDesktop:=OK;
  923. end;
  924. function SaveDesktop: boolean;
  925. var OK: boolean;
  926. F: PResourceFile;
  927. TempPath: string;
  928. begin
  929. TempPath:=DirOf(DesktopPath)+DesktopTempName;
  930. PushStatus(msg_writingdesktopfile);
  931. New(F, CreateFile(TempPath));
  932. if Assigned(Clipboard) then
  933. if (DesktopFileFlags and dfClipboardContent)<>0 then
  934. Clipboard^.SetFlags(Clipboard^.GetFlags or efStoreContent)
  935. else
  936. Clipboard^.SetFlags(Clipboard^.GetFlags and not efStoreContent);
  937. OK:=false;
  938. if Assigned(F) then
  939. begin
  940. OK:=WriteFlags(F);
  941. OK:=OK and WriteVideoMode(F);
  942. if ((DesktopFileFlags and dfHistoryLists)<>0) then
  943. OK:=OK and WriteHistory(F);
  944. if ((DesktopFileFlags and dfWatches)<>0) then
  945. OK:=OK and WriteWatches(F);
  946. if ((DesktopFileFlags and dfBreakpoints)<>0) then
  947. OK:=OK and WriteBreakpoints(F);
  948. if ((DesktopFileFlags and dfOpenWindows)<>0) then
  949. OK:=OK and WriteOpenWindows(F);
  950. { no errors if no browser info available PM }
  951. if ((DesktopFileFlags and dfSymbolInformation)<>0) then
  952. OK:=OK and (WriteSymbols(F) or not Assigned(Modules));
  953. if ((DesktopFileFlags and dfCodeCompleteWords)<>0) then
  954. OK:=OK and WriteCodeComplete(F);
  955. if ((DesktopFileFlags and dfCodeTemplates)<>0) then
  956. OK:=OK and WriteCodeTemplates(F);
  957. {$ifdef Unix}
  958. OK:=OK and WriteKeys(F);
  959. {$endif Unix}
  960. Dispose(F, Done);
  961. end;
  962. if OK then
  963. begin
  964. if ExistsFile(DesktopPath) then
  965. OK:=EraseFile(DesktopPath);
  966. OK:=OK and RenameFile(TempPath,DesktopPath);
  967. if OK=false then
  968. ErrorBox(msg_failedtoreplacedesktopfile,nil);
  969. end;
  970. PopStatus;
  971. SaveDesktop:=OK;
  972. end;
  973. function WriteSymbolsFile(const filename : string): boolean;
  974. var OK: boolean;
  975. F: PResourceFile;
  976. begin
  977. WriteSymbolsFile:=false;
  978. If not assigned(Modules) then
  979. exit;
  980. New(F, CreateFile(FileName));
  981. OK:=Assigned(F);
  982. if OK and ((DesktopFileFlags and dfSymbolInformation)<>0) then
  983. OK:=OK and WriteSymbols(F);
  984. if assigned(F) then
  985. Dispose(F,Done);
  986. WriteSymbolsFile:=OK;
  987. end;
  988. function ReadSymbolsFile(const FileName : string): boolean;
  989. var OK: boolean;
  990. F: PResourceFile;
  991. begin
  992. ReadSymbolsFile:=false;
  993. { Don't read again !! }
  994. If assigned(Modules) then
  995. exit;
  996. New(F, LoadFile(FileName));
  997. OK:=Assigned(F);
  998. if OK and ((DesktopFileFlags and dfSymbolInformation)<>0) then
  999. OK:=OK and ReadSymbols(F);
  1000. if assigned(F) then
  1001. Dispose(F,Done);
  1002. ReadSymbolsFile:=OK;
  1003. end;
  1004. END.