fpini.pas 24 KB

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