fpini.pas 22 KB

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