[Libreoffice-commits] online.git: 10 commits - cypress_test/integration_tests kit/ChildSession.cpp kit/ChildSession.hpp loleaflet/css loleaflet/Makefile.am loleaflet/src wsd/ClientSession.cpp

Tamás Zolnai (via logerrit) logerrit at kemper.freedesktop.org
Sat May 9 11:07:02 UTC 2020


 cypress_test/integration_tests/desktop/writer/shape_operations_spec.js |    4 
 kit/ChildSession.cpp                                                   |   27 +
 kit/ChildSession.hpp                                                   |    1 
 loleaflet/Makefile.am                                                  |    1 
 loleaflet/css/loleaflet.css                                            |   43 ++
 loleaflet/src/layer/FormFieldButtonLayer.js                            |  154 ++++++++++
 loleaflet/src/layer/tile/TileLayer.js                                  |   14 
 loleaflet/src/map/Map.js                                               |    1 
 wsd/ClientSession.cpp                                                  |    7 
 9 files changed, 248 insertions(+), 4 deletions(-)

New commits:
commit e0a82365f32bc379aefee292eeac24b96c8e657b
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu May 7 15:34:37 2020 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat May 9 09:54:09 2020 +0200

    cypress: fix shape operations test.
    
    Change-Id: Ibdca536bc8fb2a5b16d6ed085a65c25d1bc854b4

diff --git a/cypress_test/integration_tests/desktop/writer/shape_operations_spec.js b/cypress_test/integration_tests/desktop/writer/shape_operations_spec.js
index abbfe64b3..21b0a0d8c 100644
--- a/cypress_test/integration_tests/desktop/writer/shape_operations_spec.js
+++ b/cypress_test/integration_tests/desktop/writer/shape_operations_spec.js
@@ -8,8 +8,8 @@ describe('Shape operations', function() {
 		helper.afterAll('shape_operations.odt', 'writer');
 	});
 
