[Libreoffice-commits] online.git: 2 commits - loolwsd/bundled loolwsd/ChildSession.cpp loolwsd/ChildSession.hpp loolwsd/LibreOfficeKit.hpp loolwsd/LOOLKit.cpp loolwsd/Makefile.am loolwsd/test
Jan Holesovsky
kendy at collabora.com
Tue Nov 15 12:13:47 UTC 2016
loolwsd/ChildSession.cpp | 152 +--
loolwsd/ChildSession.hpp | 30
loolwsd/LOOLKit.cpp | 72 -
loolwsd/LibreOfficeKit.hpp | 646 --------------
loolwsd/Makefile.am | 1
loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h | 1
loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx | 610 +++++++++++++
loolwsd/test/WhiteBoxTests.cpp | 28
8 files changed, 773 insertions(+), 767 deletions(-)
New commits:
commit 72a5f35f30d2e9250795abf910a1456d7b62b78e
Author: Jan Holesovsky <kendy at collabora.com>
Date: Tue Nov 15 12:50:58 2016 +0100
LibreOfficeKit.hpp changed meaning of getPart(), update accordingly.
Change-Id: Ia346f4f838856040fa9aea26b3ac9c0b596b9218
diff --git a/loolwsd/ChildSession.cpp b/loolwsd/ChildSession.cpp
index ecd98c9..07b3a4c 100644
--- a/loolwsd/ChildSession.cpp
+++ b/loolwsd/ChildSession.cpp
@@ -100,7 +100,9 @@ bool ChildSession::_handleInput(const char *buffer, int length)
std::vector<int> viewIds(viewCount);
getLOKitDocument()->getViewIds(viewIds.data(), viewCount);
- const int curPart = getLOKitDocument()->getPart();
+ int curPart = 0;
+ if (getLOKitDocument()->getDocumentType() != LOK_DOCTYPE_TEXT)
+ curPart = getLOKitDocument()->getPart();
lockLokDoc.unlock();
@@ -919,7 +921,7 @@ bool ChildSession::setClientPart(const char* /*buffer*/, int /*length*/, StringT
getLOKitDocument()->setView(_viewId);
- if (part != getLOKitDocument()->getPart())
+ if (getLOKitDocument()->getDocumentType() != LOK_DOCTYPE_TEXT && part != getLOKitDocument()->getPart())
{
getLOKitDocument()->setPart(part);
}
commit 2069650ba64bf9bbb8a4b8f28add7502e1d24dc5
Author: Jan Holesovsky <kendy at collabora.com>
Date: Tue Nov 15 11:37:47 2016 +0100
Get rid of LibreOfficeKit.hpp, it's mostly a copy of LibreOfficeKit.hxx.
Change-Id: I55f9c28a3ac1ef2a36c18c29cc16209bedd48770
diff --git a/loolwsd/ChildSession.cpp b/loolwsd/ChildSession.cpp
index c28cfbf..ecd98c9 100644
--- a/loolwsd/ChildSession.cpp
+++ b/loolwsd/ChildSession.cpp
@@ -83,7 +83,7 @@ bool ChildSession::_handleInput(const char *buffer, int length)
updateLastActivityTime();
}
- if (tokens.count() > 0 && tokens[0] == "useractive" && _loKitDocument != nullptr)
+ if (tokens.count() > 0 && tokens[0] == "useractive" && getLOKitDocument() != nullptr)
{
LOG_DBG("Handling message after inactivity of " << getInactivityMS() << "ms.");
setIsActive(true);
@@ -91,16 +91,16 @@ bool ChildSession::_handleInput(const char *buffer, int length)
// Client is getting active again.
// Send invalidation and other sync-up messages.
std::unique_lock<std::recursive_mutex> lock(Mutex); //TODO: Move to top of function?
- auto lockLokDoc(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lockLokDoc(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
// Get the list of view ids from the core
- const int viewCount = _loKitDocument->getViewsCount();
+ const int viewCount = getLOKitDocument()->getViewsCount();
std::vector<int> viewIds(viewCount);
- _loKitDocument->getViewIds(viewIds.data(), viewCount);
+ getLOKitDocument()->getViewIds(viewIds.data(), viewCount);
- const int curPart = _loKitDocument->getPart();
+ const int curPart = getLOKitDocument()->getPart();
lockLokDoc.unlock();
@@ -311,8 +311,8 @@ bool ChildSession::loadDocument(const char * /*buffer*/, int /*length*/, StringT
std::unique_lock<std::recursive_mutex> lock(Mutex);
- _loKitDocument = _docManager.onLoad(getId(), _jailedFilePath, _userName, _docPassword, renderOpts, _haveDocPassword);
- if (!_loKitDocument || _viewId < 0)
+ bool loaded = _docManager.onLoad(getId(), _jailedFilePath, _userName, _docPassword, renderOpts, _haveDocPassword);
+ if (!loaded || _viewId < 0)
{
LOG_ERR("Failed to get LoKitDocument instance.");
return false;
@@ -321,19 +321,19 @@ bool ChildSession::loadDocument(const char * /*buffer*/, int /*length*/, StringT
LOG_INF("Created new view with viewid: [" << _viewId << + "] for username: [" <<
_userName << "] in session: [" << getId() << "].");
- auto lockLokDoc(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lockLokDoc(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _docType = LOKitHelper::getDocumentTypeAsString(_loKitDocument->get());
+ _docType = LOKitHelper::getDocumentTypeAsString(getLOKitDocument()->get());
if (_docType != "text" && part != -1)
{
- _loKitDocument->setPart(part);
+ getLOKitDocument()->setPart(part);
}
// Respond by the document status
LOG_DBG("Sending status after loading view " << _viewId << ".");
- const auto status = LOKitHelper::documentStatus(_loKitDocument->get());
+ const auto status = LOKitHelper::documentStatus(getLOKitDocument()->get());
if (status.empty() || !sendTextFrame("status: " + status))
{
LOG_ERR("Failed to get/forward document status [" << status << "].");
@@ -341,9 +341,9 @@ bool ChildSession::loadDocument(const char * /*buffer*/, int /*length*/, StringT
}
// Get the list of view ids from the core
- const int viewCount = _loKitDocument->getViewsCount();
+ const int viewCount = getLOKitDocument()->getViewsCount();
std::vector<int> viewIds(viewCount);
- _loKitDocument->getViewIds(viewIds.data(), viewCount);
+ getLOKitDocument()->getViewIds(viewIds.data(), viewCount);
lockLokDoc.unlock();
@@ -379,11 +379,11 @@ bool ChildSession::sendFontRendering(const char* /*buffer*/, int /*length*/, Str
unsigned char* ptrFont = nullptr;
{
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- ptrFont = _loKitDocument->renderFont(decodedFont.c_str(), text.c_str(), &width, &height);
+ ptrFont = getLOKitDocument()->renderFont(decodedFont.c_str(), text.c_str(), &width, &height);
}
LOG_TRC("renderFont [" << font << "] rendered in " << (timestamp.elapsed()/1000.) << "ms");
@@ -403,11 +403,11 @@ bool ChildSession::getStatus(const char* /*buffer*/, int /*length*/)
{
std::string status;
{
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- status = LOKitHelper::documentStatus(_loKitDocument->get());
+ status = LOKitHelper::documentStatus(getLOKitDocument()->get());
}
if (status.empty())
@@ -462,16 +462,16 @@ bool ChildSession::getCommandValues(const char* /*buffer*/, int /*length*/, Stri
return false;
}
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
if (command == ".uno:DocumentRepair")
{
char* pUndo;
const std::string jsonTemplate("{\"commandName\":\".uno:DocumentRepair\",\"Redo\":%s,\"Undo\":%s}");
- pValues = _loKitDocument->getCommandValues(".uno:Redo");
- pUndo = _loKitDocument->getCommandValues(".uno:Undo");
+ pValues = getLOKitDocument()->getCommandValues(".uno:Redo");
+ pUndo = getLOKitDocument()->getCommandValues(".uno:Undo");
std::string json = Poco::format(jsonTemplate,
std::string(pValues == nullptr ? "" : pValues),
std::string(pUndo == nullptr ? "" : pUndo));
@@ -484,7 +484,7 @@ bool ChildSession::getCommandValues(const char* /*buffer*/, int /*length*/, Stri
}
else
{
- pValues = _loKitDocument->getCommandValues(command.c_str());
+ pValues = getLOKitDocument()->getCommandValues(command.c_str());
success = sendTextFrame("commandvalues: " + std::string(pValues == nullptr ? "" : pValues));
std::free(pValues);
}
@@ -496,10 +496,10 @@ bool ChildSession::getPartPageRectangles(const char* /*buffer*/, int /*length*/)
{
char* partPage = nullptr;
{
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
- partPage = _loKitDocument->getPartPageRectangles();
+ getLOKitDocument()->setView(_viewId);
+ partPage = getLOKitDocument()->getPartPageRectangles();
}
sendTextFrame("partpagerectangles: " + std::string(partPage));
@@ -521,11 +521,11 @@ bool ChildSession::clientZoom(const char* /*buffer*/, int /*length*/, StringToke
return false;
}
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _loKitDocument->setClientZoom(tilePixelWidth, tilePixelHeight, tileTwipWidth, tileTwipHeight);
+ getLOKitDocument()->setClientZoom(tilePixelWidth, tilePixelHeight, tileTwipWidth, tileTwipHeight);
return true;
}
@@ -546,11 +546,11 @@ bool ChildSession::clientVisibleArea(const char* /*buffer*/, int /*length*/, Str
return false;
}
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _loKitDocument->setClientVisibleArea(x, y, width, height);
+ getLOKitDocument()->setClientVisibleArea(x, y, width, height);
return true;
}
@@ -584,9 +584,9 @@ bool ChildSession::downloadAs(const char* /*buffer*/, int /*length*/, StringToke
const auto url = JAILED_DOCUMENT_ROOT + tmpDir + "/" + filenameParam.getFileName();
{
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->saveAs(url.c_str(),
+ getLOKitDocument()->saveAs(url.c_str(),
format.size() == 0 ? nullptr :format.c_str(),
filterOptions.size() == 0 ? nullptr : filterOptions.c_str());
}
@@ -615,11 +615,11 @@ bool ChildSession::getTextSelection(const char* /*buffer*/, int /*length*/, Stri
char* textSelection = nullptr;
{
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- textSelection = _loKitDocument->getTextSelection(mimeType.c_str(), nullptr);
+ textSelection = getLOKitDocument()->getTextSelection(mimeType.c_str(), nullptr);
}
sendTextFrame("textselectioncontent: " + std::string(textSelection));
@@ -641,11 +641,11 @@ bool ChildSession::paste(const char* buffer, int length, StringTokenizer& tokens
const char* data = buffer + firstLine.size() + 1;
const size_t size = length - firstLine.size() - 1;
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _loKitDocument->paste(mimeType.c_str(), data, size);
+ getLOKitDocument()->paste(mimeType.c_str(), data, size);
return true;
}
@@ -671,11 +671,11 @@ bool ChildSession::insertFile(const char* /*buffer*/, int /*length*/, StringToke
"\"value\":\"" + fileName + "\""
"}}";
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _loKitDocument->postUnoCommand(command.c_str(), arguments.c_str(), false);
+ getLOKitDocument()->postUnoCommand(command.c_str(), arguments.c_str(), false);
}
return true;
@@ -711,11 +711,11 @@ bool ChildSession::keyEvent(const char* /*buffer*/, int /*length*/, StringTokeni
return true;
}
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _loKitDocument->postKeyEvent(type, charcode, keycode);
+ getLOKitDocument()->postKeyEvent(type, charcode, keycode);
return true;
}
@@ -756,11 +756,11 @@ bool ChildSession::mouseEvent(const char* /*buffer*/, int /*length*/, StringToke
return false;
}
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _loKitDocument->postMouseEvent(type, x, y, count, buttons, modifier);
+ getLOKitDocument()->postMouseEvent(type, x, y, count, buttons, modifier);
return true;
}
@@ -776,9 +776,9 @@ bool ChildSession::unoCommand(const char* /*buffer*/, int /*length*/, StringToke
// we need to get LOK_CALLBACK_UNO_COMMAND_RESULT callback when saving
const bool bNotify = (tokens[1] == ".uno:Save");
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
if (tokens.count() == 2 && tokens[1] == ".uno:fakeDiskFull")
{
@@ -786,11 +786,11 @@ bool ChildSession::unoCommand(const char* /*buffer*/, int /*length*/, StringToke
}
else if (tokens.count() == 2)
{
- _loKitDocument->postUnoCommand(tokens[1].c_str(), nullptr, bNotify);
+ getLOKitDocument()->postUnoCommand(tokens[1].c_str(), nullptr, bNotify);
}
else
{
- _loKitDocument->postUnoCommand(tokens[1].c_str(),
+ getLOKitDocument()->postUnoCommand(tokens[1].c_str(),
Poco::cat(std::string(" "), tokens.begin() + 2, tokens.end()).c_str(),
bNotify);
}
@@ -814,11 +814,11 @@ bool ChildSession::selectText(const char* /*buffer*/, int /*length*/, StringToke
return false;
}
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _loKitDocument->setTextSelection(type, x, y);
+ getLOKitDocument()->setTextSelection(type, x, y);
return true;
}
@@ -838,11 +838,11 @@ bool ChildSession::selectGraphic(const char* /*buffer*/, int /*length*/, StringT
return false;
}
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _loKitDocument->setGraphicSelection(type, x, y);
+ getLOKitDocument()->setGraphicSelection(type, x, y);
return true;
}
@@ -855,11 +855,11 @@ bool ChildSession::resetSelection(const char* /*buffer*/, int /*length*/, String
return false;
}
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _loKitDocument->resetSelection();
+ getLOKitDocument()->resetSelection();
return true;
}
@@ -887,11 +887,11 @@ bool ChildSession::saveAs(const char* /*buffer*/, int /*length*/, StringTokenize
bool success = false;
{
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- success = _loKitDocument->saveAs(url.c_str(),
+ success = getLOKitDocument()->saveAs(url.c_str(),
format.size() == 0 ? nullptr :format.c_str(),
filterOptions.size() == 0 ? nullptr : filterOptions.c_str());
}
@@ -915,13 +915,13 @@ bool ChildSession::setClientPart(const char* /*buffer*/, int /*length*/, StringT
return false;
}
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- if (part != _loKitDocument->getPart())
+ if (part != getLOKitDocument()->getPart())
{
- _loKitDocument->setPart(part);
+ getLOKitDocument()->setPart(part);
}
return true;
@@ -937,11 +937,11 @@ bool ChildSession::setPage(const char* /*buffer*/, int /*length*/, StringTokeniz
return false;
}
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
- _loKitDocument->setView(_viewId);
+ getLOKitDocument()->setView(_viewId);
- _loKitDocument->setPart(page);
+ getLOKitDocument()->setPart(page);
return true;
}
diff --git a/loolwsd/ChildSession.hpp b/loolwsd/ChildSession.hpp
index 624090c..871de23 100644
--- a/loolwsd/ChildSession.hpp
+++ b/loolwsd/ChildSession.hpp
@@ -12,13 +12,15 @@
#include <mutex>
+#define LOK_USE_UNSTABLE_API
+#include <LibreOfficeKit/LibreOfficeKit.hxx>
+
#include <Poco/NotificationQueue.h>
#include <Poco/Thread.h>
#include "Common.hpp"
#include "LOOLKit.hpp"
#include "LOOLSession.hpp"
-#include "LibreOfficeKit.hpp"
class ChildSession;
@@ -28,23 +30,31 @@ class IDocumentManager
{
public:
/// Reqest loading a document, or a new view, if one exists.
- virtual std::shared_ptr<lok::Document> onLoad(const std::string& sessionId,
- const std::string& jailedFilePath,
- const std::string& userName,
- const std::string& docPassword,
- const std::string& renderOpts,
- const bool haveDocPassword)
+ virtual bool onLoad(const std::string& sessionId,
+ const std::string& jailedFilePath,
+ const std::string& userName,
+ const std::string& docPassword,
+ const std::string& renderOpts,
+ const bool haveDocPassword)
= 0;
/// Unload a client session, which unloads the document
/// if it is the last and only.
virtual void onUnload(const ChildSession& session) = 0;
+ /// Access to the document instance.
+ virtual std::shared_ptr<lok::Document> getLOKitDocument() = 0;
+
/// Send updated view info to all active sessions
virtual void notifyViewInfo(const std::vector<int>& viewIds) = 0;
/// Get a view ID <-> UserInfo map.
virtual std::map<int, UserInfo> getViewInfo() = 0;
virtual std::mutex& getMutex() = 0;
+
+ /// Mutex guarding the document - so that we can lock operations like
+ /// setting a view followed by a tile render, etc.
+ virtual std::mutex& getDocumentMutex() = 0;
+
virtual std::shared_ptr<TileQueue>& getTileQueue() = 0;
virtual bool sendTextFrame(const std::string& message) = 0;
@@ -115,6 +125,11 @@ private:
virtual void disconnect() override;
virtual bool _handleInput(const char* buffer, int length) override;
+ std::shared_ptr<lok::Document> getLOKitDocument()
+ {
+ return _docManager.getLOKitDocument();
+ }
+
private:
const std::string _jailId;
IDocumentManager& _docManager;
@@ -125,7 +140,6 @@ private:
/// Whether document has been opened succesfuly
bool _isDocLoaded;
- std::shared_ptr<lok::Document> _loKitDocument;
std::string _docType;
std::map<std::string, std::string> _lastDocStates;
std::map<int, std::string> _lastDocEvents;
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index 48902cb..4577003 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -31,6 +31,7 @@
#define LOK_USE_UNSTABLE_API
#include <LibreOfficeKit/LibreOfficeKitInit.h>
+#include <LibreOfficeKit/LibreOfficeKit.hxx>
#include <Poco/Exception.h>
#include <Poco/JSON/Object.h>
@@ -55,7 +56,6 @@
#include "LOOLKit.hpp"
#include "LOOLProtocol.hpp"
#include "LOOLWebSocket.hpp"
-#include "LibreOfficeKit.hpp"
#include "Log.hpp"
#include "Png.hpp"
#include "Rectangle.hpp"
@@ -295,10 +295,11 @@ public:
_docPasswordType(PasswordType::ToView),
_stop(false),
_mutex(),
+ _documentMutex(),
_isLoading(0)
{
LOG_INF("Document ctor for url [" << _url << "] on child [" << _jailId << "].");
- assert(_loKit && _loKit->get());
+ assert(_loKit);
_callbackThread.start(*this);
}
@@ -479,7 +480,7 @@ public:
return;
}
- std::unique_lock<std::mutex> lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_documentMutex);
if (_loKitDocument->getViewsCount() <= 0)
{
LOG_ERR("Tile rendering requested without views.");
@@ -550,7 +551,7 @@ public:
return;
}
- std::unique_lock<std::mutex> lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_documentMutex);
if (_loKitDocument->getViewsCount() <= 0)
{
LOG_ERR("Tile rendering requested without views.");
@@ -739,12 +740,12 @@ private:
}
/// Load a document (or view) and register callbacks.
- std::shared_ptr<lok::Document> onLoad(const std::string& sessionId,
- const std::string& uri,
- const std::string& userName,
- const std::string& docPassword,
- const std::string& renderOpts,
- const bool haveDocPassword) override
+ bool onLoad(const std::string& sessionId,
+ const std::string& uri,
+ const std::string& userName,
+ const std::string& docPassword,
+ const std::string& renderOpts,
+ const bool haveDocPassword) override
{
std::unique_lock<std::mutex> lock(_mutex);
@@ -765,13 +766,13 @@ private:
load(sessionId, uri, userName, docPassword, renderOpts, haveDocPassword);
if (!_loKitDocument || !_loKitDocument->get())
{
- return nullptr;
+ return false;
}
}
catch (const std::exception& exc)
{
LOG_ERR("Exception while loading [" << uri << "] : " << exc.what());
- return nullptr;
+ return false;
}
// Done loading, let the next one in (if any).
@@ -780,7 +781,7 @@ private:
--_isLoading;
_cvLoading.notify_one();
- return _loKitDocument;
+ return true;
}
void onUnload(const ChildSession& session) override
@@ -797,7 +798,7 @@ private:
return;
}
- std::unique_lock<std::mutex> lockLokDoc(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lockLokDoc(_documentMutex);
_loKitDocument->setView(viewId);
_loKitDocument->registerCallback(nullptr, nullptr);
@@ -907,7 +908,7 @@ private:
std::map<std::string, int> viewColors;
{
- auto lock(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> lock(_documentMutex);
char* pValues = _loKitDocument->getCommandValues(".uno:TrackedChangeAuthors");
colorValues = std::string(pValues == nullptr ? "" : pValues);
@@ -965,16 +966,12 @@ private:
// This is the first time we are loading the document
LOG_INF("Loading new document from URI: [" << uri << "] for session [" << sessionId << "].");
- auto lock(_loKit->getLock());
+ _loKit->registerCallback(GlobalCallback, this);
- if (LIBREOFFICEKIT_HAS(_loKit->get(), registerCallback))
- {
- _loKit->get()->pClass->registerCallback(_loKit->get(), GlobalCallback, this);
- const auto flags = LOK_FEATURE_DOCUMENT_PASSWORD
- | LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY
- | LOK_FEATURE_PART_IN_INVALIDATION_CALLBACK;
- _loKit->setOptionalFeatures(flags);
- }
+ const auto flags = LOK_FEATURE_DOCUMENT_PASSWORD
+ | LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY
+ | LOK_FEATURE_PART_IN_INVALIDATION_CALLBACK;
+ _loKit->setOptionalFeatures(flags);
// Save the provided password with us and the jailed url
_haveDocPassword = haveDocPassword;
@@ -983,9 +980,9 @@ private:
_isDocPasswordProtected = false;
LOG_DBG("Calling lokit::documentLoad.");
- _loKitDocument = _loKit->documentLoad(uri.c_str());
+ _loKitDocument.reset(_loKit->documentLoad(uri.c_str()));
LOG_DBG("Returned lokit::documentLoad.");
- auto l(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> l(_documentMutex);
lockLokDoc.swap(l);
if (!_loKitDocument || !_loKitDocument->get())
@@ -1022,7 +1019,7 @@ private:
}
else
{
- auto l(_loKitDocument->getLock());
+ std::unique_lock<std::mutex> l(_documentMutex);
lockLokDoc.swap(l);
// Check if this document requires password
@@ -1236,6 +1233,18 @@ private:
LOG_DBG("Thread finished.");
}
+ /// Return access to the lok::Document instance.
+ std::shared_ptr<lok::Document> getLOKitDocument() override
+ {
+ return _loKitDocument;
+ }
+
+ /// Return access to the lok::Document instance.
+ std::mutex& getDocumentMutex() override
+ {
+ return _documentMutex;
+ }
+
private:
std::shared_ptr<lok::Office> _loKit;
const std::string _jailId;
@@ -1259,6 +1268,11 @@ private:
std::atomic<bool> _stop;
mutable std::mutex _mutex;
+
+ /// Mutex guarding the lok::Document so that we can lock operations
+ /// like setting a view followed by a tile render, etc.
+ std::mutex _documentMutex;
+
std::condition_variable _cvLoading;
std::atomic_size_t _isLoading;
std::map<int, std::unique_ptr<CallbackDescriptor>> _viewIdToCallbackDescr;
@@ -1435,14 +1449,14 @@ void lokit_main(const std::string& childRoot,
}
loKit = std::make_shared<lok::Office>(kit);
- if (!loKit || !loKit->get())
+ if (!loKit)
{
LOG_FTL("LibreOfficeKit initialization failed. Exiting.");
std::_Exit(Application::EXIT_SOFTWARE);
}
}
- assert(loKit && loKit->get());
+ assert(loKit);
LOG_INF("Process is ready.");
// Open websocket connection between the child process and WSD.
diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index a87599d..865d3e7 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -98,7 +98,6 @@ noinst_HEADERS = Admin.hpp \
common/FileUtil.hpp \
common/SigUtil.hpp \
IoUtil.hpp \
- LibreOfficeKit.hpp \
Log.hpp \
LOKitHelper.hpp \
LOOLKit.hpp \
diff --git a/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h b/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h
index c7a2130..0b9535a 100644
--- a/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h
@@ -61,6 +61,7 @@ struct _LibreOfficeKitClass
void (*freeError) (char* pFree);
#if defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
+ /// @see lok::Office::registerCallback().
void (*registerCallback) (LibreOfficeKit* pThis,
LibreOfficeKitCallback pCallback,
void* pData);
diff --git a/loolwsd/LibreOfficeKit.hpp b/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx
similarity index 69%
rename from loolwsd/LibreOfficeKit.hpp
rename to loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx
index fe54938..447f44b 100644
--- a/loolwsd/LibreOfficeKit.hpp
+++ b/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -7,15 +7,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#ifndef INCLUDED_LIBREOFFICEKIT_HPP
-#define INCLUDED_LIBREOFFICEKIT_HPP
+#ifndef INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_HXX
+#define INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_HXX
-#define LOK_USE_UNSTABLE_API
-#include <LibreOfficeKit/LibreOfficeKit.h>
-#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <cstddef>
-#include "Log.hpp"
+#include "LibreOfficeKit.h"
+#include "LibreOfficeKitInit.h"
+/*
+ * The reasons this C++ code is not as pretty as it could be are:
+ * a) provide a pure C API - that's useful for some people
+ * b) allow ABI stability - C++ vtables are not good for that.
+ * c) avoid C++ types as part of the API.
+ */
namespace lok
{
@@ -23,31 +28,17 @@ namespace lok
class Document
{
private:
- LibreOfficeKitDocument* _pDoc;
- std::mutex _mutex;
+ LibreOfficeKitDocument* mpDoc;
public:
/// A lok::Document is typically created by the lok::Office::documentLoad() method.
inline Document(LibreOfficeKitDocument* pDoc) :
- _pDoc(pDoc),
- _mutex()
- {
- Log::trace("lok::Document ctor.");
- }
+ mpDoc(pDoc)
+ {}
inline ~Document()
{
- Log::trace("lok::~Document dtor.");
- _pDoc->pClass->destroy(_pDoc);
- }
-
- /// This lock must be held while calling
- /// one or more members of this class if
- /// the client is multi-threaded.
- /// No member function takes this lock otherwise.
- std::unique_lock<std::mutex> getLock()
- {
- return std::unique_lock<std::mutex>(_mutex);
+ mpDoc->pClass->destroy(mpDoc);
}
/**
@@ -65,16 +56,11 @@ public:
*/
inline bool saveAs(const char* pUrl, const char* pFormat = NULL, const char* pFilterOptions = NULL)
{
- Log::trace() << "lok::Document: saveAs: URL: [" << pUrl << "], Format: [" << pFormat
- << "], FilterOptions: " << pFilterOptions << "." << Log::end;
- return _pDoc->pClass->saveAs(_pDoc, pUrl, pFormat, pFilterOptions) != 0;
+ return mpDoc->pClass->saveAs(mpDoc, pUrl, pFormat, pFilterOptions) != 0;
}
/// Gives access to the underlying C pointer.
- inline LibreOfficeKitDocument *get()
- {
- return _pDoc;
- }
+ inline LibreOfficeKitDocument *get() { return mpDoc; }
#if defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
/**
@@ -84,7 +70,7 @@ public:
*/
inline int getDocumentType()
{
- return _pDoc->pClass->getDocumentType(_pDoc);
+ return mpDoc->pClass->getDocumentType(mpDoc);
}
/**
@@ -95,7 +81,7 @@ public:
*/
inline int getParts()
{
- return _pDoc->pClass->getParts(_pDoc);
+ return mpDoc->pClass->getParts(mpDoc);
}
/**
@@ -109,40 +95,36 @@ public:
*/
inline char* getPartPageRectangles()
{
- return _pDoc->pClass->getPartPageRectangles(_pDoc);
+ return mpDoc->pClass->getPartPageRectangles(mpDoc);
}
/// Get the current part of the document.
- /// Note: For Writer documents this always returns 0
- /// since text docs have a single coordinate system.
inline int getPart()
{
- return getDocumentType() == LOK_DOCTYPE_TEXT ? 0 : _pDoc->pClass->getPart(_pDoc);
+ return mpDoc->pClass->getPart(mpDoc);
}
/// Set the current part of the document.
inline void setPart(int nPart)
{
- Log::trace() << "lok::Document: setPart: Part: " << nPart << "." << Log::end;
- _pDoc->pClass->setPart(_pDoc, nPart);
+ mpDoc->pClass->setPart(mpDoc, nPart);
}
/// Get the current part's name.
inline char* getPartName(int nPart)
{
- return _pDoc->pClass->getPartName(_pDoc, nPart);
+ return mpDoc->pClass->getPartName(mpDoc, nPart);
}
/// Get the current part's hash.
inline char* getPartHash(int nPart)
{
- return _pDoc->pClass->getPartHash(_pDoc, nPart);
+ return mpDoc->pClass->getPartHash(mpDoc, nPart);
}
inline void setPartMode(int nMode)
{
- Log::trace() << "lok::Document: setPartMode: Mode: " << nMode << "." << Log::end;
- _pDoc->pClass->setPartMode(_pDoc, nMode);
+ mpDoc->pClass->setPartMode(mpDoc, nMode);
}
/**
@@ -168,7 +150,7 @@ public:
const int nTileWidth,
const int nTileHeight)
{
- return _pDoc->pClass->paintTile(_pDoc, pBuffer, nCanvasWidth, nCanvasHeight,
+ return mpDoc->pClass->paintTile(mpDoc, pBuffer, nCanvasWidth, nCanvasHeight,
nTilePosX, nTilePosY, nTileWidth, nTileHeight);
}
@@ -179,13 +161,13 @@ public:
*/
inline int getTileMode()
{
- return _pDoc->pClass->getTileMode(_pDoc);
+ return mpDoc->pClass->getTileMode(mpDoc);
}
/// Get the document sizes in TWIPs.
inline void getDocumentSize(long* pWidth, long* pHeight)
{
- _pDoc->pClass->getDocumentSize(_pDoc, pWidth, pHeight);
+ mpDoc->pClass->getDocumentSize(mpDoc, pWidth, pHeight);
}
/**
@@ -210,8 +192,7 @@ public:
*/
inline void initializeForRendering(const char* pArguments = NULL)
{
- Log::trace() << "lok::Document: initializeForRendering: Arguments: [" << pArguments << "]." << Log::end;
- _pDoc->pClass->initializeForRendering(_pDoc, pArguments);
+ mpDoc->pClass->initializeForRendering(mpDoc, pArguments);
}
/**
@@ -223,7 +204,7 @@ public:
*/
inline void registerCallback(LibreOfficeKitCallback pCallback, void* pData)
{
- _pDoc->pClass->registerCallback(_pDoc, pCallback, pData);
+ mpDoc->pClass->registerCallback(mpDoc, pCallback, pData);
}
/**
@@ -235,9 +216,7 @@ public:
*/
inline void postKeyEvent(int nType, int nCharCode, int nKeyCode)
{
- Log::trace() << "lok::Document: postKeyEvent: Type=" << nType
- << ", CharCode=" << nCharCode << ", KeyCode=" << nKeyCode << Log::end;
- _pDoc->pClass->postKeyEvent(_pDoc, nType, nCharCode, nKeyCode);
+ mpDoc->pClass->postKeyEvent(mpDoc, nType, nCharCode, nKeyCode);
}
/**
@@ -252,10 +231,7 @@ public:
*/
inline void postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
{
- Log::trace() << "lok::Document: postMouseEvent: Type=" << nType
- << ", X=" << nX << ", nY=" << nY << ", Count=" << nCount
- << ", Buttons=" << nButtons << ", Modifier=" << nModifier << Log::end;
- _pDoc->pClass->postMouseEvent(_pDoc, nType, nX, nY, nCount, nButtons, nModifier);
+ mpDoc->pClass->postMouseEvent(mpDoc, nType, nX, nY, nCount, nButtons, nModifier);
}
/**
@@ -281,10 +257,7 @@ public:
*/
inline void postUnoCommand(const char* pCommand, const char* pArguments = NULL, bool bNotifyWhenFinished = false)
{
- Log::trace() << "lok::Document: postUnoCommand: Command=" << pCommand
- << ", Args=" << (pArguments ? pArguments : "''")
- << ", NotifyWhenFinished=" << bNotifyWhenFinished << Log::end;
- _pDoc->pClass->postUnoCommand(_pDoc, pCommand, pArguments, bNotifyWhenFinished);
+ mpDoc->pClass->postUnoCommand(mpDoc, pCommand, pArguments, bNotifyWhenFinished);
}
/**
@@ -296,7 +269,7 @@ public:
*/
inline void setTextSelection(int nType, int nX, int nY)
{
- _pDoc->pClass->setTextSelection(_pDoc, nType, nX, nY);
+ mpDoc->pClass->setTextSelection(mpDoc, nType, nX, nY);
}
/**
@@ -307,7 +280,7 @@ public:
*/
inline char* getTextSelection(const char* pMimeType, char** pUsedMimeType = NULL)
{
- return _pDoc->pClass->getTextSelection(_pDoc, pMimeType, pUsedMimeType);
+ return mpDoc->pClass->getTextSelection(mpDoc, pMimeType, pUsedMimeType);
}
/**
@@ -319,7 +292,7 @@ public:
*/
inline bool paste(const char* pMimeType, const char* pData, size_t nSize)
{
- return _pDoc->pClass->paste(_pDoc, pMimeType, pData, nSize);
+ return mpDoc->pClass->paste(mpDoc, pMimeType, pData, nSize);
}
/**
@@ -331,7 +304,7 @@ public:
*/
inline void setGraphicSelection(int nType, int nX, int nY)
{
- _pDoc->pClass->setGraphicSelection(_pDoc, nType, nX, nY);
+ mpDoc->pClass->setGraphicSelection(mpDoc, nType, nX, nY);
}
/**
@@ -339,7 +312,7 @@ public:
*/
inline void resetSelection()
{
- _pDoc->pClass->resetSelection(_pDoc);
+ mpDoc->pClass->resetSelection(mpDoc);
}
/**
@@ -350,7 +323,7 @@ public:
*/
inline char* getCommandValues(const char* pCommand)
{
- return _pDoc->pClass->getCommandValues(_pDoc, pCommand);
+ return mpDoc->pClass->getCommandValues(mpDoc, pCommand);
}
/**
@@ -367,11 +340,7 @@ public:
int nTileTwipWidth,
int nTileTwipHeight)
{
- Log::trace() << "lok::Document: setClientZoom: TilePixelWidth: " << nTilePixelWidth
- << ", TilePixelHeight: " << nTileTwipHeight
- << ", TileTwipWidth: " << nTileTwipWidth
- << ", TileTwipHeight: " << nTileTwipHeight << "." << Log::end;
- _pDoc->pClass->setClientZoom(_pDoc, nTilePixelWidth, nTilePixelHeight, nTileTwipWidth, nTileTwipHeight);
+ mpDoc->pClass->setClientZoom(mpDoc, nTilePixelWidth, nTilePixelHeight, nTileTwipWidth, nTileTwipHeight);
}
/**
@@ -386,10 +355,7 @@ public:
*/
inline void setClientVisibleArea(int nX, int nY, int nWidth, int nHeight)
{
- Log::trace() << "lok::Document: setClientVisibleArea: X: " << nX
- << ", Y: " << nY << ", Width: " << nWidth
- << ", Height: " << nHeight << "." << Log::end;
- _pDoc->pClass->setClientVisibleArea(_pDoc, nX, nY, nWidth, nHeight);
+ mpDoc->pClass->setClientVisibleArea(mpDoc, nX, nY, nWidth, nHeight);
}
/**
@@ -399,8 +365,7 @@ public:
*/
int createView()
{
- Log::trace() << "lok::Document: createView" << Log::end;
- return _pDoc->pClass->createView(_pDoc);
+ return mpDoc->pClass->createView(mpDoc);
}
/**
@@ -409,8 +374,7 @@ public:
*/
void destroyView(int nId)
{
- Log::trace() << "lok::Document: destroyView: " << nId << Log::end;
- _pDoc->pClass->destroyView(_pDoc, nId);
+ mpDoc->pClass->destroyView(mpDoc, nId);
}
/**
@@ -419,9 +383,7 @@ public:
*/
void setView(int nId)
{
- Log::trace() << "lok::Document: setView: " << nId << Log::end;
- assert(nId >= 0 && "ViewID must be non-negative.");
- _pDoc->pClass->setView(_pDoc, nId);
+ mpDoc->pClass->setView(mpDoc, nId);
}
/**
@@ -430,7 +392,7 @@ public:
*/
int getView()
{
- return _pDoc->pClass->getView(_pDoc);
+ return mpDoc->pClass->getView(mpDoc);
}
/**
@@ -438,26 +400,11 @@ public:
*/
inline int getViewsCount()
{
- return _pDoc->pClass->getViewsCount(_pDoc);
- }
-
- /**
- * Returns the viewID for each existing view. Since viewIDs are not reused,
- * viewIDs are not the same as the index of the view in the view array over
- * time. Use getViewsCount() to know the minimal nSize that's large enough.
- *
- * @param pArray the array to write the viewIDs into
- * @param nSize the size of pArray
- * @returns true if pArray was large enough and result is written, false
- * otherwise.
- */
- inline int getViewIds(int* pArray, size_t nSize)
- {
- return _pDoc->pClass->getViewIds(_pDoc, pArray, nSize);
+ return mpDoc->pClass->getViewsCount(mpDoc);
}
/**
- * Paints a font name to be displayed in the font list
+ * Paints a font name or character if provided to be displayed in the font list
* @param pFontName the font to be painted
*/
inline unsigned char* renderFont(const char *pFontName,
@@ -465,7 +412,7 @@ public:
int *pFontWidth,
int *pFontHeight)
{
- return _pDoc->pClass->renderFont(_pDoc, pFontName, pChar, pFontWidth, pFontHeight);
+ return mpDoc->pClass->renderFont(mpDoc, pFontName, pChar, pFontWidth, pFontHeight);
}
/**
@@ -483,12 +430,28 @@ public:
const int nTileWidth,
const int nTileHeight)
{
- return _pDoc->pClass->paintPartTile(_pDoc, pBuffer, nPart,
+ return mpDoc->pClass->paintPartTile(mpDoc, pBuffer, nPart,
nCanvasWidth, nCanvasHeight,
nTilePosX, nTilePosY,
nTileWidth, nTileHeight);
}
+ /**
+ * Returns the viewID for each existing view. Since viewIDs are not reused,
+ * viewIDs are not the same as the index of the view in the view array over
+ * time. Use getViewsCount() to know the minimal nSize that's large enough.
+ *
+ * @param pArray the array to write the viewIDs into
+ * @param nSize the size of pArray
+ * @returns true if pArray was large enough and result is written, false
+ * otherwise.
+ */
+ inline bool getViewIds(int* pArray,
+ size_t nSize)
+ {
+ return mpDoc->pClass->getViewIds(mpDoc, pArray, nSize);
+ }
+
#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
};
@@ -496,44 +459,17 @@ public:
class Office
{
private:
- LibreOfficeKit* _pOffice;
- std::mutex _mutex;
+ LibreOfficeKit* mpThis;
public:
/// A lok::Office is typically created by the lok_cpp_init() function.
inline Office(LibreOfficeKit* pThis) :
- _pOffice(pThis),
- _mutex()
- {
- Log::trace("lok::Office ctor.");
- assert(_pOffice);
- }
+ mpThis(pThis)
+ {}
inline ~Office()
{
- std::unique_lock<std::mutex> lock(_mutex);
- Log::trace("lok::~Office dtor.");
- try
- {
- _pOffice->pClass->destroy(_pOffice);
- }
- catch (const std::exception& ex)
- {
- LOG_ERR("Exception while destroying LibreOfficeKit instance: " << ex.what());
- }
- }
-
- /// This lock must be held while calling
- /// one or more member of this class.
- std::unique_lock<std::mutex> getLock()
- {
- return std::unique_lock<std::mutex>(_mutex);
- }
-
- /// Gives access to the underlying C pointer.
- inline LibreOfficeKit* get()
- {
- return _pOffice;
+ mpThis->pClass->destroy(mpThis);
}
/**
@@ -541,37 +477,53 @@ public:
*
* @param pUrl the URL of the document to load
* @param pFilterOptions options for the import filter, e.g. SkipImages.
+ * @since pFilterOptions argument added in LibreOffice 5.0
*/
- inline std::shared_ptr<Document> documentLoad(const char* pUrl, const char* pFilterOptions = NULL)
+ inline Document* documentLoad(const char* pUrl, const char* pFilterOptions = NULL)
{
- Log::trace() << "lok::Office: documentLoad: URL: [" << pUrl
- << "], FilterOptions: [" << pFilterOptions
- << "]." << Log::end;
LibreOfficeKitDocument* pDoc = NULL;
- if (LIBREOFFICEKIT_HAS(_pOffice, documentLoadWithOptions))
- pDoc = _pOffice->pClass->documentLoadWithOptions(_pOffice, pUrl, pFilterOptions);
+ if (LIBREOFFICEKIT_HAS(mpThis, documentLoadWithOptions))
+ pDoc = mpThis->pClass->documentLoadWithOptions(mpThis, pUrl, pFilterOptions);
else
- pDoc = _pOffice->pClass->documentLoad(_pOffice, pUrl);
+ pDoc = mpThis->pClass->documentLoad(mpThis, pUrl);
- return std::make_shared<lok::Document>(pDoc);
+ if (pDoc == NULL)
+ return NULL;
+
+ return new Document(pDoc);
}
/// Returns the last error as a string, the returned pointer has to be freed by the caller.
inline char* getError()
{
- return _pOffice->pClass->getError(_pOffice);
+ return mpThis->pClass->getError(mpThis);
}
- /// Frees the memory pointed to by pFree.
+ /**
+ * Frees the memory pointed to by pFree.
+ *
+ * @since LibreOffice 5.2
+ */
inline void freeError(char* pFree)
{
- _pOffice->pClass->freeError(pFree);
+ mpThis->pClass->freeError(pFree);
}
-
#if defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
/**
+ * Registers a callback. LOK will invoke this function when it wants to
+ * inform the client about events.
+ *
+ * @param pCallback the callback to invoke
+ * @param pData the user data, will be passed to the callback on invocation
+ */
+ inline void registerCallback(LibreOfficeKitCallback pCallback, void* pData)
+ {
+ mpThis->pClass->registerCallback(mpThis, pCallback, pData);
+ }
+
+ /**
* Returns details of filter types.
*
* Example returned string:
@@ -587,7 +539,7 @@ public:
*/
inline char* getFilterTypes()
{
- return _pOffice->pClass->getFilterTypes(_pOffice);
+ return mpThis->pClass->getFilterTypes(mpThis);
}
/**
@@ -597,7 +549,7 @@ public:
*/
void setOptionalFeatures(uint64_t features)
{
- return _pOffice->pClass->setOptionalFeatures(_pOffice, features);
+ return mpThis->pClass->setOptionalFeatures(mpThis, features);
}
/**
@@ -621,26 +573,38 @@ public:
*/
inline void setDocumentPassword(char const* pURL, char const* pPassword)
{
- _pOffice->pClass->setDocumentPassword(_pOffice, pURL, pPassword);
+ mpThis->pClass->setDocumentPassword(mpThis, pURL, pPassword);
}
/**
* Get version information of the LOKit process
*
- * @returns string containing version information in format:
- * PRODUCT_NAME PRODUCT_VERSION PRODUCT_EXTENSION BUILD_ID
+ * @returns JSON string containing version information in format:
+ * {ProductName: <>, ProductVersion: <>, ProductExtension: <>, BuildId: <>}
*
- * Eg: LibreOffice 5.3 .0.0 alpha0 <commit hash>
+ * Eg: {"ProductName": "LibreOffice",
+ * "ProductVersion": "5.3",
+ * "ProductExtension": ".0.0.alpha0",
+ * "BuildId": "<full 40 char git hash>"}
*/
inline char* getVersionInfo()
{
- return _pOffice->pClass->getVersionInfo(_pOffice);
+ return mpThis->pClass->getVersionInfo(mpThis);
}
#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
};
+/// Factory method to create a lok::Office instance.
+inline Office* lok_cpp_init(const char* pInstallPath, const char* pUserProfileUrl = NULL)
+{
+ LibreOfficeKit* pThis = lok_init_2(pInstallPath, pUserProfileUrl);
+ if (pThis == NULL || pThis->pClass->nSize == 0)
+ return NULL;
+ return new ::lok::Office(pThis);
+}
+
}
-#endif // INCLUDED_LIBREOFFICEKIT_HPP
+#endif // INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/test/WhiteBoxTests.cpp b/loolwsd/test/WhiteBoxTests.cpp
index fd3814a..2224619 100644
--- a/loolwsd/test/WhiteBoxTests.cpp
+++ b/loolwsd/test/WhiteBoxTests.cpp
@@ -154,26 +154,33 @@ class DummyDocument : public IDocumentManager
{
std::shared_ptr<TileQueue> _tileQueue;
std::mutex _mutex;
+ std::mutex _documentMutex;
public:
DummyDocument()
: _tileQueue(new TileQueue()),
- _mutex()
+ _mutex(),
+ _documentMutex()
{
}
- std::shared_ptr<lok::Document> onLoad(const std::string& /*sessionId*/,
- const std::string& /*jailedFilePath*/,
- const std::string& /*userName*/,
- const std::string& /*docPassword*/,
- const std::string& /*renderOpts*/,
- const bool /*haveDocPassword*/) override
+ bool onLoad(const std::string& /*sessionId*/,
+ const std::string& /*jailedFilePath*/,
+ const std::string& /*userName*/,
+ const std::string& /*docPassword*/,
+ const std::string& /*renderOpts*/,
+ const bool /*haveDocPassword*/) override
{
- return nullptr;
+ return false;
}
void onUnload(const ChildSession& /*session*/) override
{
}
+ std::shared_ptr<lok::Document> getLOKitDocument() override
+ {
+ return nullptr;
+ }
+
void notifyViewInfo(const std::vector<int>& /*viewIds*/) override
{
}
@@ -188,6 +195,11 @@ public:
return _mutex;
}
+ std::mutex& getDocumentMutex() override
+ {
+ return _mutex;
+ }
+
std::shared_ptr<TileQueue>& getTileQueue() override
{
return _tileQueue;
More information about the Libreoffice-commits
mailing list