major changes to lhelp - uses lnet now

git-svn-id: trunk@10021 -
This commit is contained in:
andrew 2006-10-01 23:13:07 +00:00
parent ef4c40fb36
commit 1e48c1f2b4
12 changed files with 1530 additions and 897 deletions

5
.gitattributes vendored
View File

@ -23,17 +23,22 @@ components/chmhelp/democontrol/unit1.lfm svneol=native#text/plain
components/chmhelp/democontrol/unit1.lrs svneol=native#text/plain
components/chmhelp/democontrol/unit1.pas svneol=native#text/plain
components/chmhelp/lhelp/back.xpm svneol=native#text/plain
components/chmhelp/lhelp/basecontentprovider.pas svneol=native#text/plain
components/chmhelp/lhelp/chmcontentprovider.pas svneol=native#text/plain
components/chmhelp/lhelp/chmdataprovider.pas svneol=native#text/plain
components/chmhelp/lhelp/chmpopup.lfm svneol=native#text/plain
components/chmhelp/lhelp/chmpopup.lrs svneol=native#text/plain
components/chmhelp/lhelp/chmpopup.pas svneol=native#text/plain
components/chmhelp/lhelp/chmspecialparser.pas svneol=native#text/plain
components/chmhelp/lhelp/filecontentprovider.pas svneol=native#text/plain
components/chmhelp/lhelp/httpcontentprovider.pas svneol=native#text/plain
components/chmhelp/lhelp/lhelp.lpi svneol=native#text/plain
components/chmhelp/lhelp/lhelp.lpr svneol=native#text/plain
components/chmhelp/lhelp/lhelpcontrol.pas svneol=native#text/plain
components/chmhelp/lhelp/lhelpcore.lfm svneol=native#text/plain
components/chmhelp/lhelp/lhelpcore.lrs svneol=native#text/plain
components/chmhelp/lhelp/lhelpcore.pas svneol=native#text/plain
components/chmhelp/lhelp/lnethttpdataprovider.pas svneol=native#text/plain
components/chmhelp/packages/chm/chmbase.pas svneol=native#text/plain
components/chmhelp/packages/chm/chmpkg.lpk svneol=native#text/plain
components/chmhelp/packages/chm/chmpkg.pas svneol=native#text/plain

View File

@ -0,0 +1,80 @@
unit BaseContentProvider;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Controls;
type
{ TBaseContentProvider }
TBaseContentProviderClass = Class of TBaseContentProvider;
TBaseContentProvider = class(TObject)
private
fParent: TWinControl;
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;
procedure GoHome; virtual; abstract;
procedure GoBack; virtual; abstract;
procedure GoForward; virtual; abstract;
class function GetProperContentProvider(const AURL: String): TBaseContentProviderClass; virtual; abstract;
constructor Create(AParent: TWinControl); virtual;
property Parent: TWinControl read fParent;
end;
// returns false if the protocol has already been registered
function RegisterContentProvider(const Protocol: String; ContentProvider: TBaseContentProviderClass): Boolean;
// example: RegisterContentProvider('chm://', TChmContentProvider);
function GetContentProvider(const Protocol: String): TBaseContentProviderClass;
implementation
var
ContentProviders: TStringList;
function RegisterContentProvider(const Protocol: String;
ContentProvider: TBaseContentProviderClass): Boolean;
begin
Result := False;
if ContentProviders.IndexOf(Protocol) > -1 then exit;
ContentProviders.AddObject(Protocol, TObject(ContentProvider));
end;
function GetContentProvider(const Protocol: String): TBaseContentProviderClass;
var
fIndex: Integer;
begin
Result := nil;
fIndex := ContentProviders.IndexOf(Protocol);
if fIndex = -1 then Exit;
Result := TBaseContentProviderClass(ContentProviders.Objects[fIndex]);
end;
{ TBaseContentProvider }
constructor TBaseContentProvider.Create(AParent: TWinControl);
begin
fParent:= AParent;
end;
initialization
ContentProviders := TStringList.Create;
finalization
ContentProviders.Free;
end.

View File

@ -0,0 +1,513 @@
unit chmcontentprovider;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, StdCtrls, ExtCtrls, ComCtrls, Controls, Buttons, Menus,
BaseContentProvider, FileContentProvider, IpHtml, ChmReader, ChmDataProvider;
type
{ TChmContentProvider }
TChmContentProvider = class(TFileContentProvider)
private
fTabsControl: TPageControl;
fContentsTab: TTabSheet;
fContentsPanel: TPanel;
fContentsTree: TTreeView;
fIndexTab: TTabSheet;
fIndexView: TListView;
fSearchTab: TTabSheet;
fKeywordLabel: TLabel;
fKeywordCombo: TComboBox;
fSearchBtn: TButton;
fResultsLabel: TLabel;
fSearchResults: TListBox;
fSplitter: TSplitter;
fHtml: TIpHtmlPanel;
fPopUp: TPopUpMenu;
fChmDataProvider: TIpChmDataProvider;
fStatusBar: TStatusBar;
fContext: THelpContext;
protected
fIsUsingHistory: Boolean;
fChms: TChmFileList;
fHistory: TStringList;
fHistoryIndex: Integer;
fStopTimer: Boolean;
fFillingToc: Boolean;
procedure AddHistory(URL: String);
procedure DoOpenChm(AFile: String);
procedure DoCloseChm;
procedure DoLoadContext(Context: THelpContext);
procedure DoLoadUrl(Url: String; AChm: TChmReader = nil);
procedure DoError(Error: Integer);
procedure NewChmOpened(ChmFileList: TChmFileList; Index: Integer);
procedure FillTOCTimer(Sender: TObject);
procedure IpHtmlPanelDocumentOpen(Sender: TObject);
procedure IpHtmlPanelHotChange(Sender: TObject);
procedure PopupCopyClick(Sender: TObject);
procedure ContentsTreeSelectionChanged(Sender: TObject);
procedure IndexViewSelectItem(Sender: TObject; Item: TListItem;
Selected: Boolean);
procedure ViewMenuContentsClick(Sender: TObject);
procedure SetTitle(const ATitle: String);
public
function CanGoBack: Boolean; override;
function CanGoForward: Boolean; override;
function GetHistory: TStrings; override;
function LoadURL(const AURL: String; const AContext: THelpContext=-1): Boolean; override;
procedure GoHome; override;
procedure GoBack; override;
procedure GoForward; override;
class function GetProperContentProvider(const AURL: String): TBaseContentProviderClass; override;
constructor Create(AParent: TWinControl); override;
destructor Destroy; override;
end;
TTocTimer = class(TIdleTimer)
private
fChm: TChmReader;
end;
implementation
uses ChmSpecialParser;
{ TChmContentProvider }
procedure TChmContentProvider.AddHistory(URL: String);
begin
if fHistoryIndex < fHistory.Count then begin
while fHistory.Count-1 > fHistoryIndex do
fHistory.Delete(fHistory.Count-1);
end;
fHistory.Add(URL);
Inc(fHistoryIndex);
end;
procedure TChmContentProvider.DoOpenChm(AFile: String);
var
Stream: TStream;
Timer: TTimer;
begin
if (fChms <> nil) and fChms.IsAnOpenFile(AFile) then Exit;
DoCloseChm;
if not FileExists(AFile) or DirectoryExists(AFile) then
begin
Exit;
end;
try
fChms := TChmFileList.Create(AFile);
if Not(fChms.Chm[0].IsValidFile) then begin
FreeAndNil(fChms);
//DoError(INVALID_FILE_TYPE);
Exit;
end;
TIpChmDataProvider(fHtml.DataProvider).Chm := fChms;
except
FreeAndNil(fChms);
//DoError(INVALID_FILE_TYPE);
Exit;
end;
if fChms = nil then Exit;
fChms.OnOpenNewFile := @NewChmOpened;
fHistoryIndex := -1;
fHistory.Clear;
// Code Here has been moved to the OpenFile handler
//FileMenuCloseItem.Enabled := True;
if fChms.Chm[0].Title <> '' then SetTitle(fChms.Chm[0].Title);
end;
procedure TChmContentProvider.DoCloseChm;
begin
fStopTimer := True;
if fChms<>nil then begin
FreeAndNil(fChms);
end;
end;
procedure TChmContentProvider.DoLoadContext(Context: THelpContext);
var
Str: String;
begin
if fChms = nil then exit;
Str := fChms.Chm[0].GetContextUrl(Context);
if Str <> '' then DoLoadUrl(Str);
end;
procedure TChmContentProvider.DoLoadUrl(Url: String; AChm: TChmReader = nil);
begin
if (fChms = nil) and (AChm = nil) then exit;
if fChms.ObjectExists(Url, AChm) = 0 then Exit;
fIsUsingHistory := True;
fHtml.OpenURL(Url);
TIpChmDataProvider(fHtml.DataProvider).CurrentPath := ExtractFileDir(URL)+'/';
AddHistory(Url);
end;
procedure TChmContentProvider.DoError(Error: Integer);
begin
//what to do with these errors?
//INVALID_FILE_TYPE;
end;
procedure TChmContentProvider.NewChmOpened(ChmFileList: TChmFileList;
Index: Integer);
var
TImer: TTocTimer;
Stream: TMemoryStream;
begin
if Index = 0 then begin
fContentsTree.Items.Clear;
if fContext > -1 then begin
DoLoadContext(fContext);
fContext := -1;
end
else if ChmFileList.Chm[Index].DefaultPage <> '' then begin
DoLoadUrl(ChmFileList.Chm[Index].DefaultPage);
end;
end;
if ChmFileList.Chm[Index].Title = '' then
ChmFileList.Chm[Index].Title := ExtractFileName(ChmFileList.FileName[Index]);
// Fill the table of contents. This actually works very well
Timer := TTocTimer.Create(fHtml);
if ChmFileList.ObjectExists(ChmFileList.Chm[Index].TOCFile) > 25000 then
Timer.Interval := 500
else
Timer.Interval := 5;
Timer.OnTimer := @FillTOCTimer;
Timer.fChm := ChmFileList.Chm[Index];
Timer.Enabled := True;
fContentsTree.Visible := False;
Stream := fchms.GetObject(ChmFileList.Chm[Index].IndexFile);
if Stream <> nil then begin
Stream.position := 0;
with TIndexFiller.Create(fIndexView, Stream) do begin;
DoFill;
Free;
end;
Stream.Free;
end;
end;
procedure TChmContentProvider.FillTOCTimer(Sender: TObject);
var
Stream: TMemoryStream;
fChm: TChmReader;
ParentNode: TTreeNode;
begin
if fFillingToc = True then begin
TTimer(Sender).Interval := 40;
exit;
end;
fFillingToc := True;
fStopTimer := False;
fContentsTree.Visible := False;
fChm := TTocTimer(Sender).fChm;
TTocTimer(Sender).Free;
if fChm <> nil then begin
Stream := TMemoryStream(fchm.GetObject(fChm.TOCFile));
if Stream <> nil then begin
Stream.position := 0;
ParentNode := fContentsTree.Items.AddChildObject(nil, fChm.Title, fChm);
with TContentsFiller.Create(fContentsTree, Stream, @fStopTimer) do begin
DoFill(ParentNode);
Free;
end;
end;
Stream.Free;
end;
if ParentNode.Index = 0 then ParentNode.Expanded := True;
fContentsTree.Visible := True;
fFillingToc := False;
fStopTimer := False;
end;
procedure TChmContentProvider.IpHtmlPanelDocumentOpen(Sender: TObject);
begin
// StatusBar1.Panels.Items[1] := fHtml.DataProvider.;
if fIsUsingHistory = False then
AddHistory(TIpChmDataProvider(fHtml.DataProvider).CurrentPage)
else fIsUsingHistory := False;
end;
procedure TChmContentProvider.IpHtmlPanelHotChange(Sender: TObject);
begin
fStatusBar.SimpleText := fHtml.HotURL;
end;
procedure TChmContentProvider.PopupCopyClick(Sender: TObject);
begin
fHtml.CopyToClipboard;
end;
procedure TChmContentProvider.ContentsTreeSelectionChanged(Sender: TObject);
var
ATreeNode: TContentTreeNode;
ARootNode: TTreeNode;
fChm: TChmReader = nil;
begin
if (fContentsTree.Selected = nil) or not(fContentsTree.Selected is TContentTreeNode) then Exit;
ATreeNode := TContentTreeNode(fContentsTree.Selected);
//find the chm associated with this branch
ARootNode := ATreeNode.Parent;
while ARootNode.Parent <> nil do
ARootNode := ARootNode.Parent;
fChm := TChmReader(ARootNode.Data);
if ATreeNode.Url <> '' then begin
DoLoadUrl(ATreeNode.Url, fChm);
end;
end;
procedure TChmContentProvider.IndexViewSelectItem(Sender: TObject;
Item: TListItem; Selected: Boolean);
var
RealItem: TIndexItem;
begin
if not Selected then Exit;
RealItem := TIndexItem(Item);
if RealItem.Url <> '' then begin
DoLoadUrl(RealItem.Url);
end;
end;
procedure TChmContentProvider.ViewMenuContentsClick(Sender: TObject);
begin
//TMenuItem(Sender).Checked := not TMenuItem(Sender).Checked;
//fSplitter.Visible := TMenuItem(Sender).Checked;
//TabPanel.Visible := Splitter1.Visible;
end;
procedure TChmContentProvider.SetTitle(const ATitle: String);
begin
if fHtml.Parent = nil then exit;
TTabSheet(fHtml.Parent).Caption := ATitle;
end;
function TChmContentProvider.CanGoBack: Boolean;
begin
Result := fHistoryIndex > 0;
end;
function TChmContentProvider.CanGoForward: Boolean;
begin
Result := fHistoryIndex < fHistory.Count-1
end;
function TChmContentProvider.GetHistory: TStrings;
begin
//Result:=inherited GetHistory;
end;
function TChmContentProvider.LoadURL(const AURL: String; const AContext: THelpContext=-1): Boolean;
var
fFile: String;
fURL: String = '';
fPos: Integer;
begin
Result := False;
fFile := Copy(AUrl,8, Length(AURL));
fPos := Pos('://', fFile);
if fPos > 0 then begin
fURL := Copy(fFile, fPos+3, Length(fFIle));
fFile := Copy(fFIle, 1, fPos-1);
end;
//writeln(fURL);
//if fChms = nil then
DoOpenChm(fFile);
if fURL <> '' then
DoLoadUrl(fUrl)
else
GoHome;
Result := True;
end;
procedure TChmContentProvider.GoHome;
begin
if (fChms <> nil) and (fChms.Chm[0].DefaultPage <> '') then begin
DoLoadUrl(fChms.Chm[0].DefaultPage);
end;
end;
procedure TChmContentProvider.GoBack;
begin
if CanGoBack then begin
Dec(fHistoryIndex);
fIsUsingHistory:=True;
fHtml.OpenURL(fHistory.Strings[fHistoryIndex]);
end;
end;
procedure TChmContentProvider.GoForward;
begin
if CanGoForward then begin
Inc(fHistoryIndex);
fIsUsingHistory:=True;
fHtml.OpenURL(fHistory.Strings[fHistoryIndex]);
end;
end;
class function TChmContentProvider.GetProperContentProvider(const AURL: String
): TBaseContentProviderClass;
begin
Result:=TChmContentProvider;
end;
constructor TChmContentProvider.Create(AParent: TWinControl);
begin
inherited Create(AParent);
fHistory := TStringList.Create;
fTabsControl := TPageControl.Create(AParent);
with fTabsControl do begin
Width := 215;
Align := alLeft;
Parent := AParent;
Visible := True;
end;
fContentsTab := TTabSheet.Create(fTabsControl);
with fContentsTab do begin
Caption := 'Contents';
Parent := fTabsControl;
Visible := True;
end;
fContentsPanel := TPanel.Create(fContentsTab);
with fContentsPanel do begin
Parent := fContentsTab;
Align := alClient;
Caption := 'Table of Contents Loading. Please Wait...';
Visible := True;
end;
fContentsTree := TTreeView.Create(fContentsPanel);
with fContentsTree do begin
Parent := fContentsPanel;
Align := alClient;
Visible := True;
OnSelectionChanged := @ContentsTreeSelectionChanged;
end;
fIndexTab := TTabSheet.Create(fTabsControl);
with fIndexTab do begin
Caption := 'Index';
Parent := fTabsControl;
Visible := True;
end;
fIndexView := TListView.Create(fIndexTab);
with fIndexView do begin
Parent := fIndexTab;
Align := alClient;
Visible := True;
OnSelectItem := @IndexViewSelectItem;
end;
{
fSearchTab := TTabSheet.Create(fTabsControl);
with fSearchTab do begin
Caption := 'Search';
Parent := fTabsControl;
Visible := True;
BorderSpacing.Around := 3;
end;
fKeywordLabel := TLabel.Create(fSearchTab);
with fKeywordLabel do begin
Parent := fSearchTab;
Top := 5;
Caption := 'Keyword:';
Left := 0;
AutoSize := True;
end;
fKeywordCombo := TComboBox.Create(fSearchTab);
with fKeywordCombo do begin
Parent := fSearchTab;
Top := fKeywordLabel.Top + fKeywordLabel.Height + 5;
Left := 0;
Width := fSearchTab.ClientWidth;
Anchors := [akLeft, akRight, akTop];
end;
fSearchBtn := TButton.Create(fSearchTab);
with fSearchBtn do begin
Parent := fSearchTab
Top := fKeywordCombo.Top + fKeywordCombo.Height + 5;
Width := 105;
Left := fSearchTab.ClientWidth - Width;
Anchors := [akTop, akRight]
end;
fResultsLabel := TLabel.Create(fSearchTab);
with fResultsLabel do begin
Parent := fSearchTab;
Top := fSearchBtn.Top + fSearchBtn.Height + 15;
Caption := 'Search Results:';
Left := 0;
AutoSize := True;
end;
fSearchResults := TListBox.Create(fSearchTab);
with fSearchResults do begin
Parent := fSearchTab;
Top := fResultsLabel.Top + fResultsLabel.Height + 5;
Height := fSearchTab.ClientHeight - Top;
Anchors := [akTop, akBottom, akLeft, akRight];
end;
}
fSplitter := TSplitter.Create(Parent);
with fSplitter do begin
Align := alLeft;
Parent := AParent
end;
fPopUp := TPopupMenu.Create(fHtml);
fPopUp.Items.Add(TMenuItem.Create(fPopup));
with fPopUp.Items.Items[0] do begin
Caption := 'Copy';
OnClick := @PopupCopyClick;
end;
fChmDataProvider := TIpChmDataProvider.Create(fChms);
fHtml := TIpHtmlPanel.Create(Parent);
with fHtml do begin
DataProvider := fChmDataProvider;
OnDocumentOpen := @IpHtmlPanelDocumentOpen;
OnHotChange := @IpHtmlPanelHotChange;
PopupMenu := fPopUp;
Parent := AParent;
Align := alClient;
end;
fStatusBar := TStatusBar.Create(AParent);
with fStatusBar do begin
Parent := AParent;
Align := alBottom;
SimplePanel := True;
end;
end;
destructor TChmContentProvider.Destroy;
begin
DoCloseChm;
inherited Destroy;
end;
initialization
RegisterFileType('.chm', TChmContentProvider);
end.

