xref: /online/loleaflet/src/control/Control.TopToolbar.js (revision d6216e4335da0e2b6b06caabd5b378bd3798d922)
1/* -*- js-indent-level: 8 -*- */
2/*
3 * L.Control.TopToolbar
4 */
5
6/* global $ w2ui _ _UNO w2utils */
7L.Control.TopToolbar = L.Control.extend({
8	options: {
9		stylesSelectValue: null,
10		fontsSelectValue: null
11	},
12
13	onAdd: function (map) {
14		this.map = map;
15		this.create();
16
17		map.on('doclayerinit', this.onDocLayerInit, this);
18		map.on('updatepermission', this.onUpdatePermission, this);
19		map.on('wopiprops', this.onWopiProps, this);
20		map.on('commandstatechanged', this.onCommandStateChanged, this);
21
22		if (!window.mode.isMobile()) {
23			map.on('updatetoolbarcommandvalues', this.updateCommandValues, this);
24		}
25
26		$(window).resize(function() {
27			if ($(window).width() !== map.getSize().x) {
28				var toolbar = w2ui['editbar'];
29				toolbar.resize();
30			}
31		});
32	},
33
34	onFontSizeSelect: function(e) {
35		this.map.applyFontSize(e.target.value);
36		this.map.focus();
37	},
38
39	onFontSelect: function(e) {
40		var font = e.target.value;
41		this.map.applyFont(font);
42		this.map.focus();
43	},
44
45	onStyleSelect: function(e) {
46		var style = e.target.value;
47		if (style.startsWith('.uno:')) {
48			this.map.sendUnoCommand(style);
49		}
50		else if (this.map.getDocType() === 'text') {
51			this.map.applyStyle(style, 'ParagraphStyles');
52		}
53		else if (this.map.getDocType() === 'spreadsheet') {
54			this.map.applyStyle(style, 'CellStyles');
55		}
56		else if (this.map.getDocType() === 'presentation' || this.map.getDocType() === 'drawing') {
57			this.map.applyLayout(style);
58		}
59		this.map.focus();
60	},
61
62	_updateVisibilityForToolbar: function(toolbar) {
63		if (!toolbar)
64			return;
65
66		var toShow = [];
67		var toHide = [];
68
69		toolbar.items.forEach(function(item) {
70			if (window.ThisIsTheiOSApp && window.mode.isTablet() && item.iosapptablet === false) {
71				toHide.push(item.id);
72			}
73			else if (((window.mode.isMobile() && item.mobile === false) || (window.mode.isTablet() && item.tablet === false) || (window.mode.isDesktop() && item.desktop === false) || (!window.ThisIsAMobileApp && item.mobilebrowser === false)) && !item.hidden) {
74				toHide.push(item.id);
75			}
76			else if (((window.mode.isMobile() && item.mobile === true) || (window.mode.isTablet() && item.tablet === true) || (window.mode.isDesktop() && item.desktop === true) || (window.ThisIsAMobileApp && item.mobilebrowser === true)) && item.hidden) {
77				toShow.push(item.id);
78			}
79		});
80
81		console.log('explicitly hiding: ' + toHide);
82		console.log('explicitly showing: ' + toShow);
83
84		toHide.forEach(function(item) { toolbar.hide(item); });
85		toShow.forEach(function(item) { toolbar.show(item); });
86	},
87
88	// mobile:false means hide it both for normal Online used from a mobile phone browser, and in a mobile app on a mobile phone
89	// mobilebrowser:false means hide it for normal Online used from a mobile browser, but don't hide it in a mobile app
90	// tablet:true means show it in normal Online from a tablet browser, and in a mobile app on a tablet
91	// tablet:false means hide it in normal Online used from a tablet browser, and in a mobile app on a tablet
92
93	getToolItems: function() {
94		return [
95			{type: 'button',  id: 'closemobile',  img: 'closemobile', desktop: false, mobile: false, tablet: true, hidden: true},
96			{type: 'button',  id: 'save', img: 'save', hint: _UNO('.uno:Save')},
97			{type: 'button',  id: 'print', img: 'print', hint: _UNO('.uno:Print', 'text'), mobile: false, tablet: false},
98			{type: 'break', id: 'savebreak', mobile: false},
99			{type: 'button',  id: 'undo',  img: 'undo', hint: _UNO('.uno:Undo'), uno: 'Undo', disabled: true, mobile: false},
100			{type: 'button',  id: 'redo',  img: 'redo', hint: _UNO('.uno:Redo'), uno: 'Redo', disabled: true, mobile: false},
101			{type: 'button',  id: 'formatpaintbrush',  img: 'copyformat', hint: _UNO('.uno:FormatPaintbrush'), uno: 'FormatPaintbrush', mobile: false},
102			{type: 'button',  id: 'reset',  img: 'deleteformat', hint: _UNO('.uno:ResetAttributes', 'text'), uno: 'ResetAttributes', mobile: false},
103			{type: 'break', mobile: false, tablet: false,},
104			{type: 'html', id: 'styles',
105				html: '<select class="styles-select"><option>' + _('Default Style') + '</option></select>',
106				onRefresh: function (edata) {
107					if (!edata.item.html) {
108						edata.isCancelled = true;
109					} else {
110						$.extend(edata, { onComplete: function (e) {
111							$('.styles-select').select2();
112							e.item.html = undefined;
113						}});
114					}
115				}, hidden: true, desktop: true, mobile: false, tablet: false},
116			{type: 'html', id: 'fonts',
117				html: '<select class="fonts-select"><option>Carlito</option></select>',
118				onRefresh: function (edata) {
119					if (!edata.item.html) {
120						edata.isCancelled = true;
121					} else {
122						$.extend(edata, { onComplete: function (e) {
123							$('.fonts-select').select2();
124							e.item.html = undefined;
125						}});
126					}
127				}, mobile: false},
128			{type: 'html',   id: 'fontsizes',
129				html: '<select class="fontsizes-select">',
130				onRefresh: function (edata) {
131					if (!edata.item.html) {
132						edata.isCancelled = true;
133					} else {
134						$.extend(edata, { onComplete: function (e) {
135							$('.fontsizes-select').select2({ dropdownAutoWidth: true, width: 'auto'});
136							e.item.html = undefined;
137						}});
138					}
139				}, mobile: false},
140			{type: 'break', id: 'breakstyles', mobile: false, tablet: false },
141			{type: 'button', id: 'languagecode', desktop: false, mobile: true, tablet: false},
142			{type: 'button',  id: 'bold',  img: 'bold', hint: _UNO('.uno:Bold'), uno: 'Bold'},
143			{type: 'button',  id: 'italic', img: 'italic', hint: _UNO('.uno:Italic'), uno: 'Italic'},
144			{type: 'button',  id: 'underline',  img: 'underline', hint: _UNO('.uno:Underline'), uno: 'Underline'},
145			{type: 'button',  id: 'strikeout', img: 'strikeout', hint: _UNO('.uno:Strikeout'), uno: 'Strikeout'},
146			{type: 'break', id: 'breakformatting'},
147			{type: 'text-color',  id: 'fontcolor', img: 'textcolor', hint: _UNO('.uno:FontColor')},
148			{type: 'color',  id: 'backcolor', img: 'backcolor', hint: _UNO('.uno:BackColor', 'text'), hidden: true},
149			{type: 'color',  id: 'backgroundcolor', img: 'backgroundcolor', hint: _UNO('.uno:BackgroundColor'), hidden: true},
150			{type: 'break' , id: 'breakcolor', mobile:false},
151			{type: 'button',  id: 'leftpara',  img: 'alignleft', hint: _UNO('.uno:LeftPara', '', true),
152				uno: {textCommand: 'LeftPara', objectCommand: 'ObjectAlignLeft'},
153				hidden: true, unosheet: 'AlignLeft', disabled: true},
154			{type: 'button',  id: 'centerpara',  img: 'alignhorizontal', hint: _UNO('.uno:CenterPara', '', true),
155				uno: {textCommand: 'CenterPara', objectCommand: 'AlignCenter'},
156				hidden: true, unosheet: 'AlignHorizontalCenter', disabled: true},
157			{type: 'button',  id: 'rightpara',  img: 'alignright', hint: _UNO('.uno:RightPara', '', true),
158				uno: {textCommand: 'RightPara', objectCommand: 'ObjectAlignRight'},
159				hidden: true, unosheet: 'AlignRight', disabled: true},
160			{type: 'button',  id: 'justifypara',  img: 'alignblock', hint: _UNO('.uno:JustifyPara', '', true), uno: 'JustifyPara', hidden: true, unosheet: '', disabled: true},
161			{type: 'break', id: 'breakpara', hidden: true},
162			{type: 'drop',  id: 'setborderstyle',  img: 'setborderstyle', hint: _('Borders'), hidden: true,
163				html: '<table id="setborderstyle-grid"><tr><td class="w2ui-tb-image w2ui-icon frame01" onclick="setBorderStyle(1)"></td>' +
164					  '<td class="w2ui-tb-image w2ui-icon frame02" onclick="setBorderStyle(2)"></td><td class="w2ui-tb-image w2ui-icon frame03" onclick="setBorderStyle(3)"></td>' +
165					  '<td class="w2ui-tb-image w2ui-icon frame04" onclick="setBorderStyle(4)"></td></tr><tr><td class="w2ui-tb-image w2ui-icon frame05" onclick="setBorderStyle(5)"></td>' +
166					  '<td class="w2ui-tb-image w2ui-icon frame06" onclick="setBorderStyle(6)"></td><td class="w2ui-tb-image w2ui-icon frame07" onclick="setBorderStyle(7)"></td>' +
167					  '<td class="w2ui-tb-image w2ui-icon frame08" onclick="setBorderStyle(8)"></td></tr><tr><td class="w2ui-tb-image w2ui-icon frame09" onclick="setBorderStyle(9)"></td>' +
168					  '<td class="w2ui-tb-image w2ui-icon frame10" onclick="setBorderStyle(10)"></td><td class="w2ui-tb-image w2ui-icon frame11" onclick="setBorderStyle(11)"></td>' +
169					  '<td class="w2ui-tb-image w2ui-icon frame12" onclick="setBorderStyle(12)"></td></tr><tr>' +
170					  '<td colspan="4" class="w2ui-tb-image w2ui-icon frame13" onclick="setBorderStyle(0)"><div id="div-frame13">' + _('More...') + '</div></td></tr></table>'
171			},
172			{type: 'button',  id: 'togglemergecells',  img: 'togglemergecells', hint: _UNO('.uno:ToggleMergeCells', 'spreadsheet', true), hidden: true, uno: 'ToggleMergeCells', disabled: true},
173			{type: 'break', id: 'breakmergecells', hidden: true},
174			{type: 'menu', id: 'textalign', img: 'alignblock', hint: _UNO('.uno:TextAlign'), hidden: true,
175				items: [
176					{id: 'alignleft', text: _UNO('.uno:AlignLeft', 'spreadsheet', true), icon: 'alignleft', uno: 'AlignLeft'},
177					{id: 'alignhorizontalcenter', text: _UNO('.uno:AlignHorizontalCenter', 'spreadsheet', true), icon: 'alignhorizontal', uno: 'AlignHorizontalCenter'},
178					{id: 'alignright', text: _UNO('.uno:AlignRight', 'spreadsheet', true), icon: 'alignright', uno: 'AlignRight'},
179					{id: 'alignblock', text: _UNO('.uno:AlignBlock', 'spreadsheet', true), icon: 'alignblock', uno: 'AlignBlock'},
180				]},
181			{type: 'menu',  id: 'linespacing',  img: 'linespacing', hint: _UNO('.uno:FormatSpacingMenu'), hidden: true,
182				items: [
183					{id: 'spacepara1', text: _UNO('.uno:SpacePara1'), uno: 'SpacePara1'},
184					{id: 'spacepara15', text: _UNO('.uno:SpacePara15'), uno: 'SpacePara15'},
185					{id: 'spacepara2', text: _UNO('.uno:SpacePara2'), uno: 'SpacePara2'},
186					{type: 'break'},
187					{id: 'paraspaceincrease', text: _UNO('.uno:ParaspaceIncrease'), uno: 'ParaspaceIncrease'},
188					{id: 'paraspacedecrease', text: _UNO('.uno:ParaspaceDecrease'), uno: 'ParaspaceDecrease'}
189				]},
190			{type: 'button',  id: 'wraptext',  img: 'wraptext', hint: _UNO('.uno:WrapText', 'spreadsheet', true), hidden: true, uno: 'WrapText', disabled: true},
191			{type: 'break', id: 'breakspacing', hidden: true},
192			{type: 'button',  id: 'defaultnumbering',  img: 'numbering', hint: _UNO('.uno:DefaultNumbering', '', true), hidden: true, uno: 'DefaultNumbering', disabled: true},
193			{type: 'button',  id: 'defaultbullet',  img: 'bullet', hint: _UNO('.uno:DefaultBullet', '', true), hidden: true, uno: 'DefaultBullet', disabled: true},
194			{type: 'break', id: 'breakbullet', hidden: true},
195			{type: 'button',  id: 'incrementindent',  img: 'incrementindent', hint: _UNO('.uno:IncrementIndent', '', true), uno: 'IncrementIndent', hidden: true, disabled: true},
196			{type: 'button',  id: 'decrementindent',  img: 'decrementindent', hint: _UNO('.uno:DecrementIndent', '', true), uno: 'DecrementIndent', hidden: true, disabled: true},
197			{type: 'break', id: 'breakindent', hidden: true},
198			{type: 'button',  id: 'sortascending',  img: 'sortascending', hint: _UNO('.uno:SortAscending', 'spreadsheet', true), uno: 'SortAscending', disabled: true, hidden: true},
199			{type: 'button',  id: 'sortdescending',  img: 'sortdescending', hint: _UNO('.uno:SortDescending', 'spreadsheet', true), uno: 'SortDescending', disabled: true, hidden: true},
200			{type: 'break', id: 'breaksorting', hidden: true},
201			{type: 'drop', id: 'conditionalformaticonset',  img: 'conditionalformatdialog', hint: _UNO('.uno:ConditionalFormatMenu', 'spreadsheet', true), hidden: true, html: window.getConditionalFormatMenuHtml()},
202			{type: 'button',  id: 'numberformatcurrency',  img: 'numberformatcurrency', hint: _UNO('.uno:NumberFormatCurrency', 'spreadsheet', true), hidden: true, uno: 'NumberFormatCurrency', disabled: true},
203			{type: 'button',  id: 'numberformatpercent',  img: 'numberformatpercent', hint: _UNO('.uno:NumberFormatPercent', 'spreadsheet', true), hidden: true, uno: 'NumberFormatPercent', disabled: true},
204			{type: 'button',  id: 'numberformatdecdecimals',  img: 'numberformatdecdecimals', hint: _UNO('.uno:NumberFormatDecDecimals', 'spreadsheet', true), hidden: true, uno: 'NumberFormatDecDecimals', disabled: true},
205			{type: 'button',  id: 'numberformatincdecimals',  img: 'numberformatincdecimals', hint: _UNO('.uno:NumberFormatIncDecimals', 'spreadsheet', true), hidden: true, uno: 'NumberFormatIncDecimals', disabled: true},
206			{type: 'break',   id: 'break-number', hidden: true},
207			{type: 'button',  id: 'inserttextbox', img: 'text', hint: _UNO('.uno:Text', '', true), uno: 'Text?CreateDirectly:bool=true', hidden: true},
208			{type: 'button',  id: 'insertannotation', img: 'annotation', hint: _UNO('.uno:InsertAnnotation', '', true), hidden: true},
209			{type: 'drop',  id: 'inserttable',  img: 'inserttable', hint: _('Insert table'), hidden: true, overlay: {onShow: window.insertTable}, html: window.getInsertTablePopupHtml()},
210			{type: 'button',  id: 'insertgraphic',  img: 'insertgraphic', hint: _UNO('.uno:InsertGraphic', '', true)},
211			{type: 'menu', id: 'menugraphic', img: 'insertgraphic', hint: _UNO('.uno:InsertGraphic', '', true), hidden: true,
212				items: [
213					{id: 'localgraphic', text: _('Insert Local Image')},
214					{id: 'remotegraphic', text: _UNO('.uno:InsertGraphic', '', true)},
215				]},
216			{type: 'button',  id: 'insertobjectchart',  img: 'insertobjectchart', hint: _UNO('.uno:InsertObjectChart', '', true), uno: 'InsertObjectChart'},
217			{type: 'drop',  id: 'insertshapes',  img: 'basicshapes_ellipse', hint: _('Insert shapes'), overlay: {onShow: window.insertShapes}, html: window.getShapesPopupHtml()},
218			{type: 'button',  id: 'link',  img: 'link', hint: _UNO('.uno:HyperlinkDialog', '', true), disabled: true},
219			{type: 'button',  id: 'insertsymbol', img: 'insertsymbol', hint: _UNO('.uno:InsertSymbol', '', true), uno: 'InsertSymbol'},
220			{type: 'spacer'},
221			{type: 'button',  id: 'edit',  img: 'edit'},
222			{type: 'button',  id: 'sidebar', img: 'sidebar_modify_page', hint: _UNO('.uno:Sidebar', '', true), uno: '.uno:Sidebar', hidden: true},
223			{type: 'button',  id: 'modifypage', img: 'sidebar_modify_page', hint: _UNO('.uno:ModifyPage', 'presentation', true), uno: '.uno:ModifyPage', hidden: true},
224			{type: 'button',  id: 'slidechangewindow', img: 'sidebar_slide_change', hint: _UNO('.uno:SlideChangeWindow', 'presentation', true), uno: '.uno:SlideChangeWindow', hidden: true},
225			{type: 'button',  id: 'customanimation', img: 'sidebar_custom_animation', hint: _UNO('.uno:CustomAnimation', 'presentation', true), uno: '.uno:CustomAnimation', hidden: true},
226			{type: 'button',  id: 'masterslidespanel', img: 'sidebar_master_slides', hint: _UNO('.uno:MasterSlidesPanel', 'presentation', true), uno: '.uno:MasterSlidesPanel', hidden: true},
227			{type: 'break', id: 'breaksidebar', hidden: true},
228			{type: 'button',  id: 'fold',  img: 'fold', desktop: true, mobile: false, hidden: true},
229			{type: 'button',  id: 'hamburger-tablet',  img: 'hamburger', desktop: false, mobile: false, tablet: true, iosapptablet: false, hidden: true},
230			{type: 'button', id: 'languagecode', desktop: false, mobile: true, tablet: false}
231		];
232	},
233
234	create: function() {
235		var toolbar = $('#toolbar-up');
236		toolbar.w2toolbar({
237			name: 'editbar',
238			items: this.getToolItems(),
239			onClick: function (e) {
240				window.onClick(e, e.target);
241				window.hideTooltip(this, e.target);
242			},
243			onRefresh: function(event) {
244				if ((event.target === 'styles' || event.target === 'fonts' || event.target === 'fontsizes') && event.item) {
245					var toolItem = $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(event.item.id));
246					if ((window.mode.isDesktop() && event.item.desktop == false)
247						|| (window.mode.isTablet() && event.item.tablet == false)) {
248						toolItem.css('display', 'none');
249					} else {
250						toolItem.css('display', '');
251					}
252				}
253
254				if (event.target === 'inserttable')
255					window.insertTable();
256
257				if (event.target === 'insertshapes')
258					window.insertShapes();
259			}
260		});
261		if (window.mode.isDesktop())
262			toolbar.tooltip();
263
264		toolbar.bind('touchstart', function() {
265			w2ui['editbar'].touchStarted = true;
266		});
267	},
268
269	onDocLayerInit: function() {
270		var toolbarUp = w2ui['editbar'];
271		var docType = this.map.getDocType();
272		var data;
273
274		switch (docType) {
275		case 'spreadsheet':
276			if (toolbarUp) {
277				toolbarUp.show('textalign', 'wraptext', 'breakspacing', 'insertannotation', 'conditionalformaticonset',
278				'numberformatcurrency', 'numberformatpercent',
279				'numberformatincdecimals', 'numberformatdecdecimals', 'break-number', 'togglemergecells', 'breakmergecells',
280				'setborderstyle', 'sortascending', 'sortdescending', 'breaksorting', 'backgroundcolor', 'breaksidebar', 'sidebar');
281				toolbarUp.remove('styles');
282			}
283
284			$('#toolbar-wrapper').addClass('spreadsheet');
285			if (window.mode.isTablet()) {
286				$(this.map.options.documentContainer).addClass('tablet');
287				$('#spreadsheet-row-column-frame').addClass('tablet');
288				$('#toolbar-wrapper').addClass('tablet');
289			}
290
291			break;
292		case 'text':
293			if (toolbarUp)
294				toolbarUp.show('leftpara', 'centerpara', 'rightpara', 'justifypara', 'breakpara', 'linespacing',
295				'breakspacing', 'defaultbullet', 'defaultnumbering', 'breakbullet', 'incrementindent', 'decrementindent',
296				'breakindent', 'inserttable', 'insertannotation', 'backcolor', 'breaksidebar', 'sidebar');
297
298			break;
299		case 'presentation':
300			// Fill the style select box if not yet filled
301			if ($('.styles-select')[0] && $('.styles-select')[0].length === 1) {
302				data = [''];
303				// Inserts a separator element
304				data = data.concat({text: '\u2500\u2500\u2500\u2500\u2500\u2500', disabled: true});
305
306				L.Styles.impressLayout.forEach(function(layout) {
307					data = data.concat({id: layout.id, text: _(layout.text)});
308				}, this);
309
310				$('.styles-select').select2({
311					data: data,
312					placeholder: _UNO('.uno:LayoutStatus', 'presentation')
313				});
314				$('.styles-select').on('select2:select', this.onStyleSelect, this);
315			}
316
317			if (toolbarUp) {
318				toolbarUp.show('breaksidebar', 'modifypage');
319			}
320
321			// FALLTHROUGH intended
322		case 'drawing':
323			if (toolbarUp)
324				toolbarUp.show('leftpara', 'centerpara', 'rightpara', 'justifypara', 'breakpara', 'linespacing',
325				'breakspacing', 'defaultbullet', 'defaultnumbering', 'breakbullet', 'inserttextbox', 'inserttable', 'backcolor',
326				'breaksidebar', 'modifypage', 'slidechangewindow', 'customanimation', 'masterslidespanel');
327			break;
328		}
329
330		this._updateVisibilityForToolbar(w2ui['editbar']);
331
332		if (toolbarUp)
333			toolbarUp.refresh();
334
335		data = [6, 7, 8, 9, 10, 10.5, 11, 12, 13, 14, 15, 16, 18, 20,
336			22, 24, 26, 28, 32, 36, 40, 44, 48, 54, 60, 66, 72, 80, 88, 96];
337		$('.fontsizes-select').select2({
338			data: data,
339			placeholder: ' ',
340			//Allow manually entered font size.
341			createTag: function(query) {
342				return {
343					id: query.term,
344					text: query.term,
345					tag: true
346				};
347			},
348			tags: true,
349			sorter: function(data) { return data.sort(function(a, b) {
350				return parseFloat(a.text) - parseFloat(b.text);
351			});}
352		});
353		$('.fontsizes-select').off('select2:select', this.onFontSizeSelect.bind(this)).on('select2:select', this.onFontSizeSelect.bind(this));
354	},
355
356	onUpdatePermission: function(e) {
357		if (e.perm === 'edit') {
358			// Enable list boxes
359			$('.styles-select').prop('disabled', false);
360			$('.fonts-select').prop('disabled', false);
361			$('.fontsizes-select').prop('disabled', false);
362		} else {
363			// Disable list boxes
364			$('.styles-select').prop('disabled', true);
365			$('.fonts-select').prop('disabled', true);
366			$('.fontsizes-select').prop('disabled', true);
367		}
368	},
369
370	onWopiProps: function(e) {
371		if (e.HideSaveOption) {
372			w2ui['editbar'].hide('save');
373		}
374		if (e.HidePrintOption) {
375			w2ui['editbar'].hide('print');
376		}
377
378		// On desktop we only have Save and Print buttons before the first
379		// splitter/break. Hide the splitter if we hid both save and print.
380		// TODO: Apply the same logic to mobile/tablet to avoid beginning with a splitter.
381		if (window.mode.isDesktop() && e.HideSaveOption && e.HidePrintOption) {
382			w2ui['editbar'].hide('savebreak');
383		}
384
385		if (e.EnableInsertRemoteImage === true && w2ui['editbar']) {
386			w2ui['editbar'].hide('insertgraphic');
387			w2ui['editbar'].show('menugraphic');
388		}
389	},
390
391	updateCommandValues: function(e) {
392		var data = [];
393		var commandValues;
394		// 1) For .uno:StyleApply
395		// we need an empty option for the place holder to work
396		if (e.commandName === '.uno:StyleApply') {
397			var styles = [];
398			var topStyles = [];
399			commandValues = this.map.getToolbarCommandValues(e.commandName);
400			if (typeof commandValues === 'undefined')
401				return;
402			var commands = commandValues.Commands;
403			if (commands && commands.length > 0) {
404				// Inserts a separator element
405				data = data.concat({text: '\u2500\u2500\u2500\u2500\u2500\u2500', disabled: true});
406
407				commands.forEach(function (command) {
408					var translated = command.text;
409					if (L.Styles.styleMappings[command.text]) {
410						// if it's in English, translate it
411						translated = L.Styles.styleMappings[command.text].toLocaleString();
412					}
413					data = data.concat({id: command.id, text: translated });
414				}, this);
415			}
416
417			if (this.map.getDocType() === 'text') {
418				styles = commandValues.ParagraphStyles.slice(7, 19);
419				topStyles = commandValues.ParagraphStyles.slice(0, 7);
420			}
421			else if (this.map.getDocType() === 'spreadsheet') {
422				styles = commandValues.CellStyles;
423			}
424			else if (this.map.getDocType() === 'presentation') {
425				// styles are not applied for presentation
426				return;
427			}
428
429			if (topStyles.length > 0) {
430				// Inserts a separator element
431				data = data.concat({text: '\u2500\u2500\u2500\u2500\u2500\u2500', disabled: true});
432
433				topStyles.forEach(function (style) {
434					data = data.concat({id: style, text: L.Styles.styleMappings[style].toLocaleString()});
435				}, this);
436			}
437
438			if (styles !== undefined && styles.length > 0) {
439				// Inserts a separator element
440				data = data.concat({text: '\u2500\u2500\u2500\u2500\u2500\u2500', disabled: true});
441
442				styles.forEach(function (style) {
443					var localeStyle;
444					if (style.startsWith('outline')) {
445						var outlineLevel = style.split('outline')[1];
446						localeStyle = 'Outline'.toLocaleString() + ' ' + outlineLevel;
447					} else {
448						localeStyle = L.Styles.styleMappings[style];
449						localeStyle = localeStyle === undefined ? style : localeStyle.toLocaleString();
450					}
451
452					data = data.concat({id: style, text: localeStyle});
453				}, this);
454			}
455
456			$('.styles-select').select2({
457				data: data,
458				placeholder: _('Style')
459			});
460			$('.styles-select').val(this.options.stylesSelectValue).trigger('change');
461			$('.styles-select').on('select2:select', this.onStyleSelect.bind(this));
462			w2ui['editbar'].resize();
463		} else if (e.commandName === '.uno:CharFontName') {
464			// 2) For .uno:CharFontName
465			commandValues = this.map.getToolbarCommandValues(e.commandName);
466			if (typeof commandValues === 'undefined') {
467				return;
468			}
469
470			data = []; // reset data in order to avoid that the font select box is populated with styles, too.
471			// Old browsers like IE11 et al don't like Object.keys with
472			// empty arguments
473			if (typeof commandValues === 'object') {
474				data = data.concat(Object.keys(commandValues));
475			}
476
477			$('.fonts-select').select2({
478				data: data.sort(function (a, b) {  // also sort(localely)
479					return a.localeCompare(b);
480				}),
481				placeholder: _('Font')
482			});
483			$('.fonts-select').on('select2:select', this.onFontSelect.bind(this));
484			$('.fonts-select').val(this.options.fontsSelectValue).trigger('change');
485			w2ui['editbar'].resize();
486		}
487	},
488
489	onCommandStateChanged: function(e) {
490		var commandName = e.commandName;
491		var state = e.state;
492		var found = false;
493		var value;
494
495		if (commandName === '.uno:StyleApply') {
496			if (!state) {
497				return;
498			}
499
500			// For impress documents, no styles is supported.
501			if (this.map.getDocType() === 'presentation') {
502				return;
503			}
504
505			$('.styles-select option').each(function () {
506				var value = this.value;
507				// For writer we get UI names; ideally we should be getting only programmatic ones
508				// For eg: 'Text body' vs 'Text Body'
509				// (likely to be fixed in core to make the pattern consistent)
510				if (state && value.toLowerCase() === state.toLowerCase()) {
511					state = value;
512					found = true;
513					return;
514				}
515			});
516			if (!found) {
517				// we need to add the size
518				$('.styles-select')
519					.append($('<option></option>')
520					.text(state));
521			}
522
523			this.options.stylesSelectValue = state;
524			$('.styles-select').val(state).trigger('change');
525		}
526		else if (commandName === '.uno:CharFontName') {
527			$('.fonts-select option').each(function () {
528				value = this.value;
529				if (value.toLowerCase() === state.toLowerCase()) {
530					found = true;
531					return;
532				}
533			});
534			if (!found) {
535				// we need to add the size
536				$('.fonts-select')
537					.append($('<option></option>')
538					.text(state));
539			}
540			this.options.fontsSelectValue = state;
541			$('.fonts-select').val(state).trigger('change');
542		}
543		else if (commandName === '.uno:FontHeight') {
544			if (state === '0') {
545				state = '';
546			}
547
548			$('.fontsizes-select option').each(function (i, e) {
549				if ($(e).text() === state) {
550					found = true;
551				}
552			});
553			if (!found) {
554				// we need to add the size
555				$('.fontsizes-select')
556					.append($('<option>')
557					.text(state).val(state));
558			}
559			$('.fontsizes-select').val(state).trigger('change');
560		}
561
562		// call shared handler for font color and highlight items handling
563		window.onCommandStateChanged(e);
564	}
565});
566
567L.control.topToolbar = function () {
568	return new L.Control.TopToolbar();
569};
570