[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.0' - 2 commits - desktop/source include/LibreOfficeKit libreofficekit/source

Jan Holesovsky kendy at collabora.com
Wed Feb 3 10:34:29 UTC 2016


 desktop/source/lib/init.cxx                  |   39 ++-
 desktop/source/lib/lokinteractionhandler.cxx |  284 +++++++++++++++++++++------
 desktop/source/lib/lokinteractionhandler.hxx |   33 ++-
 include/LibreOfficeKit/LibreOfficeKitEnums.h |   14 +
 libreofficekit/source/gtk/lokdocview.cxx     |   21 +
 5 files changed, 313 insertions(+), 78 deletions(-)

New commits:
commit 64c1690fa31937bb4adfe0eb7beb42f105841c3b
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Tue Feb 2 22:59:34 2016 +0100

    lok interaction handler: Add handling of io and network errors.
    
    Change-Id: If7c84a7b24f2072439718fb0c473b73243f2ecc1

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 0fbece0..c4d4450 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -271,7 +271,7 @@ static OUString getAbsoluteURL(const char* pURL)
     return OUString();
 }
 
-static void jsonToPropertyValues(const char* pJSON, uno::Sequence<beans::PropertyValue>& rPropertyValues)
+static std::vector<beans::PropertyValue> jsonToPropertyValuesVector(const char* pJSON)
 {
     std::vector<beans::PropertyValue> aArguments;
     if (pJSON)
@@ -298,11 +298,11 @@ static void jsonToPropertyValues(const char* pJSON, uno::Sequence<beans::Propert
             else if (rType == "unsigned short")
                 aValue.Value <<= static_cast<sal_uInt16>(OString(rValue.c_str()).toUInt32());
             else
-                SAL_WARN("desktop.lib", "jsonToPropertyValues: unhandled type '"<<rType<<"'");
+                SAL_WARN("desktop.lib", "jsonToPropertyValuesVector: unhandled type '"<<rType<<"'");
             aArguments.push_back(aValue);
         }
     }
-    rPropertyValues = comphelper::containerToSequence(aArguments);
+    return aArguments;
 }
 
 extern "C"
@@ -549,7 +549,7 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
                                                        beans::PropertyState_DIRECT_VALUE);
 
         rtl::Reference<LOKInteractionHandler> const pInteraction(
-            new LOKInteractionHandler(::comphelper::getProcessComponentContext(), pLib));
+            new LOKInteractionHandler(::comphelper::getProcessComponentContext(), "load", pLib));
         auto const pair(pLib->mInteractionMap.insert(std::make_pair(aURL.toUtf8(), pInteraction)));
         uno::Reference<task::XInteractionHandler2> const xInteraction(pInteraction.get());
         aFilterOptions[1].Name = "InteractionHandler";
@@ -1034,9 +1034,9 @@ static void doc_initializeForRendering(LibreOfficeKitDocument* pThis,
     if (pDoc)
     {
         doc_iniUnoCommands();
-        uno::Sequence<beans::PropertyValue> aPropertyValues;
-        jsonToPropertyValues(pArguments, aPropertyValues);
-        pDoc->initializeForTiledRendering(aPropertyValues);
+
+        pDoc->initializeForTiledRendering(
+                comphelper::containerToSequence(jsonToPropertyValuesVector(pArguments)));
     }
 }
 
@@ -1126,20 +1126,33 @@ public:
 static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pCommand, const char* pArguments, bool bNotifyWhenFinished)
 {
     OUString aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8);
+    LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
 
-    uno::Sequence<beans::PropertyValue> aPropertyValues;
-    jsonToPropertyValues(pArguments, aPropertyValues);
-    bool bResult = false;
+    std::vector<beans::PropertyValue> aPropertyValuesVector(jsonToPropertyValuesVector(pArguments));
 
