NSIS Menu POSIX fixes (bug #1144)

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6758 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2016-06-26 13:36:30 +00:00
parent 7fff5828ad
commit e922c1b182
6 changed files with 232 additions and 142 deletions

View file

@ -81,12 +81,14 @@ if env['PLATFORM'] != 'win32' and WhereIs('wx-config') or \
nsis_menu[0].env.ParseConfig('wx-config --cxxflags --libs')
# install menu files
env.DistributeMenu(html, alias='install-utils')
env.DistributeMenu(images, path='images', alias='install-utils')
else:
env.DistributeMenu(html, alias='install-utils')
env.DistributeMenu(images, path='images', alias='install-utils')
if env['PLATFORM'] != 'win32':
env.DistributeBin(resources);
else:
# no wxWidgets
def err(target, source, env):
if env['PLATFORM'] == 'win32':

View file

@ -23,12 +23,94 @@
#include <wx/image.h>
#include <wx/html/htmlwin.h>
#include <wx/html/htmlproc.h>
#include <wx/stdpaths.h>
#include <wx/utils.h>
#include <wx/stdpaths.h>
#include <wx/utils.h>
#include <nsis-sconf.h>
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
#if !wxCHECK_VERSION(2, 9, 0) && !defined(wxLaunchDefaultApplication)
#define wxLaunchDefaultApplication wxLaunchDefaultBrowser
#endif
#ifdef __WXMSW__
#define CanOpenChm() true
#else
#define CanOpenChm() false
#endif
typedef enum { SUT_UNKNOWN = 0, SUT_BIN = 0x14, SUT_DOC = 0x24, SUT_WEB = 0x34 } SPECIALURLTYPE; // The low nibble contains the "protocol" length!
SPECIALURLTYPE GetSpecialUrlType(const wxString&Url)
{
const wxString l4 = Url.Left(4);
if (0 == l4.CmpNoCase(wxT("BIN:"))) return SUT_BIN;
if (0 == l4.CmpNoCase(wxT("DOC:"))) return SUT_DOC;
if (0 == l4.CmpNoCase(wxT("WEB:"))) return SUT_WEB;
return SUT_UNKNOWN;
}
static bool PathExists(const wxString&Path) { return wxFileExists(Path) || wxDirExists(Path); }
static wxString BuildPathWorker(const wxChar*a, const wxChar*b)
{
wxString path(a);
if (path.Last() != wxFileName::GetPathSeparator()) path.Append(wxFileName::GetPathSeparator());
return (path.Append(b), path);
}
static const wxChar*GetCStr(const wxString&t) { return t.c_str(); }
static const wxChar*GetCStr(const wxChar*t) { return t; }
template<class A, class B> wxString BuildPath(const A&a, const B&b) { return BuildPathWorker(GetCStr(a), GetCStr(b)); }
template<class A, class B, class C> wxString BuildPath(const A&a, const B&b, const C&c) { return BuildPath(BuildPath(GetCStr(a), GetCStr(b)), GetCStr(c)); }
wxString GetMenuHtmlFile(const wxChar*file)
{
#ifdef __WXMSW__
wxString dataroot(wxPathOnly(wxStandardPaths::Get().GetExecutablePath()));
#else
const wxChar*dataroot = wxT(PREFIX_DATA);
#endif
return BuildPath(dataroot, wxT("Menu"), file);
}
SPECIALURLTYPE TransformUrl(wxString&Url)
{
SPECIALURLTYPE ut = GetSpecialUrlType(Url);
const wxString location = Url.Mid(ut & 0x0F);
const wxString exePath = wxPathOnly(wxStandardPaths::Get().GetExecutablePath());
if (SUT_BIN == ut)
{
#ifdef __WXMSW__
Url = BuildPath(exePath, location) + wxT(".exe");
if (!PathExists(Url))
Url = BuildPath(exePath, wxT("Bin"), location) + wxT(".exe");
#else
Url = BuildPath(exePath, location);
#endif
}
else if (SUT_DOC == ut)
{
#ifdef __WXMSW__
wxString path = BuildPath(exePath, location);
#else
wxString path = BuildPath(wxT(PREFIX_DOC), location);
#endif
if ((!CanOpenChm() || !wxFileExists(path)) && 0 == location.CmpNoCase(wxT("NSIS.chm")))
{
path = BuildPath(wxPathOnly(path), wxT("Docs"), wxT("Manual.html")); // DOCTYPES=htmlsingle
if (!wxFileExists(path))
path = BuildPath(wxPathOnly(path), wxT("Contents.html")); // DOCTYPES=html (Not adding /Docs/ because it has already been appended)
}
Url = path;
}
else if (SUT_WEB == ut)
{
Url = location;
}
return ut;
}
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
// Define a new application type, each program should derive a class from wxApp
class MyApp : public wxApp
@ -123,35 +205,39 @@ private:
// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------
#ifdef NSISMENU_NOLINKTAGHANDLER
static wxHtmlWindow*g_pHtmlWindow = 0;
#endif
// frame constructor
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size, wxCLOSE_BOX | wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION,
wxT("nsis_menu"))
{
m_Html = new wxHtmlWindow(this, HtmlControl);
m_Html->SetRelatedFrame(this, wxT("%s")); // Dialog caption comes from the html title element or filename
m_Html->SetBorders(0);
: wxFrame((wxFrame *)NULL, -1, title, pos, size, wxCLOSE_BOX | wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION,
wxT("nsis_menu"))
{
m_Html = new wxHtmlWindow(this, HtmlControl, wxPoint(0, 0), wxSize(HTMLW, HTMLH), wxHW_SCROLLBAR_NEVER|wxHW_NO_SELECTION);
m_Html->SetRelatedFrame(this, wxT("%s")); // Dialog caption comes from the html title element or filename
m_Html->SetBorders(0);
m_Html->EnableScrolling(false, false);
m_Html->SetSize(HTMLW, HTMLH);
// Set font size
wxSize DialogSize(1000, 1000);
#ifdef NSISMENU_NOLINKTAGHANDLER
g_pHtmlWindow = m_Html;
#endif
// Set font size
wxSize DialogSize(1000, 1000);
DialogSize = this->ConvertDialogToPixels(DialogSize);
int fonts[7] = {0, 0, 14000 / (DialogSize.GetWidth()), 19000 / (DialogSize.GetWidth()), 0, 0, 0};
m_Html->SetFonts(wxString(), wxString(), fonts);
wxString exePath = wxStandardPaths::Get().GetExecutablePath();
wxString path = ::wxPathOnly(exePath);
m_Html->LoadPage(path + wxT("\\Menu\\index.html"));
this->Centre(wxBOTH);
#ifndef __WXGTK__
this->SetIcon(wxICON(nsisicon));
int fonts[7] = {0, 0, 14000 / (DialogSize.GetWidth()), 19000 / (DialogSize.GetWidth()), 0, 0, 0};
m_Html->SetFonts(wxString(), wxString(), fonts);
#ifdef __WXMSW__
this->SetIcon(wxICON(nsisicon));
#else
wxIcon icon(wxT("nsisicon.ico"), wxBITMAP_TYPE_ICO);
this->SetIcon(icon);
#endif
}
m_Html->LoadPage(GetMenuHtmlFile(wxT("index.html")));
this->Centre(wxBOTH);
}
// event handler
void MyFrame::OnLink(wxHtmlLinkEvent& event)
@ -159,27 +245,27 @@ void MyFrame::OnLink(wxHtmlLinkEvent& event)
const wxMouseEvent *e = event.GetLinkInfo().GetEvent();
if (e == NULL || e->LeftUp())
{
const wxString href = event.GetLinkInfo().GetHref();
if (href.Left(3).IsSameAs((const wxChar*) wxT("EX:"), false))
{
wxString url = href.Mid(3);
if (url.Left(7).IsSameAs((const wxChar*) wxT("http://"), false) || url.Left(6).IsSameAs((const wxChar*) wxT("irc://"), false))
{
::wxLaunchDefaultBrowser(url);
}
else
{
wxString exePath = wxStandardPaths::Get().GetExecutablePath();
wxString path = ::wxPathOnly(exePath);
path.Append(wxFileName::GetPathSeparators()[0]);
path.Append(url);
::wxLaunchDefaultBrowser(path);
}
}
else
int notinstalled = false;
wxString href = event.GetLinkInfo().GetHref(), url = href;
SPECIALURLTYPE ut = TransformUrl(url);
switch(ut)
{
case SUT_BIN:
if (PathExists(url)) wxExecute(url); else ++notinstalled;
break;
case SUT_DOC:
if (PathExists(url)) wxLaunchDefaultApplication(url); else ++notinstalled;
break;
case SUT_WEB:
wxLaunchDefaultBrowser(url);
break;
default:
event.Skip();
}
#ifdef NSISMENU_NOLINKTAGHANDLER
if (notinstalled && g_pHtmlWindow)
g_pHtmlWindow->LoadPage(GetMenuHtmlFile(wxT("notinstalled.html")));
#endif
}
}

