lazarus/components/chmhelp/lhelp/basecontentprovider.pas

266 lines
6.7 KiB
ObjectPascal

unit BaseContentProvider;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,
// LCL
Controls,
// LazUtils
Laz2_XMLCfg, LazLoggerBase;
type
{ TBaseContentProvider }
TBaseContentProviderClass = Class of TBaseContentProvider;
TBaseContentProvider = class(TObject)
private
FOnTitleChange: TNotifyEvent;
FOnContentComplete: TNotifyEvent;
FParent: TWinControl;
FTitle: String;
FConfig: TXMLConfig;
FUpdateCount: Integer;
protected
fImageList: TImageList;
function GetTitle: String; virtual;
procedure SetTitle(const AValue: String); virtual;
function isUpdate: Boolean;
function isUpdateLast: Boolean;
public
function CanGoBack: Boolean; virtual; abstract;
function CanGoForward: Boolean; virtual; abstract;
function GetHistory: TStrings; virtual; abstract;
function LoadURL(const AURL: String; const AContext: THelpContext=-1): Boolean; virtual; abstract;
function HasLoadedData(const {%H-}AURL: String): Boolean; virtual;
procedure GoHome; virtual; abstract;
procedure GoBack; virtual; abstract;
procedure GoForward; virtual; abstract;
procedure ActivateProvider; virtual;
procedure ActivateTOCControl; virtual; abstract;
procedure ActivateIndexControl; virtual; abstract;
procedure ActivateSearchControl; virtual; abstract;
procedure BeginUpdate; virtual;
procedure EndUpdate; virtual;
procedure LoadPreferences(ACfg: TXMLConfig); virtual;
procedure SavePreferences({%H-}ACfg: TXMLConfig); virtual;
class function GetProperContentProvider(const AURL: String): TBaseContentProviderClass; virtual; abstract;
constructor Create(AParent: TWinControl; AImageList: TImageList; AUpdateCount: Integer); virtual;
destructor Destroy; override;
property Parent: TWinControl read fParent;
property Title: String read GetTitle write SetTitle;
property OnTitleChange: TNotifyEvent read FOnTitleChange write FOnTitleChange;
property OnContentComplete: TNotifyEvent read FOnContentComplete write FOnContentComplete;
end;
function GetUriPrefix( const AUri: String ):String;
function GetUrlFilePath ( const AUri: String ) : String;
function GetURIURL( const AURI: String): String;
function GetURIFileName( const AURI: String): String;
function GetUrlFile( const AUrl:String): String;
function GetUrlWoContext( const AUrl:String): String;
// returns false if the protocol has already been registered
function RegisterContentProviderClass(const Protocol: String; ContentProvider: TBaseContentProviderClass): Boolean;
// example: RegisterContentProvider('file://', TChmContentProvider);
function GetContentProvider(const Protocol: String): TBaseContentProviderClass;
function GetContentProviderList: TStringList;
implementation
var
ContentProviders: TStringList;
function GetUriPrefix ( const AUri: String ) : String;
var
xPos: Integer;
begin
Assert(AUri = Trim(AUri), 'GetUriPrefix: AUri should be trimmed.');
Result := AUri;
xPos := Pos('://', AUri);
if xPos > 0 Then
SetLength(Result, xPos+2); // Include '://' in result.
end;
function GetUriPrefixLen ( const AUri: String ) : integer;
var
xPos: Integer;
begin
xPos := Pos('://', AUri);
if xPos > 0 Then
Result := xPos+2
else
Result := Length(AUri);
end;
function GetUrlFilePath ( const AUri: String ) : String;
var
xPos: Integer;
begin
Result := Copy(AUri, GetUriPrefixLen(AUri)+1, Length(AUri));
xPos := Pos('://', Result);
if xPos > 0 then
Result := Copy(Result, 1, xPos-1);
xPos := Pos('?', Result);
if xPos > 0 then
SetLength(Result, xPos-1); // Leave parameters out.
end;
function GetURIFileName(Const AURI: String): String;
var
FileStart,
FileEnd: Integer;
begin
FileStart := Pos(':', AURI)+1;
FileEnd := Pos('::', AURI);
Result := Copy(AURI, FileStart, FileEnd-FileStart);
end;
function GetUrlFile(const AUrl: String): String;
var
xPos: Integer;
begin
Result := Copy(AUrl, GetUriPrefixLen(AUrl), Length(AUrl));
xPos := Pos('://', Result);
if xPos > 0 then
Result := Copy(Result, xPos+3, Length(Result))
else
Result:= '';
end;
function GetUrlWoContext(const AUrl: String): String;
var
xPos: Integer;
begin
Result := AUrl;
xPos := Pos('?', Result);
if xPos > 0 then
SetLength(Result, xPos-1);
xPos := Pos('#', Result);
if xPos > 0 then
SetLength(Result, xPos-1);
end;
function GetURIURL(Const AURI: String): String;
var
URLStart: Integer;
begin
URLStart := Pos('::', AURI) + 2;
Result := Copy(AURI, URLStart, Length(AURI));
end;
function RegisterContentProviderClass(const Protocol: String;
ContentProvider: TBaseContentProviderClass): Boolean;
begin
Result := False;
if GetContentProviderList.IndexOf(Protocol) > -1 then exit;
GetContentProviderList.AddObject(Protocol, TObject(ContentProvider));
Result := true;
end;
function GetContentProvider(const Protocol: String): TBaseContentProviderClass;
var
Ind: Integer;
begin
Result := nil;
Ind := GetContentProviderList.IndexOf(Protocol);
if Ind = -1 then Exit;
Result := TBaseContentProviderClass(GetContentProviderList.Objects[Ind]);
end;
function GetContentProviderList: TStringList;
begin
if ContentProviders = nil then // Singleton
ContentProviders := TStringList.Create;
Result := ContentProviders;
end;
{ TBaseContentProvider }
function TBaseContentProvider.GetTitle: String;
begin
Result := FTitle;
end;
procedure TBaseContentProvider.SetTitle(const AValue: String);
begin
FTitle := AValue;
if Assigned(FOnTitleChange) then
FOnTitleChange(Self);
end;
function TBaseContentProvider.isUpdate: Boolean;
begin
Result := FUpdateCount <> 0;
end;
function TBaseContentProvider.isUpdateLast: Boolean;
begin
Result := FUpdateCount <= 1;
end;
function TBaseContentProvider.HasLoadedData ( const AURL: String ) : Boolean;
begin
Result:= false;
end;
procedure TBaseContentProvider.ActivateProvider;
begin
//
end;
procedure TBaseContentProvider.BeginUpdate;
begin
Inc(FUpdateCount);
{$IFDEF UPDATE_CNT}
DebugLn('BeginUpdate() Cnt: ', IntToStr(FUpdateCount));
{$ENDIF}
end;
procedure TBaseContentProvider.EndUpdate;
begin
Dec(FUpdateCount);
if FUpdateCount < 0 then
FUpdateCount:=0;
{$IFDEF UPDATE_CNT}
DebugLn('EndUpdate() Cnt: ', IntToStr(FUpdateCount));
{$ENDIF}
end;
procedure TBaseContentProvider.LoadPreferences(ACfg: TXMLConfig);
begin
FConfig := ACfg;
end;
procedure TBaseContentProvider.SavePreferences(ACfg: TXMLConfig);
begin
end;
constructor TBaseContentProvider.Create(AParent: TWinControl;
AImageList: TImageList; AUpdateCount: Integer);
begin
FParent:= AParent;
FImageList:= AImageList;
FUpdateCount:= AUpdateCount;
end;
destructor TBaseContentProvider.Destroy;
begin
SavePreferences(FConfig);
inherited Destroy;
end;
initialization
finalization
ContentProviders.Free;
end.