-    LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
+    // handle potential interaction
+    if (aCommand == ".uno:Save")
+    {
+        rtl::Reference<LOKInteractionHandler> const pInteraction(
+            new LOKInteractionHandler(::comphelper::getProcessComponentContext(), "save", gImpl, pDocument));
+        uno::Reference<task::XInteractionHandler2> const xInteraction(pInteraction.get());
+
+        beans::PropertyValue aValue;
+        aValue.Name = "InteractionHandler";
+        aValue.Value <<= xInteraction;
+
+        aPropertyValuesVector.push_back(aValue);
+    }
+
+    bool bResult = false;
 
     if (bNotifyWhenFinished && pDocument->mpCallback)
     {
-        bResult = comphelper::dispatchCommand(aCommand, aPropertyValues,
+        bResult = comphelper::dispatchCommand(aCommand, comphelper::containerToSequence(aPropertyValuesVector),
                 new DispatchResultListener(pCommand, pDocument->mpCallback, pDocument->mpCallbackData));
     }
     else
-        bResult = comphelper::dispatchCommand(aCommand, aPropertyValues);
+        bResult = comphelper::dispatchCommand(aCommand, comphelper::containerToSequence(aPropertyValuesVector));
 
     if (!bResult)
     {
diff --git a/desktop/source/lib/lokinteractionhandler.cxx b/desktop/source/lib/lokinteractionhandler.cxx
index 86f521e..a4a60c2 100644
--- a/desktop/source/lib/lokinteractionhandler.cxx
+++ b/desktop/source/lib/lokinteractionhandler.cxx
@@ -19,12 +19,21 @@
 
 #include "lokinteractionhandler.hxx"
 
+#include <boost/property_tree/json_parser.hpp>
+
 #include <rtl/ref.hxx>
 #include <cppuhelper/supportsservice.hxx>
 
 #include <com/sun/star/task/XInteractionAbort.hpp>
 #include <com/sun/star/task/XInteractionApprove.hpp>
 #include <com/sun/star/task/XInteractionPassword2.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkOffLineException.hpp>
+
+#include <com/sun/star/ucb/InteractiveIOException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
 
 #define LOK_USE_UNSTABLE_API
 #include <../../inc/lib/init.hxx>
@@ -35,8 +44,12 @@ using namespace com::sun::star;
 
 LOKInteractionHandler::LOKInteractionHandler(
         uno::Reference<uno::XComponentContext> const & /*rxContext*/,
-        desktop::LibLibreOffice_Impl *const pLOKit)
+        const OString& rCommand,
+        desktop::LibLibreOffice_Impl *const pLOKit,
+        desktop::LibLODocument_Impl *const pLOKDocument)
     : m_pLOKit(pLOKit)
+    , m_pLOKDocument(pLOKDocument)
+    , m_command(rCommand)
     , m_usePassword(false)
 {
     assert(m_pLOKit);
@@ -79,8 +92,157 @@ throw (uno::RuntimeException, std::exception)
     handleInteractionRequest(xRequest);
 }
 
-sal_Bool LOKInteractionHandler::handlePasswordRequest(const uno::Sequence<uno::Reference<task::XInteractionContinuation>> &rContinuations, const task::DocumentPasswordRequest2& passwordRequest)
+void LOKInteractionHandler::postError(css::task::InteractionClassification classif, const char* kind, ErrCode code, const OUString &message)
 {
+    const char *classification = "error";
+    switch (classif)
+    {
+        case task::InteractionClassification_ERROR: break;
+        case task::InteractionClassification_WARNING: classification = "warning"; break;
+        case task::InteractionClassification_INFO: classification = "info"; break;
+        case task::InteractionClassification_QUERY: classification = "query"; break;
+        default: assert(false); break;
+    }
+
+    // create the JSON representation
+    boost::property_tree::ptree aTree;
+    aTree.put("classification", classification);
+    aTree.put("cmd", m_command.getStr());
+    aTree.put("kind", kind);
+    aTree.put("code", code);
+    aTree.put("message", message.toUtf8());
+
+    std::stringstream aStream;
+    boost::property_tree::write_json(aStream, aTree);
+
+    if (m_pLOKDocument)
+        m_pLOKDocument->mpCallback(LOK_CALLBACK_ERROR, aStream.str().c_str(), m_pLOKDocument->mpCallbackData);
+    else
+        m_pLOKit->mpCallback(LOK_CALLBACK_ERROR, aStream.str().c_str(), m_pLOKit->mpCallbackData);
+}
+
+namespace {
+
+/// Just approve the interaction.
+void selectApproved(uno::Sequence<uno::Reference<task::XInteractionContinuation>> const &rContinuations)
+{
+    for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i)
+    {
+        uno::Reference<task::XInteractionApprove> xApprove(rContinuations[i], uno::UNO_QUERY);
+        if (xApprove.is())
+            xApprove->select();
+    }
+}
+
+}
+
+bool LOKInteractionHandler::handleIOException(const css::uno::Sequence<css::uno::Reference<css::task::XInteractionContinuation>> &rContinuations, const css::uno::Any& rRequest)
+{
+    ucb::InteractiveIOException aIoException;
+    if (!(rRequest >>= aIoException))
+        return false;
+
+    static ErrCode const aErrorCode[ucb::IOErrorCode_WRONG_VERSION + 1] =
+    {
+        ERRCODE_IO_ABORT,
+        ERRCODE_IO_ACCESSDENIED,
+        ERRCODE_IO_ALREADYEXISTS,
+        ERRCODE_IO_BADCRC,
+        ERRCODE_IO_CANTCREATE,
+        ERRCODE_IO_CANTREAD,
+        ERRCODE_IO_CANTSEEK,
+        ERRCODE_IO_CANTTELL,
+        ERRCODE_IO_CANTWRITE,
+        ERRCODE_IO_CURRENTDIR,
+        ERRCODE_IO_DEVICENOTREADY,
+        ERRCODE_IO_NOTSAMEDEVICE,
+        ERRCODE_IO_GENERAL,
+        ERRCODE_IO_INVALIDACCESS,
+        ERRCODE_IO_INVALIDCHAR,
+        ERRCODE_IO_INVALIDDEVICE,
+        ERRCODE_IO_INVALIDLENGTH,
+        ERRCODE_IO_INVALIDPARAMETER,
+        ERRCODE_IO_ISWILDCARD,
+        ERRCODE_IO_LOCKVIOLATION,
+        ERRCODE_IO_MISPLACEDCHAR,
+        ERRCODE_IO_NAMETOOLONG,
+        ERRCODE_IO_NOTEXISTS,
+        ERRCODE_IO_NOTEXISTSPATH,
+        ERRCODE_IO_NOTSUPPORTED,
+        ERRCODE_IO_NOTADIRECTORY,
+        ERRCODE_IO_NOTAFILE,
+        ERRCODE_IO_OUTOFSPACE,
+        ERRCODE_IO_TOOMANYOPENFILES,
+        ERRCODE_IO_OUTOFMEMORY,
+        ERRCODE_IO_PENDING,
+        ERRCODE_IO_RECURSIVE,
+        ERRCODE_IO_UNKNOWN,
+        ERRCODE_IO_WRITEPROTECTED,
+        ERRCODE_IO_WRONGFORMAT,
+        ERRCODE_IO_WRONGVERSION,
+    };
+
+    postError(aIoException.Classification, "io", aErrorCode[aIoException.Code], "");
+    selectApproved(rContinuations);
+
+    return true;
+}
+
+bool LOKInteractionHandler::handleNetworkException(const uno::Sequence<uno::Reference<task::XInteractionContinuation>> &rContinuations, const uno::Any &rRequest)
+{
+    ucb::InteractiveNetworkException aNetworkException;
+    if (!(rRequest >>= aNetworkException))
+        return false;
+
+    ErrCode nErrorCode;
+    OUString aMessage;
+
+    ucb::InteractiveNetworkOffLineException aOffLineException;
+    ucb::InteractiveNetworkResolveNameException aResolveNameException;
+    ucb::InteractiveNetworkConnectException aConnectException;
+    ucb::InteractiveNetworkReadException aReadException;
+    ucb::InteractiveNetworkWriteException aWriteException;
+    if (rRequest >>= aOffLineException)
+    {
+        nErrorCode = ERRCODE_INET_OFFLINE;
+    }
+    else if (rRequest >>= aResolveNameException)
+    {
+        nErrorCode = ERRCODE_INET_NAME_RESOLVE;
+        aMessage = aResolveNameException.Server;
+    }
+    else if (rRequest >>= aConnectException)
+    {
+        nErrorCode = ERRCODE_INET_CONNECT;
+        aMessage = aConnectException.Server;
+    }
+    else if (rRequest >>= aReadException)
+    {
+        nErrorCode = ERRCODE_INET_READ;
+        aMessage = aReadException.Diagnostic;
+    }
+    else if (rRequest >>= aWriteException)
+    {
+        nErrorCode = ERRCODE_INET_WRITE;
+        aMessage = aWriteException.Diagnostic;
+    }
+    else
+    {
+        nErrorCode = ERRCODE_INET_GENERAL;
+    }
+
+    postError(aNetworkException.Classification, "network", nErrorCode, aMessage);
+    selectApproved(rContinuations);
+
+    return true;
+}
+
+bool LOKInteractionHandler::handlePasswordRequest(const uno::Sequence<uno::Reference<task::XInteractionContinuation>> &rContinuations, const uno::Any &rRequest)
+{
+    task::DocumentPasswordRequest2 passwordRequest;
+    if (!(rRequest >>= passwordRequest))
+        return false;
+
     if (m_pLOKit->hasOptionalFeature((passwordRequest.IsRequestPasswordToModify)
                 ? LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY
                 : LOK_FEATURE_DOCUMENT_PASSWORD))
@@ -135,28 +297,26 @@ sal_Bool LOKInteractionHandler::handlePasswordRequest(const uno::Sequence<uno::R
             }
         }
     }