-	it.skip('Insert a simple shape.', function() {
-		helper.loadTestDoc('shape_operations.odt');
+	it('Insert a simple shape.', function() {
+		helper.loadTestDoc('shape_operations.odt', 'writer');
 
 		// Scroll on the up toolbar
 		cy.get('#toolbar-up .w2ui-scroll-right').click();
commit 68017efb3caa801b733090f5b8085afc315ef529
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu May 7 15:14:13 2020 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat May 9 09:54:09 2020 +0200

    MSForms: remove weird blue border dispalyed around the drop down button.
    
    Change-Id: Iddb696f10d9eb5364904021dd50431e11efc8dfb

diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css
index b2dc2e8cb..227658acb 100644
--- a/loleaflet/css/loleaflet.css
+++ b/loleaflet/css/loleaflet.css
@@ -547,6 +547,7 @@ body {
 
 .form-field-button:hover, .form-field-button:focus {
 	background: #DDDDDD;
+	outline: 0;
 }
 
 .form-field-button-image {
commit c7c690c4e805aaf5ed40b0e7f30929d26ed59327
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu May 7 14:21:24 2020 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat May 9 09:54:08 2020 +0200

    MSForms: stop propagation of mouse events for the drop down button.
    
    Change-Id: Id63056f1aa39cadfc62021c5220d301f7ea26af8

diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js
index 33c6b561c..0acaabce5 100644
--- a/loleaflet/src/layer/FormFieldButtonLayer.js
+++ b/loleaflet/src/layer/FormFieldButtonLayer.js
@@ -90,6 +90,10 @@ L.FormFieldButton = L.Layer.extend({
 		image.src = 'images/unfold.svg';
 
 		button.addEventListener('click', this._onClickDropDown);
+
+		// Stop propagation to the main document
+		button.addEventListener('mouseup', function(event) {event.stopPropagation();});
+		button.addEventListener('mousedown', function(event) {event.stopPropagation();});
 	},
 
 	_buildDropDownList: function(framePos, frameWidth, frameHeight) {
commit 98f4b50673f9dd2e1b56a6cb63679c5e5ac723d1
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu May 7 12:36:00 2020 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat May 9 09:54:08 2020 +0200

    MSForms: do some styling of drop-down form field..
    
    Change-Id: I70d4766dcf116e31cde18f67cfea6551197657a8

diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css
index 8639f504d..b2dc2e8cb 100644
--- a/loleaflet/css/loleaflet.css
+++ b/loleaflet/css/loleaflet.css
@@ -532,6 +532,7 @@ body {
 	border: 1px solid;
 	position: absolute;
 	height: 100%;
+	border-radius: 2px;
 }
 
 .form-field-button {
@@ -541,6 +542,7 @@ body {
 	height: 100%;
 	box-sizing: content-box;
 	padding: 0px;
+	border-radius: 2px;
 }
 
 .form-field-button:hover, .form-field-button:focus {
@@ -554,6 +556,7 @@ body {
 .drop-down-field-list {
 	position: absolute;
 	border: 1px solid;
+	cursor: pointer;
 }
 
 .drop-down-field-list-item {
@@ -563,3 +566,6 @@ body {
 .drop-down-field-list-item.selected {
 	background: #99CCFF;
 }
+.drop-down-field-list-item:hover {
+	background: #0b87e7;
+}
commit 75dc61da7e6305a2f6b6e8e9a45e016ae1fc2e7d
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Wed May 6 13:59:03 2020 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat May 9 09:54:08 2020 +0200

    MSForms: send item selection event to core.
    
    Change-Id: I10fceb66a4f8cd777c43411ddace3456a315b5a2

diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index e70cfde2e..ba8bdf8ee 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -301,7 +301,8 @@ bool ChildSession::_handleInput(const char *buffer, int length)
                tokens.equals(0, "rendershapeselection") ||
                tokens.equals(0, "removetextcontext") ||
                tokens.equals(0, "dialogevent") ||
-               tokens.equals(0, "completefunction"));
+               tokens.equals(0, "completefunction")||
+               tokens.equals(0, "formfieldevent"));
 
         if (tokens.equals(0, "clientzoom"))
         {
@@ -446,6 +447,10 @@ bool ChildSession::_handleInput(const char *buffer, int length)
         {
             return completeFunction(buffer, length, tokens);
         }
+        else if (tokens.equals(0, "formfieldevent"))
+        {
+            return formFieldEvent(buffer, length, tokens);
+        }
         else
         {
             assert(false && "Unknown command token.");
@@ -1426,6 +1431,23 @@ bool ChildSession::dialogEvent(const char* /*buffer*/, int /*length*/, const Str
     return true;
 }
 
+bool ChildSession::formFieldEvent(const char* buffer, int length, const StringVector& /*tokens*/)
+{
+    std::string sFirstLine = getFirstLine(buffer, length);
+    std::string sArguments = sFirstLine.substr(std::string("formfieldevent ").size());
+
+    if (sArguments.empty())
+    {
+        sendTextFrameAndLogError("error: cmd=formfieldevent kind=syntax");
+        return false;
+    }
+
+    getLOKitDocument()->setView(_viewId);
+    getLOKitDocument()->sendFormFieldEvent(sArguments.c_str());
+
+    return true;
+}
+
 bool ChildSession::completeFunction(const char* /*buffer*/, int /*length*/, const StringVector& tokens)
 {
     std::string functionName;
diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp
index fad3061aa..4c4dbb2ec 100644
--- a/kit/ChildSession.hpp
+++ b/kit/ChildSession.hpp
@@ -291,6 +291,7 @@ private:
     bool removeTextContext(const char* /*buffer*/, int /*length*/, const StringVector& tokens);
 
     void rememberEventsForInactiveUser(const int type, const std::string& payload);
+    bool formFieldEvent(const char* buffer, int length, const StringVector& tokens);
 
     virtual void disconnect() override;
     virtual bool _handleInput(const char* buffer, int length) override;
diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js
index 4cd837ffe..33c6b561c 100644
--- a/loleaflet/src/layer/FormFieldButtonLayer.js
+++ b/loleaflet/src/layer/FormFieldButtonLayer.js
@@ -15,6 +15,7 @@ L.FormFieldButton = L.Layer.extend({
 	},
 
 	onAdd: function (map) {
+		this.map = map;
 		this._clearButton();
 		this._buildFormButton(map);
 	},
@@ -102,7 +103,10 @@ L.FormFieldButton = L.Layer.extend({
 		for (var i = 0; i < itemList.length; ++i) {
 			var option = L.DomUtil.create('div', 'drop-down-field-list-item', dropDownList);
 			option.innerHTML = itemList[i];
+
 			option.addEventListener('click', this._onListItemSelect);
+			option.map = this.map;
+
 			// Stop propagation to the main document
 			option.addEventListener('mouseup', function(event) {event.stopPropagation();});
 			option.addEventListener('mousedown', function(event) {event.stopPropagation();});
@@ -116,17 +120,27 @@ L.FormFieldButton = L.Layer.extend({
 		this._clearButton();
 	},
 
-	_onClickDropDown: function() {
+	_onClickDropDown: function(event) {
 		$('.drop-down-field-list').show();
+		event.stopPropagation();
 	},
 
 	_onListItemSelect: function(event) {
+		$('.drop-down-field-list').hide();
 		$('.drop-down-field-list-item.selected').removeClass('selected');
 		event.target.classList.add('selected');
-		// TODO: send back
-		$('.drop-down-field-list').hide();
+
 		event.stopPropagation();
-		console.warn(event.target.textContent);
+
+		// Find item index
+		var index = $(event.target).index();
+
+		var message = 'formfieldevent {\"type\": \"drop-down\",' +
+				      '\"cmd\": \"selected\",' +
+					  '\"data\":\"' + index.toString() + '\"}';
+
+		// Apply selection in the document.
+		this.map._socket.sendMessage(message);
 	},
 
 	_clearButton: function() {
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index 6deb6808f..ded1b572c 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -728,7 +728,6 @@ L.TileLayer = L.GridLayer.extend({
 		}
 		else if (textMsg.startsWith('formfieldbutton:')) {
 			this._onFormFieldButtonMsg(textMsg);
-			console.error(textMsg);
 		}
 	},
 
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 956a4ba7e..41d9bbcd0 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -439,7 +439,8 @@ bool ClientSession::_handleInput(const char *buffer, int length)
              tokens[0] != "resizewindow" &&
              tokens[0] != "removetextcontext" &&
              tokens[0] != "dialogevent" &&
-             tokens[0] != "completefunction")
+             tokens[0] != "completefunction" &&
+             tokens[0] != "formfieldevent")
     {
         LOG_ERR("Session [" << getId() << "] got unknown command [" << tokens[0] << "].");
         sendTextFrameAndLogError("error: cmd=" + tokens[0] + " kind=unknown");
@@ -721,6 +722,10 @@ bool ClientSession::_handleInput(const char *buffer, int length)
     {
         return forwardToChild(std::string(buffer, length), docBroker);
     }
+    else if (tokens.equals(0, "formfieldevent"))
+    {
+        return forwardToChild(firstLine, docBroker);
+    }
     else
     {
         if (tokens.equals(0, "key"))
commit dc9e66f4bb3a7fc6430226e0e6dc03c506b84bd7
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Tue May 5 17:37:26 2020 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat May 9 09:54:08 2020 +0200

    MSForms: restructure form field button rendering code.
    
    To make it more readable.
    
    Change-Id: Icfb179a5edfc65fe2dcaaebcc86c970e5d3b83b1

diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js
index 14ca0f401..4cd837ffe 100644
--- a/loleaflet/src/layer/FormFieldButtonLayer.js
+++ b/loleaflet/src/layer/FormFieldButtonLayer.js
@@ -10,73 +10,103 @@ L.FormFieldButton = L.Layer.extend({
 	},
 
 	initialize: function (data) {
-		if (data.type === 'drop-down') {
-			var strTwips = data.textArea.match(/\d+/g);
-			var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
-			var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
-			var bottomRightTwips = topLeftTwips.add(offset);
-			this._buttonAreaTwips = [topLeftTwips, bottomRightTwips];
-			this._buttonData = data;
-		}
+		console.assert(data.type === 'drop-down');
+		this._buttonData = data;
 	},
 
 	onAdd: function (map) {
 		this._clearButton();
-
 		this._buildFormButton(map);
 	},
 
 	_buildFormButton: function(map) {
-		this._container = L.DomUtil.create('div', 'form-field-button-container', this.getPane('formfieldPane'));
+		// We use a container to have the frame and the drop-down button the same height
+		var container = L.DomUtil.create('div', 'form-field-button-container', this.getPane('formfieldPane'));
 
-		// Create a frame around the text area
-		this._frame = L.DomUtil.create('div', 'form-field-frame', this._container);
+		// Calculate button area in layer point unot
+		var buttonArea = this._calculateButtonArea(map);
+
+		// Build the frame around the text area
+		var frameData = this._buildButtonFrame(container, buttonArea);
+		var framePos = frameData[0];
+		var frameWidth = frameData[1];
+		var frameHeight = frameData[2];
+
+		// We set the shared height here.
+		container.style.height = frameHeight + 'px';
+
+		// Add a drop down button to open the list
+		this._buildDropDownButton(container, framePos, frameWidth);
+
+		// Build list of items opened by clicking on the drop down button
+		this._buildDropDownList(framePos, frameWidth, frameHeight);
+	},
+
+	_calculateButtonArea: function(map) {
+		// First get the data from the message in twips.
+		var strTwips = this._buttonData.textArea.match(/\d+/g);
+		var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
+		var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
+		var bottomRightTwips = topLeftTwips.add(offset);
+		var buttonAreaTwips = [topLeftTwips, bottomRightTwips];
+
+		// Then convert to unit which can be used on the layer.
 		var buttonAreaLatLng = new L.LatLngBounds(
-				map._docLayer._twipsToLatLng(this._buttonAreaTwips[0], this._map.getZoom()),
-				map._docLayer._twipsToLatLng(this._buttonAreaTwips[1], this._map.getZoom()));
+				map._docLayer._twipsToLatLng(buttonAreaTwips[0], this._map.getZoom()),
+				map._docLayer._twipsToLatLng(buttonAreaTwips[1], this._map.getZoom()));
 
 		var buttonAreaLayer = new L.Bounds(
-				this._map.latLngToLayerPoint(buttonAreaLatLng.getNorthWest()),
-				this._map.latLngToLayerPoint(buttonAreaLatLng.getSouthEast()));
+				map.latLngToLayerPoint(buttonAreaLatLng.getNorthWest()),
+				map.latLngToLayerPoint(buttonAreaLatLng.getSouthEast()));
+
+		return buttonAreaLayer;
+	},
+
+	_buildButtonFrame: function(container, buttonArea) {
+		// Create a frame around the text area
+		var buttonFrame = L.DomUtil.create('div', 'form-field-frame', container);
 
 		// Use a small padding between the text and the frame
 		var extraPadding = 2;
-		var size = buttonAreaLayer.getSize();
-		this.frameWidth = size.x + 1.5 * extraPadding;
-		this.frameHeight = size.y + 1.5 * extraPadding;
-		this._frame.style.width = this.frameWidth + 'px';
-		this._container.style.height = this.frameHeight + 'px';
+		var size = buttonArea.getSize();
+		var frameWidth = size.x + 1.5 * extraPadding;
+		var frameHeight = size.y + 1.5 * extraPadding;
+		buttonFrame.style.width = frameWidth + 'px';
 
-		this.framePos = new L.Point(buttonAreaLayer.min.x - extraPadding, buttonAreaLayer.min.y - extraPadding);
-		L.DomUtil.setPosition(this._frame, this.framePos);
+		var framePos = new L.Point(buttonArea.min.x - extraPadding, buttonArea.min.y - extraPadding);
+		L.DomUtil.setPosition(buttonFrame, framePos);
 
-		// Add a drop down button to open the list
-		this._button = L.DomUtil.create('button', 'form-field-button', this._container);
-		var buttonPos = new L.Point(buttonAreaLayer.max.x + extraPadding, buttonAreaLayer.min.y - extraPadding);
-		L.DomUtil.setPosition(this._button, buttonPos);
-		this._button.style.width = this._container.style.height;
+		return [framePos, frameWidth, frameHeight];
+	},
+
+	_buildDropDownButton: function(container, framePos, frameWidth) {
+		var button = L.DomUtil.create('button', 'form-field-button', container);
+		var buttonPos = new L.Point(framePos.x + frameWidth, framePos.y);
+		L.DomUtil.setPosition(button, buttonPos);
+		button.style.width = container.style.height;
 
-		var image = L.DomUtil.create('img', 'form-field-button-image', this._button);
+		var image = L.DomUtil.create('img', 'form-field-button-image', button);
 		image.src = 'images/unfold.svg';
 
-		this._button.addEventListener('click', this._onClickDropDown);
+		button.addEventListener('click', this._onClickDropDown);
+	},
 
-		// Build list of items
-		this._dropDownList = L.DomUtil.create('div', 'drop-down-field-list', this.getPane('formfieldPane'));
+	_buildDropDownList: function(framePos, frameWidth, frameHeight) {
+		var dropDownList = L.DomUtil.create('div', 'drop-down-field-list', this.getPane('formfieldPane'));
 		$('.drop-down-field-list').hide();
-		var listPos = this.framePos;
-		L.DomUtil.setPosition(this._dropDownList, listPos);
-		this._dropDownList.style.minWidth = (this.frameWidth + this.frameHeight) + 'px';
+		L.DomUtil.setPosition(dropDownList, framePos);
+		dropDownList.style.minWidth = (frameWidth + frameHeight) + 'px';
 
 		var itemList = this._buttonData.params.items;
 		var selected = parseInt(this._buttonData.params.selected);
 		for (var i = 0; i < itemList.length; ++i) {
-			var option = L.DomUtil.create('div', 'drop-down-field-list-item', this._dropDownList);
+			var option = L.DomUtil.create('div', 'drop-down-field-list-item', dropDownList);
 			option.innerHTML = itemList[i];
 			option.addEventListener('click', this._onListItemSelect);
 			// Stop propagation to the main document
 			option.addEventListener('mouseup', function(event) {event.stopPropagation();});
 			option.addEventListener('mousedown', function(event) {event.stopPropagation();});
+
 			if (i === selected)
 				option.classList.add('selected');
 		}
@@ -101,8 +131,6 @@ L.FormFieldButton = L.Layer.extend({
 
 	_clearButton: function() {
 		this.getPane('formfieldPane').innerHTML = '';
-		this._frame = undefined;
-		this._button = undefined;
 	}
 
 });
commit 6640ba5cef23ecf911b0058df34fbec155ab5b29
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Tue May 5 15:20:22 2020 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat May 9 09:54:08 2020 +0200

    MSForms: use the actual item list for drop down field.
    
    Change-Id: Ib6021cf5d2a0c25bcd04f44771a33b3e3cea53fb

diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js
index cfd91a605..14ca0f401 100644
--- a/loleaflet/src/layer/FormFieldButtonLayer.js
+++ b/loleaflet/src/layer/FormFieldButtonLayer.js
@@ -68,17 +68,16 @@ L.FormFieldButton = L.Layer.extend({
 		L.DomUtil.setPosition(this._dropDownList, listPos);
 		this._dropDownList.style.minWidth = (this.frameWidth + this.frameHeight) + 'px';
 
-		// TODO: use the actual list here
-		var stringList = ['text1', 'text2', 'string', 'selected_item'];
-		var selected = 'selected_item';
-		for (var i = 0; i < stringList.length; ++i) {
+		var itemList = this._buttonData.params.items;
+		var selected = parseInt(this._buttonData.params.selected);
+		for (var i = 0; i < itemList.length; ++i) {
 			var option = L.DomUtil.create('div', 'drop-down-field-list-item', this._dropDownList);
-			option.innerHTML = stringList[i];
+			option.innerHTML = itemList[i];
 			option.addEventListener('click', this._onListItemSelect);
 			// Stop propagation to the main document
 			option.addEventListener('mouseup', function(event) {event.stopPropagation();});
 			option.addEventListener('mousedown', function(event) {event.stopPropagation();});
-			if (stringList[i] === selected)
+			if (i === selected)
 				option.classList.add('selected');
 		}
 	},
commit 3bce2d45ab344b5c7e3a20ac79ebd42620a95448
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri May 1 17:57:38 2020 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat May 9 09:54:08 2020 +0200

    MSForms: build drop down list for drop-down field.
    
    Change-Id: I42a68ebf8b0201d97779f2bfc43a8dabbad9e1c0

diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css
index 7f874c222..8639f504d 100644
--- a/loleaflet/css/loleaflet.css
+++ b/loleaflet/css/loleaflet.css
@@ -544,9 +544,22 @@ body {
 }
 
 .form-field-button:hover, .form-field-button:focus {
-  background: #DDDDDD;
+	background: #DDDDDD;
 }
 
 .form-field-button-image {
 	margin: 3px;
 }
+
+.drop-down-field-list {
+	position: absolute;
+	border: 1px solid;
+}
+
+.drop-down-field-list-item {
+	width: 100%;
+}
+
+.drop-down-field-list-item.selected {
+	background: #99CCFF;
+}
diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js
index 169f030e0..cfd91a605 100644
--- a/loleaflet/src/layer/FormFieldButtonLayer.js
+++ b/loleaflet/src/layer/FormFieldButtonLayer.js
@@ -2,7 +2,7 @@
 /*
  * L.FormFieldButton is used to interact with text based form fields.
  */
-
+/* global $ */
 L.FormFieldButton = L.Layer.extend({
 
 	options: {
@@ -16,6 +16,7 @@ L.FormFieldButton = L.Layer.extend({
 			var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
 			var bottomRightTwips = topLeftTwips.add(offset);
 			this._buttonAreaTwips = [topLeftTwips, bottomRightTwips];
+			this._buttonData = data;
 		}
 	},
 
@@ -26,8 +27,10 @@ L.FormFieldButton = L.Layer.extend({
 	},
 
 	_buildFormButton: function(map) {
+		this._container = L.DomUtil.create('div', 'form-field-button-container', this.getPane('formfieldPane'));
+
 		// Create a frame around the text area
-		this._frame = L.DomUtil.create('div', 'form-field-frame', this.getPane('formfieldPane'));
+		this._frame = L.DomUtil.create('div', 'form-field-frame', this._container);
 		var buttonAreaLatLng = new L.LatLngBounds(
 				map._docLayer._twipsToLatLng(this._buttonAreaTwips[0], this._map.getZoom()),
 				map._docLayer._twipsToLatLng(this._buttonAreaTwips[1], this._map.getZoom()));
@@ -39,37 +42,68 @@ L.FormFieldButton = L.Layer.extend({
 		// Use a small padding between the text and the frame
 		var extraPadding = 2;
 		var size = buttonAreaLayer.getSize();
-		this._frame.style.width = (size.x + 1.5 * extraPadding) + 'px';
+		this.frameWidth = size.x + 1.5 * extraPadding;
+		this.frameHeight = size.y + 1.5 * extraPadding;
+		this._frame.style.width = this.frameWidth + 'px';
+		this._container.style.height = this.frameHeight + 'px';
 
-		this.getPane('formfieldPane').style.height = (size.y + 1.5 * extraPadding) + 'px';
-
-		var framePos = new L.Point(buttonAreaLayer.min.x - extraPadding, buttonAreaLayer.min.y - extraPadding);
-		L.DomUtil.setPosition(this._frame, framePos);
+		this.framePos = new L.Point(buttonAreaLayer.min.x - extraPadding, buttonAreaLayer.min.y - extraPadding);
+		L.DomUtil.setPosition(this._frame, this.framePos);
 
 		// Add a drop down button to open the list
-		this._button = L.DomUtil.create('button', 'form-field-button', this.getPane('formfieldPane'));
+		this._button = L.DomUtil.create('button', 'form-field-button', this._container);
 		var buttonPos = new L.Point(buttonAreaLayer.max.x + extraPadding, buttonAreaLayer.min.y - extraPadding);
 		L.DomUtil.setPosition(this._button, buttonPos);
-		this._button.style.width = this.getPane('formfieldPane').style.height;
+		this._button.style.width = this._container.style.height;
 
 		var image = L.DomUtil.create('img', 'form-field-button-image', this._button);
 		image.src = 'images/unfold.svg';
+
+		this._button.addEventListener('click', this._onClickDropDown);
+
+		// Build list of items
+		this._dropDownList = L.DomUtil.create('div', 'drop-down-field-list', this.getPane('formfieldPane'));
+		$('.drop-down-field-list').hide();
+		var listPos = this.framePos;
+		L.DomUtil.setPosition(this._dropDownList, listPos);
+		this._dropDownList.style.minWidth = (this.frameWidth + this.frameHeight) + 'px';
+
+		// TODO: use the actual list here
+		var stringList = ['text1', 'text2', 'string', 'selected_item'];
+		var selected = 'selected_item';
+		for (var i = 0; i < stringList.length; ++i) {
+			var option = L.DomUtil.create('div', 'drop-down-field-list-item', this._dropDownList);
+			option.innerHTML = stringList[i];
+			option.addEventListener('click', this._onListItemSelect);
+			// Stop propagation to the main document
+			option.addEventListener('mouseup', function(event) {event.stopPropagation();});
+			option.addEventListener('mousedown', function(event) {event.stopPropagation();});
+			if (stringList[i] === selected)
+				option.classList.add('selected');
+		}
 	},
 
 	onRemove: function () {
 		this._clearButton();
 	},
 
+	_onClickDropDown: function() {
+		$('.drop-down-field-list').show();
+	},
+
+	_onListItemSelect: function(event) {
+		$('.drop-down-field-list-item.selected').removeClass('selected');
+		event.target.classList.add('selected');
+		// TODO: send back
+		$('.drop-down-field-list').hide();
+		event.stopPropagation();
+		console.warn(event.target.textContent);
+	},
+
 	_clearButton: function() {
 		this.getPane('formfieldPane').innerHTML = '';
-		if (this._frame) {
-			L.DomUtil.remove(this._frame);
-			this._frame = undefined;
-		}
-		if (this._button) {
-			L.DomUtil.remove(this._button);
-			this._button = undefined;
-		}
+		this._frame = undefined;
+		this._button = undefined;
 	}
 
 });
commit 87b862a4e2fafe2c420f672af835929d588757a2
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Apr 30 14:34:09 2020 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat May 9 09:54:08 2020 +0200

    MSForms: styling form field button.
    
    Change-Id: I4bbcc16aa8afb0fa7e8e84d34e1f18086f0b8615

diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css
index 834579ade..7f874c222 100644
--- a/loleaflet/css/loleaflet.css
+++ b/loleaflet/css/loleaflet.css
@@ -528,7 +528,25 @@ body {
 		-o-user-select: none;
 }
 
-.drop-down-button {
-	background: #FF0000;
+.form-field-frame {
+	border: 1px solid;
 	position: absolute;
+	height: 100%;
+}
+
+.form-field-button {
+	background: #FFFFFF;
+	position: absolute;
+	border: 1px solid;
+	height: 100%;
+	box-sizing: content-box;
+	padding: 0px;
+}
+
+.form-field-button:hover, .form-field-button:focus {
+  background: #DDDDDD;
+}
+
+.form-field-button-image {
+	margin: 3px;
 }
diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js
index bbbb0d721..169f030e0 100644
--- a/loleaflet/src/layer/FormFieldButtonLayer.js
+++ b/loleaflet/src/layer/FormFieldButtonLayer.js
@@ -20,11 +20,14 @@ L.FormFieldButton = L.Layer.extend({
 	},
 
 	onAdd: function (map) {
-		if (this._button) {
-			L.DomUtil.remove(this._button);
-		}
+		this._clearButton();
 
-		this._button = L.DomUtil.create('div', 'drop-down-button', this.getPane('formfieldPane'));
+		this._buildFormButton(map);
+	},
+
+	_buildFormButton: function(map) {
+		// Create a frame around the text area
+		this._frame = L.DomUtil.create('div', 'form-field-frame', this.getPane('formfieldPane'));
 		var buttonAreaLatLng = new L.LatLngBounds(
 				map._docLayer._twipsToLatLng(this._buttonAreaTwips[0], this._map.getZoom()),
 				map._docLayer._twipsToLatLng(this._buttonAreaTwips[1], this._map.getZoom()));
@@ -33,17 +36,40 @@ L.FormFieldButton = L.Layer.extend({
 				this._map.latLngToLayerPoint(buttonAreaLatLng.getNorthWest()),
 				this._map.latLngToLayerPoint(buttonAreaLatLng.getSouthEast()));
 
+		// Use a small padding between the text and the frame
+		var extraPadding = 2;
 		var size = buttonAreaLayer.getSize();
-		this._button.style.width  = size.x + 'px';
-		this._button.style.height = size.y + 'px';
+		this._frame.style.width = (size.x + 1.5 * extraPadding) + 'px';
+
+		this.getPane('formfieldPane').style.height = (size.y + 1.5 * extraPadding) + 'px';
+
+		var framePos = new L.Point(buttonAreaLayer.min.x - extraPadding, buttonAreaLayer.min.y - extraPadding);
+		L.DomUtil.setPosition(this._frame, framePos);
 
-		var pos = buttonAreaLayer.min;
-		L.DomUtil.setPosition(this._button, pos);
+		// Add a drop down button to open the list
+		this._button = L.DomUtil.create('button', 'form-field-button', this.getPane('formfieldPane'));
+		var buttonPos = new L.Point(buttonAreaLayer.max.x + extraPadding, buttonAreaLayer.min.y - extraPadding);
+		L.DomUtil.setPosition(this._button, buttonPos);
+		this._button.style.width = this.getPane('formfieldPane').style.height;
+
+		var image = L.DomUtil.create('img', 'form-field-button-image', this._button);
+		image.src = 'images/unfold.svg';
 	},
 
 	onRemove: function () {
-		L.DomUtil.remove(this._button);
-		this._button = undefined;
+		this._clearButton();
 	},
 
+	_clearButton: function() {
+		this.getPane('formfieldPane').innerHTML = '';
+		if (this._frame) {
+			L.DomUtil.remove(this._frame);
+			this._frame = undefined;
+		}
+		if (this._button) {
+			L.DomUtil.remove(this._button);
+			this._button = undefined;
+		}
+	}
+
 });
commit d2629961e0ca99bdebcfa0e3711abe6d5cc8cbcb
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Wed Apr 29 13:36:05 2020 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat May 9 09:54:08 2020 +0200

    MSForms: handle formfieldbutton message.
    
    Change-Id: I17243823d9bc0074b7fd015bca23de9399e0e26c

diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index b02e7a17a..e70cfde2e 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -2568,6 +2568,9 @@ void ChildSession::loKitCallback(const int type, const std::string& payload)
     case LOK_CALLBACK_TAB_STOP_LIST:
         sendTextFrame("tabstoplistupdate: " + payload);
         break;
+    case LOK_CALLBACK_FORM_FIELD_BUTTON:
+        sendTextFrame("formfieldbutton: " + payload);
+        break;
 
 #if !ENABLE_DEBUG
     // we want a compilation-time failure in the debug builds; but ERR in the
diff --git a/loleaflet/Makefile.am b/loleaflet/Makefile.am
index afbde0ec7..11945badb 100644
--- a/loleaflet/Makefile.am
+++ b/loleaflet/Makefile.am
@@ -230,6 +230,7 @@ LOLEAFLET_JS =\
 	src/layer/vector/Path.Transform.SVG.VML.js \
 	src/layer/vector/Canvas.js \
 	src/layer/vector/Path.Transform.Canvas.js \
+	src/layer/FormFieldButtonLayer.js \
 	src/dom/DomEvent.js \
 	src/dom/Draggable.js \
 	src/map/handler/Map.Drag.js \
diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css
index 40b782d95..834579ade 100644
--- a/loleaflet/css/loleaflet.css
+++ b/loleaflet/css/loleaflet.css
@@ -527,3 +527,8 @@ body {
 		-webkit-user-select: none;
 		-o-user-select: none;
 }
+
+.drop-down-button {
+	background: #FF0000;
+	position: absolute;
+}
diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js
new file mode 100644
index 000000000..bbbb0d721
--- /dev/null
+++ b/loleaflet/src/layer/FormFieldButtonLayer.js
@@ -0,0 +1,49 @@
+/* -*- js-indent-level: 8 -*- */
+/*
+ * L.FormFieldButton is used to interact with text based form fields.
+ */
+
+L.FormFieldButton = L.Layer.extend({
+
+	options: {
+		pane: 'formfieldPane'
+	},
+
+	initialize: function (data) {
+		if (data.type === 'drop-down') {
+			var strTwips = data.textArea.match(/\d+/g);
+			var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
+			var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
+			var bottomRightTwips = topLeftTwips.add(offset);
+			this._buttonAreaTwips = [topLeftTwips, bottomRightTwips];
+		}
+	},
+
+	onAdd: function (map) {
+		if (this._button) {
+			L.DomUtil.remove(this._button);
+		}
+
+		this._button = L.DomUtil.create('div', 'drop-down-button', this.getPane('formfieldPane'));
+		var buttonAreaLatLng = new L.LatLngBounds(
+				map._docLayer._twipsToLatLng(this._buttonAreaTwips[0], this._map.getZoom()),
+				map._docLayer._twipsToLatLng(this._buttonAreaTwips[1], this._map.getZoom()));
+
+		var buttonAreaLayer = new L.Bounds(
+				this._map.latLngToLayerPoint(buttonAreaLatLng.getNorthWest()),
+				this._map.latLngToLayerPoint(buttonAreaLatLng.getSouthEast()));
+
+		var size = buttonAreaLayer.getSize();
+		this._button.style.width  = size.x + 'px';
+		this._button.style.height = size.y + 'px';
+
+		var pos = buttonAreaLayer.min;
+		L.DomUtil.setPosition(this._button, pos);
+	},
+
+	onRemove: function () {
+		L.DomUtil.remove(this._button);
+		this._button = undefined;
+	},
+
+});
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index 4b51906fa..6deb6808f 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -726,6 +726,10 @@ L.TileLayer = L.GridLayer.extend({
 				this._map.fire('contextchange', {context: message[1]});
 			}
 		}
+		else if (textMsg.startsWith('formfieldbutton:')) {
+			this._onFormFieldButtonMsg(textMsg);
+			console.error(textMsg);
+		}
 	},
 
 	_onTabStopListUpdate: function (textMsg) {
@@ -3353,6 +3357,17 @@ L.TileLayer = L.GridLayer.extend({
 		this._previewInvalidations = [];
 	},
 
+	_onFormFieldButtonMsg: function (textMsg) {
+		textMsg = textMsg.substring('formfieldbutton:'.length + 1);
+		var json = JSON.parse(textMsg);
+		if (json.action === 'show') {
+			this._formFieldButton = new L.FormFieldButton(json);
+			this._map.addLayer(this._formFieldButton);
+		} else {
+			this._map.removeLayer(this._formFieldButton);
+		}
+	},
+
 	_debugGetTimeArray: function() {
 		return {count: 0, ms: 0, best: Number.MAX_SAFE_INTEGER, worst: 0, date: 0};
 	},
diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index 982cde654..18b168a1e 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -1045,6 +1045,7 @@ L.Map = L.Evented.extend({
 		this.createPane('overlayPane');
 		this.createPane('markerPane');
 		this.createPane('popupPane');
+		this.createPane('formfieldPane');
 
 		if (!this.options.markerZoomAnimation) {
 			L.DomUtil.addClass(panes.markerPane, 'leaflet-zoom-hide');


More information about the Libreoffice-commits mailing list