[Libreoffice-commits] online.git: 26 commits - loleaflet/build loleaflet/debug loleaflet/dist loleaflet/src loolwsd/protocol.txt

Pranav Kant pranavk at collabora.com
Mon May 23 08:13:21 UTC 2016


 loleaflet/build/deps.js                           |    7 
 loleaflet/debug/document/loleaflet.html           |    4 
 loleaflet/dist/contextMenu/jquery.contextMenu.css |    8 
 loleaflet/dist/images/lc_inserttable.png          |binary
 loleaflet/dist/images/sc_inserttable.png          |binary
 loleaflet/dist/loleaflet.css                      |   17 
 loleaflet/dist/loleaflet.html                     |    4 
 loleaflet/dist/partsPreviewControl.css            |    2 
 loleaflet/dist/smartmenus/jquery.smartmenus.js    | 1214 ++++++++++++++++++++++
 loleaflet/dist/smartmenus/sm-core-css.css         |   14 
 loleaflet/dist/smartmenus/sm-simple.css           |  287 +++++
 loleaflet/dist/spreadsheet.css                    |   14 
 loleaflet/dist/toolbar.css                        |   30 
 loleaflet/dist/toolbar/toolbar.js                 |  156 +-
 loleaflet/src/control/Control.ContextMenu.js      |    3 
 loleaflet/src/control/Control.Menubar.js          |  340 ++++++
 loolwsd/protocol.txt                              |    5 
 17 files changed, 2018 insertions(+), 87 deletions(-)

New commits:
commit 6104e3e4bf5fd0b98e4c71e62c074cad84d5f37b
Author: Pranav Kant <pranavk at collabora.com>
Date:   Mon May 23 10:59:34 2016 +0530

    loleaflet: Disable menubar items for view only mode
    
    Change-Id: Ic1a3c876df343598cf0b53f033ea9e35053e6a06

diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 33e47d6..09ad026 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -130,7 +130,12 @@ L.Control.menubar = L.Control.extend({
 			}
 		],
 