-    return sal_True;
+    return true;
 }
 
 sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(
-        const uno::Reference<task::XInteractionRequest>& xRequest)
-throw (uno::RuntimeException, std::exception)
+        const uno::Reference<task::XInteractionRequest>& xRequest) throw (uno::RuntimeException, std::exception)
 {
     uno::Sequence<uno::Reference<task::XInteractionContinuation>> const &rContinuations = xRequest->getContinuations();
-
     uno::Any const request(xRequest->getRequest());
-    task::DocumentPasswordRequest2 passwordRequest;
-    if (request >>= passwordRequest)
-        return handlePasswordRequest(rContinuations, passwordRequest);
 
-    // TODO: add LOK api that allows handling this for real, for the moment we
-    // just set the interaction as 'Approved'
-    for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i)
-    {
-        uno::Reference<task::XInteractionApprove> xApprove(rContinuations[i], uno::UNO_QUERY);
-        if (xApprove.is())
-            xApprove->select();
-    }
+    if (handleIOException(rContinuations, request))
+        return true;
+
+    if (handleNetworkException(rContinuations, request))
+        return true;
+
+    if (handlePasswordRequest(rContinuations, request))
+        return true;
+
+    // TODO: perform more interactions 'for real' like the above
+    selectApproved(rContinuations);
 
     return sal_True;
 }
