Document repair: expose user names, not only view IDs

Also in leaflet replace the current user with "You" to be consistent
with the statusbar.

Change-Id: If2d76f078eeae3038f8ae17506ae7679f7b23023
This commit is contained in:
Miklos Vajna 2016-09-30 14:21:14 +02:00
parent 3cabf7c9c1
commit 3090981c8a
4 changed files with 69 additions and 17 deletions

View file

@ -43,7 +43,7 @@ L.Control.DocumentRepair = L.Control.extend({
th = L.DomUtil.create('th', '', tr);
th.appendChild(document.createTextNode(_('Comment')));
th = L.DomUtil.create('th', '', tr);
th.appendChild(document.createTextNode(_('View ID')));
th.appendChild(document.createTextNode(_('User name')));
th = L.DomUtil.create('th', '', tr);
th.appendChild(document.createTextNode(_('Timestamp')));
@ -74,7 +74,11 @@ L.Control.DocumentRepair = L.Control.extend({
fillAction: function (actions, type) {
for (var iterator = 0; iterator < actions.length; ++iterator) {
this.createAction(type, actions[iterator].index, actions[iterator].comment, actions[iterator].viewId, actions[iterator].dateTime);
var userName = actions[iterator].userName;
if (parseInt(actions[iterator].viewId) === this._map._docLayer._viewId) {
userName = _('You');
}
this.createAction(type, actions[iterator].index, actions[iterator].comment, userName, actions[iterator].dateTime);
}
},

View file

@ -397,6 +397,38 @@ bool ChildSession::getStatus(const char* /*buffer*/, int /*length*/)
return sendTextFrame("status: " + status);
}
namespace
{
/// Given a view ID <-> user name map and a .uno:DocumentRepair result, annotate with user names.
void insertUserNames(const std::map<int, std::string>& viewInfo, std::string& json)
{
Poco::JSON::Parser parser;
auto root = parser.parse(json).extract<Poco::JSON::Object::Ptr>();
std::vector<std::string> directions { "Undo", "Redo" };
for (auto& directionName : directions)
{
auto direction = root->get(directionName).extract<Poco::JSON::Object::Ptr>();
if (direction->get("actions").type() == typeid(Poco::JSON::Array::Ptr))
{
auto actions = direction->get("actions").extract<Poco::JSON::Array::Ptr>();
for (auto& actionVar : *actions)
{
auto action = actionVar.extract<Poco::JSON::Object::Ptr>();
int viewId = action->getValue<int>("viewId");
auto it = viewInfo.find(viewId);
if (it != viewInfo.end())
action->set("userName", Poco::Dynamic::Var(it->second));
}
}
}
std::stringstream ss;
root->stringify(ss);
json = ss.str();
}
}
bool ChildSession::getCommandValues(const char* /*buffer*/, int /*length*/, StringTokenizer& tokens)
{
bool success;
@ -415,12 +447,16 @@ bool ChildSession::getCommandValues(const char* /*buffer*/, int /*length*/, Stri
if (command == ".uno:DocumentRepair")
{
char* pUndo;
const std::string json("{\"commandName\":\".uno:DocumentRepair\",\"Redo\":%s,\"Undo\":%s}");
const std::string jsonTemplate("{\"commandName\":\".uno:DocumentRepair\",\"Redo\":%s,\"Undo\":%s}");
pValues = _loKitDocument->getCommandValues(".uno:Redo");
pUndo = _loKitDocument->getCommandValues(".uno:Undo");
success = sendTextFrame("commandvalues: " + Poco::format(json,
std::string(pValues == nullptr ? "" : pValues),
std::string(pUndo == nullptr ? "" : pUndo)));
std::string json = Poco::format(jsonTemplate,
std::string(pValues == nullptr ? "" : pValues),
std::string(pUndo == nullptr ? "" : pUndo));
// json only contains view IDs, insert matching user names.
std::map<int, std::string> viewInfo =_docManager.getViewInfo();
insertUserNames(viewInfo, json);
success = sendTextFrame("commandvalues: " + json);
std::free(pValues);
std::free(pUndo);
}

View file

@ -43,6 +43,9 @@ public:
/// Send updated view info to all active sessions
virtual
void notifyViewInfo() = 0;
/// Get a view ID <-> user name map.
virtual
std::map<int, std::string> getViewInfo() = 0;
};
/// Represents a session to the WSD process, in a Kit process. Note that this is not a singleton.

View file

@ -996,6 +996,24 @@ private:
notifyViewInfo();
}
std::map<int, std::string> getViewInfo() override
{
std::unique_lock<std::mutex> lock(_mutex);
std::map<int, std::string> viewInfo;
for (auto& connection : _connections)
{
if (connection.second->isRunning())
{
const auto session = connection.second->getSession();
const auto viewId = session->getViewId();
viewInfo[viewId] = session->getViewUserName();
}
}
return viewInfo;
};
/// Notify all views of viewId and their associated usernames
void notifyViewInfo() override
{
@ -1007,18 +1025,9 @@ private:
_loKitDocument->getViewIds(viewIds.data(), viewCount);
lockLokDoc.unlock();
std::unique_lock<std::mutex> lock(_mutex);
// Store the list of viewid, username mapping in a map
std::map<int, std::string> viewInfoMap;
for (auto& connectionIt : _connections)
{
if (connectionIt.second->isRunning())
{
const auto session = connectionIt.second->getSession();
const auto viewId = session->getViewId();
viewInfoMap[viewId] = session->getViewUserName();
}
}
std::map<int, std::string> viewInfoMap = getViewInfo();
std::unique_lock<std::mutex> lock(_mutex);
// Double check if list of viewids from core and our list matches,
// and create an array of JSON objects containing id and username