fpini.pas 23 KB

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