mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 21:09:38 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			821 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			821 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| {
 | |
|     $Id$
 | |
|     This file is part of the Free Pascal Integrated Development Environment
 | |
|     Copyright (c) 1998 by Berczi Gabor
 | |
| 
 | |
|     Write/Read Options to INI File
 | |
| 
 | |
|     See the file COPYING.FPC, included in this distribution,
 | |
|     for details about the copyright.
 | |
| 
 | |
|     This program is distributed in the hope that it will be useful,
 | |
|     but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | |
| 
 | |
|  **********************************************************************}
 | |
| unit FPIni;
 | |
| interface
 | |
| 
 | |
| uses
 | |
|   FPUtils;
 | |
| 
 | |
| procedure InitDirs;
 | |
| procedure InitINIFile;
 | |
| procedure CheckINIFile;
 | |
| function  ReadINIFile: boolean;
 | |
| function  WriteINIFile(FromSaveAs : boolean) : boolean;
 | |
| 
 | |
| 
 | |
| implementation
 | |
| 
 | |
| uses
 | |
|   Dos,Objects,Drivers,
 | |
| {$ifdef FVISION}
 | |
|   FVConsts,
 | |
| {$else}
 | |
|   Commands,
 | |
| {$endif}
 | |
|   Version,
 | |
| {$ifdef USE_EXTERNAL_COMPILER}
 | |
|    fpintf, { superseeds version_string of version unit }
 | |
| {$endif USE_EXTERNAL_COMPILER}
 | |
|   WConsts,WUtils,WINI,WViews,{$ifndef EDITORS}WEditor,WCEdit{$else}Editors{$endif},
 | |
|   {$ifndef NODEBUG}FPDebug,{$endif}FPConst,FPVars,
 | |
|   FPIntf,FPTools,FPSwitch,FPString;
 | |
| 
 | |
| const
 | |
|   { INI file sections }
 | |
|   secFiles       = 'Files';
 | |
|   secRun         = 'Run';
 | |
|   secCompile     = 'Compile';
 | |
|   secColors      = 'Colors';
 | |
|   secHelp        = 'Help';
 | |
|   secEditor      = 'Editor';
 | |
|   secBreakpoint  = 'Breakpoints';
 | |
|   secWatches     = 'Watches';
 | |
|   secHighlight   = 'Highlight';
 | |
|   secMouse       = 'Mouse';
 | |
|   secSearch      = 'Search';
 | |
|   secTools       = 'Tools';
 | |
|   secSourcePath  = 'SourcePath';
 | |
|   secPreferences = 'Preferences';
 | |
|   secMisc        = 'Misc';
 | |
| 
 | |
|   { INI file tags }
 | |
|   ieRecentFile       = 'RecentFile';
 | |
| (*  ieOpenFile         = 'OpenFile';
 | |
|   ieOpenFileCount    = 'OpenFileCount'; *)
 | |
|   ieRunParameters    = 'Parameters';
 | |
|   ieDebuggeeRedir    = 'DebugRedirection';
 | |
|   iePrimaryFile      = 'PrimaryFile';
 | |
|   ieCompileMode      = 'CompileMode';
 | |
|   iePalette          = 'Palette';
 | |
|   ieHelpFiles        = 'Files';
 | |
|   ieDefaultTabSize   = 'DefaultTabSize';
 | |
|   ieDefaultIndentSize = 'DefaultIndentSize';
 | |
|   ieDefaultEditorFlags='DefaultFlags';
 | |
|   ieDefaultSaveExt   = 'DefaultSaveExt';
 | |
|   ieOpenExts         = 'OpenExts';
 | |
|   ieHighlightExts    = 'Exts';
 | |
|   ieTabsPattern      = 'NeedsTabs';
 | |
|   ieDoubleClickDelay = 'DoubleDelay';
 | |
|   ieReverseButtons   = 'ReverseButtons';
 | |
|   ieAltClickAction   = 'AltClickAction';
 | |
|   ieCtrlClickAction  = 'CtrlClickAction';
 | |
|   ieFindFlags        = 'FindFlags';
 | |
|   ieToolName         = 'Title';
 | |
|   ieToolProgram      = 'Program';
 | |
|   ieToolParams       = 'Params';
 | |
|   ieToolHotKey       = 'HotKey';
 | |
|   ieBreakpointTyp    = 'Type';
 | |
|   ieBreakpointCount  = 'Count';
 | |
|   ieBreakpointState  = 'State';
 | |
|   ieBreakpointName   = 'Name';
 | |
|   ieBreakpointFile   = 'FileName';
 | |
|   ieBreakpointLine   = 'LineNumber';
 | |
|   ieBreakpointCond   = 'Condition';
 | |
|   ieWatchCount       = 'Count';
 | |
|   ieWatchName        = 'Watch';
 | |
|   ieSourceList       = 'SourceList';
 | |
| {  ieVideoMode        = 'VideoMode';}
 | |
|   ieAutoSave         = 'AutoSaveFlags';
 | |
|   ieMiscOptions      = 'MiscOptions';
 | |
|   ieDesktopLocation  = 'DesktopLocation';
 | |
|   ieDesktopFlags     = 'DesktopFileFlags';
 | |
|   ieCenterDebuggerRow= 'CenterCurrentLineWhileDebugging';
 | |
|   ieShowReadme       = 'ShowReadme';
 | |
| 
 | |
| 
 | |
| Procedure InitDirs;
 | |
| begin
 | |
|   StartupDir:=CompleteDir(FExpand('.'));
 | |
| {$ifndef unix}
 | |
|   IDEDir:=CompleteDir(DirOf(system.Paramstr(0)));
 | |
| {$else}
 | |
