diff --git a/Contrib/NSIS Menu/SConscript b/Contrib/NSIS Menu/SConscript index 22718ff4..6968ce63 100644 --- a/Contrib/NSIS Menu/SConscript +++ b/Contrib/NSIS Menu/SConscript @@ -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': diff --git a/Contrib/NSIS Menu/nsismenu/nsismenu.cpp b/Contrib/NSIS Menu/nsismenu/nsismenu.cpp index 9388d913..83c98141 100644 --- a/Contrib/NSIS Menu/nsismenu/nsismenu.cpp +++ b/Contrib/NSIS Menu/nsismenu/nsismenu.cpp @@ -23,12 +23,94 @@ #include #include #include -#include -#include +#include +#include + +#include + +// ---------------------------------------------------------------------------- +// 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 wxString BuildPath(const A&a, const B&b) { return BuildPathWorker(GetCStr(a), GetCStr(b)); } +template 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 } } diff --git a/Contrib/NSIS Menu/nsismenu/nslinks.cpp b/Contrib/NSIS Menu/nsismenu/nslinks.cpp index 3f17a0dc..9fbc2793 100644 --- a/Contrib/NSIS Menu/nsismenu/nslinks.cpp +++ b/Contrib/NSIS Menu/nsismenu/nslinks.cpp @@ -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 -#include - -FORCE_LINK_ME(nslinks) - -class wxHtmlAnchorCell : public wxHtmlCell +#include +#include + +#include + +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 diff --git a/Docs/src/history.but b/Docs/src/history.but index 19d6a3df..9ca348d7 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -8,7 +8,7 @@ Released on ???? ?nd, 2016 \S2{} Major Changes -\b Fixed LogicLib nested ${Select} bug +\b Fixed LogicLib nested $\{Select\} bug \S2{} Minor Changes @@ -16,6 +16,8 @@ Released on ???? ?nd, 2016 \b Added LogicLib & operator +\b NSIS Menu POSIX fixes (\W{http://sf.net/p/nsis/bugs/1144}{bug #1144}) + \S2{} Translations \b Minor tweaks to Danish.nlf (scootergrisen) (\W{http://sf.net/p/nsis/bugs/1140}{bug #1140}) diff --git a/Menu/index.html b/Menu/index.html index a197248e..063a3556 100644 --- a/Menu/index.html +++ b/Menu/index.html @@ -9,8 +9,8 @@

Compiler
- Compile NSI scripts
- Installer based on ZIP file
+ Compile NSI scripts
+ Installer based on ZIP file



@@ -18,39 +18,39 @@

Developer Center
Many more examples, tutorials, plug-ins and NSIS-related software are available - at the on-line Developer Center. + at the on-line Developer Center.

Documentation
- NSIS Users Manual
- Example scripts
- Modern UI 2
- Multi-User Header File
- StrFunc Header File

+ NSIS Users Manual
+ Example scripts
+ Modern UI 2
+ Multi-User Header File
+ StrFunc Header File

On-line help
- Forum
- FAQ
- IRC Channel
- Bug Tracker
+ Forum
+ FAQ
+ IRC Channel
+ Bug Tracker

Plug-ins
- AdvSplash - splash with fade in/out
- Banner - banner with custom text
- BgImage - background image
- Dialer - internet connection
- Math - math operations
- nsDialogs - custom wizard pages
- nsExec - launch command line tools
- NSISdl - download files
- Splash - splash screen
- StartMenu - Start Menu folder selection
- System - Windows API calls
- VPatch - update existing files

+ AdvSplash - splash with fade in/out
+ Banner - banner with custom text
+ BgImage - background image
+ Dialer - internet connection
+ Math - math operations
+ nsDialogs - custom wizard pages
+ nsExec - launch command line tools
+ NSISdl - download files
+ Splash - splash screen
+ StartMenu - Start Menu folder selection
+ System - Windows API calls
+ VPatch - update existing files

@@ -58,7 +58,7 @@

- +
diff --git a/SConstruct b/SConstruct index 0f42d4d2..e4efb16c 100644 --- a/SConstruct +++ b/SConstruct @@ -207,12 +207,13 @@ if defenv['DEBUG']: defenv.Append(CPPDEFINES = ['DEBUG']) # add prefixes defines -if 'NSIS_CONFIG_CONST_DATA_PATH' in defenv['NSIS_CPPDEFINES']: - defenv.Append(NSIS_CPPDEFINES = [('PREFIX_CONF', '"%s"' % defenv.subst('$PREFIX_CONF'))]) - defenv.Append(NSIS_CPPDEFINES = [('PREFIX_DATA', '"%s"' % defenv.subst('$PREFIX_DATA'))]) - -# Need this early for the config header files to be placed in -if defenv['UNICODE']: +if 'NSIS_CONFIG_CONST_DATA_PATH' in defenv['NSIS_CPPDEFINES']: + defenv.Append(NSIS_CPPDEFINES = [('PREFIX_CONF', '"%s"' % defenv.subst('$PREFIX_CONF'))]) + defenv.Append(NSIS_CPPDEFINES = [('PREFIX_DATA', '"%s"' % defenv.subst('$PREFIX_DATA'))]) + defenv.Append(NSIS_CPPDEFINES = [('PREFIX_DOC', '"%s"' % defenv.subst('$PREFIX_DOC'))]) + +# Need this early for the config header files to be placed in +if defenv['UNICODE']: if defenv['DEBUG']: defenv.Replace(BUILD_PREFIX = 'build/udebug') else: