{ This file is part of the Free Pascal Integrated Development Environment Copyright (c) 1998 by Berczi Gabor Desktop loading/saving routines See the file COPYING.FPC, included in this distribution, for details about the copyright. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **********************************************************************} unit FPDesk; interface const MinDesktopVersion = $000A; DesktopVersion = $000A; { <- if you change any Load&Store methods, default object properties (Options,State) then you should also change this } ResDesktopFlags = 'FLAGS'; ResVideo = 'VIDEOMODE'; ResHistory = 'HISTORY'; ResClipboard = 'CLIPBOARD'; ResWatches = 'WATCHES'; ResBreakpoints = 'BREAKPOINTS'; ResDesktop = 'DESKTOP'; ResSymbols = 'SYMBOLS'; ResCodeComplete = 'CODECOMPLETE'; ResCodeTemplates = 'CODETEMPLATES'; ResKeys = 'KEYS'; procedure InitDesktopFile; function LoadDesktop: boolean; function SaveDesktop: boolean; procedure DoneDesktopFile; function WriteSymbolsFile(const filename : string): boolean; function ReadSymbolsFile(const filename : string): boolean; implementation uses Dos, Objects,Drivers, Video, Views,App,HistList,BrowCol, WUtils,WResourc,WViews,WEditor, fpdebug, wcedit, {$ifdef Unix} FPKeys, {$endif Unix} FPConst,FPVars,FPTools,FPUtils,FPViews,FPHelp, FPCompil,FPCodCmp,FPCodTmp; type TWindowInfo = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} packed {$endif FPC_REQUIRES_PROPER_ALIGNMENT} record HelpCtx : word; Bounds : TRect; Visible : boolean; WinNb : byte; ExtraDataSize : word; TitleLen : word; Title : packed record end; end; {$ifdef useresstrings} resourcestring {$else} const {$endif} { Desktop file messages } msg_readingdesktopfile = 'Reading desktop file...'; msg_writingdesktopfile = 'Writing desktop file...'; msg_readingdesktopcontents = 'Reading desktop contents...'; msg_storingdesktopcontents = 'Storing desktop contents...'; msg_readinghistory = 'Reading history...'; msg_storinghistory = 'Storing history...'; msg_readingwatches = 'Reading watches...'; msg_storingwatches = 'Storing watches...'; msg_readingbreakpoints = 'Reading breakpoints...'; msg_storingbreakpoints = 'Storing breakpoints...'; msg_readingcodecompletewordlist = 'Reading CodeComplete wordlist...'; msg_storingcodecompletewordlist = 'Writing CodeComplete wordlist...'; msg_readingcodetemplates = 'Reading CodeTemplates...'; msg_storingcodetemplates = 'Writing CodeTemplates...'; msg_readingsymbolinformation = 'Reading symbol information...'; msg_storingsymbolinformation = 'Storing symbol information...'; msg_failedtoreplacedesktopfile = 'Failed to replace desktop file.'; msg_errorloadinghistory = 'Error loading history'; msg_errorstoringhistory = 'Error storing history'; msg_errorloadingkeys = 'Error loading custom keys'; msg_errorstoringkeys = 'Error storing custom keys'; msg_errorloadingwatches = 'Error loading watches'; msg_errorstoringwatches = 'Error storing watches'; msg_errorloadingbreakpoints = 'Error loading breakpoints'; msg_errorstoringbreakpoints = 'Error storing breakpoints'; msg_errorloadingdesktop = 'Error loading desktop'; msg_errorstoringdesktop = 'Error storing desktop'; msg_errorreadingflags = 'Error loading flags'; msg_errorwritingflags = 'Error writing flags'; msg_errorreadingvideomode = 'Error reading video mode'; msg_errorstoringvideomode = 'Error storing video mode'; msg_errorloadingcodetemplates = 'Error loading CodeTemplates'; msg_errorstoringcodetemplates = 'Error writing CodeTemplates'; msg_errorloadingsymbolinformation = 'Error loading symbol information'; msg_errorstoringsymbolinformation = 'Error storing symbol information'; msg_errorloadingcodecompletewordlist = 'Error loading CodeComplete wordlist'; msg_errorstoringcodecompletewordlist = 'Error writing CodeComplete wordlist'; msg_invaliddesktopversionlayoutlost = 'Invalid desktop version. Desktop layout lost.'; msg_saveansifile = 'Save previous screen as Ansi File'; msg_click_upper_left = 'Click to select upper left corner; Escape to cancel; Enter to select (0,0)'; msg_click_lower_right = 'Click to select lower right corner; Escape to cancel; Enter to select (maxX,maxY)'; msg_cantopenfile = 'Can''t open %s'; msg_cantcreatefile = 'Can''t create %s'; msg_cantfindfile = 'Can''t find %s'; msg_errorreadingfile = 'Error reading file %s'; msg_loadingfile = 'Loading %s'; msg_storingfile = 'Storing %s'; msg_closingfile = 'Closing %s'; msg_openingsourcefile = 'Opening source file... (%s)'; msg_readingfileineditor = 'Reading %s into editor...'; procedure InitDesktopFile; begin if DesktopLocation=dlCurrentDir then DesktopPath:=FExpand(DesktopName) else DesktopPath:=FExpand(DirOf(IniFileName)+DesktopName); end; procedure DoneDesktopFile; begin end; function ReadHistory(F: PResourceFile): boolean; var S: PMemoryStream; OK: boolean; begin PushStatus(msg_readinghistory); New(S, Init(32*1024,4096)); OK:=F^.ReadResourceEntryToStream(resHistory,langDefault,S^); S^.Seek(0); if OK then LoadHistory(S^); Dispose(S, Done); if OK=false then ErrorBox(msg_errorloadinghistory,nil); PopStatus; ReadHistory:=OK; end; function WriteHistory(F: PResourceFile): boolean; var S: PMemoryStream; OK: boolean; begin PushStatus(msg_storinghistory); New(S, Init(10*1024,4096)); StoreHistory(S^); S^.Seek(0); F^.CreateResource(resHistory,rcBinary,0); OK:=F^.AddResourceEntryFromStream(resHistory,langDefault,0,S^,S^.GetSize); Dispose(S, Done); if OK=false then ErrorBox(msg_errorstoringhistory,nil); PopStatus; WriteHistory:=OK; end; {$ifdef Unix} function ReadKeys(F: PResourceFile): boolean; var S: PMemoryStream; OK: boolean; begin New(S, Init(32*1024,4096)); OK:=F^.ReadResourceEntryToStream(resKeys,langDefault,S^); S^.Seek(0); if OK then LoadKeys(S^); Dispose(S, Done); if OK=false then ErrorBox(msg_errorloadingkeys,nil); ReadKeys:=OK; end; function WriteKeys(F: PResourceFile): boolean; var S: PMemoryStream; OK: boolean; begin New(S, Init(10*1024,4096)); StoreKeys(S^); S^.Seek(0); F^.CreateResource(resKeys,rcBinary,0); OK:=F^.AddResourceEntryFromStream(resKeys,langDefault,0,S^,S^.GetSize); Dispose(S, Done); if OK=false then ErrorBox(msg_errorstoringkeys,nil); WriteKeys:=OK; end; {$endif Unix} (*function ReadClipboard(F: PResourceFile): boolean; begin ReadClipboard:=true; end; function WriteClipboard(F: PResourceFile): boolean; var S: PMemoryStream; begin if Assigned(Clipboard) then begin PushStatus('Storing clipboard content...'); New(S, Init(10*1024,4096)); Clipboard^.SaveToStream(S^); S^.Seek(0); F^.CreateResource(resClipboard,rcBinary,0); F^.AddResourceEntryFromStream(resClipboard,langDefault,0,S^,S^.GetSize); Dispose(S, Done); PopStatus; end; WriteClipboard:=true; end;*) function ReadWatches(F: PResourceFile): boolean; {$ifndef NODEBUG} var S: PMemoryStream; OK: boolean; OWC : PWatchesCollection; {$endif} begin {$ifndef NODEBUG} PushStatus(msg_readingwatches); New(S, Init(32*1024,4096)); OK:=F^.ReadResourceEntryToStream(resWatches,langDefault,S^); S^.Seek(0); if OK then begin OWC:=WatchesCollection; WatchesCollection:=PWatchesCollection(S^.Get); OK:=(S^.Status=stOK); if OK and assigned(OWC) and assigned(WatchesCollection) then Dispose(OWC,Done) else if assigned(OWC) then WatchesCollection:=OWC; end; if OK=false then ErrorBox(msg_errorloadingwatches,nil); ReadWatches:=OK; Dispose(S, Done); PopStatus; {$else NODEBUG} ReadWatches:=true; {$endif NODEBUG} end; function WriteWatches(F: PResourceFile): boolean; var S : PMemoryStream; OK : boolean; begin {$ifndef NODEBUG} if not assigned(WatchesCollection) then {$endif NODEBUG} WriteWatches:=true {$ifndef NODEBUG} else begin PushStatus(msg_storingwatches); New(S, Init(30*1024,4096)); S^.Put(WatchesCollection); S^.Seek(0); F^.CreateResource(resWatches,rcBinary,0); OK:=F^.AddResourceEntryFromStream(resWatches,langDefault,0,S^,S^.GetSize); Dispose(S, Done); if OK=false then ErrorBox(msg_errorstoringwatches,nil); PopStatus; WriteWatches:=OK; end; {$endif NODEBUG} end; function ReadBreakpoints(F: PResourceFile): boolean; {$ifndef NODEBUG} var S: PMemoryStream; OK: boolean; OBC : PBreakpointCollection; {$endif} begin {$ifndef NODEBUG} PushStatus(msg_readingbreakpoints); New(S, Init(32*1024,4096)); OK:=F^.ReadResourceEntryToStream(resBreakpoints,langDefault,S^); S^.Seek(0); if OK then begin OBC:=BreakpointsCollection; BreakpointsCollection:=PBreakpointCollection(S^.get); OK:=(S^.Status=stOK); If OK and assigned(OBC) and assigned(BreakpointsCollection) then Begin Dispose(OBC,Done); BreakpointsCollection^.ShowAllBreakpoints; end else if assigned(OBC) then BreakpointsCollection:=OBC; end; if OK=false then ErrorBox(msg_errorloadingbreakpoints,nil); ReadBreakpoints:=OK; Dispose(S, Done); PopStatus; {$else NODEBUG} ReadBreakpoints:=true; {$endif NODEBUG} end; function WriteBreakpoints(F: PResourceFile): boolean; var S : PMemoryStream; OK : boolean; begin {$ifndef NODEBUG} if not assigned(BreakpointsCollection) then {$endif NODEBUG} WriteBreakPoints:=true {$ifndef NODEBUG} else begin PushStatus(msg_storingbreakpoints); New(S, Init(30*1024,4096)); S^.Put(BreakpointsCollection); S^.Seek(0); F^.CreateResource(resBreakpoints,rcBinary,0); OK:=F^.AddResourceEntryFromStream(resBreakpoints,langDefault,0,S^,S^.GetSize); Dispose(S, Done); if OK=false then ErrorBox(msg_errorstoringbreakpoints,nil); WriteBreakPoints:=OK; PopStatus; end; {$endif NODEBUG} end; function DeskUseSyntaxHighlight(Editor: PFileEditor): boolean; var b : boolean; begin b:= (*(Editor^.IsFlagSet(efSyntaxHighlight)) and *) ((Editor^.FileName='') or MatchesFileList(NameAndExtOf(Editor^.FileName),HighlightExts)); DeskUseSyntaxHighlight:=b; end; function ReadOpenWindows(F: PResourceFile): boolean; var S: PMemoryStream; OK: boolean; DV: word; WI: TWindowInfo; Title: string; XDataOfs: word; XData: array[0..1024] of byte; procedure GetData(var B; Size: word); begin Move(XData[XDataOfs],B,Size); Inc(XDataOfs,Size); end; procedure ProcessWindowInfo; var W: PWindow; SW: PSourceWindow absolute W; St: string; Ch: char; TP,TP2: TPoint; L: longint; R: TRect; begin XDataOfs:=0; Desktop^.Lock; W:=SearchWindow(Title); case WI.HelpCtx of hcSourceWindow : begin GetData(St[0],1); GetData(St[1],ord(St[0])); W:=ITryToOpenFile(@WI.Bounds,St,0,0,false,false,true); if Assigned(W)=false then begin ClearFormatParams; AddFormatParamStr(St); Desktop^.Unlock; ErrorBox(msg_cantopenfile,@FormatParams); Desktop^.Lock; end else begin GetData(L,sizeof(L)); If DeskUseSyntaxHighlight(SW^.Editor) Then L:=L or efSyntaxHighlight else L:=L and not efSyntaxHighlight; SW^.Editor^.SetFlags(L); GetData(TP,sizeof(TP)); GetData(TP2,sizeof(TP2)); SW^.Editor^.SetSelection(TP,TP2); GetData(TP,sizeof(TP)); SW^.Editor^.SetCurPtr(TP.X,TP.Y); GetData(TP,sizeof(TP)); SW^.Editor^.ScrollTo(TP.X,TP.Y); end; end; hcClipboardWindow: W:=ClipboardWindow; hcCalcWindow: W:=CalcWindow; hcMessagesWindow: begin if MessagesWindow=nil then Desktop^.Insert(New(PMessagesWindow, Init)); W:=MessagesWindow; end; hcCompilerMessagesWindow: W:=CompilerMessageWindow; {$ifndef NODEBUG} hcGDBWindow: begin InitGDBWindow; W:=GDBWindow; end; hcDisassemblyWindow: begin InitDisassemblyWindow; W:=DisassemblyWindow; end; hcWatchesWindow: begin if WatchesWindow=nil then begin New(WatchesWindow,Init); Desktop^.Insert(WatchesWindow); end; W:=WatchesWindow; end; hcStackWindow: begin if StackWindow=nil then begin New(StackWindow,Init); Desktop^.Insert(StackWindow); end; W:=StackWindow; end; hcFPURegisters: begin if FPUWindow=nil then begin New(FPUWindow,Init); Desktop^.Insert(FPUWindow); end; W:=FPUWindow; end; hcVectorRegisters: begin if VectorWindow=nil then begin New(VectorWindow,Init); Desktop^.Insert(VectorWindow); end; W:=VectorWindow; end; hcRegistersWindow: begin if RegistersWindow=nil then begin New(RegistersWindow,Init); Desktop^.Insert(RegistersWindow); end; W:=RegistersWindow; end; hcBreakpointListWindow: begin if BreakpointsWindow=nil then begin New(BreakpointsWindow,Init); Desktop^.Insert(BreakpointsWindow); end; W:=BreakpointsWindow; end; {$endif NODEBUG} hcASCIITableWindow: begin if ASCIIChart=nil then begin New(ASCIIChart, Init); Desktop^.Insert(ASCIIChart); end; W:=ASCIIChart; if DV>=$A then begin GetData(ch,sizeof(char)); AsciiChart^.Report^.AsciiChar:=ord(ch); AsciiChart^.Table^.SetCursor( ord(ch) mod AsciiChart^.Table^.Size.X, ord(ch) div AsciiChart^.Table^.Size.X); end; end; end; if W=nil then begin Desktop^.Unlock; Exit; end; W^.GetBounds(R); if (R.A.X<>WI.Bounds.A.X) or (R.A.Y<>WI.Bounds.A.Y) then R.Move(WI.Bounds.A.X-R.A.X,WI.Bounds.A.Y-R.A.Y); if (W^.Flags and wfGrow)<>0 then begin R.B.X:=R.A.X+(WI.Bounds.B.X-WI.Bounds.A.X); R.B.Y:=R.A.Y+(WI.Bounds.B.Y-WI.Bounds.A.Y); end; W^.Locate(R); if W^.GetState(sfVisible)<>WI.Visible then if WI.Visible then begin W^.Show; W^.MakeFirst; end else W^.Hide; W^.Number:=WI.WinNb; Desktop^.Unlock; end; begin PushStatus(msg_readingdesktopcontents); New(S, Init(32*1024,4096)); OK:=F^.ReadResourceEntryToStream(resDesktop,langDefault,S^); S^.Seek(0); if OK then begin S^.Read(DV,SizeOf(DV)); OK:=(DV=DesktopVersion) or (DV>=MinDesktopVersion); if OK=false then ErrorBox(msg_invaliddesktopversionlayoutlost,nil); end; if OK then begin XDataOfs:=0; repeat S^.Read(WI,sizeof(WI)); if S^.Status=stOK then begin Title[0]:=chr(WI.TitleLen); S^.Read(Title[1],WI.TitleLen); if WI.ExtraDataSize>0 then S^.Read(XData,WI.ExtraDataSize); ProcessWindowInfo; end; until (S^.Status<>stOK) or (S^.GetPos=S^.GetSize); (* TempDesk:=PFPDesktop(S^.Get); OK:=Assigned(TempDesk); if OK then begin Dispose(Desktop, Done); Desktop:=TempDesk; with Desktop^ do begin GetSubViewPtr(S^,CompilerMessageWindow); GetSubViewPtr(S^,CompilerStatusDialog); GetSubViewPtr(S^,ClipboardWindow); if Assigned(ClipboardWindow) then Clipboard:=ClipboardWindow^.Editor; GetSubViewPtr(S^,CalcWindow); GetSubViewPtr(S^,GDBWindow); GetSubViewPtr(S^,BreakpointsWindow); GetSubViewPtr(S^,WatchesWindow); GetSubViewPtr(S^,UserScreenWindow); GetSubViewPtr(S^,ASCIIChart); GetSubViewPtr(S^,MessagesWindow); LastToolMessageFocused:=nil; end; Application^.GetExtent(R); Inc(R.A.Y);Dec(R.B.Y); DeskTop^.Locate(R); Application^.Insert(Desktop); Desktop^.ReDraw; Message(Application,evBroadcast,cmUpdate,nil); end;*) if OK=false then ErrorBox(msg_errorloadingdesktop,nil); end; Dispose(S, Done); PopStatus; ReadOpenWindows:=OK; end; function WriteOpenWindows(F: PResourceFile): boolean; var S: PMemoryStream; procedure CollectInfo(P: PView); var W: PWindow; SW: PSourceWindow absolute W; WI: TWindowInfo; Title: string; XDataOfs: word; XData: array[0..1024] of byte; St: string; Ch: char; TP: TPoint; L: longint; procedure AddData(const B; Size: word); begin Move(B,XData[XDataOfs],Size); Inc(XDataOfs,Size); end; begin XDataOfs:=0; W:=nil; if (P^.HelpCtx=hcSourceWindow) or (P^.HelpCtx=hcHelpWindow) or (P^.HelpCtx=hcClipboardWindow) or (P^.HelpCtx=hcCalcWindow) or (P^.HelpCtx=hcInfoWindow) or (P^.HelpCtx=hcBrowserWindow) or (P^.HelpCtx=hcMessagesWindow) or (P^.HelpCtx=hcCompilerMessagesWindow) or (P^.HelpCtx=hcGDBWindow) or (P^.HelpCtx=hcDisassemblyWindow) or (P^.HelpCtx=hcStackWindow) or (P^.HelpCtx=hcRegistersWindow) or (P^.HelpCtx=hcFPURegisters) or (P^.HelpCtx=hcVectorRegisters) or (P^.HelpCtx=hcWatchesWindow) or (P^.HelpCtx=hcBreakpointListWindow) or (P^.HelpCtx=hcASCIITableWindow) then W:=PWindow(P); if Assigned(W) and (P^.HelpCtx=hcSourceWindow) then if SW^.Editor^.FileName='' then W:=nil; if W=nil then Exit; FillChar(WI,sizeof(WI),0); Title:=W^.GetTitle(255); WI.HelpCtx:=W^.HelpCtx; W^.GetBounds(WI.Bounds); WI.Visible:=W^.GetState(sfVisible); WI.WinNb:=W^.Number; case WI.HelpCtx of hcSourceWindow : begin St:=SW^.Editor^.FileName; AddData(St,length(St)+1); L:=SW^.Editor^.GetFlags; AddData(L,sizeof(L)); TP:=SW^.Editor^.SelStart; AddData(TP,sizeof(TP)); TP:=SW^.Editor^.SelEnd; AddData(TP,sizeof(TP)); TP:=SW^.Editor^.CurPos; AddData(TP,sizeof(TP)); TP:=SW^.Editor^.Delta; AddData(TP,sizeof(TP)); end; hcAsciiTableWindow : begin ch:=chr(PFPAsciiChart(P)^.Report^.AsciiChar); AddData(ch,sizeof(char)); end; end; WI.TitleLen:=length(Title); WI.ExtraDataSize:=XDataOfs; S^.Write(WI,sizeof(WI)); S^.Write(Title[1],WI.TitleLen); if WI.ExtraDataSize>0 then S^.Write(XData,WI.ExtraDataSize); end; var W: word; OK: boolean; PV: PView; begin PushStatus(msg_storingdesktopcontents); New(S, Init(30*1024,4096)); OK:=Assigned(S); if OK then begin W:=DesktopVersion; S^.Write(W,SizeOf(W)); { S^.Put(Desktop); with Desktop^ do begin PutSubViewPtr(S^,CompilerMessageWindow); PutSubViewPtr(S^,CompilerStatusDialog); PutSubViewPtr(S^,ClipboardWindow); PutSubViewPtr(S^,CalcWindow); PutSubViewPtr(S^,GDBWindow); PutSubViewPtr(S^,BreakpointsWindow); PutSubViewPtr(S^,WatchesWindow); PutSubViewPtr(S^,UserScreenWindow); PutSubViewPtr(S^,ASCIIChart); PutSubViewPtr(S^,MessagesWindow); end;} { PV:=Application^.Last; while PV<>nil do begin CollectInfo(PV); PV:=PV^.PrevView; end;} PV:=Desktop^.Last; while PV<>nil do begin CollectInfo(PV); PV:=PV^.PrevView; end; OK:=(S^.Status=stOK); if OK then begin S^.Seek(0); OK:=F^.CreateResource(resDesktop,rcBinary,0); OK:=OK and F^.AddResourceEntryFromStream(resDesktop,langDefault,0,S^,S^.GetSize); end; Dispose(S, Done); end; if OK=false then ErrorBox(msg_errorstoringdesktop,nil); PopStatus; WriteOpenWindows:=OK; end; function WriteFlags(F: PResourceFile): boolean; var OK: boolean; begin F^.CreateResource(resDesktopFlags,rcBinary,0); OK:=F^.AddResourceEntry(resDesktopFlags,langDefault,0,DesktopFileFlags, SizeOf(DesktopFileFlags)); if OK=false then ErrorBox(msg_errorwritingflags,nil); WriteFlags:=OK; end; function ReadCodeComplete(F: PResourceFile): boolean; var S: PMemoryStream; OK: boolean; begin PushStatus(msg_readingcodecompletewordlist); New(S, Init(1024,1024)); OK:=F^.ReadResourceEntryToStream(resCodeComplete,langDefault,S^); S^.Seek(0); if OK then OK:=LoadCodeComplete(S^); Dispose(S, Done); if OK=false then ErrorBox(msg_errorloadingcodecompletewordlist,nil); PopStatus; ReadCodeComplete:=OK; end; function WriteCodeComplete(F: PResourceFile): boolean; var OK: boolean; S: PMemoryStream; begin PushStatus(msg_storingcodecompletewordlist); New(S, Init(1024,1024)); OK:=StoreCodeComplete(S^); if OK then begin S^.Seek(0); F^.CreateResource(resCodeComplete,rcBinary,0); OK:=F^.AddResourceEntryFromStream(resCodeComplete,langDefault,0,S^,S^.GetSize); end; Dispose(S, Done); if OK=false then ErrorBox(msg_errorstoringcodecompletewordlist,nil); PopStatus; WriteCodeComplete:=OK; end; function ReadCodeTemplates(F: PResourceFile): boolean; var S: PMemoryStream; OK: boolean; begin PushStatus(msg_readingcodetemplates); New(S, Init(1024,4096)); OK:=F^.ReadResourceEntryToStream(resCodeTemplates,langDefault,S^); S^.Seek(0); if OK then OK:=LoadCodeTemplates(S^); Dispose(S, Done); if OK=false then ErrorBox(msg_errorloadingcodetemplates,nil); PopStatus; ReadCodeTemplates:=OK; end; function WriteCodeTemplates(F: PResourceFile): boolean; var OK: boolean; S: PMemoryStream; begin PushStatus(msg_storingcodetemplates); New(S, Init(1024,4096)); OK:=StoreCodeTemplates(S^); if OK then begin S^.Seek(0); F^.CreateResource(resCodeTemplates,rcBinary,0); OK:=F^.AddResourceEntryFromStream(resCodeTemplates,langDefault,0,S^,S^.GetSize); end; Dispose(S, Done); if OK=false then ErrorBox(msg_errorstoringcodetemplates,nil); PopStatus; WriteCodeTemplates:=OK; end; function ReadFlags(F: PResourceFile): boolean; var OK: boolean; begin OK:=F^.ReadResourceEntry(resDesktopFlags,langDefault,DesktopFileFlags, sizeof(DesktopFileFlags)); if OK=false then ErrorBox(msg_errorreadingflags,nil); ReadFlags:=OK; end; function WriteVideoMode(F: PResourceFile): boolean; var OK: boolean; begin F^.CreateResource(resVideo,rcBinary,0); OK:=F^.AddResourceEntry(resVideo,langDefault,0,ScreenMode, SizeOf(TVideoMode)); if OK=false then ErrorBox(msg_errorstoringvideomode,nil); WriteVideoMode:=OK; end; function ReadVideoMode(F: PResourceFile;var NewScreenMode : TVideoMode): boolean; var OK,test : boolean; begin test:=F^.ReadResourceEntry(resVideo,langDefault,NewScreenMode, sizeof(NewScreenMode)); if not test then NewScreenMode:=ScreenMode; OK:=test; if OK=false then ErrorBox(msg_errorreadingvideomode,nil); ReadVideoMode:=OK; end; function ReadSymbols(F: PResourceFile): boolean; var S: PMemoryStream; OK: boolean; R: PResource; begin ReadSymbols:=false; { if no symbols stored ... no problems } R:=F^.FindResource(resSymbols); if not Assigned(R) then exit; PushStatus(msg_readingsymbolinformation); New(S, Init(32*1024,4096)); OK:=F^.ReadResourceEntryToStream(resSymbols,langDefault,S^); S^.Seek(0); if OK then OK:=LoadBrowserCol(S); Dispose(S, Done); if OK=false then ErrorBox(msg_errorloadingsymbolinformation,nil); PopStatus; ReadSymbols:=OK; end; function WriteSymbols(F: PResourceFile): boolean; var S: PMemoryStream; OK: boolean; begin OK:=Assigned(Modules); if OK then begin PushStatus(msg_storingsymbolinformation); New(S, Init(200*1024,4096)); OK:=Assigned(S); if OK then OK:=StoreBrowserCol(S); if OK then begin S^.Seek(0); F^.CreateResource(resSymbols,rcBinary,0); OK:=F^.AddResourceEntryFromStream(resSymbols,langDefault,0,S^,S^.GetSize); end; Dispose(S, Done); if OK=false then ErrorBox(msg_errorstoringsymbolinformation,nil); PopStatus; end; WriteSymbols:=OK; end; function LoadDesktop: boolean; var OK,VOK: boolean; F: PResourceFile; VM : TVideoMode; begin PushStatus(msg_readingdesktopfile); New(F, LoadFile(DesktopPath)); OK:=false; if Assigned(F) then begin OK:=ReadFlags(F); VOK:=ReadVideoMode(F,VM); if VOK and ((VM.Col<>ScreenMode.Col) or (VM.Row<>ScreenMode.Row) or (VM.Color<>ScreenMode.Color)) then begin if Assigned(Application) then Application^.SetScreenVideoMode(VM); end; if ((DesktopFileFlags and dfHistoryLists)<>0) then OK:=ReadHistory(F) and OK; if ((DesktopFileFlags and dfWatches)<>0) then OK:=ReadWatches(F) and OK; if ((DesktopFileFlags and dfBreakpoints)<>0) then OK:=ReadBreakpoints(F) and OK; if ((DesktopFileFlags and dfOpenWindows)<>0) then OK:=ReadOpenWindows(F) and OK; { no errors if no browser info available PM } if ((DesktopFileFlags and dfSymbolInformation)<>0) then OK:=ReadSymbols(F) and OK; if ((DesktopFileFlags and dfCodeCompleteWords)<>0) then OK:=ReadCodeComplete(F) and OK; if ((DesktopFileFlags and dfCodeTemplates)<>0) then OK:=ReadCodeTemplates(F) and OK; {$ifdef Unix} OK:=ReadKeys(F) and OK; {$endif Unix} Dispose(F, Done); end; PopStatus; LoadDesktop:=OK; end; function SaveDesktop: boolean; var OK: boolean; F: PResourceFile; TempPath: string; begin TempPath:=DirOf(DesktopPath)+DesktopTempName; PushStatus(msg_writingdesktopfile); New(F, CreateFile(TempPath)); if Assigned(Clipboard) then if (DesktopFileFlags and dfClipboardContent)<>0 then Clipboard^.SetFlags(Clipboard^.GetFlags or efStoreContent) else Clipboard^.SetFlags(Clipboard^.GetFlags and not efStoreContent); OK:=false; if Assigned(F) then begin OK:=WriteFlags(F); OK:=OK and WriteVideoMode(F); if ((DesktopFileFlags and dfHistoryLists)<>0) then OK:=OK and WriteHistory(F); if ((DesktopFileFlags and dfWatches)<>0) then OK:=OK and WriteWatches(F); if ((DesktopFileFlags and dfBreakpoints)<>0) then OK:=OK and WriteBreakpoints(F); if ((DesktopFileFlags and dfOpenWindows)<>0) then OK:=OK and WriteOpenWindows(F); { no errors if no browser info available PM } if ((DesktopFileFlags and dfSymbolInformation)<>0) then OK:=OK and (WriteSymbols(F) or not Assigned(Modules)); if ((DesktopFileFlags and dfCodeCompleteWords)<>0) then OK:=OK and WriteCodeComplete(F); if ((DesktopFileFlags and dfCodeTemplates)<>0) then OK:=OK and WriteCodeTemplates(F); {$ifdef Unix} OK:=OK and WriteKeys(F); {$endif Unix} Dispose(F, Done); end; if OK then begin if ExistsFile(DesktopPath) then OK:=EraseFile(DesktopPath); OK:=OK and RenameFile(TempPath,DesktopPath); if OK=false then ErrorBox(msg_failedtoreplacedesktopfile,nil); end; PopStatus; SaveDesktop:=OK; end; function WriteSymbolsFile(const filename : string): boolean; var OK: boolean; F: PResourceFile; begin WriteSymbolsFile:=false; If not assigned(Modules) then exit; New(F, CreateFile(FileName)); OK:=Assigned(F); if OK and ((DesktopFileFlags and dfSymbolInformation)<>0) then OK:=OK and WriteSymbols(F); if assigned(F) then Dispose(F,Done); WriteSymbolsFile:=OK; end; function ReadSymbolsFile(const FileName : string): boolean; var OK: boolean; F: PResourceFile; begin ReadSymbolsFile:=false; { Don't read again !! } If assigned(Modules) then exit; New(F, LoadFile(FileName)); OK:=Assigned(F); if OK and ((DesktopFileFlags and dfSymbolInformation)<>0) then OK:=OK and ReadSymbols(F); if assigned(F) then Dispose(F,Done); ReadSymbolsFile:=OK; end; END.