|   SystemIDEDir:='/usr/lib/fpc/'+version_string+'/ide/text';
 | |
|   IDEdir:=CompleteDir(FExpand('~/.fp'));
 | |
|   If Not ExistsDir(IDEdir) Then
 | |
|     begin
 | |
|       IDEDir:=SystemIDEDir;
 | |
|       if Not ExistsDir(IDEDir) then
 | |
|         begin
 | |
|           if DirOf(system.paramstr(0))<>'' then
 | |
|             IDEDir:=CompleteDir(DirOf(system.ParamStr(0)))
 | |
|           else
 | |
|             IDEDir:=StartupDir;
 | |
|         end;
 | |
|     end;
 | |
| {$endif}
 | |
| end;
 | |
| 
 | |
| procedure InitINIFile;
 | |
| var S: string;
 | |
| begin
 | |
|   S:=LocateFile(INIFileName);
 | |
|   if S<>'' then
 | |
|     IniFileName:=S;
 | |
|   IniFileName:=FExpand(IniFileName);
 | |
| end;
 | |
| 
 | |
| procedure CheckINIFile;
 | |
| var IniDir,CurDir: DirStr;
 | |
|     INI: PINIFile;
 | |
| const Btns : array[1..2] of longstring = (btn_config_copyexisting,btn_config_createnew);
 | |
| begin
 | |
|   IniDir:=DirOf(IniFileName); CurDir:=GetCurDir;
 | |
|   if CompareText(IniDir,CurDir)<>0 then
 | |
|    if not ExistsFile(CurDir+DirInfoName) then
 | |
|      if ConfirmBox(FormatStrStr(msg_doyouwanttocreatelocalconfigfile,IniDir),nil,false)=cmYes then
 | |
|        begin
 | |
|          if (not ExistsFile(IniFileName)) or
 | |
|             (ChoiceBox(msg_configcopyexistingorcreatenew,nil,
 | |
|               Btns,false)=cmUserBtn2) then
 | |
|            begin
 | |
|              { create new config here }
 | |
|              IniFileName:=CurDir+IniName;
 | |
|              SwitchesPath:=CurDir+SwitchesName;
 | |
|            end
 | |
|          else
 | |
|            begin
 | |
|              { copy config here }
 | |
|              if CopyFile(IniFileName,CurDir+IniName)=false then
 | |
|                ErrorBox(FormatStrStr(msg_errorwritingfile,CurDir+IniName),nil)
 | |
|              else
 | |
|                IniFileName:=CurDir+IniName;
 | |
|              if CopyFile(SwitchesPath,CurDir+SwitchesName)=false then
 | |
|                ErrorBox(FormatStrStr(msg_errorwritingfile,CurDir+SwitchesName),nil)
 | |
|              else
 | |
|                SwitchesPath:=CurDir+SwitchesName;
 | |
|            end;
 | |
|        end
 | |
|      else
 | |
|        begin
 | |
|          New(INI, Init(CurDir+DirInfoName));
 | |
|          INI^.SetEntry(MainSectionName,'Comment','Do NOT delete this file!!!');
 | |
|          if INI^.Update=false then
 | |
|            ErrorBox(FormatStrStr(msg_errorwritingfile,INI^.GetFileName),nil);
 | |
|          Dispose(INI, Done);
 | |
|        end;
 | |
| end;
 | |
| 
 | |
| function PaletteToStr(S: string): string;
 | |
| var C: string;
 | |
|     I: integer;
 | |
| begin
 | |
|   C:='';
 | |
|   for I:=1 to length(S) do
 | |
|     begin
 | |
|       Insert('#$'+IntToHex(ord(S[I]),2),C,Length(C)+1);
 | |
|     end;
 | |
|   PaletteToStr:=C;
 | |
| end;
 | |
| 
 | |
| function StrToPalette(S: string): string;
 | |
| var I,P,X: integer;
 | |
|     C: string;
 | |
|     Hex: boolean;
 | |
|     OK: boolean;
 | |
| begin
 | |
|   C:=''; I:=1;
 | |
|   OK:=S<>'';
 | |
|   while OK and (I<=length(S)) and (S[I]='#') do
 | |
|   begin
 | |
|     Inc(I); Hex:=false;
 | |
|     if S[I]='$' then begin Inc(I); Hex:=true; end;
 | |
|     P:=Pos('#',copy(S,I,High(S))); if P>0 then P:=I+P-1 else P:=length(S)+1;
 | |
|     if Hex=false then
 | |
|       begin
 | |
|         X:=StrToInt(copy(S,I,P-I));
 | |
|         OK:=(LastStrToIntResult=0) and (0<=X) and (X<=High(S));
 | |
|       end
 | |
|     else
 | |
|       begin
 | |
|         X:=HexToInt(copy(S,I,P-I));
 | |
|         OK:=(LastHexToIntResult=0) and (0<=X) and (X<=255);
 | |
|       end;
 | |
|     if OK then C:=C+chr(X);
 | |
|     Inc(I,P-I);
 | |
|   end;
 | |
|   StrToPalette:=C;
 | |
| end;
 | |
| 
 | |
| {$ifndef NODEBUG}
 | |
| procedure WriteOneWatchEntry(I : Longint;INIFile : PINIFile);
 | |
| var
 | |
|   PW : PWatch;
 | |
|   S  : String;
 | |
| begin
 | |
|   Str(I,S);
 | |
|   PW:=WatchesCollection^.At(I);
 | |
|   With PW^ do
 | |
|     begin
 | |
|       INIFile^.SetEntry(secWatches,ieWatchName+S,GetStr(expr));
 | |
|     end;
 | |
| end;
 | |
| 
 | |
| procedure WriteOneBreakPointEntry(I : longint;INIFile : PINIFile);
 | |