View file

@ -16,7 +16,7 @@
#pragma hdrstop
#endif
#if wxUSE_HTML && wxUSE_STREAMS
#if wxUSE_HTML && wxUSE_STREAMS && !defined(NSISMENU_NOLINKTAGHANDLER)
#ifndef WXPRECOMP
#endif
@ -24,12 +24,18 @@
#include "wx/html/forcelnk.h"
#include "wx/html/m_templ.h"
#include <wx/filefn.h>
#include <wx/stdpaths.h>
FORCE_LINK_ME(nslinks)
class wxHtmlAnchorCell : public wxHtmlCell
#include <wx/filefn.h>
#include <wx/stdpaths.h>
#include <nsis-sconf.h>
FORCE_LINK_ME(nslinks)
// TODO: These helper function declarations should be in a header file
typedef enum { SUT_UNKNOWN = 0, SUT_BIN = 0x14, SUT_DOC = 0x24, SUT_WEB = 0x34 } SPECIALURLTYPE;
SPECIALURLTYPE TransformUrl(wxString&Url);
class wxHtmlAnchorCell : public wxHtmlCell
{
private:
wxString m_AnchorName;
@ -44,45 +50,38 @@ public:
DECLARE_NO_COPY_CLASS(wxHtmlAnchorCell)
};
TAG_HANDLER_BEGIN(A, "A")
TAG_HANDLER_CONSTR(A) { }
TAG_HANDLER_PROC(tag)
{
TAG_HANDLER_BEGIN(A, "A")
TAG_HANDLER_CONSTR(A) { }
TAG_HANDLER_PROC(tag)
{
if (tag.HasParam( wxT("HREF") ))
{
wxHtmlLinkInfo oldlnk = m_WParser->GetLink();
wxColour oldclr = m_WParser->GetActualColor();
wxString name(tag.GetParam( wxT("HREF") )), target;
if (tag.HasParam( wxT("TARGET") )) target = tag.GetParam( wxT("TARGET") );
wxColour colour = m_WParser->GetLinkColor();
wxHtmlLinkInfo linkInfo(name, target);
if (name.Left(3).IsSameAs((const wxChar*) wxT("EX:"), false))
{
wxString url = name.Mid(3);
if (!url.Left(7).IsSameAs((const wxChar*) wxT("http://"), false) && !url.Left(6).IsSameAs((const wxChar*) wxT("irc://"), false))
{
wxString exePath = wxStandardPaths::Get().GetExecutablePath();
wxString path = ::wxPathOnly(exePath);
path.Append(wxFileName::GetPathSeparators()[0]);
path.Append(url);
if (!::wxFileExists(path) && !::wxDirExists(path))
{
colour = wxColour(0x80, 0x80, 0x80);
linkInfo = wxHtmlLinkInfo(wxT("notinstalled.html"), target);
}
}
}
m_WParser->SetActualColor(colour);
m_WParser->GetContainer()->InsertCell(new wxHtmlColourCell(colour));
{
wxHtmlLinkInfo oldlnk = m_WParser->GetLink();
wxColour oldclr = m_WParser->GetActualColor();
wxString href(tag.GetParam( wxT("HREF") )), target;
if (tag.HasParam( wxT("TARGET") )) target = tag.GetParam( wxT("TARGET") );
wxColour colour = m_WParser->GetLinkColor();
wxHtmlLinkInfo linkInfo(href, target);
wxString location = href;
SPECIALURLTYPE ut = TransformUrl(location);
if (ut == SUT_BIN || ut == SUT_DOC)
{
if (!wxFileExists(location) && !wxDirExists(location))
{
colour = wxColour(0x80, 0x80, 0x80);
linkInfo = wxHtmlLinkInfo(wxT("notinstalled.html"), target);
}
}
m_WParser->SetActualColor(colour);
m_WParser->GetContainer()->InsertCell(new wxHtmlColourCell(colour));
m_WParser->GetContainer()->InsertCell(new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
m_WParser->SetLink(linkInfo);
@ -95,18 +94,18 @@ TAG_HANDLER_BEGIN(A, "A")
return true;
}
else return false;
}
TAG_HANDLER_END(A)
TAGS_MODULE_BEGIN(CustomLinks)
TAGS_MODULE_ADD(A)
TAGS_MODULE_END(CustomLinks)
else return false;
}
TAG_HANDLER_END(A)
TAGS_MODULE_BEGIN(Links)
TAGS_MODULE_ADD(A)
TAGS_MODULE_END(Links)
#endif