fpini.pas 25 KB

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