| var PB : PBreakpoint;
 | |
|     S : String;
 | |
| begin
 | |
|   Str(I,S);
 | |
|   PB:=BreakpointsCollection^.At(I);
 | |
|   If assigned(PB) then
 | |
|    With PB^ do
 | |
|     Begin
 | |
|       INIFile^.SetEntry(secBreakpoint,ieBreakpointTyp+S,BreakpointTypeStr[typ]);
 | |
|       INIFile^.SetEntry(secBreakpoint,ieBreakpointState+S,BreakpointStateStr[state]);
 | |
|       if typ=bt_file_line then
 | |
|         begin
 | |
|           INIFile^.SetEntry(secBreakpoint,ieBreakpointFile+S,FileName^);
 | |
|           INIFile^.SetIntEntry(secBreakpoint,ieBreakpointLine+S,Line);
 | |
|         end
 | |
|       else
 | |
|         INIFile^.SetEntry(secBreakpoint,ieBreakpointName+S,Name^);
 | |
|       if assigned(Conditions) then
 | |
|         INIFile^.SetEntry(secBreakpoint,ieBreakpointCond+S,Conditions^);
 | |
|     end;
 | |
| end;
 | |
| 
 | |
| procedure ReadOneWatchEntry(I : Longint;INIFile : PINIFile);
 | |
| var
 | |
|   PW : PWatch;
 | |
|   S  : String;
 | |
| begin
 | |
|   Str(I,S);
 | |
|   PW:=new(PWatch,Init(INIFile^.GetEntry(secWatches,ieWatchName+S,'')));
 | |
|   WatchesCollection^.Insert(PW);
 | |
| end;
 | |
| 
 | |
| procedure ReadOneBreakPointEntry(i : longint;INIFile : PINIFile);
 | |
| var PB : PBreakpoint;
 | |
|     S,S2,SC : string;
 | |
|     Line : longint;
 | |
|     typ : BreakpointType;
 | |
|     state : BreakpointState;
 | |
| 
 | |
| begin
 | |
|   Str(I,S2);
 | |
|   typ:=bt_invalid;
 | |
|   S:=INIFile^.GetEntry(secBreakpoint,ieBreakpointTyp+S2,BreakpointTypeStr[typ]);
 | |
|   for typ:=low(BreakpointType) to high(BreakpointType) do
 | |
|     If pos(BreakpointTypeStr[typ],S)>0 then break;
 | |
|   state:=bs_deleted;
 | |
|   S:=INIFile^.GetEntry(secBreakpoint,ieBreakpointState+S2,BreakpointStateStr[state]);
 | |
|   for state:=low(BreakpointState) to high(BreakpointState) do
 | |
|     If pos(BreakpointStateStr[state],S)>0 then break;
 | |
|   case typ of
 | |
|      bt_invalid :;
 | |
|      bt_file_line :
 | |
|        begin
 | |
|          S:=INIFile^.GetEntry(secBreakpoint,ieBreakpointFile+S2,'');
 | |
|          Line:=INIFile^.GetIntEntry(secBreakpoint,ieBreakpointLine+S2,0);
 | |
|        end;
 | |
|      else
 | |
|        begin
 | |
|          S:=INIFile^.GetEntry(secBreakpoint,ieBreakpointName+S2,'');
 | |
|        end;
 | |
|      end;
 | |
|    SC:=INIFile^.GetEntry(secBreakpoint,ieBreakpointCond+S2,'');
 | |
|    if (typ=bt_function) and (S<>'') then
 | |
|      new(PB,init_function(S))
 | |
|    else if (typ=bt_file_line) and (S<>'') then
 | |
|      new(PB,init_file_line(S,Line))
 | |
|    else
 | |
|      new(PB,init_type(typ,S));
 | |
|    If assigned(PB) then
 | |
|      begin
 | |
|        PB^.state:=state;
 | |
|        If SC<>'' then
 | |
|          PB^.conditions:=NewStr(SC);
 | |
|        BreakpointsCollection^.Insert(PB);
 | |
|      end;
 | |
| end;
 | |
| {$endif NODEBUG}
 | |
| 
 | |
| function ReadINIFile: boolean;
 | |
| var INIFile: PINIFile;
 | |
|     S,PS,S1,S2,S3: string;
 | |
|     I,P: integer;
 | |
|     BreakPointCount,WatchesCount:longint;
 | |
|     OK: boolean;
 | |
|     ts : TSwitchMode;
 | |
|     W: word;
 | |
| begin
 | |
|   OK:=ExistsFile(IniFileName);
 | |
|   if OK then
 | |
|  begin
 | |
|   New(INIFile, Init(IniFileName));
 | |
|   { Files }
 | |
|   OpenExts:=INIFile^.GetEntry(secFiles,ieOpenExts,OpenExts);
 | |
|   RecentFileCount:=High(RecentFiles);
 | |
|   for I:=Low(RecentFiles) to High(RecentFiles) do
 | |
|     begin
 | |
|       S:=INIFile^.GetEntry(secFiles,ieRecentFile+IntToStr(I),'');
 | |
|       if (S='') and (RecentFileCount>I-1) then RecentFileCount:=I-1;
 | |
|       with RecentFiles[I] do
 | |
|       begin
 | |
|         P:=Pos(',',S); if P=0 then P:=length(S)+1;
 | |
|         FileName:=copy(S,1,P-1); Delete(S,1,P);
 | |
|         P:=Pos(',',S); if P=0 then P:=length(S)+1;
 | |
|         LastPos.X:=Max(0,StrToInt(copy(S,1,P-1))); Delete(S,1,P);
 | |
|         P:=Pos(',',S); if P=0 then P:=length(S)+1;
 | |