View File

@ -133,6 +133,7 @@ begin
//DebugLn('Getting Image ',(Url));
FileExt := ExtractFileExt(URL);
if FileExt[1] = '.' then Delete(FileExt,1,1);
ImageClass := GetFPImageReaderForFileExtension(FileExt);
if ImageClass <> nil then begin

View File

@ -0,0 +1,116 @@
unit filecontentprovider;
{$mode objfpc}{$H+}
interface
uses
Classes, Controls, SysUtils, BaseContentProvider;
type
{ TFileContentProvider }
TFileContentProvider = class(TBaseContentProvider)
private
public
function CanGoBack: Boolean; override;
function CanGoForward: Boolean; override;
function GetHistory: TStrings; override;
function LoadURL(const AURL: String; const AContext: THelpContext=-1): Boolean; override;
procedure GoHome; override;
procedure GoBack; override;
procedure GoForward; override;
class function GetProperContentProvider(const AURL: String): TBaseContentProviderClass; override;
constructor Create(AParent: TWinControl); override;
end;
function RegisterFileType(const FileType: String; ContentProvider: TBaseContentProviderClass): Boolean;
implementation
var
FileContentProviders: TStringList;
function RegisterFileType(const FileType: String;
ContentProvider: TBaseContentProviderClass): Boolean;
begin
Result := False;
if FileContentProviders.IndexOf(FileType) > -1 then exit;
FileContentProviders.AddObject(FileType, TObject(ContentProvider));
end;
{ TFileContentProvider }
function TFileContentProvider.CanGoBack: Boolean;
begin
Result := False;
end;
function TFileContentProvider.CanGoForward: Boolean;
begin
Result := False;
end;
function TFileContentProvider.GetHistory: TStrings;
begin
Result:= nil;
end;
function TFileContentProvider.LoadURL(const AURL: String; const AContext: THelpContext=-1): Boolean;
begin
Result := False;
end;
procedure TFileContentProvider.GoHome;
begin
end;
procedure TFileContentProvider.GoBack;
begin
end;
procedure TFileContentProvider.GoForward;
begin
end;
class function TFileContentProvider.GetProperContentProvider(const AURL: String
): TBaseContentProviderClass;
var
fIndex: Integer;
fExt: String;
fFile: String;
fPos: Integer;
begin
Result := nil;
fFile := Copy(AUrl,8, Length(AURL));
fPos := Pos('://', fFile);
if fPos > 0 then begin
fFile := Copy(fFIle, 1, fPos-1);
end;
fExt := ExtractFileExt(fFile);
WriteLn(fExt);
fIndex := FileContentProviders.IndexOf(fExt);
if fIndex = -1 then exit;
Result := TBaseContentProviderClass(FileContentProviders.Objects[fIndex]);
end;
constructor TFileContentProvider.Create(AParent: TWinControl);
begin
inherited Create(AParent);
end;
initialization
FileContentProviders := TStringList.Create;
RegisterContentProvider('file://', TFileContentProvider);
finalization
FileContentProviders.Free;
end.

View File

@ -0,0 +1,143 @@
unit HTTPContentProvider;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, BaseContentProvider, LNetHTTPDataProvider, IpHtml, ComCtrls,
Menus, Controls;
type
{ THTTPContentProvider }
THTTPContentProvider = class(TBaseContentProvider)
private
fHomeUrl: String;
fPopup: TPopupMenu;
fStatusBar: TStatusBar;
fHtml: TIpHtmlPanel;
fHttpDataProvider: TIpHTTPDataProvider;
procedure IpHtmlPanelHotChange(Sender: TObject);
procedure PopupCopyClick(Sender: TObject);
procedure SetTitle(ATitle: String);
public
function CanGoBack: Boolean; override;
function CanGoForward: Boolean; override;
function GetHistory: TStrings; override;
function LoadURL(const AURL: String; const AContext: THelpContext=-1): Boolean; override;
procedure GoHome; override;
procedure GoBack; override;
procedure GoForward; override;
class function GetProperContentProvider(const AURL: String): TBaseContentProviderClass; override;
constructor Create(AParent: TWinControl); override;
end;
implementation
{ THTTPContentProvider }
procedure THTTPContentProvider.IpHtmlPanelHotChange(Sender: TObject);
begin
fStatusBar.SimpleText := fHtml.HotURL;
end;
procedure THTTPContentProvider.PopupCopyClick(Sender: TObject);
begin
fHtml.CopyToClipboard;
end;
procedure THTTPContentProvider.SetTitle(ATitle: String);
begin
if Parent = nil then exit;
TTabSheet(Parent).Caption := ATitle;
end;
function THTTPContentProvider.CanGoBack: Boolean;
begin
//Result:=inherited CanGoBack;
fHtml.canGoBack;
end;
function THTTPContentProvider.CanGoForward: Boolean;
begin
//Result:=inherited CanGoForward;
fHtml.canGoForward;
end;
function THTTPContentProvider.GetHistory: TStrings;
begin
//Result:=inherited GetHistory;
end;
function THTTPContentProvider.LoadURL(const AURL: String;
const AContext: THelpContext): Boolean;
begin
Result:=True;
SetTitle('Loading : ' + AURL );
//WriteLn('Loading URL:', AURL);
fHtml.OpenURL(AURL);
SetTitle(AURL);
if fHomeURL = '' then fHomeURL := AURL;
end;
procedure THTTPContentProvider.GoHome;
begin
LoadURL(fHomeURL);
end;
procedure THTTPContentProvider.GoBack;
begin
fHtml.GoBack;
end;
procedure THTTPContentProvider.GoForward;
begin
fHtml.GoForward;
end;
class function THTTPContentProvider.GetProperContentProvider(const AURL: String
): TBaseContentProviderClass;
begin
Result := THTTPContentProvider;
end;
constructor THTTPContentProvider.Create(AParent: TWinControl);
begin
inherited Create(AParent);
fPopUp := TPopupMenu.Create(fHtml);
fPopUp.Items.Add(TMenuItem.Create(fPopup));
with fPopUp.Items.Items[0] do begin
Caption := 'Copy';
OnClick := @PopupCopyClick;
end;
fHttpDataProvider := TIpHTTPDataProvider.Create(AParent);
fHtml := TIpHtmlPanel.Create(Parent);
with fHtml do begin
DataProvider := fHttpDataProvider;
//OnDocumentOpen := @IpHtmlPanelDocumentOpen;
OnHotChange := @IpHtmlPanelHotChange;
PopupMenu := fPopUp;
Parent := AParent;
Align := alClient;
Visible := True;
end;
fStatusBar := TStatusBar.Create(AParent);
with fStatusBar do begin
Parent := AParent;
Align := alBottom;
SimplePanel := True;
end;
end;
initialization
RegisterContentProvider('http://', THTTPContentProvider);
end.

View File

@ -9,9 +9,27 @@
<IconPath Value="./"/>
<TargetFileExt Value=""/>
</General>
<VersionInfo>
<UseVersionInfo Value="False"/>
<AutoIncrementBuild Value="False"/>
<CurrentVersionNr Value="0"/>
<CurrentMajorRevNr Value="0"/>
<CurrentMinorRevNr Value="0"/>
<CurrentBuildNr Value="0"/>
<ProjectVersion Value="1.0.0.0"/>
<Language Value="0409"/>
<CharSet Value="04E4"/>
<Comments Value=""/>
<CompanyName Value=""/>
<FileDescription Value=""/>
<InternalName Value=""/>
<LegalCopyright Value=""/>
<LegalTrademarks Value=""/>
<OriginalFilename Value=""/>
<ProductName Value=""/>
</VersionInfo>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
<ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
</PublishOptions>
@ -22,22 +40,25 @@
<Display Value="192.168.0.250:0"/>
</local>
</RunParams>
<RequiredPackages Count="4">
<RequiredPackages Count="5">
<Item1>
<PackageName Value="TurboPowerIPro"/>
<MinVersion Major="1" Valid="True"/>
</Item1>
<Item2>
<PackageName Value="lhelpcontrolpkg"/>
<PackageName Value="lnetpackage"/>
</Item2>
<Item3>
<PackageName Value="LCL"/>
<PackageName Value="lhelpcontrolpkg"/>
</Item3>
<Item4>
<PackageName Value="chmpkg"/>
<PackageName Value="LCL"/>
</Item4>
<Item5>
<PackageName Value="chmpkg"/>
</Item5>
</RequiredPackages>
<Units Count="5">
<Units Count="9">
<Unit0>
<Filename Value="lhelp.lpr"/>
<IsPartOfProject Value="True"/>
@ -68,11 +89,32 @@
<ResourceFilename Value="lhelpcore.lrs"/>
<UnitName Value="lhelpcore"/>
</Unit4>
<Unit5>
<Filename Value="lnethttpdataprovider.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="LNetHTTPDataProvider"/>
</Unit5>
<Unit6>
<Filename Value="basecontentprovider.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="BaseContentProvider"/>
</Unit6>
<Unit7>
<Filename Value="chmcontentprovider.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="chmcontentprovider"/>
</Unit7>
<Unit8>
<Filename Value="httpcontentprovider.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="HTTPContentProvider"/>
</Unit8>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="5"/>
<SearchPaths>
<Libraries Value="/emul/linux/x86/lib/;/emul/linux/x86/usr/lib32/"/>
<SrcPath Value="$(LazarusDir)/lcl/;$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)/"/>
</SearchPaths>
<CodeGeneration>
@ -82,6 +124,9 @@
</Optimizations>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="True"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
@ -89,6 +134,8 @@
</Options>
</Linking>
<Other>
<CustomOptions Value="
"/>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>

View File

@ -24,6 +24,7 @@ uses
Forms
{ add your units here }, TurboPowerIPro, chmpopup, lhelpcontrolpkg,
chmpkg, lhelpcore;
var
X: Integer;
begin

View File

@ -1,5 +1,10 @@
object HelpForm: THelpForm
ActiveControl = ContentsTree
Left = 342
Height = 535
Top = 208
Width = 758
HorzScrollBar.Page = 757
VertScrollBar.Page = 508
Caption = 'LHelp'
ClientHeight = 509
ClientWidth = 758
@ -64,178 +69,22 @@ object HelpForm: THelpForm
Menu = MainMenu1
OnClose = FormClose
OnCreate = FormCreate
PixelsPerInch = 90
Position = poScreenCenter
ShowInTaskBar = stAlways
HorzScrollBar.Page = 757
VertScrollBar.Page = 508
Left = 342
Height = 535
Top = 208
Width = 758
object StatusBar1: TStatusBar
Panels = <
item
Width = 450
end
item
Width = 150
end>
SimplePanel = False
Height = 20
Top = 489
Width = 758
end
object TabPanel: TPanel
Align = alLeft
ClientHeight = 457
ClientWidth = 216
FullRepaint = False
TabOrder = 0
Height = 457
Top = 32
Width = 216
object TabsControl: TPageControl
ActivePage = ContentsTab
Align = alClient
TabIndex = 0
TabOrder = 0
Left = 1
Height = 455
Top = 1
Width = 214
object ContentsTab: TTabSheet
Caption = 'Contents'
ClientHeight = 425
ClientWidth = 210
Left = 2
Height = 425
Top = 28
Width = 210
object ConentsPanel: TPanel
Align = alClient
BevelOuter = bvNone
Caption = 'Table of Contents Loading. Please Wait...'
ClientHeight = 425
ClientWidth = 210
TabOrder = 0
Height = 425
Width = 210
object ContentsTree: TTreeView
Align = alClient
BorderStyle = bsNone
BorderWidth = 1
DefaultItemHeight = 14
HotTrack = True
TabOrder = 0
OnSelectionChanged = ContentsTreeSelectionChanged
Options = [tvoAutoItemHeight, tvoHideSelection, tvoHotTrack, tvoKeepCollapsedNodes, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips]
Height = 425
Width = 210
end
end
end
object IndexTab: TTabSheet
Caption = 'Index'
ClientHeight = 425
ClientWidth = 210
Left = 2
Height = 425
Top = 28
Width = 210
object IndexView: TListView
Align = alClient
Columns = <
item
Caption = 'Index'
Width = 171
end>
ShowColumnHeaders = False
ViewStyle = vsReport
OnSelectItem = IndexViewSelectItem
Height = 425
Width = 210
end
end
object SearchTab: TTabSheet
Caption = 'Search'
ClientHeight = 425
ClientWidth = 210
Enabled = False
Left = 2
Height = 425
Top = 28
Width = 210
object Label1: TLabel
AutoSize = False
Caption = 'Keyword:'
Color = clNone
ParentColor = False
Left = 5
Height = 18
Top = 11
Width = 141
end
object Label2: TLabel
AutoSize = False
Caption = 'Search Results:'
Color = clNone
ParentColor = False
Left = 5
Height = 24
Top = 91
Width = 168
end
object ComboBox1: TComboBox
Anchors = [akTop, akLeft, akRight]
MaxLength = 0
TabOrder = 0
Left = 5
Height = 25
Top = 30
Width = 200
end
object SearchBttn: TButton
Anchors = [akTop, akRight]
Caption = 'Search'
TabOrder = 1
Left = 99
Height = 25
Top = 59
Width = 106
end
object ListBox1: TListBox
Anchors = [akTop, akLeft, akRight, akBottom]
TabOrder = 2
TopIndex = -1
Left = 5
Height = 304
Top = 115
Width = 200
end
end
end
end
object Splitter1: TSplitter
Beveled = True
Height = 457
Width = 5
Cursor = crHSplit
Left = 216
Height = 457
Top = 32
Width = 5
end
object Panel1: TPanel
Height = 32
Width = 758
Align = alTop
ClientHeight = 32
ClientWidth = 758
TabOrder = 1
Height = 32
Width = 758
TabOrder = 0
object ForwardBttn: TSpeedButton
Left = 65
Height = 30
Top = 1
Width = 32
Align = alLeft
Color = clBtnFace
Glyph.Data = {
B40300002F2A2058504D202A2F0A7374617469632063686172202A666F727761
72645B5D203D207B0A2F2A20636F6C756D6E7320726F777320636F6C6F727320
@ -270,13 +119,14 @@ object HelpForm: THelpForm
}
NumGlyphs = 0
OnClick = ForwardToolBtnClick
Left = 65
end
object BackBttn: TSpeedButton
Left = 33
Height = 30
Top = 1
Width = 32
end
object BackBttn: TSpeedButton
Align = alLeft
Color = clBtnFace
Glyph.Data = {
B10300002F2A2058504D202A2F0A7374617469632063686172202A6261636B5B
5D203D207B0A2F2A20636F6C756D6E7320726F777320636F6C6F727320636861
@ -311,13 +161,14 @@ object HelpForm: THelpForm
}
NumGlyphs = 0
OnClick = BackToolBtnClick
Left = 33
end
object HomeBttn: TSpeedButton
Left = 1
Height = 30
Top = 1
Width = 32
end
object HomeBttn: TSpeedButton
Align = alLeft
Color = clBtnFace
Glyph.Data = {
700A00002F2A2058504D202A2F0A7374617469632063686172202A6772617068
69635B5D203D207B0A2232342032342038362032222C0A222E2E2063204E6F6E
@ -406,115 +257,31 @@ object HelpForm: THelpForm
}
NumGlyphs = 0
OnClick = HomeToolBtnClick
Left = 1
Height = 30
Top = 1
Width = 32
end
end
object RightPanel: TPanel
Align = alClient
BevelOuter = bvNone
ClientHeight = 457
ClientWidth = 537
TabOrder = 2
Left = 221
Height = 457
object PageControl: TPageControl
Height = 477
Top = 32
Width = 537
object IpHtmlPanel1: TIpHtmlPanel
Align = alClient
BorderStyle = bsSingle
FixedTypeface = 'times'
DefaultTypeFace = 'default'
PopupMenu = PopupMenu1
PrintSettings.MarginLeft = 0.5
PrintSettings.MarginTop = 0.5
PrintSettings.MarginRight = 0.5
PrintSettings.MarginBottom = 0.5
ShowHints = False
OnDocumentOpen = IpHtmlPanel1DocumentOpen
OnHotChange = IpHtmlPanel1HotChange
OnHotClick = IpHtmlPanel1HotClick
Height = 431
Width = 537
end
object SearchPanel: TPanel
Align = alBottom
BevelOuter = bvNone
ClientHeight = 26
ClientWidth = 537
Enabled = False
TabOrder = 0
Visible = False
Height = 26
Top = 431
Width = 537
object SearchLabel: TLabel
Align = alLeft
Alignment = taCenter
AutoSize = False
BorderSpacing.Around = 5
Caption = 'Find in page'
Color = clNone
ParentColor = False
Left = 5
Height = 16
Top = 5
Width = 97
end
object SearchEdit: TEdit
Align = alLeft
OnChange = SearchEditChange
OnKeyDown = SearchEditKeyDown
TabOrder = 0
Left = 107
Height = 26
Width = 136
end
object FindNextBttn: TButton
Align = alLeft
AutoSize = True
Caption = '&Next'
OnClick = FindNextBttnClick
TabOrder = 1
Left = 243
Height = 26
Width = 35
end
object FindPrevBttn: TButton
Align = alLeft
AutoSize = True
Caption = 'P&rev'
OnClick = FindPrevBttnClick
TabOrder = 2
Left = 278
Height = 26
Width = 36
end
object SearchHideBttn: TButton
Align = alRight
AutoSize = True
Caption = '&Hide'
OnClick = SearchHideBttnClick
TabOrder = 3
Left = 501
Height = 26
Width = 36
end
end
Width = 758
Align = alClient
TabOrder = 1
TabPosition = tpBottom
OnChange = PageControlChange
OnEnter = PageControlEnter
OnPageChanged = PageControlChange
end
object MainMenu1: TMainMenu
top = 120
top = 124
object FileMenuItem: TMenuItem
Caption = '&File'
object FileMenuOpenItem: TMenuItem
Caption = '&Open'
OnClick = FileMenuOpenItemClick
end
object FileMenuOpenURLItem: TMenuItem
Caption = 'OpenURL'
OnClick = FileMenuOpenURLItemClick
end
object FileMenuCloseItem: TMenuItem
Caption = '&Close'
OnClick = FileMenuCloseItemClick
@ -527,28 +294,12 @@ object HelpForm: THelpForm
OnClick = FileMenuExitItemClick
end
end
object SearchMenuItem: TMenuItem
Caption = 'Search'
object SearchMenuFindInPageItem: TMenuItem
Caption = 'Find in page'
Enabled = False
ShortCut = 16454
OnClick = SearchMenuFindInPageItemClick
end
object SearchMenuNextItem: TMenuItem
Caption = 'Find Next'
Enabled = False
ShortCut = 114
OnClick = FindNextBttnClick
end
end
object ViewMenuItem: TMenuItem
Caption = '&View'
object ViewMenuContents: TMenuItem
Caption = 'Contents Panel'
Checked = True
ShowAlwaysCheckable = True
OnClick = ViewMenuContentsClick
end
end
end
@ -556,31 +307,6 @@ object HelpForm: THelpForm
Title = 'Open existing file'
Filter = 'HelpFiles(*.chm)|*.chm|All FIles(*.*)|*'
FilterIndex = 0
Title = 'Open existing file'
left = 66
top = 137
end
object PopupMenu1: TPopupMenu
left = 72
top = 224
object PopupHome: TMenuItem
Caption = 'Home'
OnClick = HomeToolBtnClick
end
object PopupBack: TMenuItem
Caption = 'Back'
OnClick = BackToolBtnClick
end
object PopupForward: TMenuItem
Caption = 'Forward'
OnClick = ForwardToolBtnClick
end
object MenuItem1: TMenuItem
Caption = '-'
end
object PopupCopy: TMenuItem
Caption = 'Copy'
OnClick = PopupCopyClick
end
top = 156
end
end

View File