diff --git a/desktop/source/lib/lokinteractionhandler.hxx b/desktop/source/lib/lokinteractionhandler.hxx
index 3c18864..4a453c3 100644
--- a/desktop/source/lib/lokinteractionhandler.hxx
+++ b/desktop/source/lib/lokinteractionhandler.hxx
@@ -22,13 +22,18 @@
 
 #include <osl/conditn.hxx>
 #include <cppuhelper/implbase.hxx>
+#include <tools/errcode.hxx>
 
 #include <com/sun/star/lang/XInitialization.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/task/DocumentPasswordRequest2.hpp>
 #include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/ucb/InteractiveNetworkException.hpp>
 
-namespace desktop { struct LibLibreOffice_Impl; }
+namespace desktop {
+    struct LibLibreOffice_Impl;
+    struct LibLODocument_Impl;
+}
 
 /** InteractionHandler is an interface that provides the user with various dialogs / error messages.
 
@@ -44,6 +49,11 @@ class LOKInteractionHandler: public cppu::WeakImplHelper<com::sun::star::lang::X
 {
 private:
     desktop::LibLibreOffice_Impl * m_pLOKit;
+    desktop::LibLODocument_Impl * m_pLOKDocument;
+
+    /// Command for which we use this interaction handler (like "load", "save", "saveas", ...)
+    OString m_command;
+
     OUString m_Password;
     bool m_usePassword;
     osl::Condition m_havePassword;
@@ -51,14 +61,30 @@ private:
     LOKInteractionHandler(const LOKInteractionHandler&) SAL_DELETED_FUNCTION;
     LOKInteractionHandler& operator=(const LOKInteractionHandler&) SAL_DELETED_FUNCTION;
 
-    sal_Bool handlePasswordRequest(const css::uno::Sequence<css::uno::Reference<css::task::XInteractionContinuation>> &rContinuations, const css::task::DocumentPasswordRequest2& passwordRequest);
+    /** Call the LOK_CALLBACK_ERROR on the LOK document (if available) or LOK lib.
+
+        The error itself is a JSON message, like:
+        {
+            "classification": "error" | "warning" | "info"
+            "kind": "network" etc.
+            "code": 403 | 404 | ...
+            "message": freeform description
+        }
+    */
+    void postError(css::task::InteractionClassification classif, const char* kind, ErrCode code, const OUString &message);
+
+    bool handleIOException(const css::uno::Sequence<css::uno::Reference<css::task::XInteractionContinuation>> &rContinuations, const css::uno::Any& rRequest);
+    bool handleNetworkException(const css::uno::Sequence<css::uno::Reference<css::task::XInteractionContinuation>> &rContinuations, const css::uno::Any& rRequest);
+    bool handlePasswordRequest(const css::uno::Sequence<css::uno::Reference<css::task::XInteractionContinuation>> &rContinuations, const css::uno::Any& rRequest);
 
 public:
     void SetPassword(char const* pPassword);
 
     explicit LOKInteractionHandler(
             com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const & rxContext,
-            desktop::LibLibreOffice_Impl *);
+            const OString& rCommand,
+            desktop::LibLibreOffice_Impl *,
+            desktop::LibLODocument_Impl *pLOKDocumt = nullptr);
 
     virtual ~LOKInteractionHandler();
 
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 5931f78..3f2a6ea 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -265,6 +265,20 @@ typedef enum
      * lok::Office::setDocumentPassword().
      */
     LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY,
