686 lines
21 KiB
ObjectPascal
686 lines
21 KiB
ObjectPascal
{
|
|
********************************************************************************
|
|
|
|
SPackGui (common files)
|
|
Copyright (C) 2013 Geoffray Levasseur <geoffray.levasseurbrandin@numericable.fr>.
|
|
Copyright (C) <date> <add your name and mail address here>
|
|
|
|
http://www.geoffray-levasseur.org/
|
|
http://0.tuxfamilly.org/
|
|
|
|
This software is governed by the CeCILL license under French law and
|
|
abiding by the rules of distribution of free software. You can use,
|
|
modify and/ or redistribute the software under the terms of the CeCILL
|
|
license as circulated by CEA, CNRS and INRIA at the following URL
|
|
"http://www.cecill.info".
|
|
|
|
As a counterpart to the access to the source code and rights to copy,
|
|
modify and redistribute granted by the license, users are provided only
|
|
with a limited warranty and the software's author, the holder of the
|
|
economic rights, and the successive licensors have only limited
|
|
liability.
|
|
|
|
In this respect, the user's attention is drawn to the risks associated
|
|
with loading, using, modifying and/or developing or reproducing the
|
|
software by the user in light of its specific status of free software,
|
|
that may mean that it is complicated to manipulate, and that also
|
|
therefore means that it is reserved for developers and experienced
|
|
professionals having in-depth computer knowledge. Users are therefore
|
|
encouraged to load and test the software's suitability as regards their
|
|
requirements in conditions enabling the security of their systems and/or
|
|
data to be ensured and, more generally, to use and operate it in the
|
|
same conditions as regards security.
|
|
|
|
The fact that you are presently reading this means that you have had
|
|
knowledge of the CeCILL license and that you accept its terms.
|
|
|
|
********************************************************************************
|
|
|
|
Description:
|
|
some common vars and functions
|
|
|
|
********************************************************************************
|
|
}
|
|
unit uCommon;
|
|
|
|
{$include defines.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, IniFiles, Forms;
|
|
|
|
type
|
|
TCharSet = set of Char;
|
|
|
|
const
|
|
//for test we don't touch to real system files
|
|
{$IFDEF TEST}
|
|
//you need to change everything before the ELSE compiler directive
|
|
//accordingly to your own test path
|
|
sDefaultLogFileName = '/share/src/pascal/0linux/log/spackgui.log';
|
|
sLockFile = '/share/src/pascal/0linux/log/spackgui.lock';
|
|
sIconBaseDir = '/share/src/pascal/0linux/icons';
|
|
sRootUserName = 'fatalerrors'; //when testing we want to make change even if non root
|
|
|
|
sDefaultSpackPkgDir = '/share/src/pascal/0linux/testpack';
|
|
sDefaultConfDir = '/share/src/pascal/0linux/testconf';
|
|
sDefaultRepoIndexDir = sDefaultConfDir;
|
|
sDefaultDwlDir = '/share/src/pascal/0linux/packages';
|
|
sRepoConfFile = 'depots.conf';
|
|
sMainConfFile = 'spackgui.conf';
|
|
{$ELSE}
|
|
sDefaultLogFileName = {$LOCALSTATEDIR}'/log/spackgui.log';
|
|
sLockFile = {$LOCALSTATEDIR}'/lock/spackgui.lock';
|
|
sIconBaseDir = {$PREFIX}'/share/spackgui/icons';
|
|
sRootUserName = 'root';
|
|
|
|
sDefaultSpackPkgDir = {$LOCALSTATEDIR}'/lib/spack';
|
|
sDefaultConfDir = {$SYSCONFDIR}'/spackgui';
|
|
sDefaultRepoIndexDir = sDefaultConfDir;
|
|
sDefaultDwlDir = {$LOCALSTATEDIR}'/cache/spack';
|
|
sRepoConfFile = 'depots.conf';
|
|
sMainConfFile = 'spackgui.conf';
|
|
{$ENDIF}
|
|
|
|
sDefaultInstallPackage = 'spackadd %s';
|
|
sDefaultReinstallPackage = 'spackadd -f %s';
|
|
sDefaultRemovePackage = 'spackrm %s';
|
|
sDefaultUpdatePackage = 'spackadd %s';
|
|
|
|
AnsiLineFeed = AnsiChar(#10);
|
|
AnsiCarriageReturn = AnsiChar(#13);
|
|
AnsiCrLf = AnsiString(#13#10);
|
|
|
|
iDefaultProxyPort = 3128;
|
|
|
|
RegExprOperator: TCharSet = ['&', '|', '#'];
|
|
|
|
|
|
var
|
|
sConfDir: string; //place where configuration files will be stored
|
|
sSpackPkgDir: string; //installed packages repository
|
|
sRepoIndexDir: string; //place where repositories metadata are stored
|
|
sDwlDir: string; //place where packages are downloaded before install
|
|
sDefaultRepo: string; //default repo used for upgrades
|
|
|
|
bChangeAllowed: Boolean; //global saying if change are allowed or not
|
|
bUnitsAreDecimal: Boolean; //user may want decimal
|
|
cThousandSep: Char; //thousand separator (#0 means none)
|
|
cDecimalSep: Char; //decimal separator
|
|
|
|
bNoColors: Boolean; //colorize listview or not
|
|
bShowGrig: Boolean; //show a grid in listview or not
|
|
|
|
sInstallPackage: string; //command to install a package
|
|
sReinstallPackage: string; //command to reinstall an installed package
|
|
sRemovePackage: string; //command to remove an installed package
|
|
sUpdatePackage: string; //command to update an installed package
|
|
|
|
tLockFile: Text; //pointer to lockfile
|
|
iniMain: TIniFile; //main configuration file object
|
|
iniRepo: TIniFile; //repositories configuration file object
|
|
bReadOnly: Boolean; //when non-root we are read-only
|
|
slRepoList: TStringList; //list of non installed packages repository
|
|
slDeprecated: TStringList; //list of deprecated packages
|
|
sArch: string; //used architecture
|
|
|
|
//proxy settings
|
|
sHttpProxyAddress: string;
|
|
iHttpProxyPort: Integer;
|
|
sHttpProxyUser: string;
|
|
sHttpProxyPass: string;
|
|
sFtpProxyAddress: string;
|
|
iFtpProxyPort: Integer;
|
|
sFtpProxyUser: string;
|
|
sFtpProxyPass: string;
|
|
|
|
//write a string list in an ini file, the TInifile must be initialized
|
|
procedure IniWriteStrings(IniFile: TIniFile; const Section, Ident: string;
|
|
Str: TStrings);
|
|
|
|
//read a string list in an ini file, the TInifile must be initialized
|
|
procedure IniReadStrings(IniFile: TIniFile; const Section, Ident: string;
|
|
Str: TStrings);
|
|
|
|
// SPack use that format: pkgname-version-arch-build{,.spack}
|
|
procedure DecomposePackageName(const S: ansistring;
|
|
out Name, Version: ansistring; out Build: Byte; out Arch: ansistring);
|
|
|
|
// Extract package name a full spack format string
|
|
function ExtractPackageName(const S: ansistring): ansistring;
|
|
|
|
// Format numbers for file size display (with units)
|
|
// the base unit is Byte but spack have KB as base unit
|
|
function DispSize(const Size: integer): string;
|
|
|
|
//convert strings generated by the previous function to LongInt
|
|
function SizeStrToInt(const SzStr: string): LongInt;
|
|
|
|
// Get Major, minor and release number (sometimes there's letters so we keep that
|
|
// string)... Exotic version numbering gets remainings information in rem var
|
|
procedure DecomposeVersion(const V: string; out Maj, Min, Rel, Rem: string);
|
|
|
|
// If V1 > V2 result is 1, 0 if equal and -1 if V1 < V2
|
|
function CompareVersion(const V1, V2: string): ShortInt;
|
|
|
|
// Load/save window geometry in main ini file
|
|
procedure LoadWindowGeometry(Form: TForm);
|
|
procedure SaveWindowGeometry(Form: TForm);
|
|
|
|
// Load/save repository configuration informations
|
|
procedure LoadRepoSettings;
|
|
procedure SaveRepoSettings;
|
|
|
|
// Initialize config dir and inifiles
|
|
procedure InitConf;
|
|
|
|
// Get address of a repository from it's name
|
|
function GetRepoAddress(const RepoName: string): string;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
SysUtils, uStrings, uUtils, uDebug, Controls;
|
|
|
|
|
|
procedure IniWriteStrings(IniFile: TIniFile; const Section, Ident: string;
|
|
Str: TStrings);
|
|
var
|
|
I: integer;
|
|
OldCount: Integer;
|
|
begin
|
|
//old number of line as needed
|
|
OldCount := IniFile.ReadInteger(Section, Ident + rsConfNameCount, 0);
|
|
if OldCount > Str.Count then //more lines in old config ?
|
|
for I := Str.Count to OldCount do
|
|
IniFile.DeleteKey(Section, Ident + IntToStr(I)); //erase old keys
|
|
IniFile.WriteInteger(Section, Ident + rsConfNameCount, Str.Count); //new count
|
|
for I := 0 to Str.Count - 1 do
|
|
IniFile.WriteString(Section, Ident + IntToStr(I), Str[I]); //write each line
|
|
end;
|
|
|
|
|
|
procedure IniReadStrings(IniFile: TIniFile; const Section, Ident: string;
|
|
Str: TStrings);
|
|
var
|
|
I, N: Integer;
|
|
begin
|
|
Str.Clear;
|
|
N := IniFile.ReadInteger(Section, Ident + rsConfNameCount, 0);
|
|
for I := 0 to N - 1 do
|
|
Str.Add(IniFile.ReadString(Section, Ident + IntToStr(I), ''));
|
|
end;
|
|
|
|
|
|
procedure DecomposePackageName(const S: ansistring;
|
|
out Name, Version: ansistring; out Build: Byte; out Arch: ansistring);
|
|
var
|
|
I, J: integer;
|
|
Tmp: string;
|
|
begin
|
|
I := Length(S);
|
|
while S[I] <> '-' do
|
|
Dec(I);
|
|
Tmp := Copy(S, I + 1, Length(S) - I + 1);
|
|
if Trim(Tmp) <> '' then
|
|
Build := StrToInt(Tmp)
|
|
else
|
|
Build := 0;
|
|
Dec(I);
|
|
J := I;
|
|
while S[I] <> '-' do
|
|
Dec(I);
|
|
Arch := Copy(S, I + 1, J - I);
|
|
Dec(I);
|
|
J := I;
|
|
while S[I] <> '-' do
|
|
Dec(I);
|
|
Version := Copy(S, I + 1, J - I);
|
|
Name := Copy(S, 1, I - 1);
|
|
//the following is unneeded as we shouldn't have '-' in versions
|
|
//--------------------------------------------------------------
|
|
//I := Length(Name);
|
|
//while (I > 1) and (Name[I] <> '-') do //still some '-' in the name ?
|
|
// Dec(I);
|
|
//if I > 1 then //name or version contains '-': try to analyse this correctly...
|
|
// if (Name[I + 1] in ['0'..'9']) and (Name[Length(Name)] in ['0'..'9']) then
|
|
// begin
|
|
// Tmp := Copy(Name, I + 1, Length(Name) - I + 1);
|
|
// Version := Tmp + '-' + Version;
|
|
// Name := Copy(S, 1, I - 1);
|
|
// end;
|
|
end;
|
|
|
|
|
|
function ExtractPackageName(const S: ansistring): ansistring;
|
|
var
|
|
I, P: integer;
|
|
Tmp: string;
|
|
begin
|
|
if UpperCase(ExtractFileExt(S)) = rsSpackExt then
|
|
Tmp := RemoveFileExt(S)
|
|
else
|
|
Tmp := S;
|
|
P := Pos(' ', S);
|
|
if P <> 0 then
|
|
begin
|
|
Tmp := Copy(Tmp, P + 1, Length(Tmp) - P);
|
|
P := Pos(' ', Tmp);
|
|
Tmp := Copy(Tmp, 1, P - 1);
|
|
end;
|
|
I := Length(Tmp);
|
|
//skip build
|
|
while Tmp[I] <> '-' do
|
|
Dec(I);
|
|
Dec(I);
|
|
//skip arch
|
|
while Tmp[I] <> '-' do
|
|
Dec(I);
|
|
Dec(I);
|
|
//skip version
|
|
while Tmp[I] <> '-' do
|
|
Dec(I);
|
|
Result := Copy(S, 1, I - 1);
|
|
end;
|
|
|
|
|
|
function DispSize(const Size: LongInt): string;
|
|
var
|
|
Diviser, I, N: Integer;
|
|
Unt: string;
|
|
begin
|
|
if bUnitsAreDecimal then
|
|
Diviser := 1000
|
|
else
|
|
Diviser := 1024;
|
|
// we go up to GB as bigger is probably not needed for now in that kind of app
|
|
if Size > (Diviser * 10) then //if true at least 10KB
|
|
if (Size div Diviser) > (Diviser * 10) then //10MB
|
|
if ((Size div Diviser) div Diviser) > (Diviser * 10) then //10GB
|
|
begin
|
|
Result := IntToStr(((Size div Diviser) div Diviser) div Diviser);
|
|
if ((Size div Diviser) div Diviser) mod Diviser <> 0 then
|
|
Result := Result + cDecimalSep +
|
|
Copy(IntToStr(((Size div Diviser) div Diviser) mod Diviser), 1, 2);
|
|
if bUnitsAreDecimal then
|
|
Unt := rsGB
|
|
else
|
|
Unt := rsGiB;
|
|
end else
|
|
begin
|
|
Result := IntToStr((Size div Diviser) div Diviser);
|
|
if (Size div Diviser) mod Diviser <> 0 then
|
|
Result := Result + cDecimalSep +
|
|
Copy(IntToStr((Size div Diviser) mod Diviser), 1, 2);
|
|
if bUnitsAreDecimal then
|
|
Unt := rsMB
|
|
else
|
|
Unt := rsMiB;
|
|
end
|
|
else
|
|
begin
|
|
Result := IntToStr(Size div Diviser);
|
|
if Size mod Diviser <> 0 then
|
|
Result := Result + cDecimalSep + Copy(IntToStr(Size mod Diviser), 1, 2);
|
|
if bUnitsAreDecimal then
|
|
Unt := rsKB
|
|
else
|
|
Unt := rsKiB;
|
|
end else
|
|
begin
|
|
Unt := rsByte;
|
|
Result := IntToStr(Size);
|
|
end;
|
|
if (((Length(Result) > 3) and (Pos(cDecimalSep, Result) = 0)) or
|
|
((Pos(cDecimalSep, Result) <> 0) and (Length(Result) > 5))) and
|
|
(cThousandSep <> #0) then
|
|
begin
|
|
N := Pos(cDecimalSep, Result) - 1;
|
|
if N <= 0 then
|
|
N := Length(Result);
|
|
I := 0;
|
|
while N >= 1 do
|
|
begin
|
|
if (I <> 0) and (I mod 3 = 0) then
|
|
Insert(cThousandSep, Result, N + 1);
|
|
Inc(I);
|
|
Dec(N);
|
|
end;
|
|
end;
|
|
Result := Result + ' ' + Unt;
|
|
end;
|
|
|
|
|
|
function SizeStrToInt(const SzStr: string): LongInt;
|
|
var
|
|
Mul: Integer;
|
|
Val: Single;
|
|
S: string;
|
|
begin
|
|
S := Trim(SzStr);
|
|
if S = '' then
|
|
begin
|
|
Result := 0;
|
|
Exit;
|
|
end;
|
|
Mul := 1;
|
|
if Pos(rsKiB, S) > 1 then
|
|
begin
|
|
Mul := 1024;
|
|
S := Copy(S, 1, Length(S) - 4);
|
|
end else
|
|
if Pos(rsKB, S) > 1 then
|
|
begin
|
|
Mul := 1000;
|
|
S := Copy(S, 1, Length(S) - 3);
|
|
end else
|
|
if Pos(rsMiB, S) > 1 then
|
|
begin
|
|
Mul := 1024 * 1024;
|
|
S := Copy(S, 1, Length(S) - 4);
|
|
end else
|
|
if Pos(rsMB, S) > 1 then
|
|
begin
|
|
Mul := 1000 * 1000;
|
|
S := Copy(S, 1, Length(S) - 3);
|
|
end else
|
|
if Pos(rsGiB, S) > 1 then
|
|
begin
|
|
Mul := 1024 * 1024 * 1024;
|
|
S := Copy(S, 1, Length(S) - 4);
|
|
end else
|
|
if Pos(rsGB, S) > 1 then
|
|
begin
|
|
Mul := 1000 * 1000 * 1000;
|
|
S := Copy(S, 1, Length(S) - 3);
|
|
end else
|
|
if Pos(rsByte, S) > 1 then
|
|
S := Copy(S, 1, Length(S) - 2);
|
|
while Pos(cThousandSep, S) <> 0 do
|
|
Delete(S, Pos(cThousandSep, S), 1);
|
|
if Pos(cDecimalSep, S) <> 0 then
|
|
S[Pos(cDecimalSep, S)] := '.';
|
|
try
|
|
Val := StrToFloat(S);
|
|
except
|
|
PrintLnDbg(Format('E Error while converting %s with intermediate %s to float',
|
|
[SzStr, S]));
|
|
Result := 0;
|
|
Exit;
|
|
end;
|
|
try
|
|
Result := Round(Val * Mul);
|
|
except
|
|
PrintLnDbg(Format('E Error while converting %s: float is to big',
|
|
[SzStr, S]));
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure DecomposeVersion(const V: string; out Maj, Min, Rel, Rem: string);
|
|
var
|
|
I: integer;
|
|
Tmp: string;
|
|
begin
|
|
Rem := '';
|
|
Tmp := '';
|
|
I := Pos('.', V);
|
|
if (I = 0) then
|
|
I := Pos('_', V);
|
|
if I > 0 then
|
|
begin
|
|
Maj := Copy(V, 1, I - 1);
|
|
Tmp := Copy(V, I + 1, Length(V) - I);
|
|
if Length(V) = 0 then
|
|
begin
|
|
Min := '';
|
|
Rel := '';
|
|
Rem := '';
|
|
Exit;
|
|
end;
|
|
I := Pos('.', Tmp);
|
|
if (I = 0) then
|
|
I := Pos('_', Tmp);
|
|
if I > 0 then
|
|
begin
|
|
Min := Copy(Tmp, 1, I - 1);
|
|
Tmp := Copy(Tmp, I + 1, Length(Tmp) - I);
|
|
if Length(Tmp) = 0 then
|
|
begin
|
|
Rel := '';
|
|
Rem := '';
|
|
Exit;
|
|
end;
|
|
I := Pos('.', Tmp);
|
|
if (I = 0) then
|
|
I := Pos('_', Tmp);
|
|
if I > 0 then
|
|
begin
|
|
Rel := Copy(Tmp, 1, I - 1);
|
|
Tmp := Copy(Tmp, I + 1, Length(Tmp) - I);
|
|
if Length(Tmp) = 0 then
|
|
Exit;
|
|
Rem := Tmp;
|
|
end else
|
|
Rel := Tmp;
|
|
end else
|
|
Min := Tmp;
|
|
end else
|
|
Maj := V;
|
|
end;
|
|
|
|
|
|
function CompareVersion(const V1, V2: string): ShortInt;
|
|
var
|
|
Maj1, Maj2: string;
|
|
Min1, Min2: string;
|
|
Rel1, Rel2: string;
|
|
Rem1, Rem2: string;
|
|
begin
|
|
DecomposeVersion(V1, Maj1, Min1, Rel1, Rem1);
|
|
DecomposeVersion(V2, Maj2, Min2, Rel2, Rem2);
|
|
Result := 0;
|
|
//test remainning informations
|
|
if Rem1 > Rem2 then
|
|
Result := 1
|
|
else
|
|
if Rem1 < Rem2 then
|
|
Result := -1;
|
|
//test release (overide previous test)
|
|
if Rel1 > Rel2 then
|
|
Result := 1
|
|
else
|
|
if Rel1 < Rel2 then
|
|
Result := -1;
|
|
//test minor
|
|
if Min1 > Min2 then
|
|
Result := 1
|
|
else
|
|
if Min1 < Min2 then
|
|
Result := -1;
|
|
//test major
|
|
if Maj1 > Maj2 then
|
|
Result := 1
|
|
else
|
|
if Maj1 < Maj2 then
|
|
Result := -1;
|
|
end;
|
|
|
|
|
|
procedure LoadWindowGeometry(Form: TForm);
|
|
begin
|
|
Form.Left := iniMain.ReadInteger(Form.Name, rsConfNameLeft, Form.Left);
|
|
Form.Top := iniMain.ReadInteger(Form.Name, rsConfNameTop, Form.Top);
|
|
if Form.BorderStyle <> bsDialog then
|
|
begin
|
|
Form.Width := iniMain.ReadInteger(Form.Name, rsConfNameWidth, Form.Width);
|
|
Form.Height := iniMain.ReadInteger(Form.Name, rsConfNameHeight, Form.Height);
|
|
if iniMain.ReadBool(Form.Name, rsConfNameMaximized, False) then
|
|
Form.WindowState := wsMaximized;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure SaveWindowGeometry(Form: TForm);
|
|
var
|
|
Maxi: Boolean;
|
|
begin
|
|
iniMain.WriteInteger(Form.Name, rsConfNameLeft, Form.Left);
|
|
iniMain.WriteInteger(Form.Name, rsConfNameTop, Form.Top);
|
|
if Form.BorderStyle <> bsDialog then
|
|
begin
|
|
iniMain.WriteInteger(Form.Name, rsConfNameWidth, Form.Width);
|
|
iniMain.WriteInteger(Form.Name, rsConfNameHeight, Form.Height);
|
|
Maxi := Form.WindowState = wsMaximized;
|
|
iniMain.WriteBool(Form.Name, rsConfNameMaximized, Maxi);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure InitConf;
|
|
var
|
|
UseHome: Boolean;
|
|
ProxyTmp, Port: string;
|
|
begin
|
|
bReadOnly := False;
|
|
sConfDir := sDefaultConfDir;
|
|
if not DirectoryExists(sConfDir) then
|
|
if DirectoryIsReadOnly(ExtractFileDir(sConfDir)) then
|
|
UseHome := True
|
|
else
|
|
MkDir(sConfDir)
|
|
else
|
|
if DirectoryIsReadOnly(sConfDir) then
|
|
UseHome := True;
|
|
if UseHome then
|
|
if not DirectoryIsReadOnly(GetHomePath) then
|
|
begin
|
|
sConfDir := GetHomePath + rsFreeDesktopConfig + '/' + rsHomeConfDir; //freedestop compliant
|
|
if not DirectoryExists(sConfDir) then
|
|
begin
|
|
if not DirectoryExists(GetHomePath + rsFreeDesktopConfig) then
|
|
MkDir(GetHomePath + rsFreeDesktopConfig);
|
|
MkDir(sConfDir);
|
|
end
|
|
end else
|
|
bReadOnly := True;
|
|
iniMain := TIniFile.Create(sConfDir + '/' + sMainConfFile);
|
|
PrintLnDbg(Format(rsInfoInitConfFile, [iniMain.FileName]), vlLow);
|
|
iniRepo := TIniFile.Create(sConfDir + '/' + sRepoConfFile);
|
|
PrintLnDbg(Format(rsInfoInitConfFile, [iniRepo.FileName]), vlLow);
|
|
case GetUsedCPU of
|
|
cpu386: sArch := 'i686';
|
|
cpuX86_64: sArch := 'x86_64';
|
|
cpuArm: sArch := 'arm';
|
|
end;
|
|
//environment settings
|
|
sInstallPackage := iniMain.ReadString(rsConfSectionCommand,
|
|
rsConfNameInstallCommand, sDefaultInstallPackage);
|
|
sReinstallPackage := iniMain.ReadString(rsConfSectionCommand,
|
|
rsConfNameReinstallCommand, sDefaultReinstallPackage);
|
|
sRemovePackage := iniMain.ReadString(rsConfSectionCommand,
|
|
rsConfNameRemoveCommand, sDefaultRemovePackage);
|
|
sUpdatePackage := iniMain.ReadString(rsConfSectionCommand,
|
|
rsConfNameUpdateCommand, sDefaultUpdatePackage);
|
|
sSpackPkgDir := iniMain.ReadString(rsConfSectionPaths, rsConfNameInstPkgPath,
|
|
sDefaultSpackPkgDir);
|
|
sDwlDir := iniMain.ReadString(rsConfSectionPaths, rsConfNamePkgDownloadPath,
|
|
sDefaultDwlDir);
|
|
sRepoIndexDir := iniMain.ReadString(rsConfSectionPaths,
|
|
rsConfNameRepoDownloadPath, sDefaultRepoIndexDir);
|
|
ProxyTmp := iniMain.ReadString(rsConfSectionProxy, rsConfNameHttpProxy, '');
|
|
GetProxyInfo(ProxyTmp, sHttpProxyUser, sHttpProxyPass, sHttpProxyAddress, Port);
|
|
try
|
|
if Trim(Port) <> '' then
|
|
iHttpProxyPort := StrToInt(Port);
|
|
finally
|
|
//do nothing
|
|
end;
|
|
ProxyTmp := iniMain.ReadString(rsConfSectionProxy, rsConfNameFtpProxy, '');
|
|
GetProxyInfo(ProxyTmp, sFtpProxyUser, sFtpProxyPass, sFtpProxyAddress, Port);
|
|
try
|
|
if Trim(Port) <> '' then
|
|
iFtpProxyPort := StrToInt(Port);
|
|
finally
|
|
//do nothing
|
|
end;
|
|
//display settings
|
|
try
|
|
cThousandSep := Chr(iniMain.ReadInteger(rsConfSectionDisplay,
|
|
rsConfNameThousandsSep, Ord(' ')));
|
|
except
|
|
cThousandSep := ' ';
|
|
end;
|
|
try
|
|
cDecimalSep := Chr(iniMain.ReadInteger(rsConfSectionDisplay,
|
|
rsConfNameDecimalSep, Ord(',')));
|
|
except
|
|
cDecimalSep := ',';
|
|
end;
|
|
bUnitsAreDecimal := iniMain.ReadBool(rsConfSectionDisplay,
|
|
rsConfNameDecimalUnits, False);
|
|
bShowGrig := iniMain.ReadBool(rsConfSectionDisplay, rsConfNameShowGrid, False);
|
|
bNoColors := iniMain.ReadBool(rsConfSectionDisplay, rsConfNameNoColors, False);
|
|
end;
|
|
|
|
|
|
procedure LoadRepoSettings;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
PrintLnDbg(rsInfoLoadingRepoSettings, vlLow);
|
|
if iniRepo = nil then
|
|
Exit; //exception goes here
|
|
if slRepoList = nil then
|
|
slRepoList := TStringList.Create
|
|
else
|
|
slRepoList.Clear;
|
|
iniRepo.ReadSections(slRepoList);
|
|
for I := 0 to slRepoList.Count - 1 do
|
|
begin
|
|
if iniRepo.ReadBool(slRepoList[I], rsConfNameDefault, False) then
|
|
sDefaultRepo := slRepoList[I];
|
|
slRepoList[I] := slRepoList[I] + '=' +
|
|
iniRepo.ReadString(slRepoList[I], rsConfNameAddress, '');
|
|
end;
|
|
PrintLnDbg(Format(rsInfoDefaultRepo, [sDefaultRepo]), vlLow);
|
|
end;
|
|
|
|
|
|
procedure SaveRepoSettings;
|
|
var
|
|
I, N: Integer;
|
|
Name, Address: string;
|
|
begin
|
|
if bReadOnly then
|
|
Exit; //this should not happen: trigger an exception when conception is over
|
|
if (slRepoList = nil) or (iniRepo = nil) then
|
|
Exit; //should not happen: an exception goes here
|
|
for I := 0 to slRepoList.Count - 1 do
|
|
begin
|
|
N := Pos('=', slRepoList[I]);
|
|
if N = 0 then
|
|
Continue; //show an error message
|
|
Name := Trim(Copy(slRepoList[I], 1, N - 1));
|
|
Address := Trim(Copy(slRepoList[I], N + 1, Length(slRepoList[I]) - N));
|
|
iniRepo.WriteString(Name, rsConfNameAddress, Address);
|
|
iniRepo.WriteBool(Name, rsConfNameDefault, Name = sDefaultRepo);
|
|
end;
|
|
iniRepo.UpdateFile;
|
|
end;
|
|
|
|
function GetRepoAddress(const RepoName: string): string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to slRepoList.Count - 1 do
|
|
if Pos(RepoName, slRepoList[I]) = 1 then
|
|
Result := Copy(slRepoList[I], Pos('=', slRepoList[I]) + 1,
|
|
Length(slRepoList[I]) - Pos('=', slRepoList[I]) + 1);
|
|
end;
|
|
|
|
end.
|
|
|