fpini.pas 27 KB

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