|         LastPos.Y:=Max(0,StrToInt(copy(S,1,P-1))); Delete(S,1,P);
 | |
|       end;
 | |
|     end;
 | |
|   { Run }
 | |
|   { First read the primary file, which can also set the parameters which can
 | |
|     be overruled with the parameter loading }
 | |
|   SetPrimaryFile(INIFile^.GetEntry(secCompile,iePrimaryFile,PrimaryFile));
 | |
|   SetRunParameters(INIFile^.GetEntry(secRun,ieRunParameters,GetRunParameters));
 | |
| {$ifndef GABOR}
 | |
|   DebuggeeTTY := INIFile^.GetEntry(secRun,ieDebuggeeRedir,DebuggeeTTY);
 | |
| {$endif}
 | |
|   { Compile }
 | |
|   S:=INIFile^.GetEntry(secCompile,ieCompileMode,'');
 | |
|   for ts:=low(TSwitchMode) to high(TSwitchMode) do
 | |
|     begin
 | |
|       if SwitchesModeStr[ts]=S then
 | |
|         SwitchesMode:=ts;
 | |
|     end;
 | |
|   { Help }
 | |
|   S:=INIFile^.GetEntry(secHelp,ieHelpFiles,'');
 | |
|   repeat
 | |
|     P:=Pos(';',S); if P=0 then P:=length(S)+1;
 | |
|     PS:=copy(S,1,P-1);
 | |
|     if PS<>'' then HelpFiles^.Insert(NewStr(PS));
 | |
|     Delete(S,1,P);
 | |
|   until S='';
 | |
|   { Editor }
 | |
| {$ifndef EDITORS}
 | |
|   DefaultTabSize:=INIFile^.GetIntEntry(secEditor,ieDefaultTabSize,DefaultTabSize);
 | |
|   DefaultIndentSize:=INIFile^.GetIntEntry(secEditor,ieDefaultIndentSize,DefaultIndentSize);
 | |
|   DefaultCodeEditorFlags:=INIFile^.GetIntEntry(secEditor,ieDefaultEditorFlags,DefaultCodeEditorFlags);
 | |
|   DefaultSaveExt:=INIFile^.GetEntry(secEditor,ieDefaultSaveExt,DefaultSaveExt);
 | |
| {$endif}
 | |
|   { Highlight }
 | |
|   HighlightExts:=INIFile^.GetEntry(secHighlight,ieHighlightExts,HighlightExts);
 | |
|   TabsPattern:=INIFile^.GetEntry(secHighlight,ieTabsPattern,TabsPattern);
 | |
|   { SourcePath }
 | |
|   SourceDirs:=INIFile^.GetEntry(secSourcePath,ieSourceList,SourceDirs);
 | |
|   { Mouse }
 | |
|   DoubleDelay:=INIFile^.GetIntEntry(secMouse,ieDoubleClickDelay,DoubleDelay);
 | |
|   MouseReverse:=boolean(INIFile^.GetIntEntry(secMouse,ieReverseButtons,byte(MouseReverse)));
 | |
|   AltMouseAction:=INIFile^.GetIntEntry(secMouse,ieAltClickAction,AltMouseAction);
 | |
|   CtrlMouseAction:=INIFile^.GetIntEntry(secMouse,ieCtrlClickAction,CtrlMouseAction);
 | |
|   { Search }
 | |
|   FindFlags:=INIFile^.GetIntEntry(secSearch,ieFindFlags,FindFlags);
 | |
|   { Breakpoints }
 | |
| {$ifndef NODEBUG}
 | |
|   BreakpointCount:=INIFile^.GetIntEntry(secBreakpoint,ieBreakpointCount,0);
 | |
|   for i:=1 to BreakpointCount do
 | |
|     ReadOneBreakPointEntry(i-1,INIFile);
 | |
|   WatchesCount:=INIFile^.GetIntEntry(secWatches,ieWatchCount,0);
 | |
|   for i:=1 to WatchesCount do
 | |
|     ReadOneWatchEntry(i-1,INIFile);
 | |
| {$endif}
 | |
|   { Tools }
 | |
|   for I:=1 to MaxToolCount do
 | |
|     begin
 | |
|       S:=IntToStr(I);
 | |
|       S1:=INIFile^.GetEntry(secTools,ieToolName+S,'');
 | |
|       if S1='' then Break; { !!! }
 | |
|       S2:=INIFile^.GetEntry(secTools,ieToolProgram+S,'');
 | |
|       S3:=INIFile^.GetEntry(secTools,ieToolParams+S,'');
 | |
|       W:=Max(0,Min(65535,INIFile^.GetIntEntry(secTools,ieToolHotKey+S,0)));
 | |
|       AddTool(S1,S2,S3,W);
 | |
|     end;
 | |
|   { Colors }
 | |
|   S:=AppPalette;
 | |
|   PS:=StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_1_40',PaletteToStr(copy(S,1,40))));
 | |
|   PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_41_80',PaletteToStr(copy(S,41,40))));
 | |
|   PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_81_120',PaletteToStr(copy(S,81,40))));
 | |
|   PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_121_160',PaletteToStr(copy(S,121,40))));
 | |
|   PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_161_200',PaletteToStr(copy(S,161,40))));
 | |
|   PS:=PS+StrToPalette(INIFile^.GetEntry(secColors,iePalette+'_201_240',PaletteToStr(copy(S,201,40))));
 | |
|   if length(PS)<length(CIDEAppColor) then
 | |
|     PS:=PS+copy(CIDEAppColor,length(PS)+1,255);
 | |
|   AppPalette:=PS;
 | |
