[Libreoffice-commits] online.git: bundled/include kit/ChildSession.cpp kit/KitHelper.hpp loleaflet/build loleaflet/css loleaflet/images loleaflet/Makefile.am loleaflet/src tools/KitClient.cpp

Tomaž Vajngerl (via logerrit) logerrit at kemper.freedesktop.org
Thu Aug 15 03:16:22 UTC 2019


 bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h |    9 
 kit/ChildSession.cpp                                 |    3 
 kit/KitHelper.hpp                                    |    2 
 loleaflet/Makefile.am                                |    1 
 loleaflet/build/deps.js                              |    3 
 loleaflet/css/loleaflet.css                          |   20 +
 loleaflet/images/table-column-resize-marker.svg      |   10 
 loleaflet/images/table-row-resize-marker.svg         |   10 
 loleaflet/src/layer/tile/TileLayer.TableOverlay.js   |  191 +++++++++++++++++++
 loleaflet/src/layer/tile/TileLayer.js                |    5 
 tools/KitClient.cpp                                  |    1 
 11 files changed, 254 insertions(+), 1 deletion(-)

New commits:
commit cc7060293945a6d45bf83376a456c57165a10f2f
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Wed Aug 14 18:13:40 2019 +0900
Commit:     Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Thu Aug 15 05:16:04 2019 +0200

    tdf#122529 Support for table overlay - column/row change markers
    
    This adds table markers for resizing rows and columns if the user
    has the table selected or the cursor is in the table. The code
    reacts to the callback "tableselected:", where the markers are
    created for each column and row, if the payload (json) of course
    has any data. When the marker is dragged, a uno command to resize
    the table column or row border is send to the core.
    
    Change-Id: I9b21d09639c1b2be70a1a897f9e3340b453d847e
    Reviewed-on: https://gerrit.libreoffice.org/77360
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    Tested-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 4277adbe6..0c8e5938f 100644
--- a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -665,6 +665,15 @@ typedef enum
      * Rectangle format is the same as LOK_CALLBACK_INVALIDATE_TILES.
      */
     LOK_CALLBACK_CELL_AUTO_FILL_AREA = 43,
+
+    /**
+     * When the cursor is in a table or a table is selected in the
+     * document, this sends the table's column and row border positions
+     * to the client. If the payload is empty (empty JSON object), then
+     * no table is currently selected or the cursor is not inside a table
+     * cell.
+     */
+    LOK_CALLBACK_TABLE_SELECTED = 44,
 }
 LibreOfficeKitCallbackType;
 
diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index 9684553e9..428808835 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -2296,6 +2296,9 @@ void ChildSession::loKitCallback(const int type, const std::string& payload)
     case LOK_CALLBACK_CELL_AUTO_FILL_AREA:
         sendTextFrame("cellautofillarea: " + payload);
         break;
+    case LOK_CALLBACK_TABLE_SELECTED:
+        sendTextFrame("tableselected: " + payload);
+        break;
 
 #if !ENABLE_DEBUG
     // we want a compilation-time failure in the debug builds; but ERR in the
diff --git a/kit/KitHelper.hpp b/kit/KitHelper.hpp
index 9f51fe528..8a32cb2dd 100644
--- a/kit/KitHelper.hpp
+++ b/kit/KitHelper.hpp
@@ -137,6 +137,8 @@ namespace LOKitHelper
             return "CELL_SELECTION_AREA";
         case LOK_CALLBACK_CELL_AUTO_FILL_AREA:
             return "CELL_AUTO_FILL_AREA";
+        case LOK_CALLBACK_TABLE_SELECTED:
+            return "TABLE_SELECTED";
        }
 
         assert(!"Missing LOK_CALLBACK type");
diff --git a/loleaflet/Makefile.am b/loleaflet/Makefile.am
index 00cfdc083..cb8522a6b 100644
--- a/loleaflet/Makefile.am
+++ b/loleaflet/Makefile.am
@@ -340,6 +340,7 @@ pot:
 		src/errormessages.js \
 		src/layer/marker/Annotation.js \
 		src/layer/tile/TileLayer.js \
+		src/layer/tile/TileLayer.TableOverlay.js \
 		src/map/Map.js \
 		src/map/Clipboard.js \
 		src/map/handler/Map.FileInserter.js \
