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'). Change-Id: I254939ebc8ea5f309ae39686dcaaeddd5148b0c9
This commit is contained in:
parent
c0f37892a2
commit
8c987fabab
@ -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;
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ namespace desktop {
|
||||
{
|
||||
css::uno::Reference<css::lang::XComponent> mxComponent;
|
||||
std::shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass;
|
||||
LibreOfficeKitCallback mpCallback;
|
||||
void *mpCallbackData;
|
||||
|
||||
explicit LibLODocument_Impl(const css::uno::Reference <css::lang::XComponent> &xComponent);
|
||||
~LibLODocument_Impl();
|
||||
|
@ -36,6 +36,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>
|
||||
@ -241,7 +243,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,
|
||||
@ -884,9 +887,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())
|
||||
@ -951,13 +959,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,
|
||||
|
@ -220,9 +220,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;
|
||||
|
||||
|
@ -184,12 +184,14 @@ gboolean lok_doc_view_get_edit (LOKDocView*
|
||||
* @pDocView: the #LOKDocView instance
|
||||
* @pCommand: the command to issue to LO core
|
||||
* @pArguments: the arguments to the given command
|
||||
* @bNotifyWhenFinished: normally false, but it may be useful for eg. .uno:Save
|
||||
*
|
||||
* Posts the .uno: command to the LibreOfficeKit.
|
||||
*/
|
||||
void lok_doc_view_post_command (LOKDocView* pDocView,
|
||||
const gchar* pCommand,
|
||||
const gchar* pArguments);
|
||||
const gchar* pArguments,
|
||||
gboolean bNotifyWhenFinished);
|
||||
|
||||
/**
|
||||
* lok_doc_view_pixel_to_twip:
|
||||
|
@ -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>());
|
||||
|
||||
}
|
||||
|
||||
|
@ -596,7 +596,7 @@ static void doSearch(GtkWidget* pButton, bool bBackwards)
|
||||
std::stringstream aStream;
|
||||
boost::property_tree::write_json(aStream, aTree);
|
||||
|
||||
lok_doc_view_post_command(pLOKDocView, ".uno:ExecuteSearch", aStream.str().c_str());
|
||||
lok_doc_view_post_command(pLOKDocView, ".uno:ExecuteSearch", aStream.str().c_str(), false);
|
||||
}
|
||||
|
||||
/// Click handler for the search next button.
|
||||
@ -672,6 +672,12 @@ static void signalCommand(LOKDocView* pLOKDocView, char* pPayload, gpointer /*pD
|
||||
}
|
||||
}
|
||||
|
||||
/// LOKDocView command finished -> just write it to the console, not that useful for the viewer.
|
||||
static void signalCommandResult(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointer /*pData*/)
|
||||
{
|
||||
fprintf(stderr, "Command finished: %s\n", pPayload);
|
||||
}
|
||||
|
||||
static void loadChanged(LOKDocView* /*pLOKDocView*/, gdouble fValue, gpointer pData)
|
||||
{
|
||||
GtkWidget* pProgressBar = GTK_WIDGET (pData);
|
||||
@ -774,7 +780,11 @@ static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/)
|
||||
GtkToolItem* pItem = GTK_TOOL_ITEM(pWidget);
|
||||
const std::string& rString = rWindow.m_aToolItemCommandNames[pItem];
|
||||
g_info("toggleToolItem: lok_doc_view_post_command('%s')", rString.c_str());
|
||||
lok_doc_view_post_command(pLOKDocView, rString.c_str(), 0);
|
||||
|
||||
// notify about the finished Save
|
||||
gboolean bNotify = (rString == ".uno:Save");
|
||||
|
||||
lok_doc_view_post_command(pLOKDocView, rString.c_str(), 0, bNotify);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1172,6 +1182,7 @@ static void setupDocView(GtkWidget* pDocView)
|
||||
#endif
|
||||
g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL);
|
||||
g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL);
|
||||
g_signal_connect(pDocView, "command-result", G_CALLBACK(signalCommandResult), NULL);
|
||||
g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL);
|
||||
g_signal_connect(pDocView, "search-result-count", G_CALLBACK(signalSearchResultCount), NULL);
|
||||
g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL);
|
||||
|
@ -180,6 +180,7 @@ enum
|
||||
HYPERLINK_CLICKED,
|
||||
CURSOR_CHANGED,
|
||||
SEARCH_RESULT_COUNT,
|
||||
COMMAND_RESULT,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@ -461,6 +462,11 @@ static void searchResultCount(LOKDocView* pDocView, const std::string& rString)
|
||||
g_signal_emit(pDocView, doc_view_signals[SEARCH_RESULT_COUNT], 0, rString.c_str());
|
||||
}
|
||||
|
||||
static void commandResult(LOKDocView* pDocView, const std::string& rString)
|
||||
{
|
||||
g_signal_emit(pDocView, doc_view_signals[COMMAND_RESULT], 0, rString.c_str());
|
||||
}
|
||||
|
||||
static void
|
||||
setPart(LOKDocView* pDocView, const std::string& rString)
|
||||
{
|
||||
@ -752,6 +758,11 @@ callback (gpointer pData)
|
||||
searchResultCount(pDocView, std::to_string(nCount));
|
||||
}
|
||||
break;
|
||||
case LOK_CALLBACK_UNO_COMMAND_RESULT:
|
||||
{
|
||||
commandResult(pDocView, pCallback->m_aPayload);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert(false);
|
||||
break;
|
||||
@ -1520,7 +1531,7 @@ postCommandInThread (gpointer data)
|
||||
std::stringstream ss;
|
||||
ss << "lok::Document::postUnoCommand(" << pLOEvent->m_pCommand << ", " << pLOEvent->m_pArguments << ")";
|
||||
g_info(ss.str().c_str());
|
||||
priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pLOEvent->m_pCommand, pLOEvent->m_pArguments);
|
||||
priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pLOEvent->m_pCommand, pLOEvent->m_pArguments, pLOEvent->m_bNotifyWhenFinished);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2077,6 +2088,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
|
||||
G_TYPE_NONE, 4,
|
||||
G_TYPE_INT, G_TYPE_INT,
|
||||
G_TYPE_INT, G_TYPE_INT);
|
||||
|
||||
/**
|
||||
* LOKDocView::search-result-count:
|
||||
* @pDocView: the #LOKDocView on which the signal is emitted
|
||||
@ -2092,6 +2104,22 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
/**
|
||||
* LOKDocView::command-result:
|
||||
* @pDocView: the #LOKDocView on which the signal is emitted
|
||||
* @aCommand: JSON containing the info about the command that finished,
|
||||
* and its success status.
|
||||
*/
|
||||
doc_view_signals[COMMAND_RESULT] =
|
||||
g_signal_new("command-result",
|
||||
G_TYPE_FROM_CLASS(pGObjectClass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__STRING,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
}
|
||||
|
||||
SAL_DLLPUBLIC_EXPORT GtkWidget*
|
||||
@ -2326,7 +2354,8 @@ lok_doc_view_get_edit (LOKDocView* pDocView)
|
||||
SAL_DLLPUBLIC_EXPORT void
|
||||
lok_doc_view_post_command (LOKDocView* pDocView,
|
||||
const gchar* pCommand,
|
||||
const gchar* pArguments)
|
||||
const gchar* pArguments,
|
||||
gboolean bNotifyWhenFinished)
|
||||
{
|
||||
LOKDocViewPrivate& priv = getPrivate(pDocView);
|
||||
GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
|
||||
@ -2334,6 +2363,7 @@ lok_doc_view_post_command (LOKDocView* pDocView,
|
||||
GError* error = NULL;
|
||||
pLOEvent->m_pCommand = pCommand;
|
||||
pLOEvent->m_pArguments = g_strdup(pArguments);
|
||||
pLOEvent->m_bNotifyWhenFinished = bNotifyWhenFinished;
|
||||
|
||||
g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
|
||||
g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
|
||||
|
@ -169,6 +169,7 @@ struct LOEvent
|
||||
///@{
|
||||
const gchar* m_pCommand;
|
||||
gchar* m_pArguments;
|
||||
gboolean m_bNotifyWhenFinished;
|
||||
///@}
|
||||
|
||||
/// @name open_document parameter
|
||||
@ -221,6 +222,7 @@ struct LOEvent
|
||||
: m_nType(type)
|
||||
, m_pCommand(0)
|
||||
, m_pArguments(0)
|
||||
, m_bNotifyWhenFinished(false)
|
||||
, m_pPath(0)
|
||||
, m_bEdit(false)
|
||||
, m_nPartMode(0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user