| (*  { Open files }
 | |
|   for I:=INIFile^.GetIntEntry(secFiles,ieOpenFileCount,0) downto 1 do
 | |
|     begin
 | |
|       S:=INIFile^.GetEntry(secFiles,ieOpenFile+IntToStr(I),'');
 | |
|       if (S='') then
 | |
|         break;
 | |
|       P:=Pos(',',S); if P=0 then P:=length(S)+1;
 | |
|       S1:=copy(S,1,P-1);
 | |
|       Delete(S,1,P);
 | |
|       P:=Pos(',',S);
 | |
|       if P=0 then P:=length(S)+1;
 | |
|       X:=Max(0,StrToInt(copy(S,1,P-1)));
 | |
|       Delete(S,1,P);
 | |
|       P:=Pos(',',S);
 | |
|       if P=0 then P:=length(S)+1;
 | |
|       Y:=Max(0,StrToInt(copy(S,1,P-1)));
 | |
|       Delete(S,1,P);
 | |
|       P:=Pos(',',S);
 | |
|       if P=0 then P:=length(S)+1;
 | |
|       R.A.X:=Max(0,StrToInt(copy(S,1,P-1)));
 | |
|       Delete(S,1,P);
 | |
|       P:=Pos(',',S);
 | |
|       if P=0 then P:=length(S)+1;
 | |
|       R.A.Y:=Max(0,StrToInt(copy(S,1,P-1)));
 | |
|       Delete(S,1,P);
 | |
|       P:=Pos(',',S);
 | |
|       if P=0 then P:=length(S)+1;
 | |
|       R.B.X:=Max(0,StrToInt(copy(S,1,P-1)));
 | |
|       Delete(S,1,P);
 | |
|       P:=Pos(',',S);
 | |
|       if P=0 then P:=length(S)+1;
 | |
|       R.B.Y:=Max(0,StrToInt(copy(S,1,P-1)));
 | |
|       if (R.A.X<R.B.X) and (R.A.Y<R.B.Y) then
 | |
|         TryToOpenFile(@R,S1,X,Y,false)
 | |
|       else
 | |
|         TryToOpenFile(nil,S1,X,Y,false);
 | |
|       { remove it because otherwise we allways keep old files }
 | |
|       INIFile^.DeleteEntry(secFiles,ieOpenFile+IntToStr(I));
 | |
|     end;
 | |
| *)
 | |
|   { Desktop }
 | |
|   DesktopFileFlags:=INIFile^.GetIntEntry(secPreferences,ieDesktopFlags,DesktopFileFlags);
 | |
|   { Debugger }
 | |
|   IniCenterDebuggerRow:=INIFile^.GetIntEntry(secPreferences,ieCenterDebuggerRow,1)<>0;
 | |
|   { Preferences }
 | |
|   AutoSaveOptions:=INIFile^.GetIntEntry(secPreferences,ieAutoSave,AutoSaveOptions);
 | |
|   MiscOptions:=INIFile^.GetIntEntry(secPreferences,ieMiscOptions,MiscOptions);
 | |
|   DesktopLocation:=INIFile^.GetIntEntry(secPreferences,ieDesktopLocation,DesktopLocation);
 | |
|   { Misc }
 | |
|   ShowReadme:=INIFile^.GetIntEntry(secMisc,ieShowReadme,{integer(ShowReadme)}1)<>0;
 | |
|   Dispose(INIFile, Done);
 | |
|  end;
 | |
|   ReadINIFile:=OK;
 | |
| end;
 | |
| 
 | |
| function WriteINIFile (FromSaveAs : boolean): boolean;
 | |
| var INIFile: PINIFile;
 | |
|     S: string;
 | |
|     S1,S2,S3: string;
 | |
|     W: word;
 | |
|     BreakPointCount,WatchesCount:longint;
 | |
|     I(*,OpenFileCount*): integer;
 | |
|     OK: boolean;
 | |
| 
 | |
| procedure ConcatName(P: PString); {$ifndef FPC}far;{$endif}
 | |
| begin
 | |
|   if (S<>'') then S:=S+';';
 | |
|   S:=S+P^;
 | |
| end;
 | |
| begin
 | |
| {$ifdef Unix}
 | |
|   if not FromSaveAs and (DirOf(IniFileName)=DirOf(SystemIDEDir)) then
 | |
|     begin
 | |
|       IniFileName:=FExpand('~/.fp/'+IniName);
 | |
|       If not ExistsDir(DirOf(IniFileName)) then
 | |
|         MkDir(FExpand('~/.fp'));
 | |
|    end;
 | |
| {$endif Unix}
 | |
|   New(INIFile, Init(IniFileName));
 | |
|   { Files }
 | |
|   { avoid keeping old files }
 | |
|   INIFile^.DeleteSection(secFiles);
 | |
|   INIFile^.SetEntry(secFiles,ieOpenExts,'"'+OpenExts+'"');
 | |
|   for I:=1 to High(RecentFiles) do
 | |
|     begin
 | |
|       if I<=RecentFileCount then
 | |
|          with RecentFiles[I] do S:=FileName+','+IntToStr(LastPos.X)+','+IntToStr(LastPos.Y)
 | |
|       else
 | |
|          S:='';
 | |
|       INIFile^.SetEntry(secFiles,ieRecentFile+IntToStr(I),S);
 | |
|     end;
 | |
| 
 | |
