Kaydet (Commit) 4a669a43 authored tarafından Jan Holesovsky's avatar Jan Holesovsky

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 8c987fab)

Change-Id: I254939ebc8ea5f309ae39686dcaaeddd5148b0c9
üst 74f4fad8
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <com/sun/star/frame/Desktop.hpp> #include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/XDispatch.hpp> #include <com/sun/star/frame/XDispatch.hpp>
#include <com/sun/star/frame/XDispatchProvider.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/URL.hpp>
#include <com/sun/star/util/URLTransformer.hpp> #include <com/sun/star/util/URLTransformer.hpp>
...@@ -30,7 +31,7 @@ using namespace css; ...@@ -30,7 +31,7 @@ using namespace css;
namespace comphelper { 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 // Target where we will execute the .uno: command
uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext(); uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
...@@ -54,7 +55,11 @@ bool dispatchCommand(const OUString& rCommand, const css::uno::Sequence<css::bea ...@@ -54,7 +55,11 @@ bool dispatchCommand(const OUString& rCommand, const css::uno::Sequence<css::bea
return false; return false;
// And do the work... // 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; return true;
} }
......
...@@ -21,6 +21,8 @@ namespace desktop { ...@@ -21,6 +21,8 @@ namespace desktop {
{ {
uno::Reference<css::lang::XComponent> mxComponent; uno::Reference<css::lang::XComponent> mxComponent;
shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass; shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass;
LibreOfficeKitCallback mpCallback;
void *mpCallbackData;
explicit LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent); explicit LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent);
~LibLODocument_Impl(); ~LibLODocument_Impl();
......
...@@ -339,7 +339,7 @@ void DesktopLOKTest::testPasteWriter() ...@@ -339,7 +339,7 @@ void DesktopLOKTest::testPasteWriter()
CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength())); 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); char* pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", 0);
CPPUNIT_ASSERT_EQUAL(OString("hello"), OString(pText)); CPPUNIT_ASSERT_EQUAL(OString("hello"), OString(pText));
free(pText); free(pText);
......
...@@ -43,6 +43,8 @@ ...@@ -43,6 +43,8 @@
#include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNameAccess.hpp> #include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/frame/Desktop.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/frame/XStorable.hpp>
#include <com/sun/star/lang/Locale.hpp> #include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/lang/XComponent.hpp>
...@@ -250,7 +252,8 @@ static void doc_postMouseEvent (LibreOfficeKitDocument* pThis, ...@@ -250,7 +252,8 @@ static void doc_postMouseEvent (LibreOfficeKitDocument* pThis,
int nModifier); int nModifier);
static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
const char* pCommand, const char* pCommand,
const char* pArguments); const char* pArguments,
bool bNotifyWhenFinished);
static void doc_setTextSelection (LibreOfficeKitDocument* pThis, static void doc_setTextSelection (LibreOfficeKitDocument* pThis,
int nType, int nType,
int nX, int nX,
...@@ -892,9 +895,14 @@ static void doc_initializeForRendering(LibreOfficeKitDocument* pThis) ...@@ -892,9 +895,14 @@ static void doc_initializeForRendering(LibreOfficeKitDocument* pThis)
} }
static void doc_registerCallback(LibreOfficeKitDocument* pThis, static void doc_registerCallback(LibreOfficeKitDocument* pThis,
LibreOfficeKitCallback pCallback, LibreOfficeKitCallback pCallback,
void* pData) void* pData)
{ {
LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
pDocument->mpCallback = pCallback;
pDocument->mpCallbackData = pData;
if (comphelper::LibreOfficeKit::isViewCallback()) if (comphelper::LibreOfficeKit::isViewCallback())
{ {
if (SfxViewShell* pViewShell = SfxViewFrame::Current()->GetViewShell()) if (SfxViewShell* pViewShell = SfxViewFrame::Current()->GetViewShell())
...@@ -959,13 +967,69 @@ static void jsonToPropertyValues(const char* pJSON, uno::Sequence<beans::Propert ...@@ -959,13 +967,69 @@ static void jsonToPropertyValues(const char* pJSON, uno::Sequence<beans::Propert
rPropertyValues = comphelper::containerToSequence(aArguments); 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); OUString aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8);
uno::Sequence<beans::PropertyValue> aPropertyValues; uno::Sequence<beans::PropertyValue> aPropertyValues;
jsonToPropertyValues(pArguments, 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"; gImpl->maLastExceptionMsg = "Failed to dispatch the .uno: command";
} }
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
#include <stddef.h> #include <stddef.h>
#ifdef LOK_USE_UNSTABLE_API
// the unstable API needs C99's bool
#include <stdbool.h>
#endif
#include <LibreOfficeKit/LibreOfficeKitTypes.h> #include <LibreOfficeKit/LibreOfficeKitTypes.h>
#ifdef __cplusplus #ifdef __cplusplus
...@@ -144,7 +149,8 @@ struct _LibreOfficeKitDocumentClass ...@@ -144,7 +149,8 @@ struct _LibreOfficeKitDocumentClass
/// @see lok::Document::postUnoCommand /// @see lok::Document::postUnoCommand
void (*postUnoCommand) (LibreOfficeKitDocument* pThis, void (*postUnoCommand) (LibreOfficeKitDocument* pThis,
const char* pCommand, const char* pCommand,
const char* pArguments); const char* pArguments,
bool bNotifyWhenFinished);
/// @see lok::Document::setTextSelection /// @see lok::Document::setTextSelection
void (*setTextSelection) (LibreOfficeKitDocument* pThis, void (*setTextSelection) (LibreOfficeKitDocument* pThis,
......
...@@ -219,9 +219,9 @@ public: ...@@ -219,9 +219,9 @@ public:
* @param pCommand uno command to be posted to the document, like ".uno:Bold" * @param pCommand uno command to be posted to the document, like ".uno:Bold"
* @param pArguments arguments of the uno command. * @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);
} }
/** /**
......
...@@ -180,7 +180,22 @@ typedef enum ...@@ -180,7 +180,22 @@ typedef enum
* - searchResultSelection is an array of part-number and rectangle list * - searchResultSelection is an array of part-number and rectangle list
* pairs, in LOK_CALLBACK_SET_PART / LOK_CALLBACK_TEXT_SELECTION format. * 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; LibreOfficeKitCallbackType;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <rtl/ustring.hxx> #include <rtl/ustring.hxx>
#include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/frame/XDispatchResultListener.hpp>
namespace comphelper namespace comphelper
{ {
...@@ -24,7 +25,9 @@ namespace comphelper ...@@ -24,7 +25,9 @@ namespace comphelper
@return true on success. @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>());
} }
......
...@@ -1319,7 +1319,7 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_docview_get_edit(LOKDocView* pDocView) ...@@ -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) 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) SAL_DLLPUBLIC_EXPORT void lok_docview_post_key(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpointer pData)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment