libreoffice-online/loleaflet/dist/toolbar/toolbar.js
Ashod Nakashian 323e2789b9 loleaflet: Allow users to repair at all times
Since during an edit conflict the undo/redo
buttons are dissabled (for the user who can't
undo/redo anymore) disabling the repair button
robs them of the ability to repair the document
to an earlier state (i.e. before the conflict).

This enables the repair button as soon as either
the undo or redo is enabled, whereupon it remains
enabled for the duration of the session.

Change-Id: Ibaf257155f721e2cef596e965d8812d381ab3a5b
Reviewed-on: https://gerrit.libreoffice.org/38942
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2017-06-19 07:25:27 +02:00

1679 lines
54 KiB
JavaScript

/*
* LibreOffice Online toolbar
*/
/* global $ map closebutton w2ui w2utils vex _ */
var mobileWidth = 768;
function onDelete(e) {
if (e !== false) {
map.deletePage();
}
}
// When we are in mobile view, only these items in toolbar-up will be shown
var toolbarUpMobileItems = [
'left',
'save',
'savebreak',
'bold',
'italic',
'underline',
'strikeout',
'formatbreak',
'leftpara',
'centerpara',
'rightpara',
'justifypara',
'right',
'rightmenupadding',
'close'
];
var statusbarMobileItems = [
'search',
'searchprev',
'searchnext',
'cancelsearch',
'left',
'right',
'userlist',
'userlistbreak',
'prev',
'next'
];
var nUsers, oneUser, noUser;
function _mobilify() {
var toolbarUp = w2ui['toolbar-up'];
var toolbarUpMore = w2ui['toolbar-up-more'];
var statusbar = w2ui['toolbar-down'];
for (var itemIdx in toolbarUp.items) {
var id = toolbarUp.items[itemIdx].id;
if (toolbarUpMobileItems.indexOf(id) === -1 && toolbarUp.get(id) && !toolbarUp.get(id).hidden) {
toolbarUp.hide(id);
}
}
for (itemIdx in toolbarUpMore.items) {
id = toolbarUpMore.items[itemIdx].id;
if (toolbarUpMobileItems.indexOf(id) === -1 && toolbarUp.get(id) && !toolbarUp.get(id).hidden) {
toolbarUpMore.hide(id);
}
}
for (itemIdx in statusbar.items) {
id = statusbar.items[itemIdx].id;
if (statusbarMobileItems.indexOf(id) === -1 && !statusbar.get(id).hidden) {
statusbar.hide(id);
}
}
nUsers = '%n';
oneUser = '1';
noUser = '0';
updateUserListCount();
}
function _unmobilify() {
var toolbarUp = w2ui['toolbar-up'];
var toolbarUpMore = w2ui['toolbar-up-more'];
var statusbar = w2ui['toolbar-down'];
for (var itemIdx in toolbarUp.items) {
var id = toolbarUp.items[itemIdx].id;
if (toolbarUpMobileItems.indexOf(id) === -1 && toolbarUp.get(id) && toolbarUp.get(id).hidden) {
toolbarUp.show(id);
}
}
for (itemIdx in toolbarUpMore.items) {
id = toolbarUpMore.items[itemIdx].id;
if (toolbarUpMobileItems.indexOf(id) === -1 && toolbarUpMore.get(id) && toolbarUpMore.get(id).hidden) {
toolbarUpMore.show(id);
}
}
for (itemIdx in statusbar.items) {
id = statusbar.items[itemIdx].id;
if (statusbarMobileItems.indexOf(id) === -1 && statusbar.get(id).hidden) {
statusbar.show(id);
}
}
nUsers = _('%n users');
oneUser = _('1 user');
noUser = _('0 users');
updateUserListCount();
}
function resizeToolbar() {
var hasMoreItems = false;
var toolbarUp = w2ui['toolbar-up'];
var toolbarUpMore = w2ui['toolbar-up-more'];
if ($(window).width() < mobileWidth) {
_mobilify();
} else {
_unmobilify();
}
// move items from toolbar-up-more -> toolbar-up
while ($('#toolbar-up')[0].scrollWidth <= $(window).width()) {
var item = toolbarUpMore.items[0];
if (!item) {
break;
}
toolbarUpMore.items.shift();
toolbarUp.insert('right', item);
}
// move items from toolbar-up -> toolbar-up-more
while ($('#toolbar-up')[0].scrollWidth > Math.max($(window).width(), parseInt($('body').css('min-width')))) {
var itemId = toolbarUp.items[toolbarUp.items.length - 5].id;
item = toolbarUp.get(itemId);
toolbarUp.remove(itemId);
toolbarUpMore.insert(toolbarUpMore.items[0], item);
hasMoreItems = true;
}
if (hasMoreItems) {
w2ui['toolbar-up'].show('more');
}
else {
w2ui['toolbar-up'].hide('more');
}
// resize toolbar-up-more
var lastItem = $('#toolbar-up-more>table>tbody>tr>td[valign="middle"]').last();
if (lastItem.length) {
$('#toolbar-up-more').width($(lastItem).position().left + $(lastItem).width());
w2ui['toolbar-up-more'].render();
} else {
$('#toolbar-up-more').hide();
var toolbar = w2ui['toolbar-up'];
toolbar.uncheck('more');
}
}
function _cancelSearch() {
var toolbar = w2ui['toolbar-down'];
map.resetSelection();
toolbar.hide('cancelsearch');
toolbar.disable('searchprev');
toolbar.disable('searchnext');
L.DomUtil.get('search-input').value = '';
map.focus();
}
function onClick(id, item, subItem) {
if (w2ui['toolbar-up'].get(id) !== null) {
var toolbar = w2ui['toolbar-up'];
var item = toolbar.get(id);
}
else if (w2ui.formulabar.get(id) !== null) {
toolbar = w2ui.formulabar;
item = toolbar.get(id);
}
else if (w2ui['toolbar-down'].get(id) !== null) {
toolbar = w2ui['toolbar-down'];
item = toolbar.get(id);
}
else if (w2ui['spreadsheet-toolbar'].get(id) !== null) {
toolbar = w2ui['spreadsheet-toolbar'];
item = toolbar.get(id);
}
else if (w2ui['presentation-toolbar'].get(id) !== null) {
toolbar = w2ui['presentation-toolbar'];
item = toolbar.get(id);
}
else if (w2ui['toolbar-up-more'].get(id) !== null) {
toolbar = w2ui['toolbar-up-more'];
item = toolbar.get(id);
}
else if (item && subItem)
{
var command = {
'StatusBarFunc': {
type: 'unsigned short',
value: subItem.func
}
};
map.sendUnoCommand('.uno:StatusBarFunc', command);
}
else {
throw new Error('unknown id: ' + id);
}
var docLayer = map._docLayer;
map.focus();
if (item.disabled) {
return;
}
if (item.postmessage && item.type === 'button') {
map.fire('postMessage', {msgId: 'Clicked_Button', args: {Id: item.id} });
}
else if (item.uno) {
if (item.unosheet && map.getDocType() === 'spreadsheet') {
map.toggleCommandState(item.unosheet);
}
else {
map.toggleCommandState(item.uno);
}
}
else if (id === 'save') {
map.save(false /* An explicit save should terminate cell edit */, false /* An explicit save should save it again */);
}
else if (id === 'repair') {
map._socket.sendMessage('commandvalues command=.uno:DocumentRepair');
}
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 === 'prev' || id === 'next') {
if (docLayer._docType === 'text') {
map.goToPage(id);
}
else {
map.setPart(id);
}
}
else if (id === 'searchprev') {
map.search(L.DomUtil.get('search-input').value, true);
}
else if (id === 'searchnext') {
map.search(L.DomUtil.get('search-input').value);
}
else if (id === 'cancelsearch') {
_cancelSearch();
}
else if (id === 'presentation' && map.getDocType() === 'presentation') {
map.fire('fullscreen');
}
else if (id === 'insertannotation') {
map.insertComment();
}
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 page?'),
callback: onDelete
});
}
else if (id === 'firstrecord') {
$('#spreadsheet-tab-scroll').scrollLeft(0);
}
// TODO: We should get visible tab's width instead of 60px
else if (id === 'nextrecord') {
$('#spreadsheet-tab-scroll').scrollLeft($('#spreadsheet-tab-scroll').scrollLeft() + 60);
}
else if (id === 'prevrecord') {
$('#spreadsheet-tab-scroll').scrollLeft($('#spreadsheet-tab-scroll').scrollLeft() - 60);
}
else if (id === 'lastrecord') {
$('#spreadsheet-tab-scroll').scrollLeft($('#spreadsheet-tab-scroll').prop('scrollWidth'));
}
else if (id.startsWith('menu:wrap:wrap-'))
{
var wrapType = id.substring('menu:wrap:wrap-'.length);
map.toggleCommandState(wrapType);
}
else if (id === 'insertgraphic') {
L.DomUtil.get('insertgraphic').click();
}
else if (id === 'inserttable') {
$('#inserttable-popup').toggle();
}
else if (id === 'fontcolor') {
// absolutely no idea why, but without the timeout, the popup is
// closed as soon as it is opend
setTimeout(function () {
$('#fontColorPicker').colorpicker('showPalette');
$('.ui-widget-content').addClass('loleaflet-font');
}, 0);
}
else if (id === 'backcolor') {
// absolutely no idea why, but without the timeout, the popup is
// closed as soon as it is opend
setTimeout(function () {
$('#backColorPicker').colorpicker('showPalette');
$('.ui-widget-content').addClass('loleaflet-font');
}, 0);
}
else if (id === 'sum') {
map.sendUnoCommand('.uno:AutoSum');
}
else if (id === 'function') {
L.DomUtil.get('formulaInput').value = '=';
L.DomUtil.get('formulaInput').focus();
map.cellEnterString(L.DomUtil.get('formulaInput').value);
}
else if (id === 'cancelformula') {
map.sendUnoCommand('.uno:Cancel');
w2ui['formulabar'].hide('acceptformula', 'cancelformula');
w2ui['formulabar'].show('sum', 'function');
}
else if (id === 'acceptformula') {
// focus on map, and press enter
map.focus();
map._docLayer._postKeyboardEvent('input',
map.keyboard.keyCodes.enter,
map.keyboard._toUNOKeyCode(map.keyboard.keyCodes.enter));
w2ui['formulabar'].hide('acceptformula', 'cancelformula');
w2ui['formulabar'].show('sum', 'function');
}
else if (id === 'more') {
$('#toolbar-up-more').toggle();
if ($('#toolbar-up-more').is(':visible')) {
toolbar.check('more');
}
else {
toolbar.uncheck('more');
}
w2ui['toolbar-up-more'].render();
resizeToolbar();
}
else if (id === 'close') {
map.fire('postMessage', {msgId: 'UI_Close', args: {EverModified: map._everModified}});
map.remove();
}
else if (id === 'specialcharacter') {
var fontList = $('.fonts-select option');
var selectedIndex = $('.fonts-select').prop('selectedIndex');
map._docLayer._onSpecialChar(fontList, selectedIndex);
}
}
function insertTable() {
var rows = 10;
var cols = 10;
var $grid = $('.inserttable-grid');
var $popup = $('#inserttable-popup');
var $status = $('#inserttable-status');
// Return if already initialized
if ($grid.children().length) {
return;
}
// init
for (var r = 0; r < rows; r++) {
var $row = $('<div/>').addClass('row');
$grid.append($row);
for (var c = 0; c < cols; c++) {
var $col = $('<div/>').addClass('col');
$row.append($col);
}
}
// events
$grid.on({
mouseover: function () {
var col = $(this).index() + 1;
var row = $(this).parent().index() + 1;
$('.col').removeClass('bright');
$('.row:nth-child(-n+' + row + ') .col:nth-child(-n+' + col + ')')
.addClass('bright');
$status.html(col + 'x' + row);
},
click: function() {
var col = $(this).index() + 1;
var row = $(this).parent().index() + 1;
$popup.toggle();
$('.col').removeClass('bright');
$status.html('<br/>');
var msg = 'uno .uno:InsertTable {' +
' "Columns": { "type": "long","value": '
+ col +
' }, "Rows": { "type": "long","value": '
+ row + ' }}';
map._socket.sendMessage(msg);
// refocus map due popup
map.focus();
}
}, '.col');
// close dialog on mouseleave
$popup.mouseleave(function() {
$(this).hide();
$('.col').removeClass('bright');
$status.html('<br/>');
});
}
function onColorPick(e, color) {
if (map.getPermission() !== 'edit' || color === undefined) {
return;
}
// transform from #FFFFFF to an Int
color = parseInt(color.replace('#', ''), 16);
var command = {};
var fontcolor, backcolor;
if (e.target.id === 'fontColorPicker') {
fontcolor = {'text': 'FontColor',
'spreadsheet': 'Color',
'presentation': 'Color'}[map.getDocType()];
command[fontcolor] = {};
command[fontcolor].type = 'long';
command[fontcolor].value = color;
var uno = '.uno:' + fontcolor;
}
else if (e.target.id === 'backColorPicker') {
backcolor = {'text': 'BackColor',
'spreadsheet': 'BackgroundColor',
'presentation': 'CharBackColor'}[map.getDocType()];
command[backcolor] = {};
command[backcolor].type = 'long';
command[backcolor].value = color;
uno = '.uno:' + backcolor;
}
map.sendUnoCommand(uno, command);
map.focus();
}
var stylesSelectValue;
var fontsSelectValue;
var fontsizesSelectValue;
$(function () {
$('#toolbar-up-more').w2toolbar({
name: 'toolbar-up-more',
items: [
],
onClick: function (e) {
onClick(e.target);
}
});
$('#toolbar-up').w2toolbar({
name: 'toolbar-up',
items: [
{type: 'html', id: 'left'},
{type: 'menu', id: 'writer:menu:wrap', caption: _('Textwrap'), items: [
{ text: _('No wrap'), id: 'wrap-WrapOff' },
{ text: _('Page wrap'), id: 'wrap-WrapOn' },
{ text: _('Wrap anchor only'), id: 'wrap-WrapAnchorOnly' },
{ text: _('Ideal wrap'), id: 'wrap-WrapIdeal' },
{ text: _('Left wrap'), id: 'wrap-WrapLeft' },
{ text: _('Right wrap'), id: 'wrap-WrapRight' },
{ text: _('Wrap through'), id: 'wrap-WrapThrough' }
]},
{type: 'button', id: 'save', img: 'save', hint: _('Save')},
{type: 'break', id: 'savebreak'},
{type: 'button', id: 'undo', img: 'undo', hint: _('Undo'), uno: 'Undo'},
{type: 'button', id: 'redo', img: 'redo', hint: _('Redo'), uno: 'Redo'},
{type: 'button', id: 'repair', img: 'repair', hint: _('Document repair')},
{type: 'break'},
{type: 'html', id: 'styles', html: '<select class="styles-select"></select>'},
{type: 'html', id: 'fonts', html: '<select class="fonts-select"></select>'},
{type: 'html', id: 'fontsizes', html: '<select class="fontsizes-select"></select>'},
{type: 'break'},
{type: 'button', id: 'bold', img: 'bold', hint: _('Bold'), uno: 'Bold'},
{type: 'button', id: 'italic', img: 'italic', hint: _('Italic'), uno: 'Italic'},
{type: 'button', id: 'underline', img: 'underline', hint: _('Underline'), uno: 'Underline'},
{type: 'button', id: 'strikeout', img: 'strikeout', hint: _('Strikeout'), uno: 'Strikeout'},
{type: 'break', id: 'formatbreak'},
{type: 'button', id: 'insertfootnote', img: 'insertfootnote', hint: _('Insert Footnote'), uno: 'InsertFootnote' },
{type: 'break' },
{type: 'html', id: 'fontcolor-html', html: '<div id="fontcolor-wrapper"><input id="fontColorPicker" style="display:none;"></div>'},
{type: 'button', id: 'fontcolor', img: 'color', hint: _('Font color')},
{type: 'html', id: 'backcolor-html', html: '<div id="backcolor-wrapper"><input id="backColorPicker" style="display:none;"></div>'},
{type: 'button', id: 'backcolor', img: 'backcolor', hint: _('Highlighting')},
{type: 'break'},
{type: 'button', id: 'leftpara', img: 'alignleft', hint: _('Align left'), uno: 'LeftPara', unosheet: 'AlignLeft'},
{type: 'button', id: 'centerpara', img: 'alignhorizontal', hint: _('Center horizontally'), uno: 'CenterPara', unosheet: 'AlignHorizontalCenter'},
{type: 'button', id: 'rightpara', img: 'alignright', hint: _('Align right'), uno: 'RightPara', unosheet: 'AlignRight'},
{type: 'button', id: 'justifypara', img: 'alignblock', hint: _('Justified'), uno: 'JustifyPara', unosheet: ''},
{type: 'break', id: 'wraptextseparator'},
{type: 'button', id: 'wraptext', img: 'wraptext', hint: _('Wrap Text'), uno: 'WrapText'},
{type: 'button', id: 'togglemergecells', img: 'togglemergecells', hint: _('Merge and Center Cells'), uno: 'ToggleMergeCells'},
{type: 'break', id: 'break-toggle'},
{type: 'button', id: 'numberformatcurrency', img: 'numberformatcurrency', hint: _('Format as Currency'), uno: 'NumberFormatCurrency'},
{type: 'button', id: 'numberformatpercent', img: 'numberformatpercent', hint: _('Format as Percent'), uno: 'NumberFormatPercent'},
{type: 'button', id: 'numberformatdecimal', img: 'numberformatdecimal', hint: _('Format as Number'), uno: 'NumberFormatDecimal'},
{type: 'button', id: 'numberformatdate', img: 'numberformatdate', hint: _('Format as Date'), uno: 'NumberFormatDate'},
{type: 'button', id: 'numberformatincdecimals', img: 'numberformatincdecimals', hint: _('Add Decimal Place'), uno: 'NumberFormatIncDecimals'},
{type: 'button', id: 'numberformatdecdecimals', img: 'numberformatdecdecimals', hint: _('Delete Decimal Place'), uno: 'NumberFormatDecDecimals'},
{type: 'break', id: 'break-number'},
{type: 'button', id: 'sortascending', img: 'sortascending', hint: _('Sort Ascending'), uno: 'SortAscending'},
{type: 'button', id: 'sortdescending', img: 'sortdescending', hint: _('Sort Descending'), uno: 'SortDescending'},
{type: 'break', id: 'break-align'},
{type: 'button', id: 'defaultbullet', img: 'bullet', hint: _('Bullets on/off'), uno: 'DefaultBullet'},
{type: 'button', id: 'defaultnumbering', img: 'numbering', hint: _('Numbering on/off'), uno: 'DefaultNumbering'},
{type: 'break', id: 'break-numbering'},
{type: 'button', id: 'incrementindent', img: 'incrementindent', hint: _('Increase indent'), uno: 'IncrementIndent'},
{type: 'button', id: 'decrementindent', img: 'decrementindent', hint: _('Decrease indent'), uno: 'DecrementIndent'},
{type: 'break', id: 'incdecindent'},
{type: 'html', id: 'inserttable-html', html: '<div id="inserttable-wrapper"><div id="inserttable-popup" class="inserttable-pop ui-widget ui-widget-content ui-corner-all" style="position: absolute; display: none;"><div class="inserttable-grid"></div><div id="inserttable-status" class="loleaflet-font" style="padding: 5px;"><br/></div></div>'},
{type: 'button', id: 'inserttable', img: 'inserttable', hint: _('Insert table')},
{type: 'button', id: 'insertannotation', img: 'annotation', hint: _('Insert comment')},
{type: 'button', id: 'insertgraphic', img: 'insertgraphic', hint: _('Insert graphic')},
{type: 'button', id: 'specialcharacter', img: 'specialcharacter', hint: _('Special Character')},
{type: 'html', id: 'right'},
{type: 'button', id: 'more', img: 'more', hint: _('More')},
{type: 'html', id: 'rightmenupadding'},
{type: 'button', id: 'close', img: 'closedoc', hint: _('Close document'), hidden: true}
],
onClick: function (e) {
onClick(e.target);
},
onRefresh: function() {
if (!L.DomUtil.get('fontcolorindicator')) {
var fontColorIndicator = L.DomUtil.create('div', 'font-color-indicator', L.DomUtil.get('tb_toolbar-up_item_fontcolor'));
fontColorIndicator.id = 'fontcolorindicator';
L.DomEvent.on(fontColorIndicator, 'mouseover', function () {
var button = fontColorIndicator.parentNode.firstChild;
$(button).addClass('over');
});
L.DomEvent.on(fontColorIndicator, 'mouseout', function () {
var button = fontColorIndicator.parentNode.firstChild;
$(button).removeClass('over');
});
L.DomEvent.on(fontColorIndicator, 'mousedown', function () {
var button = fontColorIndicator.parentNode.firstChild;
$(button).addClass('down');
});
L.DomEvent.on(fontColorIndicator, 'mouseup', function () {
var button = fontColorIndicator.parentNode.firstChild;
$(button).removeClass('down');
});
fontColorIndicator.addEventListener('click', function () {
var toolbar = w2ui['toolbar-up'];
if (toolbar) {
toolbar.click('fontcolor', window.event);
}
}, false);
$('#fontColorPicker').colorpicker({showOn:'none', hideButton:true});
$('#fontColorPicker').on('change.color', onColorPick);
}
if (!L.DomUtil.get('backcolorindicator')) {
var backColorIndicator = L.DomUtil.create('div', 'back-color-indicator', L.DomUtil.get('tb_toolbar-up_item_backcolor'));
backColorIndicator.id = 'backcolorindicator';
L.DomEvent.on(backColorIndicator, 'mouseover', function () {
var button = backColorIndicator.parentNode.firstChild;
$(button).addClass('over');
});
L.DomEvent.on(backColorIndicator, 'mouseout', function () {
var button = backColorIndicator.parentNode.firstChild;
$(button).removeClass('over');
});
L.DomEvent.on(backColorIndicator, 'mousedown', function () {
var button = backColorIndicator.parentNode.firstChild;
$(button).addClass('down');
});
L.DomEvent.on(backColorIndicator, 'mouseup', function () {
var button = backColorIndicator.parentNode.firstChild;
$(button).removeClass('down');
});
backColorIndicator.addEventListener('click', function () {
var toolbar = w2ui['toolbar-up'];
if (toolbar) {
toolbar.click('backcolor', window.event);
}
}, false);
$('#backColorPicker').colorpicker({showOn:'none', hideButton:true});
$('#backColorPicker').on('change.color', onColorPick);
}
if (map.getDocType() === 'presentation') {
// Fill the style select box if not yet filled
if ($('.styles-select')[0] && $('.styles-select')[0].length === 0) {
var data = [''];
// Inserts a separator element
data = data.concat({text: '\u2500\u2500\u2500\u2500\u2500\u2500', disabled: true});
L.Styles.impressLayout.forEach(function(layout) {
data = data.concat({id: layout.id, text: _(layout.text)});
}, this);
$('.styles-select').select2({
data: data,
placeholder: _('Layout')
});
$('.styles-select').on('select2:select', onStyleSelect);
}
}
updateCommandValues();
insertTable();
}
});
$('#formulabar').w2toolbar({
name: 'formulabar',
items: [
{type: 'html', id: 'left'},
{type: 'html', id: 'address', html: '<input id="addressInput" type="text">'},
{type: 'break'},
{type: 'button', id: 'sum', img: 'autosum', hint: _('Sum')},
{type: 'button', id: 'function', img: 'equal', hint: _('Function')},
{type: 'button', hidden: true, id: 'cancelformula', img: 'cancel', hint: _('Cancel')},
{type: 'button', hidden: true, id: 'acceptformula', img: 'accepttrackedchanges', hint: _('Accept')},
{type: 'html', id: 'formula', html: '<input id="formulaInput" type="text">'}
],
onClick: function (e) {
onClick(e.target);
},
onRefresh: function(e) {
$('#addressInput').off('keyup', onAddressInput).on('keyup', onAddressInput);
$('#formulaInput').off('keyup', onFormulaInput).on('keyup', onFormulaInput);
$('#formulaInput').off('blur', onFormulaBarBlur).on('blur', onFormulaBarBlur);
$('#formulaInput').off('focus', onFormulaBarFocus).on('focus', onFormulaBarFocus);
}
});
$('#spreadsheet-toolbar').w2toolbar({
name: 'spreadsheet-toolbar',
items: [
{type: 'button', id: 'firstrecord', img: 'firstrecord', hidden: true, hint: _('First sheet')},
{type: 'button', id: 'prevrecord', img: 'prevrecord', hidden: true, hint: _('Previous sheet')},
{type: 'button', id: 'nextrecord', img: 'nextrecord', hidden: true, hint: _('Next sheet')},
{type: 'button', id: 'lastrecord', img: 'lastrecord', hidden: true, hint: _('Last sheet')}
],
onClick: function (e) {
onClick(e.target);
}
});
$('#presentation-toolbar').w2toolbar({
name: 'presentation-toolbar',
items: [
{type: 'html', id: 'left'},
{type: 'button', id: 'presentation', img: 'presentation', hidden:true, hint: _('Fullscreen presentation')},
{type: 'break', id: 'presentationbreak', hidden:true},
{type: 'button', id: 'insertpage', img: 'insertpage', hidden:true, hint: _('Insert slide')},
{type: 'button', id: 'duplicatepage', img: 'duplicatepage', hidden:true, hint: _('Duplicate slide')},
{type: 'button', id: 'deletepage', img: 'deletepage', hidden:true, hint: _('Delete slide')},
{type: 'html', id: 'right'}
],
onClick: function (e) {
onClick(e.target);
}
});
$('#toolbar-down').w2toolbar({
name: 'toolbar-down',
items: [
{type: 'html', id: 'search',
html: '<div style="padding: 3px 10px;" class="loleaflet-font">' +
' ' + _('Search:') +
' <input size="10" id="search-input"' +
'style="padding: 3px; border-radius: 2px; border: 1px solid silver"/>' +
'</div>'
},
{type: 'button', id: 'searchprev', img: 'prev', hint: _('Search backwards'), disabled: true},
{type: 'button', id: 'searchnext', img: 'next', hint: _('Search forward'), disabled: true},
{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" class="loleaflet-font"></div>'},
{type: 'break', id: 'modifiedstatuslabelbreak'},
{type: 'drop', id: 'userlist', text: _('No users'), html: '<div id="userlist_container"><table id="userlist_table"><tbody></tbody></table></div>' },
{type: 'break', id: 'userlistbreak'},
{type: 'button', id: 'prev', img: 'prev', hint: _('Previous page')},
{type: 'button', id: 'next', img: 'next', hint: _('Next page')},
{type: 'break', id: 'prevnextbreak'},
{type: 'button', id: 'zoomreset', img: 'zoomreset', hint: _('Reset zoom')},
{type: 'button', id: 'zoomout', img: 'zoomout', hint: _('Zoom out')},
{type: 'html', id: 'zoomlevel', html: '<div id="zoomlevel" class="loleaflet-font">100%</div>'},
{type: 'button', id: 'zoomin', img: 'zoomin', hint: _('Zoom in')}
],
onClick: function (e) {
if (e.item.id === 'userlist') {
return;
}
onClick(e.target, e.item, e.subItem);
},
onRefresh: function(e) {
$('#tb_toolbar-down_item_userlist .w2ui-tb-caption').addClass('loleaflet-font');
$('#search-input').off('input', onSearch).on('input', onSearch);
$('#search-input').off('keypress', onSearchKeyPress).on('keypress', onSearchKeyPress);
}
});
});
var userJoinedPopupMessage = '<div>' + _('%user has joined') + '</div>';
var userLeftPopupMessage = '<div>' + _('%user has left') + '</div>';
var userPopupTimeout = null;
function toLocalePattern (pattern, regex, text, sub1, sub2) {
var matches = new RegExp(regex, 'g').exec(text);
if (matches) {
text = pattern.toLocaleString().replace(sub1, parseInt(matches[1].replace(',','')).toLocaleString(String.locale)).replace(sub2, parseInt(matches[2].replace(',','')).toLocaleString(String.locale));
}
return text;
}
function unoCmdToToolbarId(commandname)
{
var id = commandname.toLowerCase().substr(5);
if (map.getDocType() === 'spreadsheet') {
switch (id) {
case 'alignleft':
id = 'leftpara';
break;
case 'alignhorizontalcenter':
id = 'centerpara';
break;
case 'alignright':
id = 'rightpara';
break;
}
}
return id;
}
function selectItem(item, func)
{
var index = -1;
for (var it = 0; it < item.items.length; it++) {
if (item.items[it].func === func) {
index = it;
break;
}
}
if (index !== -1) {
item.items[item.current].icon = '';
item.items[index].icon = 'selected';
item.current = index;
}
}
function onSearch(e) {
var toolbar = w2ui['toolbar-down'];
map.search(L.DomUtil.get('search-input').value, false, '', 0, true /* expand search */);
toolbar.enable('searchprev');
toolbar.enable('searchnext');
toolbar.show('cancelsearch');
}
function onSearchKeyPress(e) {
if (e.keyCode === 13) { // Enter key
if (e.shiftKey) {
// search backwards
map.search(L.DomUtil.get('search-input').value, true);
} else {
map.search(L.DomUtil.get('search-input').value);
}
} else if (e.keyCode === 27) { // Escape key
_cancelSearch();
}
}
function sortFontSizes() {
var oldVal = $('.fontsizes-select').val();
var selectList = $('.fontsizes-select option');
selectList.sort(function (a, b) {
a = parseFloat($(a).text() * 1);
b = parseFloat($(b).text() * 1);
if (a > b) {
return 1;
} else if (a < b) {
return -1;
}
return 0;
});
$('.fontsizes-select').html(selectList);
$('.fontsizes-select').val(oldVal).trigger('change');
}
function onStyleSelect(e) {
var style = e.target.value;
if (style.startsWith('.uno:')) {
map.sendUnoCommand(style);
}
else if (map.getDocType() === 'text') {
map.applyStyle(style, 'ParagraphStyles');
}
else if (map.getDocType() === 'spreadsheet') {
map.applyStyle(style, 'CellStyles');
}
else if (map.getDocType() === 'presentation' || map.getDocType() === 'drawing') {
map.applyLayout(style);
}
map.focus();
}
function updateFontSizeList(font) {
var oldSize = $('.fontsizes-select').val();
var found = false;
$('.fontsizes-select').find('option').remove();
var data = [''];
data = data.concat(map.getToolbarCommandValues('.uno:CharFontName')[font]);
$('.fontsizes-select').select2({
data: data,
placeholder: _('Size'),
//Allow manually entered font size.
createTag: function(query) {
return {
id: query.term,
text: query.term,
tag: true
};
},
tags: true
});
$('.fontsizes-select option').each(function (i, e) {
if ($(e).text() === oldSize) {
$('.fontsizes-select').val(oldSize).trigger('change');
found = true;
return;
}
});
if (!found) {
// we need to add the size
$('.fontsizes-select')
.append($('<option></option>')
.text(oldSize));
}
$('.fontsizes-select').val(oldSize).trigger('change');
sortFontSizes();
}
function onFontSelect(e) {
var font = e.target.value;
updateFontSizeList(font);
map.applyFont(font);
map.focus();
}
function onFontSizeSelect(e) {
var size = e.target.value;
var command = {};
$(e.target).find('option[data-select2-tag]').removeAttr('data-select2-tag');
map.applyFontSize(size);
var fontcolor = map.getDocType() === 'text' ? 'FontColor' : 'Color';
command[fontcolor] = {};
map.focus();
}
function onInsertFile() {
var insertGraphic = L.DomUtil.get('insertgraphic');
if ('files' in insertGraphic) {
for (var i = 0; i < insertGraphic.files.length; i++) {
var file = insertGraphic.files[i];
map.insertFile(file);
}
}
// Set the value to null everytime so that onchange event is triggered,
// even if the same file is selected
insertGraphic.value = null;
return false;
}
function onAddressInput(e) {
if (e.keyCode === 13) {
// address control should not have focus anymore
map.focus();
var value = L.DomUtil.get('addressInput').value;
var command = {
ToPoint : {
type: 'string',
value: value
}
};
map.sendUnoCommand('.uno:GoToCell', command);
} else if (e.keyCode === 27) { // 27 = esc key
map.sendUnoCommand('.uno:Cancel');
map.focus();
}
}
function onFormulaInput(e) {
// keycode = 13 is 'enter'
if (e.keyCode === 13) {
// formula bar should not have focus anymore
map.focus();
// forward the 'enter' keystroke to map to deal with the formula entered
var data = {
originalEvent: e
};
map.fire('keypress', data);
} else if (e.keyCode === 27) { // 27 = esc key
map.sendUnoCommand('.uno:Cancel');
map.focus();
} else {
map.cellEnterString(L.DomUtil.get('formulaInput').value);
}
}
function onFormulaBarFocus() {
var formulabar = w2ui.formulabar;
formulabar.hide('sum');
formulabar.hide('function');
formulabar.show('cancelformula');
formulabar.show('acceptformula');
}
function onFormulaBarBlur() {
// The timeout is needed because we want 'click' event on 'cancel',
// 'accept' button to act before we hide these buttons because
// once hidden, click event won't be processed.
// TODO: Some better way to do it ?
setTimeout(function() {
var formulabar = w2ui.formulabar;
formulabar.show('sum');
formulabar.show('function');
formulabar.hide('cancelformula');
formulabar.hide('acceptformula');
}, 250);
}
map.on('hidebusy', function() {
// If locked, unlock
if (w2ui['toolbar-down'].box.firstChild.className === 'w2ui-lock') {
w2utils.unlock(w2ui['toolbar-down'].box);
}
});
map.on('showbusy', function(e) {
w2utils.lock(w2ui['toolbar-down'].box, e.label, true);
});
map.on('wopiprops', function(e) {
if (e.HideSaveOption) {
w2ui['toolbar-up'].hide('save');
}
});
map.on('doclayerinit', function () {
var toolbarUp = w2ui['toolbar-up'];
var toolbarUpMore = w2ui['toolbar-up-more'];
var statusbar = w2ui['toolbar-down'];
var docType = map.getDocType();
switch (docType) {
case 'spreadsheet':
toolbarUp.remove('inserttable', 'styles', 'justifypara', 'defaultbullet', 'defaultnumbering', 'break-numbering');
toolbarUpMore.remove('inserttable', 'styles', 'justifypara', 'defaultbullet', 'defaultnumbering', 'break-numbering');
statusbar.disable('zoomreset', 'zoomout', 'zoomin', 'zoomlevel');
statusbar.insert('left', [
{type: 'break', id:'break1'},
{type: 'html', id: 'StatusDocPos',
html: '<div id="StatusDocPos" class="loleaflet-font" title="'+_('Number of Sheets')+ '" style="padding: 5px 5px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp</div>' },
{type: 'break', id:'break2'},
{type: 'html', id: 'RowColSelCount',
html: '<div id="RowColSelCount" class="loleaflet-font" title="'+_('Selected range of cells')+ '" style="padding: 5px 5px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp</div>' },
{type: 'break', id:'break3'},
{type: 'html', id: 'InsertMode',
html: '<div id="InsertMode" class="loleaflet-font" title="'+_('Entering text mode')+ '" style="padding: 5px 5px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp</div>' },
{type: 'break', id:'break5'},
{type: 'html', id: 'StatusSelectionMode',
html: '<div id="StatusSelectionMode" class="loleaflet-font" title="'+_('Selection Mode')+ '" style="padding: 5px 5px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp</div>' },
{type: 'break', id:'break8'},
{type: 'html', id: 'StateTableCell',
html: '<div id="StateTableCell" class="loleaflet-font" title="'+_('Choice of functions')+ '" style="padding: 5px 5px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp</div>' },
{type: 'menu', id: 'StateTableCellMenu', caption: '', current: 7, items: [
{ func: '1', text: _('Average'), icon: ''},
{ func: '3', text: _('CountA'), icon: ''},
{ func: '2', text: _('Count'), icon: ''},
{ func: '4', text: _('Maximum'), icon: ''},
{ func: '5', text: _('Minimum'), icon: ''},
{ func: '9', text: _('Sum'), icon: ''},
{ func: '12', text: _('Selection count'), icon: ''},
{ func: '16', text: _('None'), icon: 'selected'},
]},
]);
// Remove irrelevant toolbars
$('#presentation-toolbar').hide();
break;
case 'text':
toolbarUp.remove('wraptextseparator', 'wraptext', 'togglemergecells', 'break-toggle', 'numberformatcurrency', 'numberformatpercent', 'numberformatdecimal', 'numberformatdate', 'numberformatincdecimals', 'numberformatdecdecimals', 'break-number', 'sortascending', 'sortdescending');
toolbarUpMore.remove('wraptextseparator', 'wraptext', 'togglemergecells', 'break-toggle', 'numberformatcurrency', 'numberformatpercent', 'numberformatdecimal', 'numberformatdate', 'numberformatincdecimals', 'numberformatdecdecimals', 'break-number', 'sortascending', 'sortdescending');
statusbar.insert('left', [
{type: 'break', id:'break1'},
{type: 'html', id: 'StatePageNumber',
html: '<div id="StatePageNumber" class="loleaflet-font" title="'+_('Number of Pages')+ '" style="padding: 5px 5px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp</div>' },
{type: 'break', id:'break2'},
{type: 'html', id: 'StateWordCount',
html: '<div id="StateWordCount" class="loleaflet-font" title="'+_('Word Counter')+ '" style="padding: 5px 5px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp</div>' },
{type: 'break', id:'break5'},
{type: 'html', id: 'InsertMode',
html: '<div id="InsertMode" class="loleaflet-font" title="'+_('Entering text mode')+ '" style="padding: 5px 5px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp</div>' },
{type: 'break', id:'break6'},
{type: 'html', id: 'SelectionMode',
html: '<div id="StatusSelectionMode" class="loleaflet-font" title="'+_('Selection Mode')+ '" style="padding: 5px 5px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp</div>' },
]);
// Remove irrelevant toolbars
$('#formulabar').hide();
$('#spreadsheet-toolbar').hide();
$('#presentation-toolbar').hide();
break;
case 'presentation':
var presentationToolbar = w2ui['presentation-toolbar'];
presentationToolbar.show('presentation', 'presentationbreak', 'insertpage', 'duplicatepage', 'deletepage');
toolbarUp.remove('insertannotation', 'wraptextseparator', 'wraptext', 'togglemergecells', 'break-toggle', 'numberformatcurrency', 'numberformatpercent', 'numberformatdecimal', 'numberformatdate', 'numberformatincdecimals', 'numberformatdecdecimals', 'break-number', 'sortascending', 'sortdescending');
toolbarUpMore.remove('insertannotation', 'wraptextseparator', 'wraptext', 'togglemergecells', 'break-toggle', 'numberformatcurrency', 'numberformatpercent', 'numberformatdecimal', 'numberformatdate', 'numberformatincdecimals', 'numberformatdecdecimals', 'break-number', 'sortascending', 'sortdescending');
statusbar.insert('left', [
{type: 'break', id:'break1'},
{type: 'html', id: 'PageStatus',
html: '<div id="PageStatus" class="loleaflet-font" title="'+_('Number of Slides')+ '" style="padding: 5px 5px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp</div>' },
]);
// Remove irrelevant toolbars
$('#formulabar').hide();
$('#spreadsheet-toolbar').hide();
break;
case 'drawing':
toolbarUp.remove('insertannotation', 'wraptextseparator', 'wraptext', 'togglemergecells', 'break-toggle', 'numberformatcurrency', 'numberformatpercent', 'numberformatdecimal', 'numberformatdate', 'numberformatincdecimals', 'numberformatdecdecimals', 'break-number', 'sortascending', 'sortdescending');
toolbarUpMore.remove('insertannotation', 'wraptextseparator', 'wraptext', 'togglemergecells', 'break-toggle', 'numberformatcurrency', 'numberformatpercent', 'numberformatdecimal', 'numberformatdate', 'numberformatincdecimals', 'numberformatdecdecimals', 'break-number', 'sortascending', 'sortdescending');
// Remove irrelevant toolbars
$('#formulabar').hide();
$('#spreadsheet-toolbar').hide();
break;
}
toolbarUp.refresh();
toolbarUpMore.refresh();
statusbar.refresh();
resizeToolbar();
});
map.on('commandstatechanged', function (e) {
var toolbar = w2ui['toolbar-up'];
var toolbarUpMore = w2ui['toolbar-up-more'];
var statusbar = w2ui['toolbar-down'];
var commandName = e.commandName;
var state = e.state;
var found = false;
var value, color, div;
var matches;
if (commandName === '.uno:AssignLayout') {
$('.styles-select').val(state).trigger('change');
} else if (commandName === '.uno:StyleApply') {
if (!state) {
return;
}
// For impress documents, no styles is supported.
if (map.getDocType() === 'presentation') {
return;
}
$('.styles-select option').each(function () {
var value = this.value;
// For writer we get UI names; ideally we should be getting only programmatic ones
// For eg: 'Text body' vs 'Text Body'
// (likely to be fixed in core to make the pattern consistent)
if (state && value.toLowerCase() === state.toLowerCase()) {
state = value;
found = true;
return;
}
});
if (!found) {
// we need to add the size
$('.styles-select')
.append($('<option></option>')
.text(state));
}
stylesSelectValue = state;
$('.styles-select').val(state).trigger('change');
}
else if (commandName === '.uno:CharFontName') {
$('.fonts-select option').each(function () {
value = this.value;
if (value.toLowerCase() === state.toLowerCase()) {
found = true;
updateFontSizeList(value);
return;
}
});
if (!found) {
// we need to add the size
$('.fonts-select')
.append($('<option></option>')
.text(state));
}
fontsSelectValue = state;
$('.fonts-select').val(state).trigger('change');
}
else if (commandName === '.uno:FontHeight') {
if (state === '0') {
state = '';
}
$('.fontsizes-select option').each(function (i, e) {
if ($(e).text() === state) {
found = true;
return;
}
});
if (!found) {
// we need to add the size
$('.fontsizes-select')
.append($('<option></option>')
.text(state).val(state));
}
fontsizesSelectValue = state;
$('.fontsizes-select').val(state).trigger('change');
sortFontSizes();
}
else if (commandName === '.uno:FontColor' || commandName === '.uno:Color') {
// confusingly, the .uno: command is named differently in Writer, Calc and Impress
color = parseInt(e.state);
if (color === -1) {
color = 'transparent';
}
else {
color = color.toString(16);
color = '#' + Array(7 - color.length).join('0') + color;
}
div = L.DomUtil.get('fontcolorindicator');
if (div) {
L.DomUtil.setStyle(div, 'background', color);
}
}
else if (commandName === '.uno:BackColor' || commandName === '.uno:BackgroundColor' || commandName === '.uno:CharBackColor') {
// confusingly, the .uno: command is named differently in Writer, Calc and Impress
color = parseInt(e.state);
if (color === -1) {
color = 'transparent';
}
else {
color = color.toString(16);
color = '#' + Array(7 - color.length).join('0') + color;
}
div = L.DomUtil.get('backcolorindicator');
if (div) {
L.DomUtil.setStyle(div, 'background', color);
}
}
else if (commandName === '.uno:ModifiedStatus') {
var modifiedStatus = e.state === 'true';
if (modifiedStatus) {
$('#modifiedstatuslabel').html('');
}
else {
$('#modifiedstatuslabel').html(_('Document saved'));
}
}
else if (commandName === '.uno:StatusDocPos') {
state = toLocalePattern('Sheet %1 of %2', 'Sheet (\\d+) of (\\d+)', state, '%1', '%2');
$('#StatusDocPos').html(state ? state : '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp');
}
else if (commandName === '.uno:RowColSelCount') {
state = toLocalePattern('$1 rows, $2 columns selected', '(\\d+) rows, (\\d+) columns selected', state, '$1', '$2');
$('#RowColSelCount').html(state ? state : '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp');
}
else if (commandName === '.uno:InsertMode') {
$('#InsertMode').html(state ? L.Styles.insertMode[state].toLocaleString() : '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp');
}
else if (commandName === '.uno:StatusSelectionMode' ||
commandName === '.uno:SelectionMode') {
$('#StatusSelectionMode').html(state ? L.Styles.selectionMode[state].toLocaleString() : '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp');
}
else if (commandName == '.uno:StateTableCell') {
$('#StateTableCell').html(state ? state : '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp');
}
else if (commandName === '.uno:StatusBarFunc') {
if (state) {
selectItem(statusbar.get('StateTableCellMenu'), state);
}
}
else if (commandName === '.uno:StatePageNumber') {
state = toLocalePattern('Page %1 of %2', 'Page (\\d+) of (\\d+)', state, '%1', '%2');
$('#StatePageNumber').html(state ? state : '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp');
}
else if (commandName === '.uno:StateWordCount') {
state = toLocalePattern('%1 words, %2 characters', '([\\d,]+) words, ([\\d,]+) characters', state, '%1', '%2');
$('#StateWordCount').html(state ? state : '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp');
}
else if (commandName === '.uno:PageStatus') {
state = toLocalePattern('Slide %1 of %2', 'Slide (\\d+) of (\\d+)', state, '%1', '%2');
$('#PageStatus').html(state ? state : '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp');
}
var id = unoCmdToToolbarId(commandName);
if (state === 'true') {
toolbar.enable(id);
toolbar.check(id);
toolbarUpMore.check(id);
}
else if (state === 'false') {
toolbar.enable(id);
toolbar.uncheck(id);
toolbarUpMore.uncheck(id);
}
// Change the toolbar button states if we are in editmode
// If in non-edit mode, will be taken care of when permission is changed to 'edit'
else if (map._permission === 'edit' && (state === 'enabled' || state === 'disabled')) {
// in case some buttons are in toolbar-up-more, find
// them and en/dis-able them.
if (state === 'enabled') {
toolbar.enable(id);
toolbarUpMore.enable(id);
} else {
toolbar.uncheck(id);
toolbar.disable(id);
toolbarUpMore.disable(id);
}
}
if (id === 'undo' || id === 'redo') {
if (!toolbar.get('undo').disabled || !toolbar.get('redo').disabled) {
toolbar.enable('repair');
}
}
});
map.on('search', function (e) {
var searchInput = L.DomUtil.get('search-input');
var toolbar = w2ui['toolbar-down'];
if (e.count === 0) {
toolbar.disable('searchprev');
toolbar.disable('searchnext');
toolbar.hide('cancelsearch');
L.DomUtil.addClass(searchInput, 'search-not-found');
$('#findthis').addClass('search-not-found');
map.resetSelection();
setTimeout(function () {
$('#findthis').removeClass('search-not-found');
L.DomUtil.removeClass(searchInput, 'search-not-found');
}, 500);
}
});
function updateCommandValues() {
var data = [];
// 1) For .uno:StyleApply
// we need an empty option for the place holder to work
if ($('.styles-select option').length === 0) {
var styles = [];
var topStyles = [];
var commandValues = map.getToolbarCommandValues('.uno:StyleApply');
if (typeof commandValues === 'undefined')
return;
var commands = commandValues.Commands;
if (commands && commands.length > 0) {
// Inserts a separator element
data = data.concat({text: '\u2500\u2500\u2500\u2500\u2500\u2500', disabled: true});
commands.forEach(function (command) {
data = data.concat({id: command.id, text: L.Styles.styleMappings[command.text].toLocaleString()});
}, this);
}
if (map.getDocType() === 'text') {
styles = commandValues.ParagraphStyles.slice(7, 19);
topStyles = commandValues.ParagraphStyles.slice(0, 7);
}
else if (map.getDocType() === 'spreadsheet') {
styles = commandValues.CellStyles;
}
else if (map.getDocType() === 'presentation') {
// styles are not applied for presentation
return;
}
if (topStyles.length > 0) {
// Inserts a separator element
data = data.concat({text: '\u2500\u2500\u2500\u2500\u2500\u2500', disabled: true});
topStyles.forEach(function (style) {
data = data.concat({id: style, text: L.Styles.styleMappings[style].toLocaleString()});
}, this);
}
if (styles !== undefined && styles.length > 0) {
// Inserts a separator element
data = data.concat({text: '\u2500\u2500\u2500\u2500\u2500\u2500', disabled: true});
styles.forEach(function (style) {
var localeStyle;
if (style.startsWith('outline')) {
var outlineLevel = style.split('outline')[1];
localeStyle = 'Outline'.toLocaleString() + ' ' + outlineLevel;
} else {
localeStyle = L.Styles.styleMappings[style];
localeStyle = localeStyle === undefined ? style : localeStyle.toLocaleString();
}
data = data.concat({id: style, text: localeStyle});
}, this);
}
$('.styles-select').select2({
data: data,
placeholder: _('Style')
});
$('.styles-select').val(stylesSelectValue).trigger('change');
$('.styles-select').on('select2:select', onStyleSelect);
}
if ($('.fonts-select option').length === 0) {
// 2) For .uno:CharFontName
commandValues = map.getToolbarCommandValues('.uno:CharFontName');
if (typeof commandValues === 'undefined') {
return;
}
data = []; // reset data in order to avoid that the font select box is populated with styles, too.
// Old browsers like IE11 et al don't like Object.keys with
// empty arguments
if (typeof commandValues === 'object') {
data = data.concat(Object.keys(commandValues));
}
$('.fonts-select').select2({
data: data,
placeholder: _('Font')
});
$('.fonts-select').on('select2:select', onFontSelect);
$('.fonts-select').val(fontsSelectValue).trigger('change');
}
if ($('.fontsizes-select option').length === 0) {
$('.fontsizes-select').select2({
placeholder: _('Size'),
data: []
});
$('.fontsizes-select').on('select2:select', onFontSizeSelect);
if (fontsSelectValue) {
updateFontSizeList(fontsSelectValue);
}
$('.fontsizes-select').val(fontsizesSelectValue).trigger('change');
}
}
map.on('updatetoolbarcommandvalues', function(e) {
w2ui['toolbar-up'].refresh();
});
map.on('updateparts pagenumberchanged', function (e) {
if (e.docType === 'text') {
var current = e.currentPage;
var count = e.pages;
}
else {
current = e.selectedPart;
count = e.parts;
}
var toolbar = w2ui['toolbar-down'];
if (e.docType === 'presentation') {
toolbar.set('prev', {hint: _('Previous slide')});
toolbar.set('next', {hint: _('Next slide')});
}
else {
toolbar.hide('presentation');
toolbar.hide('insertpage');
toolbar.hide('duplicatepage');
toolbar.hide('deletepage');
}
if (e.docType !== 'spreadsheet') {
if (current === 0) {
toolbar.disable('prev');
}
else {
toolbar.enable('prev');
}
if (current === count - 1) {
toolbar.disable('next');
}
else {
toolbar.enable('next');
}
}
toolbar = w2ui['toolbar-up'];
if (e.docType !== 'text' && e.docType !== 'spreadsheet') {
toolbar.hide('incrementindent');
toolbar.hide('decrementindent');
toolbar.hide('incdecindent');
}
toolbar = w2ui['spreadsheet-toolbar'];
if (e.docType === 'spreadsheet') {
toolbar.show('firstrecord');
toolbar.show('nextrecord');
toolbar.show('prevrecord');
toolbar.show('lastrecord');
}
});
map.on('commandresult', function (e) {
var commandName = e.commandName;
if (commandName === '.uno:Save') {
if (e.success) {
// Saved a new version; the document is modified.
map._everModified = true;
}
var postMessageObj = {
success: e.success
};
if (!e.success) {
// add the result reason string if failed
postMessageObj['result'] = e.result && e.result.value;
}
map.fire('postMessage', {msgId: 'Action_Save_Resp', args: postMessageObj});
}
else if ((commandName === '.uno:Undo' || commandName === '.uno:Redo') &&
e.success === true && e.result.value && !isNaN(e.result.value)) { /*UNDO_CONFLICT*/
$('#tb_toolbar-up_item_repair').w2overlay({ html: '<div style="padding: 10px; line-height: 150%">' +
_('Conflict Undo/Redo with multiple users. Please use document repair to resolve') + '</div>'});
}
});
map.on('celladdress', function (e) {
if (document.activeElement !== L.DomUtil.get('addressInput')) {
// if the user is not editing the address field
L.DomUtil.get('addressInput').value = e.address;
}
});
map.on('cellformula', function (e) {
if (document.activeElement !== L.DomUtil.get('formulaInput')) {
// if the user is not editing the formula bar
L.DomUtil.get('formulaInput').value = e.formula;
}
});
map.on('zoomend', function () {
var zoomRatio = map.getZoomScale(map.getZoom(), map.options.zoom);
var zoomPercent = Math.round(zoomRatio * 100);
$('#zoomlevel').html(zoomPercent + '%');
});
map.on('hyperlinkclicked', function (e) {
window.open(e.url, '_blank');
});
map.on('updatepermission', function (e) {
var toolbar = w2ui['toolbar-up'];
var toolbarUpMore = w2ui['toolbar-up-more'];
// copy the first array
var items = toolbar.items.slice();
items.concat(toolbarUpMore.items);
for (var idx in items) {
var unoCmd = map.getDocType() === 'spreadsheet' ? items[idx].unosheet : items[idx].uno;
var keepDisabled = map['stateChangeHandler'].getItemValue(unoCmd) === 'disabled';
if (e.perm === 'edit') {
if (!keepDisabled) {
toolbar.enable(items[idx].id);
toolbarUpMore.enable(items[idx].id);
}
} else {
toolbar.disable(items[idx].id);
toolbarUpMore.disable(items[idx].id);
}
}
var spreadsheetButtons = ['firstrecord', 'prevrecord', 'nextrecord', 'lastrecord'];
var formulaBarButtons = ['sum', 'function'];
var presentationButtons = ['insertpage', 'duplicatepage', 'deletepage'];
var toolbarDownButtons = ['next', 'prev'];
if (e.perm === 'edit') {
// Enable list boxes
$('.styles-select').prop('disabled', false);
$('.fonts-select').prop('disabled', false);
$('.fontsizes-select').prop('disabled', false);
// Enable formula bar
$('#addressInput').prop('disabled', false);
$('#formulaInput').prop('disabled', false);
toolbar = w2ui.formulabar;
formulaBarButtons.forEach(function(id) {
toolbar.enable(id);
});
toolbar = w2ui['spreadsheet-toolbar'];
spreadsheetButtons.forEach(function(id) {
toolbar.enable(id);
});
toolbar = w2ui['presentation-toolbar'];
presentationButtons.forEach(function(id) {
toolbar.enable(id);
});
toolbar = w2ui['toolbar-down'];
toolbarDownButtons.forEach(function(id) {
toolbar.enable(id);
});
$('#search-input').prop('disabled', false);
}
else {
// Disable list boxes
$('.styles-select').prop('disabled', true);
$('.fonts-select').prop('disabled', true);
$('.fontsizes-select').prop('disabled', true);
// Disable formula bar
$('#addressInput').prop('disabled', true);
$('#formulaInput').prop('disabled', true);
toolbar = w2ui.formulabar;
formulaBarButtons.forEach(function(id) {
toolbar.disable(id);
});
toolbar = w2ui['spreadsheet-toolbar'];
spreadsheetButtons.forEach(function(id) {
toolbar.disable(id);
});
toolbar = w2ui['presentation-toolbar'];
presentationButtons.forEach(function(id) {
toolbar.disable(id);
});
toolbar = w2ui['toolbar-down'];
toolbarDownButtons.forEach(function(id) {
toolbar.disable(id);
});
$('#search-input').prop('disabled', true);
}
});
map.on('keydown', function (e) {
if (e.originalEvent.ctrlKey && !e.originalEvent.altKey &&
(e.originalEvent.key === 'f' || e.originalEvent.key === 'F')) {
L.DomUtil.get('search-input').focus();
e.originalEvent.preventDefault();
}
});
function onUseritemClicked(e) {
var viewId = parseInt(e.currentTarget.id.replace('user-', ''));
if (map._docLayer) {
if (map.getDocType() === 'spreadsheet') {
map._docLayer.goToCellViewCursor(viewId);
} else if (map.getDocType() === 'text') {
map._docLayer.goToViewCursor(viewId);
}
}
}
function getUserItem(viewId, userName, extraInfo, color) {
var className = 'useritem';
if (extraInfo !== undefined && extraInfo.avatar !== undefined) {
className = 'useritem-avatar';
}
var html = '<tr class="' + className + '" id="user-' + viewId + '" onclick="onUseritemClicked(event)">' +
'<td class=usercolor style="background-color: ' + color +';">';
if (extraInfo !== undefined && extraInfo.avatar !== undefined) {
html += '<img src="' + extraInfo.avatar + '" width="32" height="32" />'
}
// TODO: Add mail and other links as sub-menu.
html += '</td>' +
'<td class="username loleaflet-font" >' + userName + '</td>' +
'</tr>';
return html;
}
function updateUserListCount() {
var userlistItem = w2ui['toolbar-down'].get('userlist');
var count = $(userlistItem.html).find('#userlist_table tbody tr').length;
if (count > 1) {
userlistItem.text = nUsers.replace('%n', count);
} else if (count === 1) {
userlistItem.text = oneUser;
} else {
userlistItem.text = noUser;
}
var zoomlevel = $('#zoomlevel').html();
w2ui['toolbar-down'].refresh();
$('#zoomlevel').html(zoomlevel);
}
map.on('addview', function(e) {
$('#tb_toolbar-down_item_userlist')
.w2overlay({
class: 'loleaflet-font',
html: userJoinedPopupMessage.replace('%user', e.username),
style: 'padding: 5px'
});
clearTimeout(userPopupTimeout);
userPopupTimeout = setTimeout(function() {
$('#tb_toolbar-down_item_userlist').w2overlay('');
clearTimeout(userPopupTimeout);
userPopupTimeout = null;
}, 3000);
var username = e.username;
var color = L.LOUtil.rgbToHex(map.getViewColor(e.viewId));
if (e.viewId === map._docLayer._viewId) {
username = _('You');
color = '#000';
}
// Mention readonly sessions in userlist
if (e.readonly) {
username += ' (' + _('Readonly') + ')';
}
var userlistItem = w2ui['toolbar-down'].get('userlist');
var newhtml = $(userlistItem.html).find('#userlist_table tbody').append(getUserItem(e.viewId, username, e.extraInfo, color)).parent().parent()[0].outerHTML;
userlistItem.html = newhtml;
updateUserListCount();
});
map.on('removeview', function(e) {
$('#tb_toolbar-down_item_userlist')
.w2overlay({
class: 'loleaflet-font',
html: userLeftPopupMessage.replace('%user', e.username),
style: 'padding: 5px'
});
clearTimeout(userPopupTimeout);
userPopupTimeout = setTimeout(function() {
$('#tb_toolbar-down_item_userlist').w2overlay('');
clearTimeout(userPopupTimeout);
userPopupTimeout = null;
}, 3000);
var userlistItem = w2ui['toolbar-down'].get('userlist');
userlistItem.html = $(userlistItem.html).find('#user-' + e.viewId).remove().end()[0].outerHTML;
updateUserListCount();
});
$(window).resize(function() {
resizeToolbar();
});
$(document).ready(function() {
var toolbar = w2ui['toolbar-up'];
if (closebutton) {
toolbar.show('close');
}
// Attach insert file action
$('#insertgraphic').on('change', onInsertFile);
});