| (*
 | |
|     PW:=FirstEditorWindow;
 | |
|     PPW:=PW;
 | |
|     I:=1;
 | |
|     while assigned(PW) do
 | |
|       begin
 | |
|         If PW^.HelpCtx=hcSourceWindow then
 | |
|           begin
 | |
|             With PW^.editor^ do
 | |
|               S:=FileName+','+IntToStr(CurPos.X)+','+IntToStr(CurPos.Y);
 | |
|             PW^.GetBounds(R);
 | |
|             S:=S+','+IntToStr(R.A.X)+','+IntToStr(R.A.Y)+','+
 | |
|               IntToStr(R.B.X)+','+IntToStr(R.B.Y);
 | |
|             INIFile^.SetEntry(secFiles,ieOpenFile+IntToStr(I),S);
 | |
|             Inc(I);
 | |
|             OpenFileCount:=I-1;
 | |
|           end;
 | |
| 
 | |
|         PW:=PSourceWindow(PW^.next);
 | |
|         While assigned(PW) and (PW<>PPW) and (PW^.HelpCtx<>hcSourceWindow) do
 | |
|           PW:=PSourceWindow(PW^.next);
 | |
|         If PW=PPW then
 | |
|           break;
 | |
|       end;
 | |
| 
 | |
|   INIFile^.SetIntEntry(secFiles,ieOpenFileCount,OpenFileCount);
 | |
| *)
 | |
|   { Run }
 | |
|   INIFile^.SetEntry(secRun,ieRunParameters,GetRunParameters);
 | |
| {$ifndef GABOR}
 | |
|   If DebuggeeTTY<>'' then
 | |
|     INIFile^.SetEntry(secRun,ieDebuggeeRedir,DebuggeeTTY);
 | |
| {$endif}
 | |
|   { Compile }
 | |
|   INIFile^.SetEntry(secCompile,iePrimaryFile,PrimaryFile);
 | |
|   INIFile^.SetEntry(secCompile,ieCompileMode,SwitchesModeStr[SwitchesMode]);
 | |
|   { Help }
 | |
|   S:='';
 | |
|   HelpFiles^.ForEach(@ConcatName);
 | |
|   INIFile^.SetEntry(secHelp,ieHelpFiles,'"'+S+'"');
 | |
|   { Editor }
 | |
| {$ifndef EDITORS}
 | |
|   INIFile^.SetIntEntry(secEditor,ieDefaultTabSize,DefaultTabSize);
 | |
|   INIFile^.SetIntEntry(secEditor,ieDefaultIndentSize,DefaultIndentSize);
 | |
|   INIFile^.SetIntEntry(secEditor,ieDefaultEditorFlags,DefaultCodeEditorFlags);
 | |
|   INIFile^.SetEntry(secEditor,ieDefaultSaveExt,DefaultSaveExt);
 | |
| {$endif}
 | |
|   { Highlight }
 | |
|   INIFile^.SetEntry(secHighlight,ieHighlightExts,'"'+HighlightExts+'"');
 | |
|   INIFile^.SetEntry(secHighlight,ieTabsPattern,'"'+TabsPattern+'"');
 | |
|   { SourcePath }
 | |
|   INIFile^.SetEntry(secSourcePath,ieSourceList,'"'+SourceDirs+'"');
 | |
|   { Mouse }
 | |
|   INIFile^.SetIntEntry(secMouse,ieDoubleClickDelay,DoubleDelay);
 | |
|   INIFile^.SetIntEntry(secMouse,ieReverseButtons,byte(MouseReverse));
 | |
|   INIFile^.SetIntEntry(secMouse,ieAltClickAction,AltMouseAction);
 | |
|   INIFile^.SetIntEntry(secMouse,ieCtrlClickAction,CtrlMouseAction);
 | |
|   { Search }
 | |
|   INIFile^.SetIntEntry(secSearch,ieFindFlags,FindFlags);
 | |
|   { Breakpoints }
 | |
| {$ifndef NODEBUG}
 | |
|   BreakPointCount:=BreakpointsCollection^.Count;
 | |
|   INIFile^.SetIntEntry(secBreakpoint,ieBreakpointCount,BreakpointCount);
 | |
|   for i:=1 to BreakpointCount do
 | |
|     WriteOneBreakPointEntry(I-1,INIFile);
 | |
|   WatchesCount:=WatchesCollection^.Count;
 | |
|   INIFile^.SetIntEntry(secWatches,ieWatchCount,WatchesCount);
 | |
|   for i:=1 to WatchesCount do
 | |
|     WriteOneWatchEntry(I-1,INIFile);
 | |
| {$endif}
 | |
|   { Tools }
 | |
|   INIFile^.DeleteSection(secTools);
 | |
|   for I:=1 to GetToolCount do
 | |
|     begin
 | |
|       S:=IntToStr(I);
 | |
|       GetToolParams(I-1,S1,S2,S3,W);
 | |
|       if S1<>'' then S1:='"'+S1+'"';
 | |
|       if S2<>'' then S2:='"'+S2+'"';
 | |
|       if S3<>'' then S3:='"'+S3+'"';
 | |
|       INIFile^.SetEntry(secTools,ieToolName+S,S1);
 | |
|       INIFile^.SetEntry(secTools,ieToolProgram+S,S2);
 | |
|       INIFile^.SetEntry(secTools,ieToolParams+S,S3);
 | |
|       INIFile^.SetIntEntry(secTools,ieToolHotKey+S,W);
 | |
|     end;
 | |
|   { Colors }
 | |
|   if AppPalette<>CIDEAppColor then
 | |
|   begin
 | |
|     { this has a bug. if a different palette has been read on startup, and
 | |
|       then changed back to match the default, this will not update it in the
 | |
|       ini file, eg. the original (non-default) will be left unmodified... }
 | |
|     S:=AppPalette;
 | |
|     INIFile^.SetEntry(secColors,iePalette+'_1_40',PaletteToStr(copy(S,1,40)));
 | |
|     INIFile^.SetEntry(secColors,iePalette+'_41_80',PaletteToStr(copy(S,41,40)));
 | |
|     INIFile^.SetEntry(secColors,iePalette+'_81_120',PaletteToStr(copy(S,81,40)));
 | |