+
+    /**
+     * An error happened.
+     *
+     * The payload returns information further identifying the error, like:
+     *
+     * {
+     *     "classification": "error" | "warning" | "info"
+     *     "kind": "network" etc.
+     *     "code": 403 | 404 | ...
+     *     "message": freeform description
+     * }
+     */
+    LOK_CALLBACK_ERROR,
 }
 LibreOfficeKitCallbackType;
 
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index bdf3a19..cad178b 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -199,6 +199,8 @@ struct LOKDocView_Impl
     void searchNotFound(const std::string& rPayload);
     /// LOK decided to change parts, need to update UI.
     void setPart(const std::string& rPayload);
+    /// LOK got an error callback.
+    void reportError(const std::string& rPayload);
 };
 
 namespace {
@@ -935,6 +937,8 @@ const char* LOKDocView_Impl::callbackTypeToString(int nType)
         return "LOK_CALLBACK_DOCUMENT_SIZE_CHANGED";
     case LOK_CALLBACK_SET_PART:
         return "LOK_CALLBACK_SET_PART";
+    case LOK_CALLBACK_ERROR:
+        return "LOK_CALLBACK_ERROR";
     }
     return 0;
 }
@@ -1042,6 +1046,11 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback)
         setPart(pCallback->m_aPayload);
     }
     break;
+    case LOK_CALLBACK_ERROR:
+    {
+        reportError(pCallback->m_aPayload);
+    }
+    break;
     default:
         g_assert(false);
         break;
