diff --git a/apps/common/main/lib/component/Button.js b/apps/common/main/lib/component/Button.js index 88f69376da..bd95feb40c 100644 --- a/apps/common/main/lib/component/Button.js +++ b/apps/common/main/lib/component/Button.js @@ -191,6 +191,10 @@ define([ 'print(\' \'); %>' + '<% } %>'; + var templateBtnCaption = + '<%= caption %>' + + ''; + var templateHugeCaption = '' + @@ -225,9 +227,7 @@ define([ '' + '' + @@ -898,7 +898,7 @@ define([ setCaption: function(caption) { if (this.caption != caption) { - if ( /icon-top/.test(this.cls) && !!this.caption && /huge/.test(this.cls) ) { + if ( /icon-top/.test(this.options.cls) && !!this.caption && /huge/.test(this.options.cls) ) { var newCaption = this.getCaptionWithBreaks(caption); this.caption = newCaption || caption; } else @@ -908,7 +908,7 @@ define([ var captionNode = this.cmpEl.find('.caption'); if (captionNode.length > 0) { - captionNode.html(this.caption); + captionNode.html((this.split || this.menu) ? _.template(templateBtnCaption)({caption: this.caption}) : this.caption); } else { this.cmpEl.find('button:first').addBack().filter('button').html(this.caption); } @@ -988,5 +988,70 @@ define([ } } }); + + Common.UI.ButtonCustom = Common.UI.Button.extend(_.extend({ + initialize : function(options) { + options.iconCls = 'icon-custom ' + (options.iconCls || ''); + Common.UI.Button.prototype.initialize.call(this, options); + + this.iconsSet = Common.UI.iconsStr2IconsObj(options.iconsSet || ['']); + var icons = Common.UI.getSuitableIcons(this.iconsSet); + this.iconNormalImg = icons['normal']; + this.iconActiveImg = icons['active']; + }, + + render: function (parentEl) { + Common.UI.Button.prototype.render.call(this, parentEl); + + var _current_active = false, + me = this; + this.cmpButtonFirst = $('button:first', this.$el || $(this.el)); + const _callback = function (records, observer) { + var _hasactive = me.cmpButtonFirst.hasClass('active') || me.cmpButtonFirst.is(':active'); + if ( _hasactive !== _current_active ) { + me.updateIcon(); + _current_active = _hasactive; + } + }; + this.cmpButtonFirst[0] && (new MutationObserver(_callback)) + .observe(this.cmpButtonFirst[0], { + attributes : true, + attributeFilter : ['class'], + }); + + if (this.menu && !this.split) { + var onMouseDown = function (e) { + _callback(); + $(document).on('mouseup', onMouseUp); + }; + var onMouseUp = function (e) { + _callback(); + $(document).off('mouseup', onMouseUp); + }; + this.cmpButtonFirst.on('mousedown', _.bind(onMouseDown, this)); + } + + this.updateIcon(); + Common.NotificationCenter.on('uitheme:changed', this.updateIcons.bind(this)); + }, + + updateIcons: function() { + var icons = Common.UI.getSuitableIcons(this.iconsSet); + this.iconNormalImg = icons['normal']; + this.iconActiveImg = icons['active']; + this.updateIcon(); + }, + + updateIcon: function() { + this.$icon && this.$icon.css({'background-image': 'url('+ (this.cmpButtonFirst && (this.cmpButtonFirst.hasClass('active') || this.cmpButtonFirst.is(':active')) ? this.iconActiveImg : this.iconNormalImg) +')'}); + }, + + applyScaling: function (ratio) { + if ( this.options.scaling !== ratio ) { + this.options.scaling = ratio; + this.updateIcons(); + } + } + }, Common.UI.ButtonCustom || {})); }); diff --git a/apps/common/main/lib/component/Mixtbar.js b/apps/common/main/lib/component/Mixtbar.js index 7bd2bbb450..4e9108f74a 100644 --- a/apps/common/main/lib/component/Mixtbar.js +++ b/apps/common/main/lib/component/Mixtbar.js @@ -392,10 +392,38 @@ define([ } }, + getTab: function(tab) { + if (tab && this.$panels) { + var panel = this.$panels.filter('[data-tab=' + tab + ']'); + return panel.length ? panel : undefined; + } + }, + + createTab: function(tab, visible) { + if (!tab.action || !tab.caption) return; + + var _panel = $('
'); + this.addTab(tab, _panel, this.getLastTabIdx()); + this.setVisible(tab.action, !!visible); + return _panel; + }, + + getMorePanel: function(tab) { + return tab && btnsMore[tab] ? btnsMore[tab].panel : null; + }, + + getLastTabIdx: function() { + return config.tabs.length; + }, + isCompact: function () { return this.isFolded; }, + isExpanded: function () { + return !this.isFolded || optsFold.$bar && optsFold.$bar.hasClass('expanded'); + }, + hasTabInvisible: function() { if ($boxTabs.length<1) return false; @@ -447,6 +475,9 @@ define([ _.each($active.find('.btn-slot .x-huge'), function(item) { _btns.push($(item).closest('.btn-slot')); }); + btnsMore[data.tab] && btnsMore[data.tab].panel && _.each(btnsMore[data.tab].panel.find('.btn-slot .x-huge'), function(item) { + _btns.push($(item).closest('.btn-slot')); + }); data.buttons = _btns; } if (!_flex) { @@ -603,6 +634,83 @@ define([ } }, + addCustomItems: function(tab, added, removed) { + if (!tab.action) return; + + var $panel = tab.action ? this.getTab(tab.action) || this.createTab(tab, true) || this.getTab('plugins') : null, + $morepanel = this.getMorePanel(tab.action), + $moresection = $panel ? $panel.find('.more-box') : null, + compactcls = ''; + ($moresection.length<1) && ($moresection = null); + if ($panel) { + if (removed) { + removed.forEach(function(button, index) { + if (button.cmpEl) { + var group = button.cmpEl.closest('.group'); + button.cmpEl.closest('.btn-slot').remove(); + if (group.children().length<1) { + var in_more = group.closest('.more-container').length>0; + in_more ? group.next('.separator').remove() : group.prev('.separator').remove(); + group.remove(); + if (in_more && $morepanel.children().filter('.group').length === 0) { + btnsMore[tab.action] && btnsMore[tab.action].isActive() && btnsMore[tab.action].toggle(false); + $moresection && $moresection.css('display', "none"); + } + } + } + }); + $panel.find('.btn-slot:not(.slot-btn-more).x-huge').last().hasClass('compactwidth') && (compactcls = 'compactwidth'); + } + added && added.forEach(function(button, index) { + var _groups, _group; + if ($morepanel) { + _groups = $morepanel.children().filter('.group'); + if (_groups.length>0) { + $moresection = null; + $panel = $morepanel; + compactcls = 'compactwidth'; + } + } + if (!_groups || _groups.length<1) + _groups = $panel.children().filter('.group'); + + if (_groups.length>0 && !button.options.separator && index>0) // add first button to new group + _group = $(_groups[_groups.length-1]); + else { + if (button.options.separator) { + var el = $('
'); + $moresection ? $moresection.before(el) : el.appendTo($panel); + } + _group = $('
'); + $moresection ? $moresection.before(_group) : _group.appendTo($panel); + } + var $slot = $('').appendTo(_group); + button.render($slot); + }); + } + this.clearActiveData(tab.action); + this.processPanelVisible(null, true); + + var visible = !this.isTabEmpty(tab.action) && Common.UI.LayoutManager.isElementVisible('toolbar-' + tab.action); + this.setVisible(tab.action, visible); + if (!visible && this.isTabActive(tab.action) && this.isExpanded()) { + if (this.getTab('home')) + this.setTab('home'); + else { + tab = this.$tabs.siblings(':not(.x-lone):visible').first().find('> a[data-tab]').data('tab'); + this.setTab(tab); + } + } + }, + + isTabEmpty: function(tab) { + var $panel = this.getTab(tab), + $morepanel = this.getMorePanel(tab), + $moresection = $panel ? $panel.find('.more-box') : null; + ($moresection.length<1) && ($moresection = null); + return $panel ? !($panel.find('> .group').length>0 || $morepanel && $morepanel.find('.group').length>0) : false; + }, + resizeToolbar: function(reset) { var $active = this.$panels.filter('.active'), more_section = $active.find('.more-box'); diff --git a/apps/common/main/lib/controller/LayoutManager.js b/apps/common/main/lib/controller/LayoutManager.js index b0f9f4dd6f..5bff58ac07 100644 --- a/apps/common/main/lib/controller/LayoutManager.js +++ b/apps/common/main/lib/controller/LayoutManager.js @@ -47,10 +47,13 @@ if (Common.UI === undefined) { Common.UI.LayoutManager = new(function() { var _config, - _licensed; - var _init = function(config, licensed) { + _licensed, + _api, + _lastInternalTabIdx = 10; + var _init = function(config, licensed, api) { _config = config; _licensed = licensed; + _api = api; }; var _applyCustomization = function(config, el, prefix) { @@ -110,11 +113,193 @@ Common.UI.LayoutManager = new(function() { } }; + var _findCustomButton = function(toolbar, action, guid, id) { + if (toolbar && toolbar.customButtonsArr && toolbar.customButtonsArr[guid] ) { + for (var i=0; i< toolbar.customButtonsArr[guid].length; i++) { + var btn = toolbar.customButtonsArr[guid][i]; + if (btn.options.tabid === action && btn.options.guid === guid && btn.options.value === id) { + return btn; + } + } + } + } + + var _findRemovedButtons = function(toolbar, action, guid, items) { + var arr = []; + if (toolbar && toolbar.customButtonsArr && toolbar.customButtonsArr[guid] ) { + if (!items || items.length<1) { + arr = toolbar.customButtonsArr[guid]; + toolbar.customButtonsArr[guid] = undefined; + } else { + for (var i=0; i< toolbar.customButtonsArr[guid].length; i++) { + var btn = toolbar.customButtonsArr[guid][i]; + if (btn.options.tabid === action && !_.findWhere(items, {id: btn.options.value})) { + arr.push(btn); + toolbar.customButtonsArr[guid].splice(i, 1); + i--; + } + } + } + } + return arr; + } + + var _fillButtonMenu = function(items, guid, lang, toMenu) { + if (toMenu) + toMenu.removeAll(); + else { + toMenu = new Common.UI.Menu({ + cls: 'shifted-right', + menuAlign: 'tl-tr', + items: [] + }); + toMenu.on('item:click', function(menu, mi, e) { + _api && _api.onPluginToolbarMenuItemClick(mi.options.guid, mi.value); + }); + } + items.forEach(function(menuItem) { + if (menuItem.separator) toMenu.addItem({caption: '--'}); + menuItem.text && toMenu.addItem({ + caption: menuItem.text || '', + value: menuItem.id, + menu: menuItem.items ? _fillButtonMenu(menuItem.items, guid, lang) : false, + iconImg: Common.UI.getSuitableIcons(Common.UI.iconsStr2IconsObj(menuItem.icons)), + guid: guid + }); + }); + return toMenu; + } + + var _addCustomItems = function (toolbar, data) { + if (!data) return; + + var lang = Common.Locale.getCurrentLanguage(), + btns = []; + data.forEach(function(plugin) { + /* + plugin = { + guid: 'plugin-guid', + tabs: [ + { + id: 'tab-id', + text: 'caption', + items: [ + { + id: 'button-id', + type: 'button'='big-button' or 'small-button', + icons: 'template string' or object + text: 'caption' or - can be empty + hint: 'hint', + separator: true/false - inserted before item, + split: true/false - used when has menu + items: [ + { + id: 'item-id', + text: 'caption' + separator: true/false - inserted before item, + icons: 'template string' or object + } + ], + enableToggle: true/false - can press and depress button, only when no menu or has split menu + lockInViewMode: true/false - lock in view modes (preview review, view forms, disconnect, etc.), + disabled: true/false + } + ] + }, + { + id: 'tab-id', + text: 'caption', + items: [...] + }, + ] + } + */ + plugin.tabs && plugin.tabs.forEach(function(tab) { + if (tab) { + var added = [], + removed = _findRemovedButtons(toolbar, tab.id, plugin.guid, tab.items); + tab.items && tab.items.forEach(function(item, index) { + var btn = _findCustomButton(toolbar, tab.id, plugin.guid, item.id), + _set = Common.enumLock; + if (btn) { // change caption, hint, disable state, menu items + if (btn instanceof Common.UI.Button) { + var caption = item.text || ''; + if (btn.options.caption !== (caption || ' ')) { + btn.cmpEl.closest('.btn-slot.x-huge').toggleClass('nocaption', !caption); + btn.setCaption(caption || ' '); + btn.options.caption = caption || ' '; + } + btn.updateHint(item.hint || ''); + (item.disabled!==undefined) && Common.Utils.lockControls(_set.customLock, !!item.disabled, {array: [btn]}); + if (btn.menu && item.items && item.items.length > 0) {// update menu items + if (typeof btn.menu !== 'object') { + btn.setMenu(new Common.UI.Menu({items: []})); + btn.menu.on('item:click', function(menu, mi, e) { + _api && _api.onPluginToolbarMenuItemClick(mi.options.guid, mi.value); + }); + } + _fillButtonMenu(item.items, plugin.guid, lang, btn.menu); + } + } + return; + } + + if (item.type==='button' || item.type==='big-button') { + btn = new Common.UI.ButtonCustom({ + cls: 'btn-toolbar x-huge icon-top', + iconsSet: item.icons, + caption: item.text || ' ', + menu: item.items, + split: item.items && !!item.split, + enableToggle: item.enableToggle && (!item.items || !!item.split), + value: item.id, + guid: plugin.guid, + tabid: tab.id, + separator: item.separator, + hint: item.hint || '', + lock: item.lockInViewMode ? [_set.customLock, _set.viewMode, _set.previewReviewMode, _set.viewFormMode, _set.docLockView, _set.docLockForms, _set.docLockComments, _set.selRangeEdit, _set.editFormula ] : [_set.customLock], + dataHint: '1', + dataHintDirection: 'bottom', + dataHintOffset: 'small' + }); + + if (item.items && typeof item.items === 'object') { + btn.setMenu(new Common.UI.Menu({items: []})); + btn.menu.on('item:click', function(menu, mi, e) { + _api && _api.onPluginToolbarMenuItemClick(mi.options.guid, mi.value); + }); + _fillButtonMenu(item.items, plugin.guid, lang, btn.menu); + } + if ( !btn.menu || btn.split) { + btn.on('click', function(b, e) { + _api && _api.onPluginToolbarMenuItemClick(b.options.guid, b.options.value, b.pressed); + }); + } + added.push(btn); + item.disabled && Common.Utils.lockControls(_set.customLock, item.disabled, {array: [btn]}); + } + }); + + toolbar.addCustomItems({action: tab.id, caption: tab.text || ''}, added, removed); + if (!toolbar.customButtonsArr) + toolbar.customButtonsArr = []; + if (!toolbar.customButtonsArr[plugin.guid]) + toolbar.customButtonsArr[plugin.guid] = []; + Array.prototype.push.apply(toolbar.customButtonsArr[plugin.guid], added); + Array.prototype.push.apply(btns, added); + } + }); + }); + return btns; + }; + return { init: _init, applyCustomization: _applyCustomization, isElementVisible: _isElementVisible, - getInitValue: _getInitValue + getInitValue: _getInitValue, + lastTabIdx: _lastInternalTabIdx, + addCustomItems: _addCustomItems } })(); diff --git a/apps/common/main/lib/controller/Plugins.js b/apps/common/main/lib/controller/Plugins.js index e0702a7311..fbae06159b 100644 --- a/apps/common/main/lib/controller/Plugins.js +++ b/apps/common/main/lib/controller/Plugins.js @@ -68,7 +68,7 @@ define([ var tab = {action: 'plugins', caption: me.viewPlugins.groupCaption, dataHintTitle: 'E', layoutname: 'toolbar-plugins'}; me.$toolbarPanelPlugins = me.viewPlugins.getPanel(); me.toolbar = toolbar; - toolbar.addTab(tab, me.$toolbarPanelPlugins, 10); // TODO: clear plugins list in left panel + toolbar.addTab(tab, me.$toolbarPanelPlugins, Common.UI.LayoutManager.lastTabIdx); // TODO: clear plugins list in left panel } } }, @@ -421,6 +421,11 @@ define([ me.backgroundPlugins.push(model); return; } + if (model.get('tab')) { + me.toolbar && me.toolbar.addCustomItems(model.get('tab'), [me.viewPlugins.createPluginButton(model)]); + return; + } + //if (new_rank === 1 || new_rank === 2) return; // for test if ((new_rank === 0 || new_rank === 2) && !isBackground) { _group = me.addBackgroundPluginsButton(_group); @@ -883,7 +888,8 @@ define([ original: item, isDisplayedInViewer: isDisplayedInViewer, isBackgroundPlugin: pluginVisible && isBackgroundPlugin, - isSystem: isSystem + isSystem: isSystem, + tab: item.tab ? {action: item.tab.id, caption: ((typeof item.tab.text == 'object') ? item.tab.text[lang] || item.tab.text['en'] : item.tab.text) || ''} : undefined }; updatedItem ? updatedItem.set(props) : arr.push(new Common.Models.Plugin(props)); } diff --git a/apps/common/main/lib/util/utils.js b/apps/common/main/lib/util/utils.js index fa220d885a..7967866672 100644 --- a/apps/common/main/lib/util/utils.js +++ b/apps/common/main/lib/util/utils.js @@ -1210,3 +1210,162 @@ Common.UI.isRTL = function () { return window.isrtl; }; + +Common.UI.iconsStr2IconsObj = function(icons) { + let result = icons; + if (typeof result === 'string' && result.indexOf('%') !== -1) { + /* + valid params: + theme-type - {string} theme type (light|dark|common) + theme-name - {string} the name of theme + state - {string} state of icons for different situations (normal|hover|active) + scale - {string} list of avaliable scales (100|125|150|175|200|default|extended) + extension - {string} use it after symbol "." (png|jpeg|svg) + + Example: "resources/%theme-type%(light|dark)/%state%(normal)icon%scale%(default).%extension%(png)" + */ + let scaleValue = { + '100%' : '.', + '125%' : '@1.25x.', + '150%' : '@1.5x.', + '175%' : '@1.75x.', + '200%' : '@2x.' + } + let arrParams = ['theme-type', 'theme-name' ,'state', 'scale', 'extension'], + start = result.indexOf('%'), + template = result.substring(start).replace(/[/.]/g, ('')), + commonPart = result.substring(0, start), + end = 0, + param = null, + values = null, + iconName = '', + tempObj = {}; + + result = []; + + for (let index = 0; index < arrParams.length; index++) { + param = arrParams[index]; + start = template.indexOf(param) - 1; + if (start < 0 ) + continue; + + end = param.length + 2; + template = template.substring(0, start) + template.substring(start + end); + start = template.indexOf('(', 0); + end = template.indexOf(')', 0); + values = template.substring((start + 1), end); + template = template.substring(0, start) + template.substring(++end); + tempObj[param] = values.split('|'); + } + + if (template.length) { + iconName = template; + } else { + let arr = commonPart.split('/'); + iconName = arr.pop().replace(/\./g, ''); + commonPart = arr.join('/') + '/'; + } + + // we don't work with svg yet. Change it when we will work with it (extended variant). + if (tempObj['scale'] && (tempObj['scale'] == 'default' || tempObj['scale'] == 'extended') ) { + tempObj['scale'] = ['100', '125', '150', '175', '200']; + } else if (!tempObj['scale']) { + tempObj['scale'] = ['100']; + } + + if (!tempObj['state']) { + tempObj['state'] = ['normal']; + } + + if (!iconName) { + iconName = 'icon'; + } + + let bHasName = !!tempObj['theme-name']; + let bHasType = (tempObj['theme-type'] && tempObj['theme-type'][0] !== 'common'); + let arrThemes = bHasName ? tempObj['theme-name'] : (bHasType ? tempObj['theme-type'] : []); + let paramName = bHasName ? 'theme' : 'style'; + if (arrThemes.length) { + for (let thInd = 0; thInd < arrThemes.length; thInd++) { + let obj = {}; + obj[paramName] = arrThemes[thInd]; + result.push(obj); + } + } else { + result.push({}); + } + + for (let index = 0; index < result.length; index++) { + for (let scaleInd = 0; scaleInd < tempObj['scale'].length; scaleInd++) { + let themePath = (result[index][paramName] || 'img') + '/'; + let scale = tempObj['scale'][scaleInd] + '%'; + let obj = {}; + for (let stateInd = 0; stateInd < tempObj['state'].length; stateInd++) { + let state = tempObj['state'][stateInd]; + obj[state] = commonPart + themePath + (state == 'normal' ? '' : (state + '_')) + iconName + (scaleValue[scale] || '.') + tempObj['extension'][0]; + } + result[index][scale] = obj; + } + } + } + return result; +} + +Common.UI.getSuitableIcons = function(icons) { + if (!icons) return; + + icons = Common.UI.iconsStr2IconsObj(icons); + if (icons.length && typeof icons[0] !== 'string') { + var theme = Common.UI.Themes.currentThemeId().toLowerCase(), + style = Common.UI.Themes.isDarkTheme() ? 'dark' : 'light', + idx = -1; + for (var i=0; i0.01 && defUrl) && (bestUrl = defUrl); + return { + 'normal': bestUrl ? bestUrl['normal'] : '', + 'hover': bestUrl ? bestUrl['hover'] || bestUrl['normal'] : '', + 'active': bestUrl ? bestUrl['active'] || bestUrl['normal'] : '' + }; + } else { // old version + var url = icons[((Common.Utils.applicationPixelRatio() > 1 && icons.length > 1) ? 1 : 0) + (icons.length > 2 ? 2 : 0)]; + return { + 'normal': url, + 'hover': url, + 'active': url + }; + } +} diff --git a/apps/common/main/lib/view/ReviewChanges.js b/apps/common/main/lib/view/ReviewChanges.js index 99cd4243c9..0eec9069dc 100644 --- a/apps/common/main/lib/view/ReviewChanges.js +++ b/apps/common/main/lib/view/ReviewChanges.js @@ -65,7 +65,8 @@ define([ viewFormMode: 'view-form-mode', // view form mode on Forms tab viewMode: 'view-mode', // view mode on disconnect, version history etc (used for locking buttons not in toolbar) or view mode from header mode button (for toolbar) hideComments: 'hide-comments', // no live comments and left panel is closed - cantShare: 'cant-share' + cantShare: 'cant-share', + customLock: 'custom-lock' // for custom buttons in toolbar }; for (var key in enumLock) { if (enumLock.hasOwnProperty(key)) { diff --git a/apps/common/main/resources/less/buttons.less b/apps/common/main/resources/less/buttons.less index e96a3a868a..27b19ccff1 100644 --- a/apps/common/main/resources/less/buttons.less +++ b/apps/common/main/resources/less/buttons.less @@ -311,7 +311,7 @@ } } - .emptycaption & { + .emptycaption & { // used for buttons without caption, but with color div width: 37px; .caret { margin: 0 1px 0 2px; @@ -417,6 +417,11 @@ } } +.icon-custom { + background-position: 0 0 !important; + background-size: cover; +} + .btn-toolbar { display: inline-block; position: relative; diff --git a/apps/common/main/resources/less/toolbar.less b/apps/common/main/resources/less/toolbar.less index 8b19f96f98..30fda65faa 100644 --- a/apps/common/main/resources/less/toolbar.less +++ b/apps/common/main/resources/less/toolbar.less @@ -240,21 +240,23 @@ } /* ##adopt-panel-width */ - .panel .compactwidth:not(.emptycaption) { - .btn-group, .btn-toolbar { - &.x-huge { - .caption { - display: none; - } + .panel { + .compactwidth:not(.emptycaption), .nocaption { + .btn-group, .btn-toolbar { + &.x-huge { + .caption { + display: none; + } - .inner-box-caption { - justify-content: center; - align-items: center; - padding: 0 2px; - } + .inner-box-caption { + justify-content: center; + align-items: center; + padding: 0 2px; + } - .compact-caret { - display: block; + .compact-caret { + display: block; + } } } } @@ -272,7 +274,7 @@ .rtl & { padding: 12px 0 7px 10px; } - .compactwidth:not(.emptycaption) { + .compactwidth:not(.emptycaption), .nocaption { .btn-group, .btn-toolbar { &.x-huge { .caption { diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js index 3bd7c86522..c33e2b8a73 100644 --- a/apps/documenteditor/main/app/controller/Main.js +++ b/apps/documenteditor/main/app/controller/Main.js @@ -1689,7 +1689,7 @@ define([ this.appOptions.canRename && appHeader.setCanRename(true); this.appOptions.canBrandingExt = params.asc_getCanBranding() && (typeof this.editorConfig.customization == 'object' || this.editorConfig.plugins); this.getApplication().getController('Common.Controllers.Plugins').setMode(this.appOptions, this.api); - this.editorConfig.customization && Common.UI.LayoutManager.init(this.editorConfig.customization.layout, this.appOptions.canBrandingExt); + Common.UI.LayoutManager.init(this.editorConfig.customization ? this.editorConfig.customization.layout : null, this.appOptions.canBrandingExt, this.api); this.editorConfig.customization && Common.UI.FeaturesManager.init(this.editorConfig.customization.features, this.appOptions.canBrandingExt); Common.UI.ExternalUsers.init(this.appOptions.canRequestUsers, this.api); this.appOptions.user.image ? Common.UI.ExternalUsers.setImage(this.appOptions.user.id, this.appOptions.user.image) : Common.UI.ExternalUsers.get('info', this.appOptions.user.id); diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js index 9c33465bf4..2fa5ae7c95 100644 --- a/apps/documenteditor/main/app/controller/Toolbar.js +++ b/apps/documenteditor/main/app/controller/Toolbar.js @@ -466,6 +466,7 @@ define([ this.api.asc_registerCallback('asc_onCanRedo', _.bind(this.onApiCanRevert, this, 'redo')); } } + this.api.asc_registerCallback('onPluginToolbarMenu', _.bind(this.onPluginToolbarMenu, this)); this.api.asc_registerCallback('asc_onDownloadUrl', _.bind(this.onDownloadUrl, this)); Common.NotificationCenter.on('protect:doclock', _.bind(this.onChangeProtectDocument, this)); }, @@ -3718,6 +3719,10 @@ define([ } }, + onPluginToolbarMenu: function(data) { + this.toolbar && Array.prototype.push.apply(this.toolbar.lockControls, Common.UI.LayoutManager.addCustomItems(this.toolbar, data)); + }, + textEmptyImgUrl : 'You need to specify image URL.', textWarning : 'Warning', textFontSizeErr : 'The entered value is incorrect.
Please enter a numeric value between 1 and 300', diff --git a/apps/pdfeditor/main/app/controller/Main.js b/apps/pdfeditor/main/app/controller/Main.js index f7fe5c0fc3..31902ac113 100644 --- a/apps/pdfeditor/main/app/controller/Main.js +++ b/apps/pdfeditor/main/app/controller/Main.js @@ -1293,7 +1293,7 @@ define([ this.appOptions.canRename && appHeader.setCanRename(true); this.appOptions.canBrandingExt = params.asc_getCanBranding() && (typeof this.editorConfig.customization == 'object' || this.editorConfig.plugins); this.getApplication().getController('Common.Controllers.Plugins').setMode(this.appOptions, this.api); - this.editorConfig.customization && Common.UI.LayoutManager.init(this.editorConfig.customization.layout, this.appOptions.canBrandingExt); + Common.UI.LayoutManager.init(this.editorConfig.customization ? this.editorConfig.customization.layout : null, this.appOptions.canBrandingExt, this.api); this.editorConfig.customization && Common.UI.FeaturesManager.init(this.editorConfig.customization.features, this.appOptions.canBrandingExt); Common.UI.ExternalUsers.init(this.appOptions.canRequestUsers, this.api); this.appOptions.user.image ? Common.UI.ExternalUsers.setImage(this.appOptions.user.id, this.appOptions.user.image) : Common.UI.ExternalUsers.get('info', this.appOptions.user.id); diff --git a/apps/pdfeditor/main/app/controller/Toolbar.js b/apps/pdfeditor/main/app/controller/Toolbar.js index 9248e62e59..9196432e97 100644 --- a/apps/pdfeditor/main/app/controller/Toolbar.js +++ b/apps/pdfeditor/main/app/controller/Toolbar.js @@ -246,6 +246,7 @@ define([ this.api.asc_registerCallback('asc_onCountPages', _.bind(this.onCountPages, this)); this.api.asc_registerCallback('asc_onCurrentPage', _.bind(this.onCurrentPage, this)); this.api.asc_registerCallback('asc_onDownloadUrl', _.bind(this.onDownloadUrl, this)); + this.api.asc_registerCallback('onPluginToolbarMenu', _.bind(this.onPluginToolbarMenu, this)); }, onChangeCompactView: function(view, compact) { @@ -975,6 +976,10 @@ define([ this.toolbar && this.toolbar.chShowComments && this.toolbar.chShowComments.setValue(Common.Utils.InternalSettings.get("pdfe-settings-livecomment"), true); }, + onPluginToolbarMenu: function(data) { + this.toolbar && Array.prototype.push.apply(this.toolbar.lockControls, Common.UI.LayoutManager.addCustomItems(this.toolbar, data)); + }, + textWarning: 'Warning', notcriticalErrorTitle: 'Warning', txtNeedCommentMode: 'To save changes to the file, switch to Сommenting mode. Or you can download a copy of the modified file.', diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js index 4a69b24422..e6734b0dab 100644 --- a/apps/presentationeditor/main/app/controller/Main.js +++ b/apps/presentationeditor/main/app/controller/Main.js @@ -1324,7 +1324,7 @@ define([ this.appOptions.canRename && appHeader.setCanRename(true); this.appOptions.canBrandingExt = params.asc_getCanBranding() && (typeof this.editorConfig.customization == 'object' || this.editorConfig.plugins); this.getApplication().getController('Common.Controllers.Plugins').setMode(this.appOptions); - this.editorConfig.customization && Common.UI.LayoutManager.init(this.editorConfig.customization.layout, this.appOptions.canBrandingExt); + Common.UI.LayoutManager.init(this.editorConfig.customization ? this.editorConfig.customization.layout : null, this.appOptions.canBrandingExt, this.api); this.editorConfig.customization && Common.UI.FeaturesManager.init(this.editorConfig.customization.features, this.appOptions.canBrandingExt); Common.UI.ExternalUsers.init(this.appOptions.canRequestUsers, this.api); this.appOptions.user.image ? Common.UI.ExternalUsers.setImage(this.appOptions.user.id, this.appOptions.user.image) : Common.UI.ExternalUsers.get('info', this.appOptions.user.id); diff --git a/apps/presentationeditor/main/app/controller/Toolbar.js b/apps/presentationeditor/main/app/controller/Toolbar.js index 526e2061be..f956d3ac66 100644 --- a/apps/presentationeditor/main/app/controller/Toolbar.js +++ b/apps/presentationeditor/main/app/controller/Toolbar.js @@ -442,6 +442,7 @@ define([ } else if (this.mode.isRestrictedEdit) { this.api.asc_registerCallback('asc_onCountPages', _.bind(this.onApiCountPagesRestricted, this)); } + this.api.asc_registerCallback('onPluginToolbarMenu', _.bind(this.onPluginToolbarMenu, this)); }, onChangeCompactView: function(view, compact) { @@ -2923,6 +2924,10 @@ define([ this.toolbar._isEyedropperStart = false; }, + onPluginToolbarMenu: function(data) { + this.toolbar && Array.prototype.push.apply(this.toolbar.lockControls, Common.UI.LayoutManager.addCustomItems(this.toolbar, data)); + }, + textEmptyImgUrl : 'You need to specify image URL.', textWarning : 'Warning', textFontSizeErr : 'The entered value is incorrect.
Please enter a numeric value between 1 and 300', diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js index f3c60b9176..653b79ee7d 100644 --- a/apps/spreadsheeteditor/main/app/controller/Main.js +++ b/apps/spreadsheeteditor/main/app/controller/Main.js @@ -1440,7 +1440,7 @@ define([ if (!this.appOptions.isEditDiagram && !this.appOptions.isEditMailMerge && !this.appOptions.isEditOle) { this.appOptions.canBrandingExt = params.asc_getCanBranding() && (typeof this.editorConfig.customization == 'object' || this.editorConfig.plugins); this.getApplication().getController('Common.Controllers.Plugins').setMode(this.appOptions); - this.editorConfig.customization && Common.UI.LayoutManager.init(this.editorConfig.customization.layout, this.appOptions.canBrandingExt); + Common.UI.LayoutManager.init(this.editorConfig.customization ? this.editorConfig.customization.layout : null, this.appOptions.canBrandingExt, this.api); this.editorConfig.customization && Common.UI.FeaturesManager.init(this.editorConfig.customization.features, this.appOptions.canBrandingExt); Common.UI.ExternalUsers.init(this.appOptions.canRequestUsers, this.api); this.appOptions.user.image ? Common.UI.ExternalUsers.setImage(this.appOptions.user.id, this.appOptions.user.image) : Common.UI.ExternalUsers.get('info', this.appOptions.user.id); diff --git a/apps/spreadsheeteditor/main/app/controller/Toolbar.js b/apps/spreadsheeteditor/main/app/controller/Toolbar.js index aaac71e6eb..ffaab4c261 100644 --- a/apps/spreadsheeteditor/main/app/controller/Toolbar.js +++ b/apps/spreadsheeteditor/main/app/controller/Toolbar.js @@ -533,6 +533,8 @@ define([ this.api.asc_registerCallback('asc_onSelectionChanged', _.bind(this.onApiSelectionChangedRestricted, this)); Common.NotificationCenter.on('protect:wslock', _.bind(this.onChangeProtectSheet, this)); } + if ( !config.isEditDiagram && !config.isEditMailMerge && !config.isEditOle ) + this.api.asc_registerCallback('onPluginToolbarMenu', _.bind(this.onPluginToolbarMenu, this)); }, // onNewDocument: function(btn, e) { @@ -5224,6 +5226,10 @@ define([ } }, + onPluginToolbarMenu: function(data) { + this.toolbar && Array.prototype.push.apply(this.toolbar.lockControls, Common.UI.LayoutManager.addCustomItems(this.toolbar, data)); + }, + textEmptyImgUrl : 'You need to specify image URL.', warnMergeLostData : 'Operation can destroy data in the selected cells.
Continue?', textWarning : 'Warning',