[Libreoffice-commits] core.git: sfx2/source

Olivier Hallot olivier.hallot at libreoffice.org
Fri Jan 19 12:01:25 UTC 2018


 sfx2/source/appl/sfxhelp.cxx |  259 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 206 insertions(+), 53 deletions(-)

New commits:
commit 3feafa82dd2cbb16423a69f7bacef5524376cc7a
Author: Olivier Hallot <olivier.hallot at 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.hallot at libreoffice.org>
    Tested-by: Olivier Hallot <olivier.hallot at 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)


More information about the Libreoffice-commits mailing list