@ -1,8 +1,11 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('THelpForm','FORMDATA',[
'TPF0'#9'THelpForm'#8'HelpForm'#13'ActiveControl'#7#12'ContentsTree'#7'Captio'
+'n'#6#5'LHelp'#12'ClientHeight'#3#253#1#11'ClientWidth'#3#246#2#9'Icon.Data'
+#10#250#6#0#0#246#6#0#0'BM'#246#6#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#24#0#0#0#24#0
+#0#0#1#0#24#0#0#0#0#0#192#6#0#0'd'#0#0#0'd'#0#0#0#0#0#0#0#0#0#0#0#255#255#255
'TPF0'#9'THelpForm'#8'HelpForm'#4'Left'#3'V'#1#6'Height'#3#23#2#3'Top'#3#208#0
+#5'Width'#3#246#2#18'HorzScrollBar.Page'#3#245#2#18'VertScrollBar.Page'#3#252
+#1#7'Caption'#6#5'LHelp'#12'ClientHeight'#3#253#1#11'ClientWidth'#3#246#2#9
+'Icon.Data'#10#250#6#0#0#246#6#0#0'BM'#246#6#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#24
+#0#0#0#24#0#0#0#1#0#24#0#0#0#0#0#192#6#0#0'd'#0#0#0'd'#0#0#0#0#0#0#0#0#0#0#0
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
@ -14,67 +17,67 @@ LazarusResources.Add('THelpForm','FORMDATA',[
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255
+#255#255#255#255#255#255#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#0#0#0#183
+#223#239#199#231#239'{'#191#214'ooo==='#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#0#0#0
+#255#255#255#183#223#239#183#223#239#183#223#239#183#223#239#173#223#231#175
+#223#231#175#223#231#175#223#231#135#198#215's'#181#199'_'#156#173'Vko'#0#0#0
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255'///'#183#223#239#231#247#247#222#239#247#231
+#247#247#231#247#247#231#247#247#231#247#247#223#247#247#222#239#247#222#239
+#247#222#239#247#215#239#247#167#222#231#135#189#206'^s{'#0#0#0#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255'333'
+#183#223#239#231#247#247#231#247#247#231#247#247#231#247#247#231#247#247#231
+#247#247#231#247#247#255#255#255#255#255#255#222#239#247#222#239#247#215#239
+#247#214#239#247#167#215#231's'#165#173#0#0#0#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255'###'#156#189#199#239#247#255#231#247#247#231#247
+#255#239#247#255#239#247#255#239#247#255#231#247#255#0#0#0#0#0#0#247#255#255
+#223#247#247#222#239#247#222#239#247#215#239#247#214#239#247#167#215#231's'
+#165#173#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255's'#135#142#189
+#231#239#231#247#255#239#247#255#239#247#255#239#247#255#239#247#255#239#247
+#255#239#247#255'gkkgko'#239#247#247#231#247#247#223#247#247#222#239#247#222
+#239#247#214#239#247#214#239#247#167#215#231'Vgk'#255#255#255#255#255#255#255
+#255#255#21#21#21#173#206#214#231#247#255#239#247#255#239#247#255#239#247#255
+#239#247#255#239#247#255#239#247#255#239#247#255#198#207#215#215#214#214#255
+#255#255#239#247#247#231#247#247#222#239#247#222#239#247#215#239#247#214#239
+#247#215#239#247'c'#167#181#0#0#0#255#255#255#255#255#255#19#19#19#239#247
+#255#239#247#255#239#247#255#239#247#255#247#255#255#247#255#255#247#255#255
+#247#255#255#247#255#255#12#12#12#0#0#0#215#215#215#255#255#255#231#247#247
+#223#247#247#222#239#247#222#239#247#214#239#247#215#239#247''#198#214#0#0#0
+#255#255#255#255#255#255#28#28#28#239#247#255#239#247#255#239#247#255#247#255
+#255#247#255#255#247#255#255#247#255#255#247#255#255#247#255#255#133#134#135
+#0#0#0#22#22#22#206#206#206#255#255#255#231#247#247#222#239#247#222#239#247
+#214#239#247#214#239#247#167#215#231#0#0#0#255#255#255#255#255#255'###'#239
+#247#255#239#247#255#239#247#255#247#255#255#247#255#255#255#255#255#255#255
+#255#255#255#255#247#255#255#247#255#255'oss'#0#0#0#20#20#20#239#239#239#239
+#247#255#222#239#247#222#239#247#214#239#247#214#239#247#167#215#231#0#0#0
+#255#255#255#255#255#255'---'#191#214#222#239#247#255#239#247#255#247#255#255
+#247#255#255#255#255#255#255#255#255#222#223#231#247#255#255#255#255#255#239
+#239#247#0#0#0#0#0#0#183#183#183#231#247#247#222#239#247#222#239#247#214#239
+#247#214#239#247'c'#167#181#0#0#0#255#255#255#255#255#255#255#255#255's'#140
+#143#247#255#255#239#247#255#247#255#255#247#255#255#255#255#255#255#255#255
+#143#140#141#26#26#26'cccBBB'#0#0#0#0#0#0#199#214#215#231#247#247#222#239#247
+#222#239#247#214#239#247#222#239#247'cw{'#255#255#255#255#255#255#255#255#255
+#255#255#255'///'#175#207#214#247#255#255#247#255#255#247#255#255#247#255#255
+#247#255#255#183#191#189'799'#12#12#12#4#4#4'''))'#151#159#158#231#247#247
+#231#247#247#222#239#247#222#239#247#222#239#247#165#191#199#0#0#0#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255')))'#175#199#207#247#255
,#255#247#255#255#247#255#255#247#255#255#247#255#255#247#255#255#239#247#255
+#239#247#255#239#247#255#231#247#247#231#247#247#223#247#247#222#239#247#231
+#247#247#165#191#199#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#0#0#0''#149#156#198#223#231#247#255#255
+#247#255#255#247#255#255#239#247#255#239#247#255#239#247#255#231#247#255#231
+#247#247#231#247#247#231#247#247#183#214#231'w'#143#150#0#0#0#255#255#255#255
+#0#0#0#183#223#239#199#231#239'{'#191#214'ooo==='#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#0#0#0'Zko'#151#189#198#199#223#231#239#247#255
+#239#247#255#239#247#255#239#247#255#189#223#231#149#189#199's'#140#143#0#0#0
+#0#0#0#255#255#255#183#223#239#183#223#239#183#223#239#183#223#239#173#223
+#231#175#223#231#175#223#231#175#223#231#135#198#215's'#181#199'_'#156#173'V'
+'ko'#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255'///'#183#223#239#231#247#247#222
+#239#247#231#247#247#231#247#247#231#247#247#231#247#247#223#247#247#222#239
+#247#222#239#247#222#239#247#215#239#247#167#222#231#135#189#206'^s{'#0#0#0
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255'333'#183#223#239#231#247#247#231#247#247#231#247#247#231#247#247#231
+#247#247#231#247#247#231#247#247#255#255#255#255#255#255#222#239#247#222#239
+#247#215#239#247#214#239#247#167#215#231's'#165#173#0#0#0#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255'###'#156#189#199#239#247#255#231#247
+#247#231#247#255#239#247#255#239#247#255#239#247#255#231#247#255#0#0#0#0#0#0
+#247#255#255#223#247#247#222#239#247#222#239#247#215#239#247#214#239#247#167
+#215#231's'#165#173#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255's'
+#135#142#189#231#239#231#247#255#239#247#255#239#247#255#239#247#255#239#247
+#255#239#247#255#239#247#255'gkkgko'#239#247#247#231#247#247#223#247#247#222
+#239#247#222#239#247#214#239#247#214#239#247#167#215#231'Vgk'#255#255#255#255
+#255#255#255#255#255#21#21#21#173#206#214#231#247#255#239#247#255#239#247#255
+#239#247#255#239#247#255#239#247#255#239#247#255#239#247#255#198#207#215#215
+#214#214#255#255#255#239#247#247#231#247#247#222#239#247#222#239#247#215#239
+#247#214#239#247#215#239#247'c'#167#181#0#0#0#255#255#255#255#255#255#19#19
+#19#239#247#255#239#247#255#239#247#255#239#247#255#247#255#255#247#255#255
+#247#255#255#247#255#255#247#255#255#12#12#12#0#0#0#215#215#215#255#255#255
+#231#247#247#223#247#247#222#239#247#222#239#247#214#239#247#215#239#247''
+#198#214#0#0#0#255#255#255#255#255#255#28#28#28#239#247#255#239#247#255#239
+#247#255#247#255#255#247#255#255#247#255#255#247#255#255#247#255#255#247#255
+#255#133#134#135#0#0#0#22#22#22#206#206#206#255#255#255#231#247#247#222#239
+#247#222#239#247#214#239#247#214#239#247#167#215#231#0#0#0#255#255#255#255
+#255#255'###'#239#247#255#239#247#255#239#247#255#247#255#255#247#255#255#255
+#255#255#255#255#255#255#255#255#247#255#255#247#255#255'oss'#0#0#0#20#20#20
+#239#239#239#239#247#255#222#239#247#222#239#247#214#239#247#214#239#247#167
+#215#231#0#0#0#255#255#255#255#255#255'---'#191#214#222#239#247#255#239#247
+#255#247#255#255#247#255#255#255#255#255#255#255#255#222#223#231#247#255#255
+#255#255#255#239#239#247#0#0#0#0#0#0#183#183#183#231#247#247#222#239#247#222
+#239#247#214#239#247#214#239#247'c'#167#181#0#0#0#255#255#255#255#255#255#255
+#255#255's'#140#143#247#255#255#239#247#255#247#255#255#247#255#255#255#255
+#255#255#255#255#143#140#141#26#26#26'cccBBB'#0#0#0#0#0#0#199#214#215#231#247
+#247#222#239#247#222#239#247#214#239#247#222#239#247'cw{'#255#255#255#255#255
+#255#255#255#255#255#255#255'///'#175#207#214#247#255#255#247#255#255#247#255
+#255#247#255#255#247#255#255#183#191#189'799'#12#12#12#4#4#4'''))'#151#159
+#158#231#247#247#231#247#247#222#239#247#222#239#247#222#239#247#165#191#199
,#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255')))'#175
+#199#207#247#255#255#247#255#255#247#255#255#247#255#255#247#255#255#247#255
+#255#239#247#255#239#247#255#239#247#255#231#247#247#231#247#247#223#247#247
+#222#239#247#231#247#247#165#191#199#0#0#0#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#0#0#0''#149#156#198#223
+#231#247#255#255#247#255#255#247#255#255#239#247#255#239#247#255#239#247#255
+#231#247#255#231#247#247#231#247#247#231#247#247#183#214#231'w'#143#150#0#0#0
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#0#0#0'###!!!!!!###'#0#0#0#0#0#0#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#0#0#0'Zko'#151#189#198#199#223
+#231#239#247#255#239#247#255#239#247#255#239#247#255#189#223#231#149#189#199
+'s'#140#143#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#0#0#0'###!!!!!!###'#0#0#0#0#0#0
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
@ -87,178 +90,106 @@ LazarusResources.Add('THelpForm','FORMDATA',[
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
+#255#255#255#255#255#255#255#255#4'Menu'#7#9'MainMenu1'#7'OnClose'#7#9'FormC'
+'lose'#8'OnCreate'#7#10'FormCreate'#13'PixelsPerInch'#2'Z'#8'Position'#7#14
+'poScreenCenter'#13'ShowInTaskBar'#7#8'stAlways'#18'HorzScrollBar.Page'#3#245
+#2#18'VertScrollBar.Page'#3#252#1#4'Left'#3'V'#1#6'Height'#3#23#2#3'Top'#3
+#208#0#5'Width'#3#246#2#0#10'TStatusBar'#10'StatusBar1'#6'Panels'#14#1#5'Wid'
+'th'#3#194#1#0#1#5'Width'#3#150#0#0#0#11'SimplePanel'#8#6'Height'#2#20#3'Top'
+#3#233#1#5'Width'#3#246#2#0#0#6'TPanel'#8'TabPanel'#5'Align'#7#6'alLeft'#12
+'ClientHeight'#3#201#1#11'ClientWidth'#3#216#0#11'FullRepaint'#8#8'TabOrder'
+#2#0#6'Height'#3#201#1#3'Top'#2' '#5'Width'#3#216#0#0#12'TPageControl'#11'Ta'
+'bsControl'#10'ActivePage'#7#11'ContentsTab'#5'Align'#7#8'alClient'#8'TabInd'
+'ex'#2#0#8'TabOrder'#2#0#4'Left'#2#1#6'Height'#3#199#1#3'Top'#2#1#5'Width'#3
+#214#0#0#9'TTabSheet'#11'ContentsTab'#7'Caption'#6#8'Contents'#12'ClientHeig'
+'ht'#3#169#1#11'ClientWidth'#3#210#0#4'Left'#2#2#6'Height'#3#169#1#3'Top'#2
+#28#5'Width'#3#210#0#0#6'TPanel'#12'ConentsPanel'#5'Align'#7#8'alClient'#10
+'BevelOuter'#7#6'bvNone'#7'Caption'#6')Table of Contents Loading. Please Wai'
+'t...'#12'ClientHeight'#3#169#1#11'ClientWidth'#3#210#0#8'TabOrder'#2#0#6'He'
+'ight'#3#169#1#5'Width'#3#210#0#0#9'TTreeView'#12'ContentsTree'#5'Align'#7#8
+'alClient'#11'BorderStyle'#7#6'bsNone'#11'BorderWidth'#2#1#17'DefaultItemHei'
+'ght'#2#14#8'HotTrack'#9#8'TabOrder'#2#0#18'OnSelectionChanged'#7#28'Content'
+'sTreeSelectionChanged'#7'Options'#11#17'tvoAutoItemHeight'#16'tvoHideSelect'
+'ion'#11'tvoHotTrack'#21'tvoKeepCollapsedNodes'#14'tvoShowButtons'#12'tvoSho'
+'wLines'#11'tvoShowRoot'#11'tvoToolTips'#0#6'Height'#3#169#1#5'Width'#3#210#0
+#0#0#0#0#9'TTabSheet'#8'IndexTab'#7'Caption'#6#5'Index'#12'ClientHeight'#3
+#169#1#11'ClientWidth'#3#210#0#4'Left'#2#2#6'Height'#3#169#1#3'Top'#2#28#5'W'
+'idth'#3#210#0#0#9'TListView'#9'IndexView'#5'Align'#7#8'alClient'#7'Columns'
+#14#1#7'Caption'#6#5'Index'#5'Width'#3#171#0#0#0#17'ShowColumnHeaders'#8#9'V'
+'iewStyle'#7#8'vsReport'#12'OnSelectItem'#7#19'IndexViewSelectItem'#6'Height'
+#3#169#1#5'Width'#3#210#0#0#0#0#9'TTabSheet'#9'SearchTab'#7'Caption'#6#6'Sea'
+'rch'#12'ClientHeight'#3#169#1#11'ClientWidth'#3#210#0#7'Enabled'#8#4'Left'#2
+#2#6'Height'#3#169#1#3'Top'#2#28#5'Width'#3#210#0#0#6'TLabel'#6'Label1'#8'Au'
+'toSize'#8#7'Caption'#6#8'Keyword:'#5'Color'#7#6'clNone'#11'ParentColor'#8#4
+'Left'#2#5#6'Height'#2#18#3'Top'#2#11#5'Width'#3#141#0#0#0#6'TLabel'#6'Label'
+'2'#8'AutoSize'#8#7'Caption'#6#15'Search Results:'#5'Color'#7#6'clNone'#11'P'
+'arentColor'#8#4'Left'#2#5#6'Height'#2#24#3'Top'#2'['#5'Width'#3#168#0#0#0#9
+'TComboBox'#9'ComboBox1'#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#9'Max'
+'Length'#2#0#8'TabOrder'#2#0#4'Left'#2#5#6'Height'#2#25#3'Top'#2#30#5'Width'
+#3#200#0#0#0#7'TButton'#10'SearchBttn'#7'Anchors'#11#5'akTop'#7'akRight'#0#7
+'Caption'#6#6'Search'#8'TabOrder'#2#1#4'Left'#2'c'#6'Height'#2#25#3'Top'#2';'
+#5'Width'#2'j'#0#0#8'TListBox'#8'ListBox1'#7'Anchors'#11#5'akTop'#6'akLeft'#7
+'akRight'#8'akBottom'#0#8'TabOrder'#2#2#8'TopIndex'#2#255#4'Left'#2#5#6'Heig'
,'ht'#3'0'#1#3'Top'#2's'#5'Width'#3#200#0#0#0#0#0#0#9'TSplitter'#9'Splitter1'
+#7'Beveled'#9#6'Height'#3#201#1#5'Width'#2#5#6'Cursor'#7#8'crHSplit'#4'Left'
+#3#216#0#6'Height'#3#201#1#3'Top'#2' '#5'Width'#2#5#0#0#6'TPanel'#6'Panel1'#5
+'Align'#7#5'alTop'#12'ClientHeight'#2' '#11'ClientWidth'#3#246#2#8'TabOrder'
+#2#1#6'Height'#2' '#5'Width'#3#246#2#0#12'TSpeedButton'#11'ForwardBttn'#5'Al'
+'ign'#7#6'alLeft'#10'Glyph.Data'#10#184#3#0#0#180#3#0#0'/* XPM */'#10'static'
+' char *forward[] = {'#10'/* columns rows colors chars-per-pixel */'#10'"16 '
+'16 35 1",'#10'" c black",'#10'". c #77B3F9",'#10'"X c #76B2FB",'#10'"o c #'
+'79B3F3",'#10'"O c #78B3F5",'#10'"+ c #79B4F6",'#10'"@ c #7DB2F6",'#10'"# c '
+'#78B3F9",'#10'"$ c #7CB7FB",'#10'"% c #7EB4FA",'#10'"& c #7EB7FA",'#10'"* c'
+' #7EB8F8",'#10'"= c #7FBAFF",'#10'"- c #989898",'#10'"; c #80B5F9",'#10'": '
+'c #80B7FA",'#10'"> c #80B9FE",'#10'", c #83B9FF",'#10'"< c #82BBFE",'#10'"1'
+' c #81BCFF",'#10'"2 c #82BDFF",'#10'"3 c #84BFFF",'#10'"4 c #85BEFF",'#10'"'
+'5 c #87BFFC",'#10'"6 c #86BFFF",'#10'"7 c #87C0FF",'#10'"8 c #89C0FF",'#10
+'"9 c #8AC2FD",'#10'"0 c #8BC5FF",'#10'"q c #8FC6FF",'#10'"w c #90C6FF",'#10
+'"e c #90C7FF",'#10'"r c #90C8FF",'#10'"t c #93CBFF",'#10'"y c None",'#10'/*'
+' pixels */'#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyyyyyyyy'
+'yyyyy",'#10'"yyyyyyyyy yyyyy",'#10'"yyyyyyyyy e yyyy",'#10'"yy 7e y'
+'yy",'#10'"yy ;,474::5re yy",'#10'"yy @%4722oo7te y",'#10'"yy :%,=,7$o20 -y"'
+','#10'"yy .. -yy",'#10'"yyy------ X -yyy",'#10'"yyyyyyyyy -yyyy",'
+#10'"yyyyyyyyy--yyyyy",'#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyyyyyyyyyyyyy",'#10
+'"yyyyyyyyyyyyyyyy"'#10'};'#10#9'NumGlyphs'#2#0#7'OnClick'#7#19'ForwardToolB'
+'tnClick'#4'Left'#2'A'#6'Height'#2#30#3'Top'#2#1#5'Width'#2' '#0#0#12'TSpeed'
+'Button'#8'BackBttn'#5'Align'#7#6'alLeft'#10'Glyph.Data'#10#181#3#0#0#177#3#0
+#0'/* XPM */'#10'static char *back[] = {'#10'/* columns rows colors chars-pe'
+'r-pixel */'#10'"16 16 35 1",'#10'" c black",'#10'". c #77B3F9",'#10'"X c #'
+'76B2FB",'#10'"o c #79B3F3",'#10'"O c #78B3F5",'#10'"+ c #79B4F6",'#10'"@ c '
+'#7DB2F6",'#10'"# c #78B3F9",'#10'"$ c #7CB7FB",'#10'"% c #7EB4FA",'#10'"& c'
+' #7EB7FA",'#10'"* c #7EB8F8",'#10'"= c #7FBAFF",'#10'"- c #989898",'#10'"; '
+'c #80B5F9",'#10'": c #80B7FA",'#10'"> c #80B9FE",'#10'", c #83B9FF",'#10'"<'
+' c #82BBFE",'#10'"1 c #81BCFF",'#10'"2 c #82BDFF",'#10'"3 c #84BFFF",'#10'"'
+'4 c #85BEFF",'#10'"5 c #87BFFC",'#10'"6 c #86BFFF",'#10'"7 c #87C0FF",'#10
+#255#255#255#255#255#255#255#255#255#255#255#255#4'Menu'#7#9'MainMenu1'#7'On'
+'Close'#7#9'FormClose'#8'OnCreate'#7#10'FormCreate'#8'Position'#7#14'poScree'
+'nCenter'#13'ShowInTaskBar'#7#8'stAlways'#0#6'TPanel'#6'Panel1'#6'Height'#2
+' '#5'Width'#3#246#2#5'Align'#7#5'alTop'#12'ClientHeight'#2' '#11'ClientWidt'
+'h'#3#246#2#8'TabOrder'#2#0#0#12'TSpeedButton'#11'ForwardBttn'#4'Left'#2'A'#6
+'Height'#2#30#3'Top'#2#1#5'Width'#2' '#5'Align'#7#6'alLeft'#5'Color'#7#9'clB'
+'tnFace'#10'Glyph.Data'#10#184#3#0#0#180#3#0#0'/* XPM */'#10'static char *fo'
+'rward[] = {'#10'/* columns rows colors chars-per-pixel */'#10'"16 16 35 1",'
+#10'" c black",'#10'". c #77B3F9",'#10'"X c #76B2FB",'#10'"o c #79B3F3",'#10
+'"O c #78B3F5",'#10'"+ c #79B4F6",'#10'"@ c #7DB2F6",'#10'"# c #78B3F9",'#10
+'"$ c #7CB7FB",'#10'"% c #7EB4FA",'#10'"& c #7EB7FA",'#10'"* c #7EB8F8",'#10
+'"= c #7FBAFF",'#10'"- c #989898",'#10'"; c #80B5F9",'#10'": c #80B7FA",'#10
+'"> c #80B9FE",'#10'", c #83B9FF",'#10'"< c #82BBFE",'#10'"1 c #81BCFF",'#10
+'"2 c #82BDFF",'#10'"3 c #84BFFF",'#10'"4 c #85BEFF",'#10'"5 c #87BFFC",'#10
+'"6 c #86BFFF",'#10'"7 c #87C0FF",'#10'"8 c #89C0FF",'#10'"9 c #8AC2FD",'#10
+'"0 c #8BC5FF",'#10'"q c #8FC6FF",'#10'"w c #90C6FF",'#10'"e c #90C7FF",'#10
+'"r c #90C8FF",'#10'"t c #93CBFF",'#10'"y c None",'#10'/* pixels */'#10'"yyy'
+'yyyyyyyyyyyyy",'#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyyy'
+'yyy yyyyy",'#10'"yyyyyyyyy e yyyy",'#10'"yy 7e yyy",'#10'"yy ;,474:'
+':5re yy",'#10'"yy @%4722oo7te y",'#10'"yy :%,=,7$o20 -y",'#10'"yy ..'
+' -yy",'#10'"yyy------ X -yyy",'#10'"yyyyyyyyy -yyyy",'#10'"yyyyyyyyy--yyyy'
+'y",'#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyyyyyyyyyyyyy"'
+#10'};'#10#9'NumGlyphs'#2#0#7'OnClick'#7#19'ForwardToolBtnClick'#0#0#12'TSpe'
+'edButton'#8'BackBttn'#4'Left'#2'!'#6'Height'#2#30#3'Top'#2#1#5'Width'#2' '#5
+'Align'#7#6'alLeft'#5'Color'#7#9'clBtnFace'#10'Glyph.Data'#10#181#3#0#0#177#3
+#0#0'/* XPM */'#10'static char *back[] = {'#10'/* columns rows colors chars-'
+'per-pixel */'#10'"16 16 35 1",'#10'" c black",'#10'". c #77B3F9",'#10'"X c'
+' #76B2FB",'#10'"o c #79B3F3",'#10'"O c #78B3F5",'#10'"+ c #79B4F6",'#10'"@ '
+'c #7DB2F6",'#10'"# c #78B3F9",'#10'"$ c #7CB7FB",'#10'"% c #7EB4FA",'#10'"&'
+' c #7EB7FA",'#10'"* c #7EB8F8",'#10'"= c #7FBAFF",'#10'"- c #989898",'#10'"'
+'; c #80B5F9",'#10'": c #80B7FA",'#10'"> c #80B9FE",'#10'", c #83B9FF",'#10
+'"< c #82BBFE",'#10'"1 c #81BCFF",'#10'"2 c #82BDFF",'#10'"3 c #84BFFF",'#10
+'"4 c #85BEFF",'#10'"5 c #87BFFC",'#10'"6 c #86BFFF",'#10'"7 c #87C0FF",'#10
+'"8 c #89C0FF",'#10'"9 c #8AC2FD",'#10'"0 c #8BC5FF",'#10'"q c #8FC6FF",'#10
+'"w c #90C6FF",'#10'"e c #90C7FF",'#10'"r c #90C8FF",'#10'"t c #93CBFF",'#10
+'"y c None",'#10'/* pixels */'#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyyyyyyyyyyyyy"'
+','#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyy yyyyyyyyy",'#10'"yyyy q yyyyyyyyy",'
+#10'"yyy t9 yy",'#10'"yy wq5&&565,; -y",'#10'"y wt9OO1165&@ -y",'#10
+'"y- q1+$5=1=&; -y",'#10'"yy- #X -y",'#10'"yyy- X --------y",'#10'"yy'
+'yy- -yyyyyyyy",'#10'"yyyyy--yyyyyyyyy",'#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyy'
,'yy- -yyyyyyyy",'#10'"yyyyy--yyyyyyyyy",'#10'"yyyyyyyyyyyyyyyy",'#10'"yyyyy'
+'yyyyyyyyyyy",'#10'"yyyyyyyyyyyyyyyy"'#10'};'#10#9'NumGlyphs'#2#0#7'OnClick'
+#7#16'BackToolBtnClick'#4'Left'#2'!'#6'Height'#2#30#3'Top'#2#1#5'Width'#2' '
+#0#0#12'TSpeedButton'#8'HomeBttn'#5'Align'#7#6'alLeft'#10'Glyph.Data'#10't'
+#10#0#0'p'#10#0#0'/* XPM */'#10'static char *graphic[] = {'#10'"24 24 86 2",'
+#10'".. c None",'#10'"., c #000000",'#10'".- c #212121",'#10'".* c #2D2D2D",'
+#10'".a c #C7675A",'#10'".b c #964B37",'#10'".c c #2B2B2B",'#10'".d c #33333'
+'3",'#10'".e c #353535",'#10'".f c #252525",'#10'".g c #944F3B",'#10'".h c #'
+'A55643",'#10'".i c #181818",'#10'".j c #474747",'#10'".k c #575757",'#10'".'
+'l c #8D8D8D",'#10'".m c #393939",'#10'".n c #191919",'#10'".o c #974F3D",'
+#10'".p c #232323",'#10'".q c #313131",'#10'".r c #A5A5A5",'#10'".s c #67676'
+'7",'#10'".t c #ADADAD",'#10'".u c #BDBDBD",'#10'".v c #5A5A5A",'#10'".w c #'
+'141414",'#10'".x c #1C1C1C",'#10'".y c #464646",'#10'".z c #BFBFBF",'#10'".'
+'A c #7F7F7F",'#10'".B c #D6D6D6",'#10'".C c #FFFFFF",'#10'".D c #4F4F4F",'
+#10'".E c #272727",'#10'".F c #525252",'#10'".G c #B7B7B7",'#10'".H c #94949'
+'4",'#10'".I c #9E9E9E",'#10'".J c #878787",'#10'".K c #171717",'#10'".L c #'
+'737373",'#10'".M c #A7A7A7",'#10'".N c #636363",'#10'".O c #1D1D1D",'#10'".'
+'P c #1F1F1F",'#10'".Q c #C6C6C6",'#10'".R c #CECECE",'#10'".S c #AFAFAF",'
+#10'".T c #D7D7D7",'#10'".U c #6F6F6F",'#10'".V c #EFEFEF",'#10'".W c #C7C7C'
+'7",'#10'".X c #EF9E8F",'#10'".Y c #DF846F",'#10'".Z c #9F5343",'#10'".0 c #'
+'858585",'#10'".1 c #EFA796",'#10'".2 c #D6533B",'#10'".3 c #974F3F",'#10'".'
+'4 c #EFA795",'#10'".5 c #CF563D",'#10'".6 c #371D16",'#10'".7 c #5F5F5F",'
+#10'".8 c #868686",'#10'".9 c #7B7B7B",'#10'".@ c #CF5E4B",'#10'".# c #E77F6'
+'7",'#10'".; c #964E3D",'#10'".: c #8C8C8C",'#10'".= c #3D1208",'#10'".+ c #'
+'D75337",'#10'".% c #959595",'#10'".$ c #879D85",'#10'".( c #86947F",'#10'".'
+') c #8E9F85",'#10'".[ c #6F8467",'#10'".] c #5F7757",'#10'",. c #4E6342",'
,#10'",, c #3F4F37",'#10'",- c #313D2B",'#10'",* c #7F8F7B",'#10'",a c #677B5'
+'E",'#10'",b c #46563F",'#10'",c c #677763",'#10'",d c #42523B",'#10'"......'
+'..........................................",'#10'".......................,.'
+',......................",'#10'"...........,.,.,.,...,.-.*.,................'
+'....",'#10'"...........,.a.b.,.,.c.d.e.f.,..................",'#10'".......'
+'....,.g.h.,.i.j.k.l.m.n.,................",'#10'"...........,.o.,.p.q.r.s.t'
+'.u.v.w.,..............",'#10'"...........,.,.x.y.s.z.A.B.u.C.D.E.,.........'
+'...",'#10'"...........,.p.F.G.H.B.I.C.u.C.u.J.K.,..........",'#10'"........'
+'.,.-.L.M.B.I.C.u.C.u.C.u.C.N.O.,........",'#10'".......,.P.Q.Q.R.C.S.C.z.C.'
+'z.C.u.C.T.A.x.,......",'#10'".....,.p.S.z.z.z.z.z.z.z.z.,.,.,.,.,.H.U.f.,..'
+'..",'#10'"...,.,.,.,.V.C.C.C.C.C.C.C.,.H.W.V.,.A.,.,.,.,..",'#10'".........'
+',.B.C.,.,.,.,.,.C.,.u.C.C.,.U.,........",'#10'".........,.t.C.,.X.Y.Z.,.C.,'
+'.R.C.C.,.N.,........",'#10'".........,.0.C.,.1.2.3.,.C.,.,.,.,.,.U.,.......'
+'.",'#10'".........,.,.C.,.4.5.6.,.Q.H.7.7.8.9.,.,........",'#10'".........,'
+'.,.V.,.1.@.3.,.C.C.C.C.C.z.,..........",'#10'"...........,.z.,.#.a.;.,.u.u.'
+'u.u.u.:.,..........",'#10'"...........,.r.=.+.a.Z.,.C.C.C.C.C.%.,..........'
+'",'#10'"...,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,...,..",'#10'".........x.'
+'$.(.).$.[.],.,,,-.,.(,*,a,b,c,d.,....",'#10'".....,.,...,.,.,.,.,.,.,.,.,..'
+'.,.,.,.,.,.,......",'#10'".................,.,.,.........................."'
+','#10'"................................................"}'#10#9'NumGlyphs'#2
+#0#7'OnClick'#7#16'HomeToolBtnClick'#4'Left'#2#1#6'Height'#2#30#3'Top'#2#1#5
+'Width'#2' '#0#0#0#6'TPanel'#10'RightPanel'#5'Align'#7#8'alClient'#10'BevelO'
+'uter'#7#6'bvNone'#12'ClientHeight'#3#201#1#11'ClientWidth'#3#25#2#8'TabOrde'
+'r'#2#2#4'Left'#3#221#0#6'Height'#3#201#1#3'Top'#2' '#5'Width'#3#25#2#0#12'T'
+'IpHtmlPanel'#12'IpHtmlPanel1'#5'Align'#7#8'alClient'#11'BorderStyle'#7#8'bs'
+'Single'#13'FixedTypeface'#6#5'times'#15'DefaultTypeFace'#6#7'default'#9'Pop'
+'upMenu'#7#10'PopupMenu1'#24'PrintSettings.MarginLeft'#5#0#0#0#0#0#0#0#128
+#254'?'#23'PrintSettings.MarginTop'#5#0#0#0#0#0#0#0#128#254'?'#25'PrintSetti'
+'ngs.MarginRight'#5#0#0#0#0#0#0#0#128#254'?'#26'PrintSettings.MarginBottom'#5
+#0#0#0#0#0#0#0#128#254'?'#9'ShowHints'#8#14'OnDocumentOpen'#7#24'IpHtmlPanel'
+'1DocumentOpen'#11'OnHotChange'#7#21'IpHtmlPanel1HotChange'#10'OnHotClick'#7
+#20'IpHtmlPanel1HotClick'#6'Height'#3#175#1#5'Width'#3#25#2#0#0#6'TPanel'#11
+'SearchPanel'#5'Align'#7#8'alBottom'#10'BevelOuter'#7#6'bvNone'#12'ClientHei'
+'ght'#2#26#11'ClientWidth'#3#25#2#7'Enabled'#8#8'TabOrder'#2#0#7'Visible'#8#6
+'Height'#2#26#3'Top'#3#175#1#5'Width'#3#25#2#0#6'TLabel'#11'SearchLabel'#5'A'
+'lign'#7#6'alLeft'#9'Alignment'#7#8'taCenter'#8'AutoSize'#8#20'BorderSpacing'
+'.Around'#2#5#7'Caption'#6#12'Find in page'#5'Color'#7#6'clNone'#11'ParentCo'
+'lor'#8#4'Left'#2#5#6'Height'#2#16#3'Top'#2#5#5'Width'#2'a'#0#0#5'TEdit'#10
+'SearchEdit'#5'Align'#7#6'alLeft'#8'OnChange'#7#16'SearchEditChange'#9'OnKey'
+'Down'#7#17'SearchEditKeyDown'#8'TabOrder'#2#0#4'Left'#2'k'#6'Height'#2#26#5
+'Width'#3#136#0#0#0#7'TButton'#12'FindNextBttn'#5'Align'#7#6'alLeft'#8'AutoS'
+'ize'#9#7'Caption'#6#5'&Next'#7'OnClick'#7#17'FindNextBttnClick'#8'TabOrder'
+#2#1#4'Left'#3#243#0#6'Height'#2#26#5'Width'#2'#'#0#0#7'TButton'#12'FindPrev'
+'Bttn'#5'Align'#7#6'alLeft'#8'AutoSize'#9#7'Caption'#6#5'P&rev'#7'OnClick'#7
+#17'FindPrevBttnClick'#8'TabOrder'#2#2#4'Left'#3#22#1#6'Height'#2#26#5'Width'
+#2'$'#0#0#7'TButton'#14'SearchHideBttn'#5'Align'#7#7'alRight'#8'AutoSize'#9#7
+'Caption'#6#5'&Hide'#7'OnClick'#7#19'SearchHideBttnClick'#8'TabOrder'#2#3#4
+'Left'#3#245#1#6'Height'#2#26#5'Width'#2'$'#0#0#0#0#9'TMainMenu'#9'MainMenu1'
+#3'top'#2'x'#0#9'TMenuItem'#12'FileMenuItem'#7'Caption'#6#5'&File'#0#9'TMenu'
+'Item'#16'FileMenuOpenItem'#7'Caption'#6#5'&Open'#7'OnClick'#7#21'FileMenuOp'
+'enItemClick'#0#0#9'TMenuItem'#17'FileMenuCloseItem'#7'Caption'#6#6'&Close'#7
+'OnClick'#7#22'FileMenuCloseItemClick'#0#0#9'TMenuItem'#13'FileSeperater'#7
+'Caption'#6#1'-'#0#0#9'TMenuItem'#16'FileMenuExitItem'#7'Caption'#6#5'E&xit'
+#7'OnClick'#7#21'FileMenuExitItemClick'#0#0#0#9'TMenuItem'#14'SearchMenuItem'
+#7'Caption'#6#6'Search'#0#9'TMenuItem'#24'SearchMenuFindInPageItem'#7'Captio'
+'n'#6#12'Find in page'#7'Enabled'#8#8'ShortCut'#3'F@'#7'OnClick'#7#29'Search'
+'MenuFindInPageItemClick'#0#0#9'TMenuItem'#18'SearchMenuNextItem'#7'Caption'
+#6#9'Find Next'#7'Enabled'#8#8'ShortCut'#2'r'#7'OnClick'#7#17'FindNextBttnCl'
+'ick'#0#0#0#9'TMenuItem'#12'ViewMenuItem'#7'Caption'#6#5'&View'#0#9'TMenuIte'
+'m'#16'ViewMenuContents'#7'Caption'#6#14'Contents Panel'#7'Checked'#9#19'Sho'
+'wAlwaysCheckable'#9#7'OnClick'#7#21'ViewMenuContentsClick'#0#0#0#0#11'TOpen'
+'Dialog'#11'OpenDialog1'#5'Title'#6#18'Open existing file'#6'Filter'#6'''Hel'
+'pFiles(*.chm)|*.chm|All FIles(*.*)|*'#11'FilterIndex'#2#0#5'Title'#6#18'Ope'
+'n existing file'#4'left'#2'B'#3'top'#3#137#0#0#0#10'TPopupMenu'#10'PopupMen'
,'u1'#4'left'#2'H'#3'top'#3#224#0#0#9'TMenuItem'#9'PopupHome'#7'Caption'#6#4
+'Home'#7'OnClick'#7#16'HomeToolBtnClick'#0#0#9'TMenuItem'#9'PopupBack'#7'Cap'
+'tion'#6#4'Back'#7'OnClick'#7#16'BackToolBtnClick'#0#0#9'TMenuItem'#12'Popup'
+'Forward'#7'Caption'#6#7'Forward'#7'OnClick'#7#19'ForwardToolBtnClick'#0#0#9
+'TMenuItem'#9'MenuItem1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#9'PopupCopy'#7'C'
+'aption'#6#4'Copy'#7'OnClick'#7#14'PopupCopyClick'#0#0#0#0
+#7#16'BackToolBtnClick'#0#0#12'TSpeedButton'#8'HomeBttn'#4'Left'#2#1#6'Heigh'
+'t'#2#30#3'Top'#2#1#5'Width'#2' '#5'Align'#7#6'alLeft'#5'Color'#7#9'clBtnFac'
+'e'#10'Glyph.Data'#10't'#10#0#0'p'#10#0#0'/* XPM */'#10'static char *graphic'
+'[] = {'#10'"24 24 86 2",'#10'".. c None",'#10'"., c #000000",'#10'".- c #21'
+'2121",'#10'".* c #2D2D2D",'#10'".a c #C7675A",'#10'".b c #964B37",'#10'".c '
+'c #2B2B2B",'#10'".d c #333333",'#10'".e c #353535",'#10'".f c #252525",'#10
+'".g c #944F3B",'#10'".h c #A55643",'#10'".i c #181818",'#10'".j c #474747",'
+#10'".k c #575757",'#10'".l c #8D8D8D",'#10'".m c #393939",'#10'".n c #19191'
+'9",'#10'".o c #974F3D",'#10'".p c #232323",'#10'".q c #313131",'#10'".r c #'
+'A5A5A5",'#10'".s c #676767",'#10'".t c #ADADAD",'#10'".u c #BDBDBD",'#10'".'
+'v c #5A5A5A",'#10'".w c #141414",'#10'".x c #1C1C1C",'#10'".y c #464646",'
+#10'".z c #BFBFBF",'#10'".A c #7F7F7F",'#10'".B c #D6D6D6",'#10'".C c #FFFFF'
+'F",'#10'".D c #4F4F4F",'#10'".E c #272727",'#10'".F c #525252",'#10'".G c #'
+'B7B7B7",'#10'".H c #949494",'#10'".I c #9E9E9E",'#10'".J c #878787",'#10'".'
+'K c #171717",'#10'".L c #737373",'#10'".M c #A7A7A7",'#10'".N c #636363",'
+#10'".O c #1D1D1D",'#10'".P c #1F1F1F",'#10'".Q c #C6C6C6",'#10'".R c #CECEC'
+'E",'#10'".S c #AFAFAF",'#10'".T c #D7D7D7",'#10'".U c #6F6F6F",'#10'".V c #'
+'EFEFEF",'#10'".W c #C7C7C7",'#10'".X c #EF9E8F",'#10'".Y c #DF846F",'#10'".'
+'Z c #9F5343",'#10'".0 c #858585",'#10'".1 c #EFA796",'#10'".2 c #D6533B",'
+#10'".3 c #974F3F",'#10'".4 c #EFA795",'#10'".5 c #CF563D",'#10'".6 c #371D1'
+'6",'#10'".7 c #5F5F5F",'#10'".8 c #868686",'#10'".9 c #7B7B7B",'#10'".@ c #'
+'CF5E4B",'#10'".# c #E77F67",'#10'".; c #964E3D",'#10'".: c #8C8C8C",'#10'".'
+'= c #3D1208",'#10'".+ c #D75337",'#10'".% c #959595",'#10'".$ c #879D85",'
+#10'".( c #86947F",'#10'".) c #8E9F85",'#10'".[ c #6F8467",'#10'".] c #5F775'
+'7",'#10'",. c #4E6342",'#10'",, c #3F4F37",'#10'",- c #313D2B",'#10'",* c #'
+'7F8F7B",'#10'",a c #677B5E",'#10'",b c #46563F",'#10'",c c #677763",'#10'",'
+'d c #42523B",'#10'"................................................",'#10'"'
+'.......................,.,......................",'#10'"...........,.,.,.,.'
+'..,.-.*.,....................",'#10'"...........,.a.b.,.,.c.d.e.f.,........'
+'..........",'#10'"...........,.g.h.,.i.j.k.l.m.n.,................",'#10'".'
+'..........,.o.,.p.q.r.s.t.u.v.w.,..............",'#10'"...........,.,.x.y.s'
+'.z.A.B.u.C.D.E.,............",'#10'"...........,.p.F.G.H.B.I.C.u.C.u.J.K.,.'
+'.........",'#10'".........,.-.L.M.B.I.C.u.C.u.C.u.C.N.O.,........",'#10'"..'
+'.....,.P.Q.Q.R.C.S.C.z.C.z.C.u.C.T.A.x.,......",'#10'".....,.p.S.z.z.z.z.z.'
+'z.z.z.,.,.,.,.,.H.U.f.,....",'#10'"...,.,.,.,.V.C.C.C.C.C.C.C.,.H.W.V.,.A.,'
+'.,.,.,..",'#10'".........,.B.C.,.,.,.,.,.C.,.u.C.C.,.U.,........",'#10'"...'
+'......,.t.C.,.X.Y.Z.,.C.,.R.C.C.,.N.,........",'#10'".........,.0.C.,.1.2.3'
+'.,.C.,.,.,.,.,.U.,........",'#10'".........,.,.C.,.4.5.6.,.Q.H.7.7.8.9.,.,.'
+'.......",'#10'".........,.,.V.,.1.@.3.,.C.C.C.C.C.z.,..........",'#10'"....'
+'.......,.z.,.#.a.;.,.u.u.u.u.u.:.,..........",'#10'"...........,.r.=.+.a.Z.'
+',.C.C.C.C.C.%.,..........",'#10'"...,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,'
+'...,..",'#10'".........x.$.(.).$.[.],.,,,-.,.(,*,a,b,c,d.,....",'#10'".....'
+',.,...,.,.,.,.,.,.,.,.,...,.,.,.,.,.,......",'#10'".................,.,.,..'
+'........................",'#10'"...........................................'
+'....."}'#10#9'NumGlyphs'#2#0#7'OnClick'#7#16'HomeToolBtnClick'#0#0#0#12'TPa'
+'geControl'#11'PageControl'#6'Height'#3#221#1#3'Top'#2' '#5'Width'#3#246#2#5
+'Align'#7#8'alClient'#8'TabOrder'#2#1#11'TabPosition'#7#8'tpBottom'#8'OnChan'
+'ge'#7#17'PageControlChange'#7'OnEnter'#7#16'PageControlEnter'#13'OnPageChan'
+'ged'#7#17'PageControlChange'#0#0#9'TMainMenu'#9'MainMenu1'#3'top'#2'|'#0#9
+'TMenuItem'#12'FileMenuItem'#7'Caption'#6#5'&File'#0#9'TMenuItem'#16'FileMen'
+'uOpenItem'#7'Caption'#6#5'&Open'#7'OnClick'#7#21'FileMenuOpenItemClick'#0#0
+#9'TMenuItem'#19'FileMenuOpenURLItem'#7'Caption'#6#7'OpenURL'#7'OnClick'#7#24
+'FileMenuOpenURLItemClick'#0#0#9'TMenuItem'#17'FileMenuCloseItem'#7'Caption'
+#6#6'&Close'#7'OnClick'#7#22'FileMenuCloseItemClick'#0#0#9'TMenuItem'#13'Fil'
+'eSeperater'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#16'FileMenuExitItem'#7'Capti'
+'on'#6#5'E&xit'#7'OnClick'#7#21'FileMenuExitItemClick'#0#0#0#9'TMenuItem'#12
+'ViewMenuItem'#7'Caption'#6#5'&View'#0#9'TMenuItem'#16'ViewMenuContents'#7'C'
+'aption'#6#14'Contents Panel'#7'Checked'#9#19'ShowAlwaysCheckable'#9#0#0#0#0
+#11'TOpenDialog'#11'OpenDialog1'#5'Title'#6#18'Open existing file'#6'Filter'
+#6'''HelpFiles(*.chm)|*.chm|All FIles(*.*)|*'#11'FilterIndex'#2#0#3'top'#3
+#156#0#0#0#0
]);

View File

@ -22,191 +22,119 @@ unit lhelpcore;
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ChmReader,
Buttons, LCLProc, StdCtrls, IpHtml, ChmDataProvider, ComCtrls, ExtCtrls,
Menus, SimpleIPC;
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
Buttons, LCLProc, StdCtrls, IpHtml, ComCtrls, ExtCtrls,
Menus, SimpleIPC, BaseContentProvider, FileContentProvider, ChmContentProvider
{$IFNDEF NO_LNET}, HTTPContentProvider{$ENDIF};
type
{ THelpForm }
{ TContentTab }
TContentTab = class(TTabSheet)
private
fContentProvider: TBaseContentProvider;
public
constructor Create(AOwner: TComponent); override;
property ContentProvider: TBaseContentProvider read fContentProvider write fContentProvider;
end;
{ THelpForm }
THelpForm = class(TForm)
SearchMenuNextItem: TMenuItem;
SearchHideBttn: TButton;
FindPrevBttn: TButton;
FindNextBttn: TButton;
SearchEdit: TEdit;
IpHtmlPanel1: TIpHtmlPanel;
Label2: TLabel;
SearchLabel: TLabel;
ListBox1: TListBox;
SearchPanel: TPanel;
RightPanel: TPanel;
SearchMenuFindInPageItem: TMenuItem;
SearchMenuItem: TMenuItem;
SearchBttn: TButton;
ComboBox1: TComboBox;
ContentsTree: TTreeView;
FileMenuCloseItem: TMenuItem;
FileMenuExitItem: TMenuItem;
FileMenuItem: TMenuItem;
FileMenuOpenItem: TMenuItem;
FileSeperater: TMenuItem;
ImageList1: TImageList;
IndexView: TListView;
Label1: TLabel;
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
ConentsPanel: TPanel;
PopupForward: TMenuItem;
PopupBack: TMenuItem;
PopupHome: TMenuItem;
PopupCopy: TMenuItem;
FileMenuOpenURLItem: TMenuItem;
PageControl: TPageControl;
Panel1: TPanel;
ForwardBttn: TSpeedButton;
BackBttn: TSpeedButton;
HomeBttn: TSpeedButton;
OpenDialog1: TOpenDialog;
IndexTab: TTabSheet;
PopupMenu1: TPopupMenu;
SearchTab: TTabSheet;
TabsControl: TPageControl;
Splitter1: TSplitter;
TabPanel: TPanel;
StatusBar1: TStatusBar;
ContentsTab: TTabSheet;
ViewMenuContents: TMenuItem;
ViewMenuItem: TMenuItem;
procedure BackToolBtnClick(Sender: TObject);
procedure ContentsTreeSelectionChanged(Sender: TObject);
procedure FileMenuCloseItemClick(Sender: TObject);
procedure FileMenuExitItemClick(Sender: TObject);
procedure FileMenuOpenItemClick(Sender: TObject);
procedure FindNextBttnClick(Sender: TObject);
procedure FindPrevBttnClick(Sender: TObject);
procedure FileMenuOpenURLItemClick(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure ForwardToolBtnClick(Sender: TObject);
procedure HomeToolBtnClick(Sender: TObject);
procedure ImageList1Change(Sender: TObject);
procedure IndexViewSelectItem(Sender: TObject; Item: TListItem;
Selected: Boolean);
procedure IpHtmlPanel1DocumentOpen(Sender: TObject);
procedure IpHtmlPanel1HotChange(Sender: TObject);
procedure IpHtmlPanel1HotClick(Sender: TObject);
procedure PopupCopyClick(Sender: TObject);
procedure SearchEditChange(Sender: TObject);
procedure SearchEditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure SearchHideBttnClick(Sender: TObject);
procedure SearchMenuFindInPageItemClick(Sender: TObject);
procedure ViewMenuContentsClick(Sender: TObject);
procedure FillTOCTimer(Sender: TObject);
procedure PageControlChange(Sender: TObject);
procedure PageControlEnter(Sender: TObject);
private
{ private declarations }
fIsUsingHistory: Boolean;
fStopTimer: Boolean;
fFillingToc: Boolean;
fChms: TChmFileList;
fHistory: TStringList;
fHistoryIndex: Integer;
fServerName: String;
fServer: TSimpleIPCServer;
fServerTimer: TTimer;
fContext: LongInt; // used once when we are started on the command line with --context
procedure ServerMessage(Sender: TObject);
procedure AddHistory(URL: String);
procedure DoOpenChm(AFile: String);
procedure DoCloseChm;
procedure DoLoadContext(Context: THelpContext);
procedure DoLoadUrl(Url: String; AChm: TChmReader = nil);
procedure DoError(Error: Integer);
procedure NewChmOpened(ChmFileList: TChmFileList; Index: Integer);
procedure ReadCommandLineOptions;
procedure StartServer(ServerName: String);
procedure StopServer;
procedure OpenURL(const AURL: String; AContext: THelpContext=-1);
function ActivePage: TContentTab;
procedure RefreshState;
procedure ShowError(AError: String);
public
{ public declarations }
end;
TTocTimer = class(TIdleTimer)
private
fChm: TChmReader;
end;
var
HelpForm: THelpForm;
const INVALID_FILE_TYPE = 1;
implementation
uses ChmSpecialParser, LHelpControl;
uses LHelpControl;
{ THelpForm }
procedure THelpForm.BackToolBtnClick(Sender: TObject);
begin
if fHistoryIndex > 0 then begin
Dec(fHistoryIndex);
fIsUsingHistory:=True;
IpHtmlPanel1.OpenURL(fHistory.Strings[fHistoryIndex]);
end;
if Assigned(ActivePage) then ActivePage.ContentProvider.GoBack;
end;
procedure THelpForm.ContentsTreeSelectionChanged(Sender: TObject);
var
ATreeNode: TContentTreeNode;
ARootNode: TTreeNode;
fChm: TChmReader = nil;
begin
if (ContentsTree.Selected = nil) or not(ContentsTree.Selected is TContentTreeNode) then Exit;
ATreeNode := TContentTreeNode(ContentsTree.Selected);
//find the chm associated with this branch
ARootNode := ATreeNode.Parent;
while ARootNode.Parent <> nil do
ARootNode := ARootNode.Parent;
fChm := TChmReader(ARootNode.Data);
if ATreeNode.Url <> '' then begin
DoLoadUrl(ATreeNode.Url, fChm);
end;
end;
procedure THelpForm.FileMenuCloseItemClick(Sender: TObject);
begin
DoCloseChm;// checks if it is open first
//DoCloseChm;// checks if it is open first
if Assigned(ActivePage) then ActivePage.Free;
end;
procedure THelpForm.FileMenuExitItemClick(Sender: TObject);
begin
DoCloseChm;
//DoCloseChm;
Close;
end;
procedure THelpForm.FileMenuOpenItemClick(Sender: TObject);
begin
if OpenDialog1.Execute then DoOpenChm(OpenDialog1.FileName);
if OpenDialog1.Execute then OpenURL('file://'+OpenDialog1.FileName);
end;
procedure THelpForm.FindNextBttnClick(Sender: TObject);
procedure THelpForm.FileMenuOpenURLItemClick(Sender: TObject);
var
fRes: String;
begin
{ if IpHtmlPanel1.SearchKey = '' then begin
SearchMenuFindInPageItemClick(Sender);
Exit;
end;
IpHtmlPanel1.FindNext;}
end;
procedure THelpForm.FindPrevBttnClick(Sender: TObject);
begin
if InputQuery('Enter a URL', 'Please Enter a URL', fRes) then OpenURL(fRes);
end;
procedure THelpForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
DoCloseChm;
//DoCloseChm;
FileMenuCloseItemClick(Sender);
Stopserver;
@ -215,8 +143,6 @@ end;
procedure THelpForm.FormCreate(Sender: TObject);
begin
fContext := -1;
fHistory := TStringList.Create;
IpHtmlPanel1.DataProvider := TIpChmDataProvider.Create(fChms);
ReadCommandLineOptions;
if fServerName <> '' then begin
StartServer(fServerName);
@ -225,127 +151,25 @@ end;
procedure THelpForm.ForwardToolBtnClick(Sender: TObject);
begin
if fHistoryIndex < fHistory.Count-1 then begin
Inc(fHistoryIndex);
fIsUsingHistory:=True;
IpHtmlPanel1.OpenURL(fHistory.Strings[fHistoryIndex]);
end;
if Assigned(ActivePage) then ActivePage.ContentProvider.GoForward;
end;
procedure THelpForm.HomeToolBtnClick(Sender: TObject);
begin
if (fChms <> nil) and (fChms.Chm[0].DefaultPage <> '') then begin
DoLoadUrl(fChms.Chm[0].DefaultPage);
end;
if Assigned(ActivePage) then ActivePage.ContentProvider.GoHome;
end;
procedure THelpForm.ImageList1Change(Sender: TObject);
procedure THelpForm.PageControlChange(Sender: TObject);
begin
RefreshState;
end;
procedure THelpForm.IndexViewSelectItem(Sender: TObject; Item: TListItem;
Selected: Boolean);
var
RealItem: TIndexItem;
procedure THelpForm.PageControlEnter(Sender: TObject);
begin
if not Selected then Exit;
RealItem := TIndexItem(Item);
if RealItem.Url <> '' then begin
DoLoadUrl(RealItem.Url);
end;
RefreshState;
end;
procedure THelpForm.IpHtmlPanel1DocumentOpen(Sender: TObject);
begin
// StatusBar1.Panels.Items[1] := IpHtmlPanel1.DataProvider.;
if fIsUsingHistory = False then
AddHistory(TIpChmDataProvider(IpHtmlPanel1.DataProvider).CurrentPage)
else fIsUsingHistory := False;
end;
procedure THelpForm.IpHtmlPanel1HotChange(Sender: TObject);
begin
StatusBar1.Panels.Items[0].Text := IpHtmlPanel1.HotURL;
end;
procedure THelpForm.IpHtmlPanel1HotClick(Sender: TObject);
begin
end;
procedure THelpForm.PopupCopyClick(Sender: TObject);
begin
IpHtmlPanel1.CopyToClipboard;
end;
procedure THelpForm.SearchEditChange(Sender: TObject);
begin
//IpHtmlPanel1.SearchKey := SearchEdit.Text;
end;
procedure THelpForm.SearchEditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = 13 then begin
Key := 0;
FindNextBttn.Click;
end;
end;
procedure THelpForm.SearchHideBttnClick(Sender: TObject);
begin
SearchPanel.Visible := False;
SetFocus;
end;
procedure THelpForm.SearchMenuFindInPageItemClick(Sender: TObject);
begin
SearchPanel.Visible := True;
SearchEdit.SetFocus;
SearchEdit.SelectAll;
end;
procedure THelpForm.ViewMenuContentsClick(Sender: TObject);
begin
TMenuItem(Sender).Checked := not TMenuItem(Sender).Checked;
Splitter1.Visible := TMenuItem(Sender).Checked;
TabPanel.Visible := Splitter1.Visible;
end;
procedure THelpForm.FillTOCTimer(Sender: TObject);
var
Stream: TMemoryStream;
fChm: TChmReader;
ParentNode: TTreeNode;
begin
if fFillingToc = True then begin
TTimer(Sender).Interval := 40;
exit;
end;
fFillingToc := True;
fStopTimer := False;
ContentsTree.Visible := False;
fChm := TTocTimer(Sender).fChm;
TTocTimer(Sender).Free;
if fChm <> nil then begin
Stream := TMemoryStream(fchm.GetObject(fChm.TOCFile));
if Stream <> nil then begin
Stream.position := 0;
ParentNode := ContentsTree.Items.AddChildObject(nil, fChm.Title, fChm);
with TContentsFiller.Create(ContentsTree, Stream, @fStopTimer) do begin
DoFill(ParentNode);
Free;
end;
end;
Stream.Free;
end;
if ParentNode.Index = 0 then ParentNode.Expanded := True;
ContentsTree.Visible := True;
fFillingToc := False;
fStopTimer := False;
end;
procedure THelpForm.ServerMessage(Sender: TObject);
var
@ -360,151 +184,28 @@ begin
Stream.Read(FileReq, SizeOf(FileReq));
case FileReq.RequestType of
rtFile : begin
DoOpenChm(FileReq.FileName);
OpenURL('file://'+FileReq.FileName);
end;
rtUrl : begin
Stream.Position := 0;
Stream.Read(UrlReq, SizeOf(UrlReq));
DoOpenChm(UrlReq.FileRequest.FileName);
DoLoadUrl(UrlReq.Url);
if UrlReq.FileRequest.FileName <> '' then
OpenUrl('file://'+UrlReq.FileRequest.FileName+'://'+UrlReq.Url)
else
OpenURL(UrlReq.Url);
end;
rtContext : begin
Stream.Position := 0;
Stream.Read(ConReq, SizeOf(ConReq));
DoOpenChm(ConReq.FileRequest.FileName);
DoLoadContext(ConReq.HelpContext);
OpenURL('file://'+FileReq.FileName, ConReq.HelpContext);
end;
end;
Self.BringToFront;
end;
end;
procedure THelpForm.AddHistory(URL: String);
begin
if fHistoryIndex < fHistory.Count then begin
while fHistory.Count-1 > fHistoryIndex do
fHistory.Delete(fHistory.Count-1);
end;
fHistory.Add(URL);
Inc(fHistoryIndex);
end;
procedure THelpForm.DoOpenChm(AFile: String);
var
Stream: TStream;
Timer: TTimer;
begin
if (fChms <> nil) and fChms.IsAnOpenFile(AFile) then Exit;
DoCloseChm;
if not FileExists(AFile) or DirectoryExists(AFile) then
begin
Exit;
end;
try
fChms := TChmFileList.Create(AFile);
if Not(fChms.Chm[0].IsValidFile) then begin
FreeAndNil(fChms);
DoError(INVALID_FILE_TYPE);
Exit;
end;
TIpChmDataProvider(IpHtmlPanel1.DataProvider).Chm := fChms;
except
FreeAndNil(fChms);
DoError(INVALID_FILE_TYPE);
Exit;
end;
if fChms = nil then Exit;
fChms.OnOpenNewFile := @NewChmOpened;
fHistoryIndex := -1;
fHistory.Clear;
// Code Here has been moved to the OpenFile handler
FileMenuCloseItem.Enabled := True;
if fChms.Chm[0].Title <> '' then Caption := 'LHelp - '+fChms.Chm[0].Title;
end;
procedure THelpForm.DoCloseChm;
begin
fStopTimer := True;
if fChms<>nil then begin
FreeAndNil(fChms);
FileMenuCloseItem.Enabled := False;
fContext := -1;
end;
Caption := 'LHelp';
IndexView.Clear;
ContentsTree.Items.Clear;
IpHtmlPanel1.SetHtml(nil);
TIpChmDataProvider(IpHtmlPanel1.DataProvider).CurrentPath := '/';
TIpChmDataProvider(IpHtmlPanel1.DataProvider).Chm := nil;
end;
procedure THelpForm.DoLoadContext(Context: THelpContext);
var
Str: String;
begin
if fChms = nil then exit;
Str := fChms.Chm[0].GetContextUrl(Context);
if Str <> '' then DoLoadUrl(Str);
end;
procedure THelpForm.DoLoadUrl(Url: String; AChm: TChmReader = nil);
begin
if (fChms = nil) and (AChm = nil) then exit;
if fChms.ObjectExists(Url, AChm) = 0 then Exit;
fIsUsingHistory := True;
IpHtmlPanel1.OpenURL(Url);
TIpChmDataProvider(IpHtmlPanel1.DataProvider).CurrentPath := ExtractFileDir(URL)+'/';
AddHistory(Url);
end;
procedure THelpForm.DoError(Error: Integer);
begin
//what to do with these errors?
//INVALID_FILE_TYPE;
end;
procedure THelpForm.NewChmOpened(ChmFileList: TChmFileList; Index: Integer);
var
TImer: TTocTimer;
Stream: TMemoryStream;
begin
if Index = 0 then begin
ContentsTree.Items.Clear;
if fContext > -1 then begin
DoLoadContext(fContext);
fContext := -1;
end
else if ChmFileList.Chm[Index].DefaultPage <> '' then begin
DoLoadUrl(ChmFileList.Chm[Index].DefaultPage);
end;
end;
if ChmFileList.Chm[Index].Title = '' then
ChmFileList.Chm[Index].Title := ExtractFileName(ChmFileList.FileName[Index]);
// Fill the table of contents. This actually works very well
Timer := TTocTimer.Create(Self);
if ChmFileList.ObjectExists(ChmFileList.Chm[Index].TOCFile) > 25000 then
Timer.Interval := 500
else
Timer.Interval := 5;
Timer.OnTimer := @FillTOCTimer;
Timer.fChm := ChmFileList.Chm[Index];
Timer.Enabled := True;
ContentsTree.Visible := False;
Stream := fchms.GetObject(ChmFileList.Chm[Index].IndexFile);
if Stream <> nil then begin
Stream.position := 0;
with TIndexFiller.Create(IndexView, Stream) do begin;
DoFill;
Free;
end;
Stream.Free;
end;
end;
procedure THelpForm.ReadCommandLineOptions;
var
@ -527,10 +228,14 @@ begin
IsHandled[X+1] := True;
end;
end;
// Loop through a second time for the filename
// Loop through a second time for the url
for X := 1 to ParamCount do
if not IsHandled[X] then begin
DoOpenChm(ParamStr(X));
//DoOpenChm(ParamStr(X));
if Pos('://', ParamStr(X)) = 0 then
OpenURL('file://'+ParamStr(X), fContext)
else
OpenURL(ParamStr(X), fContext);
Break;
end;
//we reset the context because at this point the file has been loaded and the
@ -562,6 +267,92 @@ begin
end;
procedure THelpForm.OpenURL(const AURL: String; AContext: THelpContext);
function GetURLPrefix: String;
var
fPos: Integer;
begin
fPos := Pos('://', AURL);
Result := Copy(AURL, 1, fPos+2);
end;
var
fURLPrefix: String;
fContentProvider: TBaseContentProviderClass;
fRealContentProvider: TBaseContentProviderClass;
fNewPage: TContentTab;
I: Integer;
begin
fURLPrefix := GetURLPrefix;
fContentProvider := GetContentProvider(fURLPrefix);
if fContentProvider = nil then begin
ShowError('Cannot handle this type of content. "' + fURLPrefix + '"');
Exit;
end;
fRealContentProvider := fContentProvider.GetProperContentProvider(AURL);
if fRealContentProvider = nil then begin
ShowError('Cannot handle this type of subcontent. "' + fURLPrefix + '"');
Exit;
end;
for I := 0 to PageControl.PageCount-1 do begin
if fRealContentProvider.ClassName = TContentTab(PageControl.Pages[I]).ContentProvider.ClassName then begin
if TContentTab(PageControl.Pages[I]).ContentProvider.LoadURL(AURL, AContext) then
PageControl.ActivePage := PageControl.Pages[I];
Exit;
end;
end;
//no page was found already to handle this content so create one
fNewPage := TContentTab.Create(PageControl);
fNewPage.ContentProvider := fRealContentProvider.Create(fNewPage);
fNewPage.Parent := PageControl;
if fNewPage.ContentProvider.LoadURL(AURL, AContext) then
PageControl.ActivePage := fNewPage;
RefreshState;
end;
function THelpForm.ActivePage: TContentTab;
begin
Result := TContentTab(PageControl.ActivePage);
end;
procedure THelpForm.RefreshState;
begin
if ActivePage = nil then begin
BackBttn.Enabled := False;
ForwardBttn.Enabled := False;
HomeBttn.Enabled := False;
FileMenuCloseItem.Enabled := False;
exit;
end;
// else
FileMenuCloseItem.Enabled := True;
HomeBttn.Enabled := True;
BackBttn.Enabled := True;// ActivePage.ContentProvider.CanGoBack;
ForwardBttn.Enabled := True; //ActivePage.ContentProvider.CanGoForward;
//WriteLn('BackBttn.Enabled = ',BackBttn.Enabled);
//WriteLn('ForwardBttn.Enabled = ',ForwardBttn.Enabled);
//HomeBttn.Enabled := False;
FileMenuCloseItem.Enabled := True;
end;
procedure THelpForm.ShowError(AError: String);
begin
ShowMessage(AError);
end;
{ TContentTab }
constructor TContentTab.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
initialization
{$I lhelpcore.lrs}

View File

@ -0,0 +1,279 @@
unit LNetHTTPDataProvider;
{$mode objfpc}{$H+}
interface
uses
Forms, Classes, SysUtils, IpHtml, IpMsg, IpUtils, lnetcomponents, Graphics, lhttp;
type
{ TIpHTTPDataProvider }
TIpHTTPDataProvider = class(TIpAbstractHtmlDataProvider)
private
fLastType: String;
procedure HttpError(const msg: string; aSocket: TLSocket);
function HttpInput(ASocket: TLHTTPClientSocket; ABuffer: pchar; ASize: dword): dword;
procedure HttpInputDone(ASocket: TLHTTPClientSocket);
procedure HttpProcessHeader(ASocket: TLHTTPClientSocket);
procedure HttpCanWrite(ASocket: TLHTTPClientSocket; var OutputEof: TWriteBlockStatus);
procedure HttpDisconnect(aSocket: TLSocket);
function GetURL(const AURL: String; JustHeader: Boolean = False): TStream;
function GetHostAndURI(const fURL: String; var AHost: String; var AURI: String): Boolean;
protected
function DoGetHtmlStream(const URL: string;
PostData: TIpFormDataEntity) : TStream; override;
function DoCheckURL(const URL: string;
var ContentType: string): Boolean; override;
procedure DoLeave(Html: TIpHtml); override;
procedure DoReference(const URL: string); override;
procedure DoGetImage(Sender: TIpHtmlNode; const URL: string;
var Picture: TPicture); override;
function CanHandle(const URL: string): Boolean; override;
function BuildURL(const OldURL, NewURL: string): string; override;
public
constructor Create(AOwner: TComponent);
destructor Destroy; override;
end;
TLHttpClientEx = class(TLHttpClientComponent)
private
Stream: TStream;
Waiting: Boolean;
end;
implementation
uses
FPImage,
{fpreadgif,} // doesn't exist yet!
FPReadbmp,
FPReadxpm,
FPReadJPEg,
FPReadpng,
FPWritebmp,
IntFGraphics;
{ TIpHTTPDataProvider }
procedure TIpHTTPDataProvider.HttpError(const msg: string; aSocket: TLSocket);
begin
TLHttpClientEx(TLHttpClientSocket(ASocket).Connection).Waiting := False;
//WriteLn('Error occured: ', msg);
end;
function TIpHTTPDataProvider.HttpInput(ASocket: TLHTTPClientSocket;
ABuffer: pchar; ASize: dword): dword;
begin
if TLHttpClientEx(ASocket.Connection).Stream = nil then
TLHttpClientEx(ASocket.Connection).Stream := TMemoryStream.Create;
Result := TLHttpClientEx(ASocket.Connection).Stream.Write(ABuffer^, ASize);
end;
procedure TIpHTTPDataProvider.HttpInputDone(ASocket: TLHTTPClientSocket);
begin
TLHttpClientEx(ASocket.Connection).Waiting := False;
aSocket.Disconnect;
//WriteLn('InputDone');
end;
procedure TIpHTTPDataProvider.HttpProcessHeader(ASocket: TLHTTPClientSocket);
begin
//WriteLn('Process Header');
//WriteLn(ASocket.Parameters[hpContentType]);
fLastType := ASocket.Parameters[hpContentType];
end;
procedure TIpHTTPDataProvider.HttpCanWrite(ASocket: TLHTTPClientSocket;
var OutputEof: TWriteBlockStatus);
begin
//WriteLn('OnCanWrite');
end;
procedure TIpHTTPDataProvider.HttpDisconnect(aSocket: TLSocket);
begin
TLHttpClientEx(TLHttpClientSocket(ASocket).Connection).Waiting := False;
//WriteLn('Disconnected');
end;
function TIpHTTPDataProvider.GetURL(const AURL: String; JustHeader: Boolean = False): TStream;
var
fHost, fURI: String;
fHttpClient: TLHttpClientEx;
begin
Result := nil;
if not GetHostAndURI(AURL, fHost, fURI) then Exit(nil);
//WriteLn('Result := True');
fHttpClient := TLHttpClientEx.Create(Owner);
fHttpClient.OnInput := @HttpInput;
fHttpClient.OnError := @HttpError;
fHttpClient.OnDoneInput := @HttpInputDone;
fHttpClient.OnProcessHeaders := @HttpProcessHeader;
fHttpClient.OnCanWrite := @HttpCanWrite;
fHttpClient.OnDisconnect := @HttpDisconnect;
fHttpClient.Host := fHost;
fHttpClient.Port := 80;
if JustHeader then
fHttpClient.Method := hmHead
else
fHttpClient.Method := hmGet;
fHttpClient.URI := fURI;
fHttpClient.SendRequest;
fHttpClient.Waiting := True;
while fHttpClient.Waiting do begin
//WriteLn('InFirstLoop');
Application.HandleMessage;
if csDestroying in ComponentState then Exit;
end;
//WriteLn('LeftLoop');
Result := fHttpClient.Stream;
Result.Position := 0;
//fDataStream.SaveToFile('temp.txt');
//Application.Terminate;
fHttpClient.Free;
end;
function TIpHTTPDataProvider.GetHostAndURI(const fURL: String; var AHost: String; var AURI: String): Boolean;
var
fPos: Integer;
begin
fPos := Pos('://', fUrl);
if fPos = 0 then Exit(False);
Result := True;
AHost := Copy(fURL, fPos+3, Length(fURL));
fPos := Pos('/', AHost);
if fPos = 0 then begin
AURI:='/';
Exit(True);
end;
AURI := Copy(AHost, fPos, Length(AHost));
AHost := Copy(AHost, 1, fPos-1);
//WriteLn('Got Host: ',AHost);
//WriteLn('Got URI : ',AURI);
end;
function TIpHTTPDataProvider.DoGetHtmlStream(const URL: string;
PostData: TIpFormDataEntity): TStream;
begin
Result := GetURL(URL);
end;
function TIpHTTPDataProvider.DoCheckURL(const URL: string;
var ContentType: string): Boolean;
var
TmpStream: TStream;
begin
//WriteLn('Want content type: "', ContentType,'" for Url:',URL);
Result := True;
TmpStream := GetURL(URL, True);
if TmpStream <> nil then FreeAndNil(TmpStream);
ContentType := fLastType;//}'text/html';
end;
procedure TIpHTTPDataProvider.DoLeave(Html: TIpHtml);
begin
end;
procedure TIpHTTPDataProvider.DoReference(const URL: string);
begin
end;
procedure TIpHTTPDataProvider.DoGetImage(Sender: TIpHtmlNode;
const URL: string; var Picture: TPicture);
var
Stream: TMemoryStream = nil;
ImageClass: TFPCustomImageReaderClass;
ImageReader: TFPCustomImageReader;
OutImage: TFPWriterBMP= nil;
Img : TFPMemoryImage = nil;
FileExt: String;
begin
FileExt := ExtractFileExt(URL);
if FileExt[1] = '.' then Delete(FileExt,1,1);
ImageClass := GetFPImageReaderForFileExtension(FileExt);
if ImageClass = nil then begin
Stream := TMemoryStream(GetURL(URL));
//FreeAndNil(Stream);
if Pos('image/', fLastType) = 1 then FileExt := Copy(fLastType, 7, Length(fLastType));
//FileExt := ExtractFileExt(fLastType);
//WriteLn('Got FIleExt ',FileExt, ' for ',fLastType);
ImageClass := GetFPImageReaderForFileExtension(FileExt);
end;
//WriteLn('Getting Image ',(Url), ' Extension=',FileExt,' Image=nil=',BoolToStr(ImageClass=nil));
if ImageClass <> nil then begin
ImageReader := ImageClass.Create;
try
Picture := TPicture.Create;
Picture.Graphic := TBitmap.Create;
if Stream = nil then Stream := TMemoryStream(GetURL(URL));
if Stream = nil then exit;
Img := TFPMemoryImage.Create(0,0);
Img.UsePalette:=False;
Img.LoadFromStream(Stream, ImageReader);
Stream.Free;
Stream := TMemoryStream.Create;
OutImage := TFPWriterBMP.Create;
Img.SaveToStream(Stream, OutImage);
Stream.Position := 0;
Picture.Graphic.LoadFromStream(Stream);
finally
if Assigned(OutImage) then OutImage.Free;
if Assigned(Img) then Img.Free;
if Assigned(ImageReader) then ImageReader.Free;
if Assigned(Stream) then Stream.Free;
end;
end
else begin
// Couldn't find the picture we wanted.
FreeAndNil(Stream);
Picture := nil;
end;
end;
function TIpHTTPDataProvider.CanHandle(const URL: string): Boolean;
begin
//WriteLn('Can Handle: ', URL);
Result := True;
end;
function TIpHTTPDataProvider.BuildURL(const OldURL, NewURL: string): string;
begin
Result := Iputils.BuildURL(OldURL, NewURL);
end;
constructor TIpHTTPDataProvider.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
destructor TIpHTTPDataProvider.Destroy;
begin
inherited Destroy;
end;
end.