|     INIFile^.SetEntry(secColors,iePalette+'_121_160',PaletteToStr(copy(S,121,40)));
 | |
|     INIFile^.SetEntry(secColors,iePalette+'_161_200',PaletteToStr(copy(S,161,40)));
 | |
|     INIFile^.SetEntry(secColors,iePalette+'_201_240',PaletteToStr(copy(S,201,40)));
 | |
|   end;
 | |
|   { Desktop }
 | |
|   INIFile^.SetIntEntry(secPreferences,ieDesktopFlags,DesktopFileFlags);
 | |
|   INIFile^.SetIntEntry(secPreferences,ieCenterDebuggerRow,byte(IniCenterDebuggerRow));
 | |
|   { Preferences }
 | |
|   INIFile^.SetIntEntry(secPreferences,ieAutoSave,AutoSaveOptions);
 | |
|   INIFile^.SetIntEntry(secPreferences,ieMiscOptions,MiscOptions);
 | |
|   INIFile^.SetIntEntry(secPreferences,ieDesktopLocation,DesktopLocation);
 | |
|   { Misc }
 | |
|   INIFile^.SetIntEntry(secMisc,ieShowReadme,integer(ShowReadme));
 | |
|   OK:=INIFile^.Update;
 | |
|   Dispose(INIFile, Done);
 | |
|   WriteINIFile:=OK;
 | |
| end;
 | |
| 
 | |
| end.
 | |
