Makefile.am                                |    1 
 loleaflet/html/loleaflet.html.m4           |    6 +
 loleaflet/src/control/Control.Menubar.js   |   13 +++
 loleaflet/src/control/Control.StatusBar.js |   12 +++
 loleaflet/src/control/Control.UIManager.js |   39 ++++++++++
 loleaflet/src/control/Ruler.js             |    9 ++
 test/Makefile.am                           |    1 
 test/WhiteBoxTests.cpp                     |   15 ++++
 wsd/FileServer.cpp                         |    3 
 wsd/FileServer.hpp                         |    8 ++
 wsd/FileServerUtil.cpp                     |  104 +++++++++++++++++++++++++++++
 wsd/reference.md                           |   21 +++++
 12 files changed, 226 insertions(+), 6 deletions(-)

New commits:
commit 2e28b9bb655ac7ebc5b580fabb5636b629dd7f85
Author:     mert <mert.tu...@collabora.com>
AuthorDate: Wed Jun 3 21:16:31 2020 +0300
Commit:     Mert Tumer <mert.tu...@collabora.com>
CommitDate: Mon Sep 28 11:53:23 2020 +0200

    Change Show/Hide Ruler & Statusbar by default on first load
    
    Change-Id: If0bcf08f005b8461ed559d197b49dc11448344d3
    Signed-off-by: mert <mert.tu...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/96489
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/loleaflet/src/control/Control.Menubar.js 
b/loleaflet/src/control/Control.Menubar.js
index e53958f14..d3e3988a7 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -64,6 +64,7 @@ L.Control.Menubar = L.Control.extend({
                                {name: _UNO('.uno:ZoomMinus', 'text'), id: 
'zoomout', type: 'action',},
                                {name: _('Reset zoom'), id: 'zoomreset', type: 
'action'},
                                {name: _('Show Ruler'), id: 'showruler', type: 
'action'},
+                               {name: _('Show Status Bar'), id: 
'showstatusbar', type: 'action'},
                                {type: 'separator'},
                        ]).concat([
                                {uno: '.uno:ControlCodes'},
@@ -294,7 +295,8 @@ L.Control.Menubar = L.Control.extend({
                                {uno: '.uno:CustomAnimation', drawing: false},
                                {uno: '.uno:MasterSlidesPanel', drawing: false},
                                {type: 'separator', drawing: false},
-                               {uno: '.uno:Sidebar', drawing: false}]
+                               {uno: '.uno:Sidebar', drawing: false},
+                               {name: _('Show Status Bar'), id: 
'showstatusbar', type: 'action'}]
                        },
                        {name: _UNO('.uno:InsertMenu', 'presentation'), id: 
'insert', type: 'menu', menu: [
                                {name: _('Local Image...'), id: 
'insertgraphic', type: 'action'},
@@ -1082,6 +1084,13 @@ L.Control.Menubar = L.Control.extend({
                                                        
$(aItem).removeClass(constChecked);
                                                }
 
+                                       } else if (id === 'showstatusbar') {
+                                               if 
(self._map.uiManager.isStatusBarVisible()) {
+                                                       
$(aItem).addClass(constChecked);
+                                               } else {
+                                                       
$(aItem).removeClass(constChecked);
+                                               }
+
                                        } else if (self._map.getDocType() === 
'presentation' && (id === 'deletepage' || id === 'insertpage' || id === 
'duplicatepage')) {
                                                if (id === 'deletepage') {
                                                        itemState = 
self._map['stateChangeHandler'].getItemValue('.uno:DeletePage');
@@ -1215,6 +1224,8 @@ L.Control.Menubar = L.Control.extend({
                        L.toggleFullScreen();
                } else if (id === 'showruler') {
                        this._map.uiManager.toggleRuler();
+               } else if (id === 'showstatusbar') {
+                       this._map.uiManager.toggleStatusBar();
                } else if (id === 'fullscreen-presentation' && 
this._map.getDocType() === 'presentation') {
                        this._map.fire('fullscreen');
                } else if (id === 'presentation-currentslide' && 
this._map.getDocType() === 'presentation') {
diff --git a/loleaflet/src/control/Control.StatusBar.js 
b/loleaflet/src/control/Control.StatusBar.js
index 29a844e9f..62f368403 100644
--- a/loleaflet/src/control/Control.StatusBar.js
+++ b/loleaflet/src/control/Control.StatusBar.js
@@ -240,7 +240,6 @@ L.Control.StatusBar = L.Control.extend({
                        });
                        if (window.mode.isDesktop())
                                toolbar.tooltip();
-                       toolbar.show();
                }
 
                toolbar.bind('touchstart', function() {
@@ -397,6 +396,17 @@ L.Control.StatusBar = L.Control.extend({
 
                if (statusbar)
                        statusbar.refresh();
+
+               var showStatusbar = true;
+               if (window.uiDefaults) {
+                       if (window.uiDefaults[docType]) {
+                               showStatusbar = 
window.uiDefaults[docType].ShowStatusbar !== false;
+                       }
+               }
+               if (showStatusbar)
+                       $('#toolbar-down').show();
+               else
+                       this.map.uiManager.hideStatusBar(true);
        },
 
        _cancelSearch: function() {
diff --git a/loleaflet/src/control/Control.UIManager.js 
b/loleaflet/src/control/Control.UIManager.js
index 8f603eadd..edc0472e6 100644
--- a/loleaflet/src/control/Control.UIManager.js
+++ b/loleaflet/src/control/Control.UIManager.js
@@ -114,8 +114,14 @@ L.Control.UIManager = L.Control.extend({
                        
L.DomUtil.remove(L.DomUtil.get('presentation-controls-wrapper'));
 
                        if ((window.mode.isTablet() || 
window.mode.isDesktop())) {
+                               var showRuler = true;
+                               if (window.uiDefaults) {
+                                       if (window.uiDefaults[docType]) {
+                                               showRuler = 
window.uiDefaults[docType].ShowRuler || false;
+                                       }
+                               }
                                var interactiveRuler = 
this.map.isPermissionEdit();
-                               L.control.ruler({position:'topleft', 
interactive:interactiveRuler}).addTo(this.map);
+                               L.control.ruler({position:'topleft', 
interactive:interactiveRuler, showruler: showRuler}).addTo(this.map);
                        }
                }
 
@@ -260,6 +266,37 @@ L.Control.UIManager = L.Control.extend({
                return $('#document-container').hasClass('tabs-collapsed');
        },
 
+       // UI Defaults functions
+
+       showStatusBar: function() {
+               $('#document-container').css('bottom', this.documentBottom);
+               $('#presentation-controls-wrapper').css('bottom', 
this.presentationControlBottom);
+               $('#toolbar-down').show();
+               this.map.invalidateSize();
+       },
+
+       hideStatusBar: function(firstStart) {
+               if (!firstStart && !this.isStatusBarVisible())
+                       return;
+
+               this.documentBottom = $('#document-container').css('bottom');
+               this.presentationControlBottom = 
$('#presentation-controls-wrapper').css('bottom');
+               $('#document-container').css('bottom', '0px');
+               $('#presentation-controls-wrapper').css('bottom','33px');
+               $('#toolbar-down').hide();
+       },
+
+       toggleStatusBar: function() {
+               if (this.isStatusBarVisible())
+                       this.hideStatusBar();
+               else
+                       this.showStatusBar();
+       },
+
+       isStatusBarVisible: function() {
+               return $('#toolbar-down').is(':visible');
+       },
+
        // Event handlers
 
        onUpdatePermission: function(e) {
diff --git a/loleaflet/src/control/Ruler.js b/loleaflet/src/control/Ruler.js
index f9b4a913e..7df9def3d 100644
--- a/loleaflet/src/control/Ruler.js
+++ b/loleaflet/src/control/Ruler.js
@@ -19,7 +19,8 @@ L.Control.Ruler = L.Control.extend({
                tabs: [],
                unit: null,
                DraggableConvertRatio: null,
-               timer: null
+               timer: null,
+               showruler: true
        },
 
        onAdd: function(map) {
@@ -149,6 +150,12 @@ L.Control.Ruler = L.Control.extend({
 
        _initLayout: function() {
                this._rWrapper = L.DomUtil.create('div', 'loleaflet-ruler 
leaflet-bar leaflet-control leaflet-control-custom');
+               // We start it hidden rather than not initialzing at all.
+               // It is due to rulerupdate command that comes from LOK.
+               // If we delay its initialization, we can't calculate its 
margins and have to wait for another rulerupdate message to arrive.
+               if (!this.options.showruler) {
+                       L.DomUtil.setStyle(this._rWrapper, 'display', 'none');
+               }
                this._rFace = L.DomUtil.create('div', 'loleaflet-ruler-face', 
this._rWrapper);
                this._rMarginWrapper = L.DomUtil.create('div', 
'loleaflet-ruler-marginwrapper', this._rFace);
                // BP => Break Points
commit 4ad8773821f73fa0df665f4d2d4682237a7af677
Author:     Jan Holesovsky <ke...@collabora.com>
AuthorDate: Wed Jun 3 19:46:42 2020 +0300
Commit:     Mert Tumer <mert.tu...@collabora.com>
CommitDate: Mon Sep 28 11:53:16 2020 +0200

    Make various bits of the UI configurable.
    
    This adds the infrastructure to be able to pass the info which elements
    like the statusbar / ruler / sidebar are supposed to be shown or hidden
    on startup of the editor.
    
    Change-Id: I188264dec6961074444934ff5fd7088e23b170d4
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/103169
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Mert Tumer <mert.tu...@collabora.com>

diff --git a/Makefile.am b/Makefile.am
index e50b68022..1ab2f733b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -118,6 +118,7 @@ loolwsd_sources = common/Crypto.cpp \
                   wsd/LOOLWSD.cpp \
                   wsd/ClientSession.cpp \
                   wsd/FileServer.cpp \
+                  wsd/FileServerUtil.cpp \
                   wsd/RequestDetails.cpp \
                   wsd/Storage.cpp \
                   wsd/TileCache.cpp \
diff --git a/loleaflet/html/loleaflet.html.m4 b/loleaflet/html/loleaflet.html.m4
index 7abe51f18..d180165e7 100644
--- a/loleaflet/html/loleaflet.html.m4
+++ b/loleaflet/html/loleaflet.html.m4
@@ -260,7 +260,8 @@ m4_ifelse(MOBILEAPP,[true],
       window.protocolDebug = false;
       window.frameAncestors = '';
       window.socketProxy = false;
-      window.tileSize = 256;],
+      window.tileSize = 256;
+      window.uiDefaults = {};],
      [window.host = '%HOST%';
       window.serviceRoot = '%SERVICE_ROOT%';
       window.versionPath = '%VERSION%';
@@ -277,7 +278,8 @@ m4_ifelse(MOBILEAPP,[true],
       window.protocolDebug = %PROTOCOL_DEBUG%;
       window.frameAncestors = '%FRAME_ANCESTORS%';
       window.socketProxy = %SOCKET_PROXY%;
-      window.tileSize = 256;])
+      window.tileSize = 256;
+      window.uiDefaults = %UI_DEFAULTS%;])
 m4_syscmd([cat ]GLOBAL_JS)m4_dnl
 
 // Dynamically load the appropriate *-mobile.css, *-tablet.css or *-desktop.css
diff --git a/test/Makefile.am b/test/Makefile.am
index 967143b3e..1b1bcb28a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -67,6 +67,7 @@ wsd_sources = \
             ../common/Authorization.cpp \
             ../kit/Kit.cpp \
             ../kit/TestStubs.cpp \
+            ../wsd/FileServerUtil.cpp \
             ../wsd/RequestDetails.cpp \
             ../wsd/TileCache.cpp \
             ../wsd/ProofKey.cpp
diff --git a/test/WhiteBoxTests.cpp b/test/WhiteBoxTests.cpp
index 445a7134a..8f53c32ef 100644
--- a/test/WhiteBoxTests.cpp
+++ b/test/WhiteBoxTests.cpp
@@ -23,6 +23,7 @@
 #include <RequestDetails.hpp>
 
 #include <common/Authorization.hpp>
+#include <wsd/FileServer.hpp>
 
 /// WhiteBox unit-tests.
 class WhiteBoxTests : public CPPUNIT_NS::TestFixture
@@ -48,6 +49,7 @@ class WhiteBoxTests : public CPPUNIT_NS::TestFixture
     CPPUNIT_TEST(testRequestDetails_loleafletURI);
     CPPUNIT_TEST(testRequestDetails_local);
     CPPUNIT_TEST(testRequestDetails);
+    CPPUNIT_TEST(testUIDefaults);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -70,6 +72,7 @@ class WhiteBoxTests : public CPPUNIT_NS::TestFixture
     void testRequestDetails_loleafletURI();
     void testRequestDetails_local();
     void testRequestDetails();
+    void testUIDefaults();
 };
 
 void WhiteBoxTests::testLOOLProtocolFunctions()
@@ -1563,6 +1566,18 @@ void WhiteBoxTests::testRequestDetails()
     }
 }
 
+void WhiteBoxTests::testUIDefaults()
+{
+    LOK_ASSERT_EQUAL(std::string("{\"uiMode\":\"classic\"}"),
+                     
FileServerRequestHandler::uiDefaultsToJSON("UIMode=classic;huh=bleh;"));
+
+    
LOK_ASSERT_EQUAL(std::string("{\"spreadsheet\":{\"ShowSidebar\":false},\"text\":{\"ShowRuler\":true}}"),
+                     
FileServerRequestHandler::uiDefaultsToJSON("TextRuler=true;SpreadsheetSidebar=false"));
+
+    
LOK_ASSERT_EQUAL(std::string("{\"presentation\":{\"ShowStatusbar\":false},\"spreadsheet\":{\"ShowSidebar\":false},\"text\":{\"ShowRuler\":true},\"uiMode\":\"notebookbar\"}"),
+                     
FileServerRequestHandler::uiDefaultsToJSON(";;UIMode=notebookbar;;PresentationStatusbar=false;;TextRuler=true;;bah=ugh;;SpreadsheetSidebar=false"));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(WhiteBoxTests);
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index fcf853173..56ff49801 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -677,6 +677,8 @@ void FileServerRequestHandler::preprocessFile(const 
HTTPRequest& request,
     LOG_TRC("access_token=" << accessToken << ", access_token_ttl=" << 
accessTokenTtl);
     const std::string accessHeader = form.get("access_header", "");
     LOG_TRC("access_header=" << accessHeader);
+    const std::string uiDefaults = form.get("ui_defaults", "");
+    LOG_TRC("ui_defaults=" << uiDefaults);
 
     // Escape bad characters in access token.
     // This is placed directly in javascript in loleaflet.html, we need to 
make sure
@@ -718,6 +720,7 @@ void FileServerRequestHandler::preprocessFile(const 
HTTPRequest& request,
     Poco::replaceInPlace(preprocess, std::string("%HOST%"), 
cnxDetails.getWebSocketUrl());
     Poco::replaceInPlace(preprocess, std::string("%VERSION%"), 
std::string(LOOLWSD_VERSION_HASH));
     Poco::replaceInPlace(preprocess, std::string("%SERVICE_ROOT%"), 
responseRoot);
+    Poco::replaceInPlace(preprocess, std::string("%UI_DEFAULTS%"), 
uiDefaultsToJSON(uiDefaults));
 
     const auto& config = Application::instance().config();
     std::string protocolDebug = "false";
diff --git a/wsd/FileServer.hpp b/wsd/FileServer.hpp
index 58cbb0b28..1cad001fb 100644
--- a/wsd/FileServer.hpp
+++ b/wsd/FileServer.hpp
@@ -18,6 +18,8 @@ class RequestDetails;
 /// Handles file requests over HTTP(S).
 class FileServerRequestHandler
 {
+    friend class WhiteBoxTests; // for unit testing
+
     static std::string getRequestPathname(const Poco::Net::HTTPRequest& 
request);
 
     static void preprocessFile(const Poco::Net::HTTPRequest& request,
@@ -27,6 +29,12 @@ class FileServerRequestHandler
     static void preprocessAdminFile(const Poco::Net::HTTPRequest& request,
                                     const RequestDetails &requestDetails,
                                     const std::shared_ptr<StreamSocket>& 
socket);
+
+    /// Construct a JSON to be accepted by the loleflet.html from a list like
+    /// UIMode=classic;TextRuler=true;PresentationStatusbar=false
+    /// that is passed as "ui_defaults" hidden input during the iframe setup.
+    static std::string uiDefaultsToJSON(const std::string& uiDefaults);
+
 public:
     /// Evaluate if the cookie exists, and if not, ask for the credentials.
     static bool isAdminLoggedIn(const Poco::Net::HTTPRequest& request, 
Poco::Net::HTTPResponse& response);
diff --git a/wsd/FileServerUtil.cpp b/wsd/FileServerUtil.cpp
new file mode 100644
index 000000000..dbbc90028
--- /dev/null
+++ b/wsd/FileServerUtil.cpp
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <config.h>
+
+#include <Poco/JSON/Object.h>
+
+#include "FileServer.hpp"
+
+std::string FileServerRequestHandler::uiDefaultsToJSON(const std::string& 
uiDefaults)
+{
+    static std::string previousUIDefaults;
+    static std::string previousJSON("{}");
+
+    // early exit if we are serving the same thing
+    if (uiDefaults == previousUIDefaults)
+        return previousJSON;
+
+    Poco::JSON::Object json;
+    Poco::JSON::Object textDefs;
+    Poco::JSON::Object spreadsheetDefs;
+    Poco::JSON::Object presentationDefs;
+
+    StringVector tokens(Util::tokenize(uiDefaults, ';'));
+    for (const auto& token : tokens)
+    {
+        StringVector keyValue(Util::tokenize(tokens.getParam(token), '='));
+        Poco::JSON::Object* currentDef = nullptr;
+        std::string key;
+
+        // detect the UIMode or component
+        if (keyValue[0] == "UIMode")
+        {
+            if (keyValue[1] == "classic" || keyValue[1] == "notebookbar")
+                json.set("uiMode", keyValue[1]);
+            else
+                LOG_WRN("unknown UIMode value " << keyValue[1]);
+
+            continue;
+        }
+        else if (Util::startsWith(keyValue[0], "Text"))
+        {
+            currentDef = &textDefs;
+            key = keyValue[0].substr(4);
+        }
+        else if (Util::startsWith(keyValue[0], "Spreadsheet"))
+        {
+            currentDef = &spreadsheetDefs;
+            key = keyValue[0].substr(11);
+        }
+        else if (Util::startsWith(keyValue[0], "Presentation"))
+        {
+            currentDef = &presentationDefs;
+            key = keyValue[0].substr(12);
+        }
+        else
+        {
+            LOG_WRN("unknown UI default's component " << keyValue[0]);
+            continue;
+        }
+
+        assert(currentDef);
+
+        // detect the actual UI widget we want to hide or show
+        if (key == "Ruler" || key == "Sidebar" || key == "Statusbar")
+        {
+            bool value(true);
+            if (keyValue[1] == "false" || keyValue[1] == "False" || 
keyValue[1] == "0")
+                value = false;
+
+            currentDef->set("Show" + key, value);
+        }
+        else
+        {
+            LOG_WRN("unknown UI default " << keyValue[0]);
+            continue;
+        }
+    }
+
+    if (textDefs.size() > 0)
+        json.set("text", textDefs);
+
+    if (spreadsheetDefs.size() > 0)
+        json.set("spreadsheet", spreadsheetDefs);
+
+    if (presentationDefs.size() > 0)
+        json.set("presentation", presentationDefs);
+
+    std::ostringstream oss;
+    Poco::JSON::Stringifier::stringify(json, oss);
+
+    previousUIDefaults = uiDefaults;
+    previousJSON = oss.str();
+
+    return previousJSON;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/reference.md b/wsd/reference.md
index e8798debc..0c987f9eb 100644
--- a/wsd/reference.md
+++ b/wsd/reference.md
@@ -128,6 +128,27 @@ PostMessage extensions
 ### App_LoadingStatus
 Was extended with field 'Status' with 'Document_Loaded' value when document 
was loaded successfully and 'Failed' in other case.
 
+User Interface modifications
+----------------------------
+
+Some parts of the user interface can be hidden or shown based or what the
+integration needs.  This is controlled by:
+
+    <input name="ui_defaults" value="VALUES" type="hidden"/>'
+
+during sending the form when the iframe is being set up (similarly as the
+access_token).  The VALUES can have a form like:
+
+    
UIMode=notebookbar;TextRuler=false;PresentationStatusbar=false;SpreadsheetSidebar=false
+
+where the:
+
+* UIMode specifies the general mode of operatior (classic or notebookbar)
+
+* Text, Presentation or Spreadsheet - are prefixes to identify the component
+
+* Ruler, Statusbar, Sidebar - are the UI parts that can be affected by this.
+
 Alternative authentication possibility
 --------------------------------------
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to