
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4062 8e941d3f-bd1b-0410-a28a-d453659cc2b4
551 lines
14 KiB
ObjectPascal
551 lines
14 KiB
ObjectPascal
unit sHyperlinkForm;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ButtonPanel,
|
|
ExtCtrls, Buttons, StdCtrls, ComCtrls,
|
|
fpsTypes, fpspreadsheet;
|
|
|
|
type
|
|
|
|
{ THyperlinkForm }
|
|
|
|
THyperlinkForm = class(TForm)
|
|
Bevel1: TBevel;
|
|
BtnBrowseFile: TButton;
|
|
ButtonPanel1: TButtonPanel;
|
|
CbFtpServer: TComboBox;
|
|
CbFtpUsername: TComboBox;
|
|
CbFtpPassword: TComboBox;
|
|
CbHttpAddress: TComboBox;
|
|
CbFileBookmark: TComboBox;
|
|
CbWorksheets: TComboBox;
|
|
CbCellAddress: TComboBox;
|
|
CbFileName: TComboBox;
|
|
CbMailRecipient: TComboBox;
|
|
EdHttpBookmark: TEdit;
|
|
EdTooltip: TEdit;
|
|
EdMailSubject: TEdit;
|
|
GroupBox2: TGroupBox;
|
|
GbFileName: TGroupBox;
|
|
GbInternetLinkType: TGroupBox;
|
|
GbHttp: TGroupBox;
|
|
GbMailRecipient: TGroupBox;
|
|
GroupBox6: TGroupBox;
|
|
GbFileBookmark: TGroupBox;
|
|
GroupBox8: TGroupBox;
|
|
GbFtp: TGroupBox;
|
|
Images: TImageList;
|
|
HyperlinkInfo: TLabel;
|
|
Label1: TLabel;
|
|
LblFtpUserName: TLabel;
|
|
LblFtpPassword: TLabel;
|
|
LblHttpAddress: TLabel;
|
|
Label5: TLabel;
|
|
Label6: TLabel;
|
|
LblHttpBookmark: TLabel;
|
|
Notebook: TNotebook;
|
|
InternetNotebook: TNotebook;
|
|
OpenDialog: TOpenDialog;
|
|
PgHTTP: TPage;
|
|
PfFTP: TPage;
|
|
PgInternal: TPage;
|
|
PgFile: TPage;
|
|
PgInternet: TPage;
|
|
PgMail: TPage;
|
|
Panel2: TPanel;
|
|
RbFTP: TRadioButton;
|
|
RbHTTP: TRadioButton;
|
|
ToolBar: TToolBar;
|
|
TbInternal: TToolButton;
|
|
TbFile: TToolButton;
|
|
TbInternet: TToolButton;
|
|
TbMail: TToolButton;
|
|
procedure BtnBrowseFileClick(Sender: TObject);
|
|
procedure CbCellAddressEditingDone(Sender: TObject);
|
|
procedure CbFileBookmarkDropDown(Sender: TObject);
|
|
procedure CbFileNameEditingDone(Sender: TObject);
|
|
procedure CbFtpServerEditingDone(Sender: TObject);
|
|
procedure CbHttpAddressEditingDone(Sender: TObject);
|
|
procedure CbMailRecipientEditingDone(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure OKButtonClick(Sender: TObject);
|
|
procedure HTTP_FTP_Change(Sender: TObject);
|
|
procedure ToolButtonClick(Sender: TObject);
|
|
procedure UpdateHyperlinkInfo(Sender: TObject);
|
|
private
|
|
{ private declarations }
|
|
FWorkbook: TsWorkbook;
|
|
FWorksheet: TsWorksheet;
|
|
function GetHyperlinkTarget: String;
|
|
function GetHyperlinkTooltip: String;
|
|
procedure SetHyperlinkKind(AValue: Integer);
|
|
procedure SetHyperlinkTarget(const AValue: String);
|
|
procedure SetHyperlinkTooltip(const AValue: String);
|
|
procedure SetInternetLinkKind(AValue: Integer);
|
|
procedure SetWorksheet(AWorksheet: TsWorksheet);
|
|
protected
|
|
function GetHyperlinkKind: Integer;
|
|
function ValidData(out AControl: TWinControl; out AMsg: String): Boolean;
|
|
public
|
|
{ public declarations }
|
|
procedure GetHyperlink(out AHyperlink: TsHyperlink);
|
|
procedure SetHyperlink(AWorksheet: TsWorksheet; const AHyperlink: TsHyperlink);
|
|
end;
|
|
|
|
var
|
|
HyperlinkForm: THyperlinkForm;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
uses
|
|
URIParser,
|
|
fpsUtils;
|
|
|
|
const
|
|
TAG_INTERNAL = 0;
|
|
TAG_FILE = 1;
|
|
TAG_INTERNET = 2;
|
|
TAG_MAIL = 3;
|
|
|
|
TAG_HTTP = 0;
|
|
TAG_FTP = 1;
|
|
|
|
{ THyperlinkForm }
|
|
|
|
procedure THyperlinkForm.BtnBrowseFileClick(Sender: TObject);
|
|
begin
|
|
with OpenDialog do begin
|
|
Filename := CbFileName.Text;
|
|
if Execute then begin
|
|
InitialDir := ExtractFileDir(FileName);
|
|
CbFileName.Text := FileName;
|
|
if (CbFileName.Text <> '') and (CbFileName.Items.IndexOf(FileName) = -1) then
|
|
CbFilename.Items.Insert(0, FileName);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure THyperlinkForm.CbCellAddressEditingDone(Sender: TObject);
|
|
begin
|
|
CbCellAddress.Text := Uppercase(CbCellAddress.Text);
|
|
end;
|
|
|
|
procedure THyperlinkForm.CbFileBookmarkDropDown(Sender: TObject);
|
|
var
|
|
ext: String;
|
|
wb: TsWorkbook;
|
|
ws: TsWorksheet;
|
|
i: Integer;
|
|
begin
|
|
CbFileBookmark.Items.Clear;
|
|
if FileExists(CbFilename.Text) then begin
|
|
ext := Lowercase(ExtractFileExt(CbFileName.Text));
|
|
if (ext = '.xls') or (ext = '.xlsx') or (ext = '.ods') then begin
|
|
wb := TsWorkbook.Create;
|
|
try
|
|
wb.ReadFromFile(CbFileName.Text);
|
|
for i:=0 to wb.GetWorksheetCount-1 do
|
|
begin
|
|
ws := wb.GetWorksheetByIndex(i);
|
|
CbFileBookmark.Items.Add(ws.Name);
|
|
end;
|
|
finally
|
|
wb.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure THyperlinkForm.CbFileNameEditingDone(Sender: TObject);
|
|
begin
|
|
if (CbFilename.Text <> '') and
|
|
(CbFilename.Items.IndexOf(CbFilename.Text) = -1)
|
|
then
|
|
CbFileName.Items.Insert(0, CbFileName.Text);
|
|
end;
|
|
|
|
procedure THyperlinkForm.CbFtpServerEditingDone(Sender: TObject);
|
|
begin
|
|
if (CbFtpServer.Text <> '') and
|
|
(CbFtpServer.Items.IndexOf(CbFtpServer.Text) = -1)
|
|
then
|
|
CbFtpServer.Items.Insert(0, CbFtpServer.Text);
|
|
end;
|
|
|
|
procedure THyperlinkForm.CbHttpAddressEditingDone(Sender: TObject);
|
|
begin
|
|
if (CbHttpAddress.Text <> '') and
|
|
(CbHttpAddress.Items.Indexof(CbHttpAddress.Text) = -1)
|
|
then
|
|
CbHttpAddress.Items.Insert(0, CbHttpAddress.Text);
|
|
end;
|
|
|
|
procedure THyperlinkForm.CbMailRecipientEditingDone(Sender: TObject);
|
|
begin
|
|
if (CbMailRecipient.Text <> '') and
|
|
(CbMaiLRecipient.Items.IndexOf(CbMailRecipient.Text) = -1)
|
|
then
|
|
CbMailRecipient.Items.Insert(0, CbMailRecipient.Text);
|
|
end;
|
|
|
|
procedure THyperlinkForm.FormCreate(Sender: TObject);
|
|
begin
|
|
HTTP_FTP_Change(nil);
|
|
end;
|
|
|
|
procedure THyperlinkForm.GetHyperlink(out AHyperlink: TsHyperlink);
|
|
begin
|
|
AHyperlink.Target := GetHyperlinkTarget;
|
|
AHyperlink.Tooltip := GetHyperlinkTooltip;
|
|
end;
|
|
|
|
function THyperlinkForm.GetHyperlinkKind: Integer;
|
|
begin
|
|
for Result := 0 to Toolbar.ButtonCount-1 do
|
|
if Toolbar.Buttons[Result].Down then
|
|
exit;
|
|
Result := -1;
|
|
end;
|
|
|
|
function THyperlinkForm.GetHyperlinkTarget: String;
|
|
begin
|
|
Result := '';
|
|
case GetHyperlinkKind of
|
|
TAG_INTERNAL:
|
|
begin //internal
|
|
if (CbWorksheets.ItemIndex > 0) and (CbCellAddress.Text <> '') then
|
|
Result := '#' + CbWorksheets.Text + '!' + Uppercase(CbCellAddress.Text)
|
|
else if (CbWorksheets.ItemIndex > 0) then
|
|
Result := '#' + CbWorksheets.Text + '!'
|
|
else if (CbCellAddress.Text <> '') then
|
|
Result := '#' + Uppercase(CbCellAddress.Text);
|
|
end;
|
|
|
|
TAG_FILE:
|
|
begin // File
|
|
if FileNameIsAbsolute(CbFilename.Text) then
|
|
Result := FilenameToURI(CbFilename.Text)
|
|
else
|
|
Result := CbFilename.Text;
|
|
if CbFileBookmark.Text <> '' then
|
|
Result := Result + '#' + CbFileBookmark.Text;
|
|
end;
|
|
|
|
TAG_INTERNET:
|
|
begin // Internet link
|
|
if RbHttp.Checked and (CbHttpAddress.Text <> '') then
|
|
begin
|
|
if pos('http', Lowercase(CbHttpAddress.Text)) = 1 then
|
|
Result := CbHttpAddress.Text
|
|
else
|
|
Result := 'http://' + CbHttpAddress.Text;
|
|
if EdHttpBookmark.Text <> '' then
|
|
Result := Result + '#' + EdHttpBookmark.Text;
|
|
end else
|
|
if RbFtp.Checked and (CbFtpServer.Text <> '') then
|
|
begin
|
|
if (CbFtpUsername.Text <> '') and (CbFtpPassword.Text <> '') then
|
|
Result := Format('ftp://%s:%s@%s', [CbFtpUsername.Text, CbFtpPassword.Text, CbFtpServer.Text])
|
|
else
|
|
if (CbFtpUsername.Text <> '') and (CbFtpPassword.Text = '') then
|
|
Result := Format('ftp://%s@%s', [CbFtpUsername.Text , CbFtpServer.Text])
|
|
else
|
|
Result := 'ftp://anonymous@' + CbFtpServer.Text;
|
|
end;
|
|
end;
|
|
|
|
TAG_MAIL:
|
|
begin // Mail
|
|
if EdMailSubject.Text <> '' then
|
|
Result := Format('mailto:%s?subject=%s', [CbMailRecipient.Text, EdMailSubject.Text])
|
|
else
|
|
Result := Format('mailto:%s', [CbMailRecipient.Text]);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function THyperlinkForm.GetHyperlinkTooltip: String;
|
|
begin
|
|
Result := EdTooltip.Text;
|
|
end;
|
|
|
|
procedure THyperlinkForm.OKButtonClick(Sender: TObject);
|
|
var
|
|
C: TWinControl;
|
|
msg: String;
|
|
begin
|
|
if not ValidData(C, msg) then begin
|
|
C.SetFocus;
|
|
MessageDlg(msg, mtError, [mbOK], 0);
|
|
ModalResult := mrNone;
|
|
end;
|
|
end;
|
|
|
|
procedure THyperlinkForm.HTTP_FTP_Change(Sender: TObject);
|
|
begin
|
|
if RbHTTP.Checked then
|
|
InternetNotebook.PageIndex := 0;
|
|
if RbFTP.Checked then
|
|
InternetNotebook.PageIndex := 1;
|
|
UpdateHyperlinkInfo(nil);
|
|
end;
|
|
|
|
procedure THyperlinkForm.SetHyperlink(AWorksheet: TsWorksheet;
|
|
const AHyperlink: TsHyperlink);
|
|
begin
|
|
SetWorksheet(AWorksheet);
|
|
SetHyperlinkTarget(AHyperlink.Target);
|
|
SetHyperlinkTooltip(AHyperlink.Tooltip);
|
|
end;
|
|
|
|
procedure THyperlinkForm.SetHyperlinkKind(AValue: Integer);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i:=0 to Toolbar.ButtonCount-1 do
|
|
Toolbar.Buttons[i].Down := (AValue = Toolbar.Buttons[i].Tag);
|
|
Notebook.PageIndex := AValue;
|
|
end;
|
|
|
|
procedure THyperlinkForm.SetHyperlinkTarget(const AValue: String);
|
|
var
|
|
u: TURI;
|
|
sheet: TsWorksheet;
|
|
c,r: Cardinal;
|
|
i, idx: Integer;
|
|
p: Integer;
|
|
fn, bm: String;
|
|
begin
|
|
if AValue = '' then
|
|
begin
|
|
CbWorksheets.ItemIndex := 0;
|
|
CbCellAddress.Text := '';
|
|
|
|
CbMailRecipient.Text := '';
|
|
EdMailSubject.Text := '';
|
|
|
|
UpdateHyperlinkInfo(nil);
|
|
exit;
|
|
end;
|
|
|
|
// Internal link
|
|
if pos('#', AValue) = 1 then begin
|
|
SetHyperlinkKind(TAG_INTERNAL);
|
|
if FWorkbook.TryStrToCell(Copy(AValue, 2, Length(AValue)), sheet, r, c) then
|
|
begin
|
|
if (sheet = nil) or (sheet = FWorksheet) then
|
|
CbWorksheets.ItemIndex := 0
|
|
else
|
|
begin
|
|
idx := 0;
|
|
for i:=1 to CbWorksheets.Items.Count-1 do
|
|
if CbWorksheets.Items[i] = sheet.Name then
|
|
begin
|
|
idx := i;
|
|
break;
|
|
end;
|
|
CbWorksheets.ItemIndex := idx;
|
|
end;
|
|
CbCellAddress.Text := GetCellString(r, c);
|
|
UpdateHyperlinkInfo(nil);
|
|
end else begin
|
|
HyperlinkInfo.Caption := AValue;
|
|
MessageDlg(Format('Sheet not found in hyperlink "%s"', [AValue]), mtError,
|
|
[mbOK], 0);
|
|
end;
|
|
exit;
|
|
end;
|
|
|
|
// external links
|
|
u := ParseURI(AValue);
|
|
|
|
// File with absolute path
|
|
if SameText(u.Protocol, 'file') then
|
|
begin
|
|
SetHyperlinkKind(TAG_FILE);
|
|
UriToFilename(AValue, fn);
|
|
CbFilename.Text := fn;
|
|
CbFileBookmark.Text := u.Bookmark;
|
|
UpdateHyperlinkInfo(nil);
|
|
exit;
|
|
end;
|
|
|
|
// Mail
|
|
if SameText(u.Protocol, 'mailto') then
|
|
begin
|
|
SetHyperlinkKind(TAG_MAIL);
|
|
CbMailRecipient.Text := u.Document;
|
|
if CbMailRecipient.Items.IndexOf(u.Document) = -1 then
|
|
CbMailRecipient.Items.Insert(0, u.Document);
|
|
if (u.Params <> '') then
|
|
begin
|
|
p := pos('subject=', u.Params);
|
|
if p <> 0 then
|
|
EdMailSubject.Text := copy(u.Params, p+Length('subject='), MaxInt);
|
|
end;
|
|
UpdateHyperlinkInfo(nil);
|
|
exit;
|
|
end;
|
|
|
|
// http
|
|
if SameText(u.Protocol, 'http') or SameText(u.Protocol, 'https') then
|
|
begin
|
|
SetHyperlinkKind(TAG_INTERNET);
|
|
SetInternetLinkKind(TAG_HTTP);
|
|
CbHttpAddress.Text := u.Host;
|
|
EdHttpBookmark.Text := u.Bookmark;
|
|
UpdateHyperlinkInfo(nil);
|
|
exit;
|
|
end;
|
|
|
|
// ftp
|
|
if SameText(u.Protocol, 'ftp') then
|
|
begin
|
|
SetHyperlinkKind(TAG_INTERNET);
|
|
SetInternetLinkKind(TAG_FTP);
|
|
CbFtpServer.Text := u.Host;
|
|
CbFtpUserName.text := u.UserName;
|
|
CbFtpPassword.Text := u.Password;
|
|
UpdateHyperlinkInfo(nil);
|
|
exit;
|
|
end;
|
|
|
|
// If we get there it must be a local file with relative path
|
|
SetHyperlinkKind(TAG_FILE);
|
|
SplitHyperlink(AValue, fn, bm);
|
|
CbFileName.Text := fn;
|
|
CbFileBookmark.Text := bm;
|
|
UpdateHyperlinkInfo(nil);
|
|
end;
|
|
|
|
procedure THyperlinkForm.SetHyperlinkTooltip(const AValue: String);
|
|
begin
|
|
EdTooltip.Text := AValue;
|
|
end;
|
|
|
|
procedure THyperlinkForm.SetInternetLinkKind(AValue: Integer);
|
|
begin
|
|
RbHttp.Checked := AValue = TAG_HTTP;
|
|
RbFtp.Checked := AValue = TAG_FTP;
|
|
InternetNotebook.PageIndex := AValue;
|
|
end;
|
|
|
|
procedure THyperlinkForm.SetWorksheet(AWorksheet: TsWorksheet);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
FWorksheet := AWorksheet;
|
|
if FWorksheet = nil then
|
|
raise Exception.Create('[THyperlinkForm.SetWorksheet] Worksheet cannot be nil.');
|
|
FWorkbook := FWorksheet.Workbook;
|
|
|
|
CbWorksheets.Items.Clear;
|
|
CbWorksheets.Items.Add('(current worksheet)');
|
|
for i:=0 to FWorkbook.GetWorksheetCount-1 do
|
|
CbWorksheets.Items.Add(FWorkbook.GetWorksheetByIndex(i).Name);
|
|
end;
|
|
|
|
procedure THyperlinkForm.ToolButtonClick(Sender: TObject);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Notebook.PageIndex := TToolButton(Sender).Tag;
|
|
for i:=0 to Toolbar.ButtonCount-1 do
|
|
Toolbar.Buttons[i].Down := Toolbar.Buttons[i].Tag = TToolbutton(Sender).Tag;
|
|
UpdateHyperlinkInfo(nil);
|
|
end;
|
|
|
|
procedure THyperlinkForm.UpdateHyperlinkInfo(Sender: TObject);
|
|
var
|
|
s: String;
|
|
begin
|
|
s := GetHyperlinkTarget;
|
|
if s = '' then s := #32;
|
|
HyperlinkInfo.Caption := s;
|
|
end;
|
|
|
|
function THyperlinkForm.ValidData(out AControl: TWinControl;
|
|
out AMsg: String): Boolean;
|
|
var
|
|
r,c: Cardinal;
|
|
begin
|
|
Result := false;
|
|
AMsg := '';
|
|
AControl := nil;
|
|
|
|
case GetHyperlinkKind of
|
|
TAG_INTERNAL:
|
|
begin
|
|
if CbCellAddress.Text = '' then
|
|
begin
|
|
AMsg := 'No cell address specified.';
|
|
AControl := CbCellAddress;
|
|
exit;
|
|
end;
|
|
if not ParseCellString(CbCellAddress.Text, r, c) then
|
|
begin
|
|
AMsg := Format('"%s" is not a valid cell address.', [CbCellAddress.Text]);
|
|
AControl := CbCellAddress;
|
|
exit;
|
|
end;
|
|
if (CbWorksheets.Items.IndexOf(CbWorksheets.Text) = -1) and (CbWorksheets.ItemIndex <> 0) then
|
|
begin
|
|
AMsg := Format('Worksheet "%s" does not exist.', [CbWorksheets.Text]);
|
|
AControl := CbWorksheets;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
TAG_FILE:
|
|
begin
|
|
if CbFilename.Text = '' then
|
|
begin
|
|
AMsg := 'No filename specified.';
|
|
AControl := CbFileName;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
TAG_INTERNET:
|
|
if RbHttp.Checked then
|
|
begin
|
|
if CbHttpAddress.Text = '' then
|
|
begin
|
|
AMsg := 'URL of web site not specified.';
|
|
AControl := CbHttpAddress;
|
|
exit;
|
|
end;
|
|
end else
|
|
if RbFtp.Checked then
|
|
begin
|
|
if CbFtpServer.Text = '' then
|
|
begin
|
|
AMsg := 'Ftp server not specified.';
|
|
AControl := CbFtpServer;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
TAG_MAIL:
|
|
begin
|
|
if CbMailRecipient.Text = '' then
|
|
begin
|
|
AMsg := 'No mail recipient specified.';
|
|
AControl := CbMailRecipient;
|
|
exit;
|
|
end;
|
|
// Check e-mail address here also!
|
|
end;
|
|
end;
|
|
Result := true;
|
|
end;
|
|
|
|
end.
|
|
|