fpini.pas 26 KB

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