| {
 | |
|   $Log$
 | |
|   Revision 1.3  2001-08-12 00:04:50  pierre
 | |
|    * some speed improvements for string operations
 | |
| 
 | |
|   Revision 1.2  2001/08/05 02:01:48  peter
 | |
|     * FVISION define to compile with fvision units
 | |
| 
 | |
|   Revision 1.1  2001/08/04 11:30:23  peter
 | |
|     * ide works now with both compiler versions
 | |
| 
 | |
|   Revision 1.1.2.8  2001/03/08 16:39:22  pierre
 | |
|    use external compiler version if compiler external
 | |
| 
 | |
|   Revision 1.1.2.7  2000/12/20 14:27:49  pierre
 | |
|    * fp.ini for unix
 | |
| 
 | |
|   Revision 1.1.2.6  2000/12/09 17:41:20  florian
 | |
|     * IndentSize is stored in the .INI file now
 | |
| 
 | |
|   Revision 1.1.2.5  2000/11/13 16:59:09  pierre
 | |
|    * some function in double removed from fputils unit
 | |
| 
 | |
|   Revision 1.1.2.4  2000/10/18 21:53:27  pierre
 | |
|    * several Gabor fixes
 | |
| 
 | |
|   Revision 1.1.2.3  2000/10/06 22:52:35  pierre
 | |
|    * fixes for linux GDB tty command
 | |
| 
 | |
|   Revision 1.1.2.2  2000/08/16 18:46:14  peter
 | |
|    [*] double clicking on a droplistbox caused GPF (due to invalid recurson)
 | |
|    [*] Make, Build now possible even in Compiler Messages Window
 | |
|    [+] when started in a new dir the IDE now ask whether to create a local
 | |
|        config, or to use the one located in the IDE dir
 | |
| 
 | |
|   Revision 1.1.2.1  2000/07/20 11:02:15  michael
 | |
|   + Fixes from gabor. See fixes.txt
 | |
| 
 | |
|   Revision 1.1  2000/07/13 09:48:34  michael
 | |
|   + Initial import
 | |
| 
 | |
|   Revision 1.30  2000/06/22 09:07:12  pierre
 | |
|    * Gabor changes: see fixes.txt
 | |
| 
 | |
|   Revision 1.29  2000/06/16 08:50:41  pierre
 | |
|    + new bunch of Gabor's changes
 | |
| 
 | |
|   Revision 1.28  2000/03/21 23:30:22  pierre
 | |
|    adapted to wcedit addition by Gabor
 | |
| 
 | |
|   Revision 1.27  2000/03/13 20:38:02  pierre
 | |
|     IniPath removed and IniFileName moved to fpvars unit
 | |
| 
 | |
|   Revision 1.26  2000/02/04 00:08:35  pierre
 | |
|    + IniCenterDebuggerRow
 | |
| 
 | |
|   Revision 1.25  1999/11/05 13:47:19  pierre
 | |
|    * Breakpoint conditions were not reloaded correctly
 | |
| 
 | |
|   Revision 1.24  1999/09/16 14:34:59  pierre
 | |
|     + TBreakpoint and TWatch registering
 | |
|     + WatchesCollection and BreakpointsCollection stored in desk file
 | |
|     * Syntax highlighting was broken
 | |
| 
 | |
|   Revision 1.23  1999/09/13 16:24:43  peter
 | |
|     + clock
 | |
|     * backspace unident like tp7
 | |
| 
 | |
|   Revision 1.22  1999/09/07 09:21:54  pierre
 | |
|    + Watches saved
 | |
| 
 | |
|   Revision 1.21  1999/08/03 20:22:33  peter
 | |
|     + TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
 | |
|     + Desktop saving should work now
 | |
|        - History saved
 | |
|        - Clipboard content saved
 | |
|        - Desktop saved
 | |
|        - Symbol info saved
 | |
|     * syntax-highlight bug fixed, which compared special keywords case sensitive
 | |
|       (for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
 | |
|     * with 'whole words only' set, the editor didn't found occourences of the
 | |
|       searched text, if the text appeared previously in the same line, but didn't
 | |
|       satisfied the 'whole-word' condition
 | |
|     * ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
 | |
|       (ie. the beginning of the selection)
 | |
|     * when started typing in a new line, but not at the start (X=0) of it,
 | |
|       the editor inserted the text one character more to left as it should...
 | |
|     * TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
 | |
|     * Shift shouldn't cause so much trouble in TCodeEditor now...
 | |
|     * Syntax highlight had problems recognizing a special symbol if it was
 | |
|       prefixed by another symbol character in the source text
 | |
|     * Auto-save also occours at Dos shell, Tool execution, etc. now...
 | |
| 
 | |
|   Revision 1.20  1999/06/28 12:36:51  pierre
 | |
|    * avoid keeping old open file names
 | |
| 
 | |
|   Revision 1.19  1999/04/07 21:55:48  peter
 | |
|     + object support for browser
 | |
|     * html help fixes
 | |
|     * more desktop saving things
 | |
|     * NODEBUG directive to exclude debugger
 | |
| 
 | |
|   Revision 1.18  1999/03/23 15:11:31  peter
 | |
|     * desktop saving things
 | |
|     * vesa mode
 | |
|     * preferences dialog
 | |
| 
 | |
|   Revision 1.17  1999/03/12 01:13:58  peter
 | |
|     * flag if trytoopen should look for other extensions
 | |
|     + browser tab in the tools-compiler
 | |
| 
 | |
|   Revision 1.16  1999/03/08 14:58:09  peter
 | |
|     + prompt with dialogs for tools
 | |
| 
 | |
|   Revision 1.15  1999/03/05 17:53:02  pierre
 | |
|    + saving and opening of open files on exit
 | |
| 
 | |
|   Revision 1.14  1999/03/01 15:41:55  peter
 | |
|     + Added dummy entries for functions not yet implemented
 | |
|     * MenuBar didn't update itself automatically on command-set changes
 | |
|     * Fixed Debugging/Profiling options dialog
 | |
|     * TCodeEditor converts spaces to tabs at save only if efUseTabChars is
 | |
|  set
 | |
|     * efBackSpaceUnindents works correctly
 | |
|     + 'Messages' window implemented
 | |
|     + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
 | |
|     + Added TP message-filter support (for ex. you can call GREP thru
 | |
|       GREP2MSG and view the result in the messages window - just like in TP)
 | |
|     * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
 | |
|       so topic search didn't work...
 | |
|     * In FPHELP.PAS there were still context-variables defined as word instead
 | |
|       of THelpCtx
 | |
|     * StdStatusKeys() was missing from the statusdef for help windows
 | |
|     + Topic-title for index-table can be specified when adding a HTML-files
 | |
| 
 | |
|   Revision 1.13  1999/02/22 02:15:14  peter
 | |
|     + default extension for save in the editor
 | |
|     + Separate Text to Find for the grep dialog
 | |
|     * fixed redir crash with tp7
 | |
| 
 | |
|   Revision 1.12  1999/02/19 18:43:46  peter
 | |
|     + open dialog supports mask list
 | |
| 
 | |
|   Revision 1.11  1999/02/10 09:53:14  pierre
 | |
|   * better storing of breakpoints
 | |
| 
 | |
|   Revision 1.10  1999/02/05 13:08:42  pierre
 | |
|    + new breakpoint types added
 | |
| 
 | |
|   Revision 1.9  1999/02/05 12:11:55  pierre
 | |
|     + SourceDir that stores directories for sources that the
 | |
|       compiler should not know about
 | |
|       Automatically asked for addition when a new file that
 | |
|       needed filedialog to be found is in an unknown directory
 | |
|       Stored and retrieved from INIFile
 | |
|     + Breakpoints conditions added to INIFile
 | |
|     * Breakpoints insterted and removed at debin and end of debug session
 | |
| 
 | |
|   Revision 1.8  1999/02/04 17:52:38  pierre
 | |
|    * bs_invalid renamed bs_deleted
 | |
| 
 | |
|   Revision 1.7  1999/02/04 17:19:24  peter
 | |
|     * linux fixes
 | |
| 
 | |
|   Revision 1.6  1999/02/04 13:32:04  pierre
 | |
|     * Several things added (I cannot commit them independently !)
 | |
|     + added TBreakpoint and TBreakpointCollection
 | |
|     + added cmResetDebugger,cmGrep,CmToggleBreakpoint
 | |
|     + Breakpoint list in INIFile
 | |
|     * Select items now also depend of SwitchMode
 | |
|     * Reading of option '-g' was not possible !
 | |
|     + added search for -Fu args pathes in TryToOpen
 | |
|     + added code for automatic opening of FileDialog
 | |
|       if source not found
 | |
| 
 | |
|   Revision 1.5  1999/01/21 11:54:15  peter
 | |
|     + tools menu
 | |
|     + speedsearch in symbolbrowser
 | |
|     * working run command
 | |
| 
 | |
|   Revision 1.4  1999/01/04 11:49:45  peter
 | |
|    * 'Use tab characters' now works correctly
 | |
|    + Syntax highlight now acts on File|Save As...
 | |
|    + Added a new class to syntax highlight: 'hex numbers'.
 | |
|    * There was something very wrong with the palette managment. Now fixed.
 | |
|    + Added output directory (-FE<xxx>) support to 'Directories' dialog...
 | |
|    * Fixed some possible bugs in Running/Compiling, and the compilation/run
 | |
|      process revised
 | |
| 
 | |
|   Revision 1.1  1998/12/28 15:47:45  peter
 | |
|     + Added user screen support, display & window
 | |
|     + Implemented Editor,Mouse Options dialog
 | |
|     + Added location of .INI and .CFG file
 | |
|     + Option (INI) file managment implemented (see bottom of Options Menu)
 | |
|     + Switches updated
 | |
|     + Run program
 | |
| 
 | |
| }
 | 
