2
0

fpini.pas 27 KB

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