sfx2/source/appl/sfxhelp.cxx | 259 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 206 insertions(+), 53 deletions(-)
New commits: commit 3feafa82dd2cbb16423a69f7bacef5524376cc7a Author: Olivier Hallot <olivier.hal...@libreoffice.org> Date: Thu Jan 4 08:32:12 2018 -0200 Call new help With contributions from Kendy Call new help * If LibreOffice online, call help online * If no local help, call help online else call offline html help if offline help return false, call old-help * left tempfile to be deleted when LO exits (ESC) * hasHelp function now check if the right locale exist Change-Id: I14893e8ba4998773706b9cf8164636475d1f2356 Fix HIDs with a ':' inside Change-Id: I17b7c96b6b0003e8d933131b7b251f3191389a0f Call new help directly, fix locale issue Avoid passing by a html file that is necessary only in the online case. Fix path location of help/ folder Implement fall back in languages locale -> lang -> en-US. If none of the theree above, call online help with locale. fix scope Change-Id: If92673594c92e0d5a6064bc0e0bb4b66a52730ec Reviewed-on: https://gerrit.libreoffice.org/47748 Reviewed-by: Olivier Hallot <olivier.hal...@libreoffice.org> Tested-by: Olivier Hallot <olivier.hal...@libreoffice.org> diff --git a/sfx2/source/appl/sfxhelp.cxx b/sfx2/source/appl/sfxhelp.cxx index bdfba5d88435..f90e2e7d0a6b 100644 --- a/sfx2/source/appl/sfxhelp.cxx +++ b/sfx2/source/appl/sfxhelp.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <config_folders.h> #include <sfx2/sfxhelp.hxx> #include <set> @@ -46,9 +47,11 @@ #include <ucbhelper/content.hxx> #include <unotools/pathoptions.hxx> #include <rtl/ustring.hxx> +#include <officecfg/Office/Common.hxx> #include <osl/process.h> #include <osl/file.hxx> #include <unotools/bootstrap.hxx> +#include <unotools/tempfile.hxx> #include <rtl/uri.hxx> #include <vcl/commandinfoprovider.hxx> #include <vcl/layout.hxx> @@ -98,10 +101,98 @@ void NoHelpErrorBox::RequestHelp( const HelpEvent& ) // do nothing, because no help available } -static bool impl_hasHelpInstalled( const OUString &rLang ); +static OUString HelpLocaleString(); + +namespace { + +/// Root path of the help. +OUString getHelpRootURL() +{ + static OUString s_instURL; + if (!s_instURL.isEmpty()) + return s_instURL; + + s_instURL = officecfg::Office::Common::Path::Current::Help::get(comphelper::getProcessComponentContext()); + if (s_instURL.isEmpty()) + { + // try to determine path from default + s_instURL = "$(instpath)/" LIBO_SHARE_HELP_FOLDER; + } + + // replace anything like $(instpath); + SvtPathOptions aOptions; + s_instURL = aOptions.SubstituteVariable(s_instURL); + + OUString url; + if (osl::FileBase::getFileURLFromSystemPath(s_instURL, url) == osl::FileBase::E_None) + s_instURL = url; + + return s_instURL; +} + +bool impl_checkHelpLocalePath(OUString& rpPath) +{ + osl::DirectoryItem directoryItem; + bool bOK = false; + + osl::FileStatus fileStatus(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL | osl_FileStatus_Mask_FileName); + if (osl::DirectoryItem::get(rpPath, directoryItem) == osl::FileBase::E_None && + directoryItem.getFileStatus(fileStatus) == osl::FileBase::E_None && + fileStatus.isDirectory()) + { + bOK = true; + } + return bOK; +} + +/// Check for built-in help +/// Check if help//lang folder exist +bool impl_hasHelpInstalled() +{ + if (comphelper::LibreOfficeKit::isActive()) + return false; + + static OUString aLocaleStr; + + if (aLocaleStr.isEmpty()) + { + // detect installed locale + aLocaleStr = HelpLocaleString(); + } + + OUString helpRootURL = getHelpRootURL() + "/" + aLocaleStr; + + bool bOK = impl_checkHelpLocalePath( helpRootURL ); + return bOK; +} + + +/// Check for html built-in help +/// Check if help/productversion/lang folder exist +bool impl_hasHTMLHelpInstalled() +{ + if (comphelper::LibreOfficeKit::isActive()) + return false; + + static OUString aLocaleStr; + + if (aLocaleStr.isEmpty()) + { + // detect installed locale + aLocaleStr = HelpLocaleString(); + } + + OUString helpRootURL = getHelpRootURL() + "/" + utl::ConfigManager::getProductVersion() + "/" + aLocaleStr; + + bool bOK = impl_checkHelpLocalePath( helpRootURL ); + return bOK; +} + +} // namespace /// Return the locale we prefer for displaying help -static OUString const & HelpLocaleString() +// static OUString const & HelpLocaleString() +static OUString HelpLocaleString() { if (comphelper::LibreOfficeKit::isActive()) return comphelper::LibreOfficeKit::getLanguageTag().getBcp47(); @@ -109,42 +200,66 @@ static OUString const & HelpLocaleString() static OUString aLocaleStr; if (aLocaleStr.isEmpty()) { - const OUString aEnglish( "en" ); - // obtain selected UI language (/org.openoffice.Setup/L10N/ooLocale) + const OUString aEnglish("en-US"); + // detect installed locale aLocaleStr = utl::ConfigManager::getLocale(); - bool bOk = !aLocaleStr.isEmpty(); - if ( !bOk ) + + if ( aLocaleStr.isEmpty() ) aLocaleStr = aEnglish; else { - OUString aBaseInstallPath; - utl::Bootstrap::locateBaseInstallation(aBaseInstallPath); - static const char szHelpPath[] = "/help/"; - - // Use a fallback chain starting from full tag, which here usually - // is only the language hence only one value, but can also be en-US - // or ca-valencia or include script tags. - std::vector< OUString > aFallbacks( LanguageTag( aLocaleStr).getFallbackStrings( true)); - for (auto const& rTag : aFallbacks) + // get fall-back langage (country) + OUString sLang = aLocaleStr ; + sal_Int32 nSepPos = sLang.indexOf( '-' ); + if (nSepPos != -1) { - OUString sHelpPath( aBaseInstallPath + szHelpPath + rTag); - osl::DirectoryItem aDirItem; - if (osl::DirectoryItem::get(sHelpPath, aDirItem) == osl::FileBase::E_None) - { - aLocaleStr = rTag; - bOk = true; - break; - } + sLang = sLang.copy( 0, nSepPos ); + } + OUString sHelpPath(""); + sHelpPath = getHelpRootURL() + "/" + utl::ConfigManager::getProductVersion() + "/" + aLocaleStr; + if (impl_checkHelpLocalePath(sHelpPath)) + { + return aLocaleStr; + } + sHelpPath = getHelpRootURL() + "/" + utl::ConfigManager::getProductVersion() + "/" + sLang; + if (impl_checkHelpLocalePath(sHelpPath)) + { + aLocaleStr = sLang; + return aLocaleStr; } + sHelpPath = getHelpRootURL() + "/" + aLocaleStr; + if (impl_checkHelpLocalePath(sHelpPath)) + { + return aLocaleStr; + } + sHelpPath = getHelpRootURL() + "/" + sLang; + if (impl_checkHelpLocalePath(sHelpPath)) + { + aLocaleStr = sLang; + return aLocaleStr; + } + + sHelpPath = sHelpPath = getHelpRootURL() + "/" + utl::ConfigManager::getProductVersion() + "/" + aEnglish; + if (impl_checkHelpLocalePath(sHelpPath)) + { + return aEnglish; + } + sHelpPath = getHelpRootURL() + "/" + aEnglish; + if (impl_checkHelpLocalePath(sHelpPath)) + { + aLocaleStr = sLang; + return aEnglish; + } + aLocaleStr = utl::ConfigManager::getLocale(); + return aLocaleStr; } - // if not OK, and not even English installed, we use online help, and - // have to preserve the full locale name - if ( !bOk && impl_hasHelpInstalled( aEnglish ) ) - aLocaleStr = aEnglish; } + return aLocaleStr; } + + void AppendConfigToken( OUStringBuffer& rURL, bool bQuestionMark, const OUString &rLang ) { OUString aLocaleStr( rLang ); @@ -508,19 +623,6 @@ OUString SfxHelp::GetHelpText( const OUString& aCommandURL, const vcl::Window* p return sHelpText; } -/// Check for built-in help -static bool impl_hasHelpInstalled( const OUString &rLang = OUString() ) -{ - if (comphelper::LibreOfficeKit::isActive()) - return false; - - OUStringBuffer aHelpRootURL("vnd.sun.star.help://"); - AppendConfigToken(aHelpRootURL, true, rLang); - std::vector< OUString > aFactories = SfxContentHelper::GetResultSet(aHelpRootURL.makeStringAndClear()); - - return !aFactories.empty(); -} - bool SfxHelp::SearchKeyword( const OUString& rKeyword ) { return Start_Impl( OUString(), nullptr, rKeyword ); @@ -566,6 +668,48 @@ static bool impl_showOnlineHelp( const OUString& rURL ) return false; } +#define SHTML1 "<!DOCTYPE HTML><html lang=\"en-US\"><head><meta charset=\"UTF-8\">" +#define SHTML2 "<meta http-equiv=\"refresh\" content=\"1\" url=\"" +#define SHTML3 "\"><script type=\"text/javascript\"> window.location.href = \"" +#define SHTML4 "\";</script><title>Help Page Redirection</title></head><body></body></html>" + +static bool impl_showOfflineHelp( const OUString& rURL ) +{ + OUString aBaseInstallPath = getHelpRootURL(); + OUString aInternal( "vnd.sun.star.help://" ); + + OUString aHelpLink( aBaseInstallPath + "/" + utl::ConfigManager::getProductVersion() + "/index.html?" ); + aHelpLink += rURL.copy( aInternal.getLength() ); + aHelpLink = aHelpLink.replaceAll("%2F","/").replaceAll("%3A",":"); + + // get a html tempfile + OUString const aExtension(".html"); + ::utl::TempFile aTempFile("NewHelp", true, &aExtension, nullptr, false ); + + SvStream* pStream = aTempFile.GetStream(StreamMode::WRITE); + pStream->SetStreamCharSet(RTL_TEXTENCODING_UTF8); + + OUString aTempStr(SHTML1 SHTML2); + aTempStr += aHelpLink + SHTML3; + aTempStr += aHelpLink + SHTML4; + + pStream->WriteUnicodeOrByteText(aTempStr); + + aTempFile.CloseStream(); + + try + { + sfx2::openUriExternally(aTempFile.GetURL(), false); + return true; + } + catch (const Exception&) + { + } + aTempFile.EnableKillingFile(); + return false; +} + + bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const OUString& rKeyword) { OUStringBuffer aHelpRootURL("vnd.sun.star.help://"); @@ -573,16 +717,16 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const SfxContentHelper::GetResultSet(aHelpRootURL.makeStringAndClear()); /* rURL may be - - a "real" URL - - a HelpID (formerly a long, now a string) - If rURL is a URL, CreateHelpURL should be called for this URL - If rURL is an arbitrary string, the same should happen, but the URL should be tried out - if it delivers real help content. In case only the Help Error Document is returned, the - parent of the window for that help was called, is asked for its HelpID. - For compatibility reasons this upward search is not implemented for "real" URLs. - Help keyword search now is implemented as own method; in former versions it - was done via Help::Start, but this implementation conflicted with the upward search. - */ + * - a "real" URL + * - a HelpID (formerly a long, now a string) + * If rURL is a URL, CreateHelpURL should be called for this URL + * If rURL is an arbitrary string, the same should happen, but the URL should be tried out + * if it delivers real help content. In case only the Help Error Document is returned, the + * parent of the window for that help was called, is asked for its HelpID. + * For compatibility reasons this upward search is not implemented for "real" URLs. + * Help keyword search now is implemented as own method; in former versions it + * was done via Help::Start, but this implementation conflicted with the upward search. + */ OUString aHelpURL; INetURLObject aParser( rURL ); INetProtocol nProtocol = aParser.GetProtocol(); @@ -614,6 +758,7 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const { OString aHelpId = pParent->GetHelpId(); aHelpURL = CreateHelpURL( OStringToOUString(aHelpId, RTL_TEXTENCODING_UTF8), aHelpModuleName ); + if ( !SfxContentHelper::IsHelpErrorDocument( aHelpURL ) ) { break; @@ -625,6 +770,7 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const { // create help url of start page ( helpid == 0 -> start page) aHelpURL = CreateHelpURL( OUString(), aHelpModuleName ); + } else if (pParent->IsDialog() && !bTriedTabPage) { @@ -652,10 +798,16 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const return true; } + if ( impl_hasHTMLHelpInstalled() ) + { + impl_showOfflineHelp(aHelpURL); + return true; + } + if ( !impl_hasHelpInstalled() ) { ScopedVclPtrInstance< MessageDialog > aQueryBox(const_cast< vcl::Window* >( pWindow ), - "onlinehelpmanual", "sfx/ui/helpmanual.ui"); + "onlinehelpmanual", "sfx/ui/helpmanual.ui"); LanguageTag aLangTag = Application::GetSettings().GetUILanguageTag(); OUString sLocaleString = SvtLanguageTable::GetLanguageString( aLangTag.getLanguageType() ); @@ -680,7 +832,7 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const } } - + // old-help to display Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() ); // check if help window is still open @@ -688,7 +840,7 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const // search must be done here; search one desktop level could return an arbitrary frame Reference< XFrame2 > xHelp( xDesktop->findFrame( "OFFICE_HELP_TASK", FrameSearchFlag::CHILDREN), - UNO_QUERY); + UNO_QUERY); Reference< XFrame > xHelpContent = xDesktop->findFrame( "OFFICE_HELP", FrameSearchFlag::CHILDREN); @@ -713,6 +865,7 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const xTopWindow->toFront(); return true; + } OUString SfxHelp::CreateHelpURL(const OUString& aCommandURL, const OUString& rModuleName) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits