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 @@
#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;
}
......
......@@ -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();
......
......@@ -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);
......
......@@ -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,
......@@ -895,6 +898,11 @@ static void doc_registerCallback(LibreOfficeKitDocument* pThis,
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";
}
......
......@@ -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,
......
......@@ -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);
}
/**
......
......@@ -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;
......
......@@ -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>());
}
......
......@@ -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)
......
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