diff --git a/loleaflet/build/deps.js b/loleaflet/build/deps.js
index 45feef2b5..52a71fd24 100644
--- a/loleaflet/build/deps.js
+++ b/loleaflet/build/deps.js
@@ -36,7 +36,8 @@ var deps = {
 	},
 
 	TileLayer: {
-		src: ['layer/tile/TileLayer.js'],
+		src: ['layer/tile/TileLayer.js',
+			  'layer/tile/TileLayer.TableOverlay.js'],
 		desc: 'The base class for displaying tile layers on the map.',
 		deps: ['GridLayer']
 	},
diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css
index 576931f8d..62cecafa9 100644
--- a/loleaflet/css/loleaflet.css
+++ b/loleaflet/css/loleaflet.css
@@ -41,6 +41,26 @@
 	-ms-filter: "alpha(opacity=100)" !important;
 }
 
+.table-column-resize-marker {
+	margin-left: 0px;
+	margin-top: 0px;
+	width: 24px;
+	height: 24px;
+	background-image: url('images/table-column-resize-marker.svg');
+	background-size: 100% 100%;
+	background-repeat: no-repeat;
+}
+
+.table-row-resize-marker {
+	margin-left: 0px;
+	margin-top: 0px;
+	width: 24px;
+	height: 24px;
+	background-image: url('images/table-row-resize-marker.svg');
+	background-size: 100% 100%;
+	background-repeat: no-repeat;
+}
+
 body {
 	margin: 0;
 	overflow: hidden;
diff --git a/loleaflet/images/table-column-resize-marker.svg b/loleaflet/images/table-column-resize-marker.svg
new file mode 100644
index 000000000..2eefb752c
--- /dev/null
+++ b/loleaflet/images/table-column-resize-marker.svg
@@ -0,0 +1,10 @@
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <g transform="matrix(0 -.70331 .70329 0 4.7475 27.253)" fill="#fff" fill-opacity=".86275" stroke="#000" stroke-linecap="round">
+  <rect x="2.5185" y="2.5185" width="26.963" height="26.963" rx="4.4235" ry="4.4236" stroke-width="1.4745"/>
+  <g stroke-width="1.4219">
+   <rect x="8.5" y="8.5" width="15" height="1"/>
+   <rect x="8.5" y="15.5" width="15" height="1"/>
+   <rect x="8.5" y="22.5" width="15" height="1"/>
+  </g>
+ </g>
+</svg>
diff --git a/loleaflet/images/table-row-resize-marker.svg b/loleaflet/images/table-row-resize-marker.svg
new file mode 100644
index 000000000..812a38d43
--- /dev/null
+++ b/loleaflet/images/table-row-resize-marker.svg
@@ -0,0 +1,10 @@
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <g transform="matrix(.70331 0 0 .70329 4.7472 4.7474)" fill="#fff" fill-opacity=".86275" stroke="#000" stroke-linecap="round">
+  <rect x="2.5185" y="2.5185" width="26.963" height="26.963" rx="4.4235" ry="4.4236" stroke-width="1.4745"/>
+  <g stroke-width="1.4219">
+   <rect x="8.5" y="8.5" width="15" height="1"/>
+   <rect x="8.5" y="15.5" width="15" height="1"/>
+   <rect x="8.5" y="22.5" width="15" height="1"/>
+  </g>
+ </g>
+</svg>
diff --git a/loleaflet/src/layer/tile/TileLayer.TableOverlay.js b/loleaflet/src/layer/tile/TileLayer.TableOverlay.js
new file mode 100644
index 000000000..169af9d8e
--- /dev/null
+++ b/loleaflet/src/layer/tile/TileLayer.TableOverlay.js
@@ -0,0 +1,191 @@
+/* -*- js-indent-level: 8 -*- */
+/*
+ * Table Overlay
+ */
+
+L.TileLayer.include({
+	_initializeTableOverlay: function () {
+		this._tableColumnMarkers = [];
+		this._tableRowMarkers = [];
+		this._tableMarkersDragged = false;
+	},
+	_setMarkerPosition: function(marker) {
+		var point = this._twipsToLatLng(marker._pointTwips, this._map.getZoom());
+		point = this._map.project(point);
+		var markerRect = marker._icon.getBoundingClientRect();
+		if (marker._type.startsWith('column'))
+			point = point.subtract(new L.Point(markerRect.width / 2, markerRect.height));
+		else
+			point = point.subtract(new L.Point(markerRect.width, markerRect.height / 2));
+		point = this._map.unproject(point);
+		marker.setLatLng(point);
+	},
+	_createMarker: function(markerType, entry, left, right) {
+		var className;
+		if (markerType === 'column')
+			className = 'table-column-resize-marker';
+		else
+			className = 'table-row-resize-marker';
+
+		var marker = L.marker(new L.LatLng(0, 0), {
+			icon: L.divIcon({
+				className: className,
+				iconSize: null
+			}),
+			draggable: true
+		});
+		this._map.addLayer(marker);
+		marker._type = markerType + '-' + entry.type;
+		marker._position = parseInt(entry.position);
+		marker._min = parseInt(entry.min);
+		marker._max = parseInt(entry.max);
+		marker._index = parseInt(entry.index);
+		if (markerType === 'column') {
+			marker._pointTwips = new L.Point(this._tablePositionColumnOffset + marker._position, left);
+			marker._pointTop = new L.Point(this._tablePositionColumnOffset + marker._position, left);
+			marker._pointTop = this._twipsToLatLng(marker._pointTop, this._map.getZoom());
+			marker._pointBottom = new L.Point(this._tablePositionColumnOffset + marker._position, right);
+			marker._pointBottom = this._twipsToLatLng(marker._pointBottom, this._map.getZoom());
+		}
+		else {
+			marker._pointTwips = new L.Point(left, this._tablePositionRowOffset + marker._position);
+			marker._pointTop = new L.Point(left, this._tablePositionRowOffset + marker._position);
+			marker._pointTop = this._twipsToLatLng(marker._pointTop, this._map.getZoom());
+			marker._pointBottom = new L.Point(right, this._tablePositionRowOffset + marker._position);
+			marker._pointBottom = this._twipsToLatLng(marker._pointBottom, this._map.getZoom());
+		}
+		this._setMarkerPosition(marker);
+		marker.on('dragstart drag dragend', this._onTableResizeMarkerDrag, this);
+		return marker;
+	},
+	_onTableSelectedMsg: function (textMsg) {
+		if (this._tableMarkersDragged == true) {
+			return;
+		}
+
+		// Clean-up first
+		var markerIndex;
+		for (markerIndex = 0; markerIndex < this._tableColumnMarkers.length; markerIndex++) {
+			this._map.removeLayer(this._tableColumnMarkers[markerIndex]);
+		}
+		this._tableColumnMarkers = [];
+
+		for (markerIndex = 0; markerIndex < this._tableRowMarkers.length; markerIndex++) {
+			this._map.removeLayer(this._tableRowMarkers[markerIndex]);
+		}
+		this._tableRowMarkers = [];
+
+		// Parse the message
+		textMsg = textMsg.substring('tableselected:'.length + 1);
+		var message = JSON.parse(textMsg);
+
+		// Create markers
+		if (message.rows && message.rows.entries.length > 0 && message.columns && message.columns.entries.length > 0) {
+			this._tablePositionColumnOffset = parseInt(message.columns.tableOffset);
+			this._tablePositionRowOffset = parseInt(message.rows.tableOffset);
+			var firstRowPosition = parseInt(message.rows.left) + this._tablePositionRowOffset;
+			var lastRowPosition = parseInt(message.rows.right) + this._tablePositionRowOffset;
+			var firstColumnPosition = parseInt(message.columns.left) + this._tablePositionColumnOffset;
+			var lastColumnPosition = parseInt(message.columns.right) + this._tablePositionColumnOffset;
+			var markerX, i, entry;
+
+			entry = { type: 'left', position: message.columns.left, index: 0 };
+			markerX = this._createMarker('column', entry, firstRowPosition, lastRowPosition);
+			this._tableColumnMarkers.push(markerX);
+
+			for (i = 0; i < message.columns.entries.length; i++) {
+				entry = message.columns.entries[i];
+				entry.type = 'middle';
+				entry.index = i;
+				markerX = this._createMarker('column', entry, firstRowPosition, lastRowPosition);
+				this._tableColumnMarkers.push(markerX);
+			}
+
+			entry = { type: 'right', position: message.columns.right, index: 0 };
+			markerX = this._createMarker('column', entry, firstRowPosition, lastRowPosition);
+			this._tableColumnMarkers.push(markerX);
+
+			for (i = 0; i < message.rows.entries.length; i++) {
+				entry = message.rows.entries[i];
+				entry.type = 'middle';
+				entry.index = i;
+				markerX = this._createMarker('row', entry, firstColumnPosition, lastColumnPosition);
+				this._tableRowMarkers.push(markerX);
+			}
+
+			entry = { type: 'right', position: message.rows.right };
+			markerX = this._createMarker('row', entry, firstColumnPosition, lastColumnPosition);
+			this._tableRowMarkers.push(markerX);
+		}
+	},
+
+	// Update dragged text selection.
+	_onTableResizeMarkerDrag: function (e) {
+		if (e.type === 'dragstart') {
+			e.target.isDragged = true;
+			this._tableMarkersDragged = true;
+		}
+		else if (e.type === 'dragend') {
+			e.target.isDragged = false;
+			this._tableMarkersDragged = false;
+		}
+
+		// modify the mouse position - move to center of the marker
+		var aMousePosition = e.target.getLatLng();
+		aMousePosition = this._map.project(aMousePosition);
+		var size = e.target._icon.getBoundingClientRect();
+		aMousePosition = aMousePosition.add(new L.Point(size.width / 2, size.height / 2));
+		aMousePosition = this._map.unproject(aMousePosition);
+		var aLatLonPosition = aMousePosition;
+		aMousePosition = this._latLngToTwips(aMousePosition);
+
+		var newPosition;
+		if (e.target._type.startsWith('column')) {
+			newPosition = aMousePosition.x - this._tablePositionColumnOffset;
+			e.target._pointTop.lng = aLatLonPosition.lng;
+			e.target._pointBottom.lng = aLatLonPosition.lng;
+		}
+		else {
+			newPosition = aMousePosition.y - this._tablePositionRowOffset;
+			e.target._pointTop.lat = aLatLonPosition.lat;
+			e.target._pointBottom.lat = aLatLonPosition.lat;
+		}
+
+		e.target._position = newPosition;
+
+		var bounds = new L.LatLngBounds(e.target._pointTop, e.target._pointBottom);
+
+		if (e.type === 'dragstart') {
+			this._rectangle = new L.Rectangle(bounds);
+			this._map.addLayer(this._rectangle);
+		}
+		else if (e.type === 'drag') {
+			this._rectangle.setBounds(bounds);
+		}
+		else if (e.type === 'dragend') {
+			this._map.removeLayer(this._rectangle);
+			this._rectangle = null;
+
+			var params = {
+				BorderType: {
+					type : 'string',
+					value : e.target._type
+				},
+				Index: {
+					type : 'uint16',
+					value : e.target._index
+				},
+				NewPosition: {
+					type : 'int32',
+					value : e.target._position
+				}
+			}
+
+			this._map.sendUnoCommand('.uno:TableChangeCurrentBorderPosition', params);
+		}
+
+		if (e.originalEvent)
+			e.originalEvent.preventDefault();
+	}
+});
+
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index 72b1c6558..87cf380f4 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -162,6 +162,8 @@ L.TileLayer = L.GridLayer.extend({
 			draggable: true
 		});
 
+		this._initializeTableOverlay();
+
 		this._emptyTilesCount = 0;
 		this._msgQueue = [];
 		this._toolbarCommandValues = {};
@@ -510,6 +512,9 @@ L.TileLayer = L.GridLayer.extend({
 		else if (textMsg.startsWith('graphicviewselection:')) {
 			this._onGraphicViewSelectionMsg(textMsg);
 		}
+		else if (textMsg.startsWith('tableselected:')) {
+			this._onTableSelectedMsg(textMsg);
+		}
 		else if (textMsg.startsWith('editor:')) {
 			this._updateEditor(textMsg);
 		}
diff --git a/tools/KitClient.cpp b/tools/KitClient.cpp
index c68de9adf..a4419a3e3 100644
--- a/tools/KitClient.cpp
+++ b/tools/KitClient.cpp
@@ -87,6 +87,7 @@ extern "C"
             CASE(PROFILE_FRAME);
             CASE(CELL_SELECTION_AREA);
             CASE(CELL_AUTO_FILL_AREA);
+            CASE(TABLE_SELECTED);
 #undef CASE
         }
         std::cout << " payload: " << payload << std::endl;


More information about the Libreoffice-commits mailing list