summaryrefslogtreecommitdiff
path: root/src/corelib
diff options
context:
space:
mode:
authorgraemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf>2007-07-25 14:00:35 +0000
committergraemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf>2007-07-25 14:00:35 +0000
commita8a43f41c2a12ff4bb13a33b730edacd59fd21d5 (patch)
tree854997db2b923a055db0368347ea88fe883b1f39 /src/corelib
parentfca7347de9404de1f2940d58dae9bdda6ed52caf (diff)
downloadfpGUI-a8a43f41c2a12ff4bb13a33b730edacd59fd21d5.tar.xz
* Implemented and added a new unit that will handle command line parameters.
* Implemented and added a new CheckBox widget. (needs testing under Windows). * Made some timer changes for Windows (needs testing). * Moved the global variable for the MainForm into the TfpgApplication class. I can almost remove the gui_form requirement from GFX.
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/fpgfx.pas19
-rw-r--r--src/corelib/gdi/gfx_gdi.pas15
-rw-r--r--src/corelib/gfx_cmdlineparams.pas432
-rw-r--r--src/corelib/gfxbase.pas2
-rw-r--r--src/corelib/x11/fpgfx_package.lpk6
-rw-r--r--src/corelib/x11/fpgfx_package.pas2
-rw-r--r--src/corelib/x11/gfx_x11.pas7
7 files changed, 461 insertions, 22 deletions
diff --git a/src/corelib/fpgfx.pas b/src/corelib/fpgfx.pas
index e38c8700..434b5e40 100644
--- a/src/corelib/fpgfx.pas
+++ b/src/corelib/fpgfx.pas
@@ -184,7 +184,7 @@ type
end;
- TfpgTimer = class
+ TfpgTimer = class(TObject)
private
FEnabled: boolean;
FNextAlarm: TDateTime;
@@ -323,18 +323,21 @@ begin
for n := 1 to fpgTimers.Count do
begin
t := TfpgTimer(fpgTimers[n - 1]);
- if t.Enabled and (t.NextAlarm < dt) then begin
+ if t.Enabled and (t.NextAlarm < dt) then
+ begin
dt := t.NextAlarm;
tb := True;
end;
end;
- if tb then begin
+ if tb then
+ begin
Result := trunc(0.5 + (dt - ctime) / ONE_MILISEC);
if Result < 0 then
Result := 0;
end
- else Result := -1;
+ else
+ Result := -1;
end;
procedure TfpgTimer.SetEnabled(const AValue: boolean);
@@ -371,7 +374,7 @@ end;
procedure TfpgTimer.CheckAlarm(ctime: TDateTime);
begin
if not FEnabled then
- Exit;
+ Exit; //==>
if FNextAlarm <= ctime then
begin
@@ -380,8 +383,8 @@ begin
while FNextAlarm <= ctime do
FNextAlarm := FNextAlarm + interval * ONE_MILISEC;
- if Assigned(OnTimer) then
- OnTimer(self);
+ if Assigned(FOnTimer) then
+ FOnTimer(self);
end;
end;
@@ -526,7 +529,7 @@ end;
procedure TfpgApplication.Initialize;
begin
- {$Note remember to process parameter!! }
+ {$Note Remember to process parameters!! }
if IsInitialized then
InternalInit
else
diff --git a/src/corelib/gdi/gfx_gdi.pas b/src/corelib/gdi/gfx_gdi.pas
index 5e53cf56..b49367a4 100644
--- a/src/corelib/gdi/gfx_gdi.pas
+++ b/src/corelib/gdi/gfx_gdi.pas
@@ -160,7 +160,6 @@ type
FFocusedWindow: THANDLE;
LastClickWindow: TfpgWinHandle; // double click generation
LastWinClickTime: longword;
- FTimerWnd: HWND;
public
constructor Create(const aparams: string); override;
function DoMessagesPending: boolean;
@@ -742,19 +741,19 @@ procedure TfpgApplicationImpl.DoWaitWindowMessage(atimeoutms: integer);
var
Msg: TMsg;
timerid: longword;
- timerwnd: HWND;
+ ltimerWnd: HWND;
mp: boolean;
begin
timerid := 0;
- timerwnd := 0;
+ ltimerWnd := TfpgWindomImpl(wapplication.MainForm).WinHandle;
if (atimeoutms >= 0) and (not DoMessagesPending) then
+ begin
if atimeoutms > 0 then
- timerid := Windows.SetTimer(timerwnd, 1, atimeoutms, nil)
- {$Note This needs to be enabled again, but find a butter solution.}
- // timerwnd := fpgMainForm.WinHandle;
+ timerid := Windows.SetTimer(ltimerWnd, 1, atimeoutms, nil)
else
Exit; // handling waiting timeout
+ end;
{$Note Incorporate Felipe's code from previous fpGUI in here. It handles WinCE and Windows just fine. }
if (GetVersion() < $80000000) then
@@ -764,8 +763,8 @@ begin
Windows.DispatchMessage(@msg);
- if timerid > 0 then
- Windows.KillTimer(timerwnd, 1);
+ if timerid <> 0 then
+ Windows.KillTimer(ltimerWnd, 1); // same IDEvent as used in SetTimer
end;
procedure TfpgApplicationImpl.DoFlush;
diff --git a/src/corelib/gfx_cmdlineparams.pas b/src/corelib/gfx_cmdlineparams.pas
new file mode 100644
index 00000000..1e833f81
--- /dev/null
+++ b/src/corelib/gfx_cmdlineparams.pas
@@ -0,0 +1,432 @@
+{
+ fpGUI - Free Pascal GUI Library
+
+ Unit to handle command line processing
+
+ Copyright (C) 2007 See the file AUTHORS.txt, included in this
+ distribution, for details of the copyright.
+
+ See the file COPYING.modifiedLGPL, included in this distribution,
+ for details about redistributing fpGUI.
+
+ 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 gfx_cmdlineparams;
+
+{$mode objfpc}{$H+}
+
+interface
+uses
+ Classes;
+
+const
+ ctiCommandLineParamPrefix = '-';
+
+type
+
+ TGfxCommandLineParams = class(TObject)
+ private
+ FsParams: string;
+ FslParams: TStringList;
+ procedure ReadParams;
+ function WordExtract(const AInput: string; const APos: integer; const ADelims: string): string;
+ function WordCount(const AStrToProcess: string; ADelims: string): integer;
+ function WordPosition(const AN: integer; const AStr: string; ADelims: string): integer;
+ function ExtractChar(const AValue: string; const APos: integer): char;
+ function CharInStr(const AChr: char; const AStr: string): boolean;
+ function StripLeadingDelims(const AStrToProcess: string; ADelims: string): string;
+ function StripTrailingDelims(const AStrToProcess: string; ADelims: string): string;
+ function NumToken(const AValue, AToken: string): integer;
+ function Token(const AValue, AToken: string; const APos: integer): string;
+ function StrTran(AValue, ADel, AIns: string): string;
+ public
+ constructor Create;
+ destructor Destroy; override;
+ function IsParam(const AParam: string): boolean; overload;
+ function IsParam(const AParams: array of string): boolean; overload;
+ function GetParam(const AParam: string): string;
+ property Params: TStringList read FslParams;
+ property AsString: string read FsParams;
+ end;
+
+
+// Singleton
+function gCommandLineParams: TGfxCommandLineParams;
+
+
+implementation
+
+uses
+ SysUtils;
+
+var
+ uCommandLineParams: TGfxCommandLineParams;
+
+// Singleton
+function gCommandLineParams: TGfxCommandLineParams;
+begin
+ if uCommandLineParams = nil then
+ uCommandLineParams := TGfxCommandLineParams.Create;
+ result := uCommandLineParams;
+end;
+
+{ TGfxCommandLineParams }
+
+constructor TGfxCommandLineParams.Create;
+begin
+ inherited;
+ FslParams := TStringList.Create;
+ ReadParams;
+end;
+
+destructor TGfxCommandLineParams.destroy;
+begin
+ FslParams.Free;
+ inherited;
+end;
+
+function TGfxCommandLineParams.GetParam(const AParam: string): string;
+begin
+ result := FslParams.Values[ upperCase(AParam)];
+end;
+
+function TGfxCommandLineParams.IsParam(const AParam: string): boolean;
+var
+ i: integer;
+begin
+ result := false;
+ for i := 0 to FslParams.Count - 1 do begin
+ if FslParams.Names[i] = upperCase(AParam) then begin
+ result := true;
+ break; //==>
+ end;
+ end;
+end;
+
+function TGfxCommandLineParams.IsParam(const AParams: array of string): boolean;
+var
+ i: integer;
+begin
+ result := false;
+ for i := Low(AParams) to High(AParams) do
+ if IsParam(AParams[i]) then
+ begin
+ result := true;
+ Exit; //==>
+ end;
+end;
+
+procedure TGfxCommandLineParams.ReadParams;
+var
+ i: integer;
+ j: integer;
+ lsNameValue: string;
+ lsValue: string;
+ lsName: string;
+const
+ cDelim = ' ';
+begin
+ lsValue := '';
+ FsParams := '';
+ j := ParamCount;
+ for i := 1 to j do begin
+ if FsParams <> '' then FsParams := FsParams + cDelim;
+ FsParams := FsParams + ParamStr(i);
+ end ;
+
+ j := WordCount(FsParams, ctiCommandLineParamPrefix);
+ for i := 1 to j do begin
+ lsNameValue := WordExtract(FsParams, i, ctiCommandLineParamPrefix);
+ lsName := Token(lsNameValue, cDelim, 1);
+ lsValue := copy(lsNameValue, length(lsName) + 1,
+ length(FsParams) - length(lsValue));
+
+ lsValue := Trim(lsValue);
+ lsName := StrTran(lsName, ctiCommandLineParamPrefix, '');
+ lsName := upperCase(lsName);
+
+ FslParams.Add(lsName + '=' + lsValue);
+ end;
+end;
+
+function TGfxCommandLineParams.StrTran(AValue, ADel, AIns: string): string;
+var
+ i: integer;
+ sToChange: string;
+begin
+ result := '';
+ sToChange := AValue;
+ i := pos(ADel, sToChange);
+ while i <> 0 do
+ begin
+ result := result + copy(sToChange, 1, i-1) + AIns;
+ delete(sToChange, 1, i+length(ADel)-1);
+ i := pos(ADel, sToChange);
+ end;
+ result := result + sToChange;
+end;
+
+function TGfxCommandLineParams.NumToken(const AValue, AToken: string): integer;
+var
+ i, iCount: integer;
+ lsValue: string;
+begin
+ result := 0;
+ if AValue = '' then
+ Exit; //==>
+
+ iCount := 0;
+ lsValue := AValue;
+ i := pos(AToken, lsValue);
+ while i <> 0 do
+ begin
+ delete(lsValue, i, length(AToken));
+ inc(iCount);
+ i := pos(AToken, lsValue);
+ end;
+ result := iCount + 1;
+end;
+
+function TGfxCommandLineParams.Token(const AValue, AToken: string;
+ const APos: integer): string;
+var
+ i, iCount, iNumToken: integer;
+ lsValue: string;
+begin
+ result := '';
+
+ iNumToken := NumToken(AValue, AToken);
+ if APos = 1 then
+ begin
+ if pos(AToken, AValue) = 0 then
+ result := AValue
+ else
+ result := copy(AValue, 1, pos(AToken, AValue)-1);
+ end
+ else if (iNumToken < APos-1) or (APos<1) then
+ begin
+ result := '';
+ end
+ else
+ begin
+ { Remove leading blocks }
+ iCount := 1;
+ lsValue := AValue;
+ i := pos(AToken, lsValue);
+ while (i<>0) and (iCount<APos) do
+ begin
+ delete(lsValue, 1, i + length(AToken) - 1);
+ inc(iCount);
+ i := pos(AToken, lsValue);
+ end;
+
+ if (i=0) and (iCount=APos) then
+ result := lsValue
+ else if (i=0) and (iCount<>APos) then
+ result := ''
+ else
+ result := copy(lsValue, 1, i-1);
+ end;
+end;
+
+function TGfxCommandLineParams.WordExtract(const AInput: string;
+ const APos: integer; const ADelims: string): string;
+var
+ iStart: integer;
+ i: integer;
+ iLen: integer;
+begin
+ result := '';
+
+ // Find the starting pos of the Nth word
+ iStart := WordPosition(APos, AInput, ADelims);
+
+ if iStart <> 0 then
+ begin
+ i := iStart;
+ iLen := length(AInput);
+ // Build up result until we come to our next wordDelim
+ // while (i <= iLen) and not(S[i] in ADelims) do begin
+ while (i <= iLen) and not(CharInStr(ExtractChar(AInput, i), ADelims)) do
+ begin
+ result := result + ExtractChar(AInput, i);
+ inc(i);
+ end;
+ end;
+end;
+
+function TGfxCommandLineParams.WordPosition(const AN: integer;
+ const AStr: string; ADelims: string): integer;
+var
+ lCount: integer;
+ lI: Word;
+ lSLen: integer;
+begin
+ lCount := 0;
+ lI := 1;
+ Result := 0;
+ lSLen := length(AStr);
+
+ while (lI <= lSLen) and (lCount <> AN) do
+ begin
+ while (lI <= lSLen) and (CharInStr(ExtractChar(AStr, lI), ADelims)) do
+ begin
+ Inc(lI);
+ end;
+
+ // if we're not beyond end of S, we're at the start of a word
+ if lI <= lSLen then
+ begin
+ Inc(lCount);
+ end;
+
+ // if not finished, find the end of the current word
+ if lCount <> AN then
+ begin
+ while (lI <= lSLen) and not(CharInStr(ExtractChar(AStr, lI), ADelims)) do
+ begin
+ Inc(lI);
+ end;
+ end
+ else
+ begin
+ Result := lI;
+ end;
+ end;
+end;
+
+function TGfxCommandLineParams.ExtractChar(const AValue: string;
+ const APos: integer): char;
+var
+ lResult: string;
+begin
+ if APos > length(AValue) then
+ begin
+ result := ' ';
+ exit;
+ end;
+ lResult := copy(AValue, APos, 1);
+ result := lResult[1];
+end;
+
+function TGfxCommandLineParams.StripLeadingDelims(const AStrToProcess: string;
+ ADelims: string): string;
+var
+ i: integer;
+ lCharCurrent: char;
+begin
+ result := AStrToProcess;
+ // Loop through each char in the string
+ for i := 1 to length(AStrToProcess) do
+ begin
+ // Extract the current character
+ lCharCurrent := ExtractChar(AStrToProcess, i);
+
+ // Is this character a NON word delim?, then we have found the body of the string.
+ if not CharInStr(lCharCurrent, ADelims) then
+ begin
+ result := copy(AStrToProcess, i,
+ length(AStrToProcess) - i + 1);
+ exit; //==>
+ // The current char is a word delim, but we are at the end of the string -
+ // so no words
+ end
+ else
+ begin
+ if i = length(AStrToProcess) then
+ begin
+ result := '';
+ end;
+ end;
+ end;
+end;
+
+// Strip any trailing ADelims
+function TGfxCommandLineParams.StripTrailingDelims(const AStrToProcess: string;
+ ADelims: string): string;
+var
+ i: integer;
+ lCharCurrent: char;
+begin
+ result := AStrToProcess;
+ // Loop through each char in the string
+ for i := length(AStrToProcess) downto 1 do
+ begin
+ // Extract the current character
+ lCharCurrent := ExtractChar(AStrToProcess, i);
+
+ // Is this character a NON word delim?, then we have found the body of the string.
+ if not CharInStr(lCharCurrent, ADelims) then
+ begin
+ result := copy(AStrToProcess, 1, i);
+ exit; //==>
+ // The current char is a word delim, but we are at the beginning of the string -
+ // so no words
+ end
+ else
+ begin
+ if i = length(AStrToProcess) then
+ begin
+ result := '';
+ end;
+ end;
+ end;
+end;
+
+// Given a set of word delimiters, return number of words in S
+function TGfxCommandLineParams.WordCount(const AStrToProcess: string;
+ ADelims: string): integer;
+var
+ i: integer;
+ lCharLast: char;
+ lCharCurrent: char;
+ lStrToProcess: string;
+begin
+ // Strip any leading ADelims
+ lStrToProcess := StripLeadingDelims(AStrToProcess, ADelims);
+ lStrToProcess := StripTrailingDelims(lStrToProcess, ADelims);
+
+ // If lStrToProcess is empty, then there are no words
+ if lStrToProcess = '' then
+ begin
+ result := 0;
+ Exit; //==>
+ end;
+
+ // lStrToProcess is not empty, therefore there must be at least one word
+ // Every wordDelim we find equals another word:
+ // 0 word delim := 1 word
+ // 1 word delim := 2 words...
+ result := 1;
+
+ // lCharLast is used to check for more than 1 wordDelim together
+ lCharLast := #0;
+
+ for i := 1 to length(lStrToProcess) do
+ begin
+ lCharCurrent := ExtractChar(lStrToProcess, i);
+ if CharInStr(lCharCurrent, ADelims) and not(CharInStr(lCharLast, ADelims)) then
+ begin
+ inc(result);
+ end;
+ lCharLast := lCharCurrent;
+ end;
+end;
+
+// Is AChr in the string AStr ?
+function TGfxCommandLineParams.CharInStr(const AChr: char; const AStr: string): boolean;
+begin
+ result := pos(AChr, AStr) <> 0;
+end;
+
+
+initialization
+
+finalization
+ uCommandLineParams.Free;
+
+end.
+
diff --git a/src/corelib/gfxbase.pas b/src/corelib/gfxbase.pas
index 5add81ad..28149f8f 100644
--- a/src/corelib/gfxbase.pas
+++ b/src/corelib/gfxbase.pas
@@ -349,6 +349,7 @@ type
TfpgApplicationBase = class(TObject)
private
+ FMainForm: TfpgWindowBase;
FTopModalForm: TfpgWindowBase;
protected
FIsInitialized: Boolean;
@@ -356,6 +357,7 @@ type
constructor Create(const AParams: string); virtual; abstract;
property IsInitialized: boolean read FIsInitialized;
property TopModalForm: TfpgWindowBase read FTopModalForm write FTopModalForm;
+ property MainForm: TfpgWindowBase read FMainForm write FMainForm;
end;
diff --git a/src/corelib/x11/fpgfx_package.lpk b/src/corelib/x11/fpgfx_package.lpk
index 1521ea5a..77167bd2 100644
--- a/src/corelib/x11/fpgfx_package.lpk
+++ b/src/corelib/x11/fpgfx_package.lpk
@@ -24,7 +24,7 @@
<License Value="Modified LGPL
"/>
<Version Minor="5"/>
- <Files Count="10">
+ <Files Count="11">
<Item1>
<Filename Value="x11_xft.pas"/>
<UnitName Value="x11_xft"/>
@@ -65,6 +65,10 @@
<Filename Value="../gfx_extinterpolation.pas"/>
<UnitName Value="gfx_extinterpolation"/>
</Item10>
+ <Item11>
+ <Filename Value="../gfx_cmdlineparams.pas"/>
+ <UnitName Value="gfx_cmdlineparams"/>
+ </Item11>
</Files>
<RequiredPkgs Count="1">
<Item1>
diff --git a/src/corelib/x11/fpgfx_package.pas b/src/corelib/x11/fpgfx_package.pas
index 0fc83352..7fa2a8c3 100644
--- a/src/corelib/x11/fpgfx_package.pas
+++ b/src/corelib/x11/fpgfx_package.pas
@@ -8,7 +8,7 @@ interface
uses
x11_xft, x11_keyconv, gfxbase, gfx_x11, fpgfx, gfx_stdimages, gfx_imgfmt_bmp,
- gfx_widget, gfx_UTF8utils, gfx_extinterpolation;
+ gfx_widget, gfx_UTF8utils, gfx_extinterpolation, gfx_cmdlineparams;
implementation
diff --git a/src/corelib/x11/gfx_x11.pas b/src/corelib/x11/gfx_x11.pas
index 1935ff57..35564db6 100644
--- a/src/corelib/x11/gfx_x11.pas
+++ b/src/corelib/x11/gfx_x11.pas
@@ -621,10 +621,9 @@ begin
repeat
if (atimeoutms >= 0) and (XPending(display) <= 0) then
begin
- // waiting some event for the given timeout
-
- // this Select handles only the first 256 file descriptors
- // poll would be better but FPC has no official poll interface (if I'm right)
+ // Some event is waiting for the given timeout.
+ // This Select handles only the first 256 file descriptors.
+ // Poll would be better but FPC has no official poll interface (if I'm right)
fpFD_ZERO(rfds);
fpFD_SET(xfd, rfds);
r := fpSelect(xfd + 1, @rfds, nil, nil, atimeoutms);