@@ -1109,6 +1118,18 @@ void LOKDocView_Impl::setPart(const std::string& rString)
     renderDocument(0);
 }
 
+void LOKDocView_Impl::reportError(const std::string& rString)
+{
+    GtkWidget *dialog = gtk_message_dialog_new(nullptr,
+            GTK_DIALOG_DESTROY_WITH_PARENT,
+            GTK_MESSAGE_ERROR,
+            GTK_BUTTONS_CLOSE,
+            "%s",
+            rString.c_str());
+    gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(dialog);
+}
+
 static void lok_docview_class_init( gpointer ptr )
 {
     LOKDocViewClass* pClass = static_cast<LOKDocViewClass *>(ptr);
commit 0fa0bc66e2010d01947671022926c3ae920fbf11
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Tue Feb 2 11:54:35 2016 +0100

    lok interaction handler: Move password handling to an own method.
    
    Change-Id: I1b3cfdef5f4f81c9138ad5600e43755841df5d75

diff --git a/desktop/source/lib/lokinteractionhandler.cxx b/desktop/source/lib/lokinteractionhandler.cxx
index 50a7972..86f521e 100644
--- a/desktop/source/lib/lokinteractionhandler.cxx
+++ b/desktop/source/lib/lokinteractionhandler.cxx
@@ -25,7 +25,6 @@
 #include <com/sun/star/task/XInteractionAbort.hpp>
 #include <com/sun/star/task/XInteractionApprove.hpp>
 #include <com/sun/star/task/XInteractionPassword2.hpp>
-#include <com/sun/star/task/DocumentPasswordRequest2.hpp>
 
 #define LOK_USE_UNSTABLE_API
 #include <../../inc/lib/init.hxx>
@@ -80,76 +79,75 @@ throw (uno::RuntimeException, std::exception)
     handleInteractionRequest(xRequest);
 }
 
-sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(
-        const uno::Reference<task::XInteractionRequest>& xRequest)
-throw (uno::RuntimeException, std::exception)
+sal_Bool LOKInteractionHandler::handlePasswordRequest(const uno::Sequence<uno::Reference<task::XInteractionContinuation>> &rContinuations, const task::DocumentPasswordRequest2& passwordRequest)
 {
-    uno::Sequence<uno::Reference<task::XInteractionContinuation>> const &rContinuations = xRequest->getContinuations();
-
-    uno::Any const request(xRequest->getRequest());
-    task::DocumentPasswordRequest2 passwordRequest;
-    if (request >>= passwordRequest)
+    if (m_pLOKit->hasOptionalFeature((passwordRequest.IsRequestPasswordToModify)
+                ? LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY
+                : LOK_FEATURE_DOCUMENT_PASSWORD))
     {
-        if (m_pLOKit->hasOptionalFeature((passwordRequest.IsRequestPasswordToModify)
-                    ? LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY
-                    : LOK_FEATURE_DOCUMENT_PASSWORD))
-        {
-            OString const url(passwordRequest.Name.toUtf8());
-            m_pLOKit->mpCallback(passwordRequest.IsRequestPasswordToModify
-                        ? LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY
-                        : LOK_CALLBACK_DOCUMENT_PASSWORD,
-                    url.getStr(),
-                    m_pLOKit->mpCallbackData);
-
-            // block until SetPassword is called
-            m_havePassword.wait();
-            m_havePassword.reset();
-        }
+        OString const url(passwordRequest.Name.toUtf8());
+        m_pLOKit->mpCallback(passwordRequest.IsRequestPasswordToModify
+                ? LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY
+                : LOK_CALLBACK_DOCUMENT_PASSWORD,
+                url.getStr(),
+                m_pLOKit->mpCallbackData);
+
+        // block until SetPassword is called
+        m_havePassword.wait();
+        m_havePassword.reset();
+    }
 
-        for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i)
+    for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i)
+    {
+        if (m_usePassword)
         {
-            if (m_usePassword)
+            if (passwordRequest.IsRequestPasswordToModify)
             {
-                if (passwordRequest.IsRequestPasswordToModify)
-                {
-                    uno::Reference<task::XInteractionPassword2> const xIPW2(
-                            rContinuations[i], uno::UNO_QUERY);
-                    xIPW2->setPasswordToModify(m_Password);
-                    xIPW2->select();
-                }
-                else
-                {
-                    uno::Reference<task::XInteractionPassword> const xIPW(
-                            rContinuations[i], uno::UNO_QUERY);
-                    if (xIPW.is())
-                    {
-                        xIPW->setPassword(m_Password);
-                        xIPW->select();
-                    }
-                }
+                uno::Reference<task::XInteractionPassword2> const xIPW2(rContinuations[i], uno::UNO_QUERY);
+                xIPW2->setPasswordToModify(m_Password);
+                xIPW2->select();
             }
             else
             {
-                if (passwordRequest.IsRequestPasswordToModify)
+                uno::Reference<task::XInteractionPassword> const xIPW(rContinuations[i], uno::UNO_QUERY);
+                if (xIPW.is())
                 {
-                    uno::Reference<task::XInteractionPassword2> const xIPW2(
-                            rContinuations[i], uno::UNO_QUERY);
-                    xIPW2->setRecommendReadOnly(true);
-                    xIPW2->select();
+                    xIPW->setPassword(m_Password);
+                    xIPW->select();
                 }
-                else
+            }
+        }
+        else
+        {
+            if (passwordRequest.IsRequestPasswordToModify)
+            {
+                uno::Reference<task::XInteractionPassword2> const xIPW2(rContinuations[i], uno::UNO_QUERY);
+                xIPW2->setRecommendReadOnly(true);
+                xIPW2->select();
+            }
+            else
+            {
+                uno::Reference<task::XInteractionAbort> const xAbort(rContinuations[i], uno::UNO_QUERY);
+                if (xAbort.is())
                 {
-                    uno::Reference<task::XInteractionAbort> const xAbort(
-                            rContinuations[i], uno::UNO_QUERY);
-                    if (xAbort.is())
-                    {
-                        xAbort->select();
-                    }
+                    xAbort->select();
                 }
             }
         }
-        return sal_True;
     }
+    return sal_True;
+}
+
+sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(
+        const uno::Reference<task::XInteractionRequest>& xRequest)
+throw (uno::RuntimeException, std::exception)
+{
+    uno::Sequence<uno::Reference<task::XInteractionContinuation>> const &rContinuations = xRequest->getContinuations();
+
+    uno::Any const request(xRequest->getRequest());
+    task::DocumentPasswordRequest2 passwordRequest;
+    if (request >>= passwordRequest)
+        return handlePasswordRequest(rContinuations, passwordRequest);
 
     // TODO: add LOK api that allows handling this for real, for the moment we
     // just set the interaction as 'Approved'
diff --git a/desktop/source/lib/lokinteractionhandler.hxx b/desktop/source/lib/lokinteractionhandler.hxx
index 2999cbb..3c18864 100644
--- a/desktop/source/lib/lokinteractionhandler.hxx
+++ b/desktop/source/lib/lokinteractionhandler.hxx
@@ -25,6 +25,7 @@
 
 #include <com/sun/star/lang/XInitialization.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/task/DocumentPasswordRequest2.hpp>
 #include <com/sun/star/task/InteractionHandler.hpp>
 
 namespace desktop { struct LibLibreOffice_Impl; }
@@ -50,6 +51,8 @@ private:
     LOKInteractionHandler(const LOKInteractionHandler&) SAL_DELETED_FUNCTION;
     LOKInteractionHandler& operator=(const LOKInteractionHandler&) SAL_DELETED_FUNCTION;
 
+    sal_Bool handlePasswordRequest(const css::uno::Sequence<css::uno::Reference<css::task::XInteractionContinuation>> &rContinuations, const css::task::DocumentPasswordRequest2& passwordRequest);
+
 public:
     void SetPassword(char const* pPassword);
 


More information about the Libreoffice-commits mailing list