-		commandStates: {}
+		commandStates: {},
+
+		allowedViewModeActions: ['downloadas-pdf', 'downloadas-odt', 'downloadas-doc', 'downloadas-docx',
+								 'downloadas-odp', 'downloadas-ppt', 'downloadas-pptx',
+								 'downloadas-ods', 'downloadas-xls', 'downloadas-xlsx',
+								 'fullscreen', 'zoomin', 'zoomout', 'zoomreset']
 	},
 
 	onAdd: function (map) {
@@ -189,6 +194,24 @@ L.Control.menubar = L.Control.extend({
 		$(items).each(function() {
 			var aItem = this;
 			var type = $(aItem).data('type');
+			var id = $(aItem).data('id');
+			if (!map._editlock) {
+				var found = false;
+				for (var i in self.options.allowedViewModeActions) {
+					if (self.options.allowedViewModeActions[i] === id) {
+						found = true;
+						break;
+					}
+				}
+				if (!found) {
+					$(aItem).addClass('disabled');
+				} else {
+					$(aItem).removeClass('disabled');
+				}
+
+				return;
+			}
+
 			if (type === 'unocommand') {
 				var unoCommand = $(aItem).data('uno');
 				if (self.options.commandStates[unoCommand] === 'disabled') {
commit 1e806b0a46202769a60cdb802143f80bc78f72de
Author: Pranav Kant <pranavk at collabora.com>
Date:   Mon May 23 10:51:49 2016 +0530

    beforeFirstShow -> beforeShow
    
    Change-Id: I8bdcc91220873c40d4161ade9a853233227476ab

diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 9effb33..33e47d6 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -180,10 +180,10 @@ L.Control.menubar = L.Control.extend({
 		this._initialized = true;
 
 		$('#main-menu').bind('select.smapi', {self: this}, this._onItemSelected);
-		$('#main-menu').bind('beforeshow.smapi', {self: this}, this._beforeFirstShow);
+		$('#main-menu').bind('beforeshow.smapi', {self: this}, this._beforeShow);
 	},
 
-	_beforeFirstShow: function(e, menu) {
+	_beforeShow: function(e, menu) {
 		var self = e.data.self;
 		var items = $(menu).children().children('a').not('.has-submenu');
 		$(items).each(function() {
commit ffd230e1f95343c6d39bf17354ade3762df8fad5
Author: Pranav Kant <pranavk at collabora.com>
Date:   Fri May 20 18:19:16 2016 +0530

    loleaflet: Use same font-family wherever possible
    
    "Segoe UI", Tahoma, Arial, Helvetica, sans-serif; 12px
    
    Change-Id: I8927c31ca4641eaa3181e4f76bac2e112893fcd8

diff --git a/loleaflet/dist/contextMenu/jquery.contextMenu.css b/loleaflet/dist/contextMenu/jquery.contextMenu.css
index 5b1bc7e..b74941f 100644
--- a/loleaflet/dist/contextMenu/jquery.contextMenu.css
+++ b/loleaflet/dist/contextMenu/jquery.contextMenu.css
@@ -103,8 +103,8 @@
 
 .context-menu-item {
   position: relative;
-  padding: 3px 28px;
-  color: #2f2f2f;
+  padding: 5px 28px;
+  color: #000;
   -webkit-user-select: none;
      -moz-user-select: none;
       -ms-user-select: none;
diff --git a/loleaflet/dist/loleaflet.css b/loleaflet/dist/loleaflet.css
index a7c7597..15d7f9e 100644
--- a/loleaflet/dist/loleaflet.css
+++ b/loleaflet/dist/loleaflet.css
@@ -29,3 +29,9 @@
 body {
     margin: 0;
 }
+
+.loleaflet-font {
+    font-family: "Segoe UI", Tahoma, Arial, Helvetica, sans-serif !important;
+    font-size: 12px !important;
+    font-weight: normal !important;
+}
\ No newline at end of file
diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index 1f080df..ac38a70 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -6,7 +6,7 @@
     /* make room for the toggle button (sub indicator) */
     padding-right: 58px;
     color: #555555;
-    font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif;
+    font-family: "Segoe UI", Tahoma, Arial, Helvetica, sans-serif;
     font-size: 12px;
     font-weight: normal;
     line-height: 15px;
@@ -46,7 +46,7 @@
     background: #fff;
 }
 .sm-simple ul a, .sm-simple ul a:hover, .sm-simple ul a:focus, .sm-simple ul a:active {
-    font-size: 14px;
+    font-size: 12px;
     border-left: 8px solid transparent;
 }
 .sm-simple ul ul a,
diff --git a/loleaflet/dist/spreadsheet.css b/loleaflet/dist/spreadsheet.css
index 8e1c0f3..7537600 100644
--- a/loleaflet/dist/spreadsheet.css
+++ b/loleaflet/dist/spreadsheet.css
@@ -38,7 +38,7 @@
 	padding-top: 3px;
 	padding-bottom: 3px;
 
-	font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+	font: 12px/1.5 "Segoe UI", Tahoma, Arial, Helvetica, sans-serif;
 	display: inline-block;
 	border: 1px solid darkgrey;
 	background-color: lightgrey;
@@ -99,7 +99,7 @@
 
 .spreadsheet-header-column {
 	border-right: 1px solid darkgrey;
-	font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+	font: 12px/1.5 "Segoe UI", Tahoma, Arial, Helvetica, sans-serif;
 
 	display: inline-block;
 	text-align: center;
@@ -146,7 +146,7 @@
 
 .spreadsheet-header-row {
 	border-bottom: 1px solid darkgrey;
-	font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+	font: 12px/1.5 "Segoe UI", Tahoma, Arial, Helvetica, sans-serif;
 
 	text-overflow: ellipsis;
 	text-align: center;
diff --git a/loleaflet/dist/toolbar.css b/loleaflet/dist/toolbar.css
index 022d383..51d38dc 100644
--- a/loleaflet/dist/toolbar.css
+++ b/loleaflet/dist/toolbar.css
@@ -166,10 +166,15 @@ button.leaflet-control-search-next
 /* select box */
 .select2-results__option {
     padding: 5px;
-    font-size: 14px;
+    font-family: "Segoe UI", Tahoma, Arial, Helvetica, sans-serif;
+    font-size: 12px;
     overflow: hidden;
     text-overflow: ellipsis;
 }
+.select2-selection__rendered {
+    font-family: "Segoe UI", Tahoma, Arial, Helvetica, sans-serif;
+    font-size: 12px;
+}
 .styles-select {
     width: 180px;
 }
@@ -272,4 +277,4 @@ button.leaflet-control-search-next
 
 #tablePicker div {
     text-align:left;
-}
\ No newline at end of file
+}
diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index 1ca5a02..84f7af5 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -127,10 +127,10 @@ $(function () {
 			{ type: 'button',  id: 'cancelsearch', img: 'cancel', hint: _("Cancel the search"), hidden: true },
 			{ type: 'html',  id: 'left' },
 			{ type: 'html',  id: 'right' },
-			{ type: 'html',    id: 'modifiedstatuslabel', html: '<div id="modifiedstatuslabel"></div>' },
+			{ type: 'html',    id: 'modifiedstatuslabel', html: '<div id="modifiedstatuslabel" class="loleaflet-font"></div>' },
 			{ type: 'break' },
 			{ type: 'button',  id: 'takeedit', img: 'edit', hint: _("Take edit lock (others can only view)")},
-			{ type: 'html',    id: 'takeeditlabel', html: '<div id="takeeditlabel">VIEWING</div>' },
+			{ type: 'html',    id: 'takeeditlabel', html: '<div id="takeeditlabel" class="loleaflet-font">VIEWING</div>' },
 			{ type: 'break' },
 			{ type: 'button',  id: 'prev', img: 'prev', hint: _("Previous page") },
 			{ type: 'button',  id: 'next', img: 'next', hint: _("Next page") },
diff --git a/loleaflet/src/control/Control.ContextMenu.js b/loleaflet/src/control/Control.ContextMenu.js
index 3b83992..f0cfc52 100644
--- a/loleaflet/src/control/Control.ContextMenu.js
+++ b/loleaflet/src/control/Control.ContextMenu.js
@@ -60,6 +60,7 @@ L.Control.ContextMenu = L.Control.extend({
 		var contextMenu = this._createContextMenuStructure(obj);
 		$.contextMenu({
 			selector: '.leaflet-layer',
+			className: 'loleaflet-font',
 			trigger: 'none',
 			build: function(triggerEle, e) {
 				return {
commit 3d266a4d6077df0036ce3f9e462a57eefe897164
Author: Pranav Kant <pranavk at collabora.com>
Date:   Fri May 20 14:21:13 2016 +0530

    loleaflet: More consistent styling to match LO desktop
    
    Selection background color is now consistent across context menu
    and menubars.
    
    Don't change the cursor to 'pointer' in context menus on hover.
    
    Change-Id: I25d1fcba113f2c27a8ab6d028244afd75c28cd59

diff --git a/loleaflet/dist/contextMenu/jquery.contextMenu.css b/loleaflet/dist/contextMenu/jquery.contextMenu.css
index f8de521..5b1bc7e 100644
--- a/loleaflet/dist/contextMenu/jquery.contextMenu.css
+++ b/loleaflet/dist/contextMenu/jquery.contextMenu.css
@@ -128,8 +128,8 @@
 
 .context-menu-item.context-menu-hover {
   color: #fff;
-  cursor: pointer; 
-  background-color: #2980b9;
+  cursor: default;
+  background-color: #538ecd;
 }
 
 .context-menu-item.context-menu-disabled {
diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index 624d06e..1f080df 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -138,13 +138,15 @@ collapsible to desktop (navbar + dropdowns)
 }
 .sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted {
     padding: 5px 15px;
-    color: #555;
+    color: #000;
 }
 .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted {
-    background: #eee;
+    background: #538ecd;
+    color: #fff;
 }
 .sm-simple > li > a:hover, .sm-simple > li > a:focus, .sm-simple > li > a:active, .sm-simple > li > a.highlighted {
     background: #fff;
+    color: #000;
     border-color: #bbbbbb;
     border-bottom: 1px solid #bbb;
 }
diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index e907e16..9effb33 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -171,6 +171,8 @@ L.Control.menubar = L.Control.extend({
 			showOnClick: true,
 			hideTimeout: 0,
 			hideDuration: 0,
+			showDuration: 0,
+			showTimeout: 0,
 			collapsibleHideDuration: 0,
 			subIndicatorsPos: 'append',
 			subIndicatorsText: '›'
commit 461d88e38d1cd402a5d672ab28ab04ca66aef377
Author: Pranav Kant <pranavk at collabora.com>
Date:   Fri May 20 15:45:48 2016 +0530

    loleaflet: Fix errors in new draggable table grid toolbar button
    
    Change-Id: Ic5c1ecbe0753017ad4b4c57ef74ae28d724c00a4

diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index 71ec95b..1ca5a02 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -1067,22 +1067,23 @@ function walkCells() {
 				walkCells();
 			} else if (table.rows[0].cells.length>3 && cellIndex < table.rows[0].cells.length-1 ) {
 				for (var j = 0; j < table.rows.length; j++) {
-					var tr = table.rows[j]
+					var tr = table.rows[j];
 					tr.deleteCell(table.rows[0].cells.length-1);
 				}
 				walkCells();
 			}
-		}
+		};
+
 		cell.onclick = function(){
 			var cellIndex = this.cellIndex + 1;
 			var rowIndex = this.parentNode.rowIndex + 1;
 			var msg = 'uno .uno:InsertTable {' +
-				' "Columns": { "type": "long","value": '
-				cellIndex +
-				' }, "Rows": { "type": "long","value": '
-				rowIndex +' }}';
+		   ' "Columns": { "type": "long","value": ' +
+		   cellIndex +
+		   ' }, "Rows": { "type": "long","value": ' +
+		   rowIndex +' }}';
 			map._socket.sendMessage(msg);
 			L.DomUtil.get('tablePicker').style.display = 'none';
-		}
+		};
 	}
-}
\ No newline at end of file
+}
commit 5846748e2a7a376302fec11eb9058f1f64b99977
Author: Faruk Uzun <farukuzun at collabora.com>
Date:   Sun May 1 15:07:49 2016 +0300

    loleaflet: add draggable table grid button to toolbar
    
    You can insert tables to text documents and
    it is working same as the desktop version.
    
    Change-Id: I5d516e31c8b7453ca7f8306df3b9c17764e94098

diff --git a/loleaflet/dist/images/lc_inserttable.png b/loleaflet/dist/images/lc_inserttable.png
new file mode 100644
index 0000000..7f65679
Binary files /dev/null and b/loleaflet/dist/images/lc_inserttable.png differ
diff --git a/loleaflet/dist/images/sc_inserttable.png b/loleaflet/dist/images/sc_inserttable.png
new file mode 100644
index 0000000..015ebb4
Binary files /dev/null and b/loleaflet/dist/images/sc_inserttable.png differ
diff --git a/loleaflet/dist/toolbar.css b/loleaflet/dist/toolbar.css
index 4be8d61..022d383 100644
--- a/loleaflet/dist/toolbar.css
+++ b/loleaflet/dist/toolbar.css
@@ -222,6 +222,7 @@ button.leaflet-control-search-next
 .w2ui-icon.insertpage{ background: url('/loleaflet/dist/images/lc_insertpage.png') no-repeat center !important; }
 .w2ui-icon.italic{ background: url('/loleaflet/dist/images/lc_italic.png') no-repeat center !important; }
 .w2ui-icon.insertgraphic{ background: url('/loleaflet/dist/images/lc_gallery.png') no-repeat center !important; }
+.w2ui-icon.inserttable{ background: url('/loleaflet/dist/images/lc_inserttable.png') no-repeat center !important; }
 .w2ui-icon.next{ background: url('/loleaflet/dist/images/lc_downsearch.png') no-repeat center !important; }
 .w2ui-icon.numbering{ background: url('/loleaflet/dist/images/lc_defaultnumbering.png') no-repeat center !important; }
 .w2ui-icon.presentation{ background: url('/loleaflet/dist/images/lc_dia.png') no-repeat center !important; }
@@ -253,3 +254,22 @@ button.leaflet-control-search-next
 	right:-10px;
 	cursor:pointer;
 }
+
+
+#tablePicker table {
+  border: 1px solid #808080;
+}
+
+#tablePicker td {
+  border: 1px solid #808080 !important;
+  width: 15px;
+  height: 15px;
+}
+
+#tablePicker td:hover {
+  background: #87CEFA;
+}
+
+#tablePicker div {
+    text-align:left;
+}
\ No newline at end of file
diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index 16618e4..71ec95b 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -46,6 +46,8 @@ $(function () {
 			{ type: 'break', id: 'incdecindent' },
 			{ type: 'button',  id: 'annotation', img: 'annotation', hint: _("Insert Comment"), uno: 'InsertAnnotation' },
 			{ type: 'button',  id: 'insertgraphic',  img: 'insertgraphic', hint: _("Insert Graphic") },
+			{ type: 'html',  id: 'inserttable-html', html: '<div id="tablePicker" class="evo-pop" style="position:absolute !important;display:none"><div id="tpstatus"></div><table id="insert-table"></table></div>' },
+			{ type: 'button',  id: 'inserttable',  img: 'inserttable', hint: _("Insert Table") },
 			{ type: 'break' },
 			{ type: 'button',  id: 'help',  img: 'help', hint: _("Help") },
 			{ type: 'html', id: 'right' },
@@ -288,6 +290,14 @@ function onClick(id) {
 	else if (id === 'insertgraphic') {
 		L.DomUtil.get('insertgraphic').click();
 	}
+	else if (id === 'inserttable') {
+		// toggles tablePicker
+		if (L.DomUtil.get('tablePicker').style.display == 'none') {
+			L.DomUtil.get('tablePicker').style.display = '';
+		} else {
+			L.DomUtil.get('tablePicker').style.display = 'none';
+		}
+	}
 	else if (id === 'fontcolor') {
 		// absolutely no idea why, but without the timeout, the popup is
 		// closed as soon as it is opend
@@ -1007,3 +1017,72 @@ function resizeToolbar() {
 		toolbar.uncheck('more');
 	}
 }
+
+// tablePicker - init
+$(function() {
+	$( "#tablePicker" ).draggable();
+	tbl = document.getElementById('insert-table');
+	for (var i = 0; i < 3; i++) {
+		var tr = tbl.insertRow();
+		for (var j = 0; j < 3; j++) {
+			var td = tr.insertCell();
+		}
+	}
+	walkCells();
+});
+
+// tablePicker - GUI
+function walkCells() {
+	var table = document.getElementById('insert-table');
+	var cells = table.getElementsByTagName("td");
+
+	for (var i = 0; i < cells.length; i++) {
+		var cell = cells[i];
+		cell.onmouseover = function() {
+			var cellIndex = this.cellIndex + 1;
+			var rowIndex = this.parentNode.rowIndex + 1;
+			var div = document.getElementById('tpstatus');
+			div.innerHTML = cellIndex + " x " + rowIndex;
+			for (var j = 0; j < cells.length; j++) {
+				var celly = cells[j];
+				if (celly.parentNode.rowIndex < rowIndex & celly.cellIndex < cellIndex) {
+					celly.style.background = '#87CEFA';
+				} else {
+					celly.style.background = '';
+				}
+			}
+			if (cellIndex == table.rows[0].cells.length) {
+				for (var k = 0; k < table.rows.length; k++) {
+					table.rows[k].insertCell();
+					walkCells();
+				}
+			} else if (rowIndex == table.rows.length) {
+				var tr = table.insertRow();
+				for (var j = 0; j < table.rows[0].cells.length; j++) {
+					var td = tr.insertCell();
+				}
+				walkCells();
+			} else if ((table.rows.length>3 && rowIndex < table.rows.length-1)) {
+				table.deleteRow(table.rows.length-1);
+				walkCells();
+			} else if (table.rows[0].cells.length>3 && cellIndex < table.rows[0].cells.length-1 ) {
+				for (var j = 0; j < table.rows.length; j++) {
+					var tr = table.rows[j]
+					tr.deleteCell(table.rows[0].cells.length-1);
+				}
+				walkCells();
+			}
+		}
+		cell.onclick = function(){
+			var cellIndex = this.cellIndex + 1;
+			var rowIndex = this.parentNode.rowIndex + 1;
+			var msg = 'uno .uno:InsertTable {' +
+				' "Columns": { "type": "long","value": '
+				cellIndex +
+				' }, "Rows": { "type": "long","value": '
+				rowIndex +' }}';
+			map._socket.sendMessage(msg);
+			L.DomUtil.get('tablePicker').style.display = 'none';
+		}
+	}
+}
\ No newline at end of file
commit acfb9922d5bafd479fe3e1449493aa25dfc74ebe
Author: Pranav Kant <pranavk at collabora.com>
Date:   Fri May 20 13:43:01 2016 +0530

    loleaflet: menubar: Decrease separator height
    
    Change-Id: I3c96bbc227ba911861e5d13902ad4f8dbb414549

diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index 2d3de53..624d06e 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -211,7 +211,7 @@ collapsible to desktop (navbar + dropdowns)
 }
 .sm-simple a.separator {
     height: 1px;
-    margin: 9px 0;
+    margin: 4px 0;
     overflow: hidden;
     padding-top: 0;
     padding-bottom: 0;
commit 8717b0417ebdbff478da5ee0f7b10f234ed92639
Author: Pranav Kant <pranavk at collabora.com>
Date:   Fri May 20 13:38:57 2016 +0530

    loleaflet: Change 'Table' menubar structure to match LO
    
    ... useful for translation.
    
    Change-Id: If3116351ea5b29c2cae866a7ac417c074ac35043

diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 96f3d25..e907e16 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -31,16 +31,18 @@ L.Control.menubar = L.Control.extend({
 												{name: 'Zoom out', id: 'zoomout', type: 'action'},
 												{name: 'Zoom reset', id: 'zoomreset', type: 'action'}]
 			},
-			{name: 'Tables', type: 'menu', menu: [{name: 'Insert row before', type: 'unocommand', uno: '.uno:InsertRowsBefore'},
-												  {name: 'Insert row after', type: 'unocommand', uno: '.uno:InsertRowsAfter'},
-												  {type: 'separator'},
-												  {name: 'Insert column before', type: 'unocommand', uno: '.uno:InsertColumnsBefore'},
-												  {name: 'Insert column after', type: 'unocommand', uno: '.uno:InsertColumnsAfter'},
-												  {type: 'separator'},
-												  {name: 'Delete row', type: 'unocommand', uno: '.uno:DeleteRows'},
-												  {name: 'Delete column', type: 'unocommand', uno: '.uno:DeleteColumns'},
-												  {name: 'Delete table', type: 'unocommand', uno: '.uno:DeleteTable'},
-												  {type: 'separator'},
+			{name: 'Tables', type: 'menu', menu: [{name: 'Insert', type: 'menu', menu: [{name: 'Rows Before', type: 'unocommand', uno: '.uno:InsertRowsBefore'},
+																						{name: 'Rows After', type: 'unocommand', uno: '.uno:InsertRowsAfter'},
+																						{type: 'separator'},
+																						{name: 'Columns Left', type: 'unocommand', uno: '.uno:InsertColumnsBefore'},
+																						{name: 'Columns Right', type: 'unocommand', uno: '.uno:InsertColumnsAfter'}]},
+												  {name: 'Delete', type: 'menu', menu: [{name: 'Rows', type: 'unocommand', uno: '.uno:DeleteRows'},
+																						{name: 'Columns', type: 'unocommand', uno: '.uno:DeleteColumns'},
+																						{name: 'Table', type: 'unocommand', uno: '.uno:DeleteTable'}]},
+												  {name: 'Select', type: 'menu', menu: [{name: 'Table', type: 'unocommand', uno: '.uno:SelectTable'},
+																						{name: 'Row', type: 'unocommand', uno: '.uno:EntireRow'},
+																						{name: 'Column', type: 'unocommand', uno: '.uno:EntireColumn'},
+																						{name: 'Cell', type: 'unocommand', uno: '.uno:EntireCell'}]},
 												  {name: 'Merge cells', type: 'unocommand', uno: '.uno:MergeCells'}]
 			}
 		],
@@ -70,16 +72,18 @@ L.Control.menubar = L.Control.extend({
 												{name: 'Zoom out', id: 'zoomout', type: 'action'},
 												{name: 'Zoom reset', id: 'zoomreset', type: 'action'}]
 			},
-			{name: 'Tables', type: 'menu', menu: [{name: 'Insert row before', type: 'unocommand', uno: '.uno:InsertRowsBefore'},
-												  {name: 'Insert row after', type: 'unocommand', uno: '.uno:InsertRowsAfter'},
-												  {type: 'separator'},
-												  {name: 'Insert column before', type: 'unocommand', uno: '.uno:InsertColumnsBefore'},
-												  {name: 'Insert column after', type: 'unocommand', uno: '.uno:InsertColumnsAfter'},
-												  {type: 'separator'},
-												  {name: 'Delete row', type: 'unocommand', uno: '.uno:DeleteRows'},
-												  {name: 'Delete column', type: 'unocommand', uno: '.uno:DeleteColumns'},
-												  {name: 'Delete table', type: 'unocommand', uno: '.uno:DeleteTable'},
-												  {type: 'separator'},
+			{name: 'Tables', type: 'menu', menu: [{name: 'Insert', type: 'menu', menu: [{name: 'Rows Before', type: 'unocommand', uno: '.uno:InsertRowsBefore'},
+																						{name: 'Rows After', type: 'unocommand', uno: '.uno:InsertRowsAfter'},
+																						{type: 'separator'},
+																						{name: 'Columns Left', type: 'unocommand', uno: '.uno:InsertColumnsBefore'},
+																						{name: 'Columns Right', type: 'unocommand', uno: '.uno:InsertColumnsAfter'}]},
+												  {name: 'Delete', type: 'menu', menu: [{name: 'Rows', type: 'unocommand', uno: '.uno:DeleteRows'},
+																						{name: 'Columns', type: 'unocommand', uno: '.uno:DeleteColumns'},
+																						{name: 'Table', type: 'unocommand', uno: '.uno:DeleteTable'}]},
+												  {name: 'Select', type: 'menu', menu: [{name: 'Table', type: 'unocommand', uno: '.uno:SelectTable'},
+																						{name: 'Row', type: 'unocommand', uno: '.uno:EntireRow'},
+																						{name: 'Column', type: 'unocommand', uno: '.uno:EntireColumn'},
+																						{name: 'Cell', type: 'unocommand', uno: '.uno:EntireCell'}]},
 												  {name: 'Merge cells', type: 'unocommand', uno: '.uno:MergeCells'}]
 			},
 			{name: 'Slide', type: 'menu', menu: [{name: 'New slide', id: 'insertpage', type: 'action'},
@@ -109,17 +113,20 @@ L.Control.menubar = L.Control.extend({
 			},
 			{name: 'Insert', type: 'menu', menu: [{name: 'Image', id: 'insertgraphic', type: 'action'},
 												  {type: 'separator'},
-												  {name: 'Row above', type: 'unocommand', uno: '.uno:InsertRows'},
-												  {name: 'Column before', type: 'unocommand', uno: '.uno:InsertColumns'},
-												  {type: 'separator'},
-												  {name: 'Delete row', type: 'unocommand', uno: '.uno:DeleteRows'},
-												  {name: 'Delete column', type: 'unocommand', uno: '.uno:DeleteColumns'}]
+												  {name: 'Row', type: 'unocommand', uno: '.uno:InsertRows'},
+												  {name: 'Column', type: 'unocommand', uno: '.uno:InsertColumns'}]
 			},
 			{name: 'View', type: 'menu', menu: [{name: 'Full Screen', id: 'fullscreen', type: 'action'},
 												{type: 'separator'},
 												{name: 'Zoom in', id: 'zoomin', type: 'action'},
 												{name: 'Zoom out', id: 'zoomout', type: 'action'},
 												{name: 'Zoom reset', id: 'zoomreset', type: 'action'}]
+			},
+			{name: 'Cells', type: 'menu', menu: [{name: 'Insert Row', type: 'unocommand', uno: '.uno:InsertRows'},
+												 {name: 'Insert Column', type: 'unocommand', uno: '.uno:InsertColumns'},
+												 {type: 'separator'},
+												 {name: 'Delete Row', type: 'unocommand', uno: '.uno:DeleteRows'},
+												 {name: 'Delete Column', type: 'unocommand', uno: '.uno:DeleteColumns'}]
 			}
 		],
 
commit 033ec745230445c7a776e15eb0d64f6f8518fe49
Author: Pranav Kant <pranavk at collabora.com>
Date:   Fri May 20 13:05:47 2016 +0530

    loleaflet: Disable menubar items according to context
    
    Change-Id: I9c2918827eebfa033a3745a57299ba556015a2bb

diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index de7737c..96f3d25 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -121,7 +121,9 @@ L.Control.menubar = L.Control.extend({
 												{name: 'Zoom out', id: 'zoomout', type: 'action'},
 												{name: 'Zoom reset', id: 'zoomreset', type: 'action'}]
 			}
-		]
+		],
+
+		commandStates: {}
 	},
 
 	onAdd: function (map) {
@@ -131,6 +133,15 @@ L.Control.menubar = L.Control.extend({
 		this._menubarCont.id = 'main-menu';
 
 		map.on('updatepermission', this._onUpdatePermission, this);
+		map.on('commandstatechanged', this._onCommandStateChanged, this);
+	},
+
+	_onCommandStateChanged: function(e) {
+		// Store information about enabled/disabled commands
+		// Used later just before showing menu to enable/disable menu items
+		if (e.state === 'enabled' || e.state === 'disabled') {
+			this.options.commandStates[e.commandName] = e.state;
+		}
 	},
 
 	_onUpdatePermission: function() {
@@ -160,6 +171,24 @@ L.Control.menubar = L.Control.extend({
 		this._initialized = true;
 
 		$('#main-menu').bind('select.smapi', {self: this}, this._onItemSelected);
+		$('#main-menu').bind('beforeshow.smapi', {self: this}, this._beforeFirstShow);
+	},
+
+	_beforeFirstShow: function(e, menu) {
+		var self = e.data.self;
+		var items = $(menu).children().children('a').not('.has-submenu');
+		$(items).each(function() {
+			var aItem = this;
+			var type = $(aItem).data('type');
+			if (type === 'unocommand') {
+				var unoCommand = $(aItem).data('uno');
+				if (self.options.commandStates[unoCommand] === 'disabled') {
+					$(aItem).addClass('disabled');
+				} else if (self.options.commandStates[unoCommand] === 'enabled') {
+					$(aItem).removeClass('disabled');
+				}
+			}
+		});
 	},
 
 	_executeAction: function(id) {
commit 17b3748a52b99112935e1099b89c70833cf51589
Author: Pranav Kant <pranavk at collabora.com>
Date:   Fri May 20 12:03:20 2016 +0530

    loleaflet: Dont change cursor on disabled items
    
    Change-Id: If709e58a426be3d0f0bdbf52ae81a04c87790518

diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index c7d0a58..2d3de53 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -125,6 +125,9 @@ collapsible to desktop (navbar + dropdowns)
     user-select: none;
     cursor: default;
 }
+.sm-simple a.disabled {
+    cursor: default;
+}
 .sm-simple > li > a.has-submenu {
     padding-left: 15px;
     padding-right: 15px;
commit 5b30e5f9d4be8f0eee23f12704ce905c5ed67f9b
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu May 19 16:21:58 2016 +0530

    Document 'statechanged' event
    
    Change-Id: Ibfad6ae98e525af69e855d588152a9a9eaf953fe

diff --git a/loolwsd/protocol.txt b/loolwsd/protocol.txt
index 25ea3f5..0751049 100644
--- a/loolwsd/protocol.txt
+++ b/loolwsd/protocol.txt
@@ -259,6 +259,11 @@ status: type=<typeName> parts=<numberOfParts> current=<currentPartNumber> width=
 
 styles: {"styleFamily": ["styles in family"], etc. }
 
+statechanged: <key>=<value>
+
+    Notifies client of state changed events of <key>.
+    Eg: 'statechanged: .uno:Undo=enabled'
+
 partpagerectangles: <payload>
 
     Payload format is the same as LOK_CALLBACK_TEXT_SELECTION.
commit 887f6314ab341ba73add9184bd9ff147c1cb9a5b
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu May 19 16:07:10 2016 +0530

    loleaflet: Prevent user from selecting menubar items
    
    ... and don't change the cursor while hovering over items
    
    Change-Id: I221048451fdda2ac66c1f2e500732836ed66fe03

diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index 2b44254..c7d0a58 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -117,6 +117,13 @@ collapsible to desktop (navbar + dropdowns)
 /* ...end */
 .sm-simple {
     background: #efefef;
+    -webkit-touch-callout: none; /* iOS Safari */
+    -webkit-user-select: none;   /* Chrome/Safari/Opera */
+    -khtml-user-select: none;    /* Konqueror */
+    -moz-user-select: none;      /* Firefox */
+    -ms-user-select: none;       /* Internet Explorer/Edge */
+    user-select: none;
+    cursor: default;
 }
 .sm-simple > li > a.has-submenu {
     padding-left: 15px;
commit 6b773910d3c56d155b668034d86c347974978790
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu May 19 16:02:45 2016 +0530

    loleaflet: Don't move text when highlighted
    
    Change-Id: I69602c4b1b4256733506983d53d289627771f291

diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index 6b8263f..2b44254 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -118,6 +118,14 @@ collapsible to desktop (navbar + dropdowns)
 .sm-simple {
     background: #efefef;
 }
+.sm-simple > li > a.has-submenu {
+    padding-left: 15px;
+    padding-right: 15px;
+    padding-top: 8px;
+    z-index: 500;
+    border-left: 1px solid #efefef;
+    border-right: 1px solid #efefef;
+}
 .sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted {
     padding: 5px 15px;
     color: #555;
@@ -127,8 +135,11 @@ collapsible to desktop (navbar + dropdowns)
 }
 .sm-simple > li > a:hover, .sm-simple > li > a:focus, .sm-simple > li > a:active, .sm-simple > li > a.highlighted {
     background: #fff;
-    border-left: 1px solid #bbbbbb;
-    border-right: 1px solid #bbbbbb;
+    border-color: #bbbbbb;
+    border-bottom: 1px solid #bbb;
+}
+.sm-simple > li > a.highlighted {
+    border-bottom-color: #fff;
 }
 .sm-simple a.current {
     background: #555555;
@@ -141,12 +152,7 @@ collapsible to desktop (navbar + dropdowns)
 .sm-simple a.has-submenu {
     padding-right: 32px;
 }
-.sm-simple > li > a.has-submenu {
-    padding-left: 15px;
-    padding-right: 15px;
-    padding-top: 8px;
-    z-index: 500;
-}
+
 .sm-simple > li > ul {
     margin-top: -1px !important;
     z-index: 400;
commit 93ef7aae3fc35f3fd429028a7f4de6fc0be8b8a9
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu May 19 15:19:25 2016 +0530

    loleaflet: Align toolbar to the left
    
    Change-Id: I07650734b3c4a771d8fc3b9f0d968dc5df700045

diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index 8bf2459..16618e4 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -14,7 +14,6 @@ $(function () {
 	$('#toolbar-up').w2toolbar({
 		name: 'toolbar-up',
 		items: [
-			{ type: 'html',  id: 'left' },
 			{ type: 'button',  id: 'save', img: 'save', hint: _("Save"), uno: 'Save' },
 			{ type: 'break' },
 			{ type: 'button',  id: 'undo',  img: 'undo', hint: _("Undo"), uno: 'Undo' },
commit a6627556589118e6b50936869bf532c0e9188a1e
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu May 19 15:00:08 2016 +0530

    loleaflet: More styling; merge white backgrounds
    
    Merge highlighted white background of top-level menuitems with
    white background of dropdown.
    
    Change-Id: Id6671a923420b5bc0be96597f7777872df6d8332

diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index 8cd918a..6b8263f 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -127,6 +127,8 @@ collapsible to desktop (navbar + dropdowns)
 }
 .sm-simple > li > a:hover, .sm-simple > li > a:focus, .sm-simple > li > a:active, .sm-simple > li > a.highlighted {
     background: #fff;
+    border-left: 1px solid #bbbbbb;
+    border-right: 1px solid #bbbbbb;
 }
 .sm-simple a.current {
     background: #555555;
@@ -143,6 +145,11 @@ collapsible to desktop (navbar + dropdowns)
     padding-left: 15px;
     padding-right: 15px;
     padding-top: 8px;
+    z-index: 500;
+}
+.sm-simple > li > ul {
+    margin-top: -1px !important;
+    z-index: 400;
 }
 .sm-simple a span.sub-arrow {
     top: 50%;
commit 7f8d7bf07e7b5d885b7f126c4158b66094e2e0f4
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu May 19 14:45:32 2016 +0530

    loleaflet: Style changes
    
    * Center the label on top-level menubar items
    * Remove padding off the top of menubar
    * Little more padding-top to menubar
    
    Change-Id: I70adc72bb93d7388f59f670ad76b1b4ac6741f68

diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index 07aefcd..8cd918a 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -102,10 +102,6 @@ collapsible to desktop (navbar + dropdowns)
     float: none;
 }
 
-.sm-simple > li {
-    padding-top: 5px;
-}
-
 .sm-simple a {
     white-space: nowrap;
 }
@@ -143,6 +139,11 @@ collapsible to desktop (navbar + dropdowns)
 .sm-simple a.has-submenu {
     padding-right: 32px;
 }
+.sm-simple > li > a.has-submenu {
+    padding-left: 15px;
+    padding-right: 15px;
+    padding-top: 8px;
+}
 .sm-simple a span.sub-arrow {
     top: 50%;
     margin-top: -8px;
commit 2c0a1cb53fdc97b461ae940f56a52d780d8d3216
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu May 19 14:43:02 2016 +0530

    loleaflet: remove single item menus from writer
    
    Change-Id: I477149793351fe225d94107bad7ce4c79678530e

diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 31b49b6..de7737c 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -31,8 +31,6 @@ L.Control.menubar = L.Control.extend({
 												{name: 'Zoom out', id: 'zoomout', type: 'action'},
 												{name: 'Zoom reset', id: 'zoomreset', type: 'action'}]
 			},
-			{name: 'Layout', type: 'menu', menu: [{name: 'Clear formatting', type: 'unocommand', uno: '.uno:ResetAttributes'}]
-			},
 			{name: 'Tables', type: 'menu', menu: [{name: 'Insert row before', type: 'unocommand', uno: '.uno:InsertRowsBefore'},
 												  {name: 'Insert row after', type: 'unocommand', uno: '.uno:InsertRowsAfter'},
 												  {type: 'separator'},
@@ -44,8 +42,6 @@ L.Control.menubar = L.Control.extend({
 												  {name: 'Delete table', type: 'unocommand', uno: '.uno:DeleteTable'},
 												  {type: 'separator'},
 												  {name: 'Merge cells', type: 'unocommand', uno: '.uno:MergeCells'}]
-			},
-			{name: 'Review', type: 'menu', menu: [{name: 'Add comment', type: 'unocommand', uno: '.uno:InsertAnnotation'}]
 			}
 		],
 
commit da69451afea09bf9f2567fb179854601ba9d0e56
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu May 19 12:09:22 2016 +0530

    loleaflet: Kill old filemenu as we have whole menubar now
    
    Change-Id: Idec0f41fa5ce94cf152535772d9c7ea822f1ac1e

diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index 8aa22a7..8bf2459 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -15,38 +15,6 @@ $(function () {
 		name: 'toolbar-up',
 		items: [
 			{ type: 'html',  id: 'left' },
-			// Unfortunately the toolbar does not provide access to menu items
-			// so we have to define different menu items if we want to have different
-			// entries for text / presentation / spreadsheet files
-			{ type: 'menu',   id: 'writer:menu:file', caption: _("File"), items: [
-				{ text: _("Download as PDF document (.pdf)"), id: 'downloadas-pdf' },
-				{ text: _("Download as ODF Text document (.odt)"), id: 'downloadas-odt' },
-				{ text: _("Download as Microsoft Word 2003 (.doc)"), id: 'downloadas-doc' },
-				{ text: _("Download as Microsoft Word (.docx)"), id: 'downloadas-docx' },
-				{ text: _("Print"), id: 'print' }
-			]},
-
-			{ type: 'menu', hidden: true, id: 'impress:menu:file', caption: _("File"), items: [
-				{ text: _("Download as PDF document (.pdf)"), id: 'downloadas-pdf' },
-				{ text: _("Download as ODF Presentation (.odp)"), id: 'downloadas-odp' },
-				{ text: _("Download as Microsoft Powerpoint 2003 (.ppt)"), id: 'downloadas-ppt' },
-				{ text: _("Download as Microsoft Powerpoint (.pptx)"), id: 'downloadas-pptx' },
-				{ text: _("Print"), id: 'print' }
-			]},
-
-			{ type: 'menu', hidden: true, id: 'calc:menu:file', caption: _("File"), items: [
-				{ text: _("Download as PDF document (.pdf)"), id: 'downloadas-pdf' },
-				{ text: _("Download as ODF Spreadsheet (.ods)"), id: 'downloadas-ods' },
-				{ text: _("Download as Microsoft Excel 2003 (.xls)"), id: 'downloadas-xls' },
-				{ text: _("Download as Microsoft Excel (.xlsx)"), id: 'downloadas-xlsx' },
-				{ text: _("Print"), id: 'print' }
-			]},
-
-			{ type: 'menu', hidden: true, id: 'other:menu:file', caption: _("File"), items: [
-				{ text: _("Download as PDF document (.pdf)"), id: 'downloadas-pdf' },
-				{ text: _("Print"), id: 'print' }
-			]},
-
 			{ type: 'button',  id: 'save', img: 'save', hint: _("Save"), uno: 'Save' },
 			{ type: 'break' },
 			{ type: 'button',  id: 'undo',  img: 'undo', hint: _("Undo"), uno: 'Undo' },
@@ -83,7 +51,7 @@ $(function () {
 			{ type: 'button',  id: 'help',  img: 'help', hint: _("Help") },
 			{ type: 'html', id: 'right' },
 			{ type: 'button',  id: 'more', img: 'more', hint: _("More") },
-			{ type: 'button',  id: 'close',  img: 'closedoc', hint: _("Close Document"), hidden: true },
+			{ type: 'button',  id: 'close',  img: 'closedoc', hint: _("Close Document"), hidden: true }
 		],
 		onClick: function (e) {
 			onClick(e.target);
@@ -224,20 +192,6 @@ function onClick(id) {
 		toolbar = w2ui['presentation-toolbar'];
 		item = toolbar.get(id);
 	}
-	else if (id.indexOf(':') >= 0) {
-		// we just handle a menu item click,
-		// like File->Download as
-		var index = id.indexOf(':');
-		var app = id.substring(0, index);
-		if (app === 'writer' ||
-			app === 'impress' ||
-			app === 'calc' ||
-			app === 'other') {
-			// remove the app from the id so that we have a single hander
-			id = id.substring(index + 1);
-		}
-		item = {};
-	}
 	else {
 		throw new Error('unknown id: ' + id);
 	}
@@ -304,11 +258,7 @@ function onClick(id) {
 		toolbar.disable('searchnext');
 		L.DomUtil.get('search-input').value = '';
 	}
-	else if (id === 'print' || id === 'menu:file:print') {
-		map.print();
-	}
-	else if ((id === 'menu:file:presentation' || id === 'presentation')
-			&& map.getDocType() === 'presentation') {
+	else if (id === 'presentation' && map.getDocType() === 'presentation') {
 		map.fire('fullscreen');
 	}
 	else if (id === 'insertpage') {
@@ -336,14 +286,6 @@ function onClick(id) {
 	else if (id === 'lastrecord') {
 		$('#spreadsheet-tab-scroll').scrollLeft($('#spreadsheet-tab-scroll').prop("scrollWidth"));
 	}
-	else if (id.startsWith('menu:file:downloadas-')) {
-		var format = id.substring('menu:file:downloadas-'.length);
-		// remove the extension if any
-		var fileName = title.substr(0, title.lastIndexOf('.')) || title;
-		// check if it is empty
-		fileName = fileName === '' ? 'document' : fileName;
-		map.downloadAs(fileName + '.' + format, format);
-	}
 	else if (id === 'insertgraphic') {
 		L.DomUtil.get('insertgraphic').click();
 	}
@@ -569,9 +511,7 @@ map.on('updatepermission', function (e) {
 	var toolbar = w2ui['toolbar-up'];
 	var docType = map.getDocType();
 	if (docType !== 'text') {
-		toolbar.hide('writer:menu:file');
 		if (docType === 'presentation') {
-			toolbar.show('impress:menu:file');
 			toolbar.hide('annotation');
 
 			toolbar = w2ui['presentation-toolbar'];
@@ -582,14 +522,9 @@ map.on('updatepermission', function (e) {
 			toolbar.show('deletepage');
 		}
 		else if (docType === 'drawing') {
-			toolbar.show('impress:menu:file');
 			toolbar.hide('annotation');
 		}
-		else if (docType === 'spreadsheet') {
-			toolbar.show('calc:menu:file');
-		}
-		else {
-			toolbar.show('other:menu:file');
+		else if (docType !== 'spreadsheet') {
 			toolbar.hide('annotation');
 		}
 	}
commit 7f453bc90a9a2e4908676b91ecd77c318addcb46
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu May 19 11:50:08 2016 +0530

    loleaflet: Functionality in menubar for presentation and spreadsheets
    
    Change-Id: I5c235922dccdf2b6f28574a4791a6c93845f7fe7

diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 0bf5b0f..31b49b6 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -2,7 +2,7 @@
 * Control.Menubar
 */
 
-/* global $ */
+/* global $ _ map */
 L.Control.menubar = L.Control.extend({
 	options: {
 		text:  [
@@ -26,6 +26,7 @@ L.Control.menubar = L.Control.extend({
 												  {name: 'Comment', type: 'unocommand', uno: '.uno:InsertAnnotation'}]
 			},
 			{name: 'View', type: 'menu', menu: [{name: 'Full screen', id: 'fullscreen', type: 'action'},
+												{type: 'separator'},
 												{name: 'Zoom in', id: 'zoomin', type: 'action'},
 												{name: 'Zoom out', id: 'zoomout', type: 'action'},
 												{name: 'Zoom reset', id: 'zoomreset', type: 'action'}]
@@ -65,23 +66,31 @@ L.Control.menubar = L.Control.extend({
 												{type: 'separator'},
 												{name: 'Select All', type: 'unocommand', uno: '.uno:SelectAll'}]
 			},
-			{name: 'Insert', type: 'menu', menu: [{name: 'Image', type: 'command'},
-												  {name: 'Shape', type: 'command'},
-												  {name: 'Line', type: 'command'},
-												  {name: 'Table', type: 'command'},
-												  {name: 'Video', type: 'command'},
-												  {name: 'Slide', type: 'command'},
-												  {name: 'Slide numbering', type: 'command'},
-												  {name: 'Text space', type: 'command'},
-												  {name: 'Chart', type: 'command'},
-												  {name: 'Symbol', type: 'command'},
-												  {name: 'Remark', type: 'command'}]
+			{name: 'Insert', type: 'menu', menu: [{name: 'Image', id: 'insertgraphic', type: 'action'}]
+			},
+			{name: 'View', type: 'menu', menu: [{name: 'Full Screen', id: 'fullscreen', type: 'action'},
+												{type: 'separator'},
+												{name: 'Zoom in', id: 'zoomin', type: 'action'},
+												{name: 'Zoom out', id: 'zoomout', type: 'action'},
+												{name: 'Zoom reset', id: 'zoomreset', type: 'action'}]
 			},
-			{name: 'View', type: 'menu', menu: [{name: 'Full Screen', type: 'command'},
-												{name: 'Presentation views', type: 'command'},
-												{name: 'Master views', type: 'command'},
-												{name: 'Zoom', type: 'command'},
-												{name: 'Show rulers', type: 'command'}]
+			{name: 'Tables', type: 'menu', menu: [{name: 'Insert row before', type: 'unocommand', uno: '.uno:InsertRowsBefore'},
+												  {name: 'Insert row after', type: 'unocommand', uno: '.uno:InsertRowsAfter'},
+												  {type: 'separator'},
+												  {name: 'Insert column before', type: 'unocommand', uno: '.uno:InsertColumnsBefore'},
+												  {name: 'Insert column after', type: 'unocommand', uno: '.uno:InsertColumnsAfter'},
+												  {type: 'separator'},
+												  {name: 'Delete row', type: 'unocommand', uno: '.uno:DeleteRows'},
+												  {name: 'Delete column', type: 'unocommand', uno: '.uno:DeleteColumns'},
+												  {name: 'Delete table', type: 'unocommand', uno: '.uno:DeleteTable'},
+												  {type: 'separator'},
+												  {name: 'Merge cells', type: 'unocommand', uno: '.uno:MergeCells'}]
+			},
+			{name: 'Slide', type: 'menu', menu: [{name: 'New slide', id: 'insertpage', type: 'action'},
+												 {name: 'Duplicate slide', id: 'duplicatepage', type: 'action'},
+												 {name: 'Delete slide', id: 'deletepage', type: 'action'},
+												 {type: 'separator'},
+												 {name: 'Fullscreen Presentation', id: 'fullscreen-presentation', type: 'action'}]
 			}
 		],
 
@@ -102,15 +111,19 @@ L.Control.menubar = L.Control.extend({
 												{type: 'separator'},
 												{name: 'Select All', type: 'unocommand', uno: '.uno:SelectAll'}]
 			},
-			{name: 'Insert', type: 'menu', menu: [{name: 'Row', type: 'command'},
-												  {name: 'Column', type: 'command'},
-												  {name: 'Function', type: 'command'},
-												  {name: 'Page', type: 'command'}]
+			{name: 'Insert', type: 'menu', menu: [{name: 'Image', id: 'insertgraphic', type: 'action'},
+												  {type: 'separator'},
+												  {name: 'Row above', type: 'unocommand', uno: '.uno:InsertRows'},
+												  {name: 'Column before', type: 'unocommand', uno: '.uno:InsertColumns'},
+												  {type: 'separator'},
+												  {name: 'Delete row', type: 'unocommand', uno: '.uno:DeleteRows'},
+												  {name: 'Delete column', type: 'unocommand', uno: '.uno:DeleteColumns'}]
 			},
-			{name: 'View', type: 'menu', menu: [{name: 'Full screen', type: 'command'},
-												{name: 'Formula bar', type: 'command'},
-												{name: 'Zoom', type: 'command'},
-												{name: 'Headings', type: 'command'}]
+			{name: 'View', type: 'menu', menu: [{name: 'Full Screen', id: 'fullscreen', type: 'action'},
+												{type: 'separator'},
+												{name: 'Zoom in', id: 'zoomin', type: 'action'},
+												{name: 'Zoom out', id: 'zoomout', type: 'action'},
+												{name: 'Zoom reset', id: 'zoomreset', type: 'action'}]
 			}
 		]
 	},
@@ -196,6 +209,23 @@ L.Control.menubar = L.Control.extend({
 					document.webkitExitFullscreen();
 				}
 			}
+		} else if (id === 'fullscreen-presentation' && map.getDocType() === 'presentation') {
+			map.fire('fullscreen');
+		} else if (id === 'insertpage') {
+			map.insertPage();
+		} else if (id === 'duplicatepage') {
+			map.duplicatePage();
+		} else if (id === 'deletepage') {
+			vex.dialog.confirm({
+				message: _("Are you sure you want to delete this slide?"),
+				callback: this._onDeleteSlide
+			}, this);
+		}
+	},
+
+	_onDeleteSlide: function(e) {
+		if (e) {
+			map.deletePage();
 		}
 	},
 
commit 71510a75f5ae42117c2eaacdaf8a6b440b5d7fd0
Author: Pranav Kant <pranavk at collabora.com>
Date:   Thu May 19 11:07:43 2016 +0530

    Kill common menu category
    
    Change-Id: I17d6a704912fbdeb6238b838a250d4155a6ff40f

diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 09980bf..0bf5b0f 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -5,7 +5,7 @@
 /* global $ */
 L.Control.menubar = L.Control.extend({
 	options: {
-		common: [
+		text:  [
 			{name: 'File', type: 'menu', menu: [{name: 'Save', type: 'unocommand', uno: '.uno:Save'},
 												{name: 'Print', id: 'print', type: 'action'},
 												{name: 'Download as', type: 'menu', menu: [{name: 'PDF Document (.pdf)', id: 'downloadas-pdf', type: 'action'},
@@ -21,10 +21,7 @@ L.Control.menubar = L.Control.extend({
 												{name: 'Paste', type: 'unocommand', uno: '.uno:Paste'},
 												{type: 'separator'},
 												{name: 'Select All', type: 'unocommand', uno: '.uno:SelectAll'}]
-			}
-		],
-
-		text:  [
+			},
 			{name: 'Insert', type: 'menu', menu: [{name: 'Image', id: 'insertgraphic', type: 'action'},
 												  {name: 'Comment', type: 'unocommand', uno: '.uno:InsertAnnotation'}]
 			},
@@ -52,6 +49,22 @@ L.Control.menubar = L.Control.extend({
 		],
 
 		presentation: [
+			{name: 'File', type: 'menu', menu: [{name: 'Save', type: 'unocommand', uno: '.uno:Save'},
+												{name: 'Print', id: 'print', type: 'action'},
+												{name: 'Download as', type: 'menu', menu:  [{name: 'PDF Document (.pdf)', id: 'downloadas-pdf', type: 'action'},
+																							{name: 'ODF presentation (.odp)', id: 'downloadas-odp', type: 'action'},
+																							{name: 'Microsoft Powerpoint 2003 (.ppt)', id: 'downloadas-ppt', type: 'action'},
+																							{name: 'Microsoft Powerpoint (.pptx)', id: 'downloadas-pptx', type: 'action'}]}]
+			},
+			{name: 'Edit', type: 'menu', menu: [{name: 'Undo', type: 'unocommand', uno: '.uno:Undo'},
+												{name: 'Redo', type: 'unocommand', uno: '.uno:Redo'},
+												{type: 'separator'},
+												{name: 'Cut', type: 'unocommand', uno: '.uno:Cut'},
+												{name: 'Copy', type: 'unocommand', uno: '.uno:Copy'},
+												{name: 'Paste', type: 'unocommand', uno: '.uno:Paste'},
+												{type: 'separator'},
+												{name: 'Select All', type: 'unocommand', uno: '.uno:SelectAll'}]
+			},
 			{name: 'Insert', type: 'menu', menu: [{name: 'Image', type: 'command'},
 												  {name: 'Shape', type: 'command'},
 												  {name: 'Line', type: 'command'},
@@ -73,6 +86,22 @@ L.Control.menubar = L.Control.extend({
 		],
 
 		spreadsheet: [
+			{name: 'File', type: 'menu', menu: [{name: 'Save', type: 'unocommand', uno: '.uno:Save'},
+												{name: 'Print', id: 'print', type: 'action'},
+												{name: 'Download as', type: 'menu', menu: [{name: 'PDF Document (.pdf)', id: 'downloadas-pdf', type: 'action'},
+																						   {name: 'ODF spreadsheet (.ods)', id: 'downloadas-ods', type: 'action'},
+																						   {name: 'Microsoft Excel 2003 (.xls)', id: 'downloadas-xls', type: 'action'},
+																						   {name: 'Microsoft Excel (.xlsx)', id: 'downloadas-xlsx', type: 'action'}]}]
+			},
+			{name: 'Edit', type: 'menu', menu: [{name: 'Undo', type: 'unocommand', uno: '.uno:Undo'},
+												{name: 'Redo', type: 'unocommand', uno: '.uno:Redo'},
+												{type: 'separator'},
+												{name: 'Cut', type: 'unocommand', uno: '.uno:Cut'},
+												{name: 'Copy', type: 'unocommand', uno: '.uno:Copy'},
+												{name: 'Paste', type: 'unocommand', uno: '.uno:Paste'},
+												{type: 'separator'},
+												{name: 'Select All', type: 'unocommand', uno: '.uno:SelectAll'}]
+			},
 			{name: 'Insert', type: 'menu', menu: [{name: 'Row', type: 'command'},
 												  {name: 'Column', type: 'command'},
 												  {name: 'Function', type: 'command'},
@@ -99,9 +128,6 @@ L.Control.menubar = L.Control.extend({
 		if (this._initialized || !this._menubarCont)
 			return;
 
-		// Intialize menu that is common to all documents
-		this._initializeMenu(this.options.common);
-
 		// Add dcoument specific menu
 		var docType = this._map.getDocType();
 		if (docType === 'text') {
@@ -114,6 +140,7 @@ L.Control.menubar = L.Control.extend({
 
 		// initialize menubar plugin
 		$('#main-menu').smartmenus({
+			hideOnClick: true,
 			showOnClick: true,
 			hideTimeout: 0,
 			hideDuration: 0,
commit cc7b2b00cfb584470898a3642f349b39a814720d
Author: Pranav Kant <pranavk at collabora.com>
Date:   Wed May 18 20:09:54 2016 +0530

    loleaflet: menubar: Make menuitems in writer functional
    
    1. Prune out all other items that are not possible now.
    2. Add a seperator CSS class and use it between menuitems.
    
    ... and other minor functional/UI changes.
    
    Change-Id: I037e2b6f751824c973072c52905d46b0fd4be38b

diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index a2df64d..07aefcd 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -155,9 +155,6 @@ collapsible to desktop (navbar + dropdowns)
 .sm-simple > li > a span.sub-arrow {
     display: none;
 }
-.sm-simple > li:first-child a span.sub-arrow {
-    display: none;
-}
 .sm-simple a.highlighted span.sub-arrow:before {
     display: none;
 }
@@ -188,6 +185,14 @@ collapsible to desktop (navbar + dropdowns)
 .sm-simple ul > li:first-child {
     border-top: 0;
 }
+.sm-simple a.separator {
+    height: 1px;
+    margin: 9px 0;
+    overflow: hidden;
+    padding-top: 0;
+    padding-bottom: 0;
+    background-color: #efefef;
+}
 .sm-simple span.scroll-up,
 .sm-simple span.scroll-down {
     position: absolute;
diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 8e07a11..09980bf 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -6,53 +6,48 @@
 L.Control.menubar = L.Control.extend({
 	options: {
 		common: [
-			{name: 'File', type: 'menu', menu: [{name: 'New', type: 'command'},
-												{name: 'Open', type: 'command'},
-												{name: 'Save', type: 'command'},
-												{name: 'Print', type: 'command'}]
+			{name: 'File', type: 'menu', menu: [{name: 'Save', type: 'unocommand', uno: '.uno:Save'},
+												{name: 'Print', id: 'print', type: 'action'},
+												{name: 'Download as', type: 'menu', menu: [{name: 'PDF Document (.pdf)', id: 'downloadas-pdf', type: 'action'},
+																						   {name: 'ODF text document (.odt)', id: 'downloadas-odt', type: 'action'},
+																						   {name: 'Microsoft Word 2003 (.doc)', id: 'downloadas-doc', type: 'action'},
+																						   {name: 'Microsoft Word (.docx)', id: 'downloadas-docx', type: 'action'}]}]
 			},
-			{name: 'Edit', type: 'menu', menu: [{name: 'Undo', type: 'command'},
-												{name: 'Redo', type: 'command'},
-												{name: 'Cut', type: 'command'},
-												{name: 'Copy', type: 'command'},
-												{name: 'Paste', type: 'command'},
-												{name: 'Select All', type: 'command'}]
+			{name: 'Edit', type: 'menu', menu: [{name: 'Undo', type: 'unocommand', uno: '.uno:Undo'},
+												{name: 'Redo', type: 'unocommand', uno: '.uno:Redo'},
+												{type: 'separator'},
+												{name: 'Cut', type: 'unocommand', uno: '.uno:Cut'},
+												{name: 'Copy', type: 'unocommand', uno: '.uno:Copy'},
+												{name: 'Paste', type: 'unocommand', uno: '.uno:Paste'},
+												{type: 'separator'},
+												{name: 'Select All', type: 'unocommand', uno: '.uno:SelectAll'}]
 			}
 		],
 
 		text:  [
-			{name: 'Insert', type: 'menu', menu: [{name: 'Image', type: 'command'},
-												  {name: 'Link', type: 'command'},
-												  {name: 'Table', type: 'command'},
-												  {name: 'Footer', type: 'command'},
-												  {name: 'Page number', type: 'command'},
-												  {name: 'Index', type: 'command'},
-												  {name: 'Horizontal Line', type: 'command'},
-												  {name: 'Chart', type: 'command'},
-												  {name: 'Symbol', type: 'command'},
-												  {name: 'Remark', type: 'command'}]
+			{name: 'Insert', type: 'menu', menu: [{name: 'Image', id: 'insertgraphic', type: 'action'},
+												  {name: 'Comment', type: 'unocommand', uno: '.uno:InsertAnnotation'}]
 			},
-			{name: 'View', type: 'menu', menu: [{name: 'Full screen', type: 'command'},
-												{name: 'Rulers', type: 'command'},
-												{name: 'Zoom', type: 'command'},
-												{name: 'Web Layout', type: 'command'}]
+			{name: 'View', type: 'menu', menu: [{name: 'Full screen', id: 'fullscreen', type: 'action'},
+												{name: 'Zoom in', id: 'zoomin', type: 'action'},
+												{name: 'Zoom out', id: 'zoomout', type: 'action'},
+												{name: 'Zoom reset', id: 'zoomreset', type: 'action'}]
 			},
-			{name: 'Layout', type: 'menu', menu: [{name: 'Text editor', type: 'command'},
-												  {name: 'Columns', type: 'command'},
-												  {name: 'Image crop', type: 'command'},
-												  {name: 'Page layout', type: 'command'},
-												  {name: 'Clear styling', type: 'command'}]
+			{name: 'Layout', type: 'menu', menu: [{name: 'Clear formatting', type: 'unocommand', uno: '.uno:ResetAttributes'}]
 			},
-			{name: 'Tables', type: 'menu', menu: [{name: 'Insert Table', type: 'command'},
-												  {name: 'Insert row', type: 'command'},
-												  {name: 'Insert column', type: 'command'},
-												  {name: 'Submenus', type: 'menu', menu: [{name: 'Item1', type: 'command'},
-																						  {name: 'Item2', type: 'command'},
-																						  {name: 'Item3', type: 'command'}]},
-												  {name: 'Remove row', type: 'command'},
-												  {name: 'Remove column', type: 'command'},
-												  {name: 'Split cells', type: 'command'},
-												  {name: 'Merge cells', type: 'command'}]
+			{name: 'Tables', type: 'menu', menu: [{name: 'Insert row before', type: 'unocommand', uno: '.uno:InsertRowsBefore'},
+												  {name: 'Insert row after', type: 'unocommand', uno: '.uno:InsertRowsAfter'},
+												  {type: 'separator'},
+												  {name: 'Insert column before', type: 'unocommand', uno: '.uno:InsertColumnsBefore'},
+												  {name: 'Insert column after', type: 'unocommand', uno: '.uno:InsertColumnsAfter'},
+												  {type: 'separator'},
+												  {name: 'Delete row', type: 'unocommand', uno: '.uno:DeleteRows'},
+												  {name: 'Delete column', type: 'unocommand', uno: '.uno:DeleteColumns'},
+												  {name: 'Delete table', type: 'unocommand', uno: '.uno:DeleteTable'},
+												  {type: 'separator'},
+												  {name: 'Merge cells', type: 'unocommand', uno: '.uno:MergeCells'}]
+			},
+			{name: 'Review', type: 'menu', menu: [{name: 'Add comment', type: 'unocommand', uno: '.uno:InsertAnnotation'}]
 			}
 		],
 
@@ -127,6 +122,66 @@ L.Control.menubar = L.Control.extend({
 			subIndicatorsText: '›'
 		});
 		this._initialized = true;
+
+		$('#main-menu').bind('select.smapi', {self: this}, this._onItemSelected);
+	},
+
+	_executeAction: function(id) {
+		if (id === 'print') {
+			map.print();
+		} else if (id.startsWith('downloadas-')) {
+			var format = id.substring('downloadas-'.length);
+			// remove the extension if any
+			var fileName = title.substr(0, title.lastIndexOf('.')) || title;
+			// check if it is empty
+			fileName = fileName === '' ? 'document' : fileName;
+			map.downloadAs(fileName + '.' + format, format);
+		} else if (id === 'insertgraphic') {
+			L.DomUtil.get('insertgraphic').click();
+		} else if (id === 'zoomin' && map.getZoom() < map.getMaxZoom()) {
+			map.zoomIn(1);
+		} else if (id === 'zoomout' && map.getZoom() > map.getMinZoom()) {
+			map.zoomOut(1);
+		} else if (id === 'zoomreset') {
+			map.setZoom(map.options.zoom);
+		} else if (id === 'fullscreen') {
+			if (!document.fullscreenElement &&
+				!document.mozFullscreenElement &&
+				!document.msFullscreenElement &&
+				!document.webkitFullscreenElement) {
+				if (document.documentElement.requestFullscreen) {
+					document.documentElement.requestFullscreen();
+				} else if (document.documentElement.msRequestFullscreen) {
+					document.documentElement.msRequestFullscreen();
+				} else if (document.documentElement.mozRequestFullScreen) {
+					document.documentElement.mozRequestFullScreen();
+				} else if (document.documentElement.webkitRequestFullscreen) {
+					document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+				}
+			} else {
+				if (document.exitFullscreen) {
+					document.exitFullscreen();
+				} else if (document.msExitFullscreen) {
+					document.msExitFullscreen();
+				} else if (document.mozCancelFullScreen) {
+					document.mozCancelFullScreen();
+				} else if (document.webkitExitFullscreen) {
+					document.webkitExitFullscreen();
+				}
+			}
+		}
+	},
+
+	_onItemSelected: function(e, item) {
+		var self = e.data.self;
+		var type = $(item).data('type');
+		if (type === 'unocommand') {
+			var unoCommand = $(item).data('uno');
+			map.sendUnoCommand(unoCommand);
+		} else if (type === 'action') {
+			var id = $(item).data('id');
+			self._executeAction(id);
+		}
 	},
 
 	_createMenu: function(menu) {
@@ -142,6 +197,14 @@ L.Control.menubar = L.Control.extend({
 				for (var j in subitemList) {
 					ulItem.appendChild(subitemList[j]);
 				}
+			} else if (menu[i]['type'] === 'unocommand') {
+				$(aItem).data('type', 'unocommand');
+				$(aItem).data('uno', menu[i]['uno']);
+			} else if (menu[i]['type'] === 'separator') {
+				$(aItem).addClass('separator');
+			} else if (menu[i]['type'] === 'action') {
+				$(aItem).data('type', 'action');
+				$(aItem).data('id', menu[i]['id']);
 			}
 
 			itemList.push(liItem);
commit 2d18ec899dd621eacf27881812c98fa4a19c6eb4
Author: Pranav Kant <pranavk at collabora.com>
Date:   Wed May 18 13:21:44 2016 +0530

    loleaflet: We do not want to switch to mobile mode anyhow
    
    If we do, uncommenting the appropriate code pieces would make it
    work again.
    
    Change-Id: Ib4729033b2cf6c3bcafc6ac59f09f42bf02e34ca

diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index 5ce22a0..a2df64d 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -74,179 +74,183 @@
     border-left: 40px solid transparent;
 }
 
- at media (min-width: 768px) {
-    /* Switch to desktop layout
-  -----------------------------------------------
-     These transform the menu tree from
-     collapsible to desktop (navbar + dropdowns)
-  -----------------------------------------------*/
-    /* start... (it's not recommended editing these rules) */
-    .sm-simple ul {
-	position: absolute;
-	width: 12em;
-    }
+/* By default smartmenus is mobile first. But we don't need that for now, so
+   just tranform the menu to desktop style (navbar + dropdowns).
+   Uncomment below to enable mobile mode beyond min-width
+*/
+/* @media (min-width: 240px) {
+Switch to desktop layout
+-----------------------------------------------
+These transform the menu tree from
+collapsible to desktop (navbar + dropdowns)
+-----------------------------------------------*/
+/* start... (it's not recommended editing these rules) */
+.sm-simple ul {
+    position: absolute;
+    width: 12em;
+}
 
-    .sm-simple li {
-	float: left;
-    }
+.sm-simple li {
+    float: left;
+}
 
-    .sm-simple.sm-rtl li {
-	float: right;
-    }
+.sm-simple.sm-rtl li {
+    float: right;
+}
 
-    .sm-simple ul li {
-	float: none;
-    }
+.sm-simple ul li {
+    float: none;
+}
 
-    .sm-simple > li {
-	padding-top: 5px;
-    }
+.sm-simple > li {
+    padding-top: 5px;
+}
 
-    .sm-simple a {
-	white-space: nowrap;
-    }
+.sm-simple a {
+    white-space: nowrap;
+}
 
-    .sm-simple ul a, .sm-simple.sm-vertical a {
-	white-space: normal;
-    }
+.sm-simple ul a, .sm-simple.sm-vertical a {
+    white-space: normal;
+}
 
-    .sm-simple .sm-nowrap > li > a, .sm-simple .sm-nowrap > li > :not(ul) a {
-	white-space: nowrap;
-    }
+.sm-simple .sm-nowrap > li > a, .sm-simple .sm-nowrap > li > :not(ul) a {
+    white-space: nowrap;
+}
 
-    /* ...end */
-    .sm-simple {
-	background: #efefef;
-    }
-    .sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted {
-	padding: 5px 15px;
-	color: #555;
-    }
-    .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted {
-	background: #eee;
-    }
-    .sm-simple > li > a:hover, .sm-simple > li > a:focus, .sm-simple > li > a:active, .sm-simple > li > a.highlighted {
-	background: #fff;
-    }
-    .sm-simple a.current {
-	background: #555555;
-	color: white;
-    }
-    .sm-simple a.disabled {
-	background: white;
-	color: #cccccc;
-    }
-    .sm-simple a.has-submenu {
-	padding-right: 32px;
-    }
-    .sm-simple a span.sub-arrow {
-	top: 50%;
-	margin-top: -8px;
-	right: 20px;
-	width: 8px;
-	height: 16px;
-	font: 14px/16px monospace !important;
-	background: transparent;
-    }
-    .sm-simple > li > a span.sub-arrow {
-	display: none;
-    }
-    .sm-simple > li:first-child a span.sub-arrow {
-	display: none;
-    }
-    .sm-simple a.highlighted span.sub-arrow:before {
-	display: none;
-    }
-    .sm-simple > li {
-	border-top: 0;
-	border-left: 1px solid #eeeeee;
-    }
-    .sm-simple > li:first-child {
-	border-left: 0;
-    }
-    .sm-simple ul {
-	border: 1px solid #bbbbbb;
-	background: white;
-    }
-    .sm-simple ul a {
-	border: 0 !important;
-    }
-    .sm-simple ul a.has-submenu {
-	padding-right: 20px;
-    }
-    .sm-simple ul a span.sub-arrow {
-	right: 0;
-	margin-right: 5px;
-    }
-    .sm-simple ul > li {
-	border-left: 0;
-    }
-    .sm-simple ul > li:first-child {
-	border-top: 0;
-    }
-    .sm-simple span.scroll-up,
-    .sm-simple span.scroll-down {
-	position: absolute;
-	display: none;
-	visibility: hidden;
-	overflow: hidden;
-	background: white;
-	height: 20px;
-    }
-    .sm-simple span.scroll-up-arrow, .sm-simple span.scroll-down-arrow {
-	position: absolute;
-	top: -2px;
-	left: 50%;
-	margin-left: -8px;
-	width: 0;
-	height: 0;
-	overflow: hidden;
-	border-width: 8px;
-	border-style: dashed dashed solid dashed;
-	border-color: transparent transparent #555555 transparent;
-    }
-    .sm-simple span.scroll-down-arrow {
-	top: 6px;
-	border-style: solid dashed dashed dashed;
-	border-color: #555555 transparent transparent transparent;
-    }
-    .sm-simple.sm-rtl a.has-submenu {
-	padding-right: 20px;
-	padding-left: 32px;
-    }
-    .sm-simple.sm-rtl a span.sub-arrow {
-	right: auto;
-	left: 20px;
-    }
-    .sm-simple.sm-rtl.sm-vertical a.has-submenu {
-	padding: 11px 20px;
-    }
-    .sm-simple.sm-rtl.sm-vertical a span.sub-arrow {
-	right: 20px;
-	margin-right: -12px;
-    }
-    .sm-simple.sm-rtl > li:first-child {
-	border-left: 1px solid #eeeeee;
-    }
-    .sm-simple.sm-rtl > li:last-child {
-	border-left: 0;
-    }
-    .sm-simple.sm-rtl ul a.has-submenu {
-	padding: 11px 20px;
-    }
-    .sm-simple.sm-rtl ul a span.sub-arrow {
-	right: 20px;
-	margin-right: -12px;
-    }
-    .sm-simple.sm-vertical a span.sub-arrow {
-	right: auto;
-	margin-left: -12px;
-    }
-    .sm-simple.sm-vertical li {
-	border-left: 0;
-	border-top: 1px solid #eeeeee;
-    }
-    .sm-simple.sm-vertical > li:first-child {
-	border-top: 0;
-    }
-}
\ No newline at end of file
+/* ...end */
+.sm-simple {
+    background: #efefef;
+}
+.sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted {
+    padding: 5px 15px;
+    color: #555;
+}
+.sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted {
+    background: #eee;
+}
+.sm-simple > li > a:hover, .sm-simple > li > a:focus, .sm-simple > li > a:active, .sm-simple > li > a.highlighted {
+    background: #fff;
+}
+.sm-simple a.current {
+    background: #555555;
+    color: white;
+}
+.sm-simple a.disabled {
+    background: white;
+    color: #cccccc;
+}
+.sm-simple a.has-submenu {
+    padding-right: 32px;
+}
+.sm-simple a span.sub-arrow {
+    top: 50%;
+    margin-top: -8px;
+    right: 20px;
+    width: 8px;
+    height: 16px;
+    font: 14px/16px monospace !important;
+    background: transparent;
+}
+.sm-simple > li > a span.sub-arrow {
+    display: none;
+}
+.sm-simple > li:first-child a span.sub-arrow {
+    display: none;
+}
+.sm-simple a.highlighted span.sub-arrow:before {
+    display: none;
+}
+.sm-simple > li {
+    border-top: 0;
+    border-left: 1px solid #eeeeee;
+}
+.sm-simple > li:first-child {
+    border-left: 0;
+}
+.sm-simple ul {
+    border: 1px solid #bbbbbb;
+    background: white;
+}
+.sm-simple ul a {
+    border: 0 !important;
+}
+.sm-simple ul a.has-submenu {
+    padding-right: 20px;
+}
+.sm-simple ul a span.sub-arrow {
+    right: 0;
+    margin-right: 5px;
+}
+.sm-simple ul > li {
+    border-left: 0;
+}
+.sm-simple ul > li:first-child {
+    border-top: 0;
+}
+.sm-simple span.scroll-up,
+.sm-simple span.scroll-down {
+    position: absolute;
+    display: none;
+    visibility: hidden;
+    overflow: hidden;
+    background: white;
+    height: 20px;
+}
+.sm-simple span.scroll-up-arrow, .sm-simple span.scroll-down-arrow {
+    position: absolute;
+    top: -2px;
+    left: 50%;
+    margin-left: -8px;
+    width: 0;
+    height: 0;
+    overflow: hidden;
+    border-width: 8px;
+    border-style: dashed dashed solid dashed;
+    border-color: transparent transparent #555555 transparent;
+}
+.sm-simple span.scroll-down-arrow {
+    top: 6px;
+    border-style: solid dashed dashed dashed;
+    border-color: #555555 transparent transparent transparent;
+}
+.sm-simple.sm-rtl a.has-submenu {
+    padding-right: 20px;
+    padding-left: 32px;
+}
+.sm-simple.sm-rtl a span.sub-arrow {
+    right: auto;
+    left: 20px;
+}
+.sm-simple.sm-rtl.sm-vertical a.has-submenu {
+    padding: 11px 20px;
+}
+.sm-simple.sm-rtl.sm-vertical a span.sub-arrow {
+    right: 20px;
+    margin-right: -12px;
+}
+.sm-simple.sm-rtl > li:first-child {
+    border-left: 1px solid #eeeeee;
+}
+.sm-simple.sm-rtl > li:last-child {
+    border-left: 0;
+}
+.sm-simple.sm-rtl ul a.has-submenu {
+    padding: 11px 20px;
+}
+.sm-simple.sm-rtl ul a span.sub-arrow {
+    right: 20px;
+    margin-right: -12px;
+}
+.sm-simple.sm-vertical a span.sub-arrow {
+    right: auto;
+    margin-left: -12px;
+}
+.sm-simple.sm-vertical li {
+    border-left: 0;
+    border-top: 1px solid #eeeeee;
+}
+.sm-simple.sm-vertical > li:first-child {
+    border-top: 0;
+}
+/*}*/
commit 9c1a2a9dd345d78271124b92c499d2cb5e84e2fe
Author: Pranav Kant <pranavk at collabora.com>
Date:   Wed May 18 16:39:35 2016 +0530

    loleaflet: And we have a menubar now
    
    ... with some CSS tweaks in sm-simple.css to make it look more
    like LO menubar in desktop application.
    
    Change-Id: I62c88d5876da752fb487e89a3613698c463d9f32

diff --git a/loleaflet/dist/smartmenus/sm-simple.css b/loleaflet/dist/smartmenus/sm-simple.css
index d7a4835..5ce22a0 100644
--- a/loleaflet/dist/smartmenus/sm-simple.css
+++ b/loleaflet/dist/smartmenus/sm-simple.css
@@ -1,9 +1,5 @@
 .sm-simple {
-    border: 1px solid #bbbbbb;
     background: white;
-    -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-    -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
 }
 .sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active {
     padding: 13px 20px;
@@ -11,9 +7,9 @@
     padding-right: 58px;
     color: #555555;
     font-family: "Lucida Sans Unicode", "Lucida Sans", "Lucida Grande", Arial, sans-serif;
-    font-size: 16px;
+    font-size: 12px;
     font-weight: normal;
-    line-height: 17px;
+    line-height: 15px;
     text-decoration: none;
 }
 .sm-simple a.current {
@@ -42,17 +38,16 @@
     content: '-';
 }
 .sm-simple li {
-    border-top: 1px solid rgba(0, 0, 0, 0.05);
 }
 .sm-simple > li:first-child {
     border-top: 0;
 }
 .sm-simple ul {
-    background: rgba(179, 179, 179, 0.1);
+    background: #fff;
 }
 .sm-simple ul a, .sm-simple ul a:hover, .sm-simple ul a:focus, .sm-simple ul a:active {
-   font-size: 14px;
-   border-left: 8px solid transparent;
+    font-size: 14px;
+    border-left: 8px solid transparent;
 }
 .sm-simple ul ul a,
 .sm-simple ul ul a:hover,
@@ -99,10 +94,14 @@
 	float: right;
     }
 
-    .sm-simple ul li, .sm-simple.sm-rtl ul li, .sm-simple.sm-vertical li {
+    .sm-simple ul li {
 	float: none;
     }
 
+    .sm-simple > li {
+	padding-top: 5px;
+    }
+
     .sm-simple a {
 	white-space: nowrap;
     }
@@ -112,19 +111,22 @@
     }
 
     .sm-simple .sm-nowrap > li > a, .sm-simple .sm-nowrap > li > :not(ul) a {
-					white-space: nowrap;
-				    }
+	white-space: nowrap;
+    }
 
     /* ...end */
     .sm-simple {
-	background: white;
+	background: #efefef;
     }
     .sm-simple a, .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted {
-	padding: 11px 20px;
-	color: #555555;
+	padding: 5px 15px;
+	color: #555;
     }
     .sm-simple a:hover, .sm-simple a:focus, .sm-simple a:active, .sm-simple a.highlighted {
-	background: #eeeeee;
+	background: #eee;
+    }
+    .sm-simple > li > a:hover, .sm-simple > li > a:focus, .sm-simple > li > a:active, .sm-simple > li > a.highlighted {
+	background: #fff;
     }
     .sm-simple a.current {
 	background: #555555;
@@ -146,6 +148,12 @@
 	font: 14px/16px monospace !important;
 	background: transparent;
     }
+    .sm-simple > li > a span.sub-arrow {
+	display: none;
+    }
+    .sm-simple > li:first-child a span.sub-arrow {
+	display: none;
+    }
     .sm-simple a.highlighted span.sub-arrow:before {
 	display: none;
     }
@@ -159,9 +167,6 @@
     .sm-simple ul {
 	border: 1px solid #bbbbbb;
 	background: white;
-	-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-	-moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-	box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
     }
     .sm-simple ul a {
 	border: 0 !important;
@@ -170,12 +175,11 @@
 	padding-right: 20px;
     }
     .sm-simple ul a span.sub-arrow {
-	right: auto;
-	margin-left: -12px;
+	right: 0;
+	margin-right: 5px;
     }
     .sm-simple ul > li {
 	border-left: 0;
-	border-top: 1px solid #eeeeee;
     }
     .sm-simple ul > li:first-child {
 	border-top: 0;
diff --git a/loleaflet/src/control/Control.ContextMenu.js b/loleaflet/src/control/Control.ContextMenu.js
index 2e4042b..3b83992 100644
--- a/loleaflet/src/control/Control.ContextMenu.js
+++ b/loleaflet/src/control/Control.ContextMenu.js
@@ -58,7 +58,7 @@ L.Control.ContextMenu = L.Control.extend({
 		}
 
 		var contextMenu = this._createContextMenuStructure(obj);
-		var d = $.contextMenu({
+		$.contextMenu({
 			selector: '.leaflet-layer',
 			trigger: 'none',
 			build: function(triggerEle, e) {
diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index a3dda54..8e07a11 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -4,23 +4,157 @@
 
 /* global $ */
 L.Control.menubar = L.Control.extend({
+	options: {
+		common: [
+			{name: 'File', type: 'menu', menu: [{name: 'New', type: 'command'},
+												{name: 'Open', type: 'command'},
+												{name: 'Save', type: 'command'},
+												{name: 'Print', type: 'command'}]
+			},
+			{name: 'Edit', type: 'menu', menu: [{name: 'Undo', type: 'command'},
+												{name: 'Redo', type: 'command'},
+												{name: 'Cut', type: 'command'},
+												{name: 'Copy', type: 'command'},
+												{name: 'Paste', type: 'command'},
+												{name: 'Select All', type: 'command'}]
+			}
+		],
+
+		text:  [
+			{name: 'Insert', type: 'menu', menu: [{name: 'Image', type: 'command'},
+												  {name: 'Link', type: 'command'},
+												  {name: 'Table', type: 'command'},
+												  {name: 'Footer', type: 'command'},
+												  {name: 'Page number', type: 'command'},
+												  {name: 'Index', type: 'command'},
+												  {name: 'Horizontal Line', type: 'command'},
+												  {name: 'Chart', type: 'command'},
+												  {name: 'Symbol', type: 'command'},
+												  {name: 'Remark', type: 'command'}]
+			},
+			{name: 'View', type: 'menu', menu: [{name: 'Full screen', type: 'command'},
+												{name: 'Rulers', type: 'command'},
+												{name: 'Zoom', type: 'command'},
+												{name: 'Web Layout', type: 'command'}]
+			},
+			{name: 'Layout', type: 'menu', menu: [{name: 'Text editor', type: 'command'},
+												  {name: 'Columns', type: 'command'},
+												  {name: 'Image crop', type: 'command'},
+												  {name: 'Page layout', type: 'command'},
+												  {name: 'Clear styling', type: 'command'}]
+			},
+			{name: 'Tables', type: 'menu', menu: [{name: 'Insert Table', type: 'command'},
+												  {name: 'Insert row', type: 'command'},
+												  {name: 'Insert column', type: 'command'},
+												  {name: 'Submenus', type: 'menu', menu: [{name: 'Item1', type: 'command'},
+																						  {name: 'Item2', type: 'command'},
+																						  {name: 'Item3', type: 'command'}]},
+												  {name: 'Remove row', type: 'command'},
+												  {name: 'Remove column', type: 'command'},
+												  {name: 'Split cells', type: 'command'},
+												  {name: 'Merge cells', type: 'command'}]
+			}
+		],
+
+		presentation: [
+			{name: 'Insert', type: 'menu', menu: [{name: 'Image', type: 'command'},
+												  {name: 'Shape', type: 'command'},
+												  {name: 'Line', type: 'command'},
+												  {name: 'Table', type: 'command'},
+												  {name: 'Video', type: 'command'},
+												  {name: 'Slide', type: 'command'},
+												  {name: 'Slide numbering', type: 'command'},
+												  {name: 'Text space', type: 'command'},
+												  {name: 'Chart', type: 'command'},
+												  {name: 'Symbol', type: 'command'},
+												  {name: 'Remark', type: 'command'}]
+			},
+			{name: 'View', type: 'menu', menu: [{name: 'Full Screen', type: 'command'},
+												{name: 'Presentation views', type: 'command'},
+												{name: 'Master views', type: 'command'},
+												{name: 'Zoom', type: 'command'},
+												{name: 'Show rulers', type: 'command'}]
+			}
+		],
+
+		spreadsheet: [
+			{name: 'Insert', type: 'menu', menu: [{name: 'Row', type: 'command'},
+												  {name: 'Column', type: 'command'},
+												  {name: 'Function', type: 'command'},
+												  {name: 'Page', type: 'command'}]
+			},
+			{name: 'View', type: 'menu', menu: [{name: 'Full screen', type: 'command'},
+												{name: 'Formula bar', type: 'command'},
+												{name: 'Zoom', type: 'command'},
+												{name: 'Headings', type: 'command'}]
+			}
+		]
+	},
+
 	onAdd: function (map) {
 		this._initialized = false;
 		var docContainer = map.options.documentContainer;
-		map.on('updatepermission', this._onUpdatePermission, this);
+		this._menubarCont = L.DomUtil.create('ul', 'sm sm-simple', docContainer.parentElement);
+		this._menubarCont.id = 'main-menu';
 
-		//$('#main-menu').smartmenus();
+		map.on('updatepermission', this._onUpdatePermission, this);
 	},
 
 	_onUpdatePermission: function() {
-		// TODO
-		if (!this._initialized) {
-			this._initialize();
+		if (this._initialized || !this._menubarCont)
+			return;
+
+		// Intialize menu that is common to all documents
+		this._initializeMenu(this.options.common);
+
+		// Add dcoument specific menu
+		var docType = this._map.getDocType();
+		if (docType === 'text') {
+			this._initializeMenu(this.options.text);
+		} else if (docType === 'spreadsheet') {
+			this._initializeMenu(this.options.spreadsheet);
+		} else if (docType === 'presentation' || docType === 'drawing') {
+			this._initializeMenu(this.options.presentation);
 		}
+
+		// initialize menubar plugin
+		$('#main-menu').smartmenus({
+			showOnClick: true,
+			hideTimeout: 0,
+			hideDuration: 0,
+			collapsibleHideDuration: 0,
+			subIndicatorsPos: 'append',
+			subIndicatorsText: '›'
+		});
+		this._initialized = true;
+	},
+
+	_createMenu: function(menu) {
+		var itemList = [];
+		for (var i in menu) {
+			var liItem = L.DomUtil.create('li', '');
+			var aItem = L.DomUtil.create('a', '', liItem);
+			aItem.innerHTML = menu[i]['name'];
+
+			if (menu[i]['type'] === 'menu') {
+				var ulItem = L.DomUtil.create('ul', '', liItem);
+				var subitemList = this._createMenu(menu[i]['menu']);
+				for (var j in subitemList) {
+					ulItem.appendChild(subitemList[j]);
+				}
+			}
+
+			itemList.push(liItem);
+		}
+
+		return itemList;
 	},
 
-	_initialize: function() {
-		// TODO
+	_initializeMenu: function(menu) {
+		var menuHtml = this._createMenu(menu);
+		for (var i in menuHtml) {
+			this._menubarCont.appendChild(menuHtml[i]);
+		}
 	}
 });
 
commit 2c3964be1d3c561428b511201abdc5c445e87f73
Author: Pranav Kant <pranavk at collabora.com>
Date:   Tue May 17 17:58:55 2016 +0530

    loleaflet: Setup infrastructure for top menubar
    
    Change-Id: Ib48c2b3219b74da15bc2898044ad9b3c01f8a203

diff --git a/loleaflet/build/deps.js b/loleaflet/build/deps.js
index 4ac1b00..eaa9f9f 100644
--- a/loleaflet/build/deps.js
+++ b/loleaflet/build/deps.js
@@ -280,6 +280,13 @@ var deps = {
 		desc: 'Context Menu'
 	},
 
+	ControlMenubar: {
+		src: ['control/Control.js',
+			'control/Control.Menubar.js'],
+		heading: 'Controls',
+		desc: 'Menu bar'
+	},
+
 	ControlTabs: {
 		src: ['control/Control.js',
 		      'control/Control.Tabs.js'],
diff --git a/loleaflet/debug/document/loleaflet.html b/loleaflet/debug/document/loleaflet.html
index f9939d5..2584381 100644
--- a/loleaflet/debug/document/loleaflet.html
+++ b/loleaflet/debug/document/loleaflet.html
@@ -22,6 +22,8 @@
 <link rel="stylesheet" href="/loleaflet/%VERSION%/dialog/vex-theme-plain.css" />
 <link rel="stylesheet" href="/loleaflet/%VERSION%/toolbar/w2ui.min.css" />
 <link rel="stylesheet" href="/loleaflet/%VERSION%/toolbar/select2.min.css" />
+<link rel="stylesheet" href="/loleaflet/dist/smartmenus/sm-core-css.css" />
+<link rel="stylesheet" href="/loleaflet/dist/smartmenus/sm-simple.css" />
 <link rel="stylesheet" href="/loleaflet/%VERSION%/jqueryui/1.11.1/themes/ui-lightness/jquery-ui.css">
 <link rel="stylesheet" href="/loleaflet/%VERSION%/toolbar/evol.colorpicker.min.css">
 <link rel="localizations" href="/loleaflet/%VERSION%/l10n/localizations.json" type="application/vnd.oftn.l10n+json"/>
@@ -41,6 +43,7 @@
     <script src="/loleaflet/%VERSION%/scrollbar/jquery.mCustomScrollbar.js"></script>
     <script src="/loleaflet/%VERSION%/contextMenu/jquery.contextMenu.js"></script>
     <script src="/loleaflet/%VERSION%/contextMenu/jquery.ui.position.min.js"></script>
+    <script src="/loleaflet/%VERSION%/smartmenus/jquery.smartmenus.js"></script>
     <script src="/loleaflet/%VERSION%/dialog/vex.combined.min.js"></script>
     <script src="/loleaflet/%VERSION%/branding.js"></script> <!-- logo onclick handler -->
     <script>vex.defaultOptions.className = 'vex-theme-plain';</script>
@@ -123,6 +126,7 @@
     map.addControl(L.control.columnHeader());
     map.addControl(L.control.rowHeader());
     map.addControl(L.control.contextMenu());
+    map.addControl(L.control.menubar());
 
     </script>
 
diff --git a/loleaflet/dist/loleaflet.css b/loleaflet/dist/loleaflet.css
index 467e0e3..a7c7597 100644
--- a/loleaflet/dist/loleaflet.css
+++ b/loleaflet/dist/loleaflet.css
@@ -17,6 +17,15 @@
 	z-index: 10;
 }
 
+#main-menu {
+    top: 0;
+    position: fixed;
+    height: 25px;
+    right: 0;
+    left: 0;
+    z-index: 1030;
+}
+
 body {
     margin: 0;
 }
diff --git a/loleaflet/dist/loleaflet.html b/loleaflet/dist/loleaflet.html
index 2566d14..a8eac6b 100644
--- a/loleaflet/dist/loleaflet.html
+++ b/loleaflet/dist/loleaflet.html
@@ -22,6 +22,8 @@
 <link rel="stylesheet" href="/loleaflet/%VERSION%/dialog/vex-theme-plain.css" />
 <link rel="stylesheet" href="/loleaflet/%VERSION%/toolbar/w2ui.min.css" />
 <link rel="stylesheet" href="/loleaflet/%VERSION%/toolbar/select2.min.css" />
+<link rel="stylesheet" href="/loleaflet/dist/smartmenus/sm-core-css.css" />
+<link rel="stylesheet" href="/loleaflet/dist/smartmenus/sm-simple.css" />
 <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/themes/ui-lightness/jquery-ui.css">
 <link rel="stylesheet" href="/loleaflet/%VERSION%/toolbar/evol.colorpicker.min.css">
 <link rel="localizations" href="/loleaflet/%VERSION%/l10n/localizations.json" type="application/vnd.oftn.l10n+json"/>
@@ -42,6 +44,7 @@
     <script src="/loleaflet/%VERSION%/scrollbar/jquery.mCustomScrollbar.js"></script>
     <script src="/loleaflet/%VERSION%/contextMenu/jquery.contextMenu.js"></script>
     <script src="/loleaflet/%VERSION%/contextMenu/jquery.ui.position.min.js"></script>
+    <script src="/loleaflet/%VERSION%/smartmenus/jquery.smartmenus.js"></script>
     <script src="/loleaflet/%VERSION%/dialog/vex.combined.min.js"></script>
     <script src="/loleaflet/%VERSION%/branding.js"></script> <!-- logo onclick handler -->
     <script>vex.defaultOptions.className = 'vex-theme-plain';</script>
@@ -124,6 +127,7 @@
     map.addControl(L.control.columnHeader());
     map.addControl(L.control.rowHeader());
     map.addControl(L.control.contextMenu());
+    map.addControl(L.control.menubar());
 
     </script>
 
diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
new file mode 100644
index 0000000..a3dda54
--- /dev/null
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -0,0 +1,29 @@
+/*
+* Control.Menubar
+*/
+
+/* global $ */
+L.Control.menubar = L.Control.extend({
+	onAdd: function (map) {
+		this._initialized = false;
+		var docContainer = map.options.documentContainer;
+		map.on('updatepermission', this._onUpdatePermission, this);
+
+		//$('#main-menu').smartmenus();
+	},
+
+	_onUpdatePermission: function() {
+		// TODO
+		if (!this._initialized) {
+			this._initialize();
+		}
+	},
+
+	_initialize: function() {
+		// TODO
+	}
+});
+
+L.control.menubar = function (options) {
+	return new L.Control.menubar(options);
+};
commit 36d5191b4de2da5714e6dc8f6631839e04dac97f
Author: Pranav Kant <pranavk at collabora.com>
Date:   Tue May 17 17:58:15 2016 +0530

    loleaflet: Add jquery smartmenus plugin
    
    License: MIT
    
    Additionally, the sm-simple.css file is indented appropriately as
    we would need to modify it to our needs later.
    
    Change-Id: Iab909d2e06af342b22ebeffc86b3efdc1bacb73e

diff --git a/loleaflet/dist/smartmenus/jquery.smartmenus.js b/loleaflet/dist/smartmenus/jquery.smartmenus.js
new file mode 100644
index 0000000..8735d2c
--- /dev/null
+++ b/loleaflet/dist/smartmenus/jquery.smartmenus.js
@@ -0,0 +1,1214 @@
+/*!
+ * SmartMenus jQuery Plugin - v1.0.0 - January 27, 2016
+ * http://www.smartmenus.org/
+ *
+ * Copyright Vasil Dinkov, Vadikom Web Ltd.
+ * http://vadikom.com
+ *
+ * Licensed MIT
+ */
+
+(function(factory) {
+	if (typeof define === 'function' && define.amd) {
+		// AMD
+		define(['jquery'], factory);
+	} else if (typeof module === 'object' && typeof module.exports === 'object') {
+		// CommonJS
+		module.exports = factory(require('jquery'));
+	} else {
+		// Global jQuery
+		factory(jQuery);
+	}
+} (function($) {
+
+	var menuTrees = [],
+		IE = !!window.createPopup, // detect it for the iframe shim
+		mouse = false, // optimize for touch by default - we will detect for mouse input
+		touchEvents = 'ontouchstart' in window, // we use this just to choose between toucn and pointer events, not for touch screen detection
+		mouseDetectionEnabled = false,
+		requestAnimationFrame = window.requestAnimationFrame || function(callback) { return setTimeout(callback, 1000 / 60); },
+		cancelAnimationFrame = window.cancelAnimationFrame || function(id) { clearTimeout(id); };
+
+	// Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.)
+	function initMouseDetection(disable) {
+		var eNS = '.smartmenus_mouse';
+		if (!mouseDetectionEnabled && !disable) {
+			// if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present
+			// in practice, this seems like impossible to trick unintentianally with a real mouse and a pretty safe detection on touch devices (even with older browsers that do not support touch events)
+			var firstTime = true,
+				lastMove = null;
+			$(document).bind(getEventsNS([
+				['mousemove', function(e) {
+					var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() };
+					if (lastMove) {
+						var deltaX = Math.abs(lastMove.x - thisMove.x),
+							deltaY = Math.abs(lastMove.y - thisMove.y);
+	 					if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) {
+							mouse = true;
+							// if this is the first check after page load, check if we are not over some item by chance and call the mouseenter handler if yes
+							if (firstTime) {
+								var $a = $(e.target).closest('a');
+								if ($a.is('a')) {
+									$.each(menuTrees, function() {
+										if ($.contains(this.$root[0], $a[0])) {
+											this.itemEnter({ currentTarget: $a[0] });
+											return false;
+										}
+									});
+								}
+								firstTime = false;
+							}
+						}
+					}
+					lastMove = thisMove;
+				}],
+				[touchEvents ? 'touchstart' : 'pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut', function(e) {
+					if (isTouchEvent(e.originalEvent)) {
+						mouse = false;
+					}
+				}]
+			], eNS));
+			mouseDetectionEnabled = true;
+		} else if (mouseDetectionEnabled && disable) {
+			$(document).unbind(eNS);
+			mouseDetectionEnabled = false;
+		}
+	}
+
+	function isTouchEvent(e) {
+		return !/^(4|mouse)$/.test(e.pointerType);
+	}
+
+	// returns a jQuery bind() ready object
+	function getEventsNS(defArr, eNS) {
+		if (!eNS) {
+			eNS = '';
+		}
+		var obj = {};
+		$.each(defArr, function(index, value) {
+			obj[value[0].split(' ').join(eNS + ' ') + eNS] = value[1];
+		});
+		return obj;
+	}
+
+	$.SmartMenus = function(elm, options) {
+		this.$root = $(elm);
+		this.opts = options;
+		this.rootId = ''; // internal
+		this.accessIdPrefix = '';
+		this.$subArrow = null;
+		this.activatedItems = []; // stores last activated A's for each level
+		this.visibleSubMenus = []; // stores visible sub menus UL's (might be in no particular order)
+		this.showTimeout = 0;
+		this.hideTimeout = 0;
+		this.scrollTimeout = 0;
+		this.clickActivated = false;
+		this.focusActivated = false;
+		this.zIndexInc = 0;
+		this.idInc = 0;
+		this.$firstLink = null; // we'll use these for some tests
+		this.$firstSub = null; // at runtime so we'll cache them
+		this.disabled = false;
+		this.$disableOverlay = null;
+		this.$touchScrollingSub = null;
+		this.cssTransforms3d = 'perspective' in elm.style || 'webkitPerspective' in elm.style;
+		this.wasCollapsible = false;
+		this.init();
+	};
+
+	$.extend($.SmartMenus, {
+		hideAll: function() {
+			$.each(menuTrees, function() {
+				this.menuHideAll();
+			});
+		},
+		destroy: function() {
+			while (menuTrees.length) {
+				menuTrees[0].destroy();
+			}
+			initMouseDetection(true);
+		},
+		prototype: {
+			init: function(refresh) {
+				var self = this;
+
+				if (!refresh) {
+					menuTrees.push(this);
+
+					this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, '');
+					this.accessIdPrefix = 'sm-' + this.rootId + '-';
+
+					if (this.$root.hasClass('sm-rtl')) {
+						this.opts.rightToLeftSubMenus = true;
+					}
+
+					// init root (main menu)
+					var eNS = '.smartmenus';
+					this.$root
+						.data('smartmenus', this)
+						.attr('data-smartmenus-id', this.rootId)
+						.dataSM('level', 1)
+						.bind(getEventsNS([
+							['mouseover focusin', $.proxy(this.rootOver, this)],
+							['mouseout focusout', $.proxy(this.rootOut, this)],
+							['keydown', $.proxy(this.rootKeyDown, this)]
+						], eNS))
+						.delegate('a', getEventsNS([
+							['mouseenter', $.proxy(this.itemEnter, this)],
+							['mouseleave', $.proxy(this.itemLeave, this)],
+							['mousedown', $.proxy(this.itemDown, this)],
+							['focus', $.proxy(this.itemFocus, this)],
+							['blur', $.proxy(this.itemBlur, this)],
+							['click', $.proxy(this.itemClick, this)]
+						], eNS));
+
+					// hide menus on tap or click outside the root UL
+					eNS += this.rootId;
+					if (this.opts.hideOnClick) {
+						$(document).bind(getEventsNS([
+							['touchstart', $.proxy(this.docTouchStart, this)],
+							['touchmove', $.proxy(this.docTouchMove, this)],
+							['touchend', $.proxy(this.docTouchEnd, this)],
+							// for Opera Mobile < 11.5, webOS browser, etc. we'll check click too
+							['click', $.proxy(this.docClick, this)]
+						], eNS));
+					}
+					// hide sub menus on resize
+					$(window).bind(getEventsNS([['resize orientationchange', $.proxy(this.winResize, this)]], eNS));
+
+					if (this.opts.subIndicators) {
+						this.$subArrow = $('<span/>').addClass('sub-arrow');
+						if (this.opts.subIndicatorsText) {
+							this.$subArrow.html(this.opts.subIndicatorsText);
+						}
+					}
+
+					// make sure mouse detection is enabled
+					initMouseDetection();
+				}
+
+				// init sub menus
+				this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0);
+
+				this.$firstLink = this.$root.find('a').eq(0);
+
+				// find current item
+				if (this.opts.markCurrentItem) {
+					var reDefaultDoc = /(index|default)\.[^#\?\/]*/i,
+						reHash = /#.*/,
+						locHref = window.location.href.replace(reDefaultDoc, ''),
+						locHrefNoHash = locHref.replace(reHash, '');
+					this.$root.find('a').each(function() {
+						var href = this.href.replace(reDefaultDoc, ''),
+							$this = $(this);
+						if (href == locHref || href == locHrefNoHash) {
+							$this.addClass('current');
+							if (self.opts.markCurrentTree) {
+								$this.parentsUntil('[data-smartmenus-id]', 'ul').each(function() {
+									$(this).dataSM('parent-a').addClass('current');
+								});
+							}
+						}
+					});
+				}
+
+				// save initial state
+				this.wasCollapsible = this.isCollapsible();
+			},
+			destroy: function(refresh) {
+				if (!refresh) {
+					var eNS = '.smartmenus';
+					this.$root
+						.removeData('smartmenus')
+						.removeAttr('data-smartmenus-id')
+						.removeDataSM('level')
+						.unbind(eNS)
+						.undelegate(eNS);
+					eNS += this.rootId;
+					$(document).unbind(eNS);
+					$(window).unbind(eNS);
+					if (this.opts.subIndicators) {
+						this.$subArrow = null;
+					}
+				}
+				this.menuHideAll();
+				var self = this;
+				this.$root.find('ul').each(function() {
+						var $this = $(this);
+						if ($this.dataSM('scroll-arrows')) {
+							$this.dataSM('scroll-arrows').remove();
+						}
+						if ($this.dataSM('shown-before')) {
+							if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) {
+								$this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap');
+							}
+							if ($this.dataSM('scroll-arrows')) {
+								$this.dataSM('scroll-arrows').remove();
+							}
+							$this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' });
+						}
+						if (($this.attr('id') || '').indexOf(self.accessIdPrefix) == 0) {
+							$this.removeAttr('id');
+						}
+					})
+					.removeDataSM('in-mega')
+					.removeDataSM('shown-before')
+					.removeDataSM('ie-shim')
+					.removeDataSM('scroll-arrows')
+					.removeDataSM('parent-a')
+					.removeDataSM('level')
+					.removeDataSM('beforefirstshowfired')
+					.removeAttr('role')
+					.removeAttr('aria-hidden')
+					.removeAttr('aria-labelledby')
+					.removeAttr('aria-expanded');
+				this.$root.find('a.has-submenu').each(function() {
+						var $this = $(this);
+						if ($this.attr('id').indexOf(self.accessIdPrefix) == 0) {
+							$this.removeAttr('id');
+						}
+					})
+					.removeClass('has-submenu')
+					.removeDataSM('sub')
+					.removeAttr('aria-haspopup')
+					.removeAttr('aria-controls')
+					.removeAttr('aria-expanded')
+					.closest('li').removeDataSM('sub');
+				if (this.opts.subIndicators) {
+					this.$root.find('span.sub-arrow').remove();
+				}
+				if (this.opts.markCurrentItem) {
+					this.$root.find('a.current').removeClass('current');
+				}
+				if (!refresh) {
+					this.$root = null;
+					this.$firstLink = null;
+					this.$firstSub = null;
+					if (this.$disableOverlay) {
+						this.$disableOverlay.remove();
+						this.$disableOverlay = null;
+					}
+					menuTrees.splice($.inArray(this, menuTrees), 1);
+				}
+			},
+			disable: function(noOverlay) {
+				if (!this.disabled) {
+					this.menuHideAll();
+					// display overlay over the menu to prevent interaction
+					if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) {
+						var pos = this.$root.offset();
+						this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({
+							position: 'absolute',
+							top: pos.top,
+							left: pos.left,
+							width: this.$root.outerWidth(),
+							height: this.$root.outerHeight(),
+							zIndex: this.getStartZIndex(true),
+							opacity: 0
+						}).appendTo(document.body);
+					}
+					this.disabled = true;
+				}
+			},
+			docClick: function(e) {
+				if (this.$touchScrollingSub) {
+					this.$touchScrollingSub = null;
+					return;
+				}
+				// hide on any click outside the menu or on a menu link
+				if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a')) {
+					this.menuHideAll();
+				}
+			},
+			docTouchEnd: function(e) {
+				if (!this.lastTouch) {
+					return;
+				}
+				if (this.visibleSubMenus.length && (this.lastTouch.x2 === undefined || this.lastTouch.x1 == this.lastTouch.x2) && (this.lastTouch.y2 === undefined || this.lastTouch.y1 == this.lastTouch.y2) && (!this.lastTouch.target || !$.contains(this.$root[0], this.lastTouch.target))) {
+					if (this.hideTimeout) {
+						clearTimeout(this.hideTimeout);
+						this.hideTimeout = 0;
+					}
+					// hide with a delay to prevent triggering accidental unwanted click on some page element
+					var self = this;
+					this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, 350);
+				}
+				this.lastTouch = null;
+			},
+			docTouchMove: function(e) {
+				if (!this.lastTouch) {
+					return;
+				}
+				var touchPoint = e.originalEvent.touches[0];
+				this.lastTouch.x2 = touchPoint.pageX;
+				this.lastTouch.y2 = touchPoint.pageY;
+			},
+			docTouchStart: function(e) {
+				var touchPoint = e.originalEvent.touches[0];
+				this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target };
+			},
+			enable: function() {
+				if (this.disabled) {
+					if (this.$disableOverlay) {
+						this.$disableOverlay.remove();
+						this.$disableOverlay = null;
+					}
+					this.disabled = false;
+				}
+			},
+			getClosestMenu: function(elm) {
+				var $closestMenu = $(elm).closest('ul');
+				while ($closestMenu.dataSM('in-mega')) {
+					$closestMenu = $closestMenu.parent().closest('ul');
+				}
+				return $closestMenu[0] || null;
+			},
+			getHeight: function($elm) {
+				return this.getOffset($elm, true);
+			},
+			// returns precise width/height float values
+			getOffset: function($elm, height) {
+				var old;
+				if ($elm.css('display') == 'none') {
+					old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility };
+					$elm.css({ position: 'absolute', visibility: 'hidden' }).show();
+				}
+				var box = $elm[0].getBoundingClientRect && $elm[0].getBoundingClientRect(),
+					val = box && (height ? box.height || box.bottom - box.top : box.width || box.right - box.left);
+				if (!val && val !== 0) {
+					val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth;
+				}
+				if (old) {
+					$elm.hide().css(old);
+				}
+				return val;
+			},
+			getStartZIndex: function(root) {
+				var zIndex = parseInt(this[root ? '$root' : '$firstSub'].css('z-index'));
+				if (!root && isNaN(zIndex)) {
+					zIndex = parseInt(this.$root.css('z-index'));
+				}
+				return !isNaN(zIndex) ? zIndex : 1;
+			},
+			getTouchPoint: function(e) {
+				return e.touches && e.touches[0] || e.changedTouches && e.changedTouches[0] || e;
+			},
+			getViewport: function(height) {
+				var name = height ? 'Height' : 'Width',
+					val = document.documentElement['client' + name],
+					val2 = window['inner' + name];
+				if (val2) {
+					val = Math.min(val, val2);
+				}
+				return val;
+			},
+			getViewportHeight: function() {
+				return this.getViewport(true);
+			},
+			getViewportWidth: function() {
+				return this.getViewport();
+			},
+			getWidth: function($elm) {
+				return this.getOffset($elm);
+			},
+			handleEvents: function() {

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list