comphelper/source/misc/dispatchcommand.cxx | 9 ++- desktop/inc/lib/init.hxx | 2 desktop/qa/desktop_lib/test_desktop_lib.cxx | 2 desktop/source/lib/init.cxx | 74 +++++++++++++++++++++++++-- include/LibreOfficeKit/LibreOfficeKit.h | 8 ++ include/LibreOfficeKit/LibreOfficeKit.hxx | 4 - include/LibreOfficeKit/LibreOfficeKitEnums.h | 17 +++++- include/comphelper/dispatchcommand.hxx | 5 + libreofficekit/source/gtk/lokdocview.cxx | 2 9 files changed, 109 insertions(+), 14 deletions(-)
New commits: commit 4a669a434527d07f49bf2a35796ee4b421952bf6 Author: Jan Holesovsky <[email protected]> Date: Tue Nov 3 13:20:06 2015 +0100 lok: Introduce LOK_CALLBACK_UNO_COMMAND_RESULT callback. Posting of the .uno:Something commands is asynchronous. To be able to find out when eg. .uno:Save finished, this commit introduces a callback that fires when that happens. To be able to receive such a notification, the appropriate postUnoCommand() must be called with 'true' as the parameter for bNotifyWhenFinished (defaults to 'false'). (cherry picked from commit 8c987fababbddb6e4f81b0cd717b59b9a9ff9be0) Change-Id: I254939ebc8ea5f309ae39686dcaaeddd5148b0c9 diff --git a/comphelper/source/misc/dispatchcommand.cxx b/comphelper/source/misc/dispatchcommand.cxx index 5de0554..a5a6dde 100644 --- a/comphelper/source/misc/dispatchcommand.cxx +++ b/comphelper/source/misc/dispatchcommand.cxx @@ -23,6 +23,7 @@ #include <com/sun/star/frame/Desktop.hpp> #include <com/sun/star/frame/XDispatch.hpp> #include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XNotifyingDispatch.hpp> #include <com/sun/star/util/URL.hpp> #include <com/sun/star/util/URLTransformer.hpp> @@ -30,7 +31,7 @@ using namespace css; namespace comphelper { -bool dispatchCommand(const OUString& rCommand, const css::uno::Sequence<css::beans::PropertyValue>& rArguments) +bool dispatchCommand(const OUString& rCommand, const css::uno::Sequence<css::beans::PropertyValue>& rArguments, uno::Reference<css::frame::XDispatchResultListener> aListener) { // Target where we will execute the .uno: command uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext(); @@ -54,7 +55,11 @@ bool dispatchCommand(const OUString& rCommand, const css::uno::Sequence<css::bea return false; // And do the work... - xDisp->dispatch(aCommandURL, rArguments); + uno::Reference<frame::XNotifyingDispatch> xNotifyingDisp(xDisp, uno::UNO_QUERY); + if (xNotifyingDisp.is()) + xNotifyingDisp->dispatchWithNotification(aCommandURL, rArguments, aListener); + else + xNotifyingDisp->dispatch(aCommandURL, rArguments); return true; } diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx index 0bfbbe3..cb7df6f 100644 --- a/desktop/inc/lib/init.hxx +++ b/desktop/inc/lib/init.hxx @@ -21,6 +21,8 @@ namespace desktop { { uno::Reference<css::lang::XComponent> mxComponent; shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass; + LibreOfficeKitCallback mpCallback; + void *mpCallbackData; explicit LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent); ~LibLODocument_Impl(); diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index bca97f7..38664c5 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -339,7 +339,7 @@ void DesktopLOKTest::testPasteWriter() CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength())); - pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", 0); + pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", 0, false); char* pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", 0); CPPUNIT_ASSERT_EQUAL(OString("hello"), OString(pText)); free(pText); diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 2f4e547..7eb7f52 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -43,6 +43,8 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/container/XNameAccess.hpp> #include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/frame/DispatchResultEvent.hpp> +#include <com/sun/star/frame/DispatchResultState.hpp> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/lang/Locale.hpp> #include <com/sun/star/lang/XComponent.hpp> @@ -250,7 +252,8 @@ static void doc_postMouseEvent (LibreOfficeKitDocument* pThis, int nModifier); static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pCommand, - const char* pArguments); + const char* pArguments, + bool bNotifyWhenFinished); static void doc_setTextSelection (LibreOfficeKitDocument* pThis, int nType, int nX, @@ -892,9 +895,14 @@ static void doc_initializeForRendering(LibreOfficeKitDocument* pThis) } static void doc_registerCallback(LibreOfficeKitDocument* pThis, - LibreOfficeKitCallback pCallback, - void* pData) + LibreOfficeKitCallback pCallback, + void* pData) { + LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis); + + pDocument->mpCallback = pCallback; + pDocument->mpCallbackData = pData; + if (comphelper::LibreOfficeKit::isViewCallback()) { if (SfxViewShell* pViewShell = SfxViewFrame::Current()->GetViewShell()) @@ -959,13 +967,69 @@ static void jsonToPropertyValues(const char* pJSON, uno::Sequence<beans::Propert rPropertyValues = comphelper::containerToSequence(aArguments); } -static void doc_postUnoCommand(LibreOfficeKitDocument* /*pThis*/, const char* pCommand, const char* pArguments) +/** Class to react on finishing of a dispatched command. + + This will call a LOK_COMMAND_FINISHED callback when postUnoCommand was + called with the parameter requesting the notification. + + @see LibreOfficeKitCallbackType::LOK_CALLBACK_UNO_COMMAND_RESULT. +*/ +class DispatchResultListener : public cppu::WeakImplHelper<css::frame::XDispatchResultListener> +{ + OString maCommand; ///< Command for which this is the result. + LibreOfficeKitCallback mpCallback; ///< Callback to call. + void* mpCallbackData; ///< The callback's data. + +public: + DispatchResultListener(const char* pCommand, LibreOfficeKitCallback pCallback, void* pCallbackData) + : maCommand(pCommand) + , mpCallback(pCallback) + , mpCallbackData(pCallbackData) + { + assert(mpCallback); + } + + virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& rEvent) throw(css::uno::RuntimeException, std::exception) override + { + boost::property_tree::ptree aTree; + aTree.put("commandName", maCommand.getStr()); + + if (rEvent.State != frame::DispatchResultState::DONTKNOW) + { + bool bSuccess = (rEvent.State == frame::DispatchResultState::SUCCESS); + aTree.put("success", bSuccess); + } + + // TODO UNO Any rEvent.Result -> JSON + // aTree.put("result": "..."); + + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + mpCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, strdup(aStream.str().c_str()), mpCallbackData); + } + + virtual void SAL_CALL disposing(const css::lang::EventObject&) throw (css::uno::RuntimeException, std::exception) override {} +}; + +static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pCommand, const char* pArguments, bool bNotifyWhenFinished) { OUString aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8); uno::Sequence<beans::PropertyValue> aPropertyValues; jsonToPropertyValues(pArguments, aPropertyValues); - if (!comphelper::dispatchCommand(aCommand, aPropertyValues)) + bool bResult = false; + + LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis); + + if (bNotifyWhenFinished && pDocument->mpCallback) + { + bResult = comphelper::dispatchCommand(aCommand, aPropertyValues, + new DispatchResultListener(pCommand, pDocument->mpCallback, pDocument->mpCallbackData)); + } + else + bResult = comphelper::dispatchCommand(aCommand, aPropertyValues); + + if (!bResult) { gImpl->maLastExceptionMsg = "Failed to dispatch the .uno: command"; } diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h index d83717b..c887f5f 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.h +++ b/include/LibreOfficeKit/LibreOfficeKit.h @@ -12,6 +12,11 @@ #include <stddef.h> +#ifdef LOK_USE_UNSTABLE_API +// the unstable API needs C99's bool +#include <stdbool.h> +#endif + #include <LibreOfficeKit/LibreOfficeKitTypes.h> #ifdef __cplusplus @@ -144,7 +149,8 @@ struct _LibreOfficeKitDocumentClass /// @see lok::Document::postUnoCommand void (*postUnoCommand) (LibreOfficeKitDocument* pThis, const char* pCommand, - const char* pArguments); + const char* pArguments, + bool bNotifyWhenFinished); /// @see lok::Document::setTextSelection void (*setTextSelection) (LibreOfficeKitDocument* pThis, diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx index b4ee8c2..3268216 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.hxx +++ b/include/LibreOfficeKit/LibreOfficeKit.hxx @@ -219,9 +219,9 @@ public: * @param pCommand uno command to be posted to the document, like ".uno:Bold" * @param pArguments arguments of the uno command. */ - inline void postUnoCommand(const char* pCommand, const char* pArguments = 0) + inline void postUnoCommand(const char* pCommand, const char* pArguments = 0, bool bNotifyWhenFinished = false) { - mpDoc->pClass->postUnoCommand(mpDoc, pCommand, pArguments); + mpDoc->pClass->postUnoCommand(mpDoc, pCommand, pArguments, bNotifyWhenFinished); } /** diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h index 459da5d..86d9e6b 100644 --- a/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -180,7 +180,22 @@ typedef enum * - searchResultSelection is an array of part-number and rectangle list * pairs, in LOK_CALLBACK_SET_PART / LOK_CALLBACK_TEXT_SELECTION format. */ - LOK_CALLBACK_SEARCH_RESULT_SELECTION + LOK_CALLBACK_SEARCH_RESULT_SELECTION, + + /** + * Result of the UNO command execution when bNotifyWhenFinished was set + * to 'true' during the postUnoCommand() call. + * + * The result returns a success / failure state, and potentially + * additional data: + * + * { + * "commandName": "...", // the command for which this is the result + * "success": true/false, // when the result is "don't know", this is missing + * // TODO "result": "..." // UNO Any converted to JSON (not implemented yet) + * } + */ + LOK_CALLBACK_UNO_COMMAND_RESULT } LibreOfficeKitCallbackType; diff --git a/include/comphelper/dispatchcommand.hxx b/include/comphelper/dispatchcommand.hxx index 58aa0b9..7b76bd5 100644 --- a/include/comphelper/dispatchcommand.hxx +++ b/include/comphelper/dispatchcommand.hxx @@ -14,6 +14,7 @@ #include <rtl/ustring.hxx> #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/frame/XDispatchResultListener.hpp> namespace comphelper { @@ -24,7 +25,9 @@ namespace comphelper @return true on success. */ -COMPHELPER_DLLPUBLIC bool dispatchCommand(const OUString& rCommand, const css::uno::Sequence<css::beans::PropertyValue>& rArguments); +COMPHELPER_DLLPUBLIC bool dispatchCommand(const OUString& rCommand, + const css::uno::Sequence<css::beans::PropertyValue>& rArguments, + css::uno::Reference<css::frame::XDispatchResultListener> aListener = css::uno::Reference<css::frame::XDispatchResultListener>()); } diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index a9b04fc..0489d75 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -1319,7 +1319,7 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_docview_get_edit(LOKDocView* pDocView) SAL_DLLPUBLIC_EXPORT void lok_docview_post_command(LOKDocView* pDocView, const char* pCommand, const char* pArguments) { - pDocView->m_pImpl->m_pDocument->pClass->postUnoCommand(pDocView->m_pImpl->m_pDocument, pCommand, pArguments); + pDocView->m_pImpl->m_pDocument->pClass->postUnoCommand(pDocView->m_pImpl->m_pDocument, pCommand, pArguments, false); } SAL_DLLPUBLIC_EXPORT void lok_docview_post_key(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpointer pData) _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
