fpini.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Write/Read Options to INI File
  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 FPIni;
  12. interface
  13. {$i globdir.inc}
  14. uses
  15. FPUtils;
  16. procedure InitDirs;
  17. procedure InitINIFile;
  18. procedure CheckINIFile;
  19. function ReadINIFile: boolean;
  20. function WriteINIFile(FromSaveAs : boolean) : boolean;
  21. function GetPrinterDevice: string;
  22. procedure SetPrinterDevice(const Device: string);
  23. implementation
  24. uses
  25. sysutils, { used for SameFileName function }
  26. Dos,Objects,Drivers,
  27. FVConsts,
  28. Version,
  29. {$ifdef USE_EXTERNAL_COMPILER}
  30. fpintf, { superseeds version_string of version unit }
  31. {$endif USE_EXTERNAL_COMPILER}
  32. WConsts,WUtils,WINI,WViews,WEditor,WCEdit,
  33. {$ifndef NODEBUG}FPDebug,{$endif}FPConst,FPVars,
  34. FPIntf,FPTools,FPSwitch,fpccrc;
  35. const
  36. PrinterDevice : string = 'prn';
  37. {$ifdef useresstrings}
  38. resourcestring
  39. {$else}
  40. const
  41. {$endif}
  42. btn_config_copyexisting = 'Copy ~e~xisting';
  43. btn_config_createnew = ' Create ~n~ew ';
  44. msg_doyouwanttocreatelocalconfigfile =
  45. 'The Free Pascal IDE was never started in this directory before. '+
  46. 'Do you want to create a new config file in this directory? '{#13+
  47. '(If you answer with "No", the IDE will use '+
  48. 'the config file located in "%s")'};
  49. msg_configcopyexistingorcreatenew =
  50. 'Do you want to copy the existing configuration or '+
  51. 'create a new one from scratch?';
  52. function GetPrinterDevice: string;
  53. begin
  54. GetPrinterDevice:=PrinterDevice;
  55. end;
  56. procedure SetPrinterDevice(const Device: string);
  57. begin
  58. PrinterDevice:=Device;
  59. end;
  60. const
  61. { INI file sections }
  62. secFiles = 'Files';
  63. secRun = 'Run';
  64. secCompile = 'Compile';
  65. secColors = 'Colors';
  66. secHelp = 'Help';
  67. secEditor = 'Editor';
  68. secBreakpoint = 'Breakpoints';
  69. secWatches = 'Watches';
  70. secHighlight = 'Highlight';
  71. secKeyboard = 'Keyboard';
  72. secMouse = 'Mouse';
  73. secSearch = 'Search';
  74. secTools = 'Tools';
  75. secSourcePath = 'SourcePath';
  76. secPreferences = 'Preferences';
  77. secMisc = 'Misc';
  78. { INI file tags }
  79. ieRecentFile = 'RecentFile';
  80. iePrinterDevice = 'PrinterDevice';
  81. (* ieOpenFile = 'OpenFile';
  82. ieOpenFileCount = 'OpenFileCount'; *)
  83. ieRunDir = 'RunDirectory';
  84. ieRunParameters = 'Parameters';
  85. ieDebuggeeRedir = 'DebugRedirection';
  86. ieRemoteMachine = 'RemoteMachine';
  87. ieRemotePort = 'RemotePort';
  88. ieRemotePuttySession = 'RemotePuttySession';
  89. ieRemoteSendCommand = 'RemoteSendCommand';
  90. ieRemoteExecCommand = 'RemoteExecCommand';
  91. ieRemoteSshExecCommand = 'RemoteSshExecCommand';
  92. ieRemoteConfig = 'RemoteSendConfig';
  93. ieRemoteIdent = 'RemoteSendIdent';
  94. ieRemoteDirectory = 'RemoteDirectory';
  95. ieRemoteCopy = 'RemoteCopy';
  96. ieRemoteShell = 'RemoteShell';
  97. ieRemoteGdbServer = 'gdbserver';
  98. iePrimaryFile = 'PrimaryFile';
  99. ieCompileMode = 'CompileMode';
  100. iePalette = 'Palette';
  101. ieHelpFiles = 'Files';
  102. ieHelpFile = 'File';
  103. ieDefaultTabSize = 'DefaultTabSize';
  104. ieDefaultIndentSize = 'DefaultIndentSize';
  105. ieDefaultEditorFlags='DefaultFlags';
  106. ieDefaultSaveExt = 'DefaultSaveExt';
  107. ieOpenExts = 'OpenExts';
  108. ieHighlightExts = 'Exts';
  109. ieTabsPattern = 'NeedsTabs';
  110. ieDoubleClickDelay = 'DoubleDelay';
  111. ieReverseButtons = 'ReverseButtons';
  112. ieAltClickAction = 'AltClickAction';
  113. ieCtrlClickAction = 'CtrlClickAction';
  114. ieFindFlags = 'FindFlags';
  115. ieToolName = 'Title';
  116. ieToolProgram = 'Program';
  117. ieToolParams = 'Params';
  118. ieToolHotKey = 'HotKey';
  119. ieBreakpointTyp = 'Type';
  120. ieBreakpointCount = 'Count';
  121. ieBreakpointState = 'State';
  122. ieBreakpointName = 'Name';
  123. ieBreakpointFile = 'FileName';
  124. ieBreakpointLine = 'LineNumber';
  125. ieBreakpointCond = 'Condition';
  126. ieWatchCount = 'Count';
  127. ieWatchName = 'Watch';
  128. ieSourceList = 'SourceList';
  129. { ieVideoMode = 'VideoMode';}
  130. ieAutoSave = 'AutoSaveFlags';
  131. ieMiscOptions = 'MiscOptions';
  132. ieDesktopLocation = 'DesktopLocation';
  133. ieDesktopFlags = 'DesktopFileFlags';
  134. ieCenterDebuggerRow= 'CenterCurrentLineWhileDebugging';
  135. ieShowReadme = 'ShowReadme';
  136. ieEditKeys = 'EditKeys';
  137. Procedure InitDirs;
  138. begin
  139. StartupDir:=CompleteDir(FExpand('.'));
  140. {$ifndef unix}
  141. IDEDir:=CompleteDir(DirOf(system.Paramstr(0)));
  142. {$ifdef WINDOWS}
  143. SystemIDEDir:=IDEDir;
  144. if GetEnv('APPDATA')<>'' then
  145. begin
  146. IDEdir:=CompleteDir(FExpand(GetEnv('APPDATA')+'/fp'));
  147. If Not ExistsDir(IDEdir) Then
  148. begin
  149. IDEDir:=SystemIDEDir;
  150. if Not ExistsDir(IDEDir) then
  151. begin
  152. if DirOf(system.paramstr(0))<>'' then
  153. IDEDir:=CompleteDir(DirOf(system.ParamStr(0)))
  154. else
  155. IDEDir:=StartupDir;
  156. end;
  157. end;
  158. end;
  159. {$endif WINDOWS}
  160. {$else}
  161. SystemIDEDir:=FExpand(DirOf(system.paramstr(0))+'../lib/fpc/'+version_string+'/ide/text');
  162. If Not ExistsDir(SystemIDEdir) Then
  163. begin
  164. SystemIDEDir:=FExpand(DirOf(system.paramstr(0))+'../lib64/fpc/'+version_string+'/ide/text');
  165. If Not ExistsDir(SystemIDEdir) Then
  166. SystemIDEDir:='/usr/lib/fpc/'+version_string+'/ide/text';
  167. end;
  168. IDEdir:=CompleteDir(FExpand('~/.fp'));
  169. If Not ExistsDir(IDEdir) Then
  170. begin
  171. IDEDir:=SystemIDEDir;
  172. if Not ExistsDir(IDEDir) then
  173. begin
  174. if DirOf(system.paramstr(0))<>'' then
  175. IDEDir:=CompleteDir(DirOf(system.ParamStr(0)))
  176. else
  177. IDEDir:=StartupDir;
  178. end;
  179. end;
  180. {$endif}
  181. end;
  182. procedure InitINIFile;
  183. var S: string;
  184. begin
  185. S:=LocateFile(INIFileName);
  186. if S<>'' then
  187. IniFileName:=S;
  188. IniFileName:=FExpand(IniFileName);
  189. end;
  190. procedure CheckINIFile;
  191. var IniDir,CurDir: DirStr;
  192. INI: PINIFile;
  193. const Btns : array[1..2] of string = (btn_config_copyexisting,btn_config_createnew);
  194. begin
  195. IniDir:=DirOf(IniFileName); CurDir:=GetCurDir;
  196. if CompareText(IniDir,CurDir)<>0 then
  197. if not ExistsFile(CurDir+DirInfoName) then
  198. if ConfirmBox(FormatStrStr(msg_doyouwanttocreatelocalconfigfile,IniDir),nil,false)=cmYes then
  199. begin
  200. if (not ExistsFile(IniFileName)) or
  201. (ChoiceBox(msg_configcopyexistingorcreatenew,nil,
  202. Btns,false)=cmUserBtn2) then
  203. begin
  204. { create new config here }
  205. IniFileName:=CurDir+IniName;
  206. SwitchesPath:=CurDir+SwitchesName;
  207. end
  208. else
  209. begin
  210. { copy config here }
  211. if CopyFile(IniFileName,CurDir+IniName)=false then
  212. ErrorBox(FormatStrStr(msg_errorwritingfile,CurDir+IniName),nil)
  213. else
  214. IniFileName:=CurDir+IniName;
  215. { copy also SwitchesPath to current dir, but only if
  216. 1) SwitchesPath exists
  217. 2) SwitchesPath is different from CurDir+SwitchesName }
  218. if ExistsFile(SwitchesPath) and
  219. not SameFileName(SwitchesPath,CurDir+SwitchesName) then
  220. begin
  221. if CopyFile(SwitchesPath,CurDir+SwitchesName)=false then
  222. ErrorBox(FormatStrStr(msg_errorwritingfile,CurDir+SwitchesName),nil)
  223. else
  224. SwitchesPath:=CurDir+SwitchesName;
  225. end;
  226. end;
  227. end
  228. else
  229. begin
  230. New(INI, Init(CurDir+DirInfoName));
  231. INI^.SetEntry(MainSectionName,'Comment','Do NOT delete this file!!!');
  232. if INI^.Update=false then
  233. ErrorBox(FormatStrStr(msg_errorwritingfile,INI^.GetFileName),nil);
  234. Dispose(INI, Done);
  235. end;
  236. end;
  237. function PaletteToStr(S: string): string;
  238. var C: string;
  239. I: integer;
  240. begin
  241. C:='';
  242. for I:=1 to length(S) do
  243. Insert('#$'+hexstr(ord(S[I]),2),C,Length(C)+1);
  244. PaletteToStr:=C;
  245. end;
  246. function strtopalette(S: string): string;
  247. {Converts a string in palette string format, i.e #$41#$42#$43 or
  248. #65#66#67 to an actual format.}
  249. var i: integer;
  250. p,x,len:byte;
  251. code:integer;
  252. begin
  253. i:=1;
  254. len:=0;
  255. while (i<=length(S)) and (s[i]='#') do
  256. begin
  257. s[i]:=#0;
  258. inc(i);
  259. p:=pos('#',s);
  260. if p=0 then
  261. p:=length(s)
  262. else
  263. p:=p-i;
  264. val(copy(s,i,p),x,code); {Val supports hexadecimal.}
  265. if code<>0 then
  266. break;
  267. inc(len);
  268. strtopalette[len]:=char(X);
  269. inc(i,p);
  270. end;
  271. strtopalette[0]:=char(len);
  272. end;
  273. {$ifndef NODEBUG}
  274. procedure WriteOneWatchEntry(I : Longint;INIFile : PINIFile);
  275. var
  276. PW : PWatch;
  277. S : String;
  278. begin
  279. Str(I,S);
  280. PW:=WatchesCollection^.At(I);
  281. With PW^ do
  282. begin
  283. INIFile^.SetEntry(secWatches,ieWatchName+S,GetStr(expr));
  284. end;
  285. end;
  286. procedure WriteOneBreakPointEntry(I : longint;INIFile : PINIFile);
  287. var PB : PBreakpoint;
  288. S : String;
  289. begin
  290. Str(I,S);
  291. PB:=BreakpointsCollection^.At(I);
  292. If assigned(PB) then
  293. With PB^ do
  294. Begin
  295. INIFile^.SetEntry(secBreakpoint,ieBreakpointTyp+S,BreakpointTypeStr[typ]);
  296. INIFile^.SetEntry(secBreakpoint,ieBreakpointState+S,BreakpointStateStr[state]);
  297. if typ=bt_file_line then
  298. begin
  299. INIFile^.SetEntry(secBreakpoint,ieBreakpointFile+S,FileName^);
  300. INIFile^.SetIntEntry(secBreakpoint,ieBreakpointLine+S,Line);
  301. end
  302. else
  303. INIFile^.SetEntry(secBreakpoint,ieBreakpointName+S,Name^);
  304. if assigned(Conditions) then
  305. INIFile^.SetEntry(secBreakpoint,ieBreakpointCond+S,Conditions^)
  306. else
  307. INIFile^.SetEntry(secBreakpoint,ieBreakpointCond+S,'');
  308. end;
  309. end;
  310. procedure ReadOneWatchEntry(I : Longint;INIFile : PINIFile);
  311. var
  312. PW : PWatch;
  313. S : String;
  314. begin
  315. Str(I,S);
  316. PW:=new(PWatch,Init(INIFile^.GetEntry(secWatches,ieWatchName+S,'')));
  317. WatchesCollection^.Insert(PW);
  318. end;
  319. procedure ReadOneBreakPointEntry(i : longint;INIFile : PINIFile);
  320. var PB : PBreakpoint;
  321. S,S2,SC : string;
  322. Line : longint;
  323. typ : BreakpointType;
  324. state : BreakpointState;
  325. begin
  326. Str(I,S2);
  327. typ:=bt_invalid;
  328. S:=INIFile^.GetEntry(secBreakpoint,ieBreakpointTyp+S2,BreakpointTypeStr[typ]);
  329. for typ:=low(BreakpointType) to high(BreakpointType) do
  330. If pos(BreakpointTypeStr[typ],S)>0 then break;
  331. state:=bs_deleted;
  332. S:=INIFile^.GetEntry(secBreakpoint,ieBreakpointState+S2,BreakpointStateStr[state]);
  333. for state:=low(BreakpointState) to high(BreakpointState) do
  334. If pos(BreakpointStateStr[state],S)>0 then break;
  335. case typ of
  336. bt_invalid :;
  337. bt_file_line :
  338. begin
  339. S:=INIFile^.GetEntry(secBreakpoint,ieBreakpointFile+S2,'');
  340. Line:=INIFile^.GetIntEntry(secBreakpoint,ieBreakpointLine+S2,0);
  341. end;
  342. else
  343. begin
  344. S:=INIFile^.GetEntry(secBreakpoint,ieBreakpointName+S2,'');
  345. end;
  346. end;
  347. SC:=INIFile^.GetEntry(secBreakpoint,ieBreakpointCond+S2,'');
  348. if (typ=bt_function) and (S<>'') then
  349. new(PB,init_function(S))
  350. else if (typ=bt_file_line) and (S<>'') then
  351. new(PB,init_file_line(S,Line))
  352. else
  353. new(PB,init_type(typ,S));
  354. If assigned(PB) then
  355. begin
  356. PB^.state:=state;
  357. If SC<>'' then
  358. PB^.conditions:=NewStr(SC);
  359. BreakpointsCollection^.Insert(PB);
  360. end;
  361. end;
  362. {$endif NODEBUG}
  363. function ReadINIFile: boolean;
  364. var INIFile: PINIFile;
  365. S,PS,S1,S2,S3: string;
  366. I,P: integer;
  367. BreakPointCount,WatchesCount:longint;
  368. OK: boolean;
  369. ts : TSwitchMode;
  370. W: word;
  371. crcv:cardinal;
  372. begin
  373. OK:=ExistsFile(IniFileName);
  374. if OK then
  375. begin
  376. New(INIFile, Init(IniFileName));
  377. { Files }
  378. OpenExts:=INIFile^.GetEntry(secFiles,ieOpenExts,OpenExts);
  379. RecentFileCount:=High(RecentFiles);
  380. for I:=Low(RecentFiles) to High(RecentFiles) do
  381. begin
  382. S:=INIFile^.GetEntry(secFiles,ieRecentFile+IntToStr(I),'');
  383. if (S='') and (RecentFileCount>I-1) then RecentFileCount:=I-1;
  384. with RecentFiles[I] do
  385. begin
  386. P:=Pos(',',S); if P=0 then P:=length(S)+1;
  387. FileName:=copy(S,1,P-1); Delete(S,1,P);
  388. P:=Pos(',',S); if P=0 then P:=length(S)+1;
  389. LastPos.X:=Max(0,StrToInt(copy(S,1,P-1))); Delete(S,1,P);
  390. P:=Pos(',',S); if P=0 then P:=length(S)+1;
  391. LastPos.Y:=Max(0,StrToInt(copy(S,1,P-1))); Delete(S,1,P);
  392. end;
  393. end;
  394. { Run }
  395. SetRunDir(INIFile^.GetEntry(secRun,ieRunDir,GetRunDir));
  396. SetRunParameters(INIFile^.GetEntry(secRun,ieRunParameters,GetRunParameters));
  397. SetPrinterDevice(INIFile^.GetEntry(secFiles,iePrinterDevice,GetPrinterDevice));
  398. { First read the primary file, which can also set the parameters which can
  399. be overruled with the parameter loading }
  400. SetPrimaryFile(INIFile^.GetEntry(secCompile,iePrimaryFile,PrimaryFile));
  401. {$ifndef GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE}
  402. DebuggeeTTY := INIFile^.GetEntry(secRun,ieDebuggeeRedir,DebuggeeTTY);
  403. {$endif not GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE}
  404. {$ifdef SUPPORT_REMOTE}
  405. RemoteMachine :=INIFile^.GetEntry(secRun,ieRemoteMachine,RemoteMachine);
  406. RemotePort :=INIFile^.GetEntry(secRun,ieRemotePort,RemotePort);
  407. RemotePuttySession :=INIFile^.GetEntry(secRun,ieRemotePuttySession,RemotePuttySession);
  408. RemoteSendCommand :=INIFile^.GetEntry(secRun,ieRemoteSendCommand,RemoteSendCommand);
  409. RemoteExecCommand :=INIFile^.GetEntry(secRun,ieRemoteExecCommand,RemoteExecCommand);
  410. RemoteSshExecCommand :=INIFile^.GetEntry(secRun,ieRemoteSshExecCommand,RemoteSshExecCommand);
  411. RemoteConfig :=INIFile^.GetEntry(secRun,ieRemoteConfig,RemoteConfig);
  412. RemoteIdent :=INIFile^.GetEntry(secRun,ieRemoteIdent,RemoteIdent);
  413. RemoteDir :=INIFile^.GetEntry(secRun,ieRemoteDirectory,RemoteDir);
  414. RemoteGDBServer :=INIFile^.GetEntry(secRun,ieRemoteGDBServer,RemoteGDBServer);
  415. RemoteCopy :=INIFile^.GetEntry(secRun,ieRemoteCopy,RemoteCopy);
  416. RemoteShell :=INIFile^.GetEntry(secRun,ieRemoteShell,RemoteShell);
  417. {$endif SUPPORT_REMOTE}
  418. { Compile }
  419. S:=INIFile^.GetEntry(secCompile,ieCompileMode,'');
  420. for ts:=low(TSwitchMode) to high(TSwitchMode) do
  421. begin
  422. if SwitchesModeStr[ts]=S then
  423. SwitchesMode:=ts;
  424. end;
  425. { Help }
  426. { Reading single string with help-file names }
  427. S:=INIFile^.GetEntry(secHelp,ieHelpFiles,'');
  428. repeat
  429. P:=Pos(';',S); if P=0 then P:=length(S)+1;
  430. PS:=copy(S,1,P-1);
  431. if PS<>'' then HelpFiles^.Insert(NewStr(PS));
  432. Delete(S,1,P);
  433. until S='';
  434. { Reading separate strings with help-file names }
  435. I:=1;
  436. repeat
  437. S:=INIFile^.GetEntry(secHelp,ieHelpFile + IntToStr(I),'');
  438. inc(I);
  439. if S<>'' then HelpFiles^.Insert(NewStr(S));
  440. until S='';
  441. { Editor }
  442. DefaultTabSize:=INIFile^.GetIntEntry(secEditor,ieDefaultTabSize,DefaultTabSize);
  443. DefaultIndentSize:=INIFile^.GetIntEntry(secEditor,ieDefaultIndentSize,DefaultIndentSize);
  444. DefaultCodeEditorFlags:=INIFile^.GetIntEntry(secEditor,ieDefaultEditorFlags,DefaultCodeEditorFlags);
  445. DefaultSaveExt:=INIFile^.GetEntry(secEditor,ieDefaultSaveExt,DefaultSaveExt);
  446. { Highlight }
  447. HighlightExts:=INIFile^.GetEntry(secHighlight,ieHighlightExts,HighlightExts);
  448. TabsPattern:=INIFile^.GetEntry(secHighlight,ieTabsPattern,TabsPattern);
  449. { SourcePath }
  450. SourceDirs:=INIFile^.GetEntry(secSourcePath,ieSourceList,SourceDirs);
  451. { Mouse }
  452. DoubleDelay:=INIFile^.GetIntEntry(secMouse,ieDoubleClickDelay,DoubleDelay);
  453. MouseReverse:=boolean(INIFile^.GetIntEntry(secMouse,ieReverseButtons,byte(MouseReverse)));
  454. AltMouseAction:=INIFile^.GetIntEntry(secMouse,ieAltClickAction,AltMouseAction);
  455. CtrlMouseAction:=INIFile^.GetIntEntry(secMouse,ieCtrlClickAction,CtrlMouseAction);
  456. {Keyboard}
  457. S:=upcase(INIFile^.GetEntry(secKeyboard,ieEditKeys,''));
  458. crcv := UpdateCrc32(0,s[1],Length(s)) ;
  459. case crcv of
  460. $795B3767 : {crc32 for 'MICROSOFT'}
  461. EditKeys:=ekm_microsoft;
  462. $4DF4784C
  463. : {crc32 for 'BORLAND'}
  464. EditKeys:=ekm_borland;
  465. else
  466. EditKeys:=ekm_default;
  467. end;
  468. { Search }
  469. FindFlags:=INIFile^.GetIntEntry(secSearch,ieFindFlags,FindFlags);
  470. { Breakpoints }
  471. {$ifndef NODEBUG}
  472. BreakpointCount:=INIFile^.GetIntEntry(secBreakpoint,ieBreakpointCount,0);
  473. for i:=1 to BreakpointCount do
  474. ReadOneBreakPointEntry(i-1,INIFile);
  475. WatchesCount:=INIFile^.GetIntEntry(secWatches,ieWatchCount,0);
  476. for i:=1 to WatchesCount do
  477. ReadOneWatchEntry(i-1,INIFile);
  478. {$endif}
  479. { Tools }
  480. for I:=1 to MaxToolCount do
  481. begin
  482. S:=IntToStr(I);
  483. S1:=INIFile^.GetEntry(secTools,ieToolName+S,'');
  484. if S1='' then Break; { !!! }
  485. S2:=INIFile^.GetEntry(secTools,ieToolProgram+S,'');
  486. S3:=INIFile^.GetEntry(secTools,ieToolParams+S,'');
  487. W:=Max(0,Min(65535,INIFile^.GetIntEntry(secTools,ieToolHotKey+S,0)));
  488. AddTool(S1,S2,S3,W);
  489. end;
  490. { Colors }
  491. S:=AppPalette;
  492. PS:=StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_1_40',PaletteToStr(copy(S,1,40))));
  493. PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_41_80',PaletteToStr(copy(S,41,40))));
  494. PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_81_120',PaletteToStr(copy(S,81,40))));
  495. PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_121_160',PaletteToStr(copy(S,121,40))));
  496. PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_161_200',PaletteToStr(copy(S,161,40))));
  497. PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_201_240',PaletteToStr(copy(S,201,40))));
  498. if length(PS)<length(CIDEAppColor) then
  499. PS:=PS+copy(CIDEAppColor,length(PS)+1,255);
  500. AppPalette:=PS;
  501. (* { Open files }
  502. for I:=INIFile^.GetIntEntry(secFiles,ieOpenFileCount,0) downto 1 do
  503. begin
  504. S:=INIFile^.GetEntry(secFiles,ieOpenFile+IntToStr(I),'');
  505. if (S='') then
  506. break;
  507. P:=Pos(',',S); if P=0 then P:=length(S)+1;
  508. S1:=copy(S,1,P-1);
  509. Delete(S,1,P);
  510. P:=Pos(',',S);
  511. if P=0 then P:=length(S)+1;
  512. X:=Max(0,StrToInt(copy(S,1,P-1)));
  513. Delete(S,1,P);
  514. P:=Pos(',',S);
  515. if P=0 then P:=length(S)+1;
  516. Y:=Max(0,StrToInt(copy(S,1,P-1)));
  517. Delete(S,1,P);
  518. P:=Pos(',',S);
  519. if P=0 then P:=length(S)+1;
  520. R.A.X:=Max(0,StrToInt(copy(S,1,P-1)));
  521. Delete(S,1,P);
  522. P:=Pos(',',S);
  523. if P=0 then P:=length(S)+1;
  524. R.A.Y:=Max(0,StrToInt(copy(S,1,P-1)));
  525. Delete(S,1,P);
  526. P:=Pos(',',S);
  527. if P=0 then P:=length(S)+1;
  528. R.B.X:=Max(0,StrToInt(copy(S,1,P-1)));
  529. Delete(S,1,P);
  530. P:=Pos(',',S);
  531. if P=0 then P:=length(S)+1;
  532. R.B.Y:=Max(0,StrToInt(copy(S,1,P-1)));
  533. if (R.A.X<R.B.X) and (R.A.Y<R.B.Y) then
  534. TryToOpenFile(@R,S1,X,Y,false)
  535. else
  536. TryToOpenFile(nil,S1,X,Y,false);
  537. { remove it because otherwise we allways keep old files }
  538. INIFile^.DeleteEntry(secFiles,ieOpenFile+IntToStr(I));
  539. end;
  540. *)
  541. { Desktop }
  542. DesktopFileFlags:=INIFile^.GetIntEntry(secPreferences,ieDesktopFlags,DesktopFileFlags);
  543. { Debugger }
  544. IniCenterDebuggerRow:=tcentre(INIFile^.GetIntEntry(secPreferences,ieCenterDebuggerRow,1));
  545. { Preferences }
  546. AutoSaveOptions:=INIFile^.GetIntEntry(secPreferences,ieAutoSave,AutoSaveOptions);
  547. MiscOptions:=INIFile^.GetIntEntry(secPreferences,ieMiscOptions,MiscOptions);
  548. DesktopLocation:=INIFile^.GetIntEntry(secPreferences,ieDesktopLocation,DesktopLocation);
  549. { Misc }
  550. ShowReadme:=INIFile^.GetIntEntry(secMisc,ieShowReadme,{integer(ShowReadme)}1)<>0;
  551. Dispose(INIFile, Done);
  552. end;
  553. ReadINIFile:=OK;
  554. end;
  555. function WriteINIFile (FromSaveAs : boolean): boolean;
  556. var INIFile: PINIFile;
  557. S: string;
  558. S1,S2,S3: string;
  559. W: word;
  560. HelpFileCount, BreakPointCount,WatchesCount:longint;
  561. I(*,OpenFileCount*): integer;
  562. OK: boolean;
  563. begin
  564. {$ifdef Unix}
  565. if not FromSaveAs and (DirOf(IniFileName)=DirOf(SystemIDEDir)) then
  566. begin
  567. IniFileName:=FExpand('~/.fp/'+IniName);
  568. If not ExistsDir(DirOf(IniFileName)) then
  569. MkDir(FExpand('~/.fp'));
  570. end;
  571. {$endif Unix}
  572. {$ifdef WINDOWS}
  573. if not FromSaveAs and (DirOf(IniFileName)=DirOf(SystemIDEDir)) and
  574. (GetEnv('APPDATA')<>'') then
  575. begin
  576. IniFileName:=FExpand(GetEnv('APPDATA')+'/fp/'+IniName);
  577. If not ExistsDir(DirOf(IniFileName)) then
  578. MkDir(FExpand(GetEnv('APPDATA')+'/fp'));
  579. end;
  580. {$endif WINDOWS}
  581. New(INIFile, Init(IniFileName));
  582. { Files }
  583. { avoid keeping old files }
  584. INIFile^.DeleteSection(secFiles);
  585. INIFile^.SetEntry(secFiles,ieOpenExts,EscapeIniText(OpenExts));
  586. for I:=1 to High(RecentFiles) do
  587. begin
  588. if I<=RecentFileCount then
  589. with RecentFiles[I] do S:=FileName+','+IntToStr(LastPos.X)+','+IntToStr(LastPos.Y)
  590. else
  591. S:='';
  592. INIFile^.SetEntry(secFiles,ieRecentFile+IntToStr(I),S);
  593. end;
  594. (*
  595. PW:=FirstEditorWindow;
  596. PPW:=PW;
  597. I:=1;
  598. while assigned(PW) do
  599. begin
  600. If PW^.HelpCtx=hcSourceWindow then
  601. begin
  602. With PW^.editor^ do
  603. S:=FileName+','+IntToStr(CurPos.X)+','+IntToStr(CurPos.Y);
  604. PW^.GetBounds(R);
  605. S:=S+','+IntToStr(R.A.X)+','+IntToStr(R.A.Y)+','+
  606. IntToStr(R.B.X)+','+IntToStr(R.B.Y);
  607. INIFile^.SetEntry(secFiles,ieOpenFile+IntToStr(I),S);
  608. Inc(I);
  609. OpenFileCount:=I-1;
  610. end;
  611. PW:=PSourceWindow(PW^.next);
  612. While assigned(PW) and (PW<>PPW) and (PW^.HelpCtx<>hcSourceWindow) do
  613. PW:=PSourceWindow(PW^.next);
  614. If PW=PPW then
  615. break;
  616. end;
  617. INIFile^.SetIntEntry(secFiles,ieOpenFileCount,OpenFileCount);
  618. *)
  619. { Run }
  620. INIFile^.SetEntry(secRun,ieRunDir,GetRunDir);
  621. INIFile^.SetEntry(secRun,ieRunParameters,GetRunParameters);
  622. INIFile^.SetEntry(secFiles,iePrinterDevice,GetPrinterDevice);
  623. {$ifndef GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE}
  624. { If DebuggeeTTY<>'' then }
  625. INIFile^.SetEntry(secRun,ieDebuggeeRedir,DebuggeeTTY);
  626. {$endif not GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE}
  627. {$ifdef SUPPORT_REMOTE}
  628. INIFile^.SetEntry(secRun,ieRemoteMachine,RemoteMachine);
  629. INIFile^.SetEntry(secRun,ieRemotePort,RemotePort);
  630. INIFile^.SetEntry(secRun,ieRemotePuttySession,RemotePuttySession);
  631. INIFile^.SetEntry(secRun,ieRemoteSendCommand,RemoteSendCommand);
  632. INIFile^.SetEntry(secRun,ieRemoteConfig,RemoteConfig);
  633. INIFile^.SetEntry(secRun,ieRemoteIdent,RemoteIdent);
  634. INIFile^.SetEntry(secRun,ieRemoteDirectory,RemoteDir);
  635. INIFile^.SetEntry(secRun,ieRemoteExecCommand,RemoteExecCommand);
  636. INIFile^.SetEntry(secRun,ieRemoteSshExecCommand,RemoteSshExecCommand);
  637. INIFile^.SetEntry(secRun,ieRemoteConfig,RemoteConfig);
  638. INIFile^.SetEntry(secRun,ieRemoteIdent,RemoteIdent);
  639. INIFile^.SetEntry(secRun,ieRemoteDirectory,RemoteDir);
  640. INIFile^.SetEntry(secRun,ieRemoteGDBServer,RemoteGDBServer);
  641. INIFile^.SetEntry(secRun,ieRemoteCopy,RemoteCopy);
  642. INIFile^.SetEntry(secRun,ieRemoteShell,RemoteShell);
  643. {$endif SUPPORT_REMOTE}
  644. { Compile }
  645. INIFile^.SetEntry(secCompile,iePrimaryFile,PrimaryFile);
  646. INIFile^.SetEntry(secCompile,ieCompileMode,SwitchesModeStr[SwitchesMode]);
  647. { Deleting single string with help-files list }
  648. INIFile^.DeleteEntry(secHelp, ieHelpFiles);
  649. { Saving help-files as separate strings }
  650. { Will it produce compatibility problems? }
  651. HelpFileCount:=HelpFiles^.Count;
  652. for I := 1 to HelpFileCount do
  653. begin
  654. S:=HelpFiles^.At(I-1)^;
  655. INIFile^.SetEntry(secHelp, ieHelpFile + IntToStr(I), EscapeIniText(S));
  656. end;
  657. { Editor }
  658. INIFile^.SetIntEntry(secEditor,ieDefaultTabSize,DefaultTabSize);
  659. INIFile^.SetIntEntry(secEditor,ieDefaultIndentSize,DefaultIndentSize);
  660. INIFile^.SetIntEntry(secEditor,ieDefaultEditorFlags,DefaultCodeEditorFlags);
  661. INIFile^.SetEntry(secEditor,ieDefaultSaveExt,DefaultSaveExt);
  662. { Highlight }
  663. INIFile^.SetEntry(secHighlight,ieHighlightExts,EscapeIniText(HighlightExts));
  664. INIFile^.SetEntry(secHighlight,ieTabsPattern,EscapeIniText(TabsPattern));
  665. { SourcePath }
  666. INIFile^.SetEntry(secSourcePath,ieSourceList,EscapeIniText(SourceDirs));
  667. { Mouse }
  668. INIFile^.SetIntEntry(secMouse,ieDoubleClickDelay,DoubleDelay);
  669. INIFile^.SetIntEntry(secMouse,ieReverseButtons,byte(MouseReverse));
  670. INIFile^.SetIntEntry(secMouse,ieAltClickAction,AltMouseAction);
  671. INIFile^.SetIntEntry(secMouse,ieCtrlClickAction,CtrlMouseAction);
  672. { Keyboard }
  673. if EditKeys=ekm_microsoft then
  674. INIFile^.SetEntry(secKeyboard,ieEditKeys,'microsoft')
  675. else
  676. INIFile^.SetEntry(secKeyboard,ieEditKeys,'borland');
  677. { Search }
  678. INIFile^.SetIntEntry(secSearch,ieFindFlags,FindFlags);
  679. { Breakpoints }
  680. {$ifndef NODEBUG}
  681. BreakPointCount:=BreakpointsCollection^.Count;
  682. INIFile^.SetIntEntry(secBreakpoint,ieBreakpointCount,BreakpointCount);
  683. for i:=1 to BreakpointCount do
  684. WriteOneBreakPointEntry(I-1,INIFile);
  685. WatchesCount:=WatchesCollection^.Count;
  686. INIFile^.SetIntEntry(secWatches,ieWatchCount,WatchesCount);
  687. for i:=1 to WatchesCount do
  688. WriteOneWatchEntry(I-1,INIFile);
  689. {$endif}
  690. { Tools }
  691. INIFile^.DeleteSection(secTools);
  692. for I:=1 to GetToolCount do
  693. begin
  694. S:=IntToStr(I);
  695. GetToolParams(I-1,S1,S2,S3,W);
  696. if S1<>'' then S1:=EscapeIniText(S1);
  697. if S2<>'' then S2:=EscapeIniText(S2);
  698. if S3<>'' then S3:=EscapeIniText(S3);
  699. INIFile^.SetEntry(secTools,ieToolName+S,S1);
  700. INIFile^.SetEntry(secTools,ieToolProgram+S,S2);
  701. INIFile^.SetEntry(secTools,ieToolParams+S,S3);
  702. INIFile^.SetIntEntry(secTools,ieToolHotKey+S,W);
  703. end;
  704. { Colors }
  705. if AppPalette<>CIDEAppColor then
  706. begin
  707. { this has a bug. if a different palette has been read on startup, and
  708. then changed back to match the default, this will not update it in the
  709. ini file, eg. the original (non-default) will be left unmodified... }
  710. S:=AppPalette;
  711. INIFile^.SetEntry(secColors,iePalette+'_1_40',PaletteToStr(copy(S,1,40)));
  712. INIFile^.SetEntry(secColors,iePalette+'_41_80',PaletteToStr(copy(S,41,40)));
  713. INIFile^.SetEntry(secColors,iePalette+'_81_120',PaletteToStr(copy(S,81,40)));
  714. INIFile^.SetEntry(secColors,iePalette+'_121_160',PaletteToStr(copy(S,121,40)));
  715. INIFile^.SetEntry(secColors,iePalette+'_161_200',PaletteToStr(copy(S,161,40)));
  716. INIFile^.SetEntry(secColors,iePalette+'_201_240',PaletteToStr(copy(S,201,40)));
  717. end;
  718. { Desktop }
  719. INIFile^.SetIntEntry(secPreferences,ieDesktopFlags,DesktopFileFlags);
  720. INIFile^.SetIntEntry(secPreferences,ieCenterDebuggerRow,byte(IniCenterDebuggerRow));
  721. { Preferences }
  722. INIFile^.SetIntEntry(secPreferences,ieAutoSave,AutoSaveOptions);
  723. INIFile^.SetIntEntry(secPreferences,ieMiscOptions,MiscOptions);
  724. INIFile^.SetIntEntry(secPreferences,ieDesktopLocation,DesktopLocation);
  725. { Misc }
  726. INIFile^.SetIntEntry(secMisc,ieShowReadme,integer(ShowReadme));
  727. OK:=INIFile^.Update;
  728. Dispose(INIFile, Done);
  729. WriteINIFile:=OK;
  730. end;
  731. end.