fpdesk.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. Desktop loading/saving routines
  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. unit FPDesk;
  13. interface
  14. const
  15. DesktopVersion = $0005; { <- if you change any Load&Store methods,
  16. default object properties (Options,State)
  17. then you should also change this }
  18. ResDesktopFlags = 'FLAGS';
  19. ResVideo = 'VIDEOMODE';
  20. ResHistory = 'HISTORY';
  21. ResClipboard = 'CLIPBOARD';
  22. ResWatches = 'WATCHES';
  23. ResBreakpoints = 'BREAKPOINTS';
  24. ResDesktop = 'DESKTOP';
  25. ResSymbols = 'SYMBOLS';
  26. procedure InitDesktopFile;
  27. function LoadDesktop: boolean;
  28. function SaveDesktop: boolean;
  29. procedure DoneDesktopFile;
  30. implementation
  31. uses Dos,
  32. Objects,Drivers,Video,
  33. Views,App,HistList,BrowCol,
  34. WResource,WViews,WEditor,
  35. {$ifndef NODEBUG}
  36. fpdebug,
  37. {$endif ndef NODEBUG}
  38. FPConst,FPVars,FPUtils,FPViews,FPCompile,FPTools,FPHelp;
  39. procedure InitDesktopFile;
  40. begin
  41. if DesktopLocation=dlCurrentDir then
  42. DesktopPath:=FExpand(DesktopName)
  43. else
  44. DesktopPath:=FExpand(DirOf(INIPath)+DesktopName);
  45. end;
  46. procedure DoneDesktopFile;
  47. begin
  48. end;
  49. function ReadHistory(F: PResourceFile): boolean;
  50. var S: PMemoryStream;
  51. OK: boolean;
  52. begin
  53. PushStatus('Reading history...');
  54. New(S, Init(32*1024,4096));
  55. OK:=F^.ReadResourceEntryToStream(resHistory,langDefault,S^);
  56. S^.Seek(0);
  57. if OK then
  58. LoadHistory(S^);
  59. Dispose(S, Done);
  60. PopStatus;
  61. ReadHistory:=OK;
  62. end;
  63. function WriteHistory(F: PResourceFile): boolean;
  64. var S: PMemoryStream;
  65. begin
  66. PushStatus('Storing history...');
  67. New(S, Init(10*1024,4096));
  68. StoreHistory(S^);
  69. S^.Seek(0);
  70. F^.CreateResource(resHistory,rcBinary,0);
  71. F^.AddResourceEntryFromStream(resHistory,langDefault,0,S^,S^.GetSize);
  72. Dispose(S, Done);
  73. PopStatus;
  74. WriteHistory:=true;
  75. end;
  76. (*function ReadClipboard(F: PResourceFile): boolean;
  77. begin
  78. ReadClipboard:=true;
  79. end;
  80. function WriteClipboard(F: PResourceFile): boolean;
  81. var S: PMemoryStream;
  82. begin
  83. if Assigned(Clipboard) then
  84. begin
  85. PushStatus('Storing clipboard content...');
  86. New(S, Init(10*1024,4096));
  87. Clipboard^.SaveToStream(S^);
  88. S^.Seek(0);
  89. F^.CreateResource(resClipboard,rcBinary,0);
  90. F^.AddResourceEntryFromStream(resClipboard,langDefault,0,S^,S^.GetSize);
  91. Dispose(S, Done);
  92. PopStatus;
  93. end;
  94. WriteClipboard:=true;
  95. end;*)
  96. function ReadWatches(F: PResourceFile): boolean;
  97. {$ifndef NODEBUG}
  98. var S: PMemoryStream;
  99. OK: boolean;
  100. OWC : PWatchesCollection;
  101. {$endif}
  102. begin
  103. {$ifndef NODEBUG}
  104. PushStatus('Reading watches...');
  105. New(S, Init(32*1024,4096));
  106. OK:=F^.ReadResourceEntryToStream(resWatches,langDefault,S^);
  107. S^.Seek(0);
  108. if OK then
  109. begin
  110. OWC:=WatchesCollection;
  111. WatchesCollection:=PWatchesCollection(S^.Get);
  112. OK:=(S^.Status=stOK);
  113. if OK and assigned(OWC) and assigned(WatchesCollection) then
  114. Dispose(OWC,Done)
  115. else if assigned(OWC) then
  116. WatchesCollection:=OWC;
  117. end;
  118. ReadWatches:=OK;
  119. Dispose(S, Done);
  120. PopStatus;
  121. {$else NODEBUG}
  122. ReadWatches:=true;
  123. {$endif NODEBUG}
  124. end;
  125. function WriteWatches(F: PResourceFile): boolean;
  126. var
  127. S : PMemoryStream;
  128. begin
  129. {$ifndef NODEBUG}
  130. if not assigned(WatchesCollection) then
  131. {$endif NODEBUG}
  132. WriteWatches:=true
  133. {$ifndef NODEBUG}
  134. else
  135. begin
  136. PushStatus('Storing watches...');
  137. New(S, Init(30*1024,4096));
  138. S^.Put(WatchesCollection);
  139. S^.Seek(0);
  140. F^.CreateResource(resWatches,rcBinary,0);
  141. WriteWatches:=F^.AddResourceEntryFromStream(resWatches,langDefault,0,S^,S^.GetSize);
  142. Dispose(S, Done);
  143. PopStatus;
  144. end;
  145. {$endif NODEBUG}
  146. end;
  147. function ReadBreakpoints(F: PResourceFile): boolean;
  148. {$ifndef NODEBUG}
  149. var S: PMemoryStream;
  150. OK: boolean;
  151. OBC : PBreakpointCollection;
  152. {$endif}
  153. begin
  154. {$ifndef NODEBUG}
  155. PushStatus('Reading breakpoints...');
  156. New(S, Init(32*1024,4096));
  157. OK:=F^.ReadResourceEntryToStream(resBreakpoints,langDefault,S^);
  158. S^.Seek(0);
  159. if OK then
  160. begin
  161. OBC:=BreakpointsCollection;
  162. BreakpointsCollection:=PBreakpointCollection(S^.get);
  163. OK:=(S^.Status=stOK);
  164. If OK and assigned(OBC) and assigned(BreakpointsCollection) then
  165. Dispose(OBC,Done)
  166. else if assigned(OBC) then
  167. BreakpointsCollection:=OBC;
  168. end;
  169. ReadBreakpoints:=OK;
  170. Dispose(S, Done);
  171. PopStatus;
  172. {$else NODEBUG}
  173. ReadBreakpoints:=true;
  174. {$endif NODEBUG}
  175. end;
  176. function WriteBreakpoints(F: PResourceFile): boolean;
  177. var
  178. S : PMemoryStream;
  179. begin
  180. {$ifndef NODEBUG}
  181. if not assigned(BreakpointsCollection) then
  182. {$endif NODEBUG}
  183. WriteBreakPoints:=true
  184. {$ifndef NODEBUG}
  185. else
  186. begin
  187. PushStatus('Storing breakpoints...');
  188. New(S, Init(30*1024,4096));
  189. BreakpointsCollection^.Store(S^);
  190. S^.Seek(0);
  191. F^.CreateResource(resBreakpoints,rcBinary,0);
  192. WriteBreakPoints:=F^.AddResourceEntryFromStream(resBreakpoints,langDefault,0,S^,S^.GetSize);
  193. Dispose(S, Done);
  194. PopStatus;
  195. end;
  196. {$endif NODEBUG}
  197. end;
  198. function ReadOpenWindows(F: PResourceFile): boolean;
  199. var S: PMemoryStream;
  200. TempDesk: PFPDesktop;
  201. OK: boolean;
  202. R : TRect;
  203. W: word;
  204. begin
  205. PushStatus('Reading desktop contents...');
  206. New(S, Init(32*1024,4096));
  207. OK:=F^.ReadResourceEntryToStream(resDesktop,langDefault,S^);
  208. S^.Seek(0);
  209. if OK then
  210. begin
  211. S^.Read(W,SizeOf(W));
  212. OK:=(W=DesktopVersion);
  213. if OK=false then
  214. ErrorBox('Invalid desktop version. Desktop layout lost.',nil);
  215. end;
  216. if OK then
  217. begin
  218. TempDesk:=PFPDesktop(S^.Get);
  219. OK:=Assigned(TempDesk);
  220. if OK then
  221. begin
  222. Dispose(Desktop, Done);
  223. Desktop:=TempDesk;
  224. with Desktop^ do
  225. begin
  226. GetSubViewPtr(S^,CompilerMessageWindow);
  227. GetSubViewPtr(S^,CompilerStatusDialog);
  228. GetSubViewPtr(S^,ClipboardWindow);
  229. if Assigned(ClipboardWindow) then Clipboard:=ClipboardWindow^.Editor;
  230. GetSubViewPtr(S^,CalcWindow);
  231. GetSubViewPtr(S^,ProgramInfoWindow);
  232. GetSubViewPtr(S^,GDBWindow);
  233. GetSubViewPtr(S^,BreakpointsWindow);
  234. GetSubViewPtr(S^,WatchesWindow);
  235. GetSubViewPtr(S^,UserScreenWindow);
  236. GetSubViewPtr(S^,ASCIIChart);
  237. GetSubViewPtr(S^,MessagesWindow); LastToolMessageFocused:=nil;
  238. end;
  239. Application^.GetExtent(R);
  240. Inc(R.A.Y);Dec(R.B.Y);
  241. DeskTop^.Locate(R);
  242. Application^.Insert(Desktop);
  243. Desktop^.ReDraw;
  244. Message(Application,evBroadcast,cmUpdate,nil);
  245. end;
  246. if OK=false then
  247. ErrorBox('Error loading desktop',nil);
  248. end;
  249. Dispose(S, Done);
  250. PopStatus;
  251. ReadOpenWindows:=OK;
  252. end;
  253. function WriteOpenWindows(F: PResourceFile): boolean;
  254. var S: PMemoryStream;
  255. W: word;
  256. OK: boolean;
  257. begin
  258. PushStatus('Storing desktop contents...');
  259. New(S, Init(30*1024,4096));
  260. OK:=Assigned(S);
  261. if OK then
  262. begin
  263. W:=DesktopVersion;
  264. S^.Write(W,SizeOf(W));
  265. S^.Put(Desktop);
  266. with Desktop^ do
  267. begin
  268. PutSubViewPtr(S^,CompilerMessageWindow);
  269. PutSubViewPtr(S^,CompilerStatusDialog);
  270. PutSubViewPtr(S^,ClipboardWindow);
  271. PutSubViewPtr(S^,CalcWindow);
  272. PutSubViewPtr(S^,ProgramInfoWindow);
  273. PutSubViewPtr(S^,GDBWindow);
  274. PutSubViewPtr(S^,BreakpointsWindow);
  275. PutSubViewPtr(S^,WatchesWindow);
  276. PutSubViewPtr(S^,UserScreenWindow);
  277. PutSubViewPtr(S^,ASCIIChart);
  278. PutSubViewPtr(S^,MessagesWindow);
  279. end;
  280. OK:=(S^.Status=stOK);
  281. if OK then
  282. begin
  283. S^.Seek(0);
  284. OK:=F^.CreateResource(resDesktop,rcBinary,0);
  285. OK:=OK and F^.AddResourceEntryFromStream(resDesktop,langDefault,0,S^,S^.GetSize);
  286. end;
  287. Dispose(S, Done);
  288. end;
  289. PopStatus;
  290. WriteOpenWindows:=OK;
  291. end;
  292. function WriteFlags(F: PResourceFile): boolean;
  293. begin
  294. F^.CreateResource(resDesktopFlags,rcBinary,0);
  295. WriteFlags:=F^.AddResourceEntry(resDesktopFlags,langDefault,0,DesktopFileFlags,
  296. SizeOf(DesktopFileFlags));
  297. end;
  298. function ReadFlags(F: PResourceFile): boolean;
  299. var
  300. size : sw_word;
  301. begin
  302. ReadFlags:=F^.ReadResourceEntry(resDesktopFlags,langDefault,DesktopFileFlags,
  303. size);
  304. end;
  305. function WriteVideoMode(F: PResourceFile): boolean;
  306. begin
  307. F^.CreateResource(resVideo,rcBinary,0);
  308. WriteVideoMode:=F^.AddResourceEntry(resVideo,langDefault,0,ScreenMode,
  309. SizeOf(TVideoMode));
  310. end;
  311. function ReadVideoMode(F: PResourceFile;var NewScreenMode : TVideoMode): boolean;
  312. var
  313. size : sw_word;
  314. test : boolean;
  315. begin
  316. size:=SizeOf(TVideoMode);
  317. test:=F^.ReadResourceEntry(resVideo,langDefault,NewScreenMode,
  318. size);
  319. if not test then
  320. NewScreenMode:=ScreenMode;
  321. ReadVideoMode:= test and (size = SizeOf(TVideoMode));
  322. end;
  323. function ReadSymbols(F: PResourceFile): boolean;
  324. var S: PMemoryStream;
  325. OK: boolean;
  326. begin
  327. PushStatus('Reading symbol information...');
  328. New(S, Init(32*1024,4096));
  329. OK:=F^.ReadResourceEntryToStream(resSymbols,langDefault,S^);
  330. S^.Seek(0);
  331. if OK then
  332. LoadBrowserCol(S);
  333. Dispose(S, Done);
  334. PopStatus;
  335. ReadSymbols:=OK;
  336. end;
  337. function WriteSymbols(F: PResourceFile): boolean;
  338. var S: PMemoryStream;
  339. OK: boolean;
  340. begin
  341. OK:=Assigned(Modules);
  342. if OK then
  343. begin
  344. PushStatus('Storing symbol information...');
  345. New(S, Init(200*1024,4096));
  346. StoreBrowserCol(S);
  347. S^.Seek(0);
  348. F^.CreateResource(resSymbols,rcBinary,0);
  349. OK:=F^.AddResourceEntryFromStream(resSymbols,langDefault,0,S^,S^.GetSize);
  350. Dispose(S, Done);
  351. PopStatus;
  352. end;
  353. WriteSymbols:=OK;
  354. end;
  355. function LoadDesktop: boolean;
  356. var OK,VOK: boolean;
  357. F: PResourceFile;
  358. VM : TVideoMode;
  359. begin
  360. PushStatus('Reading desktop file...');
  361. New(F, LoadFile(DesktopPath));
  362. OK:=Assigned(F);
  363. if OK then
  364. begin
  365. OK:=ReadFlags(F);
  366. if OK then
  367. begin
  368. VOK:=ReadVideoMode(F,VM);
  369. if VOK and ((VM.Col<>ScreenMode.Col) or
  370. (VM.Row<>ScreenMode.Row) or (VM.Color<>ScreenMode.Color)) then
  371. Application^.SetScreenVideoMode(VM);
  372. end;
  373. if {OK and} ((DesktopFileFlags and dfHistoryLists)<>0) then
  374. OK:=OK and ReadHistory(F);
  375. if {OK and} ((DesktopFileFlags and dfWatches)<>0) then
  376. OK:=OK and ReadWatches(F);
  377. if {OK and} ((DesktopFileFlags and dfBreakpoints)<>0) then
  378. OK:=OK and ReadBreakpoints(F);
  379. if {OK and} ((DesktopFileFlags and dfOpenWindows)<>0) then
  380. OK:=OK and ReadOpenWindows(F);
  381. { no errors if no browser info available PM }
  382. if {OK and} ((DesktopFileFlags and dfSymbolInformation)<>0) then
  383. OK:=OK and ReadSymbols(F);
  384. Dispose(F, Done);
  385. end;
  386. PopStatus;
  387. LoadDesktop:=OK;
  388. end;
  389. function SaveDesktop: boolean;
  390. var OK: boolean;
  391. F: PResourceFile;
  392. TempPath: string;
  393. ff: file;
  394. begin
  395. TempPath:=DirOf(DesktopPath)+DesktopTempName;
  396. PushStatus('Writing desktop file...');
  397. New(F, CreateFile(TempPath));
  398. if Assigned(Clipboard) then
  399. if (DesktopFileFlags and dfClipboardContent)<>0 then
  400. Clipboard^.Flags:=Clipboard^.Flags or efStoreContent
  401. else
  402. Clipboard^.Flags:=Clipboard^.Flags and not efStoreContent;
  403. OK:=Assigned(F);
  404. {if OK then}
  405. OK:=OK and WriteFlags(F);
  406. {if OK then}
  407. OK:=OK and WriteVideoMode(F);
  408. if {OK and} ((DesktopFileFlags and dfHistoryLists)<>0) then
  409. OK:=OK and WriteHistory(F);
  410. if {OK and} ((DesktopFileFlags and dfWatches)<>0) then
  411. OK:=OK and WriteWatches(F);
  412. if {OK and} ((DesktopFileFlags and dfBreakpoints)<>0) then
  413. OK:=OK and WriteBreakpoints(F);
  414. if {OK and} ((DesktopFileFlags and dfOpenWindows)<>0) then
  415. OK:=OK and WriteOpenWindows(F);
  416. { no errors if no browser info available PM }
  417. if {OK and} ((DesktopFileFlags and dfSymbolInformation)<>0) then
  418. OK:=OK and (WriteSymbols(F) or not Assigned(Modules));
  419. Dispose(F, Done);
  420. if OK then
  421. begin
  422. if ExistsFile(DesktopPath) then
  423. OK:=EraseFile(DesktopPath);
  424. OK:=OK and RenameFile(TempPath,DesktopPath);
  425. if OK=false then
  426. ErrorBox('Failed to replace desktop file.',nil);
  427. end;
  428. PopStatus;
  429. SaveDesktop:=OK;
  430. end;
  431. END.
  432. {
  433. $Log$
  434. Revision 1.18 2000-01-03 11:38:33 michael
  435. Changes from Gabor
  436. Revision 1.17 1999/12/20 00:30:56 pierre
  437. * problem with VideoMode storing solved
  438. Revision 1.16 1999/12/10 13:02:05 pierre
  439. + VideoMode save/restore
  440. Revision 1.15 1999/11/26 17:09:51 pierre
  441. * Force Desktop into Screen
  442. Revision 1.14 1999/11/25 00:25:43 pierre
  443. * add Status when loading/saving files
  444. Revision 1.13 1999/09/20 15:37:59 pierre
  445. * ReadOpenWindows and ReadSymobls was missing, still does not work correctly :(
  446. Revision 1.12 1999/09/17 16:41:10 pierre
  447. * other stream error for Watches/Breakpoints corrected
  448. Revision 1.11 1999/09/17 16:28:58 pierre
  449. * ResWatches in WriteBreakpoints typo !
  450. Revision 1.10 1999/09/16 14:34:58 pierre
  451. + TBreakpoint and TWatch registering
  452. + WatchesCollection and BreakpointsCollection stored in desk file
  453. * Syntax highlighting was broken
  454. Revision 1.9 1999/09/07 09:23:00 pierre
  455. * no errors if no browser info available
  456. Revision 1.8 1999/08/16 18:25:16 peter
  457. * Adjusting the selection when the editor didn't contain any line.
  458. * Reserved word recognition redesigned, but this didn't affect the overall
  459. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  460. The syntax scanner loop is a bit slow but the main problem is the
  461. recognition of special symbols. Switching off symbol processing boosts
  462. the performance up to ca. 200%...
  463. * The editor didn't allow copying (for ex to clipboard) of a single character
  464. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  465. * Compiler Messages window (actually the whole desktop) did not act on any
  466. keypress when compilation failed and thus the window remained visible
  467. + Message windows are now closed upon pressing Esc
  468. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  469. only when neccessary
  470. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  471. + LineSelect (Ctrl+K+L) implemented
  472. * The IDE had problems closing help windows before saving the desktop
  473. Revision 1.7 1999/08/03 20:22:30 peter
  474. + TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
  475. + Desktop saving should work now
  476. - History saved
  477. - Clipboard content saved
  478. - Desktop saved
  479. - Symbol info saved
  480. * syntax-highlight bug fixed, which compared special keywords case sensitive
  481. (for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
  482. * with 'whole words only' set, the editor didn't found occourences of the
  483. searched text, if the text appeared previously in the same line, but didn't
  484. satisfied the 'whole-word' condition
  485. * ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
  486. (ie. the beginning of the selection)
  487. * when started typing in a new line, but not at the start (X=0) of it,
  488. the editor inserted the text one character more to left as it should...
  489. * TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
  490. * Shift shouldn't cause so much trouble in TCodeEditor now...
  491. * Syntax highlight had problems recognizing a special symbol if it was
  492. prefixed by another symbol character in the source text
  493. * Auto-save also occours at Dos shell, Tool execution, etc. now...
  494. Revision 1.5 1999/06/30 23:58:13 pierre
  495. + BreakpointsList Window implemented
  496. with Edit/New/Delete functions
  497. + Individual breakpoint dialog with support for all types
  498. ignorecount and conditions
  499. (commands are not yet implemented, don't know if this wolud be useful)
  500. awatch and rwatch have problems because GDB does not annotate them
  501. I fixed v4.16 for this
  502. Revision 1.4 1999/04/15 08:58:05 peter
  503. * syntax highlight fixes
  504. * browser updates
  505. Revision 1.3 1999/04/07 21:55:45 peter
  506. + object support for browser
  507. * html help fixes
  508. * more desktop saving things
  509. * NODEBUG directive to exclude debugger
  510. Revision 1.2 1999/03/23 16:16:39 peter
  511. * linux fixes
  512. Revision 1.1 1999/03/23 15:11:28 peter
  513. * desktop saving things
  514. * vesa mode
  515. * preferences dialog
  516. }