diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js index 7e18427ef..76c6f6ea1 100644 --- a/apps/api/documents/api.js +++ b/apps/api/documents/api.js @@ -43,7 +43,8 @@ print: , // default = true rename: , // default = false changeHistory: , // default = false - comment: // default = edit + comment: // default = edit, + modifyFilter: // default = true } }, editorConfig: { @@ -170,7 +171,8 @@ 'onAppReady': , 'onBack': , 'onError': , - 'onDocumentReady': + 'onDocumentReady': , + 'onWarning': } } */ @@ -506,9 +508,10 @@ }); }; - var _downloadAs = function() { + var _downloadAs = function(data) { _sendCommand({ - command: 'downloadAs' + command: 'downloadAs', + data: data }); }; diff --git a/apps/common/Gateway.js b/apps/common/Gateway.js index 1fe953700..71d36ecc1 100644 --- a/apps/common/Gateway.js +++ b/apps/common/Gateway.js @@ -80,8 +80,8 @@ if (Common === undefined) { $me.trigger('processmailmerge', data); }, - 'downloadAs': function() { - $me.trigger('downloadas'); + 'downloadAs': function(data) { + $me.trigger('downloadas', data); }, 'processMouse': function(data) { @@ -189,6 +189,16 @@ if (Common === undefined) { }); }, + reportWarning: function(code, description) { + _postMessage({ + event: 'onWarning', + data: { + warningCode: code, + warningDescription: description + } + }); + }, + sendInfo: function(info) { _postMessage({ event: 'onInfo', diff --git a/apps/common/locale.js b/apps/common/locale.js index 6217b8e01..4112b39c1 100644 --- a/apps/common/locale.js +++ b/apps/common/locale.js @@ -106,7 +106,14 @@ Common.Locale = new(function() { l10n = eval("(" + xhrObj.responseText + ")"); } } - catch (e) { + catch (e) { + try { + xhrObj.open('GET', 'locale/en.json', false); + xhrObj.send(''); + l10n = eval("(" + xhrObj.responseText + ")"); + } + catch (e) { + } } return { diff --git a/apps/common/main/lib/component/Button.js b/apps/common/main/lib/component/Button.js index 97efcc3ff..e55b50942 100644 --- a/apps/common/main/lib/component/Button.js +++ b/apps/common/main/lib/component/Button.js @@ -160,8 +160,8 @@ define([ '' + '' + '' + @@ -180,7 +180,8 @@ define([ menu : null, disabled : false, pressed : false, - split : false + split : false, + visible : true }, template: _.template([ @@ -238,6 +239,7 @@ define([ me.split = me.options.split; me.toggleGroup = me.options.toggleGroup; me.disabled = me.options.disabled; + me.visible = me.options.visible; me.pressed = me.options.pressed; me.caption = me.options.caption; me.template = me.options.template || me.template; @@ -466,6 +468,10 @@ define([ me.setDisabled(!(me.disabled=false)); } + if (!me.visible) { + me.setVisible(me.visible); + } + me.trigger('render:after', me); return this; @@ -550,6 +556,11 @@ define([ setVisible: function(visible) { if (this.cmpEl) this.cmpEl.toggleClass('hidden', !visible); + this.visible = visible; + }, + + isVisible: function() { + return (this.cmpEl) ? this.cmpEl.is(":visible") : $(this.el).is(":visible"); }, updateHint: function(hint) { diff --git a/apps/common/main/lib/component/CheckBox.js b/apps/common/main/lib/component/CheckBox.js index 0bba39402..428224d03 100644 --- a/apps/common/main/lib/component/CheckBox.js +++ b/apps/common/main/lib/component/CheckBox.js @@ -99,10 +99,32 @@ define([ initialize : function(options) { Common.UI.BaseView.prototype.initialize.call(this, options); + if (this.options.el) + this.render(); + }, + + render: function (parentEl) { var me = this, el = $(this.el); + if (!me.rendered) { + if (parentEl) { + this.setElement(parentEl, false); + parentEl.html(this.template({ + labelText: this.options.labelText + })); + el = $(this.el); + } else { + el.html(this.template({ + labelText: this.options.labelText + })); + } - this.render(); + this.$chk = el.find('input[type=button]'); + this.$label = el.find('label'); + this.$chk.on('click', _.bind(this.onItemCheck, this)); + } + + this.rendered = true; if (this.options.disabled) this.setDisabled(this.options.disabled); @@ -111,20 +133,6 @@ define([ this.setValue(this.options.value, true); // handle events - this.$chk.on('click', _.bind(this.onItemCheck, this)); - }, - - render: function () { - var el = $(this.el); - el.html(this.template({ - labelText: this.options.labelText - })); - - this.$chk = el.find('input[type=button]'); - this.$label = el.find('label'); - - this.rendered = true; - return this; }, diff --git a/apps/common/main/lib/component/ColorButton.js b/apps/common/main/lib/component/ColorButton.js index 5fb4933d1..4572aa358 100644 --- a/apps/common/main/lib/component/ColorButton.js +++ b/apps/common/main/lib/component/ColorButton.js @@ -41,7 +41,8 @@ define([ Common.UI.ColorButton = Common.UI.Button.extend({ options : { hint: false, - enableToggle: false + enableToggle: false, + visible: true }, template: _.template([ diff --git a/apps/common/main/lib/component/ComboBoxFonts.js b/apps/common/main/lib/component/ComboBoxFonts.js index c1bf141bd..8e9bec06b 100644 --- a/apps/common/main/lib/component/ComboBoxFonts.js +++ b/apps/common/main/lib/component/ComboBoxFonts.js @@ -113,6 +113,8 @@ define([ this._input.on('keyup', _.bind(this.onInputKeyUp, this)); this._input.on('keydown', _.bind(this.onInputKeyDown, this)); + this._modalParents = this.cmpEl.closest('.asc-window'); + return this; }, @@ -139,7 +141,7 @@ define([ me.onAfterHideMenu(e); }, 10); return false; - } else if ((e.keyCode == Common.UI.Keys.HOME || e.keyCode == Common.UI.Keys.END || e.keyCode == Common.UI.Keys.BACKSPACE) && this.isMenuOpen()) { + } else if ((e.keyCode == Common.UI.Keys.HOME && !e.shiftKey || e.keyCode == Common.UI.Keys.END && !e.shiftKey || e.keyCode == Common.UI.Keys.BACKSPACE && !me._input.is(':focus')) && this.isMenuOpen()) { me._input.focus(); setTimeout(function() { me._input[0].selectionStart = me._input[0].selectionEnd = (e.keyCode == Common.UI.Keys.HOME) ? 0 : me._input[0].value.length; @@ -319,6 +321,8 @@ define([ var name = (_.isFunction(font.get_Name) ? font.get_Name() : font.asc_getName()); if (this.getRawValue() !== name) { + if (this._modalParents.length > 0) return; + var record = this.store.findWhere({ name: name }); diff --git a/apps/common/main/lib/component/DataView.js b/apps/common/main/lib/component/DataView.js index 01c399756..b4d1811bf 100644 --- a/apps/common/main/lib/component/DataView.js +++ b/apps/common/main/lib/component/DataView.js @@ -233,6 +233,8 @@ define([ me.emptyText = me.options.emptyText || ''; me.listenStoreEvents= (me.options.listenStoreEvents!==undefined) ? me.options.listenStoreEvents : true; me.allowScrollbar = (me.options.allowScrollbar!==undefined) ? me.options.allowScrollbar : true; + if (me.parentMenu) + me.parentMenu.options.restoreHeight = (me.options.restoreHeight>0); me.rendered = false; me.dataViewItems = []; if (me.options.keyMoveDirection=='vertical') @@ -471,6 +473,9 @@ define([ }); } + if (this.disabled) + this.setDisabled(this.disabled); + this.attachKeyEvents(); this.lastSelectedRec = null; this._layoutParams = undefined; @@ -688,20 +693,19 @@ define([ var menuRoot = (this.parentMenu.cmpEl.attr('role') === 'menu') ? this.parentMenu.cmpEl : this.parentMenu.cmpEl.find('[role=menu]'), + docH = Common.Utils.innerHeight()-10, innerEl = $(this.el).find('.inner').addBack().filter('.inner'), - docH = Common.Utils.innerHeight(), + parent = innerEl.parent(), + margins = parseInt(parent.css('margin-top')) + parseInt(parent.css('margin-bottom')) + parseInt(menuRoot.css('margin-top')), + paddings = parseInt(menuRoot.css('padding-top')) + parseInt(menuRoot.css('padding-bottom')), menuH = menuRoot.outerHeight(), top = parseInt(menuRoot.css('top')); - if (menuH > docH) { - innerEl.css('max-height', (docH - parseInt(menuRoot.css('padding-top')) - parseInt(menuRoot.css('padding-bottom'))-5) + 'px'); + if (top + menuH > docH ) { + innerEl.css('max-height', (docH - top - paddings - margins) + 'px'); if (this.allowScrollbar) this.scroller.update({minScrollbarLength : 40}); - } else if ( innerEl.height() < this.options.restoreHeight ) { - innerEl.css('max-height', (Math.min(docH - parseInt(menuRoot.css('padding-top')) - parseInt(menuRoot.css('padding-bottom'))-5, this.options.restoreHeight)) + 'px'); - menuH = menuRoot.outerHeight(); - if (top+menuH > docH) { - menuRoot.css('top', 0); - } + } else if ( top + menuH < docH && innerEl.height() < this.options.restoreHeight ) { + innerEl.css('max-height', (Math.min(docH - top - paddings - margins, this.options.restoreHeight)) + 'px'); if (this.allowScrollbar) this.scroller.update({minScrollbarLength : 40}); } }, diff --git a/apps/common/main/lib/component/Layout.js b/apps/common/main/lib/component/Layout.js index bb294def8..9b07c7c5c 100644 --- a/apps/common/main/lib/component/Layout.js +++ b/apps/common/main/lib/component/Layout.js @@ -168,6 +168,7 @@ define([ this.splitters.push({resizer:resizer}); panel.resize.hidden && resizer.el.hide(); + Common.Gateway.on('processmouse', this.resize.eventStop); } }, this); @@ -298,6 +299,11 @@ define([ if (!this.resize.$el) return; var zoom = (e instanceof jQuery.Event) ? Common.Utils.zoom() : 1; + if (!(e instanceof jQuery.Event) && (e.pageY === undefined || e.pageX === undefined)) { + e.pageY = e.y; + e.pageX = e.x; + + } if (this.resize.type == 'vertical') { var prop = 'height'; var value = e.pageY*zoom - this.resize.inity; diff --git a/apps/common/main/lib/component/ListView.js b/apps/common/main/lib/component/ListView.js index aa2e457af..0c9e99262 100644 --- a/apps/common/main/lib/component/ListView.js +++ b/apps/common/main/lib/component/ListView.js @@ -64,6 +64,7 @@ define([ onResetItems : function() { this.innerEl = null; Common.UI.DataView.prototype.onResetItems.call(this); + this.trigger('items:reset', this); }, onAddItem: function(record, index) { @@ -97,6 +98,16 @@ define([ this.listenTo(view, 'dblclick',this.onDblClickItem); this.listenTo(view, 'select', this.onSelectItem); + if (record.get('tip')) { + var view_el = $(view.el); + view_el.attr('data-toggle', 'tooltip'); + view_el.tooltip({ + title : record.get('tip'), + placement : 'cursor', + zIndex : this.tipZIndex + }); + } + if (!this.isSuspendEvents) this.trigger('item:add', this, view, record); } diff --git a/apps/common/main/lib/component/Menu.js b/apps/common/main/lib/component/Menu.js index c28a62d3d..f529a4ac8 100644 --- a/apps/common/main/lib/component/Menu.js +++ b/apps/common/main/lib/component/Menu.js @@ -424,6 +424,9 @@ define([ onAfterShowMenu: function(e) { this.trigger('show:after', this, e); + if (this.options.restoreHeight && this.scroller) + this.scroller.update({minScrollbarLength : 40}); + if (this.$el.find('> ul > .menu-scroll').length) { var el = this.$el.find('li .checked')[0]; if (el) { @@ -465,14 +468,20 @@ define([ }, onScroll: function(item, e) { - if (this.fromKeyDown) { - var menuRoot = (this.cmpEl.attr('role') === 'menu') - ? this.cmpEl - : this.cmpEl.find('[role=menu]'); + if (this.scroller) return; - menuRoot.find('.menu-scroll.top').css('top', menuRoot.scrollTop() + 'px'); - menuRoot.find('.menu-scroll.bottom').css('bottom', (-menuRoot.scrollTop()) + 'px'); + var menuRoot = (this.cmpEl.attr('role') === 'menu') + ? this.cmpEl + : this.cmpEl.find('[role=menu]'), + scrollTop = menuRoot.scrollTop(), + top = menuRoot.find('.menu-scroll.top'), + bottom = menuRoot.find('.menu-scroll.bottom'); + if (this.fromKeyDown) { + top.css('top', scrollTop + 'px'); + bottom.css('bottom', (-scrollTop) + 'px'); } + top.toggleClass('disabled', scrollTop<1); + bottom.toggleClass('disabled', scrollTop + this.options.maxHeight > menuRoot[0].scrollHeight-1); }, onItemClick: function(item, e) { @@ -493,6 +502,8 @@ define([ }, onScrollClick: function(e) { + if (/disabled/.test(e.currentTarget.className)) return false; + this.scrollMenu(/top/.test(e.currentTarget.className)); return false; }, @@ -562,17 +573,37 @@ define([ left = docW - menuW; } - if (top + menuH > docH) - top = docH - menuH; + if (this.options.restoreHeight) { + if (typeof (this.options.restoreHeight) == "number") { + if (top + menuH > docH) { + menuRoot.css('max-height', (docH - top) + 'px'); + menuH = menuRoot.outerHeight(); + } else if ( top + menuH < docH && menuRoot.height() < this.options.restoreHeight ) { + menuRoot.css('max-height', (Math.min(docH - top, this.options.restoreHeight)) + 'px'); + menuH = menuRoot.outerHeight(); + } + } + } else { + if (top + menuH > docH) + top = docH - menuH; - if (top < 0) - top = 0; + if (top < 0) + top = 0; + } if (this.options.additionalAlign) this.options.additionalAlign.call(this, menuRoot, left, top); else menuRoot.css({left: left, top: top}); + }, + + clearAll: function() { + _.each(this.items, function(item){ + if (item.setChecked) + item.setChecked(false, true); + }); } + }), { Manager: (function() { return manager; diff --git a/apps/common/main/lib/component/Mixtbar.js b/apps/common/main/lib/component/Mixtbar.js index cbee01232..0edc4d482 100644 --- a/apps/common/main/lib/component/Mixtbar.js +++ b/apps/common/main/lib/component/Mixtbar.js @@ -57,7 +57,7 @@ define([ if ( sv || opts == 'right' ) { $boxTabs.animate({scrollLeft: opts == 'left' ? sv - 100 : sv + 100}, 200); } - } + }; function onTabDblclick(e) { this.fireEvent('change:compact', [$(e.target).data('tab')]); @@ -92,6 +92,10 @@ define([ config.tabs = options.tabs; $(document.body).on('click', onClickDocument.bind(this)); + + Common.NotificationCenter.on('tab:visible', _.bind(function(action, visible){ + this.setVisible(action, visible) + }, this)); }, afterRender: function() { @@ -108,6 +112,7 @@ define([ $scrollR.on('click', onScrollTabs.bind(this, 'right')); $boxTabs.on('dblclick', '> .ribtab', onTabDblclick.bind(this)); + $boxTabs.on('click', '> .ribtab', me.onTabClick.bind(this)); }, isTabActive: function(tag) { @@ -164,6 +169,12 @@ define([ // clearTimeout(optsFold.timer); optsFold.$bar.removeClass('folded'); optsFold.$box.off(); + + var active_panel = optsFold.$box.find('.panel.active'); + if ( active_panel.length ) { + var tab = active_panel.data('tab'); + me.$tabs.find('> a[data-tab=' + tab + ']').parent().toggleClass('active', true); + } } }, @@ -194,6 +205,18 @@ define([ } }, + onTabClick: function (e) { + var _is_active = $(e.currentTarget).hasClass('active'); + if ( _is_active ) { + if ( this.isFolded ) { + // this.collapse(); + } + } else { + var tab = $(e.target).data('tab'); + this.setTab(tab); + } + }, + setTab: function (tab) { if ( !tab ) { onShowFullviewPanel.call(this, false); @@ -234,7 +257,7 @@ define([ return config.tabs[index].action; } - var _tabTemplate = _.template('
  • '); + var _tabTemplate = _.template(''); config.tabs[after + 1] = tab; var _after_action = _get_tab_action(after); @@ -269,13 +292,13 @@ define([ var _left_bound_ = Math.round($boxTabs.offset().left), _right_bound_ = Math.round(_left_bound_ + $boxTabs.width()); - var tab = this.$tabs.filter(':first:visible').get(0); + var tab = this.$tabs.filter(':visible:first').get(0); if ( !tab ) return false; var rect = tab.getBoundingClientRect(); if ( !(Math.round(rect.left) < _left_bound_) ) { - tab = this.$tabs.filter(':last:visible').get(0); + tab = this.$tabs.filter(':visible:last').get(0); rect = tab.getBoundingClientRect(); if (!(Math.round(rect.right) > _right_bound_)) @@ -296,6 +319,11 @@ define([ } } } + }, + + setVisible: function (tab, visible) { + if ( tab && this.$tabs ) + this.$tabs.find('> a[data-tab=' + tab + ']').parent().css('display', visible ? '' : 'none'); } }; }())); diff --git a/apps/common/main/lib/component/SynchronizeTip.js b/apps/common/main/lib/component/SynchronizeTip.js index c8146b1cc..cb1aa968c 100644 --- a/apps/common/main/lib/component/SynchronizeTip.js +++ b/apps/common/main/lib/component/SynchronizeTip.js @@ -43,7 +43,8 @@ define([ options : { target : $(document.body), text : '', - placement: 'right' + placement: 'right', + showLink: true }, template: _.template([ @@ -54,7 +55,9 @@ define([ '
    <%= scope.text %>
    ', '
    ', '', - '', + '<% if ( scope.showLink ) { %>', + '', + '<% } %>', '', '' ].join('')), @@ -65,7 +68,9 @@ define([ Common.UI.BaseView.prototype.initialize.call(this, options); this.target = this.options.target; this.text = !_.isEmpty(this.options.text) ? this.options.text : this.textSynchronize; + this.textLink = !_.isEmpty(this.options.textLink) ? this.options.textLink : this.textDontShow; this.placement = this.options.placement; + this.showLink = this.options.showLink; }, render: function() { @@ -93,10 +98,18 @@ define([ if (this.cmpEl) this.cmpEl.hide(); }, + close: function() { + if (this.cmpEl) this.cmpEl.remove(); + }, + applyPlacement: function () { var showxy = this.target.offset(); - (this.placement == 'top') ? this.cmpEl.css({bottom : Common.Utils.innerHeight() - showxy.top + 'px', right: Common.Utils.innerWidth() - showxy.left - this.target.width()/2 + 'px'}) - : this.cmpEl.css({top : showxy.top + this.target.height()/2 + 'px', left: showxy.left + this.target.width() + 'px'}); + if (this.placement == 'top') + this.cmpEl.css({bottom : Common.Utils.innerHeight() - showxy.top + 'px', right: Common.Utils.innerWidth() - showxy.left - this.target.width()/2 + 'px'}); + else if (this.placement == 'left') + this.cmpEl.css({top : showxy.top + this.target.height()/2 + 'px', right: Common.Utils.innerWidth() - showxy.left - 5 + 'px'}); + else // right + this.cmpEl.css({top : showxy.top + this.target.height()/2 + 'px', left: showxy.left + this.target.width() + 'px'}); }, isVisible: function() { diff --git a/apps/common/main/lib/component/TabBar.js b/apps/common/main/lib/component/TabBar.js index a59a5a208..81db94966 100644 --- a/apps/common/main/lib/component/TabBar.js +++ b/apps/common/main/lib/component/TabBar.js @@ -207,7 +207,7 @@ define([ function dragComplete() { if (!_.isUndefined(me.drag)) { me.drag.tab.$el.css('z-index', ''); - + me.bar.dragging = false; var tab = null; for (var i = me.bar.tabs.length - 1; i >= 0; --i) { tab = me.bar.tabs[i].$el; @@ -254,6 +254,7 @@ define([ _clientX = e.clientX*Common.Utils.zoom(); me.bar = bar; me.drag = {tab: tab, index: index}; + bar.dragging = true; this.calculateBounds(); this.setAbsTabs(); @@ -343,6 +344,8 @@ define([ this.insert(-1, this.saved); delete this.saved; + Common.Gateway.on('processmouse', _.bind(this.onProcessMouse, this)); + this.rendered = true; return this; }, @@ -362,6 +365,14 @@ define([ } }, + onProcessMouse: function(data) { + if (data.type == 'mouseup' && this.dragging) { + var tab = this.getActive(true); + if (tab) + tab.mouseup(); + } + }, + add: function(tabs) { return this.insert(-1, tabs) > 0; }, diff --git a/apps/common/main/lib/component/ThemeColorPalette.js b/apps/common/main/lib/component/ThemeColorPalette.js index 71bc9f127..bfdeae7d2 100644 --- a/apps/common/main/lib/component/ThemeColorPalette.js +++ b/apps/common/main/lib/component/ThemeColorPalette.js @@ -146,6 +146,13 @@ define([ updateCustomColors: function() { var el = $(this.el); if (el) { + var selected = el.find('a.' + this.selectedCls), + color = (selected.length>0 && /color-dynamic/.test(selected[0].className)) ? selected.attr('color') : undefined; + if (color) { // custom color was selected + color = color.toUpperCase(); + selected.removeClass(this.selectedCls); + } + var colors = Common.localStorage.getItem('asc.'+Common.localStorage.getId()+'.colors.custom'); colors = colors ? colors.split(',') : []; @@ -156,6 +163,10 @@ define([ colorEl.find('span').css({ 'background-color': '#'+colors[i] }); + if (colors[i] == color) { + colorEl.addClass(this.selectedCls); + color = undefined; //select only first found color + } } } }, diff --git a/apps/common/main/lib/component/Window.js b/apps/common/main/lib/component/Window.js index 9a6cbef9e..acfec692b 100644 --- a/apps/common/main/lib/component/Window.js +++ b/apps/common/main/lib/component/Window.js @@ -294,6 +294,13 @@ define([ } } + function _onProcessMouse(data) { + if (data.type == 'mouseup' && this.dragging.enabled) { + _mouseup.call(this); + } + } + + /* window resize functions */ function _resizestart(event) { Common.UI.Menu.Manager.hideAll(); @@ -580,6 +587,9 @@ define([ }; this.$window.find('.header').on('mousedown', this.binding.dragStart); this.$window.find('.tool.close').on('click', _.bind(doclose, this)); + + if (!this.initConfig.modal) + Common.Gateway.on('processmouse', _.bind(_onProcessMouse, this)); } else { this.$window.find('.body').css({ top:0, diff --git a/apps/common/main/lib/controller/Chat.js b/apps/common/main/lib/controller/Chat.js index 2abb2bd0b..25697ac19 100644 --- a/apps/common/main/lib/controller/Chat.js +++ b/apps/common/main/lib/controller/Chat.js @@ -112,7 +112,7 @@ define([ return this; }, - onUsersChanged: function(users){ + onUsersChanged: function(users, currentUserId){ if (!this.mode.canLicense || !this.mode.canCoAuthoring) { var len = 0; for (name in users) { @@ -146,13 +146,14 @@ define([ if (undefined !== name) { user = users[name]; if (user) { - arrUsers.push(new Common.Models.User({ + var usermodel = new Common.Models.User({ id : user.asc_getId(), username : user.asc_getUserName(), online : true, color : user.asc_getColor(), view : user.asc_getView() - })); + }); + arrUsers[(user.asc_getId() == currentUserId ) ? 'unshift' : 'push'](usermodel); } } } diff --git a/apps/common/main/lib/controller/Plugins.js b/apps/common/main/lib/controller/Plugins.js index c5d98ef50..f783c7898 100644 --- a/apps/common/main/lib/controller/Plugins.js +++ b/apps/common/main/lib/controller/Plugins.js @@ -173,6 +173,8 @@ define([ arr.push(plugin); }); this.api.asc_pluginsRegister('', arr); + if (storePlugins.length>0) + Common.NotificationCenter.trigger('tab:visible', 'plugins', true); }, onAddPlugin: function (model) { diff --git a/apps/common/main/lib/controller/Protection.js b/apps/common/main/lib/controller/Protection.js new file mode 100644 index 000000000..99e8ac821 --- /dev/null +++ b/apps/common/main/lib/controller/Protection.js @@ -0,0 +1,252 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * Protection.js + * + * Created by Julia Radzhabova on 14.11.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +if (Common === undefined) + var Common = {}; +Common.Controllers = Common.Controllers || {}; + +define([ + 'core', + 'common/main/lib/view/Protection', + 'common/main/lib/view/PasswordDialog', + 'common/main/lib/view/SignDialog', + 'common/main/lib/view/SignSettingsDialog' +], function () { + 'use strict'; + + Common.Controllers.Protection = Backbone.Controller.extend(_.extend({ + models : [], + collections : [ + ], + views : [ + 'Common.Views.Protection' + ], + sdkViewName : '#id_main', + + initialize: function () { + + this.addListeners({ + 'Common.Views.Protection': { + 'protect:password': _.bind(this.onPasswordClick, this), + 'protect:signature': _.bind(this.onSignatureClick, this) + } + }); + }, + onLaunch: function () { + this._state = {}; + + Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); + Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); + }, + setConfig: function (data, api) { + this.setApi(api); + + if (data) { + this.sdkViewName = data['sdkviewname'] || this.sdkViewName; + } + }, + setApi: function (api) { + if (api) { + this.api = api; + + if (this.appConfig.isDesktopApp && this.appConfig.isOffline) { + this.api.asc_registerCallback('asc_onDocumentPassword', _.bind(this.onDocumentPassword, this)); + if (this.appConfig.canProtect) { + Common.NotificationCenter.on('protect:sign', _.bind(this.onSignatureRequest, this)); + Common.NotificationCenter.on('protect:signature', _.bind(this.onSignatureClick, this)); + this.api.asc_registerCallback('asc_onSignatureClick', _.bind(this.onSignatureSign, this)); + this.api.asc_registerCallback('asc_onUpdateSignatures', _.bind(this.onApiUpdateSignatures, this)); + } + } + this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.onCoAuthoringDisconnect, this)); + } + }, + + setMode: function(mode) { + this.appConfig = mode; + + this.view = this.createView('Common.Views.Protection', { + mode: mode + }); + + return this; + }, + + onDocumentPassword: function(hasPassword) { + this.view && this.view.onDocumentPassword(hasPassword); + }, + + SetDisabled: function(state, canProtect) { + this.view && this.view.SetDisabled(state, canProtect); + }, + + onPasswordClick: function(btn, opts){ + switch (opts) { + case 'add': this.addPassword(); break; + case 'delete': this.deletePassword(); break; + } + + Common.NotificationCenter.trigger('edit:complete', this.view); + }, + + onSignatureRequest: function(guid){ + this.api.asc_RequestSign(guid); + }, + + onSignatureClick: function(type, signed, guid){ + switch (type) { + case 'invisible': this.onSignatureRequest('unvisibleAdd'); break; + case 'visible': this.addVisibleSignature(signed, guid); break; + } + }, + + createToolbarPanel: function() { + return this.view.getPanel(); + }, + + getView: function(name) { + return !name && this.view ? + this.view : Backbone.Controller.prototype.getView.call(this, name); + }, + + onAppReady: function (config) { + }, + + addPassword: function() { + var me = this, + win = new Common.Views.PasswordDialog({ + api: me.api, + signType: 'invisible', + handler: function(result, props) { + if (result == 'ok') { + me.api.asc_setCurrentPassword(props); + } + Common.NotificationCenter.trigger('edit:complete'); + } + }); + + win.show(); + }, + + deletePassword: function() { + this.api.asc_resetPassword(); + }, + + addInvisibleSignature: function() { + var me = this, + win = new Common.Views.SignDialog({ + api: me.api, + signType: 'invisible', + handler: function(dlg, result) { + if (result == 'ok') { + var props = dlg.getSettings(); + me.api.asc_Sign(props.certificateId); + } + Common.NotificationCenter.trigger('edit:complete'); + } + }); + + win.show(); + }, + + addVisibleSignature: function(signed, guid) { + var me = this, + win = new Common.Views.SignSettingsDialog({ + type: (!signed) ? 'edit' : 'view', + handler: function(dlg, result) { + if (!signed && result == 'ok') { + me.api.asc_AddSignatureLine2(dlg.getSettings()); + } + Common.NotificationCenter.trigger('edit:complete'); + } + }); + + win.show(); + + if (guid) + win.setSettings(this.api.asc_getSignatureSetup(guid)); + }, + + signVisibleSignature: function(guid, width, height) { + var me = this; + if (_.isUndefined(me.fontStore)) { + me.fontStore = new Common.Collections.Fonts(); + var fonts = me.getApplication().getController('Toolbar').getView('Toolbar').cmbFontName.store.toJSON(); + var arr = []; + _.each(fonts, function(font, index){ + if (!font.cloneid) { + arr.push(_.clone(font)); + } + }); + me.fontStore.add(arr); + } + + var win = new Common.Views.SignDialog({ + api: me.api, + signType: 'visible', + fontStore: me.fontStore, + signSize: {width: width || 0, height: height || 0}, + handler: function(dlg, result) { + if (result == 'ok') { + var props = dlg.getSettings(); + me.api.asc_Sign(props.certificateId, guid, props.images[0], props.images[1]); + } + Common.NotificationCenter.trigger('edit:complete'); + } + }); + + win.show(); + }, + + onSignatureSign: function(guid, width, height, isVisible) { + (isVisible) ? this.signVisibleSignature(guid, width, height) : this.addInvisibleSignature(); + }, + + onApiUpdateSignatures: function(valid, requested){ + this.SetDisabled(valid && valid.length>0, true);// can add invisible signature + }, + + onCoAuthoringDisconnect: function() { + this.SetDisabled(true); + } + + }, Common.Controllers.Protection || {})); +}); \ No newline at end of file diff --git a/apps/common/main/lib/controller/ReviewChanges.js b/apps/common/main/lib/controller/ReviewChanges.js index 93a0a2ba4..2d634f94d 100644 --- a/apps/common/main/lib/controller/ReviewChanges.js +++ b/apps/common/main/lib/controller/ReviewChanges.js @@ -76,7 +76,8 @@ define([ 'reviewchange:delete': _.bind(this.onDeleteClick, this), 'reviewchange:preview': _.bind(this.onBtnPreviewClick, this), 'reviewchanges:view': _.bind(this.onReviewViewClick, this), - 'lang:document': _.bind(this.onDocLanguage, this) + 'lang:document': _.bind(this.onDocLanguage, this), + 'collaboration:coauthmode': _.bind(this.onCoAuthMode, this) }, 'Common.Views.ReviewChangesDialog': { 'reviewchange:accept': _.bind(this.onAcceptClick, this), @@ -94,7 +95,7 @@ define([ Common.NotificationCenter.on('reviewchanges:turn', this.onTurnPreview.bind(this)); Common.NotificationCenter.on('spelling:turn', this.onTurnSpelling.bind(this)); Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); - Common.NotificationCenter.on('api:disconnect', _.bind(this.onApiServerDisconnect, this)); + Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); }, setConfig: function (data, api) { this.setApi(api); @@ -111,7 +112,7 @@ define([ this.api.asc_registerCallback('asc_onShowRevisionsChange', _.bind(this.onApiShowChange, this)); this.api.asc_registerCallback('asc_onUpdateRevisionsChangesPosition', _.bind(this.onApiUpdateChangePosition, this)); } - this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.onApiServerDisconnect, this)); + this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.onCoAuthoringDisconnect, this)); } }, @@ -131,7 +132,7 @@ define([ SetDisabled: function(state) { if (this.dlgChanges) this.dlgChanges.close(); - this.view && this.view.SetDisabled(state); + this.view && this.view.SetDisabled(state, this.langs); }, onApiShowChange: function (sdkchange) { @@ -487,7 +488,7 @@ define([ state = (state == 'on'); this.api.asc_SetTrackRevisions(state); - Common.localStorage.setItem("de-track-changes", state ? 1 : 0); + Common.localStorage.setItem(this.view.appPrefix + "track-changes", state ? 1 : 0); this.view.turnChanges(state); } @@ -497,8 +498,9 @@ define([ state = (state == 'on'); this.view.turnSpelling(state); - Common.localStorage.setItem("de-settings-spellcheck", state ? 1 : 0); + Common.localStorage.setItem(this.view.appPrefix + "settings-spellcheck", state ? 1 : 0); this.api.asc_setSpellCheck(state); + Common.Utils.InternalSettings.set("de-settings-spellcheck", state); }, onReviewViewClick: function(menu, item, e) { @@ -519,6 +521,35 @@ define([ return this._state.previewMode; }, + onCoAuthMode: function(menu, item, e) { + Common.localStorage.setItem(this.view.appPrefix + "settings-coauthmode", item.value); + Common.Utils.InternalSettings.set(this.view.appPrefix + "settings-coauthmode", item.value); + + if (this.api) { + this.api.asc_SetFastCollaborative(item.value==1); + + if (this.api.SetCollaborativeMarksShowType) { + var value = Common.localStorage.getItem(item.value ? this.view.appPrefix + "settings-showchanges-fast" : this.view.appPrefix + "settings-showchanges-strict"); + if (value !== null) + this.api.SetCollaborativeMarksShowType(value == 'all' ? Asc.c_oAscCollaborativeMarksShowType.All : + value == 'none' ? Asc.c_oAscCollaborativeMarksShowType.None : Asc.c_oAscCollaborativeMarksShowType.LastChanges); + else + this.api.SetCollaborativeMarksShowType(item.value ? Asc.c_oAscCollaborativeMarksShowType.None : Asc.c_oAscCollaborativeMarksShowType.LastChanges); + } + + value = Common.localStorage.getItem(this.view.appPrefix + "settings-autosave"); + if (value===null && this.appConfig.customization && this.appConfig.customization.autosave===false) + value = 0; + value = (!item.value && value!==null) ? parseInt(value) : 1; + + Common.localStorage.setItem(this.view.appPrefix + "settings-autosave", value); + Common.Utils.InternalSettings.set(this.view.appPrefix + "settings-autosave", value); + this.api.asc_setAutoSaveGap(value); + } + Common.NotificationCenter.trigger('edit:complete', this.view); + this.view.fireEvent('settings:apply', [this]); + }, + disableEditing: function(disable) { var app = this.getApplication(); app.getController('RightMenu').getView('RightMenu').clearSelection(); @@ -535,8 +566,16 @@ define([ if (comments) comments.setPreviewMode(disable); + leftMenu.getMenu('file').miProtect.setDisabled(disable); + if (this.view) { this.view.$el.find('.no-group-mask').css('opacity', 1); + + this.view.btnsDocLang && this.view.btnsDocLang.forEach(function(button) { + if ( button ) { + button.setDisabled(disable || this.langs.length<1); + } + }, this); } }, @@ -551,7 +590,7 @@ define([ onAppReady: function (config) { var me = this; - if ( me.view && Common.localStorage.getBool("de-settings-spellcheck", true) ) + if ( me.view && Common.localStorage.getBool(me.view.appPrefix + "settings-spellcheck", true) ) me.view.turnSpelling(true); if ( config.canReview ) { @@ -572,7 +611,7 @@ define([ _setReviewStatus(false); } else { me.api.asc_HaveRevisionsChanges() && me.view.markChanges(true); - _setReviewStatus(Common.localStorage.getBool("de-track-changes")); + _setReviewStatus(Common.localStorage.getBool(me.view.appPrefix + "track-changes")); } if ( typeof (me.appConfig.customization) == 'object' && (me.appConfig.customization.showReviewChanges==true) ) { @@ -586,10 +625,19 @@ define([ } }); } + + if (me.view && me.view.btnChat) { + me.getApplication().getController('LeftMenu').leftMenu.btnChat.on('toggle', function(btn, state){ + if (state !== me.view.btnChat.pressed) + me.view.turnChat(state); + }); + + } }, applySettings: function(menu) { - this.view && this.view.turnSpelling( Common.localStorage.getBool("de-settings-spellcheck", true) ); + this.view && this.view.turnSpelling( Common.localStorage.getBool(this.view.appPrefix + "settings-spellcheck", true) ); + this.view && this.view.turnCoAuthMode( Common.localStorage.getBool(this.view.appPrefix + "settings-coauthmode", true) ); }, synchronizeChanges: function() { @@ -600,7 +648,11 @@ define([ setLanguages: function (array) { this.langs = array; - this.view.btnDocLang.setDisabled(this.langs.length<1); + this.view && this.view.btnsDocLang && this.view.btnsDocLang.forEach(function(button) { + if ( button ) { + button.setDisabled(this.langs.length<1); + } + }, this); }, onDocLanguage: function() { @@ -625,7 +677,11 @@ define([ })).show(); }, - onApiServerDisconnect: function() { + onLostEditRights: function() { + this.view && this.view.onLostEditRights(); + }, + + onCoAuthoringDisconnect: function() { this.SetDisabled(true); }, diff --git a/apps/common/main/lib/mods/perfect-scrollbar.js b/apps/common/main/lib/mods/perfect-scrollbar.js index 2bb5896f7..1375e41eb 100644 --- a/apps/common/main/lib/mods/perfect-scrollbar.js +++ b/apps/common/main/lib/mods/perfect-scrollbar.js @@ -317,7 +317,7 @@ var deltaX = e.deltaX * e.deltaFactor || deprecatedDeltaX, deltaY = e.deltaY * e.deltaFactor || deprecatedDeltaY; - if (e && e.target && (e.target.type === 'textarea' || e.target.type === 'input')) { + if (e && e.target && (e.target.type === 'textarea' && !e.target.hasAttribute('readonly') || e.target.type === 'input')) { e.stopImmediatePropagation(); e.preventDefault(); diff --git a/apps/common/main/lib/template/CommentsPopover.template b/apps/common/main/lib/template/CommentsPopover.template index 9ca9e3ed8..e96797333 100644 --- a/apps/common/main/lib/template/CommentsPopover.template +++ b/apps/common/main/lib/template/CommentsPopover.template @@ -5,7 +5,7 @@
    <%=scope.getUserName(username)%>
    <%=date%>
    <% if (!editTextInPopover || hint) { %> -
    <%=scope.pickLink(comment)%>
    + <% } else { %>
    @@ -27,7 +27,7 @@
    <%=scope.getUserName(item.get("username"))%>
    <%=item.get("date")%>
    <% if (!item.get("editTextInPopover")) { %> -
    <%=scope.pickLink(item.get("reply"))%>
    + <% if (!hint) { %>
    <% if (item.get("editable")) { %> diff --git a/apps/common/main/lib/util/LocalStorage.js b/apps/common/main/lib/util/LocalStorage.js index 8b3b1daa8..1b0a86888 100644 --- a/apps/common/main/lib/util/LocalStorage.js +++ b/apps/common/main/lib/util/LocalStorage.js @@ -125,6 +125,9 @@ define(['gateway'], function () { setKeysFilter: function(value) { _filter = value; }, + getKeysFilter: function() { + return _filter; + }, itemExists: _getItemExists, sync: _refresh, save: _save diff --git a/apps/common/main/lib/util/utils.js b/apps/common/main/lib/util/utils.js index da546a159..b30f674dc 100644 --- a/apps/common/main/lib/util/utils.js +++ b/apps/common/main/lib/util/utils.js @@ -101,7 +101,9 @@ Common.Utils = _.extend(new(function() { Shape : 5, Slide : 6, Chart : 7, - MailMerge : 8 + MailMerge : 8, + Signature : 9, + Pivot : 10 }, isMobile = /android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent || navigator.vendor || window.opera), me = this, @@ -700,7 +702,23 @@ Common.Utils.createXhr = function () { } return xmlhttp; -} +}; + +Common.Utils.getConfigJson = function (url) { + if ( url ) { + try { + var xhrObj = Common.Utils.createXhr(); + if ( xhrObj ) { + xhrObj.open('GET', url, false); + xhrObj.send(''); + + return JSON.parse(xhrObj.responseText); + } + } catch (e) {} + } + + return null; +}; Common.Utils.getConfigJson = function (url) { if ( url ) { @@ -724,7 +742,7 @@ Common.Utils.asyncCall = function (callback, scope, args) { })).then(function () { callback.call(scope, args); }); -} +}; // Extend javascript String type String.prototype.strongMatch = function(regExp){ @@ -734,4 +752,20 @@ String.prototype.strongMatch = function(regExp){ } return false; -}; \ No newline at end of file +}; + +Common.Utils.InternalSettings = new(function() { + var settings = {}; + + var _get = function(name) { + return settings[name]; + }, + _set = function(name, value) { + settings[name] = value; + }; + + return { + get: _get, + set: _set + } +}); \ No newline at end of file diff --git a/apps/common/main/lib/view/Comments.js b/apps/common/main/lib/view/Comments.js index bcd4560c8..bfad0b236 100644 --- a/apps/common/main/lib/view/Comments.js +++ b/apps/common/main/lib/view/Comments.js @@ -152,11 +152,11 @@ define([ }, getTextBox: function () { - var text = $(this.el).find('textarea'); + var text = $(this.el).find('textarea:not(.user-message)'); return (text && text.length) ? text : undefined; }, setFocusToTextBox: function (blur) { - var text = $(this.el).find('textarea'); + var text = $(this.el).find('textarea:not(.user-message)'); if (blur) { text.blur(); } else { @@ -169,15 +169,16 @@ define([ } }, getActiveTextBoxVal: function () { - var text = $(this.el).find('textarea'); + var text = $(this.el).find('textarea:not(.user-message)'); return (text && text.length) ? text.val().trim() : ''; }, autoHeightTextBox: function () { var view = this, textBox = this.$el.find('textarea'), domTextBox = null, - minHeight = 50, + $domTextBox = null, lineHeight = 0, + minHeight = 50, scrollPos = 0, oldHeight = 0, newHeight = 0; @@ -186,17 +187,17 @@ define([ scrollPos = $(view.scroller.el).scrollTop(); if (domTextBox.scrollHeight > domTextBox.clientHeight) { - textBox.css({height: (domTextBox.scrollHeight + lineHeight) + 'px'}); + $domTextBox.css({height: (domTextBox.scrollHeight + lineHeight) + 'px'}); parentView.calculateSizeOfContent(); } else { oldHeight = domTextBox.clientHeight; if (oldHeight >= minHeight) { - textBox.css({height: minHeight + 'px'}); + $domTextBox.css({height: minHeight + 'px'}); if (domTextBox.scrollHeight > domTextBox.clientHeight) { newHeight = Math.max(domTextBox.scrollHeight + lineHeight, minHeight); - textBox.css({height: newHeight + 'px'}); + $domTextBox.css({height: newHeight + 'px'}); } parentView.calculateSizeOfContent(); @@ -209,17 +210,23 @@ define([ view.autoScrollToEditButtons(); } + this.textBox = undefined; if (textBox && textBox.length) { - domTextBox = textBox.get(0); - - if (domTextBox) { - lineHeight = parseInt(textBox.css('lineHeight'), 10) * 0.25; - updateTextBoxHeight(); - textBox.bind('input propertychange', updateTextBoxHeight) - } + textBox.each(function(idx, item){ + if (item) { + domTextBox = item; + $domTextBox = $(item); + var isEdited = !$domTextBox.hasClass('user-message'); + lineHeight = isEdited ? parseInt($domTextBox.css('lineHeight'), 10) * 0.25 : 0; + minHeight = isEdited ? 50 : 24; + updateTextBoxHeight(); + if (isEdited) { + $domTextBox.bind('input propertychange', updateTextBoxHeight); + view.textBox = $domTextBox; + } + } + }); } - - this.textBox = textBox; }, clearTextBoxBind: function () { if (this.textBox) { @@ -375,6 +382,7 @@ define([ t.fireEvent('comment:closeEditing'); readdresolves(); + this.autoHeightTextBox(); } else if (btn.hasClass('user-reply')) { t.fireEvent('comment:closeEditing'); @@ -399,6 +407,7 @@ define([ t.fireEvent('comment:closeEditing'); readdresolves(); + this.autoHeightTextBox(); } } else if (btn.hasClass('btn-close', false)) { t.fireEvent('comment:closeEditing', [commentId]); @@ -406,6 +415,7 @@ define([ t.fireEvent('comment:show', [commentId]); readdresolves(); + this.autoHeightTextBox(); } else if (btn.hasClass('btn-inner-edit', false)) { @@ -427,6 +437,7 @@ define([ } readdresolves(); + this.autoHeightTextBox(); } else if (btn.hasClass('btn-inner-close', false)) { if (record.get('dummy')) { @@ -438,11 +449,8 @@ define([ me.saveText(); record.set('hideAddReply', false); this.getTextBox().val(me.textVal); - this.autoHeightTextBox(); } else { - this.clearTextBoxBind(); - t.fireEvent('comment:closeEditing', [commentId]); } @@ -453,6 +461,7 @@ define([ me.calculateSizeOfContent(); readdresolves(); + this.autoHeightTextBox(); } else if (btn.hasClass('btn-resolve', false)) { var tip = btn.data('bs.tooltip'); @@ -461,6 +470,7 @@ define([ t.fireEvent('comment:resolve', [commentId]); readdresolves(); + this.autoHeightTextBox(); } else if (btn.hasClass('btn-resolve-check', false)) { var tip = btn.data('bs.tooltip'); if (tip) tip.dontShow = true; @@ -468,20 +478,21 @@ define([ t.fireEvent('comment:resolve', [commentId]); readdresolves(); + this.autoHeightTextBox(); } } }); me.on({ 'show': function () { - me.commentsView.autoHeightTextBox(); - me.$window.find('textarea').keydown(function (event) { + me.$window.find('textarea:not(.user-message)').keydown(function (event) { if (event.keyCode == Common.UI.Keys.ESC) { me.hide(); } }); }, 'animate:before': function () { - var text = me.$window.find('textarea'); + me.commentsView.autoHeightTextBox(); + var text = me.$window.find('textarea:not(.user-message)'); if (text && text.length) text.focus(); } @@ -889,11 +900,11 @@ define([ }, getTextBox: function () { - var text = $(this.el).find('textarea'); + var text = $(this.el).find('textarea:not(.user-message)'); return (text && text.length) ? text : undefined; }, setFocusToTextBox: function () { - var text = $(this.el).find('textarea'); + var text = $(this.el).find('textarea:not(.user-message)'); if (text && text.length) { var val = text.val(); text.focus(); @@ -902,7 +913,7 @@ define([ } }, getActiveTextBoxVal: function () { - var text = $(this.el).find('textarea'); + var text = $(this.el).find('textarea:not(.user-message)'); return (text && text.length) ? text.val().trim() : ''; }, autoHeightTextBox: function () { diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js index 42fdf831c..792c70ff7 100644 --- a/apps/common/main/lib/view/Header.js +++ b/apps/common/main/lib/view/Header.js @@ -70,7 +70,9 @@ define([ ''); var templateRightBox = '
    ' + - '
    ' + + '
    ' + + '' + + '
    ' + '<%= textSaveEnd %>' + '
    ' + '
    ' + @@ -394,12 +396,13 @@ define([ if ( this.labelDocName ) this.labelDocName.off(); this.labelDocName = $html.find('#rib-doc-name'); - this.labelDocName.on({ - 'keydown': onDocNameKeyDown.bind(this) - }); + // this.labelDocName.attr('maxlength', 50); + this.labelDocName.text = function (text) { + this.val(text).attr('size', text.length); + } if ( this.documentCaption ) { - this.labelDocName.val( this.documentCaption ); + this.labelDocName.text( this.documentCaption ); } if ( !_.isUndefined(this.options.canRename) ) { @@ -497,8 +500,8 @@ define([ this.documentCaption = value; this.isModified && (value += '*'); if ( this.labelDocName ) { - this.labelDocName.val( value ); - this.labelDocName.attr('size', value.length); + this.labelDocName.text( value ); + // this.labelDocName.attr('size', value.length); this.setCanRename(true); } @@ -516,7 +519,7 @@ define([ var _name = this.documentCaption; changed && (_name += '*'); - this.labelDocName.val(_name); + this.labelDocName.text(_name); }, setCanBack: function (value) { @@ -541,7 +544,16 @@ define([ title: me.txtRename, placement: 'cursor'} ); + + label.on({ + 'keydown': onDocNameKeyDown.bind(this), + 'blur': function (e) { + + } + }); + } else { + label.off(); label.attr('disabled', true); var tip = label.data('bs.tooltip'); if ( tip ) { diff --git a/apps/common/main/lib/view/PasswordDialog.js b/apps/common/main/lib/view/PasswordDialog.js new file mode 100644 index 000000000..c88765c2e --- /dev/null +++ b/apps/common/main/lib/view/PasswordDialog.js @@ -0,0 +1,170 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * OpenDialog.js + * + * Select Codepage for open CSV/TXT format file. + * + * Created by Alexey.Musinov on 29/04/14 + * Copyright (c) 2014 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'common/main/lib/component/Window' +], function () { + 'use strict'; + + Common.Views.PasswordDialog = Common.UI.Window.extend(_.extend({ + + applyFunction: undefined, + + initialize : function (options) { + var t = this, + _options = {}; + + _.extend(_options, { + closable: false, + width : 350, + height : 220, + header : true, + cls : 'modal-dlg', + contentTemplate : '', + title : t.txtTitle + + }, options); + + this.template = options.template || [ + '
    ', + '
    ', + '', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '
    ', + '' + ].join(''); + + this.handler = options.handler; + this.settings = options.settings; + + _options.tpl = _.template(this.template)(_options); + + Common.UI.Window.prototype.initialize.call(this, _options); + }, + render: function () { + Common.UI.Window.prototype.render.call(this); + + if (this.$window) { + var me = this; + this.$window.find('.tool').hide(); + this.$window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this)); + this.inputPwd = new Common.UI.InputField({ + el: $('#id-password-txt'), + type: 'password', + allowBlank : false, + style : 'width: 100%;', + validateOnBlur: false + }); + this.repeatPwd = new Common.UI.InputField({ + el: $('#id-repeat-txt'), + type: 'password', + allowBlank : false, + style : 'width: 100%;', + validateOnBlur: false, + validation : function(value) { + return me.txtIncorrectPwd; + } + }); + this.$window.find('input').on('keypress', _.bind(this.onKeyPress, this)); + } + }, + + show: function() { + Common.UI.Window.prototype.show.apply(this, arguments); + + var me = this; + setTimeout(function(){ + me.inputPwd.cmpEl.find('input').focus(); + }, 500); + }, + + onKeyPress: function(event) { + if (event.keyCode == Common.UI.Keys.RETURN) { + this._handleInput('ok'); + } + }, + + onBtnClick: function(event) { + this._handleInput(event.currentTarget.attributes['result'].value); + }, + + _handleInput: function(state) { + if (this.handler) { + if (state == 'ok') { + if (this.inputPwd.checkValidate() !== true) { + this.inputPwd.cmpEl.find('input').focus(); + return; + } + if (this.inputPwd.getValue() !== this.repeatPwd.getValue()) { + this.repeatPwd.checkValidate(); + this.repeatPwd.cmpEl.find('input').focus(); + return; + } + } + this.handler.call(this, state, this.inputPwd.getValue()); + } + + this.close(); + }, + + okButtonText : "OK", + cancelButtonText : "Cancel", + txtTitle : "Set Password", + txtPassword : "Password", + txtDescription : "A Password is required to open this document", + txtRepeat: 'Repeat password', + txtIncorrectPwd: 'Confirmation password is not identical' + + }, Common.Views.PasswordDialog || {})); +}); \ No newline at end of file diff --git a/apps/common/main/lib/view/Protection.js b/apps/common/main/lib/view/Protection.js new file mode 100644 index 000000000..b66853b11 --- /dev/null +++ b/apps/common/main/lib/view/Protection.js @@ -0,0 +1,314 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * Protection.js + * + * Created by Julia Radzhabova on 14.11.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +if (Common === undefined) + var Common = {}; + +Common.Views = Common.Views || {}; + +define([ + 'common/main/lib/util/utils', + 'common/main/lib/component/BaseView', + 'common/main/lib/component/Layout', + 'common/main/lib/component/Window' +], function (template) { + 'use strict'; + + Common.Views.Protection = Common.UI.BaseView.extend(_.extend((function(){ + var template = + '
    ' + + '
    ' + + '' + + '' + + '' + + '
    ' + + '
    '; + + function setEvents() { + var me = this; + + if ( me.appConfig.isDesktopApp && me.appConfig.isOffline ) { + this.btnsAddPwd.concat(this.btnsChangePwd).forEach(function(button) { + button.on('click', function (b, e) { + me.fireEvent('protect:password', [b, 'add']); + }); + }); + + this.btnsDelPwd.forEach(function(button) { + button.on('click', function (b, e) { + me.fireEvent('protect:password', [b, 'delete']); + }); + }); + + this.btnPwd.menu.on('item:click', function (menu, item, e) { + me.fireEvent('protect:password', [menu, item.value]); + }); + + if (me.appConfig.canProtect) { + if (this.btnSignature.menu) + this.btnSignature.menu.on('item:click', function (menu, item, e) { + me.fireEvent('protect:signature', [item.value, false]); + }); + + this.btnsInvisibleSignature.forEach(function(button) { + button.on('click', function (b, e) { + me.fireEvent('protect:signature', ['invisible']); + }); + }); + } + } + } + + return { + + options: {}, + + initialize: function (options) { + Common.UI.BaseView.prototype.initialize.call(this, options); + + this.appConfig = options.mode; + + this.btnsInvisibleSignature = []; + this.btnsAddPwd = []; + this.btnsDelPwd = []; + this.btnsChangePwd = []; + + this._state = {disabled: false, hasPassword: false}; + + var filter = Common.localStorage.getKeysFilter(); + this.appPrefix = (filter && filter.length) ? filter.split(',')[0] : ''; + + if ( this.appConfig.isDesktopApp && this.appConfig.isOffline ) { + this.btnAddPwd = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-protect', + caption: this.txtEncrypt + }); + this.btnsAddPwd.push(this.btnAddPwd); + + this.btnPwd = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-protect', + caption: this.txtEncrypt, + menu: true, + visible: false + }); + + if (this.appConfig.canProtect) { + this.btnSignature = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-signature', + caption: this.txtSignature, + menu: (this.appPrefix !== 'pe-') + }); + if (!this.btnSignature.menu) + this.btnsInvisibleSignature.push(this.btnSignature); + } + } + + Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); + }, + + render: function (el) { + this.boxSdk = $('#editor_sdk'); + if ( el ) el.html( this.getPanel() ); + + return this; + }, + + onAppReady: function (config) { + var me = this; + (new Promise(function (accept, reject) { + accept(); + })).then(function(){ + if ( config.isDesktopApp && config.isOffline) { + me.btnAddPwd.updateHint(me.hintAddPwd); + me.btnPwd.updateHint(me.hintPwd); + + me.btnPwd.setMenu( + new Common.UI.Menu({ + items: [ + { + caption: me.txtChangePwd, + value: 'add' + }, + { + caption: me.txtDeletePwd, + value: 'delete' + } + ] + }) + ); + + if (me.btnSignature) { + me.btnSignature.updateHint((me.btnSignature.menu) ? me.hintSignature : me.txtInvisibleSignature); + me.btnSignature.menu && me.btnSignature.setMenu( + new Common.UI.Menu({ + items: [ + { + caption: me.txtInvisibleSignature, + value: 'invisible' + }, + { + caption: me.txtSignatureLine, + value: 'visible', + disabled: me._state.disabled + } + ] + }) + ); + } + Common.NotificationCenter.trigger('tab:visible', 'protect', true); + } + + setEvents.call(me); + }); + }, + + getPanel: function () { + this.$el = $(_.template(template)( {} )); + + if ( this.appConfig.isDesktopApp && this.appConfig.isOffline ) { + this.btnAddPwd.render(this.$el.find('#slot-btn-add-password')); + this.btnPwd.render(this.$el.find('#slot-btn-change-password')); + this.btnSignature && this.btnSignature.render(this.$el.find('#slot-btn-signature')); + } + return this.$el; + }, + + show: function () { + Common.UI.BaseView.prototype.show.call(this); + this.fireEvent('show', this); + }, + + getButton: function(type, parent) { + if ( type == 'signature' ) { + var button = new Common.UI.Button({ + cls: 'btn-text-default', + style: 'width: 100%;', + caption: this.txtInvisibleSignature, + disabled: this._state.disabled + }); + this.btnsInvisibleSignature.push(button); + + return button; + } else if ( type == 'add-password' ) { + var button = new Common.UI.Button({ + cls: 'btn-text-default', + style: 'width: 100%;', + caption: this.txtAddPwd, + disabled: this._state.disabled, + visible: !this._state.hasPassword + }); + this.btnsAddPwd.push(button); + + return button; + } else if ( type == 'del-password' ) { + var button = new Common.UI.Button({ + cls: 'btn-text-default', + style: 'width: 100%;', + caption: this.txtDeletePwd, + disabled: this._state.disabled, + visible: this._state.hasPassword + }); + this.btnsDelPwd.push(button); + + return button; + } else if ( type == 'change-password' ) { + var button = new Common.UI.Button({ + cls: 'btn-text-default', + style: 'width: 100%;', + caption: this.txtChangePwd, + disabled: this._state.disabled, + visible: this._state.hasPassword + }); + this.btnsChangePwd.push(button); + + return button; + } + }, + + SetDisabled: function (state, canProtect) { + this._state.disabled = state; + this.btnsInvisibleSignature && this.btnsInvisibleSignature.forEach(function(button) { + if ( button ) { + button.setDisabled(state && !canProtect); + } + }, this); + if (this.btnSignature && this.btnSignature.menu) { + this.btnSignature.menu.items && this.btnSignature.menu.items[1].setDisabled(state); // disable adding signature line + this.btnSignature.setDisabled(state && !canProtect); // disable adding any signature + } + this.btnsAddPwd.concat(this.btnsDelPwd, this.btnsChangePwd).forEach(function(button) { + if ( button ) { + button.setDisabled(state); + } + }, this); + }, + + onDocumentPassword: function (hasPassword) { + this._state.hasPassword = hasPassword; + this.btnsAddPwd && this.btnsAddPwd.forEach(function(button) { + if ( button ) { + button.setVisible(!hasPassword); + } + }, this); + this.btnsDelPwd.concat(this.btnsChangePwd).forEach(function(button) { + if ( button ) { + button.setVisible(hasPassword); + } + }, this); + this.btnPwd.setVisible(hasPassword); + }, + + txtEncrypt: 'Encrypt', + txtSignature: 'Signature', + hintAddPwd: 'Encrypt with password', + hintPwd: 'Change or delete password', + hintSignature: 'Add digital signature or signature line', + txtChangePwd: 'Change password', + txtDeletePwd: 'Delete password', + txtAddPwd: 'Add password', + txtInvisibleSignature: 'Add digital signature', + txtSignatureLine: 'Signature line' + } + }()), Common.Views.Protection || {})); +}); \ No newline at end of file diff --git a/apps/common/main/lib/view/ReviewChanges.js b/apps/common/main/lib/view/ReviewChanges.js index 852e57d28..02e3ccf9e 100644 --- a/apps/common/main/lib/view/ReviewChanges.js +++ b/apps/common/main/lib/view/ReviewChanges.js @@ -412,30 +412,35 @@ define([ Common.Views.ReviewChanges = Common.UI.BaseView.extend(_.extend((function(){ var template = '
    ' + - '
    ' + - '' + + '
    ' + + '' + + '' + '
    ' + - '
    ' + - '' + - '
    ' + - '
    ' + + '
    '; function setEvents() { @@ -489,8 +494,26 @@ define([ }); }); - this.btnDocLang.on('click', function (btn, e) { - me.fireEvent('lang:document', this); + this.btnsDocLang.forEach(function(button) { + button.on('click', function (b, e) { + me.fireEvent('lang:document', this); + }); + }); + + this.btnSharing && this.btnSharing.on('click', function (btn, e) { + Common.NotificationCenter.trigger('collaboration:sharing'); + }); + + this.btnCoAuthMode && this.btnCoAuthMode.menu.on('item:click', function (menu, item, e) { + me.fireEvent('collaboration:coauthmode', [menu, item]); + }); + + this.btnHistory && this.btnHistory.on('click', function (btn, e) { + Common.NotificationCenter.trigger('collaboration:history'); + }); + + this.btnChat && this.btnChat.on('click', function (btn, e) { + me.fireEvent('collaboration:chat', [btn.pressed]); }); } @@ -549,20 +572,45 @@ define([ }); } - this.btnSetSpelling = new Common.UI.Button({ - cls: 'btn-toolbar x-huge icon-top', - iconCls: 'btn-ic-docspell', - caption: this.txtSpelling, - enableToggle: true - }); - this.btnsSpelling = [this.btnSetSpelling]; + if (!!this.appConfig.sharingSettingsUrl && this.appConfig.sharingSettingsUrl.length && this._readonlyRights!==true) { + this.btnSharing = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-sharing', + caption: this.txtSharing + }); + } - this.btnDocLang = new Common.UI.Button({ - cls: 'btn-toolbar x-huge icon-top', - iconCls: 'btn-ic-doclang', - caption: this.txtDocLang, - disabled: true - }); + if (!this.appConfig.isOffline && this.appConfig.canCoAuthoring) { + this.btnCoAuthMode = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-coedit', + caption: this.txtCoAuthMode, + menu: true + }); + } + + this.btnsSpelling = []; + this.btnsDocLang = []; + + if (this.appConfig.canUseHistory && !this.appConfig.isDisconnected) { + this.btnHistory = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-history', + caption: this.txtHistory + }); + } + + if (this.appConfig.canCoAuthoring && this.appConfig.canChat) { + this.btnChat = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-chat', + caption: this.txtChat, + enableToggle: true + }); + } + + var filter = Common.localStorage.getKeysFilter(); + this.appPrefix = (filter && filter.length) ? filter.split(',')[0] : ''; Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); }, @@ -579,6 +627,10 @@ define([ (new Promise(function (accept, reject) { accept(); })).then(function(){ + var menuTemplate = _.template('
    <%= caption %>
    ' + + '<% if (options.description !== null) { %>' + + '<% } %>
    '); + if ( config.canReview ) { me.btnPrev.updateHint(me.hintPrev); me.btnNext.updateHint(me.hintNext); @@ -621,24 +673,30 @@ define([ cls: 'ppm-toolbar', items: [ { - caption: me.txtMarkup, + caption: me.txtMarkupCap, checkable: true, toggleGroup: 'menuReviewView', checked: true, - value: 'markup' + value: 'markup', + template: menuTemplate, + description: me.txtMarkup }, { - caption: me.txtFinal, + caption: me.txtFinalCap, checkable: true, toggleGroup: 'menuReviewView', checked: false, + template: menuTemplate, + description: me.txtFinal, value: 'final' }, { - caption: me.txtOriginal, + caption: me.txtOriginalCap, checkable: true, toggleGroup: 'menuReviewView', checked: false, + template: menuTemplate, + description: me.txtOriginal, value: 'original' } ] @@ -647,20 +705,78 @@ define([ me.btnAccept.setDisabled(config.isReviewOnly); me.btnReject.setDisabled(config.isReviewOnly); - } else { - me.$el.find('.separator.review') - .hide() - .next('.group').hide(); } - if ( !config.canComments || !config.canCoAuthoring) { - $('.separator.comments', me.$el) - .hide() - .next('.group').hide(); + me.btnSharing && me.btnSharing.updateHint(me.tipSharing); + me.btnHistory && me.btnHistory.updateHint(me.tipHistory); + me.btnChat && me.btnChat.updateHint(me.txtChat + Common.Utils.String.platformKey('Alt+Q')); + + if (me.btnCoAuthMode) { + me.btnCoAuthMode.setMenu( + new Common.UI.Menu({ + cls: 'ppm-toolbar', + style: 'max-width: 220px;', + items: [ + { + caption: me.strFast, + checkable: true, + toggleGroup: 'menuCoauthMode', + checked: true, + template: menuTemplate, + description: me.strFastDesc, + value: 1 + }, + { + caption: me.strStrict, + checkable: true, + toggleGroup: 'menuCoauthMode', + checked: false, + template: menuTemplate, + description: me.strStrictDesc, + value: 0 + } + ] + })); + me.btnCoAuthMode.updateHint(me.tipCoAuthMode); + + var value = Common.localStorage.getItem(me.appPrefix + "settings-coauthmode"); + if (value===null && !Common.localStorage.itemExists(me.appPrefix + "settings-autosave") && + config.customization && config.customization.autosave===false) { + value = 0; // use customization.autosave only when de-settings-coauthmode and de-settings-autosave are null + } + me.turnCoAuthMode((value===null || parseInt(value) == 1) && !(config.isDesktopApp && config.isOffline) && config.canCoAuthoring); } - me.btnDocLang.updateHint(me.tipSetDocLang); - me.btnSetSpelling.updateHint(me.tipSetSpelling); + var separator_sharing = !(me.btnSharing || me.btnCoAuthMode) ? me.$el.find('.separator.sharing') : '.separator.sharing', + separator_comments = !(config.canComments && config.canCoAuthoring) ? me.$el.find('.separator.comments') : '.separator.comments', + separator_review = !config.canReview ? me.$el.find('.separator.review') : '.separator.review', + separator_chat = !me.btnChat ? me.$el.find('.separator.chat') : '.separator.chat', + separator_last; + + if (typeof separator_sharing == 'object') + separator_sharing.hide().prev('.group').hide(); + else + separator_last = separator_sharing; + + if (typeof separator_comments == 'object') + separator_comments.hide().prev('.group').hide(); + else + separator_last = separator_comments; + + if (typeof separator_review == 'object') + separator_review.hide().prevUntil('.separator.comments').hide(); + else + separator_last = separator_review; + + if (typeof separator_chat == 'object') + separator_chat.hide().prev('.group').hide(); + else + separator_last = separator_chat; + + if (!me.btnHistory && separator_last) + me.$el.find(separator_last).hide(); + + Common.NotificationCenter.trigger('tab:visible', 'review', true); setEvents.call(me); }); @@ -678,8 +794,10 @@ define([ this.btnReviewView.render(this.$el.find('#btn-review-view')); } - this.btnSetSpelling.render(this.$el.find('#slot-btn-spelling')); - this.btnDocLang.render(this.$el.find('#slot-set-lang')); + this.btnSharing && this.btnSharing.render(this.$el.find('#slot-btn-sharing')); + this.btnCoAuthMode && this.btnCoAuthMode.render(this.$el.find('#slot-btn-coauthmode')); + this.btnHistory && this.btnHistory.render(this.$el.find('#slot-btn-history')); + this.btnChat && this.btnChat.render(this.$el.find('#slot-btn-chat')); return this.$el; }, @@ -725,6 +843,17 @@ define([ }); this.btnsSpelling.push(button); + return button; + } else if (type == 'doclang' && parent == 'statusbar' ) { + button = new Common.UI.Button({ + cls: 'btn-toolbar', + iconCls: 'btn-ic-doclang', + hintAnchor : 'top', + hint: this.tipSetDocLang, + disabled: true + }); + this.btnsDocLang.push(button); + return button; } }, @@ -758,17 +887,42 @@ define([ }, this); }, - SetDisabled: function (state) { + turnCoAuthMode: function (fast) { + if (this.btnCoAuthMode) { + this.btnCoAuthMode.menu.items[0].setChecked(fast, true); + this.btnCoAuthMode.menu.items[1].setChecked(!fast, true); + } + }, + + turnChat: function (state) { + this.btnChat && this.btnChat.toggle(state, true); + }, + + SetDisabled: function (state, langs) { this.btnsSpelling && this.btnsSpelling.forEach(function(button) { if ( button ) { button.setDisabled(state); } }, this); + this.btnsDocLang && this.btnsDocLang.forEach(function(button) { + if ( button ) { + button.setDisabled(state || langs && langs.length<1); + } + }, this); this.btnsTurnReview && this.btnsTurnReview.forEach(function(button) { if ( button ) { button.setDisabled(state); } }, this); + this.btnChat && this.btnChat.setDisabled(state); + }, + + onLostEditRights: function() { + this._readonlyRights = true; + if (!this.rendered) + return; + + this.btnSharing && this.btnSharing.setDisabled(true); }, txtAccept: 'Accept', @@ -790,12 +944,26 @@ define([ txtAcceptChanges: 'Accept Changes', txtRejectChanges: 'Reject Changes', txtView: 'Display Mode', - txtMarkup: 'All changes (Editing)', - txtFinal: 'All changes accepted (Preview)', - txtOriginal: 'All changes rejected (Preview)', + txtMarkup: 'Text with changes (Editing)', + txtFinal: 'All changes like accept (Preview)', + txtOriginal: 'Text without changes (Preview)', tipReviewView: 'Select the way you want the changes to be displayed', tipAcceptCurrent: 'Accept current changes', - tipRejectCurrent: 'Reject current changes' + tipRejectCurrent: 'Reject current changes', + txtSharing: 'Sharing', + tipSharing: 'Manage document access rights', + txtCoAuthMode: 'Co-editing Mode', + tipCoAuthMode: 'Set co-editing mode', + strFast: 'Fast', + strStrict: 'Strict', + txtHistory: 'Version History', + tipHistory: 'Show version history', + txtChat: 'Chat', + txtMarkupCap: 'Markup', + txtFinalCap: 'Final', + txtOriginalCap: 'Original', + strFastDesc: 'Real-time co-editing. All changes are saved automatically.', + strStrictDesc: 'Use the \'Save\' button to sync the changes you and others make.' } }()), Common.Views.ReviewChanges || {})); diff --git a/apps/common/main/lib/view/SignDialog.js b/apps/common/main/lib/view/SignDialog.js new file mode 100644 index 000000000..2ce0863ac --- /dev/null +++ b/apps/common/main/lib/view/SignDialog.js @@ -0,0 +1,358 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * SignDialog.js + * + * Created by Julia Radzhabova on 5/19/17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + + +if (Common === undefined) + var Common = {}; + +define([ + 'common/main/lib/util/utils', + 'common/main/lib/component/InputField', + 'common/main/lib/component/Window', + 'common/main/lib/component/ComboBoxFonts' +], function () { 'use strict'; + + Common.Views.SignDialog = Common.UI.Window.extend(_.extend({ + options: { + width: 350, + style: 'min-width: 350px;', + cls: 'modal-dlg' + }, + + initialize : function(options) { + _.extend(this.options, { + title: this.textTitle + }, options || {}); + + this.api = this.options.api; + this.signType = this.options.signType || 'invisible'; + this.signSize = this.options.signSize || {width: 0, height: 0}; + this.certificateId = null; + this.signObject = null; + this.fontStore = this.options.fontStore; + this.font = { + size: 11, + name: 'Arial', + bold: false, + italic: false + }; + + this.template = [ + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ','
    ', + '
    ', + '', + '
    ', + '', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '', + '' + + '', + '', + '', + '
    ', + '
    ', + '' + ].join(''); + + this.templateCertificate = _.template([ + '', + '' + ].join('')); + + this.options.tpl = _.template(this.template)(this.options); + + Common.UI.Window.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.UI.Window.prototype.render.call(this); + + var me = this, + $window = this.getChild(); + + me.inputPurpose = new Common.UI.InputField({ + el : $('#id-dlg-sign-purpose'), + style : 'width: 100%;' + }); + + me.inputName = new Common.UI.InputField({ + el : $('#id-dlg-sign-name'), + style : 'width: 100%;', + validateOnChange: true + }).on ('changing', _.bind(me.onChangeName, me)); + + me.cmbFonts = new Common.UI.ComboBoxFonts({ + el : $('#id-dlg-sign-fonts'), + cls : 'input-group-nr', + style : 'width: 214px;', + menuCls : 'scrollable-menu', + menuStyle : 'min-width: 55px;max-height: 270px;', + store : new Common.Collections.Fonts(), + recent : 0, + hint : me.tipFontName + }).on('selected', function(combo, record) { + if (me.signObject) { + me.signObject.setText(me.inputName.getValue(), record.name, me.font.size, me.font.italic, me.font.bold); + } + me.font.name = record.name; + }); + + this.cmbFontSize = new Common.UI.ComboBox({ + el: $('#id-dlg-sign-font-size'), + cls: 'input-group-nr', + style: 'width: 55px;', + menuCls : 'scrollable-menu', + menuStyle: 'min-width: 55px;max-height: 270px;', + hint: this.tipFontSize, + data: [ + { value: 8, displayValue: "8" }, + { value: 9, displayValue: "9" }, + { value: 10, displayValue: "10" }, + { value: 11, displayValue: "11" }, + { value: 12, displayValue: "12" }, + { value: 14, displayValue: "14" }, + { value: 16, displayValue: "16" }, + { value: 18, displayValue: "18" }, + { value: 20, displayValue: "20" }, + { value: 22, displayValue: "22" }, + { value: 24, displayValue: "24" }, + { value: 26, displayValue: "26" }, + { value: 28, displayValue: "28" }, + { value: 36, displayValue: "36" }, + { value: 48, displayValue: "48" }, + { value: 72, displayValue: "72" } + ] + }).on('selected', function(combo, record) { + if (me.signObject) { + me.signObject.setText(me.inputName.getValue(), me.font.name, record.value, me.font.italic, me.font.bold); + } + me.font.size = record.value; + }); + this.cmbFontSize.setValue(this.font.size); + + me.btnBold = new Common.UI.Button({ + cls: 'btn-toolbar', + iconCls: 'btn-bold', + enableToggle: true, + hint: me.textBold + }); + me.btnBold.render($('#id-dlg-sign-bold')) ; + me.btnBold.on('click', function(btn, e) { + if (me.signObject) { + me.signObject.setText(me.inputName.getValue(), me.font.name, me.font.size, me.font.italic, btn.pressed); + } + me.font.bold = btn.pressed; + }); + + me.btnItalic = new Common.UI.Button({ + cls: 'btn-toolbar', + iconCls: 'btn-italic', + enableToggle: true, + hint: me.textItalic + }); + me.btnItalic.render($('#id-dlg-sign-italic')) ; + me.btnItalic.on('click', function(btn, e) { + if (me.signObject) { + me.signObject.setText(me.inputName.getValue(), me.font.name, me.font.size, btn.pressed, me.font.bold); + } + me.font.italic = btn.pressed; + }); + + me.btnSelectImage = new Common.UI.Button({ + el: '#id-dlg-sign-image' + }); + me.btnSelectImage.on('click', _.bind(me.onSelectImage, me)); + + me.btnChangeCertificate = new Common.UI.Button({ + el: '#id-dlg-sign-change' + }); + me.btnChangeCertificate.on('click', _.bind(me.onChangeCertificate, me)); + + me.btnOk = new Common.UI.Button({ + el: $window.find('.primary'), + disabled: true + }); + + me.cntCertificate = $('#id-dlg-sign-certificate'); + me.cntVisibleSign = $('#id-dlg-sign-visible'); + me.cntInvisibleSign = $('#id-dlg-sign-invisible'); + + (me.signType == 'visible') ? me.cntInvisibleSign.addClass('hidden') : me.cntVisibleSign.addClass('hidden'); + + $window.find('.dlg-btn').on('click', _.bind(me.onBtnClick, me)); + $window.find('input').on('keypress', _.bind(me.onKeyPress, me)); + + me.afterRender(); + }, + + show: function() { + Common.UI.Window.prototype.show.apply(this, arguments); + + var me = this; + _.delay(function(){ + ((me.signType == 'visible') ? me.inputName : me.inputPurpose).cmpEl.find('input').focus(); + },500); + }, + + close: function() { + this.api.asc_unregisterCallback('on_signature_defaultcertificate_ret', this.binding.certificateChanged); + this.api.asc_unregisterCallback('on_signature_selectsertificate_ret', this.binding.certificateChanged); + + Common.UI.Window.prototype.close.apply(this, arguments); + + if (this.signObject) + this.signObject.destroy(); + }, + + afterRender: function () { + if (this.api) { + this.binding = { + certificateChanged: _.bind(this.onCertificateChanged, this) + }; + this.api.asc_registerCallback('on_signature_defaultcertificate_ret', this.binding.certificateChanged); + this.api.asc_registerCallback('on_signature_selectsertificate_ret', this.binding.certificateChanged); + this.api.asc_GetDefaultCertificate(); + } + + if (this.signType == 'visible') { + this.cmbFonts.fillFonts(this.fontStore); + this.cmbFonts.selectRecord(this.fontStore.findWhere({name: this.font.name}) || this.fontStore.at(0)); + + this.signObject = new AscCommon.CSignatureDrawer('signature-preview-img', this.api, this.signSize.width, this.signSize.height); + } + }, + + getSettings: function () { + var props = {}; + props.certificateId = this.certificateId; + if (this.signType == 'invisible') { + props.purpose = this.inputPurpose.getValue(); + } else { + props.images = this.signObject ? this.signObject.getImages() : [null, null]; + } + + return props; + }, + + onBtnClick: function(event) { + this._handleInput(event.currentTarget.attributes['result'].value); + }, + + onKeyPress: function(event) { + if (event.keyCode == Common.UI.Keys.RETURN) { + this._handleInput('ok'); + return false; + } + }, + + _handleInput: function(state) { + if (this.options.handler) { + if (state == 'ok' && (this.btnOk.isDisabled() || this.signObject && !this.signObject.isValid())) + return; + + this.options.handler.call(this, this, state); + } + this.close(); + }, + + onChangeCertificate: function() { + this.api.asc_SelectCertificate(); + }, + + onCertificateChanged: function(certificate) { + this.certificateId = certificate.id; + var date = certificate.date, + arr_date = (typeof date == 'string') ? date.split(' - ') : ['', '']; + this.cntCertificate.html(this.templateCertificate({name: certificate.name, valid: this.textValid.replace('%1', arr_date[0]).replace('%2', arr_date[1])})); + this.cntCertificate.toggleClass('hidden', _.isEmpty(this.certificateId) || this.certificateId<0); + this.btnOk.setDisabled(_.isEmpty(this.certificateId) || this.certificateId<0); + }, + + onSelectImage: function() { + if (!this.signObject) return; + this.signObject.selectImage(); + this.inputName.setValue(''); + }, + + onChangeName: function (input, value) { + if (!this.signObject) return; + this.signObject.setText(value, this.font.name, this.font.size, this.font.italic, this.font.bold); + }, + + textTitle: 'Sign Document', + textPurpose: 'Purpose for signing this document', + textCertificate: 'Certificate', + textValid: 'Valid from %1 to %2', + textChange: 'Change', + cancelButtonText: 'Cancel', + okButtonText: 'Ok', + textInputName: 'Input signer name', + textUseImage: 'or click \'Select Image\' to use a picture as signature', + textSelectImage: 'Select Image', + textSignature: 'Signature looks as', + tipFontName: 'Font Name', + tipFontSize: 'Font Size', + textBold: 'Bold', + textItalic: 'Italic' + + }, Common.Views.SignDialog || {})) +}); \ No newline at end of file diff --git a/apps/common/main/lib/view/SignSettingsDialog.js b/apps/common/main/lib/view/SignSettingsDialog.js new file mode 100644 index 000000000..e85b8c3e0 --- /dev/null +++ b/apps/common/main/lib/view/SignSettingsDialog.js @@ -0,0 +1,213 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * SignSettingsDialog.js + * + * Created by Julia Radzhabova on 5/19/17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + + +if (Common === undefined) + var Common = {}; + +define([ + 'common/main/lib/util/utils', + 'common/main/lib/component/InputField', + 'common/main/lib/component/CheckBox', + 'common/main/lib/component/Window' +], function () { 'use strict'; + + Common.Views.SignSettingsDialog = Common.UI.Window.extend(_.extend({ + options: { + width: 350, + style: 'min-width: 350px;', + cls: 'modal-dlg', + type: 'edit' + }, + + initialize : function(options) { + _.extend(this.options, { + title: this.textTitle + }, options || {}); + + this.template = [ + '
    ', + '
    ', + '', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '', + '
    ', + '
    ', + '' + ].join(''); + + this.api = this.options.api; + this.type = this.options.type || 'edit'; + this.options.tpl = _.template(this.template)(this.options); + + Common.UI.Window.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.UI.Window.prototype.render.call(this); + + var me = this, + $window = this.getChild(); + + me.inputName = new Common.UI.InputField({ + el : $('#id-dlg-sign-settings-name'), + style : 'width: 100%;', + disabled : this.type=='view' + }); + + me.inputTitle = new Common.UI.InputField({ + el : $('#id-dlg-sign-settings-title'), + style : 'width: 100%;', + disabled : this.type=='view' + }); + + me.inputEmail = new Common.UI.InputField({ + el : $('#id-dlg-sign-settings-email'), + style : 'width: 100%;', + disabled : this.type=='view' + }); + + me.textareaInstructions = this.$window.find('textarea'); + me.textareaInstructions.keydown(function (event) { + if (event.keyCode == Common.UI.Keys.RETURN) { + event.stopPropagation(); + } + }); + (this.type=='view') ? this.textareaInstructions.attr('disabled', 'disabled') : this.textareaInstructions.removeAttr('disabled'); + this.textareaInstructions.toggleClass('disabled', this.type=='view'); + + this.chDate = new Common.UI.CheckBox({ + el: $('#id-dlg-sign-settings-date'), + labelText: this.textShowDate, + disabled: this.type=='view' + }); + + $window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this)); + $window.find('input').on('keypress', _.bind(this.onKeyPress, this)); + }, + + show: function() { + Common.UI.Window.prototype.show.apply(this, arguments); + + var me = this; + _.delay(function(){ + me.inputName.cmpEl.find('input').focus(); + },500); + }, + + setSettings: function (props) { + if (props) { + var me = this; + + var value = props.asc_getSigner1(); + me.inputName.setValue(value ? value : ''); + value = props.asc_getSigner2(); + me.inputTitle.setValue(value ? value : ''); + value = props.asc_getEmail(); + me.inputEmail.setValue(value ? value : ''); + value = props.asc_getInstructions(); + me.textareaInstructions.val(value ? value : ''); + me.chDate.setValue(props.asc_getShowDate()); + } + }, + + getSettings: function () { + var me = this, + props = new AscCommon.asc_CSignatureLine(); + + props.asc_setSigner1(me.inputName.getValue()); + props.asc_setSigner2(me.inputTitle.getValue()); + props.asc_setEmail(me.inputEmail.getValue()); + props.asc_setInstructions(me.textareaInstructions.val()); + props.asc_setShowDate(me.chDate.getValue()=='checked'); + + return props; + }, + + onBtnClick: function(event) { + this._handleInput(event.currentTarget.attributes['result'].value); + }, + + onKeyPress: function(event) { + if (event.keyCode == Common.UI.Keys.RETURN) { + this._handleInput('ok'); + return false; + } + }, + + _handleInput: function(state) { + if (this.options.handler) + this.options.handler.call(this, this, state); + this.close(); + }, + + textInfo: 'Signer Info', + textInfoName: 'Name', + textInfoTitle: 'Signer Title', + textInfoEmail: 'E-mail', + textInstructions: 'Instructions for Signer', + cancelButtonText: 'Cancel', + okButtonText: 'Ok', + txtEmpty: 'This field is required', + textAllowComment: 'Allow signer to add comment in the signature dialog', + textShowDate: 'Show sign date in signature line', + textTitle: 'Signature Settings' + }, Common.Views.SignSettingsDialog || {})) +}); \ No newline at end of file diff --git a/apps/common/main/resources/img/controls/toolbarbig.png b/apps/common/main/resources/img/controls/toolbarbig.png index d5bbddcae..27c5fc2a2 100644 Binary files a/apps/common/main/resources/img/controls/toolbarbig.png and b/apps/common/main/resources/img/controls/toolbarbig.png differ diff --git a/apps/common/main/resources/img/controls/toolbarbig@2x.png b/apps/common/main/resources/img/controls/toolbarbig@2x.png index 63d5f5de2..98a5c5cbd 100644 Binary files a/apps/common/main/resources/img/controls/toolbarbig@2x.png and b/apps/common/main/resources/img/controls/toolbarbig@2x.png differ diff --git a/apps/common/main/resources/img/header/buttons.svg b/apps/common/main/resources/img/header/buttons.svg index 28656d8d3..3b82b4ee7 100644 --- a/apps/common/main/resources/img/header/buttons.svg +++ b/apps/common/main/resources/img/header/buttons.svg @@ -11,10 +11,10 @@ - + + + + diff --git a/apps/common/main/resources/less/buttons.less b/apps/common/main/resources/less/buttons.less index 61d783629..90545b262 100644 --- a/apps/common/main/resources/less/buttons.less +++ b/apps/common/main/resources/less/buttons.less @@ -155,6 +155,9 @@ } .btn-fixflex-vcenter { + display: flex; + align-items: center; + .caret { vertical-align: inherit; } diff --git a/apps/common/main/resources/less/combo-dataview.less b/apps/common/main/resources/less/combo-dataview.less index d098973e7..4a390c4c3 100644 --- a/apps/common/main/resources/less/combo-dataview.less +++ b/apps/common/main/resources/less/combo-dataview.less @@ -275,4 +275,15 @@ } } } +} + +.combo-pivot-template { + .combo-template(60px); + + margin-top: -6px; + margin-bottom: -6px; + + .view .dataview { + padding: 1px; + } } \ No newline at end of file diff --git a/apps/common/main/resources/less/comments.less b/apps/common/main/resources/less/comments.less index 0d808ae2f..a5933f4c1 100644 --- a/apps/common/main/resources/less/comments.less +++ b/apps/common/main/resources/less/comments.less @@ -78,7 +78,7 @@ overflow: hidden; color: @gray-darker; - textarea { + textarea:not(.user-message) { width: 100%; height: 50px; resize: none; @@ -172,6 +172,14 @@ } } + textarea.user-message { + border: none; + resize: none; + width: 100%; + line-height: 15px; + cursor: text; + } + .user-reply { color: @black; margin-top: 10px; diff --git a/apps/common/main/resources/less/dropdown-menu.less b/apps/common/main/resources/less/dropdown-menu.less index cc0762c42..797244129 100644 --- a/apps/common/main/resources/less/dropdown-menu.less +++ b/apps/common/main/resources/less/dropdown-menu.less @@ -66,6 +66,7 @@ background-color: @dropdown-bg; height: 16px; width: 100%; + cursor: pointer; &.top { top: 0; @@ -96,5 +97,10 @@ border-left: 3px solid transparent; } } + + &.disabled { + opacity: 0.3; + cursor: default; + } } } \ No newline at end of file diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less index 67c665f3a..b105a0702 100644 --- a/apps/common/main/resources/less/header.less +++ b/apps/common/main/resources/less/header.less @@ -100,8 +100,16 @@ border: 0 none; cursor: default; - &:focus { + &:hover:not(:disabled) { + border: 1px solid @gray-dark; + background-color: rgba(255,255,255,0.2); + } + + &:focus:not(:active) { + border: 1px solid @gray-dark; cursor: text; + background-color: white; + color: @gray-deep; } width: 100%; } @@ -217,7 +225,7 @@ .name { display: block; padding-left: 16px; - margin-top: -3px; + margin-top: -5px; white-space: nowrap; text-overflow: ellipsis; vertical-align: middle; diff --git a/apps/common/main/resources/less/listview.less b/apps/common/main/resources/less/listview.less index a9cfaadbf..9a80b2fd1 100644 --- a/apps/common/main/resources/less/listview.less +++ b/apps/common/main/resources/less/listview.less @@ -28,24 +28,33 @@ border-style: solid; border-width: 1px 0; border-top-color: #fafafa; + } + &:not(.disabled) > .item { &:hover { - background-color: @secondary; - border-color: @secondary; - border-style: solid; - border-width: 1px 0; + background-color: @secondary; + border-color: @secondary; + border-style: solid; + border-width: 1px 0; } &.selected { - background-color: @primary; - color: #fff; - border-color: @primary; - border-style: solid; - border-width: 1px 0; + background-color: @primary; + color: #fff; + border-color: @primary; + border-style: solid; + border-width: 1px 0; } } &.ps-container { overflow: hidden; } + + &.disabled { + > .item { + cursor: default; + opacity: 0.5; + } + } } \ No newline at end of file diff --git a/apps/common/main/resources/less/synchronize-tip.less b/apps/common/main/resources/less/synchronize-tip.less index 6de6e6e41..df5b141c9 100644 --- a/apps/common/main/resources/less/synchronize-tip.less +++ b/apps/common/main/resources/less/synchronize-tip.less @@ -23,6 +23,21 @@ } } + &.left { + margin: -32px 15px 0 0; + + .tip-arrow { + right: -15px; + top: 20px; + width: 15px; + height: 30px; + &:after { + top: 5px; + left: -8px; + } + } + } + &.top { margin: 0 -32px 15px 0; diff --git a/apps/common/main/resources/less/toolbar.less b/apps/common/main/resources/less/toolbar.less index 5b02b5eff..e2f0f6800 100644 --- a/apps/common/main/resources/less/toolbar.less +++ b/apps/common/main/resources/less/toolbar.less @@ -224,6 +224,10 @@ width: 22px; height: 22px; } + + .checkbox-indeterminate { + margin-top: 3px; + } } } @@ -275,6 +279,12 @@ .button-normal-icon(~'x-huge .btn-ic-docspell', 12, @toolbar-big-icon-size); .button-normal-icon(~'x-huge .btn-ic-review', 13, @toolbar-big-icon-size); .button-normal-icon(~'x-huge .btn-ic-reviewview', 30, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-sharing', 31, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-coedit', 32, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-chat', 33, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-history', 34, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-protect', 35, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-signature', 36, @toolbar-big-icon-size); .button-normal-icon(review-save, 14, @toolbar-big-icon-size); .button-normal-icon(review-deny, 15, @toolbar-big-icon-size); .button-normal-icon(review-next, 16, @toolbar-big-icon-size); diff --git a/apps/documenteditor/embed/js/ApplicationController.js b/apps/documenteditor/embed/js/ApplicationController.js index 12dc6f7ea..22b0216a8 100644 --- a/apps/documenteditor/embed/js/ApplicationController.js +++ b/apps/documenteditor/embed/js/ApplicationController.js @@ -398,6 +398,8 @@ var ApplicationController = new(function(){ }); } else { + Common.Gateway.reportWarning(id, message); + $('#id-critical-error-title').text(me.notcriticalErrorTitle); $('#id-critical-error-message').text(message); $('#id-critical-error-close').off(); diff --git a/apps/documenteditor/main/app.js b/apps/documenteditor/main/app.js index 471759e72..bc6d337c9 100644 --- a/apps/documenteditor/main/app.js +++ b/apps/documenteditor/main/app.js @@ -163,6 +163,7 @@ require([ ,'Common.Controllers.ExternalDiagramEditor' ,'Common.Controllers.ExternalMergeEditor' ,'Common.Controllers.ReviewChanges' + ,'Common.Controllers.Protection' ] }); @@ -183,6 +184,7 @@ require([ 'documenteditor/main/app/view/TableSettings', 'documenteditor/main/app/view/ShapeSettings', 'documenteditor/main/app/view/TextArtSettings', + 'documenteditor/main/app/view/SignatureSettings', 'common/main/lib/util/utils', 'common/main/lib/util/LocalStorage', 'common/main/lib/controller/Fonts', @@ -196,6 +198,7 @@ require([ ,'common/main/lib/controller/ExternalDiagramEditor' ,'common/main/lib/controller/ExternalMergeEditor' ,'common/main/lib/controller/ReviewChanges' + ,'common/main/lib/controller/Protection' ], function() { app.start(); }); diff --git a/apps/documenteditor/main/app/controller/LeftMenu.js b/apps/documenteditor/main/app/controller/LeftMenu.js index a05ae62e0..5a5dceced 100644 --- a/apps/documenteditor/main/app/controller/LeftMenu.js +++ b/apps/documenteditor/main/app/controller/LeftMenu.js @@ -99,11 +99,18 @@ define([ 'search:replace': _.bind(this.onQueryReplace, this), 'search:replaceall': _.bind(this.onQueryReplaceAll, this), 'search:highlight': _.bind(this.onSearchHighlight, this) + }, + 'Common.Views.ReviewChanges': { + 'collaboration:chat': _.bind(this.onShowHideChat, this) } }); Common.NotificationCenter.on('leftmenu:change', _.bind(this.onMenuChange, this)); Common.NotificationCenter.on('app:comment:add', _.bind(this.onAppAddComment, this)); + Common.NotificationCenter.on('collaboration:history', _.bind(function () { + if ( !this.leftMenu.panelHistory.isVisible() ) + this.clickMenuFileItem(null, 'history'); + }, this)); }, onLaunch: function() { @@ -267,7 +274,7 @@ define([ default: close_menu = false; } - if (close_menu) { + if (close_menu && menu) { menu.hide(); } }, @@ -297,16 +304,21 @@ define([ applySettings: function(menu) { var value; - this.api.SetTextBoxInputMode(Common.localStorage.getBool("de-settings-inputmode")); + + value = Common.localStorage.getBool("de-settings-inputmode"); + Common.Utils.InternalSettings.set("de-settings-inputmode", value); + this.api.SetTextBoxInputMode(value); if (Common.Utils.isChrome) { value = Common.localStorage.getBool("de-settings-inputsogou"); + Common.Utils.InternalSettings.set("de-settings-inputsogou", value); this.api.setInputParams({"SogouPinyin" : value}); } /** coauthoring begin **/ if (this.mode.isEdit && !this.mode.isOffline && this.mode.canCoAuthoring) { var fast_coauth = Common.localStorage.getBool("de-settings-coauthmode", true); + Common.Utils.InternalSettings.set("de-settings-coauthmode", fast_coauth); this.api.asc_SetFastCollaborative(fast_coauth); value = Common.localStorage.getItem((fast_coauth) ? "de-settings-showchanges-fast" : "de-settings-showchanges-strict"); @@ -316,13 +328,21 @@ define([ case 'last': value = Asc.c_oAscCollaborativeMarksShowType.LastChanges; break; default: value = (fast_coauth) ? Asc.c_oAscCollaborativeMarksShowType.None : Asc.c_oAscCollaborativeMarksShowType.LastChanges; } + Common.Utils.InternalSettings.set((fast_coauth) ? "de-settings-showchanges-fast" : "de-settings-showchanges-strict", value); this.api.SetCollaborativeMarksShowType(value); } - (Common.localStorage.getBool("de-settings-livecomment", true)) ? this.api.asc_showComments(Common.localStorage.getBool("de-settings-resolvedcomment", true)) : this.api.asc_hideComments(); + value = Common.localStorage.getBool("de-settings-livecomment", true); + Common.Utils.InternalSettings.set("de-settings-livecomment", value); + var resolved = Common.localStorage.getBool("de-settings-resolvedcomment", true); + Common.Utils.InternalSettings.set("de-settings-resolvedcomment", resolved); + if (this.mode.canComments && this.leftMenu.panelComments.isVisible()) + value = resolved = true; + (value) ? this.api.asc_showComments(resolved) : this.api.asc_hideComments(); /** coauthoring end **/ value = Common.localStorage.getItem("de-settings-fontrender"); + Common.Utils.InternalSettings.set("de-settings-fontrender", value); switch (value) { case '1': this.api.SetFontRenderingMode(1); break; case '2': this.api.SetFontRenderingMode(2); break; @@ -330,13 +350,16 @@ define([ } if (this.mode.isEdit) { - value = Common.localStorage.getItem("de-settings-autosave"); - this.api.asc_setAutoSaveGap(parseInt(value)); + value = parseInt(Common.localStorage.getItem("de-settings-autosave")); + Common.Utils.InternalSettings.set("de-settings-autosave", value); + this.api.asc_setAutoSaveGap(value); - this.api.asc_setSpellCheck(Common.localStorage.getBool("de-settings-spellcheck", true)); + value = Common.localStorage.getBool("de-settings-spellcheck", true); + Common.Utils.InternalSettings.set("de-settings-spellcheck", value); + this.api.asc_setSpellCheck(value); } - this.api.put_ShowSnapLines(Common.localStorage.getBool("de-settings-showsnaplines", true)); + this.api.put_ShowSnapLines(Common.Utils.InternalSettings.get("de-settings-showsnaplines")); menu.hide(); }, @@ -527,8 +550,9 @@ define([ }, commentsShowHide: function(mode) { - var value = Common.localStorage.getBool("de-settings-livecomment", true), - resolved = Common.localStorage.getBool("de-settings-resolvedcomment", true); + var value = Common.Utils.InternalSettings.get("de-settings-livecomment"), + resolved = Common.Utils.InternalSettings.get("de-settings-resolvedcomment"); + if (!value || !resolved) { (mode === 'show') ? this.api.asc_showComments(true) : ((value) ? this.api.asc_showComments(resolved) : this.api.asc_hideComments()); } @@ -676,6 +700,18 @@ define([ Common.Gateway.requestHistory(); }, + onShowHideChat: function(state) { + if (this.mode.canCoAuthoring && this.mode.canChat && !this.mode.isLightVersion) { + if (state) { + Common.UI.Menu.Manager.hideAll(); + this.leftMenu.showMenu('chat'); + } else { + this.leftMenu.btnChat.toggle(false, true); + this.leftMenu.onBtnMenuClick(this.leftMenu.btnChat); + } + } + }, + textNoTextFound : 'Text not found', newDocumentTitle : 'Unnamed document', requestEditRightsText : 'Requesting editing rights...', diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js index b653d52a5..a090b4f02 100644 --- a/apps/documenteditor/main/app/controller/Main.js +++ b/apps/documenteditor/main/app/controller/Main.js @@ -93,6 +93,9 @@ define([ this.addListeners({ 'FileMenu': { 'settings:apply': _.bind(this.applySettings, this) + }, + 'Common.Views.ReviewChanges': { + 'settings:apply': _.bind(this.applySettings, this) } }); }, @@ -119,6 +122,7 @@ define([ var value = Common.localStorage.getItem("de-settings-fontrender"); if (value === null) window.devicePixelRatio > 1 ? value = '1' : '0'; + Common.Utils.InternalSettings.set("de-settings-fontrender", value); // Initialize api @@ -131,7 +135,19 @@ define([ 'Diagram Title': this.txtDiagramTitle, 'X Axis': this.txtXAxis, 'Y Axis': this.txtYAxis, - 'Your text here': this.txtArt + 'Your text here': this.txtArt, + "Error! Bookmark not defined.": this.txtBookmarkError, + "above": this.txtAbove, + "below": this.txtBelow, + "on page ": this.txtOnPage, + "Header": this.txtHeader, + "Footer": this.txtFooter, + " -Section ": this.txtSection, + "First Page ": this.txtFirstPage, + "Even Page ": this.txtEvenPage, + "Odd Page ": this.txtOddPage, + "Same as Previous": this.txtSameAsPrev, + "Current Document": this.txtCurrentDocument }; styleNames.forEach(function(item){ translate[item] = me.translationTable[item] = me['txtStyle_' + item.replace(/ /g, '_')] || item; @@ -371,10 +387,25 @@ define([ } }, - onDownloadAs: function() { + onDownloadAs: function(format) { this._state.isFromGatewayDownloadAs = true; var type = /^(?:(pdf|djvu|xps))$/.exec(this.document.fileType); - (type && typeof type[1] === 'string') ? this.api.asc_DownloadOrigin(true) : this.api.asc_DownloadAs(Asc.c_oAscFileType.DOCX, true); + if (type && typeof type[1] === 'string') + this.api.asc_DownloadOrigin(true); + else { + var _format = (format && (typeof format == 'string')) ? Asc.c_oAscFileType[ format.toUpperCase() ] : null, + _supported = [ + Asc.c_oAscFileType.TXT, + Asc.c_oAscFileType.ODT, + Asc.c_oAscFileType.DOCX, + Asc.c_oAscFileType.HTML, + Asc.c_oAscFileType.PDF + ]; + + if ( !_format || _supported.indexOf(_format) < 0 ) + _format = Asc.c_oAscFileType.DOCX; + this.api.asc_DownloadAs(_format, true); + } }, onProcessMouse: function(data) { @@ -767,10 +798,14 @@ define([ /** coauthoring begin **/ this.isLiveCommenting = Common.localStorage.getBool("de-settings-livecomment", true); - this.isLiveCommenting ? this.api.asc_showComments(Common.localStorage.getBool("de-settings-resolvedcomment", true)) : this.api.asc_hideComments(); + Common.Utils.InternalSettings.set("de-settings-livecomment", this.isLiveCommenting); + value = Common.localStorage.getBool("de-settings-resolvedcomment", true); + Common.Utils.InternalSettings.set("de-settings-resolvedcomment", value); + this.isLiveCommenting ? this.api.asc_showComments(value) : this.api.asc_hideComments(); /** coauthoring end **/ value = Common.localStorage.getItem("de-settings-zoom"); + Common.Utils.InternalSettings.set("de-settings-zoom", value); var zf = (value!==null) ? parseInt(value) : (this.appOptions.customization && this.appOptions.customization.zoom ? parseInt(this.appOptions.customization.zoom) : 100); (zf == -1) ? this.api.zoomFitToPage() : ((zf == -2) ? this.api.zoomFitToWidth() : this.api.zoom(zf>0 ? zf : 100)); @@ -780,9 +815,11 @@ define([ value = Common.localStorage.getItem("de-show-tableline"); me.api.put_ShowTableEmptyLine((value!==null) ? eval(value) : true); - me.api.asc_setSpellCheck(Common.localStorage.getBool("de-settings-spellcheck", true)); + value = Common.localStorage.getBool("de-settings-spellcheck", true); + Common.Utils.InternalSettings.set("de-settings-spellcheck", value); + me.api.asc_setSpellCheck(value); - Common.localStorage.setBool("de-settings-showsnaplines", me.api.get_ShowSnapLines()); + Common.Utils.InternalSettings.set("de-settings-showsnaplines", me.api.get_ShowSnapLines()); function checkWarns() { if (!window['AscDesktopEditor']) { @@ -806,11 +843,14 @@ define([ appHeader.setDocumentCaption(me.api.asc_getDocumentName()); me.updateWindowTitle(true); - me.api.SetTextBoxInputMode(Common.localStorage.getBool("de-settings-inputmode")); + value = Common.localStorage.getBool("de-settings-inputmode"); + Common.Utils.InternalSettings.set("de-settings-inputmode", value); + me.api.SetTextBoxInputMode(value); if (Common.Utils.isChrome) { value = Common.localStorage.getBool("de-settings-inputsogou"); me.api.setInputParams({"SogouPinyin" : value}); + Common.Utils.InternalSettings.set("de-settings-inputsogou", value); } /** coauthoring begin **/ @@ -824,21 +864,23 @@ define([ me.api.asc_SetFastCollaborative(me._state.fastCoauth); value = Common.localStorage.getItem((me._state.fastCoauth) ? "de-settings-showchanges-fast" : "de-settings-showchanges-strict"); - if (value !== null) - me.api.SetCollaborativeMarksShowType(value == 'all' ? Asc.c_oAscCollaborativeMarksShowType.All : - value == 'none' ? Asc.c_oAscCollaborativeMarksShowType.None : Asc.c_oAscCollaborativeMarksShowType.LastChanges); - else - me.api.SetCollaborativeMarksShowType(me._state.fastCoauth ? Asc.c_oAscCollaborativeMarksShowType.None : Asc.c_oAscCollaborativeMarksShowType.LastChanges); + if (value == null) value = me._state.fastCoauth ? 'none' : 'last'; + me.api.SetCollaborativeMarksShowType(value == 'all' ? Asc.c_oAscCollaborativeMarksShowType.All : + (value == 'none' ? Asc.c_oAscCollaborativeMarksShowType.None : Asc.c_oAscCollaborativeMarksShowType.LastChanges)); + Common.Utils.InternalSettings.set((me._state.fastCoauth) ? "de-settings-showchanges-fast" : "de-settings-showchanges-strict", value); } else if (!me.appOptions.isEdit && me.appOptions.canComments) { me._state.fastCoauth = true; me.api.asc_SetFastCollaborative(me._state.fastCoauth); me.api.SetCollaborativeMarksShowType(Asc.c_oAscCollaborativeMarksShowType.None); me.api.asc_setAutoSaveGap(1); + Common.Utils.InternalSettings.set("de-settings-autosave", 1); } else { me._state.fastCoauth = false; me.api.asc_SetFastCollaborative(me._state.fastCoauth); me.api.SetCollaborativeMarksShowType(Asc.c_oAscCollaborativeMarksShowType.None); } + Common.Utils.InternalSettings.set("de-settings-coauthmode", me._state.fastCoauth); + /** coauthoring end **/ var application = me.getApplication(); @@ -878,11 +920,12 @@ define([ if (value===null && me.appOptions.customization && me.appOptions.customization.autosave===false) value = 0; value = (!me._state.fastCoauth && value!==null) ? parseInt(value) : (me.appOptions.canCoAuthoring ? 1 : 0); - + Common.Utils.InternalSettings.set("de-settings-autosave", value); me.api.asc_setAutoSaveGap(value); if (me.appOptions.canForcesave) {// use asc_setIsForceSaveOnUserSave only when customization->forcesave = true me.appOptions.forcesave = Common.localStorage.getBool("de-settings-forcesave", me.appOptions.canForcesave); + Common.Utils.InternalSettings.set("de-settings-forcesave", me.appOptions.forcesave); me.api.asc_setIsForceSaveOnUserSave(me.appOptions.forcesave); } @@ -910,16 +953,14 @@ define([ me.api.UpdateInterfaceState(); me.fillTextArt(me.api.asc_getTextArtPreviews()); - if (me.appOptions.canBrandingExt) - Common.NotificationCenter.trigger('document:ready', 'main'); + Common.NotificationCenter.trigger('document:ready', 'main'); me.applyLicense(); } }, 50); } else { documentHolderController.getView().createDelayedElementsViewer(); - if (me.appOptions.canBrandingExt) - Common.NotificationCenter.trigger('document:ready', 'main'); + Common.NotificationCenter.trigger('document:ready', 'main'); } if (this.appOptions.canAnalytics && false) @@ -1033,6 +1074,7 @@ define([ this.appOptions.forcesave = this.appOptions.canForcesave; this.appOptions.canEditComments= this.appOptions.isOffline || !(typeof (this.editorConfig.customization) == 'object' && this.editorConfig.customization.commentAuthorOnly); this.appOptions.trialMode = params.asc_getLicenseMode(); + this.appOptions.canProtect = this.appOptions.isDesktopApp && this.api.asc_isSignaturesSupport(); if ( this.appOptions.isLightVersion ) { this.appOptions.canUseHistory = @@ -1123,6 +1165,9 @@ define([ reviewController.setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + if (this.appOptions.isDesktopApp && this.appOptions.isOffline) + application.getController('Common.Controllers.Protection').setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + var viewport = this.getApplication().getController('Viewport').getView('Viewport'); viewport.applyEditorMode(); @@ -1151,6 +1196,7 @@ define([ var value = Common.localStorage.getItem('de-settings-unit'); value = (value!==null) ? parseInt(value) : Common.Utils.Metric.getDefaultMetric(); Common.Utils.Metric.setCurrentMetric(value); + Common.Utils.InternalSettings.set("de-settings-unit", value); me.api.asc_SetDocumentUnits((value==Common.Utils.Metric.c_MetricUnits.inch) ? Asc.c_oAscDocumentUnits.Inch : ((value==Common.Utils.Metric.c_MetricUnits.pt) ? Asc.c_oAscDocumentUnits.Point : Asc.c_oAscDocumentUnits.Millimeter)); me.api.asc_SetViewRulers(!Common.localStorage.getBool('de-hidden-rulers')); @@ -1336,6 +1382,8 @@ define([ } } else { + Common.Gateway.reportWarning(id, config.msg); + config.title = this.notcriticalErrorTitle; config.iconCls = 'warn'; config.buttons = ['ok']; @@ -1346,6 +1394,20 @@ define([ this.api.asc_DownloadAs(); else (this.appOptions.canDownload) ? this.getApplication().getController('LeftMenu').leftMenu.showMenu('file:saveas') : this.api.asc_DownloadOrigin(); + } else if (id == Asc.c_oAscError.ID.SplitCellMaxRows || id == Asc.c_oAscError.ID.SplitCellMaxCols || id == Asc.c_oAscError.ID.SplitCellRowsDivider) { + var me = this; + setTimeout(function(){ + (new Common.Views.InsertTableDialog({ + split: true, + handler: function(result, value) { + if (result == 'ok') { + if (me.api) + me.api.SplitCell(value.columns, value.rows); + } + me.onEditComplete(); + } + })).show(); + },10); } this._state.lostEditingRights = false; this.onEditComplete(); @@ -1750,6 +1812,7 @@ define([ var value = Common.localStorage.getItem("de-settings-unit"); value = (value!==null) ? parseInt(value) : Common.Utils.Metric.getDefaultMetric(); Common.Utils.Metric.setCurrentMetric(value); + Common.Utils.InternalSettings.set("de-settings-unit", value); this.api.asc_SetDocumentUnits((value==Common.Utils.Metric.c_MetricUnits.inch) ? Asc.c_oAscDocumentUnits.Inch : ((value==Common.Utils.Metric.c_MetricUnits.pt) ? Asc.c_oAscDocumentUnits.Point : Asc.c_oAscDocumentUnits.Millimeter)); this.getApplication().getController('RightMenu').updateMetricUnit(); this.getApplication().getController('Toolbar').getView().updateMetricUnit(); @@ -1811,12 +1874,13 @@ define([ if (dontshow) window.localStorage.setItem("de-hide-try-undoredo", 1); if (btn == 'custom') { Common.localStorage.setItem("de-settings-coauthmode", 0); + Common.Utils.InternalSettings.set("de-settings-coauthmode", false); this.api.asc_SetFastCollaborative(false); this._state.fastCoauth = false; Common.localStorage.setItem("de-settings-showchanges-strict", 'last'); this.api.SetCollaborativeMarksShowType(Asc.c_oAscCollaborativeMarksShowType.LastChanges); } - this.fireEvent('editcomplete', this); + this.onEditComplete(); }, this) }); }, @@ -1839,6 +1903,7 @@ define([ } if (this.appOptions.canForcesave) { this.appOptions.forcesave = Common.localStorage.getBool("de-settings-forcesave", this.appOptions.canForcesave); + Common.Utils.InternalSettings.set("de-settings-forcesave", this.appOptions.forcesave); this.api.asc_setIsForceSaveOnUserSave(this.appOptions.forcesave); } }, @@ -1910,18 +1975,11 @@ define([ var pluginsData = (uiCustomize) ? plugins.UIpluginsData : plugins.pluginsData; if (!pluginsData || pluginsData.length<1) return; - var arr = [], - baseUrl = _.isEmpty(plugins.url) ? "" : plugins.url; - - if (baseUrl !== "") - console.warn("Obsolete: The url parameter is deprecated. Please check the documentation for new plugin connection configuration."); - + var arr = []; pluginsData.forEach(function(item){ - item = baseUrl + item; // for compatibility with previous version of server, where plugins.url is used. var value = Common.Utils.getConfigJson(item); if (value) { value.baseUrl = item.substring(0, item.lastIndexOf("config.json")); - value.oldVersion = (baseUrl !== ""); arr.push(value); } }); @@ -1961,14 +2019,6 @@ define([ var visible = (isEdit || itemVar.isViewer) && _.contains(itemVar.EditorsSupport, 'word'); if ( visible ) pluginVisible = true; - var icons = itemVar.icons; - if (item.oldVersion) { // for compatibility with previouse version of server, where plugins.url is used. - icons = []; - itemVar.icons.forEach(function(icon){ - icons.push(icon.substring(icon.lastIndexOf("\/")+1)); - }); - } - if (item.isUICustomizer ) { visible && arrUI.push(item.baseUrl + itemVar.url); } else { @@ -1976,8 +2026,8 @@ define([ model.set({ index: variationsArr.length, - url: (item.oldVersion) ? (itemVar.url.substring(itemVar.url.lastIndexOf("\/") + 1) ) : itemVar.url, - icons: icons, + url: itemVar.url, + icons: itemVar.icons, visible: visible }); @@ -2138,6 +2188,18 @@ define([ txtStyle_List_Paragraph: 'List Paragraph', saveTextText: 'Saving document...', saveTitleText: 'Saving Document', + txtBookmarkError: "Error! Bookmark not defined.", + txtAbove: "above", + txtBelow: "below", + txtOnPage: "on page ", + txtHeader: "Header", + txtFooter: "Footer", + txtSection: " -Section ", + txtFirstPage: "First Page ", + txtEvenPage: "Even Page ", + txtOddPage: "Odd Page ", + txtSameAsPrev: "Same as Previous", + txtCurrentDocument: "Current Document", warnNoLicenseUsers: 'This version of ONLYOFFICE Editors has certain limitations for concurrent users.
    If you need more please consider upgrading your current license or purchasing a commercial one.' } })(), DE.Controllers.Main || {})) diff --git a/apps/documenteditor/main/app/controller/RightMenu.js b/apps/documenteditor/main/app/controller/RightMenu.js index 67e8afae1..e8f72db52 100644 --- a/apps/documenteditor/main/app/controller/RightMenu.js +++ b/apps/documenteditor/main/app/controller/RightMenu.js @@ -78,11 +78,13 @@ define([ this._settings[Common.Utils.documentSettingsType.Shape] = {panelId: "id-shape-settings", panel: rightMenu.shapeSettings, btn: rightMenu.btnShape, hidden: 1, locked: false}; this._settings[Common.Utils.documentSettingsType.TextArt] = {panelId: "id-textart-settings", panel: rightMenu.textartSettings, btn: rightMenu.btnTextArt, hidden: 1, locked: false}; this._settings[Common.Utils.documentSettingsType.Chart] = {panelId: "id-chart-settings", panel: rightMenu.chartSettings, btn: rightMenu.btnChart, hidden: 1, locked: false}; - this._settings[Common.Utils.documentSettingsType.MailMerge] = {panelId: "id-mail-merge-settings", panel: rightMenu.mergeSettings, btn: rightMenu.btnMailMerge, hidden: 1, props: {}, locked: false}; + this._settings[Common.Utils.documentSettingsType.MailMerge] = {panelId: "id-mail-merge-settings", panel: rightMenu.mergeSettings, btn: rightMenu.btnMailMerge, hidden: 1, props: {}, locked: false}; + this._settings[Common.Utils.documentSettingsType.Signature] = {panelId: "id-signature-settings", panel: rightMenu.signatureSettings, btn: rightMenu.btnSignature, hidden: 1, props: {}, locked: false}; }, setApi: function(api) { this.api = api; + this.api.asc_registerCallback('asc_onUpdateSignatures', _.bind(this.onApiUpdateSignatures, this)); this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.onCoAuthoringDisconnect, this)); Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); }, @@ -96,7 +98,7 @@ define([ var panel = this._settings[type].panel; var props = this._settings[type].props; if (props && panel) - panel.ChangeSettings.call(panel, (type==Common.Utils.documentSettingsType.MailMerge) ? undefined : props); + panel.ChangeSettings.call(panel, (type==Common.Utils.documentSettingsType.MailMerge || type==Common.Utils.documentSettingsType.Signature) ? undefined : props); } else if (minimized && type==Common.Utils.documentSettingsType.MailMerge) { this.rightmenu.mergeSettings.disablePreviewMode(); } @@ -112,13 +114,14 @@ define([ in_equation = false, needhide = true; for (var i=0; i 0.01 || Math.abs(this._state.pgsize[1] - h) > 0.01) { this._state.pgsize = [w, h]; if (this.toolbar.mnuPageSize) { - this._clearChecked(this.toolbar.mnuPageSize); + this.toolbar.mnuPageSize.clearAll(); _.each(this.toolbar.mnuPageSize.items, function(item){ if (item.value && typeof(item.value) == 'object' && - Math.abs(item.value[0] - w) < 0.01 && Math.abs(item.value[1] - h) < 0.01) { + Math.abs(item.value[0] - width) < 0.01 && Math.abs(item.value[1] - height) < 0.01) { item.setChecked(true); return false; } @@ -609,7 +611,7 @@ define([ Math.abs(this._state.pgmargins[3] - right) > 0.01) { this._state.pgmargins = [top, left, bottom, right]; if (this.toolbar.btnPageMargins.menu) { - this._clearChecked(this.toolbar.btnPageMargins.menu); + this.toolbar.btnPageMargins.menu.clearAll(); _.each(this.toolbar.btnPageMargins.menu.items, function(item){ if (item.value && typeof(item.value) == 'object' && Math.abs(item.value[0] - top) < 0.01 && Math.abs(item.value[1] - left) < 0.01 && @@ -656,7 +658,7 @@ define([ header_locked = pr.get_Locked(); in_header = true; } else if (type === Asc.c_oAscTypeSelectElement.Image) { - in_image = in_header = true; + in_image = true; image_locked = pr.get_Locked(); if (pr && pr.get_ChartProperties()) in_chart = true; @@ -726,7 +728,7 @@ define([ need_disable = toolbar.mnuPageNumCurrentPos.isDisabled() && toolbar.mnuPageNumberPosPicker.isDisabled(); toolbar.mnuInsertPageNum.setDisabled(need_disable); - need_disable = paragraph_locked || header_locked || in_header || in_equation && !btn_eq_state || this.api.asc_IsCursorInFootnote(); + need_disable = paragraph_locked || header_locked || in_header || in_image || in_equation && !btn_eq_state || this.api.asc_IsCursorInFootnote(); toolbar.btnsPageBreak.disable(need_disable); need_disable = paragraph_locked || header_locked || !can_add_image || in_equation; @@ -1371,9 +1373,9 @@ define([ me.api.put_Table(value.columns, value.rows); } - Common.NotificationCenter.trigger('edit:complete', me.toolbar); Common.component.Analytics.trackEvent('ToolBar', 'Table'); } + Common.NotificationCenter.trigger('edit:complete', me.toolbar); } })).show(); } @@ -1605,7 +1607,7 @@ define([ case Asc.c_oAscDropCap.Margin: index = 2; break; } if (index < 0) - this._clearChecked(this.toolbar.btnDropCap.menu); + this.toolbar.btnDropCap.menu.clearAll(); else this.toolbar.btnDropCap.menu.items[index].setChecked(true); @@ -1738,7 +1740,7 @@ define([ return; if (index < 0) - this._clearChecked(this.toolbar.btnColumns.menu); + this.toolbar.btnColumns.menu.clearAll(); else this.toolbar.btnColumns.menu.items[index].setChecked(true); this._state.columns = index; @@ -2656,13 +2658,6 @@ define([ this._state.clrshd_asccolor = undefined; }, - _clearChecked: function(menu) { - _.each(menu.items, function(item){ - if (item.setChecked) - item.setChecked(false, true); - }); - }, - _onInitEditorStyles: function(styles) { window.styles_loaded = false; @@ -2847,11 +2842,18 @@ define([ me.toolbar.render(_.extend({isCompactView: compactview}, config)); if ( config.isEdit ) { - var tab = {action: 'review', caption: me.toolbar.textTabReview}; - var $panel = DE.getController('Common.Controllers.ReviewChanges').createToolbarPanel(); + var tab = {action: 'review', caption: me.toolbar.textTabCollaboration}; + var $panel = this.getApplication().getController('Common.Controllers.ReviewChanges').createToolbarPanel(); - if ( $panel ) { + if ( $panel ) me.toolbar.addTab(tab, $panel, 3); + + if (config.isDesktopApp && config.isOffline) { + tab = {action: 'protect', caption: me.toolbar.textTabProtect}; + $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel(); + + if ( $panel ) + me.toolbar.addTab(tab, $panel, 4); } } }, diff --git a/apps/documenteditor/main/app/template/FileMenu.template b/apps/documenteditor/main/app/template/FileMenu.template index d1ed92b31..8ec3a1927 100644 --- a/apps/documenteditor/main/app/template/FileMenu.template +++ b/apps/documenteditor/main/app/template/FileMenu.template @@ -8,6 +8,7 @@
  • +
  • @@ -30,4 +31,5 @@
    +
    \ No newline at end of file diff --git a/apps/documenteditor/main/app/template/ParagraphSettingsAdvanced.template b/apps/documenteditor/main/app/template/ParagraphSettingsAdvanced.template index f14b20a0d..6dc19d04e 100644 --- a/apps/documenteditor/main/app/template/ParagraphSettingsAdvanced.template +++ b/apps/documenteditor/main/app/template/ParagraphSettingsAdvanced.template @@ -139,12 +139,15 @@
    -
    - -
    -
    -
    +
    + +
    +
    + +
    +
    +
    diff --git a/apps/documenteditor/main/app/template/RightMenu.template b/apps/documenteditor/main/app/template/RightMenu.template index a0226ef70..6605f9949 100644 --- a/apps/documenteditor/main/app/template/RightMenu.template +++ b/apps/documenteditor/main/app/template/RightMenu.template @@ -16,6 +16,8 @@
    +
    +
    @@ -27,5 +29,6 @@ +
    \ No newline at end of file diff --git a/apps/documenteditor/main/app/template/SignatureSettings.template b/apps/documenteditor/main/app/template/SignatureSettings.template new file mode 100644 index 000000000..c4ee01174 --- /dev/null +++ b/apps/documenteditor/main/app/template/SignatureSettings.template @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    \ No newline at end of file diff --git a/apps/documenteditor/main/app/template/StatusBar.template b/apps/documenteditor/main/app/template/StatusBar.template index 4d7133891..c9cccb90e 100644 --- a/apps/documenteditor/main/app/template/StatusBar.template +++ b/apps/documenteditor/main/app/template/StatusBar.template @@ -19,6 +19,7 @@
    +
    diff --git a/apps/documenteditor/main/app/view/DocumentHolder.js b/apps/documenteditor/main/app/view/DocumentHolder.js index 51c8c2c72..f5ca0946e 100644 --- a/apps/documenteditor/main/app/view/DocumentHolder.js +++ b/apps/documenteditor/main/app/view/DocumentHolder.js @@ -612,6 +612,8 @@ define([ me._arrSpecialPaste = []; me._arrSpecialPaste[Asc.c_oSpecialPasteProps.paste] = me.textPaste; me._arrSpecialPaste[Asc.c_oSpecialPasteProps.keepTextOnly] = me.txtKeepTextOnly; + me._arrSpecialPaste[Asc.c_oSpecialPasteProps.insertAsNestedTable] = me.textNest; + me._arrSpecialPaste[Asc.c_oSpecialPasteProps.overwriteCells] = me.txtOverwriteCells; pasteContainer = $('
    '); me.cmpEl.append(pasteContainer); @@ -1527,7 +1529,6 @@ define([ this.api.asc_registerCallback('asc_onFocusObject', _.bind(onFocusObject, this)); this.api.asc_registerCallback('asc_onShowSpecialPasteOptions', _.bind(onShowSpecialPasteOptions, this)); this.api.asc_registerCallback('asc_onHideSpecialPasteOptions', _.bind(onHideSpecialPasteOptions, this)); - } return this; @@ -1814,14 +1815,39 @@ define([ caption: me.addCommentText }).on('click', _.bind(me.addComment, me)); + var menuSignatureViewSign = new Common.UI.MenuItem({caption: this.strSign, value: 0 }).on('click', _.bind(me.onSignatureClick, me)); + var menuSignatureDetails = new Common.UI.MenuItem({caption: this.strDetails, value: 1 }).on('click', _.bind(me.onSignatureClick, me)); + var menuSignatureViewSetup = new Common.UI.MenuItem({caption: this.strSetup, value: 2 }).on('click', _.bind(me.onSignatureClick, me)); + var menuSignatureRemove = new Common.UI.MenuItem({caption: this.strDelete, value: 3 }).on('click', _.bind(me.onSignatureClick, me)); + var menuViewSignSeparator = new Common.UI.MenuItem({caption: '--' }); + this.viewModeMenu = new Common.UI.Menu({ initMenu: function (value) { - var isInChart = (value.imgProps && value.imgProps.value && !_.isNull(value.imgProps.value.get_ChartProperties())); + var isInChart = (value.imgProps && value.imgProps.value && !_.isNull(value.imgProps.value.get_ChartProperties())), + signGuid = (value.imgProps && value.imgProps.value && me.mode.canProtect) ? value.imgProps.value.asc_getSignatureId() : undefined, + signProps = (signGuid) ? me.api.asc_getSignatureSetup(signGuid) : null, + isInSign = !!signProps && me._canProtect, + canComment = !isInChart && me.api.can_AddQuotedComment() !== false && me.mode.canCoAuthoring && me.mode.canComments && !me._isDisabled; menuViewUndo.setVisible(me.mode.canCoAuthoring && me.mode.canComments && !me._isDisabled); menuViewUndo.setDisabled(!me.api.asc_getCanUndo() && !me._isDisabled); - menuViewCopySeparator.setVisible(!isInChart && me.api.can_AddQuotedComment() !== false && me.mode.canCoAuthoring && me.mode.canComments && !me._isDisabled); - menuViewAddComment.setVisible(!isInChart && me.api.can_AddQuotedComment() !== false && me.mode.canCoAuthoring && me.mode.canComments && !me._isDisabled); + menuViewCopySeparator.setVisible(isInSign); + + var isRequested = (signProps) ? signProps.asc_getRequested() : false; + menuSignatureViewSign.setVisible(isInSign && isRequested); + menuSignatureDetails.setVisible(isInSign && !isRequested); + menuSignatureViewSetup.setVisible(isInSign); + menuSignatureRemove.setVisible(isInSign && !isRequested); + menuViewSignSeparator.setVisible(canComment); + + if (isInSign) { + menuSignatureViewSign.cmpEl.attr('data-value', signGuid); // sign + menuSignatureDetails.cmpEl.attr('data-value', signProps.asc_getId()); // view certificate + menuSignatureViewSetup.cmpEl.attr('data-value', signGuid); // view signature settings + menuSignatureRemove.cmpEl.attr('data-value', signGuid); + } + + menuViewAddComment.setVisible(canComment); menuViewAddComment.setDisabled(value.paraProps && value.paraProps.locked === true); var cancopy = me.api && me.api.can_CopyCut(); @@ -1831,6 +1857,11 @@ define([ menuViewCopy, menuViewUndo, menuViewCopySeparator, + menuSignatureViewSign, + menuSignatureDetails, + menuSignatureViewSetup, + menuSignatureRemove, + menuViewSignSeparator, menuViewAddComment ] }).on('hide:after', function (menu, e, isFromInputControl) { @@ -2150,6 +2181,10 @@ define([ value : 'cut' }).on('click', _.bind(me.onCutCopyPaste, me)); + var menuSignatureEditSign = new Common.UI.MenuItem({caption: this.strSign, value: 0 }).on('click', _.bind(me.onSignatureClick, me)); + var menuSignatureEditSetup = new Common.UI.MenuItem({caption: this.strSetup, value: 2 }).on('click', _.bind(me.onSignatureClick, me)); + var menuEditSignSeparator = new Common.UI.MenuItem({ caption: '--' }); + this.pictureMenu = new Common.UI.Menu({ initMenu: function(value){ if (_.isUndefined(value.imgProps)) @@ -2210,7 +2245,7 @@ define([ me.menuOriginalSize.setVisible(_.isNull(value.imgProps.value.get_ChartProperties()) && _.isNull(value.imgProps.value.get_ShapeProperties()) && !onlyCommonProps); - me.pictureMenu.items[7].setVisible(menuChartEdit.isVisible() || me.menuOriginalSize.isVisible()); + me.pictureMenu.items[10].setVisible(menuChartEdit.isVisible() || me.menuOriginalSize.isVisible()); var islocked = value.imgProps.locked || (value.headerProps!==undefined && value.headerProps.locked); if (menuChartEdit.isVisible()) @@ -2233,12 +2268,26 @@ define([ menuImgCopy.setDisabled(!cancopy); menuImgCut.setDisabled(islocked || !cancopy); menuImgPaste.setDisabled(islocked); + + var signGuid = (value.imgProps && value.imgProps.value && me.mode.canProtect) ? value.imgProps.value.asc_getSignatureId() : undefined, + isInSign = !!signGuid; + menuSignatureEditSign.setVisible(isInSign); + menuSignatureEditSetup.setVisible(isInSign); + menuEditSignSeparator.setVisible(isInSign); + + if (isInSign) { + menuSignatureEditSign.cmpEl.attr('data-value', signGuid); // sign + menuSignatureEditSetup.cmpEl.attr('data-value', signGuid); // edit signature settings + } }, items: [ menuImgCut, menuImgCopy, menuImgPaste, { caption: '--' }, + menuSignatureEditSign, + menuSignatureEditSetup, + menuEditSignSeparator, menuImageArrange, menuImageAlign, me.menuImageWrap, @@ -2318,10 +2367,9 @@ define([ if (me.api) { me.api.SplitCell(value.columns, value.rows); } - me.fireEvent('editcomplete', me); - Common.component.Analytics.trackEvent('DocumentHolder', 'Table'); } + me.fireEvent('editcomplete', me); } })).show(); } @@ -3298,13 +3346,32 @@ define([ } }, + onSignatureClick: function(item) { + var datavalue = item.cmpEl.attr('data-value'); + switch (item.value) { + case 0: + Common.NotificationCenter.trigger('protect:sign', datavalue); //guid + break; + case 1: + this.api.asc_ViewCertificate(datavalue); //certificate id + break; + case 2: + Common.NotificationCenter.trigger('protect:signature', 'visible', this._isDisabled, datavalue);//guid, can edit settings for requested signature + break; + case 3: + this.api.asc_RemoveSignature(datavalue); //guid + break; + } + }, + focus: function() { var me = this; _.defer(function(){ me.cmpEl.focus(); }, 50); }, - SetDisabled: function(state) { + SetDisabled: function(state, canProtect) { this._isDisabled = state; + this._canProtect = canProtect; }, alignmentText : 'Alignment', @@ -3476,7 +3543,13 @@ define([ txtDeleteChars: 'Delete enclosing characters', txtDeleteCharsAndSeparators: 'Delete enclosing characters and separators', txtKeepTextOnly: 'Keep text only', - textUndo: 'Undo' + textUndo: 'Undo', + strSign: 'Sign', + strDetails: 'Signature Details', + strSetup: 'Signature Setup', + strDelete: 'Remove Signature', + txtOverwriteCells: 'Overwrite cells', + textNest: 'Nest table' }, DE.Views.DocumentHolder || {})); }); \ No newline at end of file diff --git a/apps/documenteditor/main/app/view/FileMenu.js b/apps/documenteditor/main/app/view/FileMenu.js index 542e822a5..19fa85f47 100644 --- a/apps/documenteditor/main/app/view/FileMenu.js +++ b/apps/documenteditor/main/app/view/FileMenu.js @@ -126,6 +126,13 @@ define([ canFocused: false }); + this.miProtect = new Common.UI.MenuItem({ + el : $('#fm-btn-protect',this.el), + action : 'protect', + caption : this.btnProtectCaption, + canFocused: false + }); + this.miRecent = new Common.UI.MenuItem({ el : $('#fm-btn-recent',this.el), action : 'recent', @@ -168,6 +175,7 @@ define([ this.miSaveAs, this.miPrint, this.miRename, + this.miProtect, this.miRecent, this.miNew, new Common.UI.MenuItem({ @@ -215,10 +223,11 @@ define([ show: function(panel, opts) { if (this.isVisible() && panel===undefined) return; + var defPanel = (this.mode.canDownload && (!this.mode.isDesktopApp || !this.mode.isOffline)) ? 'saveas' : 'info'; if (!panel) - panel = this.active || ((this.mode.canDownload && (!this.mode.isDesktopApp || !this.mode.isOffline)) ? 'saveas' : 'info'); + panel = this.active || defPanel; this.$el.show(); - this.selectMenu(panel, opts); + this.selectMenu(panel, opts, defPanel); this.api.asc_enableKeyEvents(false); this.fireEvent('menu:show', [this]); @@ -234,7 +243,8 @@ define([ applyMode: function() { this.miPrint[this.mode.canPrint?'show':'hide'](); this.miRename[(this.mode.canRename && !this.mode.isDesktopApp) ?'show':'hide'](); - this.miRename.$el.find('+.devider')[!this.mode.isDisconnected?'show':'hide'](); + this.miProtect[(this.mode.isEdit && this.mode.isDesktopApp && this.mode.isOffline) ?'show':'hide'](); + this.miProtect.$el.find('+.devider')[!this.mode.isDisconnected?'show':'hide'](); this.miRecent[this.mode.canOpenRecent?'show':'hide'](); this.miNew[this.mode.canCreateNew?'show':'hide'](); this.miNew.$el.find('+.devider')[this.mode.canCreateNew?'show':'hide'](); @@ -270,8 +280,10 @@ define([ } } - if (this.mode.isDesktopApp) { + if (this.mode.isDesktopApp && this.mode.isOffline) { // this.$el.find('#fm-btn-back').hide(); + this.panels['protect'] = (new DE.Views.FileMenuPanels.ProtectDoc({menu:this})).render(); + this.panels['protect'].setMode(this.mode); } if (this.mode.canDownload) { @@ -302,16 +314,21 @@ define([ setApi: function(api) { this.api = api; this.panels['info'].setApi(api); + if (this.panels['protect']) this.panels['protect'].setApi(api); }, loadDocument: function(data) { this.document = data.doc; }, - selectMenu: function(menu, opts) { + selectMenu: function(menu, opts, defMenu) { if ( menu ) { - var item = this._getMenuItem(menu), + var item = this._getMenuItem(menu), panel = this.panels[menu]; + if ( item.isDisabled() ) { + item = this._getMenuItem(defMenu); + panel = this.panels[defMenu]; + } if ( item && panel ) { $('.fm-btn',this.el).removeClass('active'); item.$el.addClass('active'); @@ -360,6 +377,7 @@ define([ btnSaveAsCaption : 'Save as', textDownload : 'Download', btnRenameCaption : 'Rename...', - btnCloseMenuCaption : 'Close Menu' + btnCloseMenuCaption : 'Close Menu', + btnProtectCaption: 'Protect\\Sign' }, DE.Views.FileMenu || {})); }); diff --git a/apps/documenteditor/main/app/view/FileMenuPanels.js b/apps/documenteditor/main/app/view/FileMenuPanels.js index 8ef6e6458..c2eade423 100644 --- a/apps/documenteditor/main/app/view/FileMenuPanels.js +++ b/apps/documenteditor/main/app/view/FileMenuPanels.js @@ -353,60 +353,55 @@ define([ }, updateSettings: function() { - this.chInputMode.setValue(Common.localStorage.getBool("de-settings-inputmode")); - Common.Utils.isChrome && this.chInputSogou.setValue(Common.localStorage.getBool("de-settings-inputsogou")); + this.chInputMode.setValue(Common.Utils.InternalSettings.get("de-settings-inputmode")); + Common.Utils.isChrome && this.chInputSogou.setValue(Common.Utils.InternalSettings.get("de-settings-inputsogou")); - var value = Common.localStorage.getItem("de-settings-zoom"); + var value = Common.Utils.InternalSettings.get("de-settings-zoom"); value = (value!==null) ? parseInt(value) : (this.mode.customization && this.mode.customization.zoom ? parseInt(this.mode.customization.zoom) : 100); var item = this.cmbZoom.store.findWhere({value: value}); this.cmbZoom.setValue(item ? parseInt(item.get('value')) : (value>0 ? value+'%' : 100)); /** coauthoring begin **/ - this.chLiveComment.setValue(Common.localStorage.getBool("de-settings-livecomment", true)); - this.chResolvedComment.setValue(Common.localStorage.getBool("de-settings-resolvedcomment", true)); + this.chLiveComment.setValue(Common.Utils.InternalSettings.get("de-settings-livecomment")); + this.chResolvedComment.setValue(Common.Utils.InternalSettings.get("de-settings-resolvedcomment")); - value = Common.localStorage.getItem("de-settings-coauthmode"); - if (value===null && !Common.localStorage.itemExists("de-settings-autosave") && - this.mode.customization && this.mode.customization.autosave===false) - value = 0; // use customization.autosave only when de-settings-coauthmode and de-settings-autosave are null - var fast_coauth = (value===null || parseInt(value) == 1) && !(this.mode.isDesktopApp && this.mode.isOffline) && this.mode.canCoAuthoring; - - item = this.cmbCoAuthMode.store.findWhere({value: parseInt(value)}); + var fast_coauth = Common.Utils.InternalSettings.get("de-settings-coauthmode"); + item = this.cmbCoAuthMode.store.findWhere({value: fast_coauth ? 1 : 0}); this.cmbCoAuthMode.setValue(item ? item.get('value') : 1); this.lblCoAuthMode.text(item ? item.get('descValue') : this.strCoAuthModeDescFast); this.fillShowChanges(fast_coauth); - value = Common.localStorage.getItem((fast_coauth) ? "de-settings-showchanges-fast" : "de-settings-showchanges-strict"); + value = Common.Utils.InternalSettings.get((fast_coauth) ? "de-settings-showchanges-fast" : "de-settings-showchanges-strict"); item = this.cmbShowChanges.store.findWhere({value: value}); this.cmbShowChanges.setValue(item ? item.get('value') : (fast_coauth) ? 'none' : 'last'); /** coauthoring end **/ - value = Common.localStorage.getItem("de-settings-fontrender"); + value = Common.Utils.InternalSettings.get("de-settings-fontrender"); item = this.cmbFontRender.store.findWhere({value: parseInt(value)}); this.cmbFontRender.setValue(item ? item.get('value') : (window.devicePixelRatio > 1 ? 1 : 0)); - value = Common.localStorage.getItem("de-settings-unit"); - item = this.cmbUnit.store.findWhere({value: parseInt(value)}); + value = Common.Utils.InternalSettings.get("de-settings-unit"); + item = this.cmbUnit.store.findWhere({value: value}); this.cmbUnit.setValue(item ? parseInt(item.get('value')) : Common.Utils.Metric.getDefaultMetric()); this._oldUnits = this.cmbUnit.getValue(); - value = Common.localStorage.getItem("de-settings-autosave"); - if (value===null && this.mode.customization && this.mode.customization.autosave===false) - value = 0; - this.chAutosave.setValue(fast_coauth || (value===null ? this.mode.canCoAuthoring : parseInt(value) == 1)); + value = Common.Utils.InternalSettings.get("de-settings-autosave"); + this.chAutosave.setValue(value == 1); if (this.mode.canForcesave) - this.chForcesave.setValue(Common.localStorage.getBool("de-settings-forcesave", this.mode.canForcesave)); + this.chForcesave.setValue(Common.Utils.InternalSettings.get("de-settings-forcesave")); - this.chSpell.setValue(Common.localStorage.getBool("de-settings-spellcheck", true)); - this.chAlignGuides.setValue(Common.localStorage.getBool("de-settings-showsnaplines", true)); + this.chSpell.setValue(Common.Utils.InternalSettings.get("de-settings-spellcheck")); + this.chAlignGuides.setValue(Common.Utils.InternalSettings.get("de-settings-showsnaplines")); }, applySettings: function() { Common.localStorage.setItem("de-settings-inputmode", this.chInputMode.isChecked() ? 1 : 0); Common.Utils.isChrome && Common.localStorage.setItem("de-settings-inputsogou", this.chInputSogou.isChecked() ? 1 : 0); Common.localStorage.setItem("de-settings-zoom", this.cmbZoom.getValue()); + Common.Utils.InternalSettings.set("de-settings-zoom", Common.localStorage.getItem("de-settings-zoom")); + /** coauthoring begin **/ Common.localStorage.setItem("de-settings-livecomment", this.chLiveComment.isChecked() ? 1 : 0); Common.localStorage.setItem("de-settings-resolvedcomment", this.chResolvedComment.isChecked() ? 1 : 0); @@ -421,7 +416,7 @@ define([ if (this.mode.canForcesave) Common.localStorage.setItem("de-settings-forcesave", this.chForcesave.isChecked() ? 1 : 0); Common.localStorage.setItem("de-settings-spellcheck", this.chSpell.isChecked() ? 1 : 0); - Common.localStorage.setItem("de-settings-showsnaplines", this.chAlignGuides.isChecked() ? 1 : 0); + Common.Utils.InternalSettings.set("de-settings-showsnaplines", this.chAlignGuides.isChecked()); Common.localStorage.save(); if (this.menu) { @@ -875,6 +870,8 @@ define([ }); } + Common.NotificationCenter.on('collaboration:sharing', _.bind(this.changeAccessRights, this)); + return this; }, @@ -1097,4 +1094,174 @@ define([ } } }); + + DE.Views.FileMenuPanels.ProtectDoc = Common.UI.BaseView.extend(_.extend({ + el: '#panel-protect', + menu: undefined, + + template: _.template([ + '', + '
    ', + '', + '
    ', + '', + '', + '', + '', + '', + '', + '', + '', + '
    <%= scope.txtEncrypted %>
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ' + ].join('')), + + initialize: function(options) { + Common.UI.BaseView.prototype.initialize.call(this,arguments); + + this.menu = options.menu; + + var me = this; + this.templateSignature = _.template([ + '', + '', + '', + '', + '', + '', + '', + '', + '
    <%= tipText %>
    ' + ].join('')); + }, + + render: function() { + $(this.el).html(this.template({scope: this})); + + var protection = DE.getController('Common.Controllers.Protection').getView(); + + this.btnAddPwd = protection.getButton('add-password'); + this.btnAddPwd.render(this.$el.find('#fms-btn-add-pwd')); + this.btnAddPwd.on('click', _.bind(this.closeMenu, this)); + + this.btnChangePwd = protection.getButton('change-password'); + this.btnChangePwd.render(this.$el.find('#fms-btn-change-pwd')); + this.btnChangePwd.on('click', _.bind(this.closeMenu, this)); + + this.btnDeletePwd = protection.getButton('del-password'); + this.btnDeletePwd.render(this.$el.find('#fms-btn-delete-pwd')); + this.btnDeletePwd.on('click', _.bind(this.closeMenu, this)); + + this.cntPassword = $('#id-fms-view-pwd'); + + this.btnAddInvisibleSign = protection.getButton('signature'); + this.btnAddInvisibleSign.render(this.$el.find('#fms-btn-invisible-sign')); + this.btnAddInvisibleSign.on('click', _.bind(this.closeMenu, this)); + + this.cntSignature = $('#id-fms-signature'); + this.cntSignatureView = $('#id-fms-signature-view'); + if (_.isUndefined(this.scroller)) { + this.scroller = new Common.UI.Scroller({ + el: $(this.el), + suppressScrollX: true + }); + } + + this.$el.on('click', '.signature-edit-link', _.bind(this.onEdit, this)); + this.$el.on('click', '.signature-view-link', _.bind(this.onView, this)); + + return this; + }, + + show: function() { + Common.UI.BaseView.prototype.show.call(this,arguments); + this.updateSignatures(); + this.updateEncrypt(); + }, + + setMode: function(mode) { + this.mode = mode; + this.cntSignature.toggleClass('hidden', !this.mode.canProtect); + }, + + setApi: function(o) { + this.api = o; + return this; + }, + + closeMenu: function() { + this.menu && this.menu.hide(); + }, + + onEdit: function() { + this.menu && this.menu.hide(); + + var me = this; + Common.UI.warning({ + title: this.notcriticalErrorTitle, + msg: this.txtEditWarning, + buttons: ['ok', 'cancel'], + primary: 'ok', + callback: function(btn) { + if (btn == 'ok') { + me.api.asc_RemoveAllSignatures(); + } + } + }); + + }, + + onView: function() { + this.menu && this.menu.hide(); + DE.getController('RightMenu').rightmenu.SetActivePane(Common.Utils.documentSettingsType.Signature, true); + }, + + updateSignatures: function(){ + var requested = this.api.asc_getRequestSignatures(), + valid = this.api.asc_getSignatures(), + hasRequested = requested && requested.length>0, + hasValid = false, + hasInvalid = false; + + _.each(valid, function(item, index){ + if (item.asc_getValid()==0) + hasValid = true; + else + hasInvalid = true; + }); + + // hasRequested = true; + // hasValid = true; + // hasInvalid = true; + + var tipText = (hasInvalid) ? this.txtSignedInvalid : (hasValid ? this.txtSigned : ""); + if (hasRequested) + tipText = this.txtRequestedSignatures + (tipText!="" ? "

    " : "")+ tipText; + + this.cntSignatureView.html(this.templateSignature({tipText: tipText, hasSigned: (hasValid || hasInvalid), hasRequested: hasRequested})); + }, + + updateEncrypt: function() { + this.cntPassword.toggleClass('hidden', this.btnAddPwd.isVisible()); + }, + + strProtect: 'Protect Document', + strSignature: 'Signature', + txtView: 'View signatures', + txtEdit: 'Edit document', + txtSigned: 'Valid signatures has been added to the document. The document is protected from editing.', + txtSignedInvalid: 'Some of the digital signatures in document are invalid or could not be verified. The document is protected from editing.', + txtRequestedSignatures: 'This document needs to be signed.', + notcriticalErrorTitle: 'Warning', + txtEditWarning: 'Editing will remove the signatures from the document.
    Are you sure you want to continue?', + strEncrypt: 'Password', + txtEncrypted: 'This document has been protected by password' + + }, DE.Views.FileMenuPanels.ProtectDoc || {})); + }); diff --git a/apps/documenteditor/main/app/view/ImageSettings.js b/apps/documenteditor/main/app/view/ImageSettings.js index 75e6589d7..fe6551062 100644 --- a/apps/documenteditor/main/app/view/ImageSettings.js +++ b/apps/documenteditor/main/app/view/ImageSettings.js @@ -173,8 +173,11 @@ define([ this.btnOriginalSize.on('click', _.bind(this.setOriginalSize, this)); this.btnInsertFromFile.on('click', _.bind(function(btn){ + if (this._isFromFile) return; + this._isFromFile = true; if (this.api) this.api.ChangeImageFromFile(); this.fireEvent('editcomplete', this); + this._isFromFile = false; }, this)); this.btnInsertFromUrl.on('click', _.bind(this.insertFromUrl, this)); this.btnEditObject.on('click', _.bind(function(btn){ diff --git a/apps/documenteditor/main/app/view/LeftMenu.js b/apps/documenteditor/main/app/view/LeftMenu.js index fc9ea47ca..40da13f04 100644 --- a/apps/documenteditor/main/app/view/LeftMenu.js +++ b/apps/documenteditor/main/app/view/LeftMenu.js @@ -276,7 +276,7 @@ define([ } if (this.mode.canChat) { this.panelChat['hide'](); - this.btnChat.toggle(false, true); + this.btnChat.toggle(false); } } /** coauthoring end **/ diff --git a/apps/documenteditor/main/app/view/ParagraphSettingsAdvanced.js b/apps/documenteditor/main/app/view/ParagraphSettingsAdvanced.js index 00bef7748..dd0a1857b 100644 --- a/apps/documenteditor/main/app/view/ParagraphSettingsAdvanced.js +++ b/apps/documenteditor/main/app/view/ParagraphSettingsAdvanced.js @@ -42,7 +42,6 @@ define([ 'text!documenteditor/main/app/template/ParagraphSettingsAdvanced.tem 'common/main/lib/view/AdvancedSettingsWindow', 'common/main/lib/component/MetricSpinner', 'common/main/lib/component/CheckBox', - 'common/main/lib/component/RadioBox', 'common/main/lib/component/ThemeColorPalette', 'common/main/lib/component/ColorButton', 'common/main/lib/component/ListView', @@ -410,24 +409,35 @@ define([ 'text!documenteditor/main/app/template/ParagraphSettingsAdvanced.tem this.listenTo(this.tabList.store, 'remove', storechanged); this.listenTo(this.tabList.store, 'reset', storechanged); - this.radioLeft = new Common.UI.RadioBox({ - el: $('#paragraphadv-radio-left'), - labelText: this.textTabLeft, - name: 'asc-radio-tab', - checked: true + this.cmbAlign = new Common.UI.ComboBox({ + el : $('#paraadv-cmb-align'), + style : 'width: 85px;', + menuStyle : 'min-width: 85px;', + editable : false, + cls : 'input-group-nr', + data : [ + { value: 1, displayValue: this.textTabLeft }, + { value: 3, displayValue: this.textTabCenter }, + { value: 2, displayValue: this.textTabRight } + ] }); + this.cmbAlign.setValue(1); - this.radioCenter = new Common.UI.RadioBox({ - el: $('#paragraphadv-radio-center'), - labelText: this.textTabCenter, - name: 'asc-radio-tab' - }); - - this.radioRight = new Common.UI.RadioBox({ - el: $('#paragraphadv-radio-right'), - labelText: this.textTabRight, - name: 'asc-radio-tab' + this.cmbLeader = new Common.UI.ComboBox({ + el : $('#paraadv-cmb-leader'), + style : 'width: 85px;', + menuStyle : 'min-width: 85px;', + editable : false, + cls : 'input-group-nr', + data : [ + { value: Asc.c_oAscTabLeader.None, displayValue: this.textNone }, + { value: Asc.c_oAscTabLeader.Dot, displayValue: '....................' }, + { value: Asc.c_oAscTabLeader.Hyphen, displayValue: '-----------------' }, + { value: Asc.c_oAscTabLeader.MiddleDot, displayValue: '·················' }, + { value: Asc.c_oAscTabLeader.Underscore,displayValue: '__________' } + ] }); + this.cmbLeader.setValue(Asc.c_oAscTabLeader.None); this.btnAddTab = new Common.UI.Button({ el: $('#paraadv-button-add-tab') @@ -562,7 +572,7 @@ define([ 'text!documenteditor/main/app/template/ParagraphSettingsAdvanced.tem if (this._changedProps.get_Tabs()===null || this._changedProps.get_Tabs()===undefined) this._changedProps.put_Tabs(new Asc.asc_CParagraphTabs()); this.tabList.store.each(function (item, index) { - var tab = new Asc.asc_CParagraphTab(Common.Utils.Metric.fnRecalcToMM(item.get('tabPos')), item.get('tabAlign')); + var tab = new Asc.asc_CParagraphTab(Common.Utils.Metric.fnRecalcToMM(item.get('tabPos')), item.get('tabAlign'), item.get('tabLeader')); this._changedProps.get_Tabs().add_Tab(tab); }, this); } @@ -663,7 +673,8 @@ define([ 'text!documenteditor/main/app/template/ParagraphSettingsAdvanced.tem rec.set({ tabPos: pos, value: parseFloat(pos.toFixed(3)) + ' ' + Common.Utils.Metric.getCurrentMetricName(), - tabAlign: tab.get_Value() + tabAlign: tab.get_Value(), + tabLeader: tab.asc_getLeader() }); arr.push(rec); } @@ -1054,8 +1065,9 @@ define([ 'text!documenteditor/main/app/template/ParagraphSettingsAdvanced.tem }, addTab: function(btn, eOpts){ - var val = this.numTab.getNumberValue(); - var align = this.radioLeft.getValue() ? 1 : (this.radioCenter.getValue() ? 3 : 2); + var val = this.numTab.getNumberValue(), + align = this.cmbAlign.getValue(), + leader = this.cmbLeader.getValue(); var store = this.tabList.store; var rec = store.find(function(record){ @@ -1063,13 +1075,15 @@ define([ 'text!documenteditor/main/app/template/ParagraphSettingsAdvanced.tem }); if (rec) { rec.set('tabAlign', align); + rec.set('tabLeader', leader); this._tabListChanged = true; } else { rec = new Common.UI.DataViewModel(); rec.set({ tabPos: val, value: val + ' ' + Common.Utils.Metric.getCurrentMetricName(), - tabAlign: align + tabAlign: align, + tabLeader: leader }); store.add(rec); } @@ -1110,8 +1124,8 @@ define([ 'text!documenteditor/main/app/template/ParagraphSettingsAdvanced.tem rawData = record; } this.numTab.setValue(rawData.tabPos); - (rawData.tabAlign==1) ? this.radioLeft.setValue(true) : ((rawData.tabAlign==3) ? this.radioCenter.setValue(true) : this.radioRight.setValue(true)); - + this.cmbAlign.setValue(rawData.tabAlign); + this.cmbLeader.setValue(rawData.tabLeader); }, hideTextOnlySettings: function(value) { @@ -1173,6 +1187,8 @@ define([ 'text!documenteditor/main/app/template/ParagraphSettingsAdvanced.tem tipNone: 'Set No Borders', tipInner: 'Set Horizontal Inner Lines Only', tipOuter: 'Set Outer Border Only', - noTabs: 'The specified tabs will appear in this field' + noTabs: 'The specified tabs will appear in this field', + textLeader: 'Leader', + textNone: 'None' }, DE.Views.ParagraphSettingsAdvanced || {})); }); \ No newline at end of file diff --git a/apps/documenteditor/main/app/view/RightMenu.js b/apps/documenteditor/main/app/view/RightMenu.js index 0d52aace0..453cd508e 100644 --- a/apps/documenteditor/main/app/view/RightMenu.js +++ b/apps/documenteditor/main/app/view/RightMenu.js @@ -57,6 +57,7 @@ define([ 'documenteditor/main/app/view/ShapeSettings', 'documenteditor/main/app/view/MailMergeSettings', 'documenteditor/main/app/view/TextArtSettings', + 'documenteditor/main/app/view/SignatureSettings', 'common/main/lib/component/Scroller' ], function (menuTemplate, $, _, Backbone) { 'use strict'; @@ -194,6 +195,21 @@ define([ this.mergeSettings = new DE.Views.MailMergeSettings(); } + if (mode && mode.canProtect) { + this.btnSignature = new Common.UI.Button({ + hint: this.txtSignatureSettings, + asctype: Common.Utils.documentSettingsType.Signature, + enableToggle: true, + disabled: true, + toggleGroup: 'tabpanelbtnsGroup' + }); + this._settings[Common.Utils.documentSettingsType.Signature] = {panel: "id-signature-settings", btn: this.btnSignature}; + + this.btnSignature.el = $('#id-right-menu-signature'); this.btnSignature.render().setVisible(true); + this.btnSignature.on('click', _.bind(this.onBtnMenuClick, this)); + this.signatureSettings = new DE.Views.SignatureSettings(); + } + if (_.isUndefined(this.scroller)) { this.scroller = new Common.UI.Scroller({ el: $(this.el).find('.right-panel'), @@ -223,6 +239,7 @@ define([ this.shapeSettings.setApi(api).on('editcomplete', _.bind( fire, this)); this.textartSettings.setApi(api).on('editcomplete', _.bind( fire, this)); if (this.mergeSettings) this.mergeSettings.setApi(api).on('editcomplete', _.bind( fire, this)); + if (this.signatureSettings) this.signatureSettings.setApi(api).on('editcomplete', _.bind( fire, this)); }, setMode: function(mode) { @@ -303,6 +320,7 @@ define([ txtShapeSettings: 'Shape Settings', txtTextArtSettings: 'Text Art Settings', txtChartSettings: 'Chart Settings', - txtMailMergeSettings: 'Mail Merge Settings' + txtMailMergeSettings: 'Mail Merge Settings', + txtSignatureSettings: 'Signature Settings' }, DE.Views.RightMenu || {})); }); \ No newline at end of file diff --git a/apps/documenteditor/main/app/view/ShapeSettings.js b/apps/documenteditor/main/app/view/ShapeSettings.js index f6975dee3..7828424e5 100644 --- a/apps/documenteditor/main/app/view/ShapeSettings.js +++ b/apps/documenteditor/main/app/view/ShapeSettings.js @@ -979,7 +979,8 @@ define([ // border colors var stroke = shapeprops.get_stroke(), strokeType = stroke.get_type(), - borderType; + borderType, + update = (this._state.StrokeColor == 'transparent' && this.BorderColor.Color !== 'transparent'); // border color was changed for shape without line and then shape was reselected (or apply other settings) if (stroke) { if ( strokeType == Asc.c_oAscStrokeType.STROKE_COLOR ) { @@ -1005,7 +1006,7 @@ define([ type1 = typeof(this.BorderColor.Color); type2 = typeof(this._state.StrokeColor); - if ( (type1 !== type2) || (type1=='object' && + if ( update || (type1 !== type2) || (type1=='object' && (this.BorderColor.Color.effectValue!==this._state.StrokeColor.effectValue || this._state.StrokeColor.color.indexOf(this.BorderColor.Color.color)<0)) || (type1!='object' && (this._state.StrokeColor.indexOf(this.BorderColor.Color)<0 || typeof(this.btnBorderColor.color)=='object'))) { @@ -1201,7 +1202,7 @@ define([ this.fillControls.push(this.btnInsertFromUrl); this.btnInsertFromFile.on('click', _.bind(function(btn){ - if (this.api) this.api.ChangeShapeImageFromFile(); + if (this.api) this.api.ChangeShapeImageFromFile(this.BlipFillType); this.fireEvent('editcomplete', this); }, this)); this.btnInsertFromUrl.on('click', _.bind(this.insertFromUrl, this)); diff --git a/apps/documenteditor/main/app/view/SignatureSettings.js b/apps/documenteditor/main/app/view/SignatureSettings.js new file mode 100644 index 000000000..265249083 --- /dev/null +++ b/apps/documenteditor/main/app/view/SignatureSettings.js @@ -0,0 +1,387 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * SignatureSettings.js + * + * Created by Julia Radzhabova on 5/24/17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'text!documenteditor/main/app/template/SignatureSettings.template', + 'jquery', + 'underscore', + 'backbone', + 'common/main/lib/component/Button' +], function (menuTemplate, $, _, Backbone) { + 'use strict'; + + DE.Views.SignatureSettings = Backbone.View.extend(_.extend({ + el: '#id-signature-settings', + + // Compile our stats template + template: _.template(menuTemplate), + + // Delegated events for creating new items, and clearing completed ones. + events: { + }, + + options: { + alias: 'SignatureSettings' + }, + + initialize: function () { + this._state = { + DisabledEditing: false, + ready: false, + hasValid: false, + hasInvalid: false, + hasRequested: false, + tip: undefined + }; + this._locked = false; + + this.render(); + }, + + render: function () { + this.$el.html(this.template({ + scope: this + })); + + var protection = DE.getController('Common.Controllers.Protection').getView(); + this.btnAddInvisibleSign = protection.getButton('signature'); + this.btnAddInvisibleSign.render(this.$el.find('#signature-invisible-sign')); + + this.viewRequestedList = new Common.UI.DataView({ + el: $('#signature-requested-sign'), + enableKeyEvents: false, + itemTemplate: _.template([ + '
    ', + '
    ', + '
    <%= Common.Utils.String.htmlEncode(name) %>
    ', + '
    ' + ].join('')) + }); + + this.viewValidList = new Common.UI.DataView({ + el: $('#signature-valid-sign'), + enableKeyEvents: false, + itemTemplate: _.template([ + '
    ', + '
    ' + 'nomargin' + '<% } %>">
    ', + '
    <%= Common.Utils.String.htmlEncode(name) %>
    ', + '
    <%= Common.Utils.String.htmlEncode(date) %>
    ', + '
    ' + ].join('')) + }); + + this.viewInvalidList = new Common.UI.DataView({ + el: $('#signature-invalid-sign'), + enableKeyEvents: false, + itemTemplate: _.template([ + '
    ', + '
    ' + 'nomargin' + '<% } %>">
    ', + '
    <%= Common.Utils.String.htmlEncode(name) %>
    ', + '
    <%= Common.Utils.String.htmlEncode(date) %>
    ', + '
    ' + ].join('')) + }); + + this.viewRequestedList.on('item:click', _.bind(this.onSelectSignature, this)); + this.viewValidList.on('item:click', _.bind(this.onSelectSignature, this)); + this.viewInvalidList.on('item:click', _.bind(this.onSelectSignature, this)); + + this.signatureMenu = new Common.UI.Menu({ + menuAlign : 'tr-br', + items: [ + { caption: this.strSign, value: 0 }, + { caption: this.strDetails,value: 1 }, + { caption: this.strSetup, value: 2 }, + { caption: this.strDelete, value: 3 } + ] + }); + this.signatureMenu.on('item:click', _.bind(this.onMenuSignatureClick, this)); + }, + + setApi: function(api) { + this.api = api; + if (this.api) { + this.api.asc_registerCallback('asc_onUpdateSignatures', _.bind(this.onApiUpdateSignatures, this)); + } + Common.NotificationCenter.on('document:ready', _.bind(this.onDocumentReady, this)); + return this; + }, + + ChangeSettings: function(props) { + if (!this._state.hasRequested && !this._state.hasValid && !this._state.hasInvalid) + this.updateSignatures(this.api.asc_getSignatures(), this.api.asc_getRequestSignatures()); + }, + + setLocked: function (locked) { + this._locked = locked; + }, + + setMode: function(mode) { + this.mode = mode; + }, + + onApiUpdateSignatures: function(valid, requested){ + if (!this._state.ready) return; + + this.updateSignatures(valid, requested); + this.showSignatureTooltip(this._state.hasValid, this._state.hasInvalid); + }, + + updateSignatures: function(valid, requested){ + var me = this, + requestedSignatures = [], + validSignatures = [], + invalidSignatures = []; + + _.each(requested, function(item, index){ + requestedSignatures.push({name: item.asc_getSigner1(), guid: item.asc_getGuid(), requested: true}); + }); + _.each(valid, function(item, index){ + var item_date = item.asc_getDate(); + var sign = {name: item.asc_getSigner1(), certificateId: item.asc_getId(), guid: item.asc_getGuid(), date: (!_.isEmpty(item_date)) ? new Date(item_date).toLocaleString() : '', invisible: !item.asc_getVisible()}; + (item.asc_getValid()==0) ? validSignatures.push(sign) : invalidSignatures.push(sign); + }); + + // requestedSignatures = [{name: 'Hammish Mitchell', guid: '123', requested: true}, {name: 'Someone Somewhere', guid: '123', requested: true}, {name: 'Mary White', guid: '123', requested: true}, {name: 'John Black', guid: '123', requested: true}]; + // validSignatures = [{name: 'Hammish Mitchell', guid: '123', date: '18/05/2017', invisible: true}, {name: 'Someone Somewhere', guid: '345', date: '18/05/2017'}]; + // invalidSignatures = [{name: 'Mary White', guid: '111', date: '18/05/2017'}, {name: 'John Black', guid: '456', date: '18/05/2017'}]; + + me._state.hasValid = validSignatures.length>0; + me._state.hasInvalid = invalidSignatures.length>0; + me._state.hasRequested = requestedSignatures.length>0; + + this.viewRequestedList.store.reset(requestedSignatures); + this.viewValidList.store.reset(validSignatures); + this.viewInvalidList.store.reset(invalidSignatures); + + this.$el.find('.requested').toggleClass('hidden', !me._state.hasRequested); + this.$el.find('.valid').toggleClass('hidden', !me._state.hasValid); + this.$el.find('.invalid').toggleClass('hidden', !me._state.hasInvalid); + + me.disableEditing(me._state.hasValid || me._state.hasInvalid); + }, + + onSelectSignature: function(picker, item, record, e){ + if (!record) return; + + var btn = $(e.target); + if (btn && btn.hasClass('caret')) { + var menu = this.signatureMenu; + if (menu.isVisible()) { + menu.hide(); + return; + } + + var showPoint, me = this, + currentTarget = $(e.currentTarget), + parent = $(this.el), + offset = currentTarget.offset(), + offsetParent = parent.offset(); + + showPoint = [offset.left - offsetParent.left + currentTarget.width(), offset.top - offsetParent.top + currentTarget.height()/2]; + + var menuContainer = parent.find('#menu-signature-container'); + if (!menu.rendered) { + if (menuContainer.length < 1) { + menuContainer = $('', menu.id); + parent.append(menuContainer); + } + menu.render(menuContainer); + menu.cmpEl.attr({tabindex: "-1"}); + + menu.on({ + 'show:after': function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', true); + }, + 'hide:after': function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', false); + } + }); + } + var requested = record.get('requested'), + signed = (this._state.hasValid || this._state.hasInvalid); + menu.items[0].setVisible(requested); + menu.items[1].setVisible(!requested); + menu.items[2].setVisible(requested || !record.get('invisible')); + menu.items[3].setVisible(!requested); + + menu.items[0].setDisabled(this._locked); + menu.items[3].setDisabled(this._locked); + + menu.items[1].cmpEl.attr('data-value', record.get('certificateId')); // view certificate + menu.items[2].cmpEl.attr('data-value', signed ? 1 : 0); // view or edit signature settings + menu.cmpEl.attr('data-value', record.get('guid')); + + menuContainer.css({left: showPoint[0], top: showPoint[1]}); + + menu.menuAlignEl = currentTarget; + menu.setOffset(-20, -currentTarget.height()/2 + 3); + menu.show(); + _.delay(function() { + menu.cmpEl.focus(); + }, 10); + e.stopPropagation(); + e.preventDefault(); + } else { + this.api.asc_gotoSignature(record.get('guid')); + } + }, + + onMenuSignatureClick: function(menu, item) { + var guid = menu.cmpEl.attr('data-value'); + switch (item.value) { + case 0: + Common.NotificationCenter.trigger('protect:sign', guid); + break; + case 1: + this.api.asc_ViewCertificate(item.cmpEl.attr('data-value')); + break; + case 2: + Common.NotificationCenter.trigger('protect:signature', 'visible', !!parseInt(item.cmpEl.attr('data-value')), guid);// can edit settings for requested signature + break; + case 3: + this.api.asc_RemoveSignature(guid); + break; + } + }, + + onDocumentReady: function() { + this._state.ready = true; + + this.updateSignatures(this.api.asc_getSignatures(), this.api.asc_getRequestSignatures()); + this.showSignatureTooltip(this._state.hasValid, this._state.hasInvalid, this._state.hasRequested); + }, + + showSignatureTooltip: function(hasValid, hasInvalid, hasRequested) { + var me = this, + tip = me._state.tip; + + if (!hasValid && !hasInvalid && !hasRequested) { + if (tip && tip.isVisible()) { + tip.close(); + me._state.tip = undefined; + } + return; + } + + var showLink = hasValid || hasInvalid, + tipText = (hasInvalid) ? me.txtSignedInvalid : (hasValid ? me.txtSigned : ""); + if (hasRequested) + tipText = me.txtRequestedSignatures + "

    " + tipText; + + if (tip && tip.isVisible() && (tipText !== tip.text || showLink !== tip.showLink)) { + tip.close(); + me._state.tip = undefined; + } + + if (!me._state.tip) { + tip = new Common.UI.SynchronizeTip({ + target : DE.getController('RightMenu').getView('RightMenu').btnSignature.btnEl, + text : tipText, + showLink: showLink, + textLink: this.txtContinueEditing, + placement: 'left' + }); + tip.on({ + 'dontshowclick': function() { + Common.UI.warning({ + title: me.notcriticalErrorTitle, + msg: me.txtEditWarning, + buttons: ['ok', 'cancel'], + primary: 'ok', + callback: function(btn) { + if (btn == 'ok') { + tip.close(); + me._state.tip = undefined; + me.api.asc_RemoveAllSignatures(); + } + } + }); + }, + 'closeclick': function() { + tip.close(); + me._state.tip = undefined; + } + }); + me._state.tip = tip; + tip.show(); + } + }, + + disableEditing: function(disable) { + if (this._state.DisabledEditing != disable) { + this._state.DisabledEditing = disable; + + var rightMenuController = DE.getController('RightMenu'); + if (disable && rightMenuController.rightmenu.GetActivePane() !== 'id-signature-settings') + rightMenuController.rightmenu.clearSelection(); + rightMenuController.SetDisabled(disable, false, true); + DE.getController('Toolbar').DisableToolbar(disable, disable); + DE.getController('Statusbar').getView('Statusbar').SetDisabled(disable); + DE.getController('Common.Controllers.ReviewChanges').SetDisabled(disable); + DE.getController('DocumentHolder').getView().SetDisabled(disable, true); + + var leftMenu = DE.getController('LeftMenu').leftMenu; + leftMenu.btnComments.setDisabled(disable); + var comments = DE.getController('Common.Controllers.Comments'); + if (comments) + comments.setPreviewMode(disable); + } + }, + + strSignature: 'Signature', + strRequested: 'Requested signatures', + strValid: 'Valid signatures', + strInvalid: 'Invalid signatures', + strSign: 'Sign', + strDetails: 'Signature Details', + strSetup: 'Signature Setup', + txtSigned: 'Valid signatures has been added to the document. The document is protected from editing.', + txtSignedInvalid: 'Some of the digital signatures in document are invalid or could not be verified. The document is protected from editing.', + txtRequestedSignatures: 'This document needs to be signed.', + txtContinueEditing: 'Edit anyway', + notcriticalErrorTitle: 'Warning', + txtEditWarning: 'Editing will remove the signatures from the document.
    Are you sure you want to continue?', + strDelete: 'Remove Signature' + + }, DE.Views.SignatureSettings || {})); +}); \ No newline at end of file diff --git a/apps/documenteditor/main/app/view/Statusbar.js b/apps/documenteditor/main/app/view/Statusbar.js index 386d13f95..05b758bb8 100644 --- a/apps/documenteditor/main/app/view/Statusbar.js +++ b/apps/documenteditor/main/app/view/Statusbar.js @@ -373,8 +373,11 @@ define([ $parent.find('#status-label-lang').text(info.title); var index = $parent.find('ul li a:contains("'+info.title+'")').parent().index(); - index < 0 ? this.langMenu.saved = info.title : - this.langMenu.items[index-1].setChecked(true); + if (index < 0) { + this.langMenu.saved = info.title; + this.langMenu.clearAll(); + } else + this.langMenu.items[index-1].setChecked(true); } }, diff --git a/apps/documenteditor/main/app/view/TableSettings.js b/apps/documenteditor/main/app/view/TableSettings.js index cf0ecc039..babc878c2 100644 --- a/apps/documenteditor/main/app/view/TableSettings.js +++ b/apps/documenteditor/main/app/view/TableSettings.js @@ -243,8 +243,8 @@ define([ if (me.api) { me.api.SplitCell(value.columns, value.rows); } - me.fireEvent('editcomplete', me); } + me.fireEvent('editcomplete', me); } })).show(); }, diff --git a/apps/documenteditor/main/app/view/TextArtSettings.js b/apps/documenteditor/main/app/view/TextArtSettings.js index 35ec21de0..859f8c90b 100644 --- a/apps/documenteditor/main/app/view/TextArtSettings.js +++ b/apps/documenteditor/main/app/view/TextArtSettings.js @@ -672,7 +672,8 @@ define([ // border colors var stroke = shapeprops.asc_getLine(), strokeType = (stroke) ? stroke.get_type() : null, - borderType; + borderType, + update = (this._state.StrokeColor == 'transparent' && this.BorderColor.Color !== 'transparent'); // border color was changed for shape without line and then shape was reselected (or apply other settings) if (stroke) { if ( strokeType == Asc.c_oAscStrokeType.STROKE_COLOR ) { @@ -697,7 +698,7 @@ define([ type1 = typeof(this.BorderColor.Color); type2 = typeof(this._state.StrokeColor); - if ( (type1 !== type2) || (type1=='object' && + if ( update || (type1 !== type2) || (type1=='object' && (this.BorderColor.Color.effectValue!==this._state.StrokeColor.effectValue || this._state.StrokeColor.color.indexOf(this.BorderColor.Color.color)<0)) || (type1!='object' && (this._state.StrokeColor.indexOf(this.BorderColor.Color)<0 || typeof(this.btnBorderColor.color)=='object'))) { diff --git a/apps/documenteditor/main/app/view/Toolbar.js b/apps/documenteditor/main/app/view/Toolbar.js index 8a6ee001a..13be79f3a 100644 --- a/apps/documenteditor/main/app/view/Toolbar.js +++ b/apps/documenteditor/main/app/view/Toolbar.js @@ -893,8 +893,8 @@ define([ iconCls: 'btn-colorschemas', menu: new Common.UI.Menu({ items: [], - maxHeight: 600, - restoreHeight: 600 + maxHeight: 560, + restoreHeight: 560 }).on('show:before', function (mnu) { if (!this.scroller) { this.scroller = new Common.UI.Scroller({ @@ -904,23 +904,6 @@ define([ alwaysVisibleY: true }); } - }).on('show:after', function (btn, e) { - var mnu = $(this.el).find('.dropdown-menu '), - docH = $(document).height(), - menuH = mnu.outerHeight(), - top = parseInt(mnu.css('top')); - - if (menuH > docH) { - mnu.css('max-height', (docH - parseInt(mnu.css('padding-top')) - parseInt(mnu.css('padding-bottom')) - 5) + 'px'); - this.scroller.update({minScrollbarLength: 40}); - } else if (mnu.height() < this.options.restoreHeight) { - mnu.css('max-height', (Math.min(docH - parseInt(mnu.css('padding-top')) - parseInt(mnu.css('padding-bottom')) - 5, this.options.restoreHeight)) + 'px'); - menuH = mnu.outerHeight(); - if (top + menuH > docH) { - mnu.css('top', 0); - } - this.scroller.update({minScrollbarLength: 40}); - } }) }); this.toolbarControls.push(this.btnColorSchemas); @@ -1189,17 +1172,6 @@ define([ this.needShowSynchTip = false; /** coauthoring end **/ - me.$tabs.parent().on('click', '.ribtab', function (e) { - var tab = $(e.target).data('tab'); - if (tab == 'file') { - me.fireEvent('file:open'); - } else - if ( me.isTabActive('file') ) - me.fireEvent('file:close'); - - me.setTab(tab); - }); - Common.NotificationCenter.on({ 'window:resize': function() { Common.UI.Mixtbar.prototype.onResize.apply(me, arguments); @@ -1225,6 +1197,21 @@ define([ return this; }, + onTabClick: function (e) { + var tab = $(e.target).data('tab'), + me = this; + + if ( !me.isTabActive(tab) ) { + if ( tab == 'file' ) { + me.fireEvent('file:open'); + } else + if ( me.isTabActive('file') ) + me.fireEvent('file:close'); + } + + Common.UI.Mixtbar.prototype.onTabClick.apply(me, arguments); + }, + rendererComponents: function (html) { var $host = $(html); var _injectComponent = function (id, cmp) { @@ -2110,8 +2097,8 @@ define([ if (this.mnuColorSchema == null) { this.mnuColorSchema = new Common.UI.Menu({ - maxHeight: 600, - restoreHeight: 600 + maxHeight: 560, + restoreHeight: 560 }).on('show:before', function (mnu) { this.scroller = new Common.UI.Scroller({ el: $(this.el).find('.dropdown-menu '), @@ -2469,7 +2456,9 @@ define([ capImgWrapping: 'Wrapping', capBtnComment: 'Comment', textColumnsCustom: 'Custom Columns', - textSurface: 'Surface' + textSurface: 'Surface', + textTabCollaboration: 'Collaboration', + textTabProtect: 'Protection' } })(), DE.Views.Toolbar || {})); }); diff --git a/apps/documenteditor/main/app_dev.js b/apps/documenteditor/main/app_dev.js index ff894fd0b..6e444ed4c 100644 --- a/apps/documenteditor/main/app_dev.js +++ b/apps/documenteditor/main/app_dev.js @@ -153,6 +153,7 @@ require([ ,'Common.Controllers.ExternalDiagramEditor' ,'Common.Controllers.ExternalMergeEditor' ,'Common.Controllers.ReviewChanges' + ,'Common.Controllers.Protection' ] }); @@ -173,6 +174,7 @@ require([ 'documenteditor/main/app/view/TableSettings', 'documenteditor/main/app/view/ShapeSettings', 'documenteditor/main/app/view/TextArtSettings', + 'documenteditor/main/app/view/SignatureSettings', 'common/main/lib/util/utils', 'common/main/lib/util/LocalStorage', 'common/main/lib/controller/Fonts', @@ -186,6 +188,7 @@ require([ ,'common/main/lib/controller/ExternalDiagramEditor' ,'common/main/lib/controller/ExternalMergeEditor' ,'common/main/lib/controller/ReviewChanges' + ,'common/main/lib/controller/Protection' ], function() { window.compareVersions = true; app.start(); diff --git a/apps/documenteditor/main/locale/en.json b/apps/documenteditor/main/locale/en.json index c7f0fa98f..d1b233dab 100644 --- a/apps/documenteditor/main/locale/en.json +++ b/apps/documenteditor/main/locale/en.json @@ -183,12 +183,29 @@ "Common.Views.OpenDialog.txtPassword": "Password", "Common.Views.OpenDialog.txtTitle": "Choose %1 options", "Common.Views.OpenDialog.txtTitleProtected": "Protected File", + "Common.Views.PasswordDialog.cancelButtonText": "Cancel", + "Common.Views.PasswordDialog.okButtonText": "OK", + "Common.Views.PasswordDialog.txtPassword": "Password", + "Common.Views.PasswordDialog.txtTitle": "Set Password", + "Common.Views.PasswordDialog.txtDescription": "A Password is required to open this document", + "Common.Views.PasswordDialog.txtRepeat": "Repeat password", + "Common.Views.PasswordDialog.txtIncorrectPwd": "Confirmation password is not identical", "Common.Views.PluginDlg.textLoading": "Loading", "Common.Views.Plugins.groupCaption": "Plugins", "Common.Views.Plugins.strPlugins": "Plugins", "Common.Views.Plugins.textLoading": "Loading", "Common.Views.Plugins.textStart": "Start", "Common.Views.Plugins.textStop": "Stop", + "Common.Views.Protection.txtAddPwd": "Add password", + "Common.Views.Protection.txtEncrypt": "Encrypt", + "Common.Views.Protection.txtSignature": "Signature", + "Common.Views.Protection.hintAddPwd": "Encrypt with password", + "Common.Views.Protection.hintPwd": "Change or delete password", + "Common.Views.Protection.hintSignature": "Add digital signature or signature line", + "Common.Views.Protection.txtChangePwd": "Change password", + "Common.Views.Protection.txtDeletePwd": "Delete password", + "Common.Views.Protection.txtInvisibleSignature": "Add digital signature", + "Common.Views.Protection.txtSignatureLine": "Signature line", "Common.Views.RenameDialog.cancelButtonText": "Cancel", "Common.Views.RenameDialog.okButtonText": "Ok", "Common.Views.RenameDialog.textName": "File name", @@ -207,10 +224,13 @@ "Common.Views.ReviewChanges.txtAcceptCurrent": "Accept Current Change", "Common.Views.ReviewChanges.txtClose": "Close", "Common.Views.ReviewChanges.txtDocLang": "Language", - "Common.Views.ReviewChanges.txtFinal": "All changes accepted (Preview)", - "Common.Views.ReviewChanges.txtMarkup": "All changes (Editing)", + "Common.Views.ReviewChanges.txtFinal": "All changes like accept (Preview)", + "Common.Views.ReviewChanges.txtMarkup": "Text with changes (Editing)", "Common.Views.ReviewChanges.txtNext": "Next", - "Common.Views.ReviewChanges.txtOriginal": "All changes rejected (Preview)", + "Common.Views.ReviewChanges.txtOriginal": "Text without changes (Preview)", + "Common.Views.ReviewChanges.txtMarkupCap": "Markup", + "Common.Views.ReviewChanges.txtFinalCap": "Final", + "Common.Views.ReviewChanges.txtOriginalCap": "Original", "Common.Views.ReviewChanges.txtPrev": "Previous", "Common.Views.ReviewChanges.txtReject": "Reject", "Common.Views.ReviewChanges.txtRejectAll": "Reject All Changes", @@ -219,6 +239,16 @@ "Common.Views.ReviewChanges.txtSpelling": "Spell Checking", "Common.Views.ReviewChanges.txtTurnon": "Track Changes", "Common.Views.ReviewChanges.txtView": "Display Mode", + "Common.Views.ReviewChanges.txtSharing": "Sharing", + "Common.Views.ReviewChanges.tipSharing": "Manage document access rights", + "Common.Views.ReviewChanges.txtCoAuthMode": "Co-editing Mode", + "Common.Views.ReviewChanges.tipCoAuthMode": "Set co-editing mode", + "Common.Views.ReviewChanges.strFast": "Fast", + "Common.Views.ReviewChanges.strStrict": "Strict", + "Common.Views.ReviewChanges.strFastDesc": "Real-time co-editing. All changes are saved automatically.", + "Common.Views.ReviewChanges.strStrictDesc": "Use the 'Save' button to sync the changes you and others make.", + "Common.Views.ReviewChanges.txtHistory": "Version History", + "Common.Views.ReviewChanges.tipHistory": "Show version history", "Common.Views.ReviewChangesDialog.textTitle": "Review Changes", "Common.Views.ReviewChangesDialog.txtAccept": "Accept", "Common.Views.ReviewChangesDialog.txtAcceptAll": "Accept All Changes", @@ -228,6 +258,32 @@ "Common.Views.ReviewChangesDialog.txtReject": "Reject", "Common.Views.ReviewChangesDialog.txtRejectAll": "Reject All Changes", "Common.Views.ReviewChangesDialog.txtRejectCurrent": "Reject Current Change", + "Common.Views.SignDialog.textTitle": "Sign Document", + "Common.Views.SignDialog.textPurpose": "Purpose for signing this document", + "Common.Views.SignDialog.textCertificate": "Certificate", + "Common.Views.SignDialog.textValid": "Valid from %1 to %2", + "Common.Views.SignDialog.textChange": "Change", + "Common.Views.SignDialog.cancelButtonText": "Cancel", + "Common.Views.SignDialog.okButtonText": "Ok", + "Common.Views.SignDialog.textInputName": "Input signer name", + "Common.Views.SignDialog.textUseImage": "or click 'Select Image' to use a picture as signature", + "Common.Views.SignDialog.textSelectImage": "Select Image", + "Common.Views.SignDialog.textSignature": "Signature looks as", + "Common.Views.SignDialog.tipFontName": "Font Name", + "Common.Views.SignDialog.tipFontSize": "Font Size", + "Common.Views.SignDialog.textBold": "Bold", + "Common.Views.SignDialog.textItalic": "Italic", + "Common.Views.SignSettingsDialog.textInfo": "Signer Info", + "Common.Views.SignSettingsDialog.textInfoName": "Name", + "Common.Views.SignSettingsDialog.textInfoTitle": "Signer Title", + "Common.Views.SignSettingsDialog.textInfoEmail": "E-mail", + "Common.Views.SignSettingsDialog.textInstructions": "Instructions for Signer", + "Common.Views.SignSettingsDialog.cancelButtonText": "Cancel", + "Common.Views.SignSettingsDialog.okButtonText": "Ok", + "Common.Views.SignSettingsDialog.txtEmpty": "This field is required", + "Common.Views.SignSettingsDialog.textAllowComment": "Allow signer to add comment in the signature dialog", + "Common.Views.SignSettingsDialog.textShowDate": "Show sign date in signature line", + "Common.Views.SignSettingsDialog.textTitle": "Signature Settings", "DE.Controllers.LeftMenu.leavePageText": "All unsaved changes in this document will be lost.
    Click \"Cancel\" then \"Save\" to save them. Click \"OK\" to discard all the unsaved changes.", "DE.Controllers.LeftMenu.newDocumentTitle": "Unnamed document", "DE.Controllers.LeftMenu.notcriticalErrorTitle": "Warning", @@ -322,6 +378,7 @@ "DE.Controllers.Main.txtButtons": "Buttons", "DE.Controllers.Main.txtCallouts": "Callouts", "DE.Controllers.Main.txtCharts": "Charts", + "DE.Controllers.Main.txtCurrentDocument": "Current Document", "DE.Controllers.Main.txtDiagramTitle": "Chart Title", "DE.Controllers.Main.txtEditingMode": "Set editing mode...", "DE.Controllers.Main.txtErrorLoadHistory": "History loading failed", @@ -350,6 +407,17 @@ "DE.Controllers.Main.txtStyle_Title": "Title", "DE.Controllers.Main.txtXAxis": "X Axis", "DE.Controllers.Main.txtYAxis": "Y Axis", + "DE.Controllers.Main.txtBookmarkError": "Error! Bookmark not defined.", + "DE.Controllers.Main.txtAbove": "above", + "DE.Controllers.Main.txtBelow": "below", + "DE.Controllers.Main.txtOnPage": "on page ", + "DE.Controllers.Main.txtHeader": "Header", + "DE.Controllers.Main.txtFooter": "Footer", + "DE.Controllers.Main.txtSection": " -Section ", + "DE.Controllers.Main.txtFirstPage": "First Page ", + "DE.Controllers.Main.txtEvenPage": "Even Page ", + "DE.Controllers.Main.txtOddPage": "Odd Page ", + "DE.Controllers.Main.txtSameAsPrev": "Same as Previous", "DE.Controllers.Main.unknownErrorText": "Unknown error.", "DE.Controllers.Main.unsupportedBrowserErrorText ": "Your browser is not supported.", "DE.Controllers.Main.uploadImageExtMessage": "Unknown image format.", @@ -903,6 +971,12 @@ "DE.Views.DocumentHolder.txtUngroup": "Ungroup", "DE.Views.DocumentHolder.updateStyleText": "Update %1 style", "DE.Views.DocumentHolder.vertAlignText": "Vertical Alignment", + "DE.Views.DocumentHolder.strSign": "Sign", + "DE.Views.DocumentHolder.strDetails": "Signature Details", + "DE.Views.DocumentHolder.strSetup": "Signature Setup", + "DE.Views.DocumentHolder.strDelete": "Remove Signature", + "DE.Views.DocumentHolder.txtOverwriteCells": "Overwrite cells", + "DE.Views.DocumentHolder.textNest": "Nest table", "DE.Views.DropcapSettingsAdvanced.cancelButtonText": "Cancel", "DE.Views.DropcapSettingsAdvanced.okButtonText": "Ok", "DE.Views.DropcapSettingsAdvanced.strBorders": "Borders & Fill", @@ -964,6 +1038,7 @@ "DE.Views.FileMenu.btnSettingsCaption": "Advanced Settings...", "DE.Views.FileMenu.btnToEditCaption": "Edit Document", "DE.Views.FileMenu.textDownload": "Download", + "DE.Views.FileMenu.btnProtectCaption": "Protect\\Sign", "DE.Views.FileMenuPanels.CreateNew.fromBlankText": "From Blank", "DE.Views.FileMenuPanels.CreateNew.fromTemplateText": "From Template", "DE.Views.FileMenuPanels.CreateNew.newDescriptionText": "Create a new blank text document which you will be able to style and format after it is created during the editing. Or choose one of the templates to start a document of a certain type or purpose where some styles have already been pre-applied.", @@ -984,6 +1059,17 @@ "DE.Views.FileMenuPanels.DocumentInfo.txtWords": "Words", "DE.Views.FileMenuPanels.DocumentRights.txtBtnAccessRights": "Change access rights", "DE.Views.FileMenuPanels.DocumentRights.txtRights": "Persons who have rights", + "DE.Views.FileMenuPanels.ProtectDoc.strProtect": "Protect Document", + "DE.Views.FileMenuPanels.ProtectDoc.strSignature": "Signature", + "DE.Views.FileMenuPanels.ProtectDoc.txtView": "View signatures", + "DE.Views.FileMenuPanels.ProtectDoc.txtEdit": "Edit document", + "DE.Views.FileMenuPanels.ProtectDoc.txtSigned": "Valid signatures has been added to the document. The document is protected from editing.", + "DE.Views.FileMenuPanels.ProtectDoc.txtSignedInvalid": "Some of the digital signatures in document are invalid or could not be verified. The document is protected from editing.", + "DE.Views.FileMenuPanels.ProtectDoc.txtRequestedSignatures": "This document needs to be signed.", + "DE.Views.FileMenuPanels.ProtectDoc.notcriticalErrorTitle": "Warning", + "DE.Views.FileMenuPanels.ProtectDoc.txtEditWarning": "Editing will remove the signatures from the document.
    Are you sure you want to continue?", + "DE.Views.FileMenuPanels.ProtectDoc.strEncrypt": "Password", + "DE.Views.FileMenuPanels.ProtectDoc.txtEncrypted": "This document has been protected by password", "DE.Views.FileMenuPanels.Settings.okButtonText": "Apply", "DE.Views.FileMenuPanels.Settings.strAlignGuides": "Turn on alignment guides", "DE.Views.FileMenuPanels.Settings.strAutoRecover": "Turn on autorecover", @@ -1300,6 +1386,8 @@ "DE.Views.ParagraphSettingsAdvanced.tipRight": "Set right border only", "DE.Views.ParagraphSettingsAdvanced.tipTop": "Set top border only", "DE.Views.ParagraphSettingsAdvanced.txtNoBorders": "No borders", + "DE.Views.ParagraphSettingsAdvanced.textLeader": "Leader", + "DE.Views.ParagraphSettingsAdvanced.textNone": "None", "DE.Views.RightMenu.txtChartSettings": "Chart settings", "DE.Views.RightMenu.txtHeaderFooterSettings": "Header and footer settings", "DE.Views.RightMenu.txtImageSettings": "Image settings", @@ -1308,6 +1396,7 @@ "DE.Views.RightMenu.txtShapeSettings": "Shape settings", "DE.Views.RightMenu.txtTableSettings": "Table settings", "DE.Views.RightMenu.txtTextArtSettings": "Text Art settings", + "DE.Views.RightMenu.txtSignatureSettings": "Signature Settings", "DE.Views.ShapeSettings.strBackground": "Background color", "DE.Views.ShapeSettings.strChange": "Change Autoshape", "DE.Views.ShapeSettings.strColor": "Color", @@ -1358,6 +1447,20 @@ "DE.Views.ShapeSettings.txtTight": "Tight", "DE.Views.ShapeSettings.txtTopAndBottom": "Top and bottom", "DE.Views.ShapeSettings.txtWood": "Wood", + "DE.Views.SignatureSettings.strSignature": "Signature", + "DE.Views.SignatureSettings.strRequested": "Requested signatures", + "DE.Views.SignatureSettings.strValid": "Valid signatures", + "DE.Views.SignatureSettings.strInvalid": "Invalid signatures", + "DE.Views.SignatureSettings.strSign": "Sign", + "DE.Views.SignatureSettings.strDetails": "Signature Details", + "DE.Views.SignatureSettings.strDelete": "Remove Signature", + "DE.Views.SignatureSettings.strSetup": "Signature Setup", + "DE.Views.SignatureSettings.txtSigned": "Valid signatures has been added to the document. The document is protected from editing.", + "DE.Views.SignatureSettings.txtSignedInvalid": "Some of the digital signatures in document are invalid or could not be verified. The document is protected from editing.", + "DE.Views.SignatureSettings.txtRequestedSignatures": "This document needs to be signed.", + "DE.Views.SignatureSettings.txtContinueEditing": "Edit anyway", + "DE.Views.SignatureSettings.notcriticalErrorTitle": "Warning", + "DE.Views.SignatureSettings.txtEditWarning": "Editing will remove the signatures from the document.
    Are you sure you want to continue?", "DE.Views.Statusbar.goToPageText": "Go to Page", "DE.Views.Statusbar.pageIndexText": "Page {0} of {1}", "DE.Views.Statusbar.tipFitPage": "Fit to page", @@ -1613,6 +1716,8 @@ "DE.Views.Toolbar.textTabInsert": "Insert", "DE.Views.Toolbar.textTabLayout": "Layout", "DE.Views.Toolbar.textTabReview": "Review", + "DE.Views.Toolbar.textTabCollaboration": "Collaboration", + "DE.Views.Toolbar.textTabProtect": "Protection", "DE.Views.Toolbar.textTitleError": "Error", "DE.Views.Toolbar.textToCurrent": "To current position", "DE.Views.Toolbar.textTop": "Top: ", diff --git a/apps/documenteditor/main/locale/ru.json b/apps/documenteditor/main/locale/ru.json index ee0487045..52b20e7eb 100644 --- a/apps/documenteditor/main/locale/ru.json +++ b/apps/documenteditor/main/locale/ru.json @@ -350,6 +350,8 @@ "DE.Controllers.Main.txtStyle_Title": "Название", "DE.Controllers.Main.txtXAxis": "Ось X", "DE.Controllers.Main.txtYAxis": "Ось Y", + "DE.Controllers.Main.txtHeader": "Верхний колонтитул", + "DE.Controllers.Main.txtFooter": "Нижний колонтитул", "DE.Controllers.Main.unknownErrorText": "Неизвестная ошибка.", "DE.Controllers.Main.unsupportedBrowserErrorText ": "Ваш браузер не поддерживается.", "DE.Controllers.Main.uploadImageExtMessage": "Неизвестный формат изображения.", diff --git a/apps/documenteditor/main/resources/img/toolbar-menu.png b/apps/documenteditor/main/resources/img/toolbar-menu.png index 8eda1c7d8..262b0d758 100644 Binary files a/apps/documenteditor/main/resources/img/toolbar-menu.png and b/apps/documenteditor/main/resources/img/toolbar-menu.png differ diff --git a/apps/documenteditor/main/resources/img/toolbar-menu@2x.png b/apps/documenteditor/main/resources/img/toolbar-menu@2x.png index b9f258d3f..d93c424e8 100644 Binary files a/apps/documenteditor/main/resources/img/toolbar-menu@2x.png and b/apps/documenteditor/main/resources/img/toolbar-menu@2x.png differ diff --git a/apps/documenteditor/main/resources/less/filemenu.less b/apps/documenteditor/main/resources/less/filemenu.less index 09a61ca02..a37fdee1a 100644 --- a/apps/documenteditor/main/resources/less/filemenu.less +++ b/apps/documenteditor/main/resources/less/filemenu.less @@ -144,7 +144,8 @@ width: 30%; label { - font: bold 12px tahoma, arial, verdana, sans-serif; + font-weight: bold; + font-size: 12px; } } @@ -367,6 +368,27 @@ } label, span { - font: 12px tahoma, arial, verdana, sans-serif; + font-size: 12px; } } + +#panel-protect { + label, span { + font-size: 12px; + } + + #file-menu-panel & { + padding: 30px 30px; + } + + .header { + font-weight: bold; + margin: 30px 0 10px; + } + + table { + td { + padding: 5px 0; + } + } +} \ No newline at end of file diff --git a/apps/documenteditor/main/resources/less/leftmenu.less b/apps/documenteditor/main/resources/less/leftmenu.less index ee490c488..1a58d8c97 100644 --- a/apps/documenteditor/main/resources/less/leftmenu.less +++ b/apps/documenteditor/main/resources/less/leftmenu.less @@ -77,4 +77,4 @@ button.notify .btn-menu-comments {background-position: -0*@toolbar-icon-size -60 -webkit-transform: rotate(180deg); -o-transform: rotate(180deg); transform: rotate(180deg); -} \ No newline at end of file +} diff --git a/apps/documenteditor/main/resources/less/rightmenu.less b/apps/documenteditor/main/resources/less/rightmenu.less index 2983c04f0..90b026654 100644 --- a/apps/documenteditor/main/resources/less/rightmenu.less +++ b/apps/documenteditor/main/resources/less/rightmenu.less @@ -105,6 +105,7 @@ /*menuTextArt*/ .button-normal-icon(btn-menu-textart, 54, @toolbar-icon-size); +.button-normal-icon(btn-menu-signature, 78, @toolbar-icon-size); .button-otherstates-icon2(btn-category, @toolbar-icon-size); @@ -268,3 +269,55 @@ button:active:not(.disabled) .btn-change-shape {background-position: -56px - .gradient-radial-center { background-position: -100px -150px; } + +#signature-requested-sign, +#signature-valid-sign, +#signature-invalid-sign { + height: 100%; + overflow: hidden; + margin: 0 -10px 0 -15px; + + .item { + display: block; + border: none; + width: 100%; + .box-shadow(none); + margin: 0; + + &:hover, + &.over { + background-color: @secondary; + } + } + + .signature-item { + padding: 5px 2px 5px 15px; + text-overflow: ellipsis; + min-height: 25px; + + .name { + width: 100%; + white-space: nowrap; + overflow: hidden; + cursor: pointer; + max-width: 160px; + text-overflow: ellipsis; + } + + .caret { + width: 23px; + height: 14px; + border: 0; + background-position: -43px -150px; + margin: 8px 15px; + display: inline-block; + position: absolute; + right: 0; + + &.nomargin { + margin-top: 0; + margin-bottom: 0; + } + } + } +} \ No newline at end of file diff --git a/apps/documenteditor/main/resources/less/toolbar.less b/apps/documenteditor/main/resources/less/toolbar.less index 171114fe6..8f3718162 100644 --- a/apps/documenteditor/main/resources/less/toolbar.less +++ b/apps/documenteditor/main/resources/less/toolbar.less @@ -1,13 +1,9 @@ @tabs-bg-color: #4f6279; -#toolbar { - //z-index: 101; -} - .toolbar { &:not(.cover) { - z-index: 101; + z-index: 1001; } &.masked { @@ -312,12 +308,6 @@ .button-normal-icon(mmerge-first, 74, @toolbar-icon-size); //.button-normal-icon(btn-columns, 75, @toolbar-icon-size); //.button-normal-icon(btn-pagemargins, 76, @toolbar-icon-size); -//.button-normal-icon(btn-img-frwd, 83, @toolbar-icon-size); -//.button-normal-icon(btn-img-bkwd, 84, @toolbar-icon-size); -//.button-normal-icon(btn-img-wrap, 85, @toolbar-icon-size); -//.button-normal-icon(btn-img-group, 86, @toolbar-icon-size); -//.button-normal-icon(btn-img-align, 87, @toolbar-icon-size); -.button-normal-icon(btn-goback, 88, @toolbar-icon-size); //.button-normal-icon(btn-insertimage, 17, @toolbar-icon-size); //.button-normal-icon(btn-inserttable, 18, @toolbar-icon-size); @@ -327,12 +317,7 @@ //.button-normal-icon(btn-text, 46, @toolbar-icon-size); //.button-normal-icon(btn-insertequation, 53, @toolbar-icon-size); //.button-normal-icon(btn-dropcap, 50, @toolbar-icon-size); -//.button-normal-icon(btn-ic-doclang, 67, @toolbar-icon-size); -//.button-normal-icon(btn-notes, 78, @toolbar-icon-size); -//.button-normal-icon(review-prev, 79, @toolbar-icon-size); -//.button-normal-icon(review-next, 80, @toolbar-icon-size); -//.button-normal-icon(review-save, 81, @toolbar-icon-size); -//.button-normal-icon(review-deny, 82, @toolbar-icon-size); +.button-normal-icon(btn-ic-doclang, 67, @toolbar-icon-size); @menu-icon-size: 22px; .menu-icon-normal(mnu-wrap-inline, 0, @menu-icon-size); diff --git a/apps/documenteditor/mobile/app/controller/Main.js b/apps/documenteditor/mobile/app/controller/Main.js index 8076ecf8f..64b305202 100644 --- a/apps/documenteditor/mobile/app/controller/Main.js +++ b/apps/documenteditor/mobile/app/controller/Main.js @@ -866,6 +866,8 @@ define([ } } else { + Common.Gateway.reportWarning(id, config.msg); + config.title = this.notcriticalErrorTitle; config.callback = _.bind(function(btn){ if (id == Asc.c_oAscError.ID.Warning && btn == 'ok' && (this.appOptions.canDownload || this.appOptions.canDownloadOrigin)) { diff --git a/apps/documenteditor/sdk_dev_scripts.js b/apps/documenteditor/sdk_dev_scripts.js index c021353bd..758428c8f 100644 --- a/apps/documenteditor/sdk_dev_scripts.js +++ b/apps/documenteditor/sdk_dev_scripts.js @@ -88,8 +88,10 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/word/Editor/GraphicObjects/WrapManager.js", "../../../../sdkjs/word/Editor/CollaborativeEditing.js", "../../../../sdkjs/word/Editor/DocumentContentElementBase.js", + "../../../../sdkjs/word/Editor/ParagraphContentBase.js", "../../../../sdkjs/word/Editor/Comments.js", "../../../../sdkjs/word/Editor/CommentsChanges.js", + "../../../../sdkjs/word/Editor/Bookmarks.js", "../../../../sdkjs/word/Editor/Styles.js", "../../../../sdkjs/word/Editor/StylesChanges.js", "../../../../sdkjs/word/Editor/RevisionsChange.js", @@ -98,6 +100,8 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/word/Editor/Paragraph/ParaTextPrChanges.js", "../../../../sdkjs/word/Editor/Paragraph/ParaDrawing.js", "../../../../sdkjs/word/Editor/Paragraph/ParaDrawingChanges.js", + "../../../../sdkjs/word/Editor/Paragraph/ComplexFieldInstruction.js", + "../../../../sdkjs/word/Editor/Paragraph/ComplexField.js", "../../../../sdkjs/word/Editor/Paragraph.js", "../../../../sdkjs/word/Editor/ParagraphChanges.js", "../../../../sdkjs/word/Editor/DocumentContentBase.js", @@ -109,8 +113,7 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/word/Editor/LogicDocumentController.js", "../../../../sdkjs/word/Editor/DrawingsController.js", "../../../../sdkjs/word/Editor/HeaderFooterController.js", - "../../../../sdkjs/word/Editor/FlowObjects.js", - "../../../../sdkjs/word/Editor/ParagraphContentBase.js", + "../../../../sdkjs/word/Editor/FlowObjects.js", "../../../../sdkjs/word/Editor/Hyperlink.js", "../../../../sdkjs/word/Editor/HyperlinkChanges.js", "../../../../sdkjs/word/Editor/Field.js", diff --git a/apps/presentationeditor/embed/js/ApplicationController.js b/apps/presentationeditor/embed/js/ApplicationController.js index bec396de7..d598967e4 100644 --- a/apps/presentationeditor/embed/js/ApplicationController.js +++ b/apps/presentationeditor/embed/js/ApplicationController.js @@ -497,6 +497,8 @@ var ApplicationController = new(function(){ }); } else { + Common.Gateway.reportWarning(id, message); + $('#id-critical-error-title').text(me.notcriticalErrorTitle); $('#id-critical-error-message').text(message); $('#id-critical-error-close').off(); diff --git a/apps/presentationeditor/main/app.js b/apps/presentationeditor/main/app.js index 0cb25efb3..88c9a9a38 100644 --- a/apps/presentationeditor/main/app.js +++ b/apps/presentationeditor/main/app.js @@ -155,6 +155,8 @@ require([ /** coauthoring end **/ ,'Common.Controllers.Plugins' ,'Common.Controllers.ExternalDiagramEditor' + ,'Common.Controllers.ReviewChanges' + ,'Common.Controllers.Protection' ] }); @@ -175,6 +177,7 @@ require([ 'presentationeditor/main/app/view/SlideSettings', 'presentationeditor/main/app/view/TableSettings', 'presentationeditor/main/app/view/TextArtSettings', + 'presentationeditor/main/app/view/SignatureSettings', 'common/main/lib/util/utils', 'common/main/lib/util/LocalStorage', 'common/main/lib/controller/Fonts' @@ -185,6 +188,8 @@ require([ 'common/main/lib/controller/Plugins', 'presentationeditor/main/app/view/ChartSettings', 'common/main/lib/controller/ExternalDiagramEditor' + ,'common/main/lib/controller/ReviewChanges' + ,'common/main/lib/controller/Protection' ], function() { app.start(); }); diff --git a/apps/presentationeditor/main/app/controller/LeftMenu.js b/apps/presentationeditor/main/app/controller/LeftMenu.js index 45e4e9550..cb450cf3f 100644 --- a/apps/presentationeditor/main/app/controller/LeftMenu.js +++ b/apps/presentationeditor/main/app/controller/LeftMenu.js @@ -94,8 +94,12 @@ define([ 'hide': _.bind(this.onSearchDlgHide, this), 'search:back': _.bind(this.onQuerySearch, this, 'back'), 'search:next': _.bind(this.onQuerySearch, this, 'next') + }, + 'Common.Views.ReviewChanges': { + 'collaboration:chat': _.bind(this.onShowHideChat, this) } }); + Common.NotificationCenter.on('leftmenu:change', _.bind(this.onMenuChange, this)); }, onLaunch: function() { @@ -238,27 +242,35 @@ define([ }, applySettings: function(menu) { - this.api.SetTextBoxInputMode(Common.localStorage.getBool("pe-settings-inputmode")); + var value = Common.localStorage.getBool("pe-settings-inputmode"); + Common.Utils.InternalSettings.set("pe-settings-inputmode", value); + this.api.SetTextBoxInputMode(value); if (Common.Utils.isChrome) { value = Common.localStorage.getBool("pe-settings-inputsogou"); + Common.Utils.InternalSettings.set("pe-settings-inputsogou", value); this.api.setInputParams({"SogouPinyin" : value}); } /** coauthoring begin **/ if (this.mode.isEdit && !this.mode.isOffline && this.mode.canCoAuthoring) { - this.api.asc_SetFastCollaborative(Common.localStorage.getBool("pe-settings-coauthmode", true)); + value = Common.localStorage.getBool("pe-settings-coauthmode", true); + Common.Utils.InternalSettings.set("pe-settings-coauthmode", value); + this.api.asc_SetFastCollaborative(value); } /** coauthoring end **/ if (this.mode.isEdit) { - var value = Common.localStorage.getItem("pe-settings-autosave"); - this.api.asc_setAutoSaveGap(parseInt(value)); + value = parseInt(Common.localStorage.getItem("pe-settings-autosave")); + Common.Utils.InternalSettings.set("pe-settings-autosave", value); + this.api.asc_setAutoSaveGap(value); - this.api.asc_setSpellCheck(Common.localStorage.getBool("pe-settings-spellcheck", true)); + value = Common.localStorage.getBool("pe-settings-spellcheck", true); + Common.Utils.InternalSettings.set("pe-settings-spellcheck", value); + this.api.asc_setSpellCheck(value); } - this.api.put_ShowSnapLines( Common.localStorage.getBool("pe-settings-showsnaplines") ); + this.api.put_ShowSnapLines(Common.Utils.InternalSettings.get("pe-settings-showsnaplines")); menu.hide(); }, @@ -533,18 +545,42 @@ define([ }, onPluginOpen: function(panel, type, action) { - if ( type == 'onboard' ) { - if ( action == 'open' ) { + if (type == 'onboard') { + if (action == 'open') { this.leftMenu.close(); this.leftMenu.btnThumbs.toggle(false, false); this.leftMenu.panelPlugins.show(); - this.leftMenu.onBtnMenuClick({pressed:true, options: {action: 'plugins'}}); + this.leftMenu.onBtnMenuClick({pressed: true, options: {action: 'plugins'}}); } else { this.leftMenu.close(); } } }, + onMenuChange: function (value) { + if ('hide' === value) { + if (this.leftMenu.btnComments.isActive() && this.api) { + this.leftMenu.btnComments.toggle(false); + this.leftMenu.onBtnMenuClick(this.leftMenu.btnComments); + + // focus to sdk + this.api.asc_enableKeyEvents(true); + } + } + }, + + onShowHideChat: function(state) { + if (this.mode.canCoAuthoring && this.mode.canChat && !this.mode.isLightVersion) { + if (state) { + Common.UI.Menu.Manager.hideAll(); + this.leftMenu.showMenu('chat'); + } else { + this.leftMenu.btnChat.toggle(false, true); + this.leftMenu.onBtnMenuClick(this.leftMenu.btnChat); + } + } + }, + textNoTextFound : 'Text not found', newDocumentTitle : 'Unnamed document', requestEditRightsText : 'Requesting editing rights...' diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js index c04f5d053..6c8c004ee 100644 --- a/apps/presentationeditor/main/app/controller/Main.js +++ b/apps/presentationeditor/main/app/controller/Main.js @@ -92,6 +92,9 @@ define([ this.addListeners({ 'FileMenu': { 'settings:apply': _.bind(this.applySettings, this) + }, + 'Common.Views.ReviewChanges': { + 'settings:apply': _.bind(this.applySettings, this) } }); }, @@ -142,7 +145,8 @@ define([ 'Slide subtitle': this.txtSlideSubtitle, 'Table': this.txtSldLtTTbl, 'Slide title': this.txtSlideTitle, - 'Loading': this.txtLoading + 'Loading': this.txtLoading, + 'Click to add notes': this.txtAddNotes } }); @@ -359,8 +363,17 @@ define([ } }, - onDownloadAs: function() { - this.api.asc_DownloadAs(Asc.c_oAscFileType.PPTX, true); + onDownloadAs: function(format) { + var _format = (format && (typeof format == 'string')) ? Asc.c_oAscFileType[ format.toUpperCase() ] : null, + _supported = [ + Asc.c_oAscFileType.PPTX, + Asc.c_oAscFileType.ODP, + Asc.c_oAscFileType.PDF + ]; + + if ( !_format || _supported.indexOf(_format) < 0 ) + _format = Asc.c_oAscFileType.PPTX; + this.api.asc_DownloadAs(_format, true); }, onProcessMouse: function(data) { @@ -572,10 +585,13 @@ define([ me.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument); value = Common.localStorage.getItem("pe-settings-zoom"); + Common.Utils.InternalSettings.set("pe-settings-zoom", value); var zf = (value!==null) ? parseInt(value) : (this.appOptions.customization && this.appOptions.customization.zoom ? parseInt(this.appOptions.customization.zoom) : -1); (zf == -1) ? this.api.zoomFitToPage() : ((zf == -2) ? this.api.zoomFitToWidth() : this.api.zoom(zf>0 ? zf : 100)); - me.api.asc_setSpellCheck(Common.localStorage.getBool("pe-settings-spellcheck", true)); + value = Common.localStorage.getBool("pe-settings-spellcheck", true); + Common.Utils.InternalSettings.set("pe-settings-spellcheck", value); + me.api.asc_setSpellCheck(value); function checkWarns() { if (!window['AscDesktopEditor']) { @@ -599,11 +615,14 @@ define([ appHeader.setDocumentCaption( me.api.asc_getDocumentName() ); me.updateWindowTitle(true); - me.api.SetTextBoxInputMode(Common.localStorage.getBool("pe-settings-inputmode")); + value = Common.localStorage.getBool("pe-settings-inputmode"); + Common.Utils.InternalSettings.set("pe-settings-inputmode", value); + me.api.SetTextBoxInputMode(value); if (Common.Utils.isChrome) { value = Common.localStorage.getBool("pe-settings-inputsogou"); me.api.setInputParams({"SogouPinyin" : value}); + Common.Utils.InternalSettings.set("pe-settings-inputsogou", value); } /** coauthoring begin **/ @@ -616,12 +635,16 @@ define([ me._state.fastCoauth = (value===null || parseInt(value) == 1); } else { me._state.fastCoauth = (!me.appOptions.isEdit && me.appOptions.canComments); - me._state.fastCoauth && me.api.asc_setAutoSaveGap(1); + if (me._state.fastCoauth) { + me.api.asc_setAutoSaveGap(1); + Common.Utils.InternalSettings.set("pe-settings-autosave", 1); + } } me.api.asc_SetFastCollaborative(me._state.fastCoauth); + Common.Utils.InternalSettings.set("pe-settings-coauthmode", me._state.fastCoauth); /** coauthoring end **/ - Common.localStorage.setBool("pe-settings-showsnaplines", me.api.get_ShowSnapLines()); + Common.Utils.InternalSettings.set("pe-settings-showsnaplines", me.api.get_ShowSnapLines()); var application = me.getApplication(); var toolbarController = application.getController('Toolbar'), @@ -662,9 +685,11 @@ define([ value = 0; value = (!me._state.fastCoauth && value!==null) ? parseInt(value) : (me.appOptions.canCoAuthoring ? 1 : 0); me.api.asc_setAutoSaveGap(value); + Common.Utils.InternalSettings.set("pe-settings-autosave", value); if (me.appOptions.canForcesave) {// use asc_setIsForceSaveOnUserSave only when customization->forcesave = true me.appOptions.forcesave = Common.localStorage.getBool("pe-settings-forcesave", me.appOptions.canForcesave); + Common.Utils.InternalSettings.set("pe-settings-forcesave", me.appOptions.forcesave); me.api.asc_setIsForceSaveOnUserSave(me.appOptions.forcesave); } @@ -694,16 +719,14 @@ define([ toolbarController.onApiCoAuthoringDisconnect(); me.api.UpdateInterfaceState(); - if (me.appOptions.canBrandingExt) - Common.NotificationCenter.trigger('document:ready', 'main'); + Common.NotificationCenter.trigger('document:ready', 'main'); me.applyLicense(); } }, 50); } else { documentHolderController.getView('DocumentHolder').createDelayedElementsViewer(); - if (me.appOptions.canBrandingExt) - Common.NotificationCenter.trigger('document:ready', 'main'); + Common.NotificationCenter.trigger('document:ready', 'main'); } if (this.appOptions.canAnalytics && false) @@ -814,6 +837,7 @@ define([ this.appOptions.forcesave = this.appOptions.canForcesave; this.appOptions.canEditComments= this.appOptions.isOffline || !(typeof (this.editorConfig.customization) == 'object' && this.editorConfig.customization.commentAuthorOnly); this.appOptions.trialMode = params.asc_getLicenseMode(); + this.appOptions.canProtect = this.appOptions.isDesktopApp && this.api.asc_isSignaturesSupport(); this.appOptions.canBranding = (licType === Asc.c_oLicenseResult.Success) && (typeof this.editorConfig.customization == 'object'); if (this.appOptions.canBranding) @@ -878,7 +902,8 @@ define([ application = this.getApplication(), toolbarController = application.getController('Toolbar'), rightmenuController = application.getController('RightMenu'), - fontsControllers = application.getController('Common.Controllers.Fonts'); + fontsControllers = application.getController('Common.Controllers.Fonts'), + reviewController = application.getController('Common.Controllers.ReviewChanges'); // me.getStore('SlideLayouts'); fontsControllers && fontsControllers.setApi(me.api); @@ -886,6 +911,11 @@ define([ rightmenuController && rightmenuController.setApi(me.api); + reviewController.setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + + if (me.appOptions.isDesktopApp && me.appOptions.isOffline) + application.getController('Common.Controllers.Protection').setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + var viewport = this.getApplication().getController('Viewport').getView('Viewport'); viewport.applyEditorMode(); @@ -914,6 +944,7 @@ define([ var value = Common.localStorage.getItem('pe-settings-unit'); value = (value!==null) ? parseInt(value) : Common.Utils.Metric.getDefaultMetric(); Common.Utils.Metric.setCurrentMetric(value); + Common.Utils.InternalSettings.set("pe-settings-unit", value); me.api.asc_SetDocumentUnits((value==Common.Utils.Metric.c_MetricUnits.inch) ? Asc.c_oAscDocumentUnits.Inch : ((value==Common.Utils.Metric.c_MetricUnits.pt) ? Asc.c_oAscDocumentUnits.Point : Asc.c_oAscDocumentUnits.Millimeter)); if (me.api.asc_SetViewRulers) me.api.asc_SetViewRulers(!Common.localStorage.getBool('pe-hidden-rulers', true)); @@ -1095,6 +1126,8 @@ define([ } } else { + Common.Gateway.reportWarning(id, config.msg); + config.title = this.notcriticalErrorTitle; config.iconCls = 'warn'; config.buttons = ['ok']; @@ -1102,6 +1135,20 @@ define([ if (id == Asc.c_oAscError.ID.Warning && btn == 'ok' && this.appOptions.canDownload) { Common.UI.Menu.Manager.hideAll(); (this.appOptions.isDesktopApp && this.appOptions.isOffline) ? this.api.asc_DownloadAs() : this.getApplication().getController('LeftMenu').leftMenu.showMenu('file:saveas'); + } else if (id == Asc.c_oAscError.ID.SplitCellMaxRows || id == Asc.c_oAscError.ID.SplitCellMaxCols || id == Asc.c_oAscError.ID.SplitCellRowsDivider) { + var me = this; + setTimeout(function(){ + (new Common.Views.InsertTableDialog({ + split: true, + handler: function(result, value) { + if (result == 'ok') { + if (me.api) + me.api.SplitCell(value.columns, value.rows); + } + me.onEditComplete(); + } + })).show(); + },10); } this._state.lostEditingRights = false; this.onEditComplete(); @@ -1391,6 +1438,7 @@ define([ var value = Common.localStorage.getItem("pe-settings-unit"); value = (value!==null) ? parseInt(value) : Common.Utils.Metric.getDefaultMetric(); Common.Utils.Metric.setCurrentMetric(value); + Common.Utils.InternalSettings.set("pe-settings-unit", value); this.api.asc_SetDocumentUnits((value==Common.Utils.Metric.c_MetricUnits.inch) ? Asc.c_oAscDocumentUnits.Inch : ((value==Common.Utils.Metric.c_MetricUnits.pt) ? Asc.c_oAscDocumentUnits.Point : Asc.c_oAscDocumentUnits.Millimeter)); this.getApplication().getController('RightMenu').updateMetricUnit(); }, @@ -1558,6 +1606,7 @@ define([ if (btn == 'custom') { Common.localStorage.setItem("pe-settings-coauthmode", 0); this.api.asc_SetFastCollaborative(false); + Common.Utils.InternalSettings.set("pe-settings-coauthmode", false); this._state.fastCoauth = false; } this.onEditComplete(); @@ -1583,6 +1632,7 @@ define([ } if (this.appOptions.canForcesave) { this.appOptions.forcesave = Common.localStorage.getBool("pe-settings-forcesave", this.appOptions.canForcesave); + Common.Utils.InternalSettings.set("pe-settings-forcesave", this.appOptions.forcesave); this.api.asc_setIsForceSaveOnUserSave(this.appOptions.forcesave); } }, @@ -1683,18 +1733,11 @@ define([ var pluginsData = (uiCustomize) ? plugins.UIpluginsData : plugins.pluginsData; if (!pluginsData || pluginsData.length<1) return; - var arr = [], - baseUrl = _.isEmpty(plugins.url) ? "" : plugins.url; - - if (baseUrl !== "") - console.warn("Obsolete: The url parameter is deprecated. Please check the documentation for new plugin connection configuration."); - + var arr = []; pluginsData.forEach(function(item){ - item = baseUrl + item; // for compatibility with previouse version of server, where plugins.url is used. var value = Common.Utils.getConfigJson(item); if (value) { value.baseUrl = item.substring(0, item.lastIndexOf("config.json")); - value.oldVersion = (baseUrl !== ""); arr.push(value); } }); @@ -1734,14 +1777,6 @@ define([ var visible = (isEdit || itemVar.isViewer) && _.contains(itemVar.EditorsSupport, 'slide'); if ( visible ) pluginVisible = true; - var icons = itemVar.icons; - if (item.oldVersion) { // for compatibility with previouse version of server, where plugins.url is used. - icons = []; - itemVar.icons.forEach(function(icon){ - icons.push(icon.substring(icon.lastIndexOf("\/")+1)); - }); - } - if ( item.isUICustomizer ) { visible && arrUI.push(item.baseUrl + itemVar.url); } else { @@ -1749,8 +1784,8 @@ define([ model.set({ index: variationsArr.length, - url: (item.oldVersion) ? (itemVar.url.substring(itemVar.url.lastIndexOf("\/") + 1) ) : itemVar.url, - icons: icons, + url: itemVar.url, + icons: itemVar.icons, visible: visible }); @@ -1936,6 +1971,7 @@ define([ saveTitleText: 'Saving Document', saveTextText: 'Saving document...', txtLoading: 'Loading...', + txtAddNotes: 'Click to add notes', warnNoLicenseUsers: 'This version of ONLYOFFICE Editors has certain limitations for concurrent users.
    If you need more please consider upgrading your current license or purchasing a commercial one.' } })(), PE.Controllers.Main || {})) diff --git a/apps/presentationeditor/main/app/controller/RightMenu.js b/apps/presentationeditor/main/app/controller/RightMenu.js index a625e3887..6b7c8e5d2 100644 --- a/apps/presentationeditor/main/app/controller/RightMenu.js +++ b/apps/presentationeditor/main/app/controller/RightMenu.js @@ -79,10 +79,12 @@ define([ this._settings[Common.Utils.documentSettingsType.Shape] = {panelId: "id-shape-settings", panel: rightMenu.shapeSettings, btn: rightMenu.btnShape, hidden: 1, locked: false}; this._settings[Common.Utils.documentSettingsType.TextArt] = {panelId: "id-textart-settings", panel: rightMenu.textartSettings, btn: rightMenu.btnTextArt, hidden: 1, locked: false}; this._settings[Common.Utils.documentSettingsType.Chart] = {panelId: "id-chart-settings", panel: rightMenu.chartSettings, btn: rightMenu.btnChart, hidden: 1, locked: false}; + this._settings[Common.Utils.documentSettingsType.Signature] = {panelId: "id-signature-settings", panel: rightMenu.signatureSettings, btn: rightMenu.btnSignature, hidden: 1, props: {}, locked: false}; }, setApi: function(api) { this.api = api; + this.api.asc_registerCallback('asc_onUpdateSignatures', _.bind(this.onApiUpdateSignatures, this)); this.api.asc_registerCallback('asc_onCountPages', _.bind(this.onApiCountPages, this)); this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.onCoAuthoringDisconnect, this)); Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); @@ -97,7 +99,7 @@ define([ var panel = this._settings[type].panel; var props = this._settings[type].props; if (props && panel) - panel.ChangeSettings.call(panel, props); + panel.ChangeSettings.call(panel, (type==Common.Utils.documentSettingsType.Signature) ? undefined : props); } Common.NotificationCenter.trigger('layout:changed', 'rightmenu'); this.rightmenu.fireEvent('editcomplete', this.rightmenu); @@ -109,12 +111,14 @@ define([ var needhide = true; for (var i=0; i0) ? 0 : 1; + this._settings[Common.Utils.documentSettingsType.Signature].locked = false; for (i=0; i 0) + this.onFocusObject(selectedElements); + } + } + }, + onInsertTable: function() { this._settings[Common.Utils.documentSettingsType.Table].needShow = true; }, @@ -268,6 +305,16 @@ define([ } }, + onApiUpdateSignatures: function(valid){ + if (!this.rightmenu.signatureSettings) return; + + var disabled = (!valid || valid.length<1), + type = Common.Utils.documentSettingsType.Signature; + this._settings[type].hidden = disabled ? 1 : 0; + this._settings[type].btn.setDisabled(disabled); + this._settings[type].panel.setLocked(this._settings[type].locked); + }, + onApiCountPages: function(count) { if (this._state.no_slides !== (count<=0) && this.editMode) { this._state.no_slides = (count<=0); diff --git a/apps/presentationeditor/main/app/controller/Statusbar.js b/apps/presentationeditor/main/app/controller/Statusbar.js index 1a7146282..0ac99b94b 100644 --- a/apps/presentationeditor/main/app/controller/Statusbar.js +++ b/apps/presentationeditor/main/app/controller/Statusbar.js @@ -84,7 +84,7 @@ define([ this.bindViewEvents(this.statusbar, this.events); - $('#status-label-zoom').css('min-width', 70); + $('#status-label-zoom').css('min-width', 80); this.statusbar.btnZoomToPage.on('click', _.bind(this.onBtnZoomTo, this, 'topage')); this.statusbar.btnZoomToWidth.on('click', _.bind(this.onBtnZoomTo, this, 'towidth')); @@ -208,6 +208,7 @@ define([ onBtnSpelling: function(d, b, e) { Common.localStorage.setItem("pe-settings-spellcheck", d.pressed ? 1 : 0); + Common.Utils.InternalSettings.set("pe-settings-spellcheck", d.pressed); this.api.asc_setSpellCheck(d.pressed); Common.NotificationCenter.trigger('edit:complete', this.statusbar); }, diff --git a/apps/presentationeditor/main/app/controller/Toolbar.js b/apps/presentationeditor/main/app/controller/Toolbar.js index 9e98c59df..e24abc378 100644 --- a/apps/presentationeditor/main/app/controller/Toolbar.js +++ b/apps/presentationeditor/main/app/controller/Toolbar.js @@ -121,6 +121,7 @@ define([ 'insert:text' : this.onInsertText.bind(this), 'insert:textart' : this.onInsertTextart.bind(this), 'insert:shape' : this.onInsertShape.bind(this), + 'add:slide' : this.onAddSlide.bind(this), 'change:compact' : this.onClickChangeCompact }, 'FileMenu': { @@ -166,8 +167,8 @@ define([ btn_id = cmp.closest('.btn-group').attr('id'); if (cmp.attr('id') != 'editor_sdk' && cmp_sdk.length<=0) { - if ( me.toolbar.btnsInsertText.pressed && !me.toolbar.btnsInsertText.contains(btn_id) || - me.toolbar.btnsInsertShape.pressed && !me.toolbar.btnsInsertShape.contains(btn_id) ) + if ( me.toolbar.btnsInsertText.pressed() && !me.toolbar.btnsInsertText.contains(btn_id) || + me.toolbar.btnsInsertShape.pressed() && !me.toolbar.btnsInsertShape.contains(btn_id) ) { me._isAddingShape = false; @@ -176,7 +177,7 @@ define([ me.toolbar.btnsInsertText.toggle(false, true); Common.NotificationCenter.trigger('edit:complete', me.toolbar); } else - if ( me.toolbar.btnsInsertShape.pressed && me.toolbar.btnsInsertShape.contains(btn_id) ) { + if ( me.toolbar.btnsInsertShape.pressed() && me.toolbar.btnsInsertShape.contains(btn_id) ) { _.defer(function(){ me.api.StartAddShape('', false); Common.NotificationCenter.trigger('edit:complete', me.toolbar); @@ -188,10 +189,10 @@ define([ this.onApiEndAddShape = function() { this.toolbar.fireEvent('insertshape', this.toolbar); - if ( this.toolbar.btnsInsertShape.pressed ) + if ( this.toolbar.btnsInsertShape.pressed() ) this.toolbar.btnsInsertShape.toggle(false, true); - if ( this.toolbar.btnsInsertText.pressed ) + if ( this.toolbar.btnsInsertText.pressed() ) this.toolbar.btnsInsertText.toggle(false, true); $(document.body).off('mouseup', checkInsertAutoshape); @@ -225,6 +226,10 @@ define([ PE.getCollection('ShapeGroups').bind({ reset: me.onResetAutoshapes.bind(this) }); + + PE.getCollection('SlideLayouts').bind({ + reset: me.onResetSlides.bind(this) + }); }, attachUIEvents: function(toolbar) { @@ -232,8 +237,6 @@ define([ * UI Events */ - toolbar.btnAddSlide.on('click', _.bind(this.onBtnAddSlide, this)); - toolbar.mnuAddSlidePicker.on('item:click', _.bind(this.onAddSlide, this)); if (toolbar.mnuChangeSlidePicker) toolbar.mnuChangeSlidePicker.on('item:click', _.bind(this.onChangeSlide, this)); toolbar.btnPreview.on('click', _.bind(this.onPreviewBtnClick, this)); @@ -499,7 +502,7 @@ define([ if (!(index < 0)) { btnHorizontalAlign.menu.items[index].setChecked(true); } else if (index == -255) { - this._clearChecked(btnHorizontalAlign.menu); + btnHorizontalAlign.menu.clearAll(); } if (btnHorizontalAlign.rendered) { @@ -532,7 +535,7 @@ define([ if (!(index < 0)) { btnVerticalAlign.menu.items[index].setChecked(true); } else if (index == -255) { - this._clearChecked(btnVerticalAlign.menu); + btnVerticalAlign.menu.clearAll(); } if (btnVerticalAlign.rendered) { @@ -803,23 +806,16 @@ define([ Common.component.Analytics.trackEvent('ToolBar', 'Open Document'); }, - onAddSlide: function(picker, item, record) { - if (this.api) { - if (record) - this.api.AddSlide(record.get('data').idx); + onAddSlide: function(type) { + var me = this; + if ( this.api) { + this.api.AddSlide(type); - Common.NotificationCenter.trigger('edit:complete', this.toolbar); + Common.NotificationCenter.trigger('edit:complete', me.toolbar); Common.component.Analytics.trackEvent('ToolBar', 'Add Slide'); } }, - onBtnAddSlide: function() { - this.api.AddSlide(); - - Common.NotificationCenter.trigger('edit:complete', this.toolbar); - Common.component.Analytics.trackEvent('ToolBar', 'Add Slide'); - }, - onChangeSlide: function(picker, item, record) { if (this.api) { if (record) @@ -1338,9 +1334,9 @@ define([ me.api.put_Table(value.columns, value.rows); } - Common.NotificationCenter.trigger('edit:complete', me.toolbar); Common.component.Analytics.trackEvent('ToolBar', 'Table'); } + Common.NotificationCenter.trigger('edit:complete', me.toolbar); } })).show(); } @@ -1384,12 +1380,12 @@ define([ if ( status == 'begin' ) { this._addAutoshape(true, 'textRect'); - if ( !this.toolbar.btnsInsertText.pressed ) + if ( !this.toolbar.btnsInsertText.pressed() ) this.toolbar.btnsInsertText.toggle(true, true); } else this._addAutoshape(false, 'textRect'); - if ( this.toolbar.btnsInsertShape.pressed ) + if ( this.toolbar.btnsInsertShape.pressed() ) this.toolbar.btnsInsertShape.toggle(false, true); Common.NotificationCenter.trigger('edit:complete', this.toolbar); @@ -1399,7 +1395,7 @@ define([ onInsertShape: function (type) { var me = this; if ( type == 'menu:hide' ) { - if ( me.toolbar.btnsInsertShape.pressed && !me._isAddingShape ) { + if ( me.toolbar.btnsInsertShape.pressed() && !me._isAddingShape ) { me.toolbar.btnsInsertShape.toggle(false, true); } me._isAddingShape = false; @@ -1409,7 +1405,7 @@ define([ me._addAutoshape(true, type); me._isAddingShape = true; - if ( me.toolbar.btnsInsertText.pressed ) + if ( me.toolbar.btnsInsertText.pressed() ) me.toolbar.btnsInsertText.toggle(false, true); Common.NotificationCenter.trigger('edit:complete', me.toolbar); @@ -1423,7 +1419,7 @@ define([ me.toolbar.fireEvent('inserttextart', me.toolbar); me.api.AddTextArt(data); - if ( me.toolbar.btnsInsertShape.pressed ) + if ( me.toolbar.btnsInsertShape.pressed() ) me.toolbar.btnsInsertShape.toggle(false, true); Common.NotificationCenter.trigger('edit:complete', me.toolbar); @@ -1717,6 +1713,12 @@ define([ }.bind(this)); }, + onResetSlides: function () { + setTimeout(function () { + this.toolbar.updateAddSlideMenu(PE.getCollection('SlideLayouts')); + }.bind(this), 0); + }, + fillEquations: function() { if (!this.toolbar.btnInsertEquation.rendered || this.toolbar.btnInsertEquation.menu.items.length>0) return; @@ -1776,10 +1778,10 @@ define([ if (record) me.api.asc_AddMath(record.get('data').equationType); - if (me.toolbar.btnsInsertText.pressed) { + if (me.toolbar.btnsInsertText.pressed()) { me.toolbar.btnsInsertText.toggle(false, true); } - if (me.toolbar.btnsInsertShape.pressed) { + if (me.toolbar.btnsInsertShape.pressed()) { me.toolbar.btnsInsertShape.toggle(false, true); } @@ -1948,13 +1950,6 @@ define([ this._state.clrtext_asccolor = undefined; }, - _clearChecked: function(menu) { - _.each(menu.items, function(item){ - if (item.setChecked) - item.setChecked(false, true); - }); - }, - _onInitEditorThemes: function(editorThemes, documentThemes) { var me = this; window.styles_loaded = false; @@ -2041,14 +2036,17 @@ define([ this._state.activated = true; }, - DisableToolbar: function(disable) { + DisableToolbar: function(disable, viewMode) { + if (viewMode!==undefined) this.editMode = !viewMode; + disable = disable || !this.editMode; + var mask = $('.toolbar-mask'); if (disable && mask.length>0 || !disable && mask.length==0) return; var toolbar = this.toolbar; toolbar.$el.find('.toolbar').toggleClass('masked', disable); - this.toolbar.lockToolbar(PE.enumLock.menuFileOpen, disable, {array: [toolbar.btnAddSlide, toolbar.btnChangeSlide, toolbar.btnPreview, toolbar.btnHide]}); + this.toolbar.lockToolbar(PE.enumLock.menuFileOpen, disable, {array: [toolbar.btnsAddSlide, toolbar.btnChangeSlide, toolbar.btnPreview, toolbar.btnHide]}); if(disable) { mask = $("
    ").appendTo(toolbar.$el.find('.toolbar')); Common.util.Shortcuts.suspendEvents('command+k, ctrl+k, alt+h, command+f5, ctrl+f5'); @@ -2076,6 +2074,20 @@ define([ } me.toolbar.render(_.extend({compactview: compactview}, config)); + + if ( config.isEdit ) { + var tab = {action: 'review', caption: me.toolbar.textTabCollaboration}; + var $panel = me.getApplication().getController('Common.Controllers.ReviewChanges').createToolbarPanel(); + if ( $panel ) + me.toolbar.addTab(tab, $panel, 3); + + if (config.isDesktopApp && config.isOffline) { + tab = {action: 'protect', caption: me.toolbar.textTabProtect}; + $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel(); + if ( $panel ) + me.toolbar.addTab(tab, $panel, 4); + } + } }, onAppReady: function (config) { diff --git a/apps/presentationeditor/main/app/template/FileMenu.template b/apps/presentationeditor/main/app/template/FileMenu.template index 53e645328..5565d15e9 100644 --- a/apps/presentationeditor/main/app/template/FileMenu.template +++ b/apps/presentationeditor/main/app/template/FileMenu.template @@ -8,6 +8,7 @@
  • +
  • @@ -29,4 +30,5 @@
    +
    \ No newline at end of file diff --git a/apps/presentationeditor/main/app/template/RightMenu.template b/apps/presentationeditor/main/app/template/RightMenu.template index baba70c3e..f4cfb2d7b 100644 --- a/apps/presentationeditor/main/app/template/RightMenu.template +++ b/apps/presentationeditor/main/app/template/RightMenu.template @@ -14,6 +14,8 @@
    +
    +
    @@ -24,5 +26,6 @@ +
    \ No newline at end of file diff --git a/apps/presentationeditor/main/app/template/SignatureSettings.template b/apps/presentationeditor/main/app/template/SignatureSettings.template new file mode 100644 index 000000000..8f0461e4f --- /dev/null +++ b/apps/presentationeditor/main/app/template/SignatureSettings.template @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    + +
    +
    +
    + +
    \ No newline at end of file diff --git a/apps/presentationeditor/main/app/template/Toolbar.template b/apps/presentationeditor/main/app/template/Toolbar.template index d7a1b14ec..a66ccad0e 100644 --- a/apps/presentationeditor/main/app/template/Toolbar.template +++ b/apps/presentationeditor/main/app/template/Toolbar.template @@ -41,13 +41,13 @@
  • -
    - -
    -
    +
    + +
    +
    @@ -123,6 +123,10 @@
    +
    + +
    +
    diff --git a/apps/presentationeditor/main/app/view/DocumentHolder.js b/apps/presentationeditor/main/app/view/DocumentHolder.js index df4466f13..74ebb1f5a 100644 --- a/apps/presentationeditor/main/app/view/DocumentHolder.js +++ b/apps/presentationeditor/main/app/view/DocumentHolder.js @@ -67,7 +67,8 @@ define([ me._currentSpellObj = undefined; me._currLang = {}; me._state = {}; - + me._isDisabled = false; + /** coauthoring begin **/ var usersStore = PE.getCollection('Common.Collections.Users'); /** coauthoring end **/ @@ -212,7 +213,7 @@ define([ var showObjectMenu = function(event, docElement, eOpts){ if (me.api){ - var obj = (me.mode.isEdit) ? fillMenuProps(me.api.getSelectedElements()) : fillViewMenuProps(me.api.getSelectedElements()); + var obj = (me.mode.isEdit && !me._isDisabled) ? fillMenuProps(me.api.getSelectedElements()) : fillViewMenuProps(me.api.getSelectedElements()); if (obj) showPopupMenu(obj.menu_to_show, obj.menu_props, event, docElement, eOpts); } }; @@ -220,8 +221,7 @@ define([ var onContextMenu = function(event){ _.delay(function(){ if (event.get_Type() == Asc.c_oAscContextMenuTypes.Thumbnails) { - if (me.mode.isEdit) - showPopupMenu.call(me, me.slideMenu, {isSlideSelect: event.get_IsSlideSelect(), isSlideHidden: event.get_IsSlideHidden(), fromThumbs: true}, event); + !me._isDisabled && showPopupMenu.call(me, me.slideMenu, {isSlideSelect: event.get_IsSlideSelect(), isSlideHidden: event.get_IsSlideHidden(), fromThumbs: true}, event); } else { showObjectMenu.call(me, event); } @@ -231,7 +231,7 @@ define([ var onFocusObject = function(selectedElements) { if (me.currentMenu && me.currentMenu.isVisible()){ if (me.api.asc_getCurrentFocusObject() === 0 ){ // thumbnails - if (me.slideMenu===me.currentMenu) { + if (me.slideMenu===me.currentMenu && !me._isDisabled) { var isHidden = false; _.each(selectedElements, function(element, index) { if (Asc.c_oAscTypeSelectElement.Slide == element.get_ObjectType()) { @@ -243,7 +243,7 @@ define([ me.currentMenu.alignPosition(); } } else { - var obj = (me.mode.isEdit) ? fillMenuProps(selectedElements) : fillViewMenuProps(selectedElements); + var obj = (me.mode.isEdit && !me._isDisabled) ? fillMenuProps(selectedElements) : fillViewMenuProps(selectedElements); if (obj) { if (obj.menu_to_show===me.currentMenu) { me.currentMenu.options.initMenu(obj.menu_props); @@ -296,6 +296,10 @@ define([ $('ul.dropdown-menu', me.currentMenu.el).focus(); } } + if (key == Common.UI.Keys.ESC) { + Common.UI.Menu.Manager.hideAll(); + Common.NotificationCenter.trigger('leftmenu:change', 'hide'); + } } }; @@ -578,7 +582,7 @@ define([ var onDialogAddHyperlink = function() { var win, props, text; - if (me.api && me.mode.isEdit){ + if (me.api && me.mode.isEdit && !me._isDisabled){ var handlerDlg = function(dlg, result) { if (result == 'ok') { props = dlg.getSettings(); @@ -671,7 +675,7 @@ define([ }; var onDoubleClickOnChart = function(chart) { - if (me.mode.isEdit) { + if (me.mode.isEdit && !me._isDisabled) { var diagramEditor = PE.getController('Common.Controllers.ExternalDiagramEditor').getView('Common.Views.ExternalDiagramEditor'); if (diagramEditor && chart) { @@ -1490,6 +1494,69 @@ define([ me._state.themeLock = false; }; + var onShowSpecialPasteOptions = function(specialPasteShowOptions) { + var coord = specialPasteShowOptions.asc_getCellCoord(), + pasteContainer = me.cmpEl.find('#special-paste-container'), + pasteItems = specialPasteShowOptions.asc_getOptions(); + + // Prepare menu container + if (pasteContainer.length < 1) { + me._arrSpecialPaste = []; + me._arrSpecialPaste[Asc.c_oSpecialPasteProps.paste] = me.textPaste; + me._arrSpecialPaste[Asc.c_oSpecialPasteProps.keepTextOnly] = me.txtKeepTextOnly; + me._arrSpecialPaste[Asc.c_oSpecialPasteProps.picture] = me.txtPastePicture; + me._arrSpecialPaste[Asc.c_oSpecialPasteProps.sourceformatting] = me.txtPasteSourceFormat; + me._arrSpecialPaste[Asc.c_oSpecialPasteProps.destinationFormatting] = me.txtPasteDestFormat; + + + pasteContainer = $('
    '); + me.cmpEl.append(pasteContainer); + + me.btnSpecialPaste = new Common.UI.Button({ + cls : 'btn-toolbar', + iconCls : 'btn-paste', + menu : new Common.UI.Menu({items: []}) + }); + me.btnSpecialPaste.render($('#id-document-holder-btn-special-paste')) ; + } + + if (pasteItems.length>0) { + var menu = me.btnSpecialPaste.menu; + for (var i = 0; i < menu.items.length; i++) { + menu.removeItem(menu.items[i]); + i--; + } + + var group_prev = -1; + _.each(pasteItems, function(menuItem, index) { + var mnu = new Common.UI.MenuItem({ + caption: me._arrSpecialPaste[menuItem], + value: menuItem, + checkable: true, + toggleGroup : 'specialPasteGroup' + }).on('click', function(item, e) { + me.api.asc_SpecialPaste(item.value); + setTimeout(function(){menu.hide();}, 100); + }); + menu.addItem(mnu); + }); + (menu.items.length>0) && menu.items[0].setChecked(true, true); + } + if (coord.asc_getX()<0 || coord.asc_getY()<0) { + if (pasteContainer.is(':visible')) pasteContainer.hide(); + } else { + var showPoint = [coord.asc_getX() + coord.asc_getWidth() + 3, coord.asc_getY() + coord.asc_getHeight() + 3]; + pasteContainer.css({left: showPoint[0], top : showPoint[1]}); + pasteContainer.show(); + } + }; + + var onHideSpecialPasteOptions = function() { + var pasteContainer = me.cmpEl.find('#special-paste-container'); + if (pasteContainer.is(':visible')) + pasteContainer.hide(); + }; + this.setApi = function(o) { me.api = o; @@ -1511,6 +1578,9 @@ define([ me.api.asc_registerCallback('asc_onDialogAddHyperlink', _.bind(onDialogAddHyperlink, me)); me.api.asc_registerCallback('asc_doubleClickOnChart', onDoubleClickOnChart); me.api.asc_registerCallback('asc_onSpellCheckVariantsFound', _.bind(onSpellCheckVariantsFound, me)); + me.api.asc_registerCallback('asc_onShowSpecialPasteOptions', _.bind(onShowSpecialPasteOptions, me)); + me.api.asc_registerCallback('asc_onHideSpecialPasteOptions', _.bind(onHideSpecialPasteOptions, me)); + } me.api.asc_registerCallback('asc_onCoAuthoringDisconnect', _.bind(onCoAuthoringDisconnect, me)); Common.NotificationCenter.on('api:disconnect', _.bind(onCoAuthoringDisconnect, me)); @@ -1711,10 +1781,10 @@ define([ this.viewModeMenu = new Common.UI.Menu({ initMenu: function (value) { - menuViewUndo.setVisible(me.mode.canCoAuthoring && me.mode.canComments); - menuViewUndo.setDisabled(!me.api.asc_getCanUndo()); - menuViewCopySeparator.setVisible(!value.isChart && me.api.can_AddQuotedComment() !== false && me.mode.canCoAuthoring && me.mode.canComments); - menuViewAddComment.setVisible(!value.isChart && me.api.can_AddQuotedComment() !== false && me.mode.canCoAuthoring && me.mode.canComments); + menuViewUndo.setVisible(me.mode.canCoAuthoring && me.mode.canComments && !me._isDisabled); + menuViewUndo.setDisabled(!me.api.asc_getCanUndo() && !me._isDisabled); + menuViewCopySeparator.setVisible(!value.isChart && me.api.can_AddQuotedComment() !== false && me.mode.canCoAuthoring && me.mode.canComments && !me._isDisabled); + menuViewAddComment.setVisible(!value.isChart && me.api.can_AddQuotedComment() !== false && me.mode.canCoAuthoring && me.mode.canComments && !me._isDisabled); menuViewAddComment.setDisabled(value.locked); }, items: [ @@ -1905,7 +1975,7 @@ define([ el : $('#id-docholder-menu-changeslide'), parentMenu : mnuChangeSlide.menu, showLast: false, - restoreHeight: 300, + // restoreHeight: 300, style: 'max-height: 300px;', store : PE.getCollection('SlideLayouts'), itemTemplate: _.template([ @@ -1939,7 +2009,7 @@ define([ me.slideThemeMenu = new Common.UI.DataView({ el : $('#id-docholder-menu-changetheme'), parentMenu : mnuChangeTheme.menu, - restoreHeight: 300, + // restoreHeight: 300, style: 'max-height: 300px;', store : PE.getCollection('SlideThemes'), itemTemplate: _.template([ @@ -1986,9 +2056,9 @@ define([ if (me.api) { me.api.SplitCell(value.columns, value.rows); } - me.fireEvent('editcomplete', me); Common.component.Analytics.trackEvent('DocumentHolder', 'Table Split'); } + me.fireEvent('editcomplete', me); } })).show(); } @@ -3131,6 +3201,10 @@ define([ } }, + SetDisabled: function(state) { + this._isDisabled = state; + }, + insertRowAboveText : 'Row Above', insertRowBelowText : 'Row Below', insertColumnLeftText : 'Column Left', @@ -3285,7 +3359,11 @@ define([ langText: 'Select Language', textUndo: 'Undo', txtSlideHide: 'Hide Slide', - txtChangeTheme: 'Change Theme' + txtChangeTheme: 'Change Theme', + txtKeepTextOnly: 'Keep text only', + txtPastePicture: 'Picture', + txtPasteSourceFormat: 'Keep source formatting', + txtPasteDestFormat: 'Use destination theme' }, PE.Views.DocumentHolder || {})); }); \ No newline at end of file diff --git a/apps/presentationeditor/main/app/view/DocumentPreview.js b/apps/presentationeditor/main/app/view/DocumentPreview.js index f91dd33de..a2d60240a 100644 --- a/apps/presentationeditor/main/app/view/DocumentPreview.js +++ b/apps/presentationeditor/main/app/view/DocumentPreview.js @@ -227,10 +227,18 @@ define([ } } ); + + this.previewControls = $(this.el).find('.preview-controls'); + $(document).on("webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange",function(){ var fselem = (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement ); me.btnFullScreen.cmpEl.toggleClass('fullscreen', fselem !== undefined && fselem !== null); + setTimeout( function() { + me.previewControls.css('display', ''); + me.$el.css('cursor', ''); + },100); + if (Common.Utils.isIE) { // for tooltips in IE me.btnFullScreen.updateHint( fselem ? '' : me.txtFullScreen); me.btnPrev.updateHint( fselem ? '' : me.txtPrev); @@ -242,18 +250,17 @@ define([ }); if (Common.Utils.isIE) { - el.find('.preview-controls').css('opacity', '0.4'); + me.previewControls.css('opacity', '0.4'); } this.separatorFullScreen = el.find('.separator.fullscreen'); - var controls = $(this.el).find('.preview-controls'); - controls.on('mouseenter', function(e) { + me.previewControls.on('mouseenter', function(e) { clearTimeout(me.timerMove); - controls.addClass('over'); + me.previewControls.addClass('over'); }); - controls.on('mouseleave', function(e) { - controls.removeClass('over'); + me.previewControls.on('mouseleave', function(e) { + me.previewControls.removeClass('over'); }); }, @@ -274,18 +281,17 @@ define([ } var me = this; - var controls = $(this.el).find('.preview-controls'); - controls.css('display', 'none'); + me.previewControls.css('display', 'none'); me.$el.css('cursor', 'none'); setTimeout(function(){ me.$el.on('mousemove', function() { clearTimeout(me.timerMove); - controls.css('display', ''); + me.previewControls.css('display', ''); me.$el.css('cursor', ''); - if (!controls.hasClass('over')) + if (!me.previewControls.hasClass('over')) me.timerMove = setTimeout(function () { - controls.css('display', 'none'); + me.previewControls.css('display', 'none'); me.$el.css('cursor', 'none'); }, 3000); @@ -372,6 +378,8 @@ define([ fullScreen: function(element) { if (this.mode.isDesktopApp || Common.Utils.isIE11) return; if (element) { + this.previewControls.css('display', 'none'); + this.$el.css('cursor', 'none'); if(element.requestFullscreen) { element.requestFullscreen(); } else if(element.webkitRequestFullscreen) { @@ -386,6 +394,8 @@ define([ fullScreenCancel: function () { if (this.mode.isDesktopApp || Common.Utils.isIE11) return; + this.previewControls.css('display', 'none'); + this.$el.css('cursor', 'none'); if(document.cancelFullScreen) { document.cancelFullScreen(); } else if(document.webkitCancelFullScreen ) { diff --git a/apps/presentationeditor/main/app/view/FileMenu.js b/apps/presentationeditor/main/app/view/FileMenu.js index e6d79d23d..6d88796be 100644 --- a/apps/presentationeditor/main/app/view/FileMenu.js +++ b/apps/presentationeditor/main/app/view/FileMenu.js @@ -129,6 +129,13 @@ define([ canFocused: false }); + this.miProtect = new Common.UI.MenuItem({ + el : $('#fm-btn-protect',this.el), + action : 'protect', + caption : this.btnProtectCaption, + canFocused: false + }); + this.miRecent = new Common.UI.MenuItem({ el : $('#fm-btn-recent',this.el), action : 'recent', @@ -164,6 +171,7 @@ define([ this.miSaveAs, this.miPrint, this.miRename, + this.miProtect, this.miRecent, this.miNew, new Common.UI.MenuItem({ @@ -210,10 +218,12 @@ define([ show: function(panel) { if (this.isVisible() && panel===undefined) return; + var defPanel = (this.mode.canDownload && (!this.mode.isDesktopApp || !this.mode.isOffline)) ? 'saveas' : 'info'; if (!panel) - panel = this.active || ((this.mode.canDownload && (!this.mode.isDesktopApp || !this.mode.isOffline)) ? 'saveas' : 'info'); + panel = this.active || defPanel; this.$el.show(); - this.selectMenu(panel); + this.selectMenu(panel, defPanel); + this.api.asc_enableKeyEvents(false); this.fireEvent('menu:show', [this]); @@ -228,7 +238,8 @@ define([ applyMode: function() { this.miPrint[this.mode.canPrint?'show':'hide'](); this.miRename[(this.mode.canRename && !this.mode.isDesktopApp) ?'show':'hide'](); - this.miRename.$el.find('+.devider')[!this.mode.isDisconnected?'show':'hide'](); + this.miProtect[(this.mode.isEdit && this.mode.isDesktopApp && this.mode.isOffline) ?'show':'hide'](); + this.miProtect.$el.find('+.devider')[!this.mode.isDisconnected?'show':'hide'](); this.miRecent[this.mode.canOpenRecent?'show':'hide'](); this.miNew[this.mode.canCreateNew?'show':'hide'](); this.miNew.$el.find('+.devider')[this.mode.canCreateNew?'show':'hide'](); @@ -264,8 +275,10 @@ define([ } } - if (this.mode.targetApp == 'desktop') { + if (this.mode.isDesktopApp && this.mode.isOffline) { this.$el.find('#fm-btn-create, #fm-btn-back, #fm-btn-create+.devider').hide(); + this.panels['protect'] = (new PE.Views.FileMenuPanels.ProtectDoc({menu:this})).render(); + this.panels['protect'].setMode(this.mode); } this.panels['help'].setLangConfig(this.mode.lang); @@ -288,6 +301,7 @@ define([ setApi: function(api) { this.api = api; + if (this.panels['protect']) this.panels['protect'].setApi(api); this.api.asc_registerCallback('asc_onDocumentName', _.bind(this.onDocumentName, this)); }, @@ -295,10 +309,14 @@ define([ this.document = data.doc; }, - selectMenu: function(menu) { + selectMenu: function(menu, defMenu) { if ( menu ) { - var item = this._getMenuItem(menu), + var item = this._getMenuItem(menu), panel = this.panels[menu]; + if ( item.isDisabled() ) { + item = this._getMenuItem(defMenu); + panel = this.panels[defMenu]; + } if ( item && panel ) { $('.fm-btn',this.el).removeClass('active'); item.$el.addClass('active'); @@ -354,6 +372,7 @@ define([ btnSettingsCaption : 'Advanced Settings...', btnSaveAsCaption : 'Save as', btnRenameCaption : 'Rename...', - btnCloseMenuCaption : 'Close Menu' + btnCloseMenuCaption : 'Close Menu', + btnProtectCaption: 'Protect\\Sign' }, PE.Views.FileMenu || {})); }); diff --git a/apps/presentationeditor/main/app/view/FileMenuPanels.js b/apps/presentationeditor/main/app/view/FileMenuPanels.js index 4aae8916d..8942e9bed 100644 --- a/apps/presentationeditor/main/app/view/FileMenuPanels.js +++ b/apps/presentationeditor/main/app/view/FileMenuPanels.js @@ -296,43 +296,36 @@ define([ }, updateSettings: function() { - this.chSpell.setValue(Common.localStorage.getBool("pe-settings-spellcheck", true)); + this.chSpell.setValue(Common.Utils.InternalSettings.get("pe-settings-spellcheck")); - this.chInputMode.setValue(Common.localStorage.getBool("pe-settings-inputmode")); - Common.Utils.isChrome && this.chInputSogou.setValue(Common.localStorage.getBool("pe-settings-inputsogou")); + this.chInputMode.setValue(Common.Utils.InternalSettings.get("pe-settings-inputmode")); + Common.Utils.isChrome && this.chInputSogou.setValue(Common.Utils.InternalSettings.get("pe-settings-inputsogou")); - var value = Common.localStorage.getItem("pe-settings-zoom"); + var value = Common.Utils.InternalSettings.get("pe-settings-zoom"); value = (value!==null) ? parseInt(value) : (this.mode.customization && this.mode.customization.zoom ? parseInt(this.mode.customization.zoom) : -1); var item = this.cmbZoom.store.findWhere({value: value}); this.cmbZoom.setValue(item ? parseInt(item.get('value')) : (value>0 ? value+'%' : 100)); /** coauthoring begin **/ - value = Common.localStorage.getItem("pe-settings-coauthmode"); - if (value===null && !Common.localStorage.itemExists("pe-settings-autosave") && - this.mode.customization && this.mode.customization.autosave===false) - value = 0; // use customization.autosave only when pe-settings-coauthmode and pe-settings-autosave are null - var fast_coauth = (value===null || parseInt(value) == 1) && !(this.mode.isDesktopApp && this.mode.isOffline) && this.mode.canCoAuthoring; - - item = this.cmbCoAuthMode.store.findWhere({value: parseInt(value)}); + var fast_coauth = Common.Utils.InternalSettings.get("pe-settings-coauthmode"); + item = this.cmbCoAuthMode.store.findWhere({value: fast_coauth ? 1 : 0}); this.cmbCoAuthMode.setValue(item ? item.get('value') : 1); this.lblCoAuthMode.text(item ? item.get('descValue') : this.strCoAuthModeDescFast); /** coauthoring end **/ - value = Common.localStorage.getItem("pe-settings-unit"); - item = this.cmbUnit.store.findWhere({value: parseInt(value)}); + value = Common.Utils.InternalSettings.get("pe-settings-unit"); + item = this.cmbUnit.store.findWhere({value: value}); this.cmbUnit.setValue(item ? parseInt(item.get('value')) : Common.Utils.Metric.getDefaultMetric()); this._oldUnits = this.cmbUnit.getValue(); - value = Common.localStorage.getItem("pe-settings-autosave"); - if (value===null && this.mode.customization && this.mode.customization.autosave===false) - value = 0; - this.chAutosave.setValue(fast_coauth || (value===null ? this.mode.canCoAuthoring : parseInt(value) == 1)); + value = Common.Utils.InternalSettings.get("pe-settings-autosave"); + this.chAutosave.setValue(value == 1); if (this.mode.canForcesave) { - this.chForcesave.setValue(Common.localStorage.getBool("pe-settings-forcesave", this.mode.canForcesave)); + this.chForcesave.setValue(Common.Utils.InternalSettings.get("pe-settings-forcesave")); } - this.chAlignGuides.setValue(Common.localStorage.getBool("pe-settings-showsnaplines", true)); + this.chAlignGuides.setValue(Common.Utils.InternalSettings.get("pe-settings-showsnaplines")); }, applySettings: function() { @@ -340,6 +333,7 @@ define([ Common.localStorage.setItem("pe-settings-inputmode", this.chInputMode.isChecked() ? 1 : 0); Common.Utils.isChrome && Common.localStorage.setItem("pe-settings-inputsogou", this.chInputSogou.isChecked() ? 1 : 0); Common.localStorage.setItem("pe-settings-zoom", this.cmbZoom.getValue()); + Common.Utils.InternalSettings.set("pe-settings-zoom", Common.localStorage.getItem("pe-settings-zoom")); /** coauthoring begin **/ if (this.mode.isEdit && !this.mode.isOffline && this.mode.canCoAuthoring) { Common.localStorage.setItem("pe-settings-coauthmode", this.cmbCoAuthMode.getValue()); @@ -349,7 +343,8 @@ define([ Common.localStorage.setItem("pe-settings-autosave", this.chAutosave.isChecked() ? 1 : 0); if (this.mode.canForcesave) Common.localStorage.setItem("pe-settings-forcesave", this.chForcesave.isChecked() ? 1 : 0); - Common.localStorage.setItem("pe-settings-showsnaplines", this.chAlignGuides.isChecked() ? 1 : 0); + Common.Utils.InternalSettings.set("pe-settings-showsnaplines", this.chAlignGuides.isChecked()); + Common.localStorage.save(); if (this.menu) { @@ -670,6 +665,8 @@ define([ }); } + Common.NotificationCenter.on('collaboration:sharing', _.bind(this.changeAccessRights, this)); + return this; }, @@ -866,4 +863,167 @@ define([ } } }); + + PE.Views.FileMenuPanels.ProtectDoc = Common.UI.BaseView.extend(_.extend({ + el: '#panel-protect', + menu: undefined, + + template: _.template([ + '', + '
    ', + '', + '
    ', + '', + '', + '', + '', + '', + '', + '', + '', + '
    <%= scope.txtEncrypted %>
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ' + ].join('')), + + initialize: function(options) { + Common.UI.BaseView.prototype.initialize.call(this,arguments); + + this.menu = options.menu; + + var me = this; + this.templateSignature = _.template([ + '', + '', + '', + '', + '', + '', + '', + '', + '
    <%= tipText %>
    ' + ].join('')); + }, + + render: function() { + $(this.el).html(this.template({scope: this})); + + var protection = PE.getController('Common.Controllers.Protection').getView(); + + this.btnAddPwd = protection.getButton('add-password'); + this.btnAddPwd.render(this.$el.find('#fms-btn-add-pwd')); + this.btnAddPwd.on('click', _.bind(this.closeMenu, this)); + + this.btnChangePwd = protection.getButton('change-password'); + this.btnChangePwd.render(this.$el.find('#fms-btn-change-pwd')); + this.btnChangePwd.on('click', _.bind(this.closeMenu, this)); + + this.btnDeletePwd = protection.getButton('del-password'); + this.btnDeletePwd.render(this.$el.find('#fms-btn-delete-pwd')); + this.btnDeletePwd.on('click', _.bind(this.closeMenu, this)); + + this.cntPassword = $('#id-fms-view-pwd'); + + this.btnAddInvisibleSign = protection.getButton('signature'); + this.btnAddInvisibleSign.render(this.$el.find('#fms-btn-invisible-sign')); + this.btnAddInvisibleSign.on('click', _.bind(this.closeMenu, this)); + + this.cntSignature = $('#id-fms-signature'); + this.cntSignatureView = $('#id-fms-signature-view'); + if (_.isUndefined(this.scroller)) { + this.scroller = new Common.UI.Scroller({ + el: $(this.el), + suppressScrollX: true + }); + } + + this.$el.on('click', '.signature-edit-link', _.bind(this.onEdit, this)); + this.$el.on('click', '.signature-view-link', _.bind(this.onView, this)); + + return this; + }, + + show: function() { + Common.UI.BaseView.prototype.show.call(this,arguments); + this.updateSignatures(); + this.updateEncrypt(); + }, + + setMode: function(mode) { + this.mode = mode; + this.cntSignature.toggleClass('hidden', !this.mode.canProtect); + }, + + setApi: function(o) { + this.api = o; + return this; + }, + + closeMenu: function() { + this.menu && this.menu.hide(); + }, + + onEdit: function() { + this.menu && this.menu.hide(); + + var me = this; + Common.UI.warning({ + title: this.notcriticalErrorTitle, + msg: this.txtEditWarning, + buttons: ['ok', 'cancel'], + primary: 'ok', + callback: function(btn) { + if (btn == 'ok') { + me.api.asc_RemoveAllSignatures(); + } + } + }); + + }, + + onView: function() { + this.menu && this.menu.hide(); + PE.getController('RightMenu').rightmenu.SetActivePane(Common.Utils.documentSettingsType.Signature, true); + }, + + updateSignatures: function(){ + var valid = this.api.asc_getSignatures(), + hasValid = false, + hasInvalid = false; + + _.each(valid, function(item, index){ + if (item.asc_getValid()==0) + hasValid = true; + else + hasInvalid = true; + }); + + // hasValid = true; + // hasInvalid = true; + + var tipText = (hasInvalid) ? this.txtSignedInvalid : (hasValid ? this.txtSigned : ""); + this.cntSignatureView.html(this.templateSignature({tipText: tipText, hasSigned: (hasValid || hasInvalid)})); + }, + + updateEncrypt: function() { + this.cntPassword.toggleClass('hidden', this.btnAddPwd.isVisible()); + }, + + strProtect: 'Protect Presentation', + strSignature: 'Signature', + txtView: 'View signatures', + txtEdit: 'Edit presentation', + txtSigned: 'Valid signatures has been added to the presentation. The presentation is protected from editing.', + txtSignedInvalid: 'Some of the digital signatures in presentation are invalid or could not be verified. The presentation is protected from editing.', + notcriticalErrorTitle: 'Warning', + txtEditWarning: 'Editing will remove the signatures from the presentation.
    Are you sure you want to continue?', + strEncrypt: 'Password', + txtEncrypted: 'This presentation has been protected by password' + + }, PE.Views.FileMenuPanels.ProtectDoc || {})); + }); diff --git a/apps/presentationeditor/main/app/view/ImageSettings.js b/apps/presentationeditor/main/app/view/ImageSettings.js index d57634338..2919e53b7 100644 --- a/apps/presentationeditor/main/app/view/ImageSettings.js +++ b/apps/presentationeditor/main/app/view/ImageSettings.js @@ -127,8 +127,11 @@ define([ this.btnOriginalSize.on('click', _.bind(this.setOriginalSize, this)); this.btnInsertFromFile.on('click', _.bind(function(btn){ + if (this._isFromFile) return; + this._isFromFile = true; if (this.api) this.api.ChangeImageFromFile(); this.fireEvent('editcomplete', this); + this._isFromFile = false; }, this)); this.btnInsertFromUrl.on('click', _.bind(this.insertFromUrl, this)); this.btnEditObject.on('click', _.bind(function(btn){ diff --git a/apps/presentationeditor/main/app/view/LeftMenu.js b/apps/presentationeditor/main/app/view/LeftMenu.js index f4d2dbbc5..5bd9deb5c 100644 --- a/apps/presentationeditor/main/app/view/LeftMenu.js +++ b/apps/presentationeditor/main/app/view/LeftMenu.js @@ -282,7 +282,7 @@ define([ } if (this.mode.canChat) { this.panelChat['hide'](); - this.btnChat.toggle(false, true); + this.btnChat.toggle(false); } } /** coauthoring end **/ diff --git a/apps/presentationeditor/main/app/view/RightMenu.js b/apps/presentationeditor/main/app/view/RightMenu.js index fe1d4583a..0551372cf 100644 --- a/apps/presentationeditor/main/app/view/RightMenu.js +++ b/apps/presentationeditor/main/app/view/RightMenu.js @@ -56,6 +56,7 @@ define([ 'presentationeditor/main/app/view/ShapeSettings', 'presentationeditor/main/app/view/SlideSettings', 'presentationeditor/main/app/view/TextArtSettings', + 'presentationeditor/main/app/view/SignatureSettings', 'common/main/lib/component/Scroller' ], function (menuTemplate, $, _, Backbone) { 'use strict'; @@ -143,7 +144,7 @@ define([ return this; }, - render: function () { + render: function (mode) { var el = $(this.el); this.trigger('render:before', this); @@ -178,6 +179,21 @@ define([ this.shapeSettings = new PE.Views.ShapeSettings(); this.textartSettings = new PE.Views.TextArtSettings(); + if (mode && mode.canProtect) { + this.btnSignature = new Common.UI.Button({ + hint: this.txtSignatureSettings, + asctype: Common.Utils.documentSettingsType.Signature, + enableToggle: true, + disabled: true, + toggleGroup: 'tabpanelbtnsGroup' + }); + this._settings[Common.Utils.documentSettingsType.Signature] = {panel: "id-signature-settings", btn: this.btnSignature}; + + this.btnSignature.el = $('#id-right-menu-signature'); this.btnSignature.render().setVisible(true); + this.btnSignature.on('click', _.bind(this.onBtnMenuClick, this)); + this.signatureSettings = new PE.Views.SignatureSettings(); + } + if (_.isUndefined(this.scroller)) { this.scroller = new Common.UI.Scroller({ el: $(this.el).find('.right-panel'), @@ -206,6 +222,7 @@ define([ this.tableSettings.setApi(api).on('editcomplete', _.bind( fire, this)); this.shapeSettings.setApi(api).on('editcomplete', _.bind( fire, this)); this.textartSettings.setApi(api).on('editcomplete', _.bind( fire, this)); + if (this.signatureSettings) this.signatureSettings.setApi(api).on('editcomplete', _.bind( fire, this)); }, setMode: function(mode) { @@ -263,23 +280,6 @@ define([ return (this.minimizedMode) ? null : this.$el.find(".settings-panel.active")[0].id; }, - SetDisabled: function(id, disabled, all) { - if (all) { - this.slideSettings.SetSlideDisabled(disabled, disabled, disabled); - this.paragraphSettings.disableControls(disabled); - this.shapeSettings.disableControls(disabled); - this.tableSettings.disableControls(disabled); - this.imageSettings.disableControls(disabled); - this.chartSettings.disableControls(disabled); - } else { - var cmp = $("#" + id); - if (disabled !== cmp.hasClass('disabled')) { - cmp.toggleClass('disabled', disabled); - (disabled) ? cmp.attr({disabled: disabled}) : cmp.removeAttr('disabled'); - } - } - }, - clearSelection: function() { var target_pane = $(".right-panel"); target_pane.find('> .active').removeClass('active'); @@ -299,6 +299,7 @@ define([ txtShapeSettings: 'Shape Settings', txtTextArtSettings: 'Text Art Settings', txtSlideSettings: 'Slide Settings', - txtChartSettings: 'Chart Settings' + txtChartSettings: 'Chart Settings', + txtSignatureSettings: 'Signature Settings' }, PE.Views.RightMenu || {})); }); \ No newline at end of file diff --git a/apps/presentationeditor/main/app/view/ShapeSettings.js b/apps/presentationeditor/main/app/view/ShapeSettings.js index e44ce7f15..3d96ff791 100644 --- a/apps/presentationeditor/main/app/view/ShapeSettings.js +++ b/apps/presentationeditor/main/app/view/ShapeSettings.js @@ -892,7 +892,8 @@ define([ // border colors var stroke = props.get_stroke(), strokeType = stroke.get_type(), - borderType; + borderType, + update = (this._state.StrokeColor == 'transparent' && this.BorderColor.Color !== 'transparent'); // border color was changed for shape without line and then shape was reselected (or apply other settings) if (stroke) { if ( strokeType == Asc.c_oAscStrokeType.STROKE_COLOR ) { @@ -918,7 +919,7 @@ define([ type1 = typeof(this.BorderColor.Color); type2 = typeof(this._state.StrokeColor); - if ( (type1 !== type2) || (type1=='object' && + if ( update || (type1 !== type2) || (type1=='object' && (this.BorderColor.Color.effectValue!==this._state.StrokeColor.effectValue || this._state.StrokeColor.color.indexOf(this.BorderColor.Color.color)<0)) || (type1!='object' && (this._state.StrokeColor.indexOf(this.BorderColor.Color)<0 || typeof(this.btnBorderColor.color)=='object'))) { @@ -1114,7 +1115,7 @@ define([ this.fillControls.push(this.btnInsertFromUrl); this.btnInsertFromFile.on('click', _.bind(function(btn){ - if (this.api) this.api.ChangeShapeImageFromFile(); + if (this.api) this.api.ChangeShapeImageFromFile(this.BlipFillType); this.fireEvent('editcomplete', this); }, this)); this.btnInsertFromUrl.on('click', _.bind(this.insertFromUrl, this)); diff --git a/apps/presentationeditor/main/app/view/SignatureSettings.js b/apps/presentationeditor/main/app/view/SignatureSettings.js new file mode 100644 index 000000000..0d9deec6a --- /dev/null +++ b/apps/presentationeditor/main/app/view/SignatureSettings.js @@ -0,0 +1,341 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * SignatureSettings.js + * + * Created by Julia Radzhabova on 5/24/17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'text!presentationeditor/main/app/template/SignatureSettings.template', + 'jquery', + 'underscore', + 'backbone', + 'common/main/lib/component/Button' +], function (menuTemplate, $, _, Backbone) { + 'use strict'; + + PE.Views.SignatureSettings = Backbone.View.extend(_.extend({ + el: '#id-signature-settings', + + // Compile our stats template + template: _.template(menuTemplate), + + // Delegated events for creating new items, and clearing completed ones. + events: { + }, + + options: { + alias: 'SignatureSettings' + }, + + initialize: function () { + this._state = { + DisabledEditing: false, + ready: false, + hasValid: false, + hasInvalid: false, + tip: undefined + }; + this._locked = false; + + this.render(); + }, + + render: function () { + this.$el.html(this.template({ + scope: this + })); + + var protection = PE.getController('Common.Controllers.Protection').getView(); + this.btnAddInvisibleSign = protection.getButton('signature'); + this.btnAddInvisibleSign.render(this.$el.find('#signature-invisible-sign')); + + this.viewValidList = new Common.UI.DataView({ + el: $('#signature-valid-sign'), + enableKeyEvents: false, + itemTemplate: _.template([ + '
    ', + '
    ' + 'nomargin' + '<% } %>">
    ', + '
    <%= Common.Utils.String.htmlEncode(name) %>
    ', + '
    <%= Common.Utils.String.htmlEncode(date) %>
    ', + '
    ' + ].join('')) + }); + + this.viewInvalidList = new Common.UI.DataView({ + el: $('#signature-invalid-sign'), + enableKeyEvents: false, + itemTemplate: _.template([ + '
    ', + '
    ' + 'nomargin' + '<% } %>">
    ', + '
    <%= Common.Utils.String.htmlEncode(name) %>
    ', + '
    <%= Common.Utils.String.htmlEncode(date) %>
    ', + '
    ' + ].join('')) + }); + + this.viewValidList.on('item:click', _.bind(this.onSelectSignature, this)); + this.viewInvalidList.on('item:click', _.bind(this.onSelectSignature, this)); + + this.signatureMenu = new Common.UI.Menu({ + menuAlign : 'tr-br', + items: [ + { caption: this.strDetails,value: 1 }, + { caption: this.strDelete, value: 3 } + ] + }); + this.signatureMenu.on('item:click', _.bind(this.onMenuSignatureClick, this)); + }, + + setApi: function(api) { + this.api = api; + if (this.api) { + this.api.asc_registerCallback('asc_onUpdateSignatures', _.bind(this.onApiUpdateSignatures, this)); + } + Common.NotificationCenter.on('document:ready', _.bind(this.onDocumentReady, this)); + return this; + }, + + ChangeSettings: function(props) { + if (!this._state.hasValid && !this._state.hasInvalid) + this.updateSignatures(this.api.asc_getSignatures()); + }, + + setLocked: function (locked) { + this._locked = locked; + }, + + setMode: function(mode) { + this.mode = mode; + }, + + onApiUpdateSignatures: function(valid){ + if (!this._state.ready) return; + + this.updateSignatures(valid); + this.showSignatureTooltip(this._state.hasValid, this._state.hasInvalid); + }, + + updateSignatures: function(valid){ + var me = this, + validSignatures = [], + invalidSignatures = []; + + _.each(valid, function(item, index){ + var item_date = item.asc_getDate(); + var sign = {name: item.asc_getSigner1(), certificateId: item.asc_getId(), guid: item.asc_getGuid(), date: (!_.isEmpty(item_date)) ? new Date(item_date).toLocaleString() : '', invisible: !item.asc_getVisible()}; + (item.asc_getValid()==0) ? validSignatures.push(sign) : invalidSignatures.push(sign); + }); + + // validSignatures = [{name: 'Hammish Mitchell', guid: '123', date: '18/05/2017', invisible: true}, {name: 'Someone Somewhere', guid: '345', date: '18/05/2017'}]; + // invalidSignatures = [{name: 'Mary White', guid: '111', date: '18/05/2017'}, {name: 'John Black', guid: '456', date: '18/05/2017'}]; + + me._state.hasValid = validSignatures.length>0; + me._state.hasInvalid = invalidSignatures.length>0; + + this.viewValidList.store.reset(validSignatures); + this.viewInvalidList.store.reset(invalidSignatures); + + this.$el.find('.valid').toggleClass('hidden', !me._state.hasValid); + this.$el.find('.invalid').toggleClass('hidden', !me._state.hasInvalid); + + me.disableEditing(me._state.hasValid || me._state.hasInvalid); + }, + + onSelectSignature: function(picker, item, record, e){ + if (!record) return; + + var btn = $(e.target); + if (btn && btn.hasClass('caret')) { + var menu = this.signatureMenu; + if (menu.isVisible()) { + menu.hide(); + return; + } + + var showPoint, me = this, + currentTarget = $(e.currentTarget), + parent = $(this.el), + offset = currentTarget.offset(), + offsetParent = parent.offset(); + + showPoint = [offset.left - offsetParent.left + currentTarget.width(), offset.top - offsetParent.top + currentTarget.height()/2]; + + var menuContainer = parent.find('#menu-signature-container'); + if (!menu.rendered) { + if (menuContainer.length < 1) { + menuContainer = $('', menu.id); + parent.append(menuContainer); + } + menu.render(menuContainer); + menu.cmpEl.attr({tabindex: "-1"}); + + menu.on({ + 'show:after': function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', true); + }, + 'hide:after': function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', false); + } + }); + } + menu.items[1].setDisabled(this._locked); + + menu.items[0].cmpEl.attr('data-value', record.get('certificateId')); // view certificate + menu.cmpEl.attr('data-value', record.get('guid')); + + menuContainer.css({left: showPoint[0], top: showPoint[1]}); + + menu.menuAlignEl = currentTarget; + menu.setOffset(-20, -currentTarget.height()/2 + 3); + menu.show(); + _.delay(function() { + menu.cmpEl.focus(); + }, 10); + e.stopPropagation(); + e.preventDefault(); + } + }, + + onMenuSignatureClick: function(menu, item) { + var guid = menu.cmpEl.attr('data-value'); + switch (item.value) { + case 1: + this.api.asc_ViewCertificate(item.cmpEl.attr('data-value')); + break; + case 3: + this.api.asc_RemoveSignature(guid); + break; + } + }, + + onDocumentReady: function() { + this._state.ready = true; + + this.updateSignatures(this.api.asc_getSignatures(), this.api.asc_getRequestSignatures()); + this.showSignatureTooltip(this._state.hasValid, this._state.hasInvalid); + }, + + showSignatureTooltip: function(hasValid, hasInvalid) { + var me = this, + tip = me._state.tip; + + if (!hasValid && !hasInvalid) { + if (tip && tip.isVisible()) { + tip.close(); + me._state.tip = undefined; + } + return; + } + + var showLink = hasValid || hasInvalid, + tipText = (hasInvalid) ? me.txtSignedInvalid : (hasValid ? me.txtSigned : ""); + + if (tip && tip.isVisible() && (tipText !== tip.text || showLink !== tip.showLink)) { + tip.close(); + me._state.tip = undefined; + } + + if (!me._state.tip) { + tip = new Common.UI.SynchronizeTip({ + target : PE.getController('RightMenu').getView('RightMenu').btnSignature.btnEl, + text : tipText, + showLink: showLink, + textLink: this.txtContinueEditing, + placement: 'left' + }); + tip.on({ + 'dontshowclick': function() { + Common.UI.warning({ + title: me.notcriticalErrorTitle, + msg: me.txtEditWarning, + buttons: ['ok', 'cancel'], + primary: 'ok', + callback: function(btn) { + if (btn == 'ok') { + tip.close(); + me._state.tip = undefined; + me.api.asc_RemoveAllSignatures(); + } + } + }); + }, + 'closeclick': function() { + tip.close(); + me._state.tip = undefined; + } + }); + me._state.tip = tip; + tip.show(); + } + }, + + disableEditing: function(disable) { + if (this._state.DisabledEditing != disable) { + this._state.DisabledEditing = disable; + + var rightMenuController = PE.getController('RightMenu'); + if (disable && rightMenuController.rightmenu.GetActivePane() !== 'id-signature-settings') + rightMenuController.rightmenu.clearSelection(); + rightMenuController.SetDisabled(disable, true); + PE.getController('Toolbar').DisableToolbar(disable, disable); + PE.getController('Statusbar').getView('Statusbar').SetDisabled(disable); + PE.getController('Common.Controllers.ReviewChanges').SetDisabled(disable); + PE.getController('DocumentHolder').getView('DocumentHolder').SetDisabled(disable); + + var leftMenu = PE.getController('LeftMenu').leftMenu; + leftMenu.btnComments.setDisabled(disable); + var comments = PE.getController('Common.Controllers.Comments'); + if (comments) + comments.setPreviewMode(disable); + } + }, + + strSignature: 'Signature', + strValid: 'Valid signatures', + strInvalid: 'Invalid signatures', + strDetails: 'Signature Details', + txtSigned: 'Valid signatures has been added to the presentation. The presentation is protected from editing.', + txtSignedInvalid: 'Some of the digital signatures in presentation are invalid or could not be verified. The presentation is protected from editing.', + txtContinueEditing: 'Edit anyway', + notcriticalErrorTitle: 'Warning', + txtEditWarning: 'Editing will remove the signatures from the presentation.
    Are you sure you want to continue?', + strDelete: 'Remove Signature' + + }, PE.Views.SignatureSettings || {})); +}); \ No newline at end of file diff --git a/apps/presentationeditor/main/app/view/SlideSettings.js b/apps/presentationeditor/main/app/view/SlideSettings.js index a691fa1d4..a72138855 100644 --- a/apps/presentationeditor/main/app/view/SlideSettings.js +++ b/apps/presentationeditor/main/app/view/SlideSettings.js @@ -655,7 +655,7 @@ define([ el: $('#slide-button-from-file') }); this.btnInsertFromFile.on('click', _.bind(function(btn){ - if (this.api) this.api.ChangeSlideImageFromFile(); + if (this.api) this.api.ChangeSlideImageFromFile(this.BlipFillType); this.fireEvent('editcomplete', this); }, this)); this.FillItems.push(this.btnInsertFromFile); diff --git a/apps/presentationeditor/main/app/view/SlideSizeSettings.js b/apps/presentationeditor/main/app/view/SlideSizeSettings.js index 77ec2b563..74ad4ef1c 100644 --- a/apps/presentationeditor/main/app/view/SlideSizeSettings.js +++ b/apps/presentationeditor/main/app/view/SlideSizeSettings.js @@ -224,6 +224,11 @@ define([ } }, + onPrimary: function() { + this._handleInput('ok'); + return false; + }, + setSettings: function (type, pagewitdh, pageheight) { this.spnWidth.setValue(Common.Utils.Metric.fnRecalcFromMM(pagewitdh), true); this.spnHeight.setValue(Common.Utils.Metric.fnRecalcFromMM(pageheight), true); diff --git a/apps/presentationeditor/main/app/view/SlideshowSettings.js b/apps/presentationeditor/main/app/view/SlideshowSettings.js index 41bc3ef22..d2827f2f4 100644 --- a/apps/presentationeditor/main/app/view/SlideshowSettings.js +++ b/apps/presentationeditor/main/app/view/SlideshowSettings.js @@ -107,6 +107,11 @@ define([ } }, + onPrimary: function() { + this._handleInput('ok'); + return false; + }, + setSettings: function (loop) { this.chLoop.setValue(loop); }, diff --git a/apps/presentationeditor/main/app/view/Statusbar.js b/apps/presentationeditor/main/app/view/Statusbar.js index e4eb65355..375d97ebf 100644 --- a/apps/presentationeditor/main/app/view/Statusbar.js +++ b/apps/presentationeditor/main/app/view/Statusbar.js @@ -361,7 +361,10 @@ define([ $parent.find('#status-label-lang').text(info.title); var index = $parent.find('ul li a:contains("'+info.title+'")').parent().index(); - index < 0 ? this.langMenu.saved = info.title : + if (index < 0) { + this.langMenu.saved = info.title; + this.langMenu.clearAll(); + } else this.langMenu.items[index-1].setChecked(true); } }, @@ -370,6 +373,7 @@ define([ var langs = this.langMenu.items.length>0; this.btnLanguage.setDisabled(disable || !langs || this._state.no_paragraph); this.btnDocLanguage.setDisabled(disable || !langs); + this.mode.isEdit = !disable; }, onApiFocusObject: function(selectedObjects) { diff --git a/apps/presentationeditor/main/app/view/TableSettings.js b/apps/presentationeditor/main/app/view/TableSettings.js index bf751e82a..815b66760 100644 --- a/apps/presentationeditor/main/app/view/TableSettings.js +++ b/apps/presentationeditor/main/app/view/TableSettings.js @@ -209,8 +209,8 @@ define([ if (me.api) { me.api.SplitCell(value.columns, value.rows); } - me.fireEvent('editcomplete', me); } + me.fireEvent('editcomplete', me); } })).show(); }, diff --git a/apps/presentationeditor/main/app/view/TextArtSettings.js b/apps/presentationeditor/main/app/view/TextArtSettings.js index 42b739c68..a568842db 100644 --- a/apps/presentationeditor/main/app/view/TextArtSettings.js +++ b/apps/presentationeditor/main/app/view/TextArtSettings.js @@ -871,7 +871,8 @@ define([ // border colors var stroke = shapeprops.asc_getLine(), strokeType = (stroke) ? stroke.get_type() : null, - borderType; + borderType, + update = (this._state.StrokeColor == 'transparent' && this.BorderColor.Color !== 'transparent'); // border color was changed for shape without line and then shape was reselected (or apply other settings) if (stroke) { if ( strokeType == Asc.c_oAscStrokeType.STROKE_COLOR ) { @@ -896,7 +897,7 @@ define([ type1 = typeof(this.BorderColor.Color); type2 = typeof(this._state.StrokeColor); - if ( (type1 !== type2) || (type1=='object' && + if ( update || (type1 !== type2) || (type1=='object' && (this.BorderColor.Color.effectValue!==this._state.StrokeColor.effectValue || this._state.StrokeColor.color.indexOf(this.BorderColor.Color.color)<0)) || (type1!='object' && (this._state.StrokeColor.indexOf(this.BorderColor.Color)<0 || typeof(this.btnBorderColor.color)=='object'))) { @@ -1104,7 +1105,7 @@ define([ this.lockedControls.push(this.btnInsertFromUrl); this.btnInsertFromFile.on('click', _.bind(function(btn){ - if (this.api) this.api.ChangeArtImageFromFile(); + if (this.api) this.api.ChangeArtImageFromFile(this.BlipFillType); this.fireEvent('editcomplete', this); }, this)); this.btnInsertFromUrl.on('click', _.bind(this.insertFromUrl, this)); diff --git a/apps/presentationeditor/main/app/view/Toolbar.js b/apps/presentationeditor/main/app/view/Toolbar.js index e376a6345..b4261aab4 100644 --- a/apps/presentationeditor/main/app/view/Toolbar.js +++ b/apps/presentationeditor/main/app/view/Toolbar.js @@ -166,17 +166,6 @@ define([ */ var _set = PE.enumLock; - me.btnAddSlide = new Common.UI.Button({ - id : 'id-toolbar-button-add-slide', - cls : 'btn-toolbar x-huge icon-top', - iconCls : 'btn-addslide', - split : true, - caption : me.capAddSlide, - lock : [_set.menuFileOpen, _set.slideDeleted, _set.lostConnect, _set.disableOnStart], - menu : true - }); - me.slideOnlyControls.push(me.btnAddSlide); - me.btnChangeSlide = new Common.UI.Button({ id : 'id-toolbar-button-change-slide', cls : 'btn-toolbar', @@ -610,8 +599,8 @@ define([ lock : [_set.themeLock, _set.slideDeleted, _set.lostConnect, _set.noSlides, _set.disableOnStart], menu : new Common.UI.Menu({ items : [], - maxHeight : 600, - restoreHeight: 600 + maxHeight : 560, + restoreHeight: 560 }).on('show:before', function(mnu) { this.scroller = new Common.UI.Scroller({ el: $(this.el).find('.dropdown-menu '), @@ -619,24 +608,7 @@ define([ minScrollbarLength : 40, alwaysVisibleY: true }); - }).on('show:after', function(btn, e) { - var mnu = $(this.el).find('.dropdown-menu '), - docH = Common.Utils.innerHeight(), - menuH = mnu.outerHeight(), - top = parseInt(mnu.css('top')); - - if (menuH > docH) { - mnu.css('max-height', (docH - parseInt(mnu.css('padding-top')) - parseInt(mnu.css('padding-bottom'))-5) + 'px'); - this.scroller.update({minScrollbarLength : 40}); - } else if ( mnu.height() < this.options.restoreHeight ) { - mnu.css('max-height', (Math.min(docH - parseInt(mnu.css('padding-top')) - parseInt(mnu.css('padding-bottom'))-5, this.options.restoreHeight)) + 'px'); - menuH = mnu.outerHeight(); - if (top+menuH > docH) { - mnu.css('top', 0); - } - this.scroller.update({minScrollbarLength : 40}); - } - }) + }) }); me.slideOnlyControls.push(me.btnColorSchemas); @@ -766,7 +738,7 @@ define([ id : 'id-toolbar-btn-slide-size', cls : 'btn-toolbar', iconCls : 'btn-slidesize', - lock : [_set.docPropsLock, _set.slideDeleted, _set.lostConnect, _set.noSlides, _set.disableOnStart], + lock : [_set.docPropsLock, _set.slideDeleted, _set.lostConnect, _set.disableOnStart], menu : new Common.UI.Menu({ items: [ { @@ -846,7 +818,7 @@ define([ '
    ' ].join('')); - this.lockControls = [ this.btnAddSlide, this.btnChangeSlide, this.btnSave, + this.lockControls = [ this.btnChangeSlide, this.btnSave, this.btnCopy, this.btnPaste, this.btnUndo, this.btnRedo, this.cmbFontName, this.cmbFontSize, this.btnBold, this.btnItalic, this.btnUnderline, this.btnStrikeout, this.btnSuperscript, this.btnSubscript, this.btnFontColor, this.btnClearStyle, this.btnCopyStyle, this.btnMarkers, @@ -932,16 +904,6 @@ define([ this.fireEvent('render:after', [this]); Common.UI.Mixtbar.prototype.afterRender.call(this); - me.$tabs.parent().on('click', '.ribtab', function (e) { - var tab = $(e.target).data('tab'); - if (tab == 'file') { - me.fireEvent('file:open'); - } else - if ( me.isTabActive('file') ) - me.fireEvent('file:close'); - - me.setTab(tab); - }); Common.NotificationCenter.on({ 'window:resize': function() { @@ -956,6 +918,21 @@ define([ return this; }, + onTabClick: function (e) { + var tab = $(e.target).data('tab'), + me = this; + + if ( !me.isTabActive(tab) ) { + if ( tab == 'file' ) { + me.fireEvent('file:open'); + } else + if ( me.isTabActive('file') ) + me.fireEvent('file:close'); + } + + Common.UI.Mixtbar.prototype.onTabClick.apply(this, arguments); + }, + rendererComponents: function (html) { var $host = $(html); var _injectComponent = function (id, cmp) { @@ -968,7 +945,6 @@ define([ _injectComponent('#slot-field-fontname', this.cmbFontName); _injectComponent('#slot-field-fontsize', this.cmbFontSize); - _injectComponent('#slot-btn-addslide', this.btnAddSlide); _injectComponent('#slot-btn-changeslide', this.btnChangeSlide); _injectComponent('#slot-btn-preview', this.btnPreview); _injectComponent('#slot-btn-print', this.btnPrint); @@ -1060,7 +1036,20 @@ define([ } }); - var created = me.btnsInsertImage.concat(me.btnsInsertText, me.btnsInsertShape); + me.btnsAddSlide = _injectBtns({ + slot: '.slot-addslide', + btnconfig: { + id : 'tlbtn-addslide-', + cls : 'btn-toolbar x-huge icon-top', + iconCls : 'btn-addslide', + split : true, + caption : me.capAddSlide, + lock : [PE.enumLock.menuFileOpen, PE.enumLock.slideDeleted, PE.enumLock.lostConnect, PE.enumLock.disableOnStart], + menu : true + } + }); + + var created = me.btnsInsertImage.concat(me.btnsInsertText, me.btnsInsertShape, me.btnsAddSlide); this.lockToolbar(PE.enumLock.disableOnStart, true, {array: created}); Array.prototype.push.apply(me.slideOnlyControls, created); @@ -1104,11 +1093,24 @@ define([ }) ); }); + + me.btnsAddSlide.forEach(function (btn, index) { + btn.updateHint(me.tipAddSlide + Common.Utils.String.platformKey('Ctrl+M')); + btn.setMenu( + new Common.UI.Menu({ + items: [ + {template: _.template('')} + ] + }) + ); + btn.on('click', function (btn, e) { + me.fireEvent('add:slide'); + }); + }); }, createDelayedElements: function () { // set hints - this.btnAddSlide.updateHint(this.tipAddSlide + Common.Utils.String.platformKey('Ctrl+M')); this.btnChangeSlide.updateHint(this.tipChangeSlide); this.btnPreview.updateHint(this.tipPreview); this.btnPrint.updateHint(this.tipPrint + Common.Utils.String.platformKey('Ctrl+P')); @@ -1225,14 +1227,6 @@ define([ }) ); - this.btnAddSlide.setMenu( - new Common.UI.Menu({ - items: [ - {template: _.template('')} - ] - }) - ); - this.btnChangeSlide.setMenu( new Common.UI.Menu({ items: [ @@ -1340,29 +1334,6 @@ define([ maxColumns: 10 }); - this.mnuAddSlidePicker = new Common.UI.DataView({ - el: $('#id-toolbar-menu-addslide'), - parentMenu: this.btnAddSlide.menu, - showLast: false, - restoreHeight: 300, - style: 'max-height: 300px;', - store: PE.getCollection('SlideLayouts'), - itemTemplate: _.template([ - '
    ', - '
    ', - '
    <%= title %>
    ', - '
    ' - ].join('')) - }); - if (this.btnAddSlide.menu) { - this.btnAddSlide.menu.on('show:after', function () { - me.onSlidePickerShowAfter(me.mnuAddSlidePicker); - me.mnuAddSlidePicker.scroller.update({alwaysVisibleY: true}); - me.mnuAddSlidePicker.scroller.scrollTop(0); - }); - } - this.mnuAddSlidePicker._needRecalcSlideLayout = true; - var createDataPicker = function (btn) { me.mnuChangeSlidePicker = new Common.UI.DataView({ el: $('#id-toolbar-menu-changeslide'), @@ -1394,7 +1365,6 @@ define([ this.btnChangeSlide.on('render:after', createDataPicker); this.listenTo(PE.getCollection('SlideLayouts'), 'reset', function () { - me.mnuAddSlidePicker._needRecalcSlideLayout = true; if (me.mnuChangeSlidePicker) me.mnuChangeSlidePicker._needRecalcSlideLayout = true; }); @@ -1484,8 +1454,8 @@ define([ if (mnuColorSchema == null) { mnuColorSchema = new Common.UI.Menu({ - maxHeight: 600, - restoreHeight: 600 + maxHeight: 560, + restoreHeight: 560 }).on('render:after', function (mnu) { this.scroller = new Common.UI.Scroller({ el: $(this.el).find('.dropdown-menu '), @@ -1722,6 +1692,43 @@ define([ } }, + updateAddSlideMenu: function(collection) { + if (collection.size()<1) return; + + var me = this; + me.btnsAddSlide.forEach(function (btn, index) { + if ( !btn.mnuAddSlidePicker ) { + btn.mnuAddSlidePicker = new Common.UI.DataView({ + el: $('#id-toolbar-menu-addslide-' + index), + parentMenu: btn.menu, + showLast: false, + restoreHeight: 300, + style: 'max-height: 300px;', + store: PE.getCollection('SlideLayouts'), + itemTemplate: _.template([ + '
    ', + '
    ', + '
    <%= title %>
    ', + '
    ' + ].join('')) + }); + btn.mnuAddSlidePicker.on('item:click', function (picker, item, record, e) { + if (e.type !== 'click') Common.UI.Menu.Manager.hideAll(); + if (record) + me.fireEvent('add:slide', [record.get('data').idx]); + }); + if (btn.menu) { + btn.menu.on('show:after', function () { + me.onSlidePickerShowAfter(btn.mnuAddSlidePicker); + btn.mnuAddSlidePicker.scroller.update({alwaysVisibleY: true}); + btn.mnuAddSlidePicker.scroller.scrollTop(0); + }); + } + } + btn.mnuAddSlidePicker._needRecalcSlideLayout = true; + }); + }, + textBold: 'Bold', textItalic: 'Italic', textUnderline: 'Underline', @@ -1855,7 +1862,9 @@ define([ textTabHome: 'Home', textTabInsert: 'Insert', textSurface: 'Surface', - textShowPresenterView: 'Show presenter view' + textShowPresenterView: 'Show presenter view', + textTabCollaboration: 'Collaboration', + textTabProtect: 'Protection' } }()), PE.Views.Toolbar || {})); }); \ No newline at end of file diff --git a/apps/presentationeditor/main/app/view/Viewport.js b/apps/presentationeditor/main/app/view/Viewport.js index e7da2ea5f..e1be9b2d2 100644 --- a/apps/presentationeditor/main/app/view/Viewport.js +++ b/apps/presentationeditor/main/app/view/Viewport.js @@ -123,7 +123,7 @@ define([ }, applyEditorMode: function() { - PE.getController('RightMenu').getView('RightMenu').render(); + PE.getController('RightMenu').getView('RightMenu').render(this.mode); if ( Common.localStorage.getBool('pe-hidden-status') ) PE.getController('Statusbar').getView('Statusbar').setVisible(false); diff --git a/apps/presentationeditor/main/app_dev.js b/apps/presentationeditor/main/app_dev.js index af1cdf9fa..d23302912 100644 --- a/apps/presentationeditor/main/app_dev.js +++ b/apps/presentationeditor/main/app_dev.js @@ -146,6 +146,8 @@ require([ /** coauthoring end **/ ,'Common.Controllers.Plugins' ,'Common.Controllers.ExternalDiagramEditor' + ,'Common.Controllers.ReviewChanges' + ,'Common.Controllers.Protection' ] }); @@ -166,6 +168,7 @@ require([ 'presentationeditor/main/app/view/SlideSettings', 'presentationeditor/main/app/view/TableSettings', 'presentationeditor/main/app/view/TextArtSettings', + 'presentationeditor/main/app/view/SignatureSettings', 'common/main/lib/util/utils', 'common/main/lib/util/LocalStorage', 'common/main/lib/controller/Fonts' @@ -176,6 +179,8 @@ require([ 'common/main/lib/controller/Plugins', 'presentationeditor/main/app/view/ChartSettings', 'common/main/lib/controller/ExternalDiagramEditor' + ,'common/main/lib/controller/ReviewChanges' + ,'common/main/lib/controller/Protection' ], function() { window.compareVersions = true; app.start(); diff --git a/apps/presentationeditor/main/locale/en.json b/apps/presentationeditor/main/locale/en.json index 7e0fd0111..84941f148 100644 --- a/apps/presentationeditor/main/locale/en.json +++ b/apps/presentationeditor/main/locale/en.json @@ -116,16 +116,98 @@ "Common.Views.OpenDialog.txtPassword": "Password", "Common.Views.OpenDialog.txtTitle": "Choose %1 options", "Common.Views.OpenDialog.txtTitleProtected": "Protected File", + "Common.Views.PasswordDialog.cancelButtonText": "Cancel", + "Common.Views.PasswordDialog.okButtonText": "OK", + "Common.Views.PasswordDialog.txtPassword": "Password", + "Common.Views.PasswordDialog.txtTitle": "Set Password", + "Common.Views.PasswordDialog.txtDescription": "A Password is required to open this document", + "Common.Views.PasswordDialog.txtRepeat": "Repeat password", + "Common.Views.PasswordDialog.txtIncorrectPwd": "Confirmation password is not identical", "Common.Views.PluginDlg.textLoading": "Loading", "Common.Views.Plugins.groupCaption": "Plugins", "Common.Views.Plugins.strPlugins": "Plugins", "Common.Views.Plugins.textLoading": "Loading", "Common.Views.Plugins.textStart": "Start", "Common.Views.Plugins.textStop": "Stop", + "Common.Views.Protection.txtAddPwd": "Add password", + "Common.Views.Protection.txtEncrypt": "Encrypt", + "Common.Views.Protection.txtSignature": "Signature", + "Common.Views.Protection.hintAddPwd": "Encrypt with password", + "Common.Views.Protection.hintPwd": "Change or delete password", + "Common.Views.Protection.hintSignature": "Add digital signature or signature line", + "Common.Views.Protection.txtChangePwd": "Change password", + "Common.Views.Protection.txtDeletePwd": "Delete password", + "Common.Views.Protection.txtInvisibleSignature": "Add digital signature", + "Common.Views.Protection.txtSignatureLine": "Signature line", "Common.Views.RenameDialog.cancelButtonText": "Cancel", "Common.Views.RenameDialog.okButtonText": "Ok", "Common.Views.RenameDialog.textName": "File name", "Common.Views.RenameDialog.txtInvalidName": "The file name cannot contain any of the following characters: ", + "Common.Views.ReviewChanges.hintNext": "To next change", + "Common.Views.ReviewChanges.hintPrev": "To previous change", + "Common.Views.ReviewChanges.tipAcceptCurrent": "Accept current change", + "Common.Views.ReviewChanges.tipRejectCurrent": "Reject current change", + "Common.Views.ReviewChanges.tipReview": "Track changes", + "Common.Views.ReviewChanges.tipReviewView": "Select the mode you want the changes to be displayed", + "Common.Views.ReviewChanges.tipSetDocLang": "Set document language", + "Common.Views.ReviewChanges.tipSetSpelling": "Spell checking", + "Common.Views.ReviewChanges.txtAccept": "Accept", + "Common.Views.ReviewChanges.txtAcceptAll": "Accept All Changes", + "Common.Views.ReviewChanges.txtAcceptChanges": "Accept changes", + "Common.Views.ReviewChanges.txtAcceptCurrent": "Accept Current Change", + "Common.Views.ReviewChanges.txtClose": "Close", + "Common.Views.ReviewChanges.txtDocLang": "Language", + "Common.Views.ReviewChanges.txtFinal": "All changes like accept (Preview)", + "Common.Views.ReviewChanges.txtMarkup": "Text with changes (Editing)", + "Common.Views.ReviewChanges.txtNext": "Next", + "Common.Views.ReviewChanges.txtOriginal": "Text without changes (Preview)", + "Common.Views.ReviewChanges.txtMarkupCap": "Markup", + "Common.Views.ReviewChanges.txtFinalCap": "Final", + "Common.Views.ReviewChanges.txtOriginalCap": "Original", + "Common.Views.ReviewChanges.txtPrev": "Previous", + "Common.Views.ReviewChanges.txtReject": "Reject", + "Common.Views.ReviewChanges.txtRejectAll": "Reject All Changes", + "Common.Views.ReviewChanges.txtRejectChanges": "Reject changes", + "Common.Views.ReviewChanges.txtRejectCurrent": "Reject Current Change", + "Common.Views.ReviewChanges.txtSpelling": "Spell Checking", + "Common.Views.ReviewChanges.txtTurnon": "Track Changes", + "Common.Views.ReviewChanges.txtView": "Display Mode", + "Common.Views.ReviewChanges.txtSharing": "Sharing", + "Common.Views.ReviewChanges.tipSharing": "Manage document access rights", + "Common.Views.ReviewChanges.txtCoAuthMode": "Co-editing Mode", + "Common.Views.ReviewChanges.tipCoAuthMode": "Set co-editing mode", + "Common.Views.ReviewChanges.strFast": "Fast", + "Common.Views.ReviewChanges.strStrict": "Strict", + "Common.Views.ReviewChanges.strFastDesc": "Real-time co-editing. All changes are saved automatically.", + "Common.Views.ReviewChanges.strStrictDesc": "Use the 'Save' button to sync the changes you and others make.", + "Common.Views.ReviewChanges.txtHistory": "Version History", + "Common.Views.ReviewChanges.tipHistory": "Show version history", + "Common.Views.SignDialog.textTitle": "Sign Document", + "Common.Views.SignDialog.textPurpose": "Purpose for signing this document", + "Common.Views.SignDialog.textCertificate": "Certificate", + "Common.Views.SignDialog.textValid": "Valid from %1 to %2", + "Common.Views.SignDialog.textChange": "Change", + "Common.Views.SignDialog.cancelButtonText": "Cancel", + "Common.Views.SignDialog.okButtonText": "Ok", + "Common.Views.SignDialog.textInputName": "Input signer name", + "Common.Views.SignDialog.textUseImage": "or click 'Select Image' to use a picture as signature", + "Common.Views.SignDialog.textSelectImage": "Select Image", + "Common.Views.SignDialog.textSignature": "Signature looks as", + "Common.Views.SignDialog.tipFontName": "Font Name", + "Common.Views.SignDialog.tipFontSize": "Font Size", + "Common.Views.SignDialog.textBold": "Bold", + "Common.Views.SignDialog.textItalic": "Italic", + "Common.Views.SignSettingsDialog.textInfo": "Signer Info", + "Common.Views.SignSettingsDialog.textInfoName": "Name", + "Common.Views.SignSettingsDialog.textInfoTitle": "Signer Title", + "Common.Views.SignSettingsDialog.textInfoEmail": "E-mail", + "Common.Views.SignSettingsDialog.textInstructions": "Instructions for Signer", + "Common.Views.SignSettingsDialog.cancelButtonText": "Cancel", + "Common.Views.SignSettingsDialog.okButtonText": "Ok", + "Common.Views.SignSettingsDialog.txtEmpty": "This field is required", + "Common.Views.SignSettingsDialog.textAllowComment": "Allow signer to add comment in the signature dialog", + "Common.Views.SignSettingsDialog.textShowDate": "Show sign date in signature line", + "Common.Views.SignSettingsDialog.textTitle": "Signature Settings", "PE.Controllers.LeftMenu.newDocumentTitle": "Unnamed presentation", "PE.Controllers.LeftMenu.requestEditRightsText": "Requesting editing rights...", "PE.Controllers.LeftMenu.textNoTextFound": "The data you have been searching for could not be found. Please adjust your search options.", @@ -202,6 +284,7 @@ "PE.Controllers.Main.textTryUndoRedo": "The Undo/Redo functions are disabled for the Fast co-editing mode.
    Click the 'Strict mode' button to switch to the Strict co-editing mode to edit the file without other users interference and send your changes only after you save them. You can switch between the co-editing modes using the editor Advanced settings.", "PE.Controllers.Main.titleLicenseExp": "License expired", "PE.Controllers.Main.titleServerVersion": "Editor updated", + "PE.Controllers.Main.txtAddNotes": "Click to add notes", "PE.Controllers.Main.txtArt": "Your text here", "PE.Controllers.Main.txtBasicShapes": "Basic Shapes", "PE.Controllers.Main.txtButtons": "Buttons", @@ -789,6 +872,10 @@ "PE.Views.DocumentHolder.txtUnderbar": "Bar under text", "PE.Views.DocumentHolder.txtUngroup": "Ungroup", "PE.Views.DocumentHolder.vertAlignText": "Vertical Alignment", + "PE.Views.DocumentHolder.txtKeepTextOnly": "Keep text only", + "PE.Views.DocumentHolder.txtPastePicture": "Picture", + "PE.Views.DocumentHolder.txtPasteSourceFormat": "Keep source formatting", + "PE.Views.DocumentHolder.txtPasteDestFormat": "Use destination theme", "PE.Views.DocumentPreview.goToSlideText": "Go to Slide", "PE.Views.DocumentPreview.slideIndexText": "Slide {0} of {1}", "PE.Views.DocumentPreview.txtClose": "Close slideshow", @@ -818,6 +905,7 @@ "PE.Views.FileMenu.btnSaveCaption": "Save", "PE.Views.FileMenu.btnSettingsCaption": "Advanced Settings...", "PE.Views.FileMenu.btnToEditCaption": "Edit Presentation", + "PE.Views.FileMenu.btnProtectCaption": "Protect\\Sign", "PE.Views.FileMenuPanels.CreateNew.fromBlankText": "From Blank", "PE.Views.FileMenuPanels.CreateNew.fromTemplateText": "From Template", "PE.Views.FileMenuPanels.CreateNew.newDescriptionText": "Create a new blank presentation which you will be able to style and format after it is created during the editing. Or choose one of the templates to start a presentation of a certain type or purpose where some styles have already been pre-applied.", @@ -831,6 +919,16 @@ "PE.Views.FileMenuPanels.DocumentInfo.txtTitle": "Presentation Title", "PE.Views.FileMenuPanels.DocumentRights.txtBtnAccessRights": "Change access rights", "PE.Views.FileMenuPanels.DocumentRights.txtRights": "Persons who have rights", + "PE.Views.FileMenuPanels.ProtectDoc.strProtect": "Protect Presentation", + "PE.Views.FileMenuPanels.ProtectDoc.strSignature": "Signature", + "PE.Views.FileMenuPanels.ProtectDoc.txtView": "View signatures", + "PE.Views.FileMenuPanels.ProtectDoc.txtEdit": "Edit presentation", + "PE.Views.FileMenuPanels.ProtectDoc.txtSigned": "Valid signatures has been added to the presentation. The presentation is protected from editing.", + "PE.Views.FileMenuPanels.ProtectDoc.txtSignedInvalid": "Some of the digital signatures in presentation are invalid or could not be verified. The presentation is protected from editing.", + "PE.Views.FileMenuPanels.ProtectDoc.notcriticalErrorTitle": "Warning", + "PE.Views.FileMenuPanels.ProtectDoc.txtEditWarning": "Editing will remove the signatures from the presentation.
    Are you sure you want to continue?", + "PE.Views.FileMenuPanels.ProtectDoc.strEncrypt": "Password", + "PE.Views.FileMenuPanels.ProtectDoc.txtEncrypted": "This presentation has been protected by password", "PE.Views.FileMenuPanels.Settings.okButtonText": "Apply", "PE.Views.FileMenuPanels.Settings.strAlignGuides": "Turn on alignment guides", "PE.Views.FileMenuPanels.Settings.strAutoRecover": "Turn on autorecover", @@ -965,6 +1063,7 @@ "PE.Views.RightMenu.txtSlideSettings": "Slide settings", "PE.Views.RightMenu.txtTableSettings": "Table settings", "PE.Views.RightMenu.txtTextArtSettings": "Text Art settings", + "PE.Views.RightMenu.txtSignatureSettings": "Signature Settings", "PE.Views.ShapeSettings.strBackground": "Background color", "PE.Views.ShapeSettings.strChange": "Change Autoshape", "PE.Views.ShapeSettings.strColor": "Color", @@ -1041,6 +1140,17 @@ "PE.Views.ShapeSettingsAdvanced.textWeightArrows": "Weights & Arrows", "PE.Views.ShapeSettingsAdvanced.textWidth": "Width", "PE.Views.ShapeSettingsAdvanced.txtNone": "None", + "PE.Views.SignatureSettings.strSignature": "Signature", + "PE.Views.SignatureSettings.strValid": "Valid signatures", + "PE.Views.SignatureSettings.strInvalid": "Invalid signatures", + "PE.Views.SignatureSettings.strSign": "Sign", + "PE.Views.SignatureSettings.strDetails": "Signature Details", + "PE.Views.SignatureSettings.strDelete": "Remove Signature", + "PE.Views.SignatureSettings.txtSigned": "Valid signatures has been added to the presentation. The presentation is protected from editing.", + "PE.Views.SignatureSettings.txtSignedInvalid": "Some of the digital signatures in presentation are invalid or could not be verified. The presentation is protected from editing.", + "PE.Views.SignatureSettings.txtContinueEditing": "Edit anyway", + "PE.Views.SignatureSettings.notcriticalErrorTitle": "Warning", + "PE.Views.SignatureSettings.txtEditWarning": "Editing will remove the signatures from the presentation.
    Are you sure you want to continue?", "PE.Views.SlideSettings.strBackground": "Background color", "PE.Views.SlideSettings.strColor": "Color", "PE.Views.SlideSettings.strDelay": "Delay", @@ -1315,6 +1425,8 @@ "PE.Views.Toolbar.textTabFile": "File", "PE.Views.Toolbar.textTabHome": "Home", "PE.Views.Toolbar.textTabInsert": "Insert", + "PE.Views.Toolbar.textTabCollaboration": "Collaboration", + "PE.Views.Toolbar.textTabProtect": "Protection", "PE.Views.Toolbar.textTitleError": "Error", "PE.Views.Toolbar.textUnderline": "Underline", "PE.Views.Toolbar.textZoom": "Zoom", diff --git a/apps/presentationeditor/main/resources/img/toolbar-menu.png b/apps/presentationeditor/main/resources/img/toolbar-menu.png index 2c5504c88..13271481d 100644 Binary files a/apps/presentationeditor/main/resources/img/toolbar-menu.png and b/apps/presentationeditor/main/resources/img/toolbar-menu.png differ diff --git a/apps/presentationeditor/main/resources/img/toolbar-menu@2x.png b/apps/presentationeditor/main/resources/img/toolbar-menu@2x.png index b379daadb..b6a317b03 100644 Binary files a/apps/presentationeditor/main/resources/img/toolbar-menu@2x.png and b/apps/presentationeditor/main/resources/img/toolbar-menu@2x.png differ diff --git a/apps/presentationeditor/main/resources/less/leftmenu.less b/apps/presentationeditor/main/resources/less/leftmenu.less index d12639436..a269387b9 100644 --- a/apps/presentationeditor/main/resources/less/leftmenu.less +++ b/apps/presentationeditor/main/resources/less/leftmenu.less @@ -221,7 +221,8 @@ width: 30%; label { - font: bold 12px tahoma, arial, verdana, sans-serif; + font-weight: bold; + font-size: 12px; } } @@ -448,7 +449,26 @@ } label, span { - font: 12px tahoma, arial, verdana, sans-serif; + font-size: 12px; + } + } + + #panel-protect { + label, span { + font-size: 12px; + } + + padding: 30px 30px; + + .header { + font-weight: bold; + margin: 30px 0 10px; + } + + table { + td { + padding: 5px 0; + } } } } diff --git a/apps/presentationeditor/main/resources/less/rightmenu.less b/apps/presentationeditor/main/resources/less/rightmenu.less index c2955f812..e80606dc1 100644 --- a/apps/presentationeditor/main/resources/less/rightmenu.less +++ b/apps/presentationeditor/main/resources/less/rightmenu.less @@ -26,6 +26,9 @@ /*menuTextArt*/ .toolbar-btn-icon(btn-menu-textart, 57, @toolbar-icon-size); + + /**menuSignature*/ + .toolbar-btn-icon(btn-menu-signature, 77, @toolbar-icon-size); } } @@ -201,4 +204,56 @@ button:active:not(.disabled) .btn-change-shape {background-position: -56px - .gradient-radial-center { background-position: -100px -150px; +} + +#signature-requested-sign, +#signature-valid-sign, +#signature-invalid-sign { + height: 100%; + overflow: hidden; + margin: 0 -10px 0 -15px; + + .item { + display: block; + border: none; + width: 100%; + .box-shadow(none); + margin: 0; + + &:hover, + &.over { + background-color: @secondary; + } + } + + .signature-item { + padding: 5px 2px 5px 15px; + text-overflow: ellipsis; + min-height: 25px; + + .name { + width: 100%; + white-space: nowrap; + overflow: hidden; + cursor: pointer; + max-width: 160px; + text-overflow: ellipsis; + } + + .caret { + width: 23px; + height: 14px; + border: 0; + background-position: -43px -150px; + margin: 8px 15px; + display: inline-block; + position: absolute; + right: 0; + + &.nomargin { + margin-top: 0; + margin-bottom: 0; + } + } + } } \ No newline at end of file diff --git a/apps/presentationeditor/main/resources/less/toolbar.less b/apps/presentationeditor/main/resources/less/toolbar.less index f84d2dc27..d0fdeb364 100644 --- a/apps/presentationeditor/main/resources/less/toolbar.less +++ b/apps/presentationeditor/main/resources/less/toolbar.less @@ -2,7 +2,7 @@ .toolbar { &:not(.cover) { - z-index: 101; + z-index: 1001; } &.masked { @@ -352,4 +352,11 @@ .separator:first-child { display: inline-block; } +} + +#special-paste-container { + position: absolute; + z-index: @zindex-dropdown - 20; + background-color: @gray-light; + border: 1px solid @gray; } \ No newline at end of file diff --git a/apps/presentationeditor/mobile/app/controller/Main.js b/apps/presentationeditor/mobile/app/controller/Main.js index af79c3c0b..69d23b5c1 100644 --- a/apps/presentationeditor/mobile/app/controller/Main.js +++ b/apps/presentationeditor/mobile/app/controller/Main.js @@ -821,6 +821,8 @@ define([ } } } else { + Common.Gateway.reportWarning(id, config.msg); + config.title = this.notcriticalErrorTitle; config.callback = _.bind(function(btn){ if (id == Asc.c_oAscError.ID.Warning && btn == 'ok' && (this.appOptions.canDownload || this.appOptions.canDownloadOrigin)) { diff --git a/apps/presentationeditor/sdk_dev_scripts.js b/apps/presentationeditor/sdk_dev_scripts.js index e1f833587..2fb140848 100644 --- a/apps/presentationeditor/sdk_dev_scripts.js +++ b/apps/presentationeditor/sdk_dev_scripts.js @@ -121,6 +121,8 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/word/Editor/Paragraph/ParaTextPrChanges.js", "../../../../sdkjs/word/Editor/Paragraph/ParaDrawing.js", "../../../../sdkjs/word/Editor/Paragraph/ParaDrawingChanges.js", + "../../../../sdkjs/word/Editor/Paragraph/ComplexFieldInstruction.js", + "../../../../sdkjs/word/Editor/Paragraph/ComplexField.js", "../../../../sdkjs/word/Editor/Paragraph.js", "../../../../sdkjs/word/Editor/ParagraphChanges.js", "../../../../sdkjs/word/Editor/DocumentContentBase.js", diff --git a/apps/spreadsheeteditor/embed/js/ApplicationController.js b/apps/spreadsheeteditor/embed/js/ApplicationController.js index 2fb85a683..f02790f27 100644 --- a/apps/spreadsheeteditor/embed/js/ApplicationController.js +++ b/apps/spreadsheeteditor/embed/js/ApplicationController.js @@ -405,6 +405,8 @@ var ApplicationController = new(function(){ }); } else { + Common.Gateway.reportWarning(id, message); + $('#id-critical-error-title').text(me.notcriticalErrorTitle); $('#id-critical-error-message').text(message); $('#id-critical-error-close').off(); diff --git a/apps/spreadsheeteditor/main/app.js b/apps/spreadsheeteditor/main/app.js index d38cfe1ac..6a342e504 100644 --- a/apps/spreadsheeteditor/main/app.js +++ b/apps/spreadsheeteditor/main/app.js @@ -155,10 +155,13 @@ require([ 'RightMenu', 'LeftMenu', 'Main', + 'PivotTable', 'Common.Controllers.Fonts', 'Common.Controllers.Chat', 'Common.Controllers.Comments', 'Common.Controllers.Plugins' + ,'Common.Controllers.ReviewChanges' + ,'Common.Controllers.Protection' ] }); @@ -174,18 +177,25 @@ require([ 'spreadsheeteditor/main/app/controller/LeftMenu', 'spreadsheeteditor/main/app/controller/Main', 'spreadsheeteditor/main/app/controller/Print', + 'spreadsheeteditor/main/app/controller/PivotTable', 'spreadsheeteditor/main/app/view/FileMenuPanels', 'spreadsheeteditor/main/app/view/ParagraphSettings', 'spreadsheeteditor/main/app/view/ImageSettings', 'spreadsheeteditor/main/app/view/ChartSettings', 'spreadsheeteditor/main/app/view/ShapeSettings', 'spreadsheeteditor/main/app/view/TextArtSettings', + 'spreadsheeteditor/main/app/view/PivotSettings', + 'spreadsheeteditor/main/app/view/FieldSettingsDialog', + 'spreadsheeteditor/main/app/view/ValueFieldSettingsDialog', + 'spreadsheeteditor/main/app/view/SignatureSettings', 'common/main/lib/util/utils', 'common/main/lib/util/LocalStorage', 'common/main/lib/controller/Fonts', 'common/main/lib/controller/Comments', 'common/main/lib/controller/Chat', 'common/main/lib/controller/Plugins' + ,'common/main/lib/controller/ReviewChanges' + ,'common/main/lib/controller/Protection' ], function() { app.start(); }); diff --git a/apps/spreadsheeteditor/main/app/controller/DocumentHolder.js b/apps/spreadsheeteditor/main/app/controller/DocumentHolder.js index 18be70765..c7d2fed2f 100644 --- a/apps/spreadsheeteditor/main/app/controller/DocumentHolder.js +++ b/apps/spreadsheeteditor/main/app/controller/DocumentHolder.js @@ -81,6 +81,7 @@ define([ me.namedrange_locked = false; me._currentMathObj = undefined; me._currentParaObjDisabled = false; + me._isDisabled = false; /** coauthoring begin **/ this.wrapEvents = { @@ -137,6 +138,8 @@ define([ me.onCellsRange(status); } }); + + Common.Gateway.on('processmouse', _.bind(me.onProcessMouse, me)); }, onCreateDelayedElements: function(view) { @@ -189,10 +192,16 @@ define([ view.mnuChartEdit.on('click', _.bind(me.onChartEdit, me)); view.mnuImgAdvanced.on('click', _.bind(me.onImgAdvanced, me)); view.textInShapeMenu.on('render:after', _.bind(me.onTextInShapeAfterRender, me)); + view.menuSignatureEditSign.on('click', _.bind(me.onSignatureClick, me)); + view.menuSignatureEditSetup.on('click', _.bind(me.onSignatureClick, me)); } else { view.menuViewCopy.on('click', _.bind(me.onCopyPaste, me)); view.menuViewUndo.on('click', _.bind(me.onUndo, me)); view.menuViewAddComment.on('click', _.bind(me.onAddComment, me)); + view.menuSignatureViewSign.on('click', _.bind(me.onSignatureClick, me)); + view.menuSignatureDetails.on('click', _.bind(me.onSignatureClick, me)); + view.menuSignatureViewSetup.on('click', _.bind(me.onSignatureClick, me)); + view.menuSignatureRemove.on('click', _.bind(me.onSignatureClick, me)); } var documentHolderEl = view.cmpEl; @@ -266,6 +275,7 @@ define([ this.api.asc_registerCallback('asc_onFormulaCompleteMenu', _.bind(this.onFormulaCompleteMenu, this)); this.api.asc_registerCallback('asc_onShowSpecialPasteOptions', _.bind(this.onShowSpecialPasteOptions, this)); this.api.asc_registerCallback('asc_onHideSpecialPasteOptions', _.bind(this.onHideSpecialPasteOptions, this)); + this.api.asc_registerCallback('asc_onToggleAutoCorrectOptions', _.bind(this.onToggleAutoCorrectOptions, this)); } return this; }, @@ -869,6 +879,7 @@ define([ } } else { linkstr = props.asc_getTooltip() || (props.asc_getLocation()); + linkstr += '
    ' + me.textCtrlClick + ''; } if (hyperlinkTip.ref && hyperlinkTip.ref.isVisible()) { @@ -1220,16 +1231,20 @@ define([ event.button == 0 && (this.mouse.isLeftButtonDown = false); }, + onProcessMouse: function(data) { + (data.type == 'mouseup') && (this.mouse.isLeftButtonDown = false); + }, + showObjectMenu: function(event){ if (this.api && !this.mouse.isLeftButtonDown && !this.rangeSelectionMode){ - (this.permissions.isEdit) ? this.fillMenuProps(this.api.asc_getCellInfo(), true, event) : this.fillViewMenuProps(this.api.asc_getCellInfo(), true, event); + (this.permissions.isEdit && !this._isDisabled) ? this.fillMenuProps(this.api.asc_getCellInfo(), true, event) : this.fillViewMenuProps(this.api.asc_getCellInfo(), true, event); } }, onSelectionChanged: function(info){ if (!this.mouse.isLeftButtonDown && !this.rangeSelectionMode && this.currentMenu && this.currentMenu.isVisible()){ - (this.permissions.isEdit) ? this.fillMenuProps(info, true) : this.fillViewMenuProps(info, true); + (this.permissions.isEdit && !this._isDisabled) ? this.fillMenuProps(info, true) : this.fillViewMenuProps(info, true); } }, @@ -1241,33 +1256,26 @@ define([ isTableLocked = cellinfo.asc_getLockedTable()===true, isObjLocked = false, commentsController = this.getApplication().getController('Common.Controllers.Comments'), - insfunc = false, - cansort = false; + internaleditor = this.permissions.isEditMailMerge || this.permissions.isEditDiagram; - if (this.permissions.isEditMailMerge) { - cansort = (seltype==Asc.c_oAscSelectionType.RangeCells); - } else if (this.permissions.isEditDiagram) { - insfunc = (seltype==Asc.c_oAscSelectionType.RangeCells); - } - else { - switch (seltype) { - case Asc.c_oAscSelectionType.RangeCells: iscellmenu = true; break; - case Asc.c_oAscSelectionType.RangeRow: isrowmenu = true; break; - case Asc.c_oAscSelectionType.RangeCol: iscolmenu = true; break; - case Asc.c_oAscSelectionType.RangeMax: isallmenu = true; break; - case Asc.c_oAscSelectionType.RangeImage: isimagemenu = true; break; - case Asc.c_oAscSelectionType.RangeShape: isshapemenu = true; break; - case Asc.c_oAscSelectionType.RangeChart: ischartmenu = true; break; - case Asc.c_oAscSelectionType.RangeChartText:istextchartmenu = true; break; - case Asc.c_oAscSelectionType.RangeShapeText: istextshapemenu = true; break; - } + switch (seltype) { + case Asc.c_oAscSelectionType.RangeCells: iscellmenu = true; break; + case Asc.c_oAscSelectionType.RangeRow: isrowmenu = true; break; + case Asc.c_oAscSelectionType.RangeCol: iscolmenu = true; break; + case Asc.c_oAscSelectionType.RangeMax: isallmenu = true; break; + case Asc.c_oAscSelectionType.RangeImage: isimagemenu = !internaleditor; break; + case Asc.c_oAscSelectionType.RangeShape: isshapemenu = !internaleditor; break; + case Asc.c_oAscSelectionType.RangeChart: ischartmenu = !internaleditor; break; + case Asc.c_oAscSelectionType.RangeChartText:istextchartmenu = !internaleditor; break; + case Asc.c_oAscSelectionType.RangeShapeText: istextshapemenu = !internaleditor; break; } if (isimagemenu || isshapemenu || ischartmenu) { if (!showMenu && !documentHolder.imgMenu.isVisible()) return; isimagemenu = isshapemenu = ischartmenu = false; - var has_chartprops = false; + var has_chartprops = false, + signGuid; var selectedObjects = this.api.asc_getGraphicObjectProps(); for (var i = 0; i < selectedObjects.length; i++) { if (selectedObjects[i].asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image) { @@ -1289,6 +1297,8 @@ define([ documentHolder.mnuImgAdvanced.imageInfo = elValue; isimagemenu = true; } + if (this.permissions.canProtect) + signGuid = elValue.asc_getSignatureId(); } } @@ -1302,6 +1312,16 @@ define([ documentHolder.pmiImgPaste.setDisabled(isObjLocked); documentHolder.mnuImgAdvanced.setVisible(isimagemenu && !isshapemenu && !ischartmenu); documentHolder.mnuImgAdvanced.setDisabled(isObjLocked); + + var isInSign = !!signGuid; + documentHolder.menuSignatureEditSign.setVisible(isInSign); + documentHolder.menuSignatureEditSetup.setVisible(isInSign); + documentHolder.menuEditSignSeparator.setVisible(isInSign); + if (isInSign) { + documentHolder.menuSignatureEditSign.cmpEl.attr('data-value', signGuid); // sign + documentHolder.menuSignatureEditSetup.cmpEl.attr('data-value', signGuid); // edit signature settings + } + if (showMenu) this.showPopupMenu(documentHolder.imgMenu, {}, event); documentHolder.mnuShapeSeparator.setVisible(documentHolder.mnuShapeAdvanced.isVisible() || documentHolder.mnuChartEdit.isVisible() || documentHolder.mnuImgAdvanced.isVisible()); } else if (istextshapemenu || istextchartmenu) { @@ -1388,12 +1408,14 @@ define([ documentHolder.pmiInsertTable.setVisible(iscellmenu && !iscelledit && isintable); documentHolder.pmiDeleteTable.setVisible(iscellmenu && !iscelledit && isintable); documentHolder.pmiSparklines.setVisible(isinsparkline); - documentHolder.pmiSortCells.setVisible((iscellmenu||isallmenu||cansort) && !iscelledit); - documentHolder.pmiFilterCells.setVisible((iscellmenu||cansort) && !iscelledit); - documentHolder.pmiReapply.setVisible((iscellmenu||isallmenu||cansort) && !iscelledit); - documentHolder.ssMenu.items[12].setVisible((iscellmenu||isallmenu||cansort||isinsparkline) && !iscelledit); - documentHolder.pmiInsFunction.setVisible(iscellmenu||insfunc); - documentHolder.pmiAddNamedRange.setVisible(iscellmenu && !iscelledit); + documentHolder.pmiSortCells.setVisible((iscellmenu||isallmenu) && !iscelledit); + documentHolder.pmiSortCells.menu.items[2].setVisible(!internaleditor); + documentHolder.pmiSortCells.menu.items[3].setVisible(!internaleditor); + documentHolder.pmiFilterCells.setVisible(iscellmenu && !iscelledit && !internaleditor); + documentHolder.pmiReapply.setVisible((iscellmenu||isallmenu) && !iscelledit && !internaleditor); + documentHolder.ssMenu.items[12].setVisible((iscellmenu||isallmenu||isinsparkline) && !iscelledit); + documentHolder.pmiInsFunction.setVisible(iscellmenu); + documentHolder.pmiAddNamedRange.setVisible(iscellmenu && !iscelledit && !internaleditor); if (isintable) { documentHolder.pmiInsertTable.menu.items[0].setDisabled(!formatTableInfo.asc_getIsInsertRowAbove()); @@ -1408,8 +1430,8 @@ define([ } var hyperinfo = cellinfo.asc_getHyperlink(); - documentHolder.menuHyperlink.setVisible(iscellmenu && hyperinfo && !iscelledit && !ismultiselect); - documentHolder.menuAddHyperlink.setVisible(iscellmenu && !hyperinfo && !iscelledit && !ismultiselect); + documentHolder.menuHyperlink.setVisible(iscellmenu && hyperinfo && !iscelledit && !ismultiselect && !internaleditor); + documentHolder.menuAddHyperlink.setVisible(iscellmenu && !hyperinfo && !iscelledit && !ismultiselect && !internaleditor); documentHolder.pmiRowHeight.setVisible(isrowmenu||isallmenu); documentHolder.pmiColumnWidth.setVisible(iscolmenu||isallmenu); @@ -1422,15 +1444,16 @@ define([ documentHolder.ssMenu.items[17].setVisible(iscellmenu && !iscelledit && this.permissions.canCoAuthoring && this.permissions.canComments); documentHolder.pmiAddComment.setVisible(iscellmenu && !iscelledit && this.permissions.canCoAuthoring && this.permissions.canComments); /** coauthoring end **/ - documentHolder.pmiCellMenuSeparator.setVisible(iscellmenu || isrowmenu || iscolmenu || isallmenu || insfunc); + documentHolder.pmiCellMenuSeparator.setVisible(iscellmenu || isrowmenu || iscolmenu || isallmenu); documentHolder.pmiEntireHide.isrowmenu = isrowmenu; documentHolder.pmiEntireShow.isrowmenu = isrowmenu; documentHolder.setMenuItemCommentCaptionMode(documentHolder.pmiAddComment, cellinfo.asc_getComments().length < 1, this.permissions.canEditComments); commentsController && commentsController.blockPopover(true); + documentHolder.pmiClear.menu.items[0].setDisabled(!this.permissions.canModifyFilter); documentHolder.pmiClear.menu.items[1].setDisabled(iscelledit); - documentHolder.pmiClear.menu.items[2].setDisabled(iscelledit); + documentHolder.pmiClear.menu.items[2].setDisabled(iscelledit || !this.permissions.canModifyFilter); documentHolder.pmiClear.menu.items[3].setDisabled(iscelledit); documentHolder.pmiClear.menu.items[4].setDisabled(iscelledit); @@ -1459,8 +1482,8 @@ define([ documentHolder.pmiDeleteEntire.setDisabled(isCellLocked || isTableLocked); documentHolder.pmiDeleteCells.setDisabled(isCellLocked || isTableLocked); documentHolder.pmiDeleteTable.setDisabled(isCellLocked || isTableLocked); - documentHolder.pmiFilterCells.setDisabled(isCellLocked || isTableLocked|| (filterInfo==null) || inPivot); - documentHolder.pmiSortCells.setDisabled(isCellLocked || isTableLocked|| (filterInfo==null) || inPivot); + documentHolder.pmiFilterCells.setDisabled(isCellLocked || isTableLocked|| (filterInfo==null) || inPivot || !filterInfo && !this.permissions.canModifyFilter); + documentHolder.pmiSortCells.setDisabled(isCellLocked || isTableLocked|| (filterInfo==null) || inPivot || !this.permissions.canModifyFilter); documentHolder.pmiReapply.setDisabled(isCellLocked || isTableLocked|| (isApplyAutoFilter!==true)); documentHolder.menuHyperlink.setDisabled(isCellLocked || inPivot); documentHolder.menuAddHyperlink.setDisabled(isCellLocked || inPivot); @@ -1490,17 +1513,50 @@ define([ isTableLocked = cellinfo.asc_getLockedTable()===true, commentsController = this.getApplication().getController('Common.Controllers.Comments'), iscellmenu = (seltype==Asc.c_oAscSelectionType.RangeCells) && !this.permissions.isEditMailMerge && !this.permissions.isEditDiagram, - iscelledit = this.api.isCellEdited; + iscelledit = this.api.isCellEdited, + isimagemenu = (seltype==Asc.c_oAscSelectionType.RangeImage) && !this.permissions.isEditMailMerge && !this.permissions.isEditDiagram, + signGuid; + + if (!documentHolder.viewModeMenu) + documentHolder.createDelayedElementsViewer(); if (!documentHolder.viewModeMenu) documentHolder.createDelayedElementsViewer(); if (!showMenu && !documentHolder.viewModeMenu.isVisible()) return; - documentHolder.menuViewUndo.setVisible(this.permissions.canCoAuthoring && this.permissions.canComments); - documentHolder.menuViewUndo.setDisabled(!this.api.asc_getCanUndo()); - documentHolder.menuViewCopySeparator.setVisible(iscellmenu && !iscelledit && this.permissions.canCoAuthoring && this.permissions.canComments); - documentHolder.menuViewAddComment.setVisible(iscellmenu && !iscelledit && this.permissions.canCoAuthoring && this.permissions.canComments); + if (isimagemenu && this.permissions.canProtect) { + var selectedObjects = this.api.asc_getGraphicObjectProps(); + for (var i = 0; i < selectedObjects.length; i++) { + if (selectedObjects[i].asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image) { + signGuid = selectedObjects[i].asc_getObjectValue().asc_getSignatureId(); + } + } + } + + var signProps = (signGuid) ? this.api.asc_getSignatureSetup(signGuid) : null, + isInSign = !!signProps && this._canProtect, + canComment = iscellmenu && !iscelledit && this.permissions.canCoAuthoring && this.permissions.canComments && !this._isDisabled; + + documentHolder.menuViewUndo.setVisible(this.permissions.canCoAuthoring && this.permissions.canComments && !this._isDisabled); + documentHolder.menuViewUndo.setDisabled(!this.api.asc_getCanUndo() && !this._isDisabled); + documentHolder.menuViewCopySeparator.setVisible(isInSign); + + var isRequested = (signProps) ? signProps.asc_getRequested() : false; + documentHolder.menuSignatureViewSign.setVisible(isInSign && isRequested); + documentHolder.menuSignatureDetails.setVisible(isInSign && !isRequested); + documentHolder.menuSignatureViewSetup.setVisible(isInSign); + documentHolder.menuSignatureRemove.setVisible(isInSign && !isRequested); + documentHolder.menuViewSignSeparator.setVisible(canComment); + + if (isInSign) { + documentHolder.menuSignatureViewSign.cmpEl.attr('data-value', signGuid); // sign + documentHolder.menuSignatureDetails.cmpEl.attr('data-value', signProps.asc_getId()); // view certificate + documentHolder.menuSignatureViewSetup.cmpEl.attr('data-value', signGuid); // view signature settings + documentHolder.menuSignatureRemove.cmpEl.attr('data-value', signGuid); + } + + documentHolder.menuViewAddComment.setVisible(canComment); documentHolder.setMenuItemCommentCaptionMode(documentHolder.menuViewAddComment, cellinfo.asc_getComments().length < 1, this.permissions.canEditComments); commentsController && commentsController.blockPopover(true); documentHolder.menuViewAddComment.setDisabled(isCellLocked || isTableLocked); @@ -1778,13 +1834,34 @@ define([ }); (menu.items.length>0) && menu.items[0].setChecked(true, true); } - if (coord.asc_getX()<0 || coord.asc_getY()<0) { + + if ( coord[0].asc_getX()<0 || coord[0].asc_getY()<0) { if (pasteContainer.is(':visible')) pasteContainer.hide(); - } else { - var showPoint = [coord.asc_getX() + coord.asc_getWidth() + 3, coord.asc_getY() + coord.asc_getHeight() + 3]; - pasteContainer.css({left: showPoint[0], top : showPoint[1]}); - pasteContainer.show(); + return; } + + var rightBottom = coord[0], + leftTop = coord[1], + width = me.tooltips.coauth.bodyWidth - me.tooltips.coauth.XY[0] - me.tooltips.coauth.rightMenuWidth - 15, + height = me.tooltips.coauth.apiHeight - 15, // height - scrollbar height + showPoint = [], + btnSize = [31, 20], + right = rightBottom.asc_getX() + rightBottom.asc_getWidth() + 3 + btnSize[0], + bottom = rightBottom.asc_getY() + rightBottom.asc_getHeight() + 3 + btnSize[1]; + + + if (right > width) { + showPoint[0] = leftTop.asc_getX(); + if (bottom > height) + showPoint[0] -= (btnSize[0]+3); + if (showPoint[0]<0) showPoint[0] = width - 3 - btnSize[0]; + } else + showPoint[0] = right - btnSize[0]; + + showPoint[1] = (bottom > height) ? height - 3 - btnSize[1] : bottom - btnSize[1]; + + pasteContainer.css({left: showPoint[0], top : showPoint[1]}); + pasteContainer.show(); }, onHideSpecialPasteOptions: function() { @@ -1793,6 +1870,70 @@ define([ pasteContainer.hide(); }, + onToggleAutoCorrectOptions: function(autoCorrectOptions) { + if (!autoCorrectOptions) { + var pasteContainer = this.documentHolder.cmpEl.find('#autocorrect-paste-container'); + if (pasteContainer.is(':visible')) + pasteContainer.hide(); + return; + } + + var me = this, + documentHolderView = me.documentHolder, + coord = autoCorrectOptions.asc_getCellCoord(), + pasteContainer = documentHolderView.cmpEl.find('#autocorrect-paste-container'), + pasteItems = autoCorrectOptions.asc_getOptions(); + + // Prepare menu container + if (pasteContainer.length < 1) { + me._arrAutoCorrectPaste = []; + me._arrAutoCorrectPaste[Asc.c_oAscAutoCorrectOptions.UndoTableAutoExpansion] = me.txtUndoExpansion; + me._arrAutoCorrectPaste[Asc.c_oAscAutoCorrectOptions.RedoTableAutoExpansion] = me.txtRedoExpansion; + + pasteContainer = $('
    '); + documentHolderView.cmpEl.append(pasteContainer); + + me.btnAutoCorrectPaste = new Common.UI.Button({ + cls : 'btn-toolbar', + iconCls : 'btn-paste', + menu : new Common.UI.Menu({items: []}) + }); + me.btnAutoCorrectPaste.render($('#id-document-holder-btn-autocorrect-paste')) ; + } + + if (pasteItems.length>0) { + var menu = me.btnAutoCorrectPaste.menu; + for (var i = 0; i < menu.items.length; i++) { + menu.removeItem(menu.items[i]); + i--; + } + + var group_prev = -1; + _.each(pasteItems, function(menuItem, index) { + var mnu = new Common.UI.MenuItem({ + caption: me._arrAutoCorrectPaste[menuItem], + value: menuItem + }).on('click', function(item, e) { + me.api.asc_applyAutoCorrectOptions(item.value); + setTimeout(function(){menu.hide();}, 100); + }); + menu.addItem(mnu); + }); + } + + var width = me.tooltips.coauth.bodyWidth - me.tooltips.coauth.XY[0] - me.tooltips.coauth.rightMenuWidth - 15, + height = me.tooltips.coauth.apiHeight - 15, // height - scrollbar height + btnSize = [31, 20], + right = coord.asc_getX() + coord.asc_getWidth() + 2 + btnSize[0], + bottom = coord.asc_getY() + coord.asc_getHeight() + 1 + btnSize[1]; + if (right > width || bottom > height || coord.asc_getX()<0 || coord.asc_getY()<0) { + if (pasteContainer.is(':visible')) pasteContainer.hide(); + } else { + pasteContainer.css({left: right - btnSize[0], top : bottom - btnSize[1]}); + pasteContainer.show(); + } + }, + onCellsRange: function(status) { this.rangeSelectionMode = (status != Asc.c_oAscSelectionDialogType.None); }, @@ -2437,6 +2578,29 @@ define([ _conf && view.paraBulletsPicker.selectRecord(_conf.rec, true); }, + onSignatureClick: function(item) { + var datavalue = item.cmpEl.attr('data-value'); + switch (item.value) { + case 0: + Common.NotificationCenter.trigger('protect:sign', datavalue); //guid + break; + case 1: + this.api.asc_ViewCertificate(datavalue); //certificate id + break; + case 2: + Common.NotificationCenter.trigger('protect:signature', 'visible', this._isDisabled, datavalue);//guid, can edit settings for requested signature + break; + case 3: + this.api.asc_RemoveSignature(datavalue); //guid + break; + } + }, + + SetDisabled: function(state, canProtect) { + this._isDisabled = state; + this._canProtect = canProtect; + }, + guestText : 'Guest', textCtrlClick : 'Press CTRL and click link', txtHeight : 'Height', @@ -2552,7 +2716,9 @@ define([ txtPastePicture: 'Picture', txtPasteLinkPicture: 'Linked Picture', txtPasteSourceFormat: 'Source formatting', - txtPasteDestFormat: 'Destination formatting' + txtPasteDestFormat: 'Destination formatting', + txtUndoExpansion: 'Undo table autoexpansion', + txtRedoExpansion: 'Redo table autoexpansion' }, SSE.Controllers.DocumentHolder || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/controller/FormulaDialog.js b/apps/spreadsheeteditor/main/app/controller/FormulaDialog.js index 98425604b..1215f5d81 100644 --- a/apps/spreadsheeteditor/main/app/controller/FormulaDialog.js +++ b/apps/spreadsheeteditor/main/app/controller/FormulaDialog.js @@ -137,10 +137,7 @@ define([ allFunctionsGroup = null; if (store) { - var value = Common.localStorage.getItem("sse-settings-func-locale"); - if (value===null) - value = ((this.mode.lang) ? this.mode.lang : 'en').split("-")[0].toLowerCase(); - value = SSE.Views.FormulaLang.getDescription(value); + var value = SSE.Views.FormulaLang.getDescription(Common.Utils.InternalSettings.get("sse-settings-func-locale")); allFunctionsGroup = new SSE.Models.FormulaGroup ({ name : 'All', diff --git a/apps/spreadsheeteditor/main/app/controller/LeftMenu.js b/apps/spreadsheeteditor/main/app/controller/LeftMenu.js index 4ee7ee9a8..3bd8f796c 100644 --- a/apps/spreadsheeteditor/main/app/controller/LeftMenu.js +++ b/apps/spreadsheeteditor/main/app/controller/LeftMenu.js @@ -85,7 +85,11 @@ define([ 'search:back': _.bind(this.onQuerySearch, this, 'back'), 'search:next': _.bind(this.onQuerySearch, this, 'next'), 'search:replace': _.bind(this.onQueryReplace, this), - 'search:replaceall': _.bind(this.onQueryReplaceAll, this) + 'search:replaceall': _.bind(this.onQueryReplaceAll, this), + 'search:highlight': _.bind(this.onSearchHighlight, this) + }, + 'Common.Views.ReviewChanges': { + 'collaboration:chat': _.bind(this.onShowHideChat, this) } }); Common.NotificationCenter.on('app:comment:add', _.bind(this.onAppAddComment, this)); @@ -262,31 +266,41 @@ define([ }, applySettings: function(menu) { - this.api.asc_setFontRenderingMode(parseInt(Common.localStorage.getItem("sse-settings-fontrender"))); + var value = Common.localStorage.getItem("sse-settings-fontrender"); + Common.Utils.InternalSettings.set("sse-settings-fontrender", value); + this.api.asc_setFontRenderingMode(parseInt(value)); if (Common.Utils.isChrome) { value = Common.localStorage.getBool("sse-settings-inputsogou"); + Common.Utils.InternalSettings.set("sse-settings-inputsogou", value); this.api.setInputParams({"SogouPinyin" : value}); } /** coauthoring begin **/ - var value = Common.localStorage.getItem("sse-settings-livecomment"); - var resolved = Common.localStorage.getItem("sse-settings-resolvedcomment"); - (!(value!==null && parseInt(value) == 0)) ? this.api.asc_showComments(!(resolved!==null && parseInt(resolved) == 0)) : this.api.asc_hideComments(); -// this.getApplication().getController('DocumentHolder').setLiveCommenting(!(value!==null && parseInt(value) == 0)); + value = Common.localStorage.getBool("sse-settings-livecomment", true); + Common.Utils.InternalSettings.set("sse-settings-livecomment", value); + var resolved = Common.localStorage.getBool("sse-settings-resolvedcomment", true); + Common.Utils.InternalSettings.set("sse-settings-resolvedcomment", resolved); + + if (this.mode.canComments && this.leftMenu.panelComments.isVisible()) + value = resolved = true; + (value) ? this.api.asc_showComments(resolved) : this.api.asc_hideComments(); if (this.mode.isEdit && !this.mode.isOffline && this.mode.canCoAuthoring) { - value = Common.localStorage.getItem("sse-settings-coauthmode"); - this.api.asc_SetFastCollaborative(value===null || parseInt(value) == 1); + value = Common.localStorage.getBool("sse-settings-coauthmode", true); + Common.Utils.InternalSettings.set("sse-settings-coauthmode", value); + this.api.asc_SetFastCollaborative(value); } /** coauthoring end **/ if (this.mode.isEdit) { - value = Common.localStorage.getItem("sse-settings-autosave"); - this.api.asc_setAutoSaveGap(parseInt(value)); + value = parseInt(Common.localStorage.getItem("sse-settings-autosave")); + Common.Utils.InternalSettings.set("sse-settings-autosave", value); + this.api.asc_setAutoSaveGap(value); } value = Common.localStorage.getItem("sse-settings-func-locale"); + Common.Utils.InternalSettings.set("sse-settings-func-locale", value); if (value) value = SSE.Views.FormulaLang.get(value); if (value!==null) this.api.asc_setLocalization(value); @@ -403,6 +417,10 @@ define([ } }, + onSearchHighlight: function(w, highlight) { + this.api.asc_selectSearchingResults(highlight); + }, + showSearchDlg: function(show,action) { if ( !this.dlgSearch ) { var menuWithin = new Common.UI.MenuItem({ @@ -463,7 +481,7 @@ define([ matchcase: true, matchword: true, matchwordstr: this.textItemEntireCell, - markresult: false, + markresult: {applied: true}, extraoptions : [menuWithin,menuSearch,menuLookin] })); @@ -493,6 +511,7 @@ define([ onSearchDlgHide: function() { this.leftMenu.btnSearch.toggle(false, true); + this.api.asc_selectSearchingResults(false); $(this.leftMenu.btnSearch.el).blur(); this.api.asc_enableKeyEvents(true); }, @@ -583,12 +602,11 @@ define([ commentsShowHide: function(state) { if (this.api) { - var value = Common.localStorage.getItem("sse-settings-livecomment"), - resolved = Common.localStorage.getItem("sse-settings-resolvedcomment"); - value = (value!==null && parseInt(value) == 0); - resolved = (resolved!==null && parseInt(resolved) == 0); - if (value || resolved) { - (state) ? this.api.asc_showComments(true) : ((!value) ? this.api.asc_showComments(!resolved) : this.api.asc_hideComments()); + var value = Common.Utils.InternalSettings.get("sse-settings-livecomment"), + resolved = Common.Utils.InternalSettings.get("sse-settings-resolvedcomment"); + + if (!value || !resolved) { + (state) ? this.api.asc_showComments(true) : ((value) ? this.api.asc_showComments(resolved) : this.api.asc_hideComments()); } if (state) { @@ -751,11 +769,11 @@ define([ }, onPluginOpen: function(panel, type, action) { - if ( type == 'onboard' ) { - if ( action == 'open' ) { + if (type == 'onboard') { + if (action == 'open') { this.leftMenu.close(); this.leftMenu.panelPlugins.show(); - this.leftMenu.onBtnMenuClick({pressed:true, options: {action: 'plugins'}}); + this.leftMenu.onBtnMenuClick({pressed: true, options: {action: 'plugins'}}); this.leftMenu._state.pluginIsRunning = true; } else { this.leftMenu._state.pluginIsRunning = false; @@ -764,6 +782,18 @@ define([ } }, + onShowHideChat: function(state) { + if (this.mode.canCoAuthoring && this.mode.canChat && !this.mode.isLightVersion) { + if (state) { + Common.UI.Menu.Manager.hideAll(); + this.leftMenu.showMenu('chat'); + } else { + this.leftMenu.btnChat.toggle(false, true); + this.leftMenu.onBtnMenuClick(this.leftMenu.btnChat); + } + } + }, + textNoTextFound : 'Text not found', newDocumentTitle : 'Unnamed document', textItemEntireCell : 'Entire cell contents', diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js index 0f7461b4d..6f7fb0903 100644 --- a/apps/spreadsheeteditor/main/app/controller/Main.js +++ b/apps/spreadsheeteditor/main/app/controller/Main.js @@ -96,6 +96,9 @@ define([ this.addListeners({ 'FileMenu': { 'settings:apply': _.bind(this.applySettings, this) + }, + 'Common.Views.ReviewChanges': { + 'settings:apply': _.bind(this.applySettings, this) } }); }, @@ -118,6 +121,7 @@ define([ var value = Common.localStorage.getItem("sse-settings-fontrender"); if (value===null) value = window.devicePixelRatio > 1 ? '1' : '3'; + Common.Utils.InternalSettings.set("sse-settings-fontrender", value); // Initialize api var styleNames = ['Normal', 'Neutral', 'Bad', 'Good', 'Input', 'Output', 'Calculation', 'Check Cell', 'Explanatory Text', 'Note', 'Linked Cell', 'Warning Text', @@ -152,6 +156,7 @@ define([ if (Common.Utils.isChrome) { value = Common.localStorage.getBool("sse-settings-inputsogou"); this.api.setInputParams({"SogouPinyin" : value}); + Common.Utils.InternalSettings.set("sse-settings-inputsogou", value); } this.api.asc_registerCallback('asc_onOpenDocumentProgress', _.bind(this.onOpenDocument, this)); @@ -314,10 +319,13 @@ define([ value = Common.localStorage.getItem("sse-settings-func-locale"); if (value===null) { var lang = ((this.editorConfig.lang) ? this.editorConfig.lang : 'en').split("-")[0].toLowerCase(); + Common.Utils.InternalSettings.set("sse-settings-func-locale", lang); if (lang !== 'en') value = SSE.Views.FormulaLang.get(lang); - } else + } else { + Common.Utils.InternalSettings.set("sse-settings-func-locale", value); value = SSE.Views.FormulaLang.get(value); + } if (value) this.api.asc_setLocalization(value); if (this.appOptions.location == 'us' || this.appOptions.location == 'ca') @@ -391,8 +399,18 @@ define([ } }, - onDownloadAs: function() { - this.api.asc_DownloadAs(Asc.c_oAscFileType.XLSX, true); + onDownloadAs: function(format) { + var _format = (format && (typeof format == 'string')) ? Asc.c_oAscFileType[ format.toUpperCase() ] : null, + _supported = [ + Asc.c_oAscFileType.XLSX, + Asc.c_oAscFileType.ODS, + Asc.c_oAscFileType.CSV, + Asc.c_oAscFileType.PDF + ]; + + if ( !_format || _supported.indexOf(_format) < 0 ) + _format = Asc.c_oAscFileType.XLSX; + this.api.asc_DownloadAs(_format, true); }, onProcessMouse: function(data) { @@ -578,14 +596,16 @@ define([ me.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument); value = (this.appOptions.isEditMailMerge || this.appOptions.isEditDiagram) ? 100 : Common.localStorage.getItem("sse-settings-zoom"); + Common.Utils.InternalSettings.set("sse-settings-zoom", value); var zf = (value!==null) ? parseInt(value)/100 : (this.appOptions.customization && this.appOptions.customization.zoom ? parseInt(this.appOptions.customization.zoom)/100 : 1); this.api.asc_setZoom(zf>0 ? zf : 1); /** coauthoring begin **/ - value = Common.localStorage.getItem("sse-settings-livecomment"); - this.isLiveCommenting = !(value!==null && parseInt(value) == 0); - var resolved = Common.localStorage.getItem("sse-settings-resolvedcomment"); - this.isLiveCommenting ? this.api.asc_showComments(!(resolved!==null && parseInt(resolved) == 0)) : this.api.asc_hideComments(); + this.isLiveCommenting = Common.localStorage.getBool("sse-settings-livecomment", true); + Common.Utils.InternalSettings.set("sse-settings-livecomment", this.isLiveCommenting); + value = Common.localStorage.getBool("sse-settings-resolvedcomment", true); + Common.Utils.InternalSettings.set("sse-settings-resolvedcomment", value); + this.isLiveCommenting ? this.api.asc_showComments(value) : this.api.asc_hideComments(); if (this.appOptions.isEdit && !this.appOptions.isOffline && this.appOptions.canCoAuthoring) { value = Common.localStorage.getItem("sse-settings-coauthmode"); @@ -596,9 +616,13 @@ define([ this._state.fastCoauth = (value===null || parseInt(value) == 1); } else { this._state.fastCoauth = (!this.appOptions.isEdit && this.appOptions.canComments); - this._state.fastCoauth && this.api.asc_setAutoSaveGap(1); + if (this._state.fastCoauth) { + this.api.asc_setAutoSaveGap(1); + Common.Utils.InternalSettings.set("sse-settings-autosave", 1); + } } this.api.asc_SetFastCollaborative(this._state.fastCoauth); + Common.Utils.InternalSettings.set("sse-settings-coauthmode", me._state.fastCoauth); /** coauthoring end **/ me.api.asc_registerCallback('asc_onStartAction', _.bind(me.onLongActionBegin, me)); @@ -660,10 +684,11 @@ define([ value = 0; } me.api.asc_setAutoSaveGap(value); + Common.Utils.InternalSettings.set("sse-settings-autosave", value); if (me.appOptions.canForcesave) {// use asc_setIsForceSaveOnUserSave only when customization->forcesave = true - value = Common.localStorage.getItem("sse-settings-forcesave"); - me.appOptions.forcesave = (value === null) ? me.appOptions.canForcesave : (parseInt(value) == 1); + me.appOptions.forcesave = Common.localStorage.getBool("sse-settings-forcesave", me.appOptions.canForcesave); + Common.Utils.InternalSettings.set("sse-settings-forcesave", me.appOptions.forcesave); me.api.asc_setIsForceSaveOnUserSave(me.appOptions.forcesave); } @@ -706,16 +731,14 @@ define([ if (me.needToUpdateVersion) toolbarController.onApiCoAuthoringDisconnect(); - if (me.appOptions.canBrandingExt) - Common.NotificationCenter.trigger('document:ready', 'main'); + Common.NotificationCenter.trigger('document:ready', 'main'); me.applyLicense(); } }, 50); } else { documentHolderView.createDelayedElementsViewer(); - if (me.appOptions.canBrandingExt) - Common.NotificationCenter.trigger('document:ready', 'main'); + Common.NotificationCenter.trigger('document:ready', 'main'); } if (me.appOptions.canAnalytics && false) @@ -836,6 +859,8 @@ define([ this.appOptions.canChat = this.appOptions.canLicense && !this.appOptions.isOffline && !((typeof (this.editorConfig.customization) == 'object') && this.editorConfig.customization.chat===false); this.appOptions.canRename = !!this.permissions.rename; this.appOptions.trialMode = params.asc_getLicenseMode(); + this.appOptions.canProtect = this.appOptions.isDesktopApp && this.api.asc_isSignaturesSupport(); + this.appOptions.canModifyFilter = (this.permissions.modifyFilter!==false); this.appOptions.canBranding = (licType === Asc.c_oLicenseResult.Success) && (typeof this.editorConfig.customization == 'object'); if (this.appOptions.canBranding) @@ -846,7 +871,8 @@ define([ this.updatePlugins(this.plugins, true); this.appOptions.canRename && this.headerView.setCanRename(true); - } + } else + this.appOptions.canModifyFilter = true; this.appOptions.canRequestEditRights = this.editorConfig.canRequestEditRights; this.appOptions.canEdit = this.permissions.edit !== false && // can edit @@ -946,7 +972,8 @@ define([ toolbarController = application.getController('Toolbar'), statusbarController = application.getController('Statusbar'), rightmenuController = application.getController('RightMenu'), - fontsControllers = application.getController('Common.Controllers.Fonts'); + fontsControllers = application.getController('Common.Controllers.Fonts'), + reviewController = application.getController('Common.Controllers.ReviewChanges'); fontsControllers && fontsControllers.setApi(me.api); toolbarController && toolbarController.setApi(me.api); @@ -954,10 +981,18 @@ define([ rightmenuController && rightmenuController.setApi(me.api); + reviewController.setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + + if (me.appOptions.isDesktopApp && me.appOptions.isOffline) + application.getController('Common.Controllers.Protection').setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + if (statusbarController) { statusbarController.getView('Statusbar').changeViewMode(true); } + if (!me.appOptions.isEditMailMerge && !me.appOptions.isEditDiagram) + application.getController('PivotTable').setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + var viewport = this.getApplication().getController('Viewport').getView('Viewport'); viewport.applyEditorMode(); rightmenuController.getView('RightMenu').setMode(me.appOptions).setApi(me.api); @@ -965,7 +1000,9 @@ define([ this.toolbarView = toolbarController.getView('Toolbar'); var value = Common.localStorage.getItem('sse-settings-unit'); - Common.Utils.Metric.setCurrentMetric((value!==null) ? parseInt(value) : Common.Utils.Metric.getDefaultMetric()); + value = (value!==null) ? parseInt(value) : Common.Utils.Metric.getDefaultMetric(); + Common.Utils.Metric.setCurrentMetric(value); + Common.Utils.InternalSettings.set("sse-settings-unit", value); if (!me.appOptions.isEditMailMerge && !me.appOptions.isEditDiagram) { var options = {}; @@ -982,6 +1019,8 @@ define([ if (me.appOptions.isEditDiagram) me.api.asc_registerCallback('asc_onSelectionChanged', _.bind(me.onSelectionChanged, me)); + me.api.asc_setFilteringMode && me.api.asc_setFilteringMode(me.appOptions.canModifyFilter); + if (me.stackLongActions.exist({id: ApplyEditRights, type: Asc.c_oAscAsyncActionType['BlockInteraction']})) { me.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], ApplyEditRights); } else if (!this._isDocReady) { @@ -1252,6 +1291,8 @@ define([ } } } else { + Common.Gateway.reportWarning(id, config.msg); + config.title = this.notcriticalErrorTitle; config.iconCls = 'warn'; config.buttons = ['ok']; @@ -1671,6 +1712,7 @@ define([ if ($('body .asc-window:visible').length === 0) { this.isFrameClosed = true; this.api.asc_closeCellEditor(); + Common.UI.Menu.Manager.hideAll(); Common.Gateway.internalMessage('canClose', {mr:data.data.mr, answer: true}); } break; @@ -1728,7 +1770,9 @@ define([ unitsChanged: function(m) { var value = Common.localStorage.getItem("sse-settings-unit"); - Common.Utils.Metric.setCurrentMetric((value!==null) ? parseInt(value) : Common.Utils.Metric.getDefaultMetric()); + value = (value!==null) ? parseInt(value) : Common.Utils.Metric.getDefaultMetric(); + Common.Utils.Metric.setCurrentMetric(value); + Common.Utils.InternalSettings.set("sse-settings-unit", value); this.getApplication().getController('RightMenu').updateMetricUnit(); this.getApplication().getController('Print').getView('MainSettingsPrint').updateMetricUnit(); }, @@ -1784,6 +1828,7 @@ define([ if (btn == 'custom') { Common.localStorage.setItem("sse-settings-coauthmode", 0); this.api.asc_SetFastCollaborative(false); + Common.Utils.InternalSettings.set("sse-settings-coauthmode", false); this._state.fastCoauth = false; } this.onEditComplete(); @@ -1809,8 +1854,8 @@ define([ this.toolbarView.synchronizeChanges(); } if (this.appOptions.canForcesave) { - value = Common.localStorage.getItem("sse-settings-forcesave"); - this.appOptions.forcesave = (value===null) ? this.appOptions.canForcesave : (parseInt(value)==1); + this.appOptions.forcesave = Common.localStorage.getBool("sse-settings-forcesave", this.appOptions.canForcesave); + Common.Utils.InternalSettings.set("sse-settings-forcesave", this.appOptions.forcesave); this.api.asc_setIsForceSaveOnUserSave(this.appOptions.forcesave); } }, @@ -1879,18 +1924,11 @@ define([ var pluginsData = (uiCustomize) ? plugins.UIpluginsData : plugins.pluginsData; if (!pluginsData || pluginsData.length<1) return; - var arr = [], - baseUrl = _.isEmpty(plugins.url) ? "" : plugins.url; - - if (baseUrl !== "") - console.warn("Obsolete: The url parameter is deprecated. Please check the documentation for new plugin connection configuration."); - + var arr = []; pluginsData.forEach(function(item){ - item = baseUrl + item; // for compatibility with previouse version of server, where plugins.url is used. var value = Common.Utils.getConfigJson(item); if (value) { value.baseUrl = item.substring(0, item.lastIndexOf("config.json")); - value.oldVersion = (baseUrl !== ""); arr.push(value); } }); @@ -1930,14 +1968,6 @@ define([ var visible = (isEdit || itemVar.isViewer) && _.contains(itemVar.EditorsSupport, 'cell'); if ( visible ) pluginVisible = true; - var icons = itemVar.icons; - if (item.oldVersion) { // for compatibility with previouse version of server, where plugins.url is used. - icons = []; - itemVar.icons.forEach(function(icon){ - icons.push(icon.substring(icon.lastIndexOf("\/")+1)); - }); - } - if ( item.isUICustomizer ) { visible && arrUI.push(item.baseUrl + itemVar.url); } else { @@ -1945,8 +1975,8 @@ define([ model.set({ index: variationsArr.length, - url: (item.oldVersion) ? (itemVar.url.substring(itemVar.url.lastIndexOf("\/") + 1)) : itemVar.url, - icons: icons, + url: itemVar.url, + icons: itemVar.icons, visible: visible }); diff --git a/apps/spreadsheeteditor/main/app/controller/PivotTable.js b/apps/spreadsheeteditor/main/app/controller/PivotTable.js new file mode 100644 index 000000000..ee2b75727 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/controller/PivotTable.js @@ -0,0 +1,348 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * PivotTable.js + * + * Created by Julia.Radzhabova on 06.27.17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'core', + 'spreadsheeteditor/main/app/view/PivotTable' +], function () { + 'use strict'; + + SSE.Controllers.PivotTable = Backbone.Controller.extend(_.extend({ + models : [], + views : [ + 'PivotTable' + ], + sdkViewName : '#id_main', + + initialize: function () { + + this.addListeners({ + 'PivotTable': { + // comments handlers + 'pivottable:rowscolumns': _.bind(this.onCheckTemplateChange, this), + 'pivottable:create': _.bind(this.onCreateClick, this), + 'pivottable:refresh': _.bind(this.onRefreshClick, this), + 'pivottable:style': _.bind(this.onPivotStyleSelect, this), + 'pivottable:layout': _.bind(this.onPivotLayout, this), + 'pivottable:blankrows': _.bind(this.onPivotBlankRows, this), + 'pivottable:subtotals': _.bind(this.onPivotSubtotals, this), + 'pivottable:grandtotals': _.bind(this.onPivotGrandTotals, this) + } + }); + }, + onLaunch: function () { + this._state = { + TableName: '', + TemplateName: '', + RowHeader: undefined, + RowBanded: undefined, + ColHeader: undefined, + ColBanded: undefined, + DisabledControls: false + }; + this._originalProps = null; + + this.view = this.createView('PivotTable'); + + Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); + Common.NotificationCenter.on('api:disconnect', _.bind(this.SetDisabled, this)); + }, + + setConfig: function (data, api) { + this.setApi(api); + + if (data) { + this.sdkViewName = data['sdkviewname'] || this.sdkViewName; + } + }, + + setApi: function (api) { + if (api) { + this.api = api; + this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.SetDisabled, this)); + this.api.asc_registerCallback('asc_onSendThemeColors', _.bind(this.onSendThemeColors, this)); + this.api.asc_registerCallback('asc_onSelectionChanged', _.bind(this.onSelectionChanged, this)); + } + }, + + setMode: function(mode) { + this.appConfig = mode; + return this; + }, + + SetDisabled: function() { + this.view && this.view.SetDisabled(true); + }, + + // helpers + + onCheckTemplateChange: function(type, value) { + // this._state[stateName] = undefined; + // if (this.api) + // this.api.asc_changeFormatTableInfo(this._state.TableName, type, value=='checked'); + // for test + switch (type) { + case 0: + this._originalProps.asc_getStyleInfo().asc_setShowRowHeaders(this.api, this._originalProps, value=='checked'); + break; + case 1: + this._originalProps.asc_getStyleInfo().asc_setShowColHeaders(this.api, this._originalProps, value=='checked'); + break; + case 2: + this._originalProps.asc_getStyleInfo().asc_setShowRowStripes(this.api, this._originalProps, value=='checked'); + break; + case 3: + this._originalProps.asc_getStyleInfo().asc_setShowColStripes(this.api, this._originalProps, value=='checked'); + break; + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onCreateClick: function(btn, opts){ + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onRefreshClick: function(btn, opts){ + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onPivotStyleSelect: function(record){ + if (this.api) { + this._originalProps.asc_getStyleInfo().asc_setName(this.api, this._originalProps, record.get('name')); + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onPivotBlankRows: function(type){ + if (this.api) { + if (type === 'insert'){ + + } else { + + } + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onPivotLayout: function(type){ + if (this.api) { + switch (type){ + case 0: + break; + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + } + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onPivotGrandTotals: function(type){ + if (this.api) { + var props = new Asc.CT_pivotTableDefinition(); + props.asc_setColGrandTotals(type == 1 || type == 2); + props.asc_setRowGrandTotals(type == 1 || type == 3); + this._originalProps.asc_set(this.api, props); + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onPivotSubtotals: function(type){ + if (this.api) { + switch (type){ + case 0: + break; + case 1: + break; + case 2: + break; + } + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + ChangeSettings: function(props) { + if (props ) + { + this._originalProps = props; + + var view = this.view, + needTablePictures = false, + styleInfo = props.asc_getStyleInfo(), + value = styleInfo.asc_getShowRowHeaders(); + if (this._state.RowHeader!==value) { + view.chRowHeader.setValue(value, true); + this._state.RowHeader=value; + needTablePictures = true; + } + + value = styleInfo.asc_getShowColHeaders(); + if (this._state.ColHeader!==value) { + view.chColHeader.setValue(value, true); + this._state.ColHeader=value; + needTablePictures = true; + } + + value = styleInfo.asc_getShowColStripes(); + if (this._state.ColBanded!==value) { + view.chColBanded.setValue(value, true); + this._state.ColBanded=value; + needTablePictures = true; + } + + value = styleInfo.asc_getShowRowStripes(); + if (this._state.RowBanded!==value) { + view.chRowBanded.setValue(value, true); + this._state.RowBanded=value; + needTablePictures = true; + } + + value = props.asc_getColGrandTotals(); + if (this._state.ColGrandTotals!==value) { + this._state.ColGrandTotals=value; + needTablePictures = true; + } + + value = props.asc_getRowGrandTotals(); + if (this._state.RowGrandTotals!==value) { + this._state.RowGrandTotals=value; + needTablePictures = true; + } + + if (needTablePictures) + this.onApiInitPivotStyles(this.api.asc_getTablePictures(this._originalProps, true)); + + //for table-template + value = styleInfo.asc_getName(); + if (this._state.TemplateName!==value || this._isTemplatesChanged) { + view.pivotStyles.suspendEvents(); + var rec = view.pivotStyles.menuPicker.store.findWhere({ + name: value + }); + view.pivotStyles.menuPicker.selectRecord(rec); + view.pivotStyles.resumeEvents(); + + if (this._isTemplatesChanged) { + if (rec) + view.pivotStyles.fillComboView(view.pivotStyles.menuPicker.getSelectedRec()[0],true); + else + view.pivotStyles.fillComboView(view.pivotStyles.menuPicker.store.at(0), true); + } + this._state.TemplateName=value; + } + this._isTemplatesChanged = false; + } + }, + + onSendThemeColors: function() { + // get new table templates + if (this.view.pivotStyles && this._originalProps) { + this.onApiInitPivotStyles(this.api.asc_getTablePictures(this._originalProps, true)); + this.view.pivotStyles.menuPicker.scroller.update({alwaysVisibleY: true}); + } + }, + + onApiInitPivotStyles: function(Templates){ + var self = this, + styles = this.view.pivotStyles; + this._isTemplatesChanged = true; + + var count = styles.menuPicker.store.length; + if (count>0 && count==Templates.length) { + var data = styles.menuPicker.store.models; + _.each(Templates, function(template, index){ + data[index].set('imageUrl', template.asc_getImage()); + }); + } else { + styles.menuPicker.store.reset([]); + var arr = []; + _.each(Templates, function(template){ + arr.push({ + id : Common.UI.getId(), + name : template.asc_getName(), + caption : template.asc_getDisplayName(), + type : template.asc_getType(), + imageUrl : template.asc_getImage(), + allowSelected : true, + selected : false, + tip : template.asc_getDisplayName() + }); + }); + styles.menuPicker.store.add(arr); + } + }, + + onSelectionChanged: function(info) { + if (this.rangeSelectionMode || !this.appConfig.isEdit) return; + + var selectType = info.asc_getFlags().asc_getSelectionType(), + pivotInfo = info.asc_getPivotTableInfo(); + + var need_disable = info.asc_getLocked(); + + this.view.SetDisabled(!pivotInfo); + if (pivotInfo) + this.ChangeSettings(pivotInfo); + }, + + createToolbarPanel: function() { + return this.view.getPanel(); + }, + + getView: function(name) { + return !name && this.view ? + this.view : Backbone.Controller.prototype.getView.call(this, name); + }, + + onAppReady: function (config) { + var me = this; + (new Promise(function (resolve) { + resolve(); + })).then(function () { + }); + } + + }, SSE.Controllers.PivotTable || {})); +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/controller/RightMenu.js b/apps/spreadsheeteditor/main/app/controller/RightMenu.js index 85af0e8a4..e6724c6e4 100644 --- a/apps/spreadsheeteditor/main/app/controller/RightMenu.js +++ b/apps/spreadsheeteditor/main/app/controller/RightMenu.js @@ -85,10 +85,13 @@ define([ this._settings[Common.Utils.documentSettingsType.TextArt] = {panelId: "id-textart-settings", panel: rightMenu.textartSettings, btn: rightMenu.btnTextArt, hidden: 1, locked: false}; this._settings[Common.Utils.documentSettingsType.Chart] = {panelId: "id-chart-settings", panel: rightMenu.chartSettings, btn: rightMenu.btnChart, hidden: 1, locked: false}; this._settings[Common.Utils.documentSettingsType.Table] = {panelId: "id-table-settings", panel: rightMenu.tableSettings, btn: rightMenu.btnTable, hidden: 1, locked: false}; + this._settings[Common.Utils.documentSettingsType.Pivot] = {panelId: "id-pivot-settings", panel: rightMenu.pivotSettings, btn: rightMenu.btnPivot, hidden: 1, locked: false}; + this._settings[Common.Utils.documentSettingsType.Signature] = {panelId: "id-signature-settings", panel: rightMenu.signatureSettings, btn: rightMenu.btnSignature, hidden: 1, props: {}, locked: false}; }, setApi: function(api) { this.api = api; + this.api.asc_registerCallback('asc_onUpdateSignatures', _.bind(this.onApiUpdateSignatures, this)); this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.onCoAuthoringDisconnect, this)); Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); Common.NotificationCenter.on('cells:range', _.bind(this.onCellsRange, this)); @@ -103,7 +106,7 @@ define([ var panel = this._settings[type].panel; var props = this._settings[type].props; if (props && panel) - panel.ChangeSettings.call(panel, props); + panel.ChangeSettings.call(panel, (type==Common.Utils.documentSettingsType.Signature) ? undefined : props); } Common.NotificationCenter.trigger('layout:changed', 'rightmenu'); }, @@ -114,35 +117,39 @@ define([ var SelectedObjects = [], selectType = info.asc_getFlags().asc_getSelectionType(), formatTableInfo = info.asc_getFormatTableInfo(), - sparkLineInfo = info.asc_getSparklineInfo(); + sparkLineInfo = info.asc_getSparklineInfo(), + pivotInfo = info.asc_getPivotTableInfo(); if (selectType == Asc.c_oAscSelectionType.RangeImage || selectType == Asc.c_oAscSelectionType.RangeShape || selectType == Asc.c_oAscSelectionType.RangeChart || selectType == Asc.c_oAscSelectionType.RangeChartText || selectType == Asc.c_oAscSelectionType.RangeShapeText) { SelectedObjects = this.api.asc_getGraphicObjectProps(); } - if (SelectedObjects.length<=0 && !formatTableInfo && !sparkLineInfo && !this.rightmenu.minimizedMode) { + if (SelectedObjects.length<=0 && !formatTableInfo && !sparkLineInfo && !pivotInfo && !this.rightmenu.minimizedMode && + this.rightmenu.GetActivePane() !== 'id-signature-settings') { this.rightmenu.clearSelection(); this._openRightMenu = true; } var need_disable = info.asc_getLocked(), - need_disable_table = (info.asc_getLockedTable()===true), + need_disable_table = (info.asc_getLockedTable()===true || !this.rightmenu.mode.canModifyFilter), need_disable_spark = (info.asc_getLockedSparkline()===true); - this.onFocusObject(SelectedObjects, formatTableInfo, sparkLineInfo, need_disable, need_disable_table, need_disable_spark); + this.onFocusObject(SelectedObjects, formatTableInfo, sparkLineInfo, pivotInfo, need_disable, need_disable_table, need_disable_spark); }, - onFocusObject: function(SelectedObjects, formatTableInfo, sparkLineInfo, isCellLocked, isTableLocked, isSparkLocked) { + onFocusObject: function(SelectedObjects, formatTableInfo, sparkLineInfo, pivotInfo, isCellLocked, isTableLocked, isSparkLocked) { if (!this.editMode) return; for (var i=0; i -1) { @@ -2041,6 +2047,11 @@ define([ need_disable = !!info.asc_getPivotTableInfo(); toolbar.lockToolbar(SSE.enumLock.editPivot, need_disable, { array: [toolbar.btnMerge, toolbar.btnInsertHyperlink, toolbar.btnSetAutofilter, toolbar.btnClearAutofilter, toolbar.btnSortDown, toolbar.btnSortUp, toolbar.btnAutofilter]}); + + need_disable = !this.appConfig.canModifyFilter; + toolbar.lockToolbar(SSE.enumLock.cantModifyFilter, need_disable, { array: [toolbar.btnSortDown, toolbar.btnSortUp, toolbar.mnuitemSortAZ, toolbar.mnuitemSortZA, toolbar.btnSetAutofilter, + toolbar.btnAutofilter, toolbar.btnTableTemplate, toolbar.btnClearStyle.menu.items[0], toolbar.btnClearStyle.menu.items[2] ]}); + } val = info.asc_getNumFormatInfo(); @@ -2064,7 +2075,7 @@ define([ } else val = info.asc_getAngle(); if (this._state.angle !== val) { - this._clearChecked(toolbar.btnTextOrient.menu); + toolbar.btnTextOrient.menu.clearAll(); switch(val) { case 45: toolbar.btnTextOrient.menu.items[1].setChecked(true, true); break; case -45: toolbar.btnTextOrient.menu.items[2].setChecked(true, true); break; @@ -2742,13 +2753,6 @@ define([ return cellInfo ? cellInfo.asc_getFont().asc_getSize() : 12; }, - _clearChecked: function(menu) { - _.each(menu.items, function(item){ - if (item.setChecked) - item.setChecked(false, true); - }); - }, - _setTableFormat: function(fmtname) { var me = this; @@ -2868,7 +2872,10 @@ define([ this._state.namedrange_locked = (state == Asc.c_oAscDefinedNameReason.LockDefNameManager); }, - DisableToolbar: function(disable) { + DisableToolbar: function(disable, viewMode) { + if (viewMode!==undefined) this.editMode = !viewMode; + disable = disable || !this.editMode; + var mask = $('.toolbar-mask'); if (disable && mask.length>0 || !disable && mask.length==0) return; @@ -2913,8 +2920,30 @@ define([ Common.Utils.asyncCall(function () { me.toolbar.setMode(config); - if ( config.isEdit ) + if ( config.isEdit ) { me.toolbar.setApi(me.api); + + if ( !config.isEditDiagram && !config.isEditMailMerge ) { + var tab = {action: 'pivot', caption: me.textPivot}; + var $panel = me.getApplication().getController('PivotTable').createToolbarPanel(); + if ( $panel ) { + me.toolbar.addTab(tab, $panel, 3); + me.toolbar.setVisible('pivot', true); + } + + tab = {action: 'review', caption: me.toolbar.textTabCollaboration}; + $panel = me.getApplication().getController('Common.Controllers.ReviewChanges').createToolbarPanel(); + if ( $panel ) + me.toolbar.addTab(tab, $panel, 4); + + if (config.isDesktopApp && config.isOffline) { + tab = {action: 'protect', caption: me.toolbar.textTabProtect}; + var $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel(); + if ( $panel ) + me.toolbar.addTab(tab, $panel, 5); + } + } + } }); }, @@ -3318,7 +3347,8 @@ define([ warnLongOperation: 'The operation you are about to perform might take rather much time to complete.
    Are you sure you want to continue?', txtInvalidRange: 'ERROR! Invalid cells range', errorMaxRows: 'ERROR! The maximum number of data series per chart is 255.', - errorStockChart: 'Incorrect row order. To build a stock chart place the data on the sheet in the following order:
    opening price, max price, min price, closing price.' + errorStockChart: 'Incorrect row order. To build a stock chart place the data on the sheet in the following order:
    opening price, max price, min price, closing price.', + textPivot: 'Pivot Table' }, SSE.Controllers.Toolbar || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/template/FieldSettingsDialog.template b/apps/spreadsheeteditor/main/app/template/FieldSettingsDialog.template new file mode 100644 index 000000000..d9c5bcb3f --- /dev/null +++ b/apps/spreadsheeteditor/main/app/template/FieldSettingsDialog.template @@ -0,0 +1,134 @@ +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    diff --git a/apps/spreadsheeteditor/main/app/template/FileMenu.template b/apps/spreadsheeteditor/main/app/template/FileMenu.template index 53e645328..5565d15e9 100644 --- a/apps/spreadsheeteditor/main/app/template/FileMenu.template +++ b/apps/spreadsheeteditor/main/app/template/FileMenu.template @@ -8,6 +8,7 @@
  • +
  • @@ -29,4 +30,5 @@
    +
    \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/template/PivotSettings.template b/apps/spreadsheeteditor/main/app/template/PivotSettings.template new file mode 100644 index 000000000..975e84675 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/template/PivotSettings.template @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/template/PivotSettingsAdvanced.template b/apps/spreadsheeteditor/main/app/template/PivotSettingsAdvanced.template new file mode 100644 index 000000000..ffc7f6aa1 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/template/PivotSettingsAdvanced.template @@ -0,0 +1,100 @@ +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + + + + + + +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + + + + + + + + +
    + +
    +
    + + +
    + +
    +
    +
    \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/template/RightMenu.template b/apps/spreadsheeteditor/main/app/template/RightMenu.template index 1f7d9abf6..475b9af91 100644 --- a/apps/spreadsheeteditor/main/app/template/RightMenu.template +++ b/apps/spreadsheeteditor/main/app/template/RightMenu.template @@ -12,6 +12,10 @@
    +
    +
    +
    +
    @@ -21,5 +25,7 @@ + +
    \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/template/SignatureSettings.template b/apps/spreadsheeteditor/main/app/template/SignatureSettings.template new file mode 100644 index 000000000..c4ee01174 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/template/SignatureSettings.template @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/DocumentHolder.js b/apps/spreadsheeteditor/main/app/view/DocumentHolder.js index 000161939..02ea139ef 100644 --- a/apps/spreadsheeteditor/main/app/view/DocumentHolder.js +++ b/apps/spreadsheeteditor/main/app/view/DocumentHolder.js @@ -107,11 +107,22 @@ define([ caption: me.txtAddComment }); + me.menuSignatureViewSign = new Common.UI.MenuItem({caption: this.strSign, value: 0 }); + me.menuSignatureDetails = new Common.UI.MenuItem({caption: this.strDetails, value: 1 }); + me.menuSignatureViewSetup = new Common.UI.MenuItem({caption: this.strSetup, value: 2 }); + me.menuSignatureRemove = new Common.UI.MenuItem({caption: this.strDelete, value: 3 }); + me.menuViewSignSeparator = new Common.UI.MenuItem({caption: '--' }); + this.viewModeMenu = new Common.UI.Menu({ items: [ me.menuViewCopy, me.menuViewUndo, me.menuViewCopySeparator, + me.menuSignatureViewSign, + me.menuSignatureDetails, + me.menuSignatureViewSetup, + me.menuSignatureRemove, + me.menuViewSignSeparator, me.menuViewAddComment ] }); @@ -474,12 +485,19 @@ define([ value : 'paste' }); + me.menuSignatureEditSign = new Common.UI.MenuItem({caption: this.strSign, value: 0 }); + me.menuSignatureEditSetup = new Common.UI.MenuItem({caption: this.strSetup, value: 2 }); + me.menuEditSignSeparator = new Common.UI.MenuItem({ caption: '--' }); + this.imgMenu = new Common.UI.Menu({ items: [ me.pmiImgCut, me.pmiImgCopy, me.pmiImgPaste, {caption: '--'}, + me.menuSignatureEditSign, + me.menuSignatureEditSetup, + me.menuEditSignSeparator, { caption : this.textArrangeFront, iconCls : 'mnu-arrange-front', @@ -788,7 +806,11 @@ define([ advancedImgText: 'Image Advanced Settings', textNone: 'None', bulletsText: 'Bullets and Numbering', - textUndo: 'Undo' + textUndo: 'Undo', + strSign: 'Sign', + strDetails: 'Signature Details', + strSetup: 'Signature Setup', + strDelete: 'Remove Signature' }, SSE.Views.DocumentHolder || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/FieldSettingsDialog.js b/apps/spreadsheeteditor/main/app/view/FieldSettingsDialog.js new file mode 100644 index 000000000..95783eedb --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/FieldSettingsDialog.js @@ -0,0 +1,331 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * FieldSettingsDialog.js + * + * Created by Julia Radzhabova on 17.07.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ 'text!spreadsheeteditor/main/app/template/FieldSettingsDialog.template', + 'common/main/lib/util/utils', + 'common/main/lib/component/InputField', + 'common/main/lib/component/ComboBox', + 'common/main/lib/component/CheckBox', + 'common/main/lib/view/AdvancedSettingsWindow' +], function (contentTemplate) { 'use strict'; + + SSE.Views.FieldSettingsDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({ + options: { + contentWidth: 284, + height: 440, + toggleGroup: 'pivot-field-settings-group', + storageName: 'sse-pivot-field-settings-category' + }, + + initialize : function(options) { + var me = this; + + _.extend(this.options, { + title: this.textTitle, + items: [ + {panelId: 'id-pivot-field-settings-layout', panelCaption: this.strLayout}, + {panelId: 'id-pivot-field-settings-subtotals', panelCaption: this.strSubtotals} + ], + contentTemplate: _.template(contentTemplate)({ + scope: this + }) + }, options); + + this.api = options.api; + this.handler = options.handler; + this.props = options.props; + this.fieldIndex = options.fieldIndex || 0; + this.names = options.names || []; + this.type = options.type || 0; // 0 - columns, 1 - rows, 3 - filters + + Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.Views.AdvancedSettingsWindow.prototype.render.call(this); + var me = this; + + this.inputCustomName = new Common.UI.InputField({ + el : $('#field-settings-custom'), + allowBlank : true, + validateOnBlur: false, + style : 'width: 100%;' + }); + + this.lblSourceName = this.$window.find('#field-settings-source'); + + this.radioTabular = new Common.UI.RadioBox({ + el: $('#field-settings-radio-tab'), + labelText: this.txtTabular, + name: 'asc-radio-report-form' + }); + + this.radioOutline = new Common.UI.RadioBox({ + el: $('#field-settings-radio-outline'), + labelText: this.txtOutline, + name: 'asc-radio-report-form', + checked: true + }); + + this.chCompact = new Common.UI.CheckBox({ + el: $('#field-settings-chk-compact'), + labelText: this.txtCompact + }); + + this.chRepeat = new Common.UI.CheckBox({ + el: $('#field-settings-chk-repeat'), + labelText: this.txtRepeat + }); + + this.chBlank = new Common.UI.CheckBox({ + el: $('#field-settings-chk-blank'), + labelText: this.txtBlank + }); + + this.chSubtotals = new Common.UI.CheckBox({ + el: $('#field-settings-chk-subtotals'), + labelText: this.txtShowSubtotals + }); + + this.radioTop = new Common.UI.RadioBox({ + el: $('#field-settings-radio-top'), + labelText: this.txtTop, + name: 'asc-radio-show-subtotals' + }); + + this.radioBottom = new Common.UI.RadioBox({ + el: $('#field-settings-radio-bottom'), + labelText: this.txtBottom, + name: 'asc-radio-show-subtotals', + checked: true + }); + + this.chEmpty = new Common.UI.CheckBox({ + el: $('#field-settings-chk-empty'), + labelText: this.txtEmpty + }); + + this.chSum = new Common.UI.CheckBox({ + el: $('#field-settings-chk-sum'), + labelText: this.txtSum + }); + // this.chSum.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Sum)); + + this.chCount = new Common.UI.CheckBox({ + el: $('#field-settings-chk-count'), + labelText: this.txtCount + }); + // this.chCount.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Count)); + + this.chAve = new Common.UI.CheckBox({ + el: $('#field-settings-chk-ave'), + labelText: this.txtAverage + }); + // this.chAve.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Average)); + + this.chMax = new Common.UI.CheckBox({ + el: $('#field-settings-chk-max'), + labelText: this.txtMax + }); + // this.chMax.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Max)); + + this.chMin = new Common.UI.CheckBox({ + el: $('#field-settings-chk-min'), + labelText: this.txtMin + }); + // this.chMin.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Min)); + + this.chProduct = new Common.UI.CheckBox({ + el: $('#field-settings-chk-product'), + labelText: this.txtProduct + }); + // this.chProduct.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Product)); + + this.chNum = new Common.UI.CheckBox({ + el: $('#field-settings-chk-num'), + labelText: this.txtCountNums + }); + // this.chNum.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.CountNums)); + + this.chDev = new Common.UI.CheckBox({ + el: $('#field-settings-chk-dev'), + labelText: this.txtStdDev + }); + // this.chDev.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.StdDev)); + + this.chDevp = new Common.UI.CheckBox({ + el: $('#field-settings-chk-devp'), + labelText: this.txtStdDevp + }); + // this.chDevp.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.StdDevp)); + + this.chVar = new Common.UI.CheckBox({ + el: $('#field-settings-chk-var'), + labelText: this.txtVar + }); + // this.chVar.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Var)); + + this.chVarp = new Common.UI.CheckBox({ + el: $('#field-settings-chk-varp'), + labelText: this.txtVarp + }); + // this.chVarp.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Varp)); + + this.afterRender(); + }, + + afterRender: function() { + this._setDefaults(this.props); + if (this.storageName) { + var value = Common.localStorage.getItem(this.storageName); + this.setActiveCategory((value!==null) ? parseInt(value) : 0); + } + }, + + show: function() { + Common.Views.AdvancedSettingsWindow.prototype.show.apply(this, arguments); + }, + + _setDefaults: function (props) { + if (props) { + var me = this, + cache_names = props.asc_getCacheFields(), + field = props.asc_getPivotFields()[this.fieldIndex]; + + this.lblSourceName.html(Common.Utils.String.htmlEncode(cache_names[this.fieldIndex].asc_getName())); + this.inputCustomName.setValue(Common.Utils.String.htmlEncode((field || cache_names[this.fieldIndex]).asc_getName())); + + (field.asc_getSubtotalTop()) ? this.radioTop.setValue(true) : this.radioBottom.setValue(true); + + var arr = field.asc_getSubtotals(); + if (arr) { + _.each(arr, function(item) { + switch(item) { + case Asc.c_oAscItemType.Sum: + me.chSum.setValue(true); + break; + case Asc.c_oAscItemType.Count: + me.chCount.setValue(true); + break; + case Asc.c_oAscItemType.Avg: + me.chAve.setValue(true); + break; + case Asc.c_oAscItemType.Max: + me.chMax.setValue(true); + break; + case Asc.c_oAscItemType.Min: + me.chMin.setValue(true); + break; + case Asc.c_oAscItemType.Product: + me.chProduct.setValue(true); + break; + case Asc.c_oAscItemType.CountA: + me.chNum.setValue(true); + break; + case Asc.c_oAscItemType.StdDev: + me.chDev.setValue(true); + break; + case Asc.c_oAscItemType.StdDevP: + me.chDevp.setValue(true); + break; + case Asc.c_oAscItemType.Var: + me.chVar.setValue(true); + break; + case Asc.c_oAscItemType.VarP: + me.chVarp.setValue(true); + break; + } + }); + } + } + }, + + getSettings: function () { + return {}; + }, + + onDlgBtnClick: function(event) { + var me = this; + var state = (typeof(event) == 'object') ? event.currentTarget.attributes['result'].value : event; + if (state == 'ok') { + this.handler && this.handler.call(this, state, (state == 'ok') ? this.getSettings() : undefined); + } + + this.close(); + }, + + onPrimary: function() { + this.onDlgBtnClick('ok'); + return false; + }, + + textTitle: 'Field Settings', + textCancel: 'Cancel', + textOk: 'OK', + strSubtotals: 'Subtotals', + strLayout: 'Layout', + txtSourceName: 'Source name: ', + txtCustomName: 'Custom name', + textReport: 'Report Form', + txtTabular: 'Tabular', + txtOutline: 'Outline', + txtCompact: 'Compact', + txtRepeat: 'Repeat items labels at each row', + txtBlank: 'Insert blank rows after each item', + txtShowSubtotals: 'Show subtotals', + txtTop: 'Show at top of group', + txtBottom: 'Show at bottom of group', + txtEmpty: 'Show items with no data', + txtSummarize: 'Functions for Subtotals', + txtAverage: 'Average', + txtCount: 'Count', + txtCountNums: 'Count Numbers', + txtMax: 'Max', + txtMin: 'Min', + txtProduct: 'Product', + txtStdDev: 'StdDev', + txtStdDevp: 'StdDevp', + txtSum: 'Sum', + txtVar: 'Var', + txtVarp: 'Varp' + + }, SSE.Views.FieldSettingsDialog || {})) +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/FileMenu.js b/apps/spreadsheeteditor/main/app/view/FileMenu.js index f1067ae56..b0ab91eff 100644 --- a/apps/spreadsheeteditor/main/app/view/FileMenu.js +++ b/apps/spreadsheeteditor/main/app/view/FileMenu.js @@ -116,6 +116,13 @@ define([ canFocused: false }); + this.miProtect = new Common.UI.MenuItem({ + el : $('#fm-btn-protect',this.el), + action : 'protect', + caption : this.btnProtectCaption, + canFocused: false + }); + this.miRecent = new Common.UI.MenuItem({ el : $('#fm-btn-recent',this.el), action : 'recent', @@ -158,6 +165,7 @@ define([ this.miSaveAs, this.miPrint, this.miRename, + this.miProtect, this.miRecent, this.miNew, new Common.UI.MenuItem({ @@ -199,10 +207,12 @@ define([ show: function(panel) { if (this.isVisible() && panel===undefined) return; + var defPanel = (this.mode.canDownload && (!this.mode.isDesktopApp || !this.mode.isOffline)) ? 'saveas' : 'info'; if (!panel) - panel = this.active || ((this.mode.canDownload && (!this.mode.isDesktopApp || !this.mode.isOffline)) ? 'saveas' : 'info'); + panel = this.active || defPanel; this.$el.show(); - this.selectMenu(panel); + this.selectMenu(panel, defPanel); + this.api.asc_enableKeyEvents(false); this.fireEvent('menu:show', [this]); @@ -217,7 +227,8 @@ define([ applyMode: function() { this.miPrint[this.mode.canPrint?'show':'hide'](); this.miRename[(this.mode.canRename && !this.mode.isDesktopApp) ?'show':'hide'](); - this.miRename.$el.find('+.devider')[!this.mode.isDisconnected?'show':'hide'](); + this.miProtect[(this.mode.isEdit && this.mode.isDesktopApp && this.mode.isOffline) ?'show':'hide'](); + this.miProtect.$el.find('+.devider')[!this.mode.isDisconnected?'show':'hide'](); this.miRecent[this.mode.canOpenRecent?'show':'hide'](); this.miNew[this.mode.canCreateNew?'show':'hide'](); this.miNew.$el.find('+.devider')[this.mode.canCreateNew?'show':'hide'](); @@ -255,6 +266,11 @@ define([ } } + if (this.mode.isDesktopApp && this.mode.isOffline) { + this.panels['protect'] = (new SSE.Views.FileMenuPanels.ProtectDoc({menu:this})).render(); + this.panels['protect'].setMode(this.mode); + } + this.panels['help'].setLangConfig(this.mode.lang); }, @@ -276,6 +292,7 @@ define([ setApi: function(api) { this.api = api; if (this.panels['opts']) this.panels['opts'].setApi(api); + if (this.panels['protect']) this.panels['protect'].setApi(api); this.api.asc_registerCallback('asc_onDocumentName', _.bind(this.onDocumentName, this)); }, @@ -283,10 +300,14 @@ define([ this.document = data.doc; }, - selectMenu: function(menu) { + selectMenu: function(menu, defMenu) { if ( menu ) { - var item = this._getMenuItem(menu), + var item = this._getMenuItem(menu), panel = this.panels[menu]; + if ( item.isDisabled() ) { + item = this._getMenuItem(defMenu); + panel = this.panels[defMenu]; + } if ( item && panel ) { $('.fm-btn',this.el).removeClass('active'); item.$el.addClass('active'); @@ -333,6 +354,7 @@ define([ btnSettingsCaption : 'Advanced Settings...', btnSaveAsCaption : 'Save as', btnRenameCaption : 'Rename...', - btnCloseMenuCaption : 'Close Menu' + btnCloseMenuCaption : 'Close Menu', + btnProtectCaption: 'Protect\\Sign' }, SSE.Views.FileMenu || {})); }); diff --git a/apps/spreadsheeteditor/main/app/view/FileMenuPanels.js b/apps/spreadsheeteditor/main/app/view/FileMenuPanels.js index 8f765ea10..4fb0ea83b 100644 --- a/apps/spreadsheeteditor/main/app/view/FileMenuPanels.js +++ b/apps/spreadsheeteditor/main/app/view/FileMenuPanels.js @@ -696,54 +696,40 @@ define([ }, updateSettings: function() { - var value = Common.localStorage.getItem("sse-settings-zoom"); + var value = Common.Utils.InternalSettings.get("sse-settings-zoom"); value = (value!==null) ? parseInt(value) : (this.mode.customization && this.mode.customization.zoom ? parseInt(this.mode.customization.zoom) : 100); var item = this.cmbZoom.store.findWhere({value: value}); this.cmbZoom.setValue(item ? parseInt(item.get('value')) : (value>0 ? value+'%' : 100)); /** coauthoring begin **/ - value = Common.localStorage.getItem("sse-settings-livecomment"); - this.chLiveComment.setValue(!(value!==null && parseInt(value) == 0)); + this.chLiveComment.setValue(Common.Utils.InternalSettings.get("sse-settings-livecomment")); + this.chResolvedComment.setValue(Common.Utils.InternalSettings.get("sse-settings-resolvedcomment")); - value = Common.localStorage.getItem("sse-settings-resolvedcomment"); - this.chResolvedComment.setValue(!(value!==null && parseInt(value) == 0)); - - value = Common.localStorage.getItem("sse-settings-coauthmode"); - if (value===null && Common.localStorage.getItem("sse-settings-autosave")===null && - this.mode.customization && this.mode.customization.autosave===false) - value = 0; // use customization.autosave only when sse-settings-coauthmode and sse-settings-autosave are null - var fast_coauth = (value===null || parseInt(value) == 1) && !(this.mode.isDesktopApp && this.mode.isOffline) && this.mode.canCoAuthoring; - - item = this.cmbCoAuthMode.store.findWhere({value: parseInt(value)}); + var fast_coauth = Common.Utils.InternalSettings.get("sse-settings-coauthmode"); + item = this.cmbCoAuthMode.store.findWhere({value: fast_coauth ? 1 : 0}); this.cmbCoAuthMode.setValue(item ? item.get('value') : 1); this.lblCoAuthMode.text(item ? item.get('descValue') : this.strCoAuthModeDescFast); /** coauthoring end **/ - value = Common.localStorage.getItem("sse-settings-fontrender"); - Common.Utils.isChrome && this.chInputSogou.setValue(Common.localStorage.getBool("sse-settings-inputsogou")); + Common.Utils.isChrome && this.chInputSogou.setValue(Common.Utils.InternalSettings.get("sse-settings-inputsogou")); + value = Common.Utils.InternalSettings.get("sse-settings-fontrender"); item = this.cmbFontRender.store.findWhere({value: parseInt(value)}); this.cmbFontRender.setValue(item ? item.get('value') : (window.devicePixelRatio > 1 ? Asc.c_oAscFontRenderingModeType.noHinting : Asc.c_oAscFontRenderingModeType.hintingAndSubpixeling)); - value = Common.localStorage.getItem("sse-settings-unit"); - item = this.cmbUnit.store.findWhere({value: parseInt(value)}); + value = Common.Utils.InternalSettings.get("sse-settings-unit"); + item = this.cmbUnit.store.findWhere({value: value}); this.cmbUnit.setValue(item ? parseInt(item.get('value')) : Common.Utils.Metric.getDefaultMetric()); this._oldUnits = this.cmbUnit.getValue(); - value = Common.localStorage.getItem("sse-settings-autosave"); - if (value===null && this.mode.customization && this.mode.customization.autosave===false) - value = 0; - this.chAutosave.setValue(fast_coauth || (value===null ? this.mode.canCoAuthoring : parseInt(value) == 1)); + value = Common.Utils.InternalSettings.get("sse-settings-autosave"); + this.chAutosave.setValue(value == 1); if (this.mode.canForcesave) { - value = Common.localStorage.getItem("sse-settings-forcesave"); - value = (value === null) ? this.mode.canForcesave : (parseInt(value) == 1); - this.chForcesave.setValue(value); + this.chForcesave.setValue(Common.Utils.InternalSettings.get("sse-settings-forcesave")); } - value = Common.localStorage.getItem("sse-settings-func-locale"); - if (value===null) - value = ((this.mode.lang) ? this.mode.lang : 'en').toLowerCase(); + value = Common.Utils.InternalSettings.get("sse-settings-func-locale"); item = this.cmbFuncLocale.store.findWhere({value: value}); if (!item) item = this.cmbFuncLocale.store.findWhere({value: value.split("-")[0]}); @@ -764,6 +750,7 @@ define([ applySettings: function() { Common.localStorage.setItem("sse-settings-zoom", this.cmbZoom.getValue()); + Common.Utils.InternalSettings.set("sse-settings-zoom", Common.localStorage.getItem("sse-settings-zoom")); /** coauthoring begin **/ Common.localStorage.setItem("sse-settings-livecomment", this.chLiveComment.isChecked() ? 1 : 0); Common.localStorage.setItem("sse-settings-resolvedcomment", this.chResolvedComment.isChecked() ? 1 : 0); @@ -1132,6 +1119,8 @@ define([ }); } + Common.NotificationCenter.on('collaboration:sharing', _.bind(this.changeAccessRights, this)); + return this; }, @@ -1333,4 +1322,174 @@ define([ } } }); + + SSE.Views.FileMenuPanels.ProtectDoc = Common.UI.BaseView.extend(_.extend({ + el: '#panel-protect', + menu: undefined, + + template: _.template([ + '', + '
    ', + '', + '
    ', + '', + '', + '', + '', + '', + '', + '', + '', + '
    <%= scope.txtEncrypted %>
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ' + ].join('')), + + initialize: function(options) { + Common.UI.BaseView.prototype.initialize.call(this,arguments); + + this.menu = options.menu; + + var me = this; + this.templateSignature = _.template([ + '', + '', + '', + '', + '', + '', + '', + '', + '
    <%= tipText %>
    ' + ].join('')); + }, + + render: function() { + $(this.el).html(this.template({scope: this})); + + var protection = SSE.getController('Common.Controllers.Protection').getView(); + + this.btnAddPwd = protection.getButton('add-password'); + this.btnAddPwd.render(this.$el.find('#fms-btn-add-pwd')); + this.btnAddPwd.on('click', _.bind(this.closeMenu, this)); + + this.btnChangePwd = protection.getButton('change-password'); + this.btnChangePwd.render(this.$el.find('#fms-btn-change-pwd')); + this.btnChangePwd.on('click', _.bind(this.closeMenu, this)); + + this.btnDeletePwd = protection.getButton('del-password'); + this.btnDeletePwd.render(this.$el.find('#fms-btn-delete-pwd')); + this.btnDeletePwd.on('click', _.bind(this.closeMenu, this)); + + this.cntPassword = $('#id-fms-view-pwd'); + + this.btnAddInvisibleSign = protection.getButton('signature'); + this.btnAddInvisibleSign.render(this.$el.find('#fms-btn-invisible-sign')); + this.btnAddInvisibleSign.on('click', _.bind(this.closeMenu, this)); + + this.cntSignature = $('#id-fms-signature'); + this.cntSignatureView = $('#id-fms-signature-view'); + if (_.isUndefined(this.scroller)) { + this.scroller = new Common.UI.Scroller({ + el: $(this.el), + suppressScrollX: true + }); + } + + this.$el.on('click', '.signature-edit-link', _.bind(this.onEdit, this)); + this.$el.on('click', '.signature-view-link', _.bind(this.onView, this)); + + return this; + }, + + show: function() { + Common.UI.BaseView.prototype.show.call(this,arguments); + this.updateSignatures(); + this.updateEncrypt(); + }, + + setMode: function(mode) { + this.mode = mode; + this.cntSignature.toggleClass('hidden', !this.mode.canProtect); + }, + + setApi: function(o) { + this.api = o; + return this; + }, + + closeMenu: function() { + this.menu && this.menu.hide(); + }, + + onEdit: function() { + this.menu && this.menu.hide(); + + var me = this; + Common.UI.warning({ + title: this.notcriticalErrorTitle, + msg: this.txtEditWarning, + buttons: ['ok', 'cancel'], + primary: 'ok', + callback: function(btn) { + if (btn == 'ok') { + me.api.asc_RemoveAllSignatures(); + } + } + }); + + }, + + onView: function() { + this.menu && this.menu.hide(); + SSE.getController('RightMenu').rightmenu.SetActivePane(Common.Utils.documentSettingsType.Signature, true); + }, + + updateSignatures: function(){ + var requested = this.api.asc_getRequestSignatures(), + valid = this.api.asc_getSignatures(), + hasRequested = requested && requested.length>0, + hasValid = false, + hasInvalid = false; + + _.each(valid, function(item, index){ + if (item.asc_getValid()==0) + hasValid = true; + else + hasInvalid = true; + }); + + // hasRequested = true; + // hasValid = true; + // hasInvalid = true; + + var tipText = (hasInvalid) ? this.txtSignedInvalid : (hasValid ? this.txtSigned : ""); + if (hasRequested) + tipText = this.txtRequestedSignatures + (tipText!="" ? "

    " : "")+ tipText; + + this.cntSignatureView.html(this.templateSignature({tipText: tipText, hasSigned: (hasValid || hasInvalid), hasRequested: hasRequested})); + }, + + updateEncrypt: function() { + this.cntPassword.toggleClass('hidden', this.btnAddPwd.isVisible()); + }, + + strProtect: 'Protect Workbook', + strSignature: 'Signature', + txtView: 'View signatures', + txtEdit: 'Edit workbook', + txtSigned: 'Valid signatures has been added to the workbook. The workbook is protected from editing.', + txtSignedInvalid: 'Some of the digital signatures in workbook are invalid or could not be verified. The workbook is protected from editing.', + txtRequestedSignatures: 'This workbook needs to be signed.', + notcriticalErrorTitle: 'Warning', + txtEditWarning: 'Editing will remove the signatures from the workbook.
    Are you sure you want to continue?', + strEncrypt: 'Password', + txtEncrypted: 'This workbook has been protected by password' + + }, SSE.Views.FileMenuPanels.ProtectDoc || {})); + }); diff --git a/apps/spreadsheeteditor/main/app/view/FormatSettingsDialog.js b/apps/spreadsheeteditor/main/app/view/FormatSettingsDialog.js index 08a583996..326dfc60c 100644 --- a/apps/spreadsheeteditor/main/app/view/FormatSettingsDialog.js +++ b/apps/spreadsheeteditor/main/app/view/FormatSettingsDialog.js @@ -417,7 +417,7 @@ define([ me = this, valDecimal = (initFormatInfo) ? initFormatInfo.asc_getDecimalPlaces() : this.spnDecimal.getNumberValue(), valSeparator = (initFormatInfo) ? initFormatInfo.asc_getSeparator() : (this.chSeparator.getValue()=='checked'), - valSymbol = (initFormatInfo && initFormatInfo.asc_getSymbol()) ? initFormatInfo.asc_getSymbol() : this.langId; + valSymbol = (initFormatInfo) ? initFormatInfo.asc_getSymbol() : this.langId; if (record.value !== Asc.c_oAscNumFormatType.Custom) { var info = new Asc.asc_CFormatCellsInfo(); @@ -428,7 +428,7 @@ define([ if (hasNegative || record.value == Asc.c_oAscNumFormatType.Date || record.value == Asc.c_oAscNumFormatType.Time) { if (hasSymbols) { if (!me.CurrencySymbolsData) { - me.CurrencySymbolsData = []; + me.CurrencySymbolsData = [{value: null, displayValue: me.txtNone}]; var symbolssarr = this.api.asc_getCurrencySymbols(); for (var code in symbolssarr) { if (symbolssarr.hasOwnProperty(code)) { @@ -523,7 +523,8 @@ define([ txtAs16: 'As sixteenths (8/16)', txtAs10: 'As tenths (5/10)', txtAs100: 'As hundredths (50/100)', - txtSample: 'Sample:' + txtSample: 'Sample:', + txtNone: 'None' }, SSE.Views.FormatSettingsDialog || {})) }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/FormulaDialog.js b/apps/spreadsheeteditor/main/app/view/FormulaDialog.js index 9707f4923..b16393f11 100644 --- a/apps/spreadsheeteditor/main/app/view/FormulaDialog.js +++ b/apps/spreadsheeteditor/main/app/view/FormulaDialog.js @@ -228,7 +228,7 @@ define([ fillFormulasGroups: function () { if (this.formulasGroups) { - var lang = Common.localStorage.getItem("sse-settings-func-locale"); + var lang = Common.Utils.InternalSettings.get("sse-settings-func-locale"); if (_.isEmpty(lang)) lang = 'en'; var i, groupsListItems = [], length = this.formulasGroups.length; diff --git a/apps/spreadsheeteditor/main/app/view/ImageSettings.js b/apps/spreadsheeteditor/main/app/view/ImageSettings.js index 4360b6004..80a86944a 100644 --- a/apps/spreadsheeteditor/main/app/view/ImageSettings.js +++ b/apps/spreadsheeteditor/main/app/view/ImageSettings.js @@ -181,8 +181,11 @@ define([ this.spnHeight.on('change', _.bind(this.onHeightChange, this)); this.btnOriginalSize.on('click', _.bind(this.setOriginalSize, this)); this.btnInsertFromFile.on('click', _.bind(function(btn){ + if (this._isFromFile) return; + this._isFromFile = true; if (this.api) this.api.asc_changeImageFromFile(); Common.NotificationCenter.trigger('edit:complete', this); + this._isFromFile = false; }, this)); this.btnEditObject.on('click', _.bind(function(btn){ if (this.api) this.api.asc_startEditCurrentOleObject(); diff --git a/apps/spreadsheeteditor/main/app/view/LeftMenu.js b/apps/spreadsheeteditor/main/app/view/LeftMenu.js index ab0df1673..116ddb2d3 100644 --- a/apps/spreadsheeteditor/main/app/view/LeftMenu.js +++ b/apps/spreadsheeteditor/main/app/view/LeftMenu.js @@ -255,7 +255,7 @@ define([ } if (this.mode.canChat) { this.panelChat['hide'](); - this.btnChat.toggle(false, true); + this.btnChat.toggle(false); } } /** coauthoring end **/ diff --git a/apps/spreadsheeteditor/main/app/view/NamedRangeEditDlg.js b/apps/spreadsheeteditor/main/app/view/NamedRangeEditDlg.js index 270d43ad9..bce1411dc 100644 --- a/apps/spreadsheeteditor/main/app/view/NamedRangeEditDlg.js +++ b/apps/spreadsheeteditor/main/app/view/NamedRangeEditDlg.js @@ -303,9 +303,8 @@ define([ }, onRefreshDefNameList: function(name) { - var value = Common.localStorage.getItem("sse-settings-coauthmode"), - me = this; - if (this.isEdit && (value===null || parseInt(value) == 1)) { // fast co-editing + var me = this; + if (this.isEdit && Common.Utils.InternalSettings.get("sse-settings-coauthmode")) { // fast co-editing if (name && name.asc_getIsLock() && name.asc_getName().toLowerCase() == this.props.asc_getName().toLowerCase() && (name.asc_getScope() === null && this.props.asc_getScope() === null || name.asc_getScope().toLowerCase() == this.props.asc_getScope().toLowerCase()) && !this._listRefreshed) { this._listRefreshed = true; diff --git a/apps/spreadsheeteditor/main/app/view/PivotSettings.js b/apps/spreadsheeteditor/main/app/view/PivotSettings.js new file mode 100644 index 000000000..afb1cca3d --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/PivotSettings.js @@ -0,0 +1,673 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * PivotSettings.js + * + * Created by Julia Radzhabova on 7/10/17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'text!spreadsheeteditor/main/app/template/PivotSettings.template', + 'jquery', + 'underscore', + 'backbone', + 'common/main/lib/component/Button', + 'common/main/lib/component/ListView', + 'spreadsheeteditor/main/app/view/FieldSettingsDialog', + 'spreadsheeteditor/main/app/view/ValueFieldSettingsDialog', + 'spreadsheeteditor/main/app/view/PivotSettingsAdvanced' +], function (menuTemplate, $, _, Backbone, Sortable) { + 'use strict'; + + SSE.Views.PivotSettings = Backbone.View.extend(_.extend({ + el: '#id-pivot-settings', + + // Compile our stats template + template: _.template(menuTemplate), + + // Delegated events for creating new items, and clearing completed ones. + events: { + }, + + options: { + alias: 'PivotSettings' + }, + + initialize: function () { + this._initSettings = true; + + this._state = { + names: [], + DisabledControls: false, + field: {} + }; + this.lockedControls = []; + this._locked = false; + + this._originalProps = null; + this._noApply = false; + + this.render(); + }, + + render: function () { + var el = $(this.el); + el.html(this.template({ + scope: this + })); + + this.linkAdvanced = $('#pivot-advanced-link'); + }, + + setApi: function(o) { + this.api = o; + return this; + }, + + createDelayedControls: function() { + var me = this; + this.fieldsList = new Common.UI.ListView({ + el: $('#pivot-list-fields'), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + template: _.template(['
    '].join('')), + itemTemplate: _.template([ + '
    ', + '', + '
    <%= Common.Utils.String.htmlEncode(value) %>
    ', + '
    ', + '
    ' + ].join('')) + }); + this.fieldsList.on('item:click', _.bind(this.onFieldsCheck, this)); + // this.fieldsList.onKeyDown = _.bind(this.onFieldsListKeyDown, this); + this.lockedControls.push(this.fieldsList); + + // Sortable.create(this.fieldsList.$el.find('.listview')[0], {}); + + var itemTemplate = _.template([ + '
    ', + '
    <%= Common.Utils.String.htmlEncode(value) %>
    ', + '
    ', + '
    ' + ].join('')); + this.columnsList = new Common.UI.ListView({ + el: $('#pivot-list-columns'), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + template: _.template(['
    '].join('')), + itemTemplate: itemTemplate + }); + this.columnsList.on('item:click', _.bind(this.onColumnsSelect, this, 0)); + // this.columnsList.onKeyDown = _.bind(this.onColumnsListKeyDown, this); + this.lockedControls.push(this.columnsList); + + this.rowsList = new Common.UI.ListView({ + el: $('#pivot-list-rows'), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + template: _.template(['
    '].join('')), + itemTemplate: itemTemplate + }); + this.rowsList.on('item:click', _.bind(this.onColumnsSelect, this, 1)); + // this.rowsList.onKeyDown = _.bind(this.onRowsListKeyDown, this); + this.lockedControls.push(this.rowsList); + + this.valuesList = new Common.UI.ListView({ + el: $('#pivot-list-values'), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + template: _.template(['
    '].join('')), + itemTemplate: itemTemplate + }); + this.valuesList.on('item:click', _.bind(this.onColumnsSelect, this, 2)); + // this.valuesList.onKeyDown = _.bind(this.onValuesListKeyDown, this); + this.lockedControls.push(this.valuesList); + + this.filtersList = new Common.UI.ListView({ + el: $('#pivot-list-filters'), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + template: _.template(['
    '].join('')), + itemTemplate: itemTemplate + }); + this.filtersList.on('item:click', _.bind(this.onColumnsSelect, this,3)); + // this.filtersList.onKeyDown = _.bind(this.onFiltersListKeyDown, this); + this.lockedControls.push(this.filtersList); + + $(this.el).on('click', '#pivot-advanced-link', _.bind(this.openAdvancedSettings, this)); + + this._initSettings = false; + }, + + openAdvancedSettings: function(e) { + if (this.linkAdvanced.hasClass('disabled')) return; + + var me = this; + var win; + if (me.api && !this._locked){ + (new SSE.Views.PivotSettingsAdvanced( + { + props: me._originalProps, + api: me.api, + handler: function(result, value) { + if (result == 'ok' && me.api && value) { + me._originalProps.asc_set(me.api, value); + } + + Common.NotificationCenter.trigger('edit:complete', me); + } + })).show(); + } + }, + + ChangeSettings: function(props) { + if (this._initSettings) + this.createDelayedControls(); + + this.disableControls(this._locked); // need to update combodataview after disabled state + + if (props )//formatTableInfo + { + this._originalProps = props; + + this._state.TableName=props.asc_getName(); + + var me = this, + cache_names = props.asc_getCacheFields(), + pivot_names = props.asc_getPivotFields(); + + this._state.names = []; + pivot_names.forEach(function (item, index) { + me._state.names[index] = item.asc_getName() || cache_names[index].asc_getName(); + }); + + var arr = [], isChecked = [], + value = props.asc_getColumnFields(); + value && value.forEach(function (item, index) { + var pivotIndex = item.asc_getIndex(); + if (pivotIndex>-1 || pivotIndex == -2) { + var name = (pivotIndex>-1) ? me._state.names[pivotIndex] : me.textValues; + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : false, + pivotIndex : pivotIndex, + index : index, + value : name, + tip : (name.length>10) ? name : '' + })); + isChecked[name] = true; + } + }); + this.columnsList.store.reset(arr); + this.columnsList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + + arr = []; + value = props.asc_getRowFields(); + value && value.forEach(function (item, index) { + var pivotIndex = item.asc_getIndex(); + if (pivotIndex>-1 || pivotIndex == -2) { + var name = (pivotIndex>-1) ? me._state.names[pivotIndex] : me.textValues; + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : false, + pivotIndex : pivotIndex, + index : index, + value : name, + tip : (name.length>10) ? name : '' + })); + isChecked[name] = true; + } + }); + this.rowsList.store.reset(arr); + this.rowsList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + + arr = []; + value = props.asc_getDataFields(); + value && value.forEach(function (item, index) { + var pivotIndex = item.asc_getIndex(); + if (pivotIndex>-1) { + var name = item.asc_getName(); + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : false, + pivotIndex : pivotIndex, + index : index, + value : name, + tip : (name.length>10) ? name : '' + })); + isChecked[me._state.names[pivotIndex]] = true; + } + }); + this.valuesList.store.reset(arr); + this.valuesList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + + arr = []; + value = props.asc_getPageFields(); + value && value.forEach(function (item, index) { + var pivotIndex = item.asc_getIndex(); + if (pivotIndex>-1) { + var name = me._state.names[pivotIndex]; + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : false, + pivotIndex : pivotIndex, + index : index, + value : name, + tip : (name.length>10) ? name : '' + })); + isChecked[name] = true; + } + }); + this.filtersList.store.reset(arr); + this.filtersList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + + arr = []; + me._state.names.forEach(function (item, index) { + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : false, + value : item, + index : index, + tip : (item.length>25) ? item : '', + check : isChecked[item] + })); + }); + this.fieldsList.store.reset(arr); + this.fieldsList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + } + }, + + onFieldsCheck: function (listView, itemView, record) { + if (this.checkCellTrigerBlock) + return; + + var target = '', type = '', isLabel = false, bound = null; + + var event = window.event ? window.event : window._event; + if (event) { + + var btn = $(event.target); + if (btn && btn.hasClass('listitem-icon')) { + this._state.field = {record: record}; + if (this.pivotFieldsMenu) { + if (this.pivotFieldsMenu.isVisible()) { + this.pivotFieldsMenu.hide(); + return; + } + } else { + this.miAddFilter = new Common.UI.MenuItem({ + caption : this.txtAddFilter, + checkable : false + }); + this.miAddFilter.on('click', _.bind(this.onAddFilter, this)); + this.miAddRow = new Common.UI.MenuItem({ + caption : this.txtAddRow, + checkable : false + }); + // this.miAddRow.on('click', _.bind(this.onAddRow, this)); + this.miAddColumn = new Common.UI.MenuItem({ + caption : this.txtAddColumn, + checkable : false + }); + // this.miAddColumn.on('click', _.bind(this.onAddColumn, this)); + this.miAddValues = new Common.UI.MenuItem({ + caption : this.txtAddValues, + checkable : false + }); + // this.miAddValues.on('click', _.bind(this.onAddValues, this)); + + this.pivotFieldsMenu = new Common.UI.Menu({ + menuAlign: 'tr-br', + items: [ + this.miAddFilter, + this.miAddRow, + this.miAddColumn, + this.miAddValues + ] + }); + } + + var recIndex = (record != undefined) ? record.get('index') : -1; + + var menu = this.pivotFieldsMenu, + showPoint, me = this, + currentTarget = $(event.currentTarget), + parent = $(this.el), + offset = currentTarget.offset(), + offsetParent = parent.offset(); + + showPoint = [offset.left - offsetParent.left + currentTarget.width(), offset.top - offsetParent.top + currentTarget.height()/2]; + + var menuContainer = parent.find('#menu-pivot-fields-container'); + if (!menu.rendered) { + if (menuContainer.length < 1) { + menuContainer = $('', menu.id); + parent.append(menuContainer); + } + menu.render(menuContainer); + menu.cmpEl.attr({tabindex: "-1"}); + + menu.on('show:after', function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', true); + }).on('hide:after', function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', false); + }); + } + + menu.menuAlignEl = currentTarget; + menu.setOffset(-20, -currentTarget.height()/2 - 3); + menu.show(); + _.delay(function() { + menu.cmpEl.focus(); + }, 10); + event.stopPropagation(); + event.preventDefault(); + return; + } + + type = event.target.type; + target = $(event.currentTarget).find('.list-item'); + + if (target.length) { + bound = target.get(0).getBoundingClientRect(); + var _clientX = event.clientX*Common.Utils.zoom(), + _clientY = event.clientY*Common.Utils.zoom(); + if (bound.left < _clientX && _clientX < bound.right && + bound.top < _clientY && _clientY < bound.bottom) { + isLabel = true; + } + } + + if (type === 'button' || isLabel) { + this.updateFieldCheck(listView, record); + + _.delay(function () { + listView.$el.find('.listview').focus(); + }, 100, this); + } + } + }, + + updateFieldCheck: function (listView, record) { + if (record && listView) { + listView.isSuspendEvents = true; + + record.set('check', !record.get('check')); + + listView.isSuspendEvents = false; + listView.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + } + }, + + onColumnsSelect: function(type, picker, item, record, e){ + var btn = $(e.target); + if (btn && btn.hasClass('listitem-icon')) { + this._state.field = {record: record, type: type}; + if (this.fieldsMenu) { + if (this.fieldsMenu.isVisible()) { + this.fieldsMenu.hide(); + return; + } + } else { + this.miMoveUp = new Common.UI.MenuItem({ + caption : this.txtMoveUp, + checkable : false + }); + // this.miMoveUp.on('click', _.bind(this.onMoveUp, this)); + this.miMoveDown = new Common.UI.MenuItem({ + caption : this.txtMoveDown, + checkable : false + }); + // this.miMoveDown.on('click', _.bind(this.onMoveDown, this)); + this.miMoveBegin = new Common.UI.MenuItem({ + caption : this.txtMoveBegin, + checkable : false + }); + // this.miMoveBegin.on('click', _.bind(this.onMoveBegin, this)); + this.miMoveEnd = new Common.UI.MenuItem({ + caption : this.txtMoveEnd, + checkable : false + }); + // this.miMoveEnd.on('click', _.bind(this.onMoveEnd, this)); + + this.miMoveFilter = new Common.UI.MenuItem({ + caption : this.txtMoveFilter, + checkable : false + }); + // this.miMoveFilter.on('click', _.bind(this.onMoveFilter, this)); + this.miMoveRow = new Common.UI.MenuItem({ + caption : this.txtMoveRow, + checkable : false + }); + // this.miMoveRow.on('click', _.bind(this.onMoveRow, this)); + this.miMoveColumn = new Common.UI.MenuItem({ + caption : this.txtMoveColumn, + checkable : false + }); + // this.miMoveColumn.on('click', _.bind(this.onMoveColumn, this)); + this.miMoveValues = new Common.UI.MenuItem({ + caption : this.txtMoveValues, + checkable : false + }); + // this.miMoveValues.on('click', _.bind(this.onMoveValues, this)); + + this.miRemove = new Common.UI.MenuItem({ + caption : this.txtRemove, + checkable : false + }); + this.miRemove.on('click', _.bind(this.onRemove, this)); + + this.miFieldSettings = new Common.UI.MenuItem({ + caption : this.txtFieldSettings, + checkable : false + }); + this.miFieldSettings.on('click', _.bind(this.onFieldSettings, this)); + + this.fieldsMenu = new Common.UI.Menu({ + menuAlign: 'tr-br', + items: [ + this.miMoveUp, + this.miMoveDown, + this.miMoveBegin, + this.miMoveEnd, + {caption : '--'}, + this.miMoveFilter, + this.miMoveRow, + this.miMoveColumn, + this.miMoveValues, + {caption : '--'}, + this.miRemove, + {caption : '--'}, + this.miFieldSettings + ] + }); + } + + this.miMoveFilter.setDisabled(type == 3); // menu for filter + this.miMoveRow.setDisabled(type == 1); // menu for row + this.miMoveColumn.setDisabled(type == 0); // menu for column + this.miMoveValues.setDisabled(type == 2); // menu for value + + var recIndex = (record != undefined) ? record.get('index') : -1, + len = picker.store.length; + this.miMoveUp.setDisabled(recIndex<1); + this.miMoveDown.setDisabled(recIndex>len-2 || recIndex<0); + this.miMoveBegin.setDisabled(recIndex<1); + this.miMoveEnd.setDisabled(recIndex>len-2 || recIndex<0); + + this.miFieldSettings.setDisabled(record.get('pivotIndex')==-2); + + var menu = this.fieldsMenu, + showPoint, me = this, + currentTarget = $(e.currentTarget), + parent = $(this.el), + offset = currentTarget.offset(), + offsetParent = parent.offset(); + + showPoint = [offset.left - offsetParent.left + currentTarget.width(), offset.top - offsetParent.top + currentTarget.height()/2]; + + var menuContainer = parent.find('#menu-pivot-container'); + if (!menu.rendered) { + if (menuContainer.length < 1) { + menuContainer = $('', menu.id); + parent.append(menuContainer); + } + menu.render(menuContainer); + menu.cmpEl.attr({tabindex: "-1"}); + + menu.on('show:after', function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', true); + }).on('hide:after', function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', false); + }); + } + + menu.menuAlignEl = currentTarget; + menu.setOffset(-20, -currentTarget.height()/2 - 3); + menu.show(); + _.delay(function() { + menu.cmpEl.focus(); + }, 10); + e.stopPropagation(); + e.preventDefault(); + } + }, + + setLocked: function (locked) { + this._locked = locked; + }, + + onFieldSettings: function(record, type, e) { + var me = this; + var win; + if (me.api && !this._locked && me._state.field){ + if (me._state.field.type == 2) { // value field + var field = me._originalProps.asc_getDataFields()[me._state.field.record.get('index')]; + (new SSE.Views.ValueFieldSettingsDialog( + { + props: me._originalProps, + field: field, + names: me._state.names, + api: me.api, + handler: function(result, value) { + if (result == 'ok' && me.api && value) { + field.asc_set(me.api, me._originalProps, value); + } + + Common.NotificationCenter.trigger('edit:complete', me); + } + })).show(); + } else { + (new SSE.Views.FieldSettingsDialog( + { + props: me._originalProps, + fieldIndex: me._state.field.record.get('pivotIndex'), + names: me._state.names, + api: me.api, + type: me._state.field.type, + handler: function(result, value) { + if (result == 'ok' && me.api && value) { + // me.api.asc_changeFormatTableInfo(me._state.TableName, Asc.c_oAscChangeTableStyleInfo.advancedSettings, value); + } + + Common.NotificationCenter.trigger('edit:complete', me); + } + })).show(); + } + } + }, + + onAddFilter: function() { + if (this.api && !this._locked && this._state.field){ + this._originalProps.asc_addPageField(this.api, this._state.field.record.get('index')); + } + }, + + onRemove: function() { + if (this.api && !this._locked && this._state.field){ + this._originalProps.asc_removeField(this.api, this._state.field.record.get('pivotIndex')); + } + }, + + disableControls: function(disable) { + if (this._initSettings) return; + + if (this._state.DisabledControls!==disable) { + this._state.DisabledControls = disable; + _.each(this.lockedControls, function(item) { + item.setDisabled(disable); + }); + this.linkAdvanced.toggleClass('disabled', disable); + } + }, + + textFields: 'Select Fields', + textOK : 'OK', + textCancel : 'Cancel', + textValues : 'Values', + textRows : 'Rows', + textColumns : 'Columns', + textFilters : 'Filters', + notcriticalErrorTitle : 'Warning', + textAdvanced: 'Show advanced settings', + txtMoveUp: 'Move Up', + txtMoveDown: 'Move Down', + txtMoveBegin: 'Move to Beginning', + txtMoveEnd: 'Move to End', + txtMoveFilter: 'Move to Filters', + txtMoveRow: 'Move to Rows', + txtMoveColumn: 'Move to Columns', + txtMoveValues: 'Move to Values', + txtRemove: 'Remove Field', + txtFieldSettings: 'Field Settings', + txtAddFilter: 'Add to Filters', + txtAddRow: 'Add to Rows', + txtAddColumn: 'Add to Columns', + txtAddValues: 'Add to Values' + + }, SSE.Views.PivotSettings || {})); +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/PivotSettingsAdvanced.js b/apps/spreadsheeteditor/main/app/view/PivotSettingsAdvanced.js new file mode 100644 index 000000000..8bff50b9b --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/PivotSettingsAdvanced.js @@ -0,0 +1,312 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * PivotSettingsAdvanced.js + * + * Created by Julia Radzhabova on 17.07.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ 'text!spreadsheeteditor/main/app/template/PivotSettingsAdvanced.template', + 'common/main/lib/util/utils', + 'common/main/lib/component/InputField', + 'common/main/lib/component/ComboBox', + 'common/main/lib/component/CheckBox', + 'common/main/lib/component/MetricSpinner', + 'common/main/lib/view/AdvancedSettingsWindow' +], function (contentTemplate) { 'use strict'; + + SSE.Views.PivotSettingsAdvanced = Common.Views.AdvancedSettingsWindow.extend(_.extend({ + options: { + contentWidth: 300, + height: 395, + toggleGroup: 'pivot-adv-settings-group', + storageName: 'sse-pivot-adv-settings-category' + }, + + initialize : function(options) { + var me = this; + + _.extend(this.options, { + title: this.textTitle, + items: [ + {panelId: 'id-adv-pivot-layout', panelCaption: this.strLayout}, + {panelId: 'id-adv-pivot-data', panelCaption: this.textDataSource}, + {panelId: 'id-adv-pivot-alttext', panelCaption: this.textAlt} + ], + contentTemplate: _.template(contentTemplate)({ + scope: this + }) + }, options); + + this.api = options.api; + this.handler = options.handler; + this.props = options.props; + + Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.Views.AdvancedSettingsWindow.prototype.render.call(this); + var me = this; + + this.inputName = new Common.UI.InputField({ + el : $('#pivot-adv-name'), + allowBlank : true, + validateOnBlur: false, + style : 'width: 100%;' + }); + + this.radioDown = new Common.UI.RadioBox({ + el: $('#pivot-adv-radio-down'), + labelText: this.textDown, + name: 'asc-radio-display-field', + checked: true + }); + this.radioDown.on('change', _.bind(function(field, newValue, eOpts) { + if (newValue) { + this.lblPageWrap.html(this.textWrapCol); + } + }, this)); + + this.radioOver = new Common.UI.RadioBox({ + el: $('#pivot-adv-radio-over'), + labelText: this.textOver, + name: 'asc-radio-display-field' + }); + this.radioOver.on('change', _.bind(function(field, newValue, eOpts) { + if (newValue) { + this.lblPageWrap.html(this.textWrapRow); + } + }, this)); + + this.chRows = new Common.UI.CheckBox({ + el: $('#pivot-adv-chk-show-rows'), + labelText: this.textShowRows + }); + + this.chCols = new Common.UI.CheckBox({ + el: $('#pivot-adv-chk-show-columns'), + labelText: this.textShowCols + }); + + this.numWrap = new Common.UI.MetricSpinner({ + el: $('#pivot-adv-spin-wrap'), + step: 1, + width: 85, + allowDecimal: false, + defaultUnit : "", + value: '0', + maxValue: 255, + minValue: 0 + }); + + this.lblPageWrap = this.$window.find('#pivot-adv-label-wrap'); + + this.chHeaders = new Common.UI.CheckBox({ + el: $('#pivot-adv-chk-show-headers'), + labelText: this.textShowHeaders + }); + + this.txtDataRange = new Common.UI.InputField({ + el : $('#pivot-adv-txt-range'), + name : 'range', + style : 'width: 100%;', + allowBlank : true, + blankError : this.txtEmpty, + validateOnChange: true + }); + + this.btnSelectData = new Common.UI.Button({ + el: $('#pivot-adv-btn-data') + }); + this.btnSelectData.on('click', _.bind(this.onSelectData, this)); + + // Alt Text + + this.inputAltTitle = new Common.UI.InputField({ + el : $('#pivot-advanced-alt-title'), + allowBlank : true, + validateOnBlur: false, + style : 'width: 100%;' + }).on('changed:after', function() { + me.isAltTitleChanged = true; + }); + + this.textareaAltDescription = this.$window.find('textarea'); + this.textareaAltDescription.keydown(function (event) { + if (event.keyCode == Common.UI.Keys.RETURN) { + event.stopPropagation(); + } + me.isAltDescChanged = true; + }); + + this.afterRender(); + }, + + afterRender: function() { + this._setDefaults(this.props); + if (this.storageName) { + var value = Common.localStorage.getItem(this.storageName); + this.setActiveCategory((value!==null) ? parseInt(value) : 0); + } + }, + + show: function() { + Common.Views.AdvancedSettingsWindow.prototype.show.apply(this, arguments); + }, + + _setDefaults: function (props) { + if (props) { + var me = this; + this.inputName.setValue(Common.Utils.String.htmlEncode(props.asc_getName())); + + this.chCols.setValue(props.asc_getRowGrandTotals(), true); + this.chRows.setValue(props.asc_getColGrandTotals(), true); + + (props.asc_getPageOverThenDown()) ? this.radioOver.setValue(true) : this.radioDown.setValue(true); + this.lblPageWrap.html((props.asc_getPageOverThenDown()) ? this.textWrapRow : this.textWrapCol); + + this.numWrap.setValue(props.asc_getPageWrap()); + + this.chHeaders.setValue(props.asc_getShowHeaders(), true); + + // var value = props.getRange(); + // this.txtDataRange.setValue((value) ? value : ''); + // this.dataRangeValid = value; + + this.txtDataRange.validation = function(value) { + // var isvalid = me.api.asc_checkDataRange(Asc.c_oAscSelectionDialogType.Pivot, value, false); + // return (isvalid==Asc.c_oAscError.ID.DataRangeError) ? me.textInvalidRange : true; + return true; + }; + } + }, + + getSettings: function () { + var props = new Asc.CT_pivotTableDefinition(); + props.asc_setRowGrandTotals(this.chCols.getValue() == 'checked'); + props.asc_setColGrandTotals(this.chRows.getValue() == 'checked'); + + return props; + }, + + onDlgBtnClick: function(event) { + var me = this; + var state = (typeof(event) == 'object') ? event.currentTarget.attributes['result'].value : event; + if (state == 'ok' && this.isRangeValid()) { + this.handler && this.handler.call(this, state, (state == 'ok') ? this.getSettings() : undefined); + } + + this.close(); + }, + + onPrimary: function() { + this.onDlgBtnClick('ok'); + return false; + }, + + isRangeValid: function() { + if (this.isChart) { + var isvalid; + if (!_.isEmpty(this.txtDataRange.getValue())) { + isvalid = this.api.asc_checkDataRange(Asc.c_oAscSelectionDialogType.Pivot, this.txtDataRange.getValue()); + if (isvalid == Asc.c_oAscError.ID.No) + return true; + } else + this.txtDataRange.showError([this.txtEmpty]); + + this.setActiveCategory(1); + this.txtDataRange.cmpEl.find('input').focus(); + return false; + } else + return true; + }, + + onSelectData: function() { + var me = this; + if (me.api) { + var handlerDlg = function(dlg, result) { + if (result == 'ok') { + me.dataRangeValid = dlg.getSettings(); + me.txtDataRange.setValue(me.dataRangeValid); + me.txtDataRange.checkValidate(); + } + }; + + var win = new SSE.Views.CellRangeDialog({ + handler: handlerDlg + }).on('close', function() { + me.show(); + }); + + var xy = me.$window.offset(); + me.hide(); + win.show(xy.left + 160, xy.top + 125); + win.setSettings({ + api : me.api, + range : (!_.isEmpty(me.txtDataRange.getValue()) && (me.txtDataRange.checkValidate()==true)) ? me.txtDataRange.getValue() : me.dataRangeValid, + type : Asc.c_oAscSelectionDialogType.Pivot + }); + } + }, + + textTitle: 'Pivot Table - Advanced Settings', + textCancel: 'Cancel', + textOk: 'OK', + strLayout: 'Name and Layout', + txtName: 'Name', + textGrandTotals: 'Grand Totals', + textShowRows: 'Show for rows', + textShowCols: 'Show for columns', + textDataSource: 'Data Source', + textDataRange: 'Data Range', + textSelectData: 'Select Data', + textAlt: 'Alternative Text', + textAltTitle: 'Title', + textAltDescription: 'Description', + textAltTip: 'The alternative text-based representation of the visual object information, which will be read to the people with vision or cognitive impairments to help them better understand what information there is in the image, autoshape, chart or table.', + txtEmpty: 'This field is required', + textInvalidRange: 'ERROR! Invalid cells range', + textDisplayFields: 'Display fields in report filter area', + textDown: 'Down, then over', + textOver: 'Over, then down', + textWrapCol: 'Report filter fields per column', + textWrapRow: 'Report filter fields per row', + textHeaders: 'Field Headers', + textShowHeaders: 'Show field headers for rows and columns' + + }, SSE.Views.PivotSettingsAdvanced || {})) +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/PivotTable.js b/apps/spreadsheeteditor/main/app/view/PivotTable.js new file mode 100644 index 000000000..62459e5e3 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/PivotTable.js @@ -0,0 +1,347 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * PivotTable.js + * + * View + * + * Created by Julia.Radzhabova on 06.27.17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + // 'text!spreadsheeteditor/main/app/template/PivotTableSettings.template', + 'common/main/lib/util/utils', + 'common/main/lib/component/Button', + 'common/main/lib/component/ComboDataView', + 'common/main/lib/component/Layout' +], function (menuTemplate) { + 'use strict'; + + SSE.Views.PivotTable = Common.UI.BaseView.extend(_.extend((function(){ + var template = + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + + '
    ' + + '' + + '' + + '' + + '' + + '
    ' + + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    '; + + function setEvents() { + var me = this; + + this.btnAddPivot.on('click', function (e) { + me.fireEvent('pivottable:create'); + }); + + this.btnPivotLayout.menu.on('item:click', function (menu, item, e) { + me.fireEvent('pivottable:layout', [item.value]); + }); + + this.btnPivotBlankRows.menu.on('item:click', function (menu, item, e) { + me.fireEvent('pivottable:blankrows', [item.value]); + }); + + this.btnPivotSubtotals.menu.on('item:click', function (menu, item, e) { + me.fireEvent('pivottable:subtotals', [item.value]); + }); + + this.btnPivotGrandTotals.menu.on('item:click', function (menu, item, e) { + me.fireEvent('pivottable:grandtotals', [item.value]); + }); + + this.btnRefreshPivot.on('click', function (e) { + me.fireEvent('pivottable:refresh'); + }); + + this.chRowHeader.on('change', function (field, value) { + me.fireEvent('pivottable:rowscolumns', [0, value]); + }); + this.chColHeader.on('change', function (field, value) { + me.fireEvent('pivottable:rowscolumns', [1, value]); + }); + this.chRowBanded.on('change', function (field, value) { + me.fireEvent('pivottable:rowscolumns', [2, value]); + }); + this.chColBanded.on('change', function (field, value) { + me.fireEvent('pivottable:rowscolumns', [3, value]); + }); + + this.pivotStyles.on('click', function (combo, record) { + me.fireEvent('pivottable:style', [record]); + }); + this.pivotStyles.openButton.menu.on('show:after', function () { + me.pivotStyles.menuPicker.scroller.update({alwaysVisibleY: true}); + }); + } + + return { + options: {}, + + initialize: function (options) { + Common.UI.BaseView.prototype.initialize.call(this, options); + + this.appConfig = options.mode; + this.lockedControls = []; + + this.chRowHeader = new Common.UI.CheckBox({ + labelText: this.textRowHeader + }); + this.lockedControls.push(this.chRowHeader); + + this.chColHeader = new Common.UI.CheckBox({ + labelText: this.textColHeader + }); + this.lockedControls.push(this.chColHeader); + + this.chRowBanded = new Common.UI.CheckBox({ + labelText: this.textRowBanded + }); + this.lockedControls.push(this.chRowBanded); + + this.chColBanded = new Common.UI.CheckBox({ + labelText: this.textColBanded + }); + this.lockedControls.push(this.chColBanded); + + this.btnAddPivot = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-docspell', + caption: this.txtCreate, + disabled : true + }); + // this.lockedControls.push(this.btnAddPivot); + + this.btnPivotLayout = new Common.UI.Button({ + cls : 'btn-toolbar x-huge icon-top', + iconCls : 'btn-insertimage', + caption : this.capLayout, + disabled : true, + menu : new Common.UI.Menu({ + items: [ + { caption: this.mniLayoutCompact, value: 0 }, + { caption: this.mniLayoutOutline, value: 1 }, + { caption: this.mniLayoutTabular, value: 2 }, + { caption: '--' }, + { caption: this.mniLayoutRepeat, value: 3 }, + { caption: this.mniLayoutNoRepeat, value: 4 } + ] + }) + }); + // this.lockedControls.push(this.btnPivotLayout); // remove commentings after enabled option + + this.btnPivotBlankRows = new Common.UI.Button({ + cls : 'btn-toolbar x-huge icon-top', + iconCls : 'btn-insertimage', + caption : this.capBlankRows, + disabled : true, + menu : new Common.UI.Menu({ + items: [ + { caption: this.mniInsertBlankLine, value: 'insert' }, + { caption: this.mniRemoveBlankLine, value: 'remove' } + ] + }) + }); + // this.lockedControls.push(this.btnPivotBlankRows); // remove commentings after enabled option + + this.btnPivotSubtotals = new Common.UI.Button({ + cls : 'btn-toolbar x-huge icon-top', + iconCls : 'btn-insertimage', + caption : this.capSubtotals, + disabled : true, + menu : new Common.UI.Menu({ + items: [ + { caption: this.mniNoSubtotals, value: 0 }, + { caption: this.mniBottomSubtotals, value: 1 }, + { caption: this.mniTopSubtotals, value: 2 } + ] + }) + }); + // this.lockedControls.push(this.btnPivotSubtotals); // remove commentings after enabled option + + this.btnPivotGrandTotals = new Common.UI.Button({ + cls : 'btn-toolbar x-huge icon-top', + iconCls : 'btn-insertimage', + caption : this.capGrandTotals, + disabled : true, + menu : new Common.UI.Menu({ + items: [ + { caption: this.mniOffTotals, value: 0 }, + { caption: this.mniOnTotals, value: 1 }, + { caption: this.mniOnRowsTotals, value: 2 }, + { caption: this.mniOnColumnsTotals, value: 3 } + ] + }) + }); + // this.lockedControls.push(this.btnPivotGrandTotals); // remove commentings after enabled option + + this.btnRefreshPivot = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-docspell', + caption: this.txtRefresh, + disabled : true + }); + // this.lockedControls.push(this.btnRefreshPivot); + + this.pivotStyles = new Common.UI.ComboDataView({ + cls : 'combo-pivot-template', + enableKeyEvents : true, + itemWidth : 61, + itemHeight : 49, + menuMaxHeight : 300 + // lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth] + }); + this.lockedControls.push(this.pivotStyles); + + Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); + }, + + render: function (el) { + this.boxSdk = $('#editor_sdk'); + if ( el ) el.html( this.getPanel() ); + + return this; + }, + + onAppReady: function (config) { + var me = this; + (new Promise(function (accept, reject) { + accept(); + })).then(function(){ + me.btnAddPivot.updateHint(me.tipCreatePivot); + me.btnRefreshPivot.updateHint(me.tipRefresh); + me.btnPivotLayout.updateHint(me.capLayout); + me.btnPivotBlankRows.updateHint(me.capBlankRows); + me.btnPivotSubtotals.updateHint(me.tipSubtotals); + me.btnPivotGrandTotals.updateHint(me.tipGrandTotals); + + setEvents.call(me); + }); + }, + + getPanel: function () { + this.$el = $(_.template(template)( {} )); + + this.chRowHeader.render(this.$el.find('#slot-chk-header-row')); + this.chColHeader.render(this.$el.find('#slot-chk-header-column')); + this.chRowBanded.render(this.$el.find('#slot-chk-banded-row')); + this.chColBanded.render(this.$el.find('#slot-chk-banded-column')); + + this.btnAddPivot.render(this.$el.find('#slot-btn-add-pivot')); + this.btnRefreshPivot.render(this.$el.find('#slot-btn-refresh-pivot')); + this.btnPivotLayout.render(this.$el.find('#slot-btn-pivot-report-layout')); + this.btnPivotBlankRows.render(this.$el.find('#slot-btn-pivot-blank-rows')); + this.btnPivotSubtotals.render(this.$el.find('#slot-btn-pivot-subtotals')); + this.btnPivotGrandTotals.render(this.$el.find('#slot-btn-pivot-grand-totals')); + this.pivotStyles.render(this.$el.find('#slot-field-pivot-styles')); + + return this.$el; + }, + + show: function () { + Common.UI.BaseView.prototype.show.call(this); + this.fireEvent('show', this); + }, + + getButton: function(type, parent) { + }, + + SetDisabled: function (state) { + this.lockedControls && this.lockedControls.forEach(function(button) { + if ( button ) { + button.setDisabled(state); + } + }, this); + }, + + txtCreate: 'Insert Table', + tipCreatePivot: 'Insert Pivot Table', + textRowHeader: 'Row Headers', + textColHeader: 'Column Headers', + textRowBanded: 'Banded Rows', + textColBanded: 'Banded Columns', + capBlankRows: 'Blank Rows', + mniInsertBlankLine: 'Insert Blank Line after Each Item', + mniRemoveBlankLine: 'Remove Blank Line after Each Item', + capGrandTotals: 'Grand Totals', + mniOffTotals: 'Off for Rows and Columns', + mniOnTotals: 'On for Rows and Columns', + mniOnRowsTotals: 'On for Rows Only', + mniOnColumnsTotals: 'On for Columns Only', + capLayout: 'Report Layout', + capSubtotals: 'Subtotals', + mniLayoutCompact: 'Show in Compact Form', + mniLayoutOutline: 'Show in Outline Form', + mniLayoutTabular: 'Show in Tabular Form', + mniLayoutRepeat: 'Repeat All Item Labels', + mniLayoutNoRepeat: 'Don\'t Repeat All Item Labels', + mniNoSubtotals: 'Don\'t Show Subtotals', + mniBottomSubtotals: 'Show all Subtotals at Bottom of Group', + mniTopSubtotals: 'Show all Subtotals at Top of Group', + txtRefresh: 'Refresh', + tipRefresh: 'Update the information from data source', + tipGrandTotals: 'Show or hide grand totals', + tipSubtotals: 'Show or hide subtotals' + } + }()), SSE.Views.PivotTable || {})); +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/RightMenu.js b/apps/spreadsheeteditor/main/app/view/RightMenu.js index c685e418a..c9855b6cb 100644 --- a/apps/spreadsheeteditor/main/app/view/RightMenu.js +++ b/apps/spreadsheeteditor/main/app/view/RightMenu.js @@ -55,6 +55,8 @@ define([ 'spreadsheeteditor/main/app/view/ShapeSettings', 'spreadsheeteditor/main/app/view/TextArtSettings', 'spreadsheeteditor/main/app/view/TableSettings', + 'spreadsheeteditor/main/app/view/PivotSettings', + 'spreadsheeteditor/main/app/view/SignatureSettings', 'common/main/lib/component/Scroller' ], function (menuTemplate, $, _, Backbone) { 'use strict'; @@ -123,6 +125,15 @@ define([ allowMouseEventsOnDisabled: true }); + this.btnPivot = new Common.UI.Button({ + hint: this.txtPivotSettings, + asctype: Common.Utils.documentSettingsType.Pivot, + enableToggle: true, + disabled: true, + toggleGroup: 'tabpanelbtnsGroup', + allowMouseEventsOnDisabled: true + }); + this._settings = []; this._settings[Common.Utils.documentSettingsType.Paragraph] = {panel: "id-paragraph-settings", btn: this.btnText}; this._settings[Common.Utils.documentSettingsType.Image] = {panel: "id-image-settings", btn: this.btnImage}; @@ -130,11 +141,12 @@ define([ this._settings[Common.Utils.documentSettingsType.Chart] = {panel: "id-chart-settings", btn: this.btnChart}; this._settings[Common.Utils.documentSettingsType.TextArt] = {panel: "id-textart-settings", btn: this.btnTextArt}; this._settings[Common.Utils.documentSettingsType.Table] = {panel: "id-table-settings", btn: this.btnTable}; + this._settings[Common.Utils.documentSettingsType.Pivot] = {panel: "id-pivot-settings", btn: this.btnPivot}; return this; }, - render: function () { + render: function (mode) { var el = $(this.el); this.trigger('render:before', this); @@ -151,6 +163,7 @@ define([ this.btnShape.setElement($('#id-right-menu-shape'), false); this.btnShape.render(); this.btnTextArt.setElement($('#id-right-menu-textart'), false); this.btnTextArt.render(); this.btnTable.setElement($('#id-right-menu-table'), false); this.btnTable.render(); + this.btnPivot.setElement($('#id-right-menu-pivot'), false); this.btnPivot.render(); this.btnText.on('click', _.bind(this.onBtnMenuClick, this)); this.btnImage.on('click', _.bind(this.onBtnMenuClick, this)); @@ -158,6 +171,7 @@ define([ this.btnShape.on('click', _.bind(this.onBtnMenuClick, this)); this.btnTextArt.on('click', _.bind(this.onBtnMenuClick, this)); this.btnTable.on('click', _.bind(this.onBtnMenuClick, this)); + this.btnPivot.on('click', _.bind(this.onBtnMenuClick, this)); this.paragraphSettings = new SSE.Views.ParagraphSettings(); this.imageSettings = new SSE.Views.ImageSettings(); @@ -165,6 +179,22 @@ define([ this.shapeSettings = new SSE.Views.ShapeSettings(); this.textartSettings = new SSE.Views.TextArtSettings(); this.tableSettings = new SSE.Views.TableSettings(); + this.pivotSettings = new SSE.Views.PivotSettings(); + + if (mode && mode.canProtect) { + this.btnSignature = new Common.UI.Button({ + hint: this.txtSignatureSettings, + asctype: Common.Utils.documentSettingsType.Signature, + enableToggle: true, + disabled: true, + toggleGroup: 'tabpanelbtnsGroup' + }); + this._settings[Common.Utils.documentSettingsType.Signature] = {panel: "id-signature-settings", btn: this.btnSignature}; + + this.btnSignature.el = $('#id-right-menu-signature'); this.btnSignature.render().setVisible(true); + this.btnSignature.on('click', _.bind(this.onBtnMenuClick, this)); + this.signatureSettings = new SSE.Views.SignatureSettings(); + } if (_.isUndefined(this.scroller)) { this.scroller = new Common.UI.Scroller({ @@ -187,11 +217,13 @@ define([ this.shapeSettings.setApi(api); this.textartSettings.setApi(api); this.tableSettings.setApi(api); - + this.pivotSettings.setApi(api); + if (this.signatureSettings) this.signatureSettings.setApi(api); return this; }, setMode: function(mode) { + this.mode = mode; return this; }, @@ -264,6 +296,8 @@ define([ txtTextArtSettings: 'Text Art Settings', txtChartSettings: 'Chart Settings', txtSparklineSettings: 'Sparkline Settings', - txtTableSettings: 'Table Settings' + txtTableSettings: 'Table Settings', + txtPivotSettings: 'Pivot Table Settings', + txtSignatureSettings: 'Signature Settings' }, SSE.Views.RightMenu || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/ShapeSettings.js b/apps/spreadsheeteditor/main/app/view/ShapeSettings.js index b6aa676e4..ed33ce59f 100644 --- a/apps/spreadsheeteditor/main/app/view/ShapeSettings.js +++ b/apps/spreadsheeteditor/main/app/view/ShapeSettings.js @@ -916,7 +916,8 @@ define([ // border colors var stroke = shapeprops.asc_getStroke(), strokeType = stroke.asc_getType(), - borderType; + borderType, + update = (this._state.StrokeColor == 'transparent' && this.BorderColor.Color !== 'transparent'); // border color was changed for shape without line and then shape was reselected (or apply other settings) if (stroke) { if ( strokeType == Asc.c_oAscStrokeType.STROKE_COLOR ) { @@ -942,7 +943,7 @@ define([ type1 = typeof(this.BorderColor.Color); type2 = typeof(this._state.StrokeColor); - if ( (type1 !== type2) || (type1=='object' && + if ( update || (type1 !== type2) || (type1=='object' && (this.BorderColor.Color.effectValue!==this._state.StrokeColor.effectValue || this._state.StrokeColor.color.indexOf(this.BorderColor.Color.color)<0)) || (type1!='object' && (this._state.StrokeColor.indexOf(this.BorderColor.Color)<0 || typeof(this.btnBorderColor.color)=='object'))) { @@ -1138,7 +1139,7 @@ define([ this.fillControls.push(this.btnInsertFromUrl); this.btnInsertFromFile.on('click', _.bind(function(btn){ - if (this.api) this.api.asc_changeShapeImageFromFile(); + if (this.api) this.api.asc_changeShapeImageFromFile(this.BlipFillType); Common.NotificationCenter.trigger('edit:complete', this); }, this)); this.btnInsertFromUrl.on('click', _.bind(this.insertFromUrl, this)); diff --git a/apps/spreadsheeteditor/main/app/view/SignatureSettings.js b/apps/spreadsheeteditor/main/app/view/SignatureSettings.js new file mode 100644 index 000000000..7618382e3 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/SignatureSettings.js @@ -0,0 +1,387 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * SignatureSettings.js + * + * Created by Julia Radzhabova on 5/24/17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'text!spreadsheeteditor/main/app/template/SignatureSettings.template', + 'jquery', + 'underscore', + 'backbone', + 'common/main/lib/component/Button' +], function (menuTemplate, $, _, Backbone) { + 'use strict'; + + SSE.Views.SignatureSettings = Backbone.View.extend(_.extend({ + el: '#id-signature-settings', + + // Compile our stats template + template: _.template(menuTemplate), + + // Delegated events for creating new items, and clearing completed ones. + events: { + }, + + options: { + alias: 'SignatureSettings' + }, + + initialize: function () { + this._state = { + DisabledEditing: false, + ready: false, + hasValid: false, + hasInvalid: false, + hasRequested: false, + tip: undefined + }; + this._locked = false; + + this.render(); + }, + + render: function () { + this.$el.html(this.template({ + scope: this + })); + + var protection = SSE.getController('Common.Controllers.Protection').getView(); + this.btnAddInvisibleSign = protection.getButton('signature'); + this.btnAddInvisibleSign.render(this.$el.find('#signature-invisible-sign')); + + this.viewRequestedList = new Common.UI.DataView({ + el: $('#signature-requested-sign'), + enableKeyEvents: false, + itemTemplate: _.template([ + '
    ', + '
    ', + '
    <%= Common.Utils.String.htmlEncode(name) %>
    ', + '
    ' + ].join('')) + }); + + this.viewValidList = new Common.UI.DataView({ + el: $('#signature-valid-sign'), + enableKeyEvents: false, + itemTemplate: _.template([ + '
    ', + '
    ' + 'nomargin' + '<% } %>">
    ', + '
    <%= Common.Utils.String.htmlEncode(name) %>
    ', + '
    <%= Common.Utils.String.htmlEncode(date) %>
    ', + '
    ' + ].join('')) + }); + + this.viewInvalidList = new Common.UI.DataView({ + el: $('#signature-invalid-sign'), + enableKeyEvents: false, + itemTemplate: _.template([ + '
    ', + '
    ' + 'nomargin' + '<% } %>">
    ', + '
    <%= Common.Utils.String.htmlEncode(name) %>
    ', + '
    <%= Common.Utils.String.htmlEncode(date) %>
    ', + '
    ' + ].join('')) + }); + + this.viewRequestedList.on('item:click', _.bind(this.onSelectSignature, this)); + this.viewValidList.on('item:click', _.bind(this.onSelectSignature, this)); + this.viewInvalidList.on('item:click', _.bind(this.onSelectSignature, this)); + + this.signatureMenu = new Common.UI.Menu({ + menuAlign : 'tr-br', + items: [ + { caption: this.strSign, value: 0 }, + { caption: this.strDetails,value: 1 }, + { caption: this.strSetup, value: 2 }, + { caption: this.strDelete, value: 3 } + ] + }); + this.signatureMenu.on('item:click', _.bind(this.onMenuSignatureClick, this)); + }, + + setApi: function(api) { + this.api = api; + if (this.api) { + this.api.asc_registerCallback('asc_onUpdateSignatures', _.bind(this.onApiUpdateSignatures, this)); + } + Common.NotificationCenter.on('document:ready', _.bind(this.onDocumentReady, this)); + return this; + }, + + ChangeSettings: function(props) { + if (!this._state.hasRequested && !this._state.hasValid && !this._state.hasInvalid) + this.updateSignatures(this.api.asc_getSignatures(), this.api.asc_getRequestSignatures()); + }, + + setLocked: function (locked) { + this._locked = locked; + }, + + setMode: function(mode) { + this.mode = mode; + }, + + onApiUpdateSignatures: function(valid, requested){ + if (!this._state.ready) return; + + this.updateSignatures(valid, requested); + this.showSignatureTooltip(this._state.hasValid, this._state.hasInvalid); + }, + + updateSignatures: function(valid, requested){ + var me = this, + requestedSignatures = [], + validSignatures = [], + invalidSignatures = []; + + _.each(requested, function(item, index){ + requestedSignatures.push({name: item.asc_getSigner1(), guid: item.asc_getGuid(), requested: true}); + }); + _.each(valid, function(item, index){ + var item_date = item.asc_getDate(); + var sign = {name: item.asc_getSigner1(), certificateId: item.asc_getId(), guid: item.asc_getGuid(), date: (!_.isEmpty(item_date)) ? new Date(item_date).toLocaleString() : '', invisible: !item.asc_getVisible()}; + (item.asc_getValid()==0) ? validSignatures.push(sign) : invalidSignatures.push(sign); + }); + + // requestedSignatures = [{name: 'Hammish Mitchell', guid: '123', requested: true}, {name: 'Someone Somewhere', guid: '123', requested: true}, {name: 'Mary White', guid: '123', requested: true}, {name: 'John Black', guid: '123', requested: true}]; + // validSignatures = [{name: 'Hammish Mitchell', guid: '123', date: '18/05/2017', invisible: true}, {name: 'Someone Somewhere', guid: '345', date: '18/05/2017'}]; + // invalidSignatures = [{name: 'Mary White', guid: '111', date: '18/05/2017'}, {name: 'John Black', guid: '456', date: '18/05/2017'}]; + + me._state.hasValid = validSignatures.length>0; + me._state.hasInvalid = invalidSignatures.length>0; + me._state.hasRequested = requestedSignatures.length>0; + + this.viewRequestedList.store.reset(requestedSignatures); + this.viewValidList.store.reset(validSignatures); + this.viewInvalidList.store.reset(invalidSignatures); + + this.$el.find('.requested').toggleClass('hidden', !me._state.hasRequested); + this.$el.find('.valid').toggleClass('hidden', !me._state.hasValid); + this.$el.find('.invalid').toggleClass('hidden', !me._state.hasInvalid); + + me.disableEditing(me._state.hasValid || me._state.hasInvalid); + }, + + onSelectSignature: function(picker, item, record, e){ + if (!record) return; + + var btn = $(e.target); + if (btn && btn.hasClass('caret')) { + var menu = this.signatureMenu; + if (menu.isVisible()) { + menu.hide(); + return; + } + + var showPoint, me = this, + currentTarget = $(e.currentTarget), + parent = $(this.el), + offset = currentTarget.offset(), + offsetParent = parent.offset(); + + showPoint = [offset.left - offsetParent.left + currentTarget.width(), offset.top - offsetParent.top + currentTarget.height()/2]; + + var menuContainer = parent.find('#menu-signature-container'); + if (!menu.rendered) { + if (menuContainer.length < 1) { + menuContainer = $('', menu.id); + parent.append(menuContainer); + } + menu.render(menuContainer); + menu.cmpEl.attr({tabindex: "-1"}); + + menu.on({ + 'show:after': function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', true); + }, + 'hide:after': function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', false); + } + }); + } + var requested = record.get('requested'), + signed = (this._state.hasValid || this._state.hasInvalid); + menu.items[0].setVisible(requested); + menu.items[1].setVisible(!requested); + menu.items[2].setVisible(requested || !record.get('invisible')); + menu.items[3].setVisible(!requested); + + menu.items[0].setDisabled(this._locked); + menu.items[3].setDisabled(this._locked); + + menu.items[1].cmpEl.attr('data-value', record.get('certificateId')); // view certificate + menu.items[2].cmpEl.attr('data-value', signed ? 1 : 0); // view or edit signature settings + menu.cmpEl.attr('data-value', record.get('guid')); + + menuContainer.css({left: showPoint[0], top: showPoint[1]}); + + menu.menuAlignEl = currentTarget; + menu.setOffset(-20, -currentTarget.height()/2 + 3); + menu.show(); + _.delay(function() { + menu.cmpEl.focus(); + }, 10); + e.stopPropagation(); + e.preventDefault(); + } else { + this.api.asc_gotoSignature(record.get('guid')); + } + }, + + onMenuSignatureClick: function(menu, item) { + var guid = menu.cmpEl.attr('data-value'); + switch (item.value) { + case 0: + Common.NotificationCenter.trigger('protect:sign', guid); + break; + case 1: + this.api.asc_ViewCertificate(item.cmpEl.attr('data-value')); + break; + case 2: + Common.NotificationCenter.trigger('protect:signature', 'visible', !!parseInt(item.cmpEl.attr('data-value')), guid);// can edit settings for requested signature + break; + case 3: + this.api.asc_RemoveSignature(guid); + break; + } + }, + + onDocumentReady: function() { + this._state.ready = true; + + this.updateSignatures(this.api.asc_getSignatures(), this.api.asc_getRequestSignatures()); + this.showSignatureTooltip(this._state.hasValid, this._state.hasInvalid, this._state.hasRequested); + }, + + showSignatureTooltip: function(hasValid, hasInvalid, hasRequested) { + var me = this, + tip = me._state.tip; + + if (!hasValid && !hasInvalid && !hasRequested) { + if (tip && tip.isVisible()) { + tip.close(); + me._state.tip = undefined; + } + return; + } + + var showLink = hasValid || hasInvalid, + tipText = (hasInvalid) ? me.txtSignedInvalid : (hasValid ? me.txtSigned : ""); + if (hasRequested) + tipText = me.txtRequestedSignatures + "

    " + tipText; + + if (tip && tip.isVisible() && (tipText !== tip.text || showLink !== tip.showLink)) { + tip.close(); + me._state.tip = undefined; + } + + if (!me._state.tip) { + tip = new Common.UI.SynchronizeTip({ + target : SSE.getController('RightMenu').getView('RightMenu').btnSignature.btnEl, + text : tipText, + showLink: showLink, + textLink: this.txtContinueEditing, + placement: 'left' + }); + tip.on({ + 'dontshowclick': function() { + Common.UI.warning({ + title: me.notcriticalErrorTitle, + msg: me.txtEditWarning, + buttons: ['ok', 'cancel'], + primary: 'ok', + callback: function(btn) { + if (btn == 'ok') { + tip.close(); + me._state.tip = undefined; + me.api.asc_RemoveAllSignatures(); + } + } + }); + }, + 'closeclick': function() { + tip.close(); + me._state.tip = undefined; + } + }); + me._state.tip = tip; + tip.show(); + } + }, + + disableEditing: function(disable) { + if (this._state.DisabledEditing != disable) { + this._state.DisabledEditing = disable; + + var rightMenuController = SSE.getController('RightMenu'); + if (disable && rightMenuController.rightmenu.GetActivePane() !== 'id-signature-settings') + rightMenuController.rightmenu.clearSelection(); + rightMenuController.SetDisabled(disable, true); + SSE.getController('Toolbar').DisableToolbar(disable, disable); + SSE.getController('Statusbar').SetDisabled(disable); + SSE.getController('Common.Controllers.ReviewChanges').SetDisabled(disable); + SSE.getController('DocumentHolder').SetDisabled(disable, true); + + var leftMenu = SSE.getController('LeftMenu').leftMenu; + leftMenu.btnComments.setDisabled(disable); + var comments = SSE.getController('Common.Controllers.Comments'); + if (comments) + comments.setPreviewMode(disable); + } + }, + + strSignature: 'Signature', + strRequested: 'Requested signatures', + strValid: 'Valid signatures', + strInvalid: 'Invalid signatures', + strSign: 'Sign', + strDetails: 'Signature Details', + strSetup: 'Signature Setup', + txtSigned: 'Valid signatures has been added to the workbook. The workbook is protected from editing.', + txtSignedInvalid: 'Some of the digital signatures in workbook are invalid or could not be verified. The workbook is protected from editing.', + txtRequestedSignatures: 'This workbook needs to be signed.', + txtContinueEditing: 'Edit anyway', + notcriticalErrorTitle: 'Warning', + txtEditWarning: 'Editing will remove the signatures from the workbook.
    Are you sure you want to continue?', + strDelete: 'Remove Signature' + + }, SSE.Views.SignatureSettings || {})); +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/TextArtSettings.js b/apps/spreadsheeteditor/main/app/view/TextArtSettings.js index 0d0bb52fe..b54521a30 100644 --- a/apps/spreadsheeteditor/main/app/view/TextArtSettings.js +++ b/apps/spreadsheeteditor/main/app/view/TextArtSettings.js @@ -875,7 +875,8 @@ define([ // border colors var stroke = shapeprops.asc_getLine(), strokeType = (stroke) ? stroke.asc_getType() : null, - borderType; + borderType, + update = (this._state.StrokeColor == 'transparent' && this.BorderColor.Color !== 'transparent'); // border color was changed for shape without line and then shape was reselected (or apply other settings) if (stroke) { if ( strokeType == Asc.c_oAscStrokeType.STROKE_COLOR ) { @@ -900,7 +901,7 @@ define([ type1 = typeof(this.BorderColor.Color); type2 = typeof(this._state.StrokeColor); - if ( (type1 !== type2) || (type1=='object' && + if ( update || (type1 !== type2) || (type1=='object' && (this.BorderColor.Color.effectValue!==this._state.StrokeColor.effectValue || this._state.StrokeColor.color.indexOf(this.BorderColor.Color.color)<0)) || (type1!='object' && (this._state.StrokeColor.indexOf(this.BorderColor.Color)<0 || typeof(this.btnBorderColor.color)=='object'))) { @@ -1108,7 +1109,7 @@ define([ this.lockedControls.push(this.btnInsertFromUrl); this.btnInsertFromFile.on('click', _.bind(function(btn){ - if (this.api) this.api.asc_changeArtImageFromFile(); + if (this.api) this.api.asc_changeArtImageFromFile(this.BlipFillType); Common.NotificationCenter.trigger('edit:complete', this); }, this)); this.btnInsertFromUrl.on('click', _.bind(this.insertFromUrl, this)); diff --git a/apps/spreadsheeteditor/main/app/view/Toolbar.js b/apps/spreadsheeteditor/main/app/view/Toolbar.js index dda3a9cc8..4a08a5572 100644 --- a/apps/spreadsheeteditor/main/app/view/Toolbar.js +++ b/apps/spreadsheeteditor/main/app/view/Toolbar.js @@ -78,7 +78,8 @@ define([ cantPrint: 'cant-print', multiselect: 'is-multiselect', cantHyperlink: 'cant-hyperlink', - commentLock: 'can-comment' + commentLock: 'can-comment', + cantModifyFilter: 'cant-filter' }; SSE.Views.Toolbar = Common.UI.Mixtbar.extend(_.extend({ @@ -684,21 +685,21 @@ define([ id : 'id-toolbar-btn-sort-down', cls : 'btn-toolbar', iconCls : 'btn-sort-down', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot] + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter] }); me.btnSortUp = new Common.UI.Button({ id : 'id-toolbar-btn-sort-up', cls : 'btn-toolbar', iconCls : 'btn-sort-up', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot] + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter] }); me.btnSetAutofilter = new Common.UI.Button({ id : 'id-toolbar-btn-setautofilter', cls : 'btn-toolbar', iconCls : 'btn-autofilter', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter], enableToggle: true }); @@ -713,7 +714,7 @@ define([ id : 'id-toolbar-btn-ttempl', cls : 'btn-toolbar', iconCls : 'btn-ttempl', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.multiselect], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.multiselect, _set.cantModifyFilter], menu : new Common.UI.Menu({ items: [ { template: _.template('
    ') } @@ -894,6 +895,7 @@ define([ items : [ { caption : me.txtClearAll, + lock : [ _set.cantModifyFilter], value : Asc.c_oAscCleanOptions.All }, { @@ -903,7 +905,7 @@ define([ }, { caption : me.txtClearFormat, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.coAuth, _set.cantModifyFilter], value : Asc.c_oAscCleanOptions.Format }, { @@ -986,11 +988,11 @@ define([ id : 'id-toolbar-btn-colorschemas', cls : 'btn-toolbar', iconCls : 'btn-colorschemas', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.lostConnect, _set.coAuth], menu : new Common.UI.Menu({ items: [], - maxHeight : 600, - restoreHeight: 600 + maxHeight : 560, + restoreHeight: 560 }).on('show:before', function(mnu) { if ( !this.scroller ) { this.scroller = new Common.UI.Scroller({ @@ -1000,23 +1002,6 @@ define([ alwaysVisibleY: true }); } - }).on('show:after', function(btn, e) { - var mnu = $(this.el).find('.dropdown-menu '), - docH = Common.Utils.innerHeight(), - menuH = mnu.outerHeight(), - top = parseInt(mnu.css('top')); - - if (menuH > docH) { - mnu.css('max-height', (docH - parseInt(mnu.css('padding-top')) - parseInt(mnu.css('padding-bottom'))-5) + 'px'); - this.scroller.update({minScrollbarLength : 40}); - } else if ( mnu.height() < this.options.restoreHeight ) { - mnu.css('max-height', (Math.min(docH - parseInt(mnu.css('padding-top')) - parseInt(mnu.css('padding-bottom'))-5, this.options.restoreHeight)) + 'px'); - menuH = mnu.outerHeight(); - if (top+menuH > docH) { - mnu.css('top', 0); - } - this.scroller.update({minScrollbarLength : 40}); - } }) }); @@ -1073,7 +1058,7 @@ define([ allowDepress: true, toggleGroup : 'halignGroup', checked : true, - value : 'left' + value : AscCommon.align_Left }, { caption : me.tipAlignCenter, @@ -1082,7 +1067,7 @@ define([ checkable : true, allowDepress: true, toggleGroup : 'halignGroup', - value : 'center' + value : AscCommon.align_Center }, { caption : me.tipAlignRight, @@ -1091,7 +1076,7 @@ define([ checkable : true, allowDepress: true, toggleGroup : 'halignGroup', - value : 'right' + value : AscCommon.align_Right }, { caption : me.tipAlignJust, @@ -1100,7 +1085,7 @@ define([ checkable : true, allowDepress: true, toggleGroup : 'halignGroup', - value : 'justify' + value : AscCommon.align_Justify } ] }) @@ -1121,7 +1106,7 @@ define([ checkable : true, allowDepress: true, toggleGroup : 'valignGroup', - value : 'top' + value : Asc.c_oAscVAlign.Top }, { caption : me.tipAlignMiddle, @@ -1130,7 +1115,7 @@ define([ checkable : true, allowDepress: true, toggleGroup : 'valignGroup', - value : 'center' + value : Asc.c_oAscVAlign.Center }, { caption : me.tipAlignBottom, @@ -1140,7 +1125,7 @@ define([ allowDepress: true, checked : true, toggleGroup : 'valignGroup', - value : 'bottom' + value : Asc.c_oAscVAlign.Bottom } ] }) @@ -1156,13 +1141,13 @@ define([ me.mnuitemSortAZ = new Common.UI.MenuItem({ caption : me.txtSortAZ, iconCls : 'mnu-sort-asc', - lock : [_set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.coAuth, _set.ruleFilter], + lock : [_set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.coAuth, _set.ruleFilter, _set.cantModifyFilter], value : Asc.c_oAscSortOptions.Ascending }), me.mnuitemSortZA = new Common.UI.MenuItem({ caption : me.txtSortZA, iconCls : 'mnu-sort-desc', - lock : [_set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.coAuth, _set.ruleFilter], + lock : [_set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.coAuth, _set.ruleFilter, _set.cantModifyFilter], value : Asc.c_oAscSortOptions.Descending }), me.mnuitemAutoFilter = new Common.UI.MenuItem({ @@ -1260,17 +1245,6 @@ define([ this.fireEvent('render:after', [this]); Common.UI.Mixtbar.prototype.afterRender.call(this); - me.$tabs.parent().on('click', '.ribtab', function (e) { - var tab = $(e.target).data('tab'); - if (tab == 'file') { - me.fireEvent('file:open'); - } else - if ( me.isTabActive('file') ) - me.fireEvent('file:close'); - - me.setTab(tab); - }); - Common.NotificationCenter.on({ 'window:resize': function() { Common.UI.Mixtbar.prototype.onResize.apply(me, arguments); @@ -1284,6 +1258,21 @@ define([ return this; }, + onTabClick: function (e) { + var tab = $(e.target).data('tab'), + me = this; + + if ( !me.isTabActive(tab) ) { + if ( tab == 'file' ) { + me.fireEvent('file:open'); + } else + if ( me.isTabActive('file') ) + me.fireEvent('file:close'); + } + + Common.UI.Mixtbar.prototype.onTabClick.apply(this, arguments); + }, + rendererComponents: function(html) { var $host = $(html); var _injectComponent = function (id, cmp) { @@ -1745,8 +1734,8 @@ define([ } if (this.mnuColorSchema == null) { - this.mnuColorSchema = new Common.UI.Menu({maxHeight : 600, - restoreHeight: 600 + this.mnuColorSchema = new Common.UI.Menu({maxHeight : 560, + restoreHeight: 560 }).on('show:before', function(mnu) { this.scroller = new Common.UI.Scroller({ el: $(this.el).find('.dropdown-menu '), @@ -2078,6 +2067,9 @@ define([ textTabFile: 'File', textTabHome: 'Home', textTabInsert: 'Insert', - textSurface: 'Surface' + textSurface: 'Surface', + tipChangeChart: 'Change Chart Type', + textTabCollaboration: 'Collaboration', + textTabProtect: 'Protection' }, SSE.Views.Toolbar || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/ValueFieldSettingsDialog.js b/apps/spreadsheeteditor/main/app/view/ValueFieldSettingsDialog.js new file mode 100644 index 000000000..6bf42ce39 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/ValueFieldSettingsDialog.js @@ -0,0 +1,309 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * ValueFieldSettingsDialog.js + * + * Created by Julia Radzhabova on 14.07.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'common/main/lib/util/utils', + 'common/main/lib/component/InputField', + 'common/main/lib/component/ComboBox', + 'common/main/lib/view/AdvancedSettingsWindow' +], function () { 'use strict'; + + SSE.Views.ValueFieldSettingsDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({ + options: { + contentWidth: 284, + height: 340 + }, + + initialize : function(options) { + var me = this; + + _.extend(this.options, { + title: this.textTitle, + template: [ + '
    ', + '
    ', + '
    ', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '
    ', + '', + '', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '' + ].join('') + }, options); + + this.api = options.api; + this.handler = options.handler; + this.props = options.props; + this.field = options.field || 0; + this.names = options.names || []; + + Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.Views.AdvancedSettingsWindow.prototype.render.call(this); + var me = this; + + this.inputCustomName = new Common.UI.InputField({ + el : $('#value-field-settings-custom'), + allowBlank : true, + validateOnBlur: false, + style : 'width: 100%;' + }); + + this.cmbSummarize = new Common.UI.ComboBox({ + el: $('#value-field-settings-summarize'), + cls: 'input-group-nr', + menuStyle: 'min-width: 264px;', + editable: false, + data: [ + { value: Asc.c_oAscDataConsolidateFunction.Sum, displayValue: this.txtSum }, + { value: Asc.c_oAscDataConsolidateFunction.Count, displayValue: this.txtCount }, + { value: Asc.c_oAscDataConsolidateFunction.Average, displayValue: this.txtAverage }, + { value: Asc.c_oAscDataConsolidateFunction.Max, displayValue: this.txtMax }, + { value: Asc.c_oAscDataConsolidateFunction.Min, displayValue: this.txtMin }, + { value: Asc.c_oAscDataConsolidateFunction.Product, displayValue: this.txtProduct }, + { value: Asc.c_oAscDataConsolidateFunction.CountNums,displayValue: this.txtCountNums }, + { value: Asc.c_oAscDataConsolidateFunction.StdDev, displayValue: this.txtStdDev }, + { value: Asc.c_oAscDataConsolidateFunction.StdDevp, displayValue: this.txtStdDevp }, + { value: Asc.c_oAscDataConsolidateFunction.Var, displayValue: this.txtVar }, + { value: Asc.c_oAscDataConsolidateFunction.Varp, displayValue: this.txtVarp } + ] + }); + this.cmbSummarize.setValue(Asc.c_oAscDataConsolidateFunction.Sum); + this.cmbSummarize.on('selected', _.bind(this.onSummarizeSelect, this)); + + this.cmbShowAs = new Common.UI.ComboBox({ + el: $('#value-field-settings-showas'), + cls: 'input-group-nr', + menuStyle: 'min-width: 264px;', + editable: false, + data: [ + { value: Asc.c_oAscShowDataAs.Normal, displayValue: this.txtNormal }, + { value: Asc.c_oAscShowDataAs.PercentOfRow, displayValue: this.txtPercentOfRow }, + { value: Asc.c_oAscShowDataAs.PercentOfCol, displayValue: this.txtPercentOfCol }, + { value: Asc.c_oAscShowDataAs.PercentOfTotal, displayValue: this.txtPercentOfTotal }, + { value: Asc.c_oAscShowDataAs.Percent, displayValue: this.txtPercent }, + { value: Asc.c_oAscShowDataAs.Difference, displayValue: this.txtDifference }, + { value: Asc.c_oAscShowDataAs.PercentDiff, displayValue: this.txtPercentDiff }, + { value: Asc.c_oAscShowDataAs.RunTotal, displayValue: this.txtRunTotal }, + { value: Asc.c_oAscShowDataAs.Index, displayValue: this.txtIndex } + ] + }); + this.cmbShowAs.setValue(Asc.c_oAscDataConsolidateFunction.Normal); + this.cmbShowAs.on('selected', _.bind(this.onShowAsSelect, this)); + + this.cmbBaseField = new Common.UI.ComboBox({ + el: $('#value-field-settings-field'), + cls: 'input-group-nr', + menuStyle: 'min-width: 264px;max-height:235px;', + editable: false, + data: [], + scrollAlwaysVisible: true + }); + this.cmbBaseField.on('selected', _.bind(this.onBaseFieldSelect, this)); + + this.cmbBaseItem = new Common.UI.ComboBox({ + el: $('#value-field-settings-item'), + cls: 'input-group-nr', + menuStyle: 'min-width: 264px;max-height:235px;', + editable: false, + data: [], + scrollAlwaysVisible: true + }); + this.cmbBaseItem.on('selected', _.bind(this.onBaseItemSelect, this)); + + this.lblSourceName = this.$window.find('#value-field-settings-source'); + + this.afterRender(); + }, + + afterRender: function() { + this._setDefaults(this.props); + }, + + show: function() { + Common.Views.AdvancedSettingsWindow.prototype.show.apply(this, arguments); + }, + + _setDefaults: function (props) { + if (props) { + var field = this.field, + cache_names = props.asc_getCacheFields(), + show_as = field.asc_getShowDataAs(); + + this.lblSourceName.html(Common.Utils.String.htmlEncode(cache_names[field.asc_getIndex()].asc_getName())); + this.inputCustomName.setValue(Common.Utils.String.htmlEncode(field.asc_getName())); + + this.cmbSummarize.setValue(field.asc_getSubtotal()); + this.cmbShowAs.setValue(show_as); + + var data = []; + this.names.forEach(function(item){ + data.push({value: item, displayValue: item}); + }); + this.cmbBaseField.setData(data); + this.cmbBaseField.setValue(this.names[0]); + this.cmbBaseField.setDisabled(show_as != c_oAscShowDataAs.Difference && show_as != c_oAscShowDataAs.Percent && + show_as != c_oAscShowDataAs.PercentDiff && show_as != c_oAscShowDataAs.RunTotal); + + // this.cmbBaseItem.setData(data); + this.cmbBaseItem.setDisabled(show_as != c_oAscShowDataAs.Difference && show_as != c_oAscShowDataAs.Percent && + show_as != c_oAscShowDataAs.PercentDiff); + } + }, + + getSettings: function () { + var field = new Asc.CT_DataField(); + field.asc_setName(this.inputCustomName.getValue()); + field.asc_setSubtotal(this.cmbSummarize.getValue()); + + return field; + }, + + onDlgBtnClick: function(event) { + var me = this; + var state = (typeof(event) == 'object') ? event.currentTarget.attributes['result'].value : event; + if (state == 'ok') { + this.handler && this.handler.call(this, state, (state == 'ok') ? this.getSettings() : undefined); + } + + this.close(); + }, + + onPrimary: function() { + this.onDlgBtnClick('ok'); + return false; + }, + + onSummarizeSelect: function(combo, record) { + this.inputCustomName.setValue(record.displayValue + ' ' + this.txtByField + ' ' + this.lblSourceName.text()); + }, + + onShowAsSelect: function(combo, record) { + }, + + onBaseFieldSelect: function(combo, record) { + }, + + onBaseItemSelect: function(combo, record) { + }, + + textTitle: 'Value Field Settings', + textCancel: 'Cancel', + textOk: 'OK', + txtSourceName: 'Source name: ', + txtCustomName: 'Custom name', + txtSummarize: 'Summarize value field by', + txtShowAs: 'Show values as', + txtBaseField: 'Base field', + txtBaseItem: 'Base item', + txtAverage: 'Average', + txtCount: 'Count', + txtCountNums: 'Count Numbers', + txtMax: 'Max', + txtMin: 'Min', + txtProduct: 'Product', + txtStdDev: 'StdDev', + txtStdDevp: 'StdDevp', + txtSum: 'Sum', + txtVar: 'Var', + txtVarp: 'Varp', + txtNormal: 'No Calculation', + txtDifference: 'The Difference From', + txtPercent: 'Percent of', + txtPercentDiff: 'Percent Difference From', + txtRunTotal: 'Running Total In', + txtPercentOfRow: 'Percent of Total', + txtPercentOfCol: 'Percent of Column', + txtPercentOfTotal: 'Percent of Row', + txtIndex: 'Index', + txtByField: 'by field' + + }, SSE.Views.ValueFieldSettingsDialog || {})) +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/Viewport.js b/apps/spreadsheeteditor/main/app/view/Viewport.js index 341b4a1e1..86c059741 100644 --- a/apps/spreadsheeteditor/main/app/view/Viewport.js +++ b/apps/spreadsheeteditor/main/app/view/Viewport.js @@ -147,7 +147,7 @@ define([ var me = this, rightMenuView = SSE.getController('RightMenu').getView('RightMenu'); - me._rightMenu = rightMenuView.render(); + me._rightMenu = rightMenuView.render(this.mode); }, setMode: function(mode, delay) { diff --git a/apps/spreadsheeteditor/main/app_dev.js b/apps/spreadsheeteditor/main/app_dev.js index f541535a3..6971b85b8 100644 --- a/apps/spreadsheeteditor/main/app_dev.js +++ b/apps/spreadsheeteditor/main/app_dev.js @@ -145,10 +145,13 @@ require([ 'RightMenu', 'LeftMenu', 'Main', + 'PivotTable', 'Common.Controllers.Fonts', 'Common.Controllers.Chat', 'Common.Controllers.Comments', 'Common.Controllers.Plugins' + ,'Common.Controllers.ReviewChanges' + ,'Common.Controllers.Protection' ] }); @@ -164,18 +167,25 @@ require([ 'spreadsheeteditor/main/app/controller/LeftMenu', 'spreadsheeteditor/main/app/controller/Main', 'spreadsheeteditor/main/app/controller/Print', + 'spreadsheeteditor/main/app/controller/PivotTable', 'spreadsheeteditor/main/app/view/FileMenuPanels', 'spreadsheeteditor/main/app/view/ParagraphSettings', 'spreadsheeteditor/main/app/view/ImageSettings', 'spreadsheeteditor/main/app/view/ChartSettings', 'spreadsheeteditor/main/app/view/ShapeSettings', 'spreadsheeteditor/main/app/view/TextArtSettings', + 'spreadsheeteditor/main/app/view/PivotSettings', + 'spreadsheeteditor/main/app/view/FieldSettingsDialog', + 'spreadsheeteditor/main/app/view/ValueFieldSettingsDialog', + 'spreadsheeteditor/main/app/view/SignatureSettings', 'common/main/lib/util/utils', 'common/main/lib/util/LocalStorage', 'common/main/lib/controller/Fonts', 'common/main/lib/controller/Comments', 'common/main/lib/controller/Chat', 'common/main/lib/controller/Plugins' + ,'common/main/lib/controller/ReviewChanges' + ,'common/main/lib/controller/Protection' ], function() { window.compareVersions = true; app.start(); diff --git a/apps/spreadsheeteditor/main/locale/en.json b/apps/spreadsheeteditor/main/locale/en.json index 75138eb95..affc0f6a0 100644 --- a/apps/spreadsheeteditor/main/locale/en.json +++ b/apps/spreadsheeteditor/main/locale/en.json @@ -102,16 +102,98 @@ "Common.Views.OpenDialog.txtTab": "Tab", "Common.Views.OpenDialog.txtTitle": "Choose %1 options", "Common.Views.OpenDialog.txtTitleProtected": "Protected File", + "Common.Views.PasswordDialog.cancelButtonText": "Cancel", + "Common.Views.PasswordDialog.okButtonText": "OK", + "Common.Views.PasswordDialog.txtPassword": "Password", + "Common.Views.PasswordDialog.txtTitle": "Set Password", + "Common.Views.PasswordDialog.txtDescription": "A Password is required to open this document", + "Common.Views.PasswordDialog.txtRepeat": "Repeat password", + "Common.Views.PasswordDialog.txtIncorrectPwd": "Confirmation password is not identical", "Common.Views.PluginDlg.textLoading": "Loading", "Common.Views.Plugins.groupCaption": "Plugins", "Common.Views.Plugins.strPlugins": "Plugins", "Common.Views.Plugins.textLoading": "Loading", "Common.Views.Plugins.textStart": "Start", "Common.Views.Plugins.textStop": "Stop", + "Common.Views.Protection.txtAddPwd": "Add password", + "Common.Views.Protection.txtEncrypt": "Encrypt", + "Common.Views.Protection.txtSignature": "Signature", + "Common.Views.Protection.hintAddPwd": "Encrypt with password", + "Common.Views.Protection.hintPwd": "Change or delete password", + "Common.Views.Protection.hintSignature": "Add digital signature or signature line", + "Common.Views.Protection.txtChangePwd": "Change password", + "Common.Views.Protection.txtDeletePwd": "Delete password", + "Common.Views.Protection.txtInvisibleSignature": "Add digital signature", + "Common.Views.Protection.txtSignatureLine": "Signature line", "Common.Views.RenameDialog.cancelButtonText": "Cancel", "Common.Views.RenameDialog.okButtonText": "Ok", "Common.Views.RenameDialog.textName": "File name", "Common.Views.RenameDialog.txtInvalidName": "The file name cannot contain any of the following characters: ", + "Common.Views.ReviewChanges.hintNext": "To next change", + "Common.Views.ReviewChanges.hintPrev": "To previous change", + "Common.Views.ReviewChanges.tipAcceptCurrent": "Accept current change", + "Common.Views.ReviewChanges.tipRejectCurrent": "Reject current change", + "Common.Views.ReviewChanges.tipReview": "Track changes", + "Common.Views.ReviewChanges.tipReviewView": "Select the mode you want the changes to be displayed", + "Common.Views.ReviewChanges.tipSetDocLang": "Set document language", + "Common.Views.ReviewChanges.tipSetSpelling": "Spell checking", + "Common.Views.ReviewChanges.txtAccept": "Accept", + "Common.Views.ReviewChanges.txtAcceptAll": "Accept All Changes", + "Common.Views.ReviewChanges.txtAcceptChanges": "Accept changes", + "Common.Views.ReviewChanges.txtAcceptCurrent": "Accept Current Change", + "Common.Views.ReviewChanges.txtClose": "Close", + "Common.Views.ReviewChanges.txtDocLang": "Language", + "Common.Views.ReviewChanges.txtFinal": "All changes like accept (Preview)", + "Common.Views.ReviewChanges.txtMarkup": "Text with changes (Editing)", + "Common.Views.ReviewChanges.txtNext": "Next", + "Common.Views.ReviewChanges.txtOriginal": "Text without changes (Preview)", + "Common.Views.ReviewChanges.txtMarkupCap": "Markup", + "Common.Views.ReviewChanges.txtFinalCap": "Final", + "Common.Views.ReviewChanges.txtOriginalCap": "Original", + "Common.Views.ReviewChanges.txtPrev": "Previous", + "Common.Views.ReviewChanges.txtReject": "Reject", + "Common.Views.ReviewChanges.txtRejectAll": "Reject All Changes", + "Common.Views.ReviewChanges.txtRejectChanges": "Reject changes", + "Common.Views.ReviewChanges.txtRejectCurrent": "Reject Current Change", + "Common.Views.ReviewChanges.txtSpelling": "Spell Checking", + "Common.Views.ReviewChanges.txtTurnon": "Track Changes", + "Common.Views.ReviewChanges.txtView": "Display Mode", + "Common.Views.ReviewChanges.txtSharing": "Sharing", + "Common.Views.ReviewChanges.tipSharing": "Manage document access rights", + "Common.Views.ReviewChanges.txtCoAuthMode": "Co-editing Mode", + "Common.Views.ReviewChanges.tipCoAuthMode": "Set co-editing mode", + "Common.Views.ReviewChanges.strFast": "Fast", + "Common.Views.ReviewChanges.strStrict": "Strict", + "Common.Views.ReviewChanges.strFastDesc": "Real-time co-editing. All changes are saved automatically.", + "Common.Views.ReviewChanges.strStrictDesc": "Use the 'Save' button to sync the changes you and others make.", + "Common.Views.ReviewChanges.txtHistory": "Version History", + "Common.Views.ReviewChanges.tipHistory": "Show version history", + "Common.Views.SignDialog.textTitle": "Sign Document", + "Common.Views.SignDialog.textPurpose": "Purpose for signing this document", + "Common.Views.SignDialog.textCertificate": "Certificate", + "Common.Views.SignDialog.textValid": "Valid from %1 to %2", + "Common.Views.SignDialog.textChange": "Change", + "Common.Views.SignDialog.cancelButtonText": "Cancel", + "Common.Views.SignDialog.okButtonText": "Ok", + "Common.Views.SignDialog.textInputName": "Input signer name", + "Common.Views.SignDialog.textUseImage": "or click 'Select Image' to use a picture as signature", + "Common.Views.SignDialog.textSelectImage": "Select Image", + "Common.Views.SignDialog.textSignature": "Signature looks as", + "Common.Views.SignDialog.tipFontName": "Font Name", + "Common.Views.SignDialog.tipFontSize": "Font Size", + "Common.Views.SignDialog.textBold": "Bold", + "Common.Views.SignDialog.textItalic": "Italic", + "Common.Views.SignSettingsDialog.textInfo": "Signer Info", + "Common.Views.SignSettingsDialog.textInfoName": "Name", + "Common.Views.SignSettingsDialog.textInfoTitle": "Signer Title", + "Common.Views.SignSettingsDialog.textInfoEmail": "E-mail", + "Common.Views.SignSettingsDialog.textInstructions": "Instructions for Signer", + "Common.Views.SignSettingsDialog.cancelButtonText": "Cancel", + "Common.Views.SignSettingsDialog.okButtonText": "Ok", + "Common.Views.SignSettingsDialog.txtEmpty": "This field is required", + "Common.Views.SignSettingsDialog.textAllowComment": "Allow signer to add comment in the signature dialog", + "Common.Views.SignSettingsDialog.textShowDate": "Show sign date in signature line", + "Common.Views.SignSettingsDialog.textTitle": "Signature Settings", "SSE.Controllers.DocumentHolder.alignmentText": "Alignment", "SSE.Controllers.DocumentHolder.centerText": "Center", "SSE.Controllers.DocumentHolder.deleteColumnText": "Delete Column", @@ -229,6 +311,8 @@ "SSE.Controllers.DocumentHolder.txtTop": "Top", "SSE.Controllers.DocumentHolder.txtUnderbar": "Bar under text", "SSE.Controllers.DocumentHolder.txtWidth": "Width", + "SSE.Controllers.DocumentHolder.txtUndoExpansion": "Undo table autoexpansion", + "SSE.Controllers.DocumentHolder.txtRedoExpansion": "Redo table autoexpansion", "SSE.Controllers.LeftMenu.newDocumentTitle": "Unnamed spreadsheet", "SSE.Controllers.LeftMenu.textByColumns": "By columns", "SSE.Controllers.LeftMenu.textByRows": "By rows", @@ -236,7 +320,7 @@ "SSE.Controllers.LeftMenu.textItemEntireCell": "Entire cell contents", "SSE.Controllers.LeftMenu.textLookin": "Look in", "SSE.Controllers.LeftMenu.textNoTextFound": "The data you have been searching for could not be found. Please adjust your search options.", - "SSE.Controllers.LeftMenu.textReplaceSkipped": "The replacement has been made. {0} occurrences were skipped.", + "SSE.Controllers.LeftMenu.textReplaceSkipped": "The replacement has been maSSE. {0} occurrences were skipped.", "SSE.Controllers.LeftMenu.textReplaceSuccess": "The search has been done. Occurrences replaced: {0}", "SSE.Controllers.LeftMenu.textSearch": "Search", "SSE.Controllers.LeftMenu.textSheet": "Sheet", @@ -1063,6 +1147,10 @@ "SSE.Views.DocumentHolder.txtUngroup": "Ungroup", "SSE.Views.DocumentHolder.txtWidth": "Width", "SSE.Views.DocumentHolder.vertAlignText": "Vertical Alignment", + "SSE.Views.DocumentHolder.strSign": "Sign", + "SSE.Views.DocumentHolder.strDetails": "Signature Details", + "SSE.Views.DocumentHolder.strSetup": "Signature Setup", + "SSE.Views.DocumentHolder.strDelete": "Remove Signature", "SSE.Views.FileMenu.btnBackCaption": "Go to Documents", "SSE.Views.FileMenu.btnCloseMenuCaption": "Close Menu", "SSE.Views.FileMenu.btnCreateNewCaption": "Create New", @@ -1078,6 +1166,7 @@ "SSE.Views.FileMenu.btnSaveCaption": "Save", "SSE.Views.FileMenu.btnSettingsCaption": "Advanced Settings...", "SSE.Views.FileMenu.btnToEditCaption": "Edit Spreadsheet", + "SSE.Views.FileMenu.btnProtectCaption": "Protect\\Sign", "SSE.Views.FileMenuPanels.CreateNew.fromBlankText": "From Blank", "SSE.Views.FileMenuPanels.CreateNew.fromTemplateText": "From Template", "SSE.Views.FileMenuPanels.CreateNew.newDescriptionText": "Create a new blank spreadsheet which you will be able to style and format after it is created during the editing. Or choose one of the templates to start a spreadsheet of a certain type or purpose where some styles have already been pre-applied.", @@ -1132,6 +1221,17 @@ "SSE.Views.FileMenuPanels.MainSettingsGeneral.txtWin": "as Windows", "SSE.Views.FileMenuPanels.Settings.txtGeneral": "General", "SSE.Views.FileMenuPanels.Settings.txtPageSettings": "Page Settings", + "SSE.Views.FileMenuPanels.ProtectDoc.strProtect": "Protect Workbook", + "SSE.Views.FileMenuPanels.ProtectDoc.strSignature": "Signature", + "SSE.Views.FileMenuPanels.ProtectDoc.txtView": "View signatures", + "SSE.Views.FileMenuPanels.ProtectDoc.txtEdit": "Edit workbook", + "SSE.Views.FileMenuPanels.ProtectDoc.txtSigned": "Valid signatures has been added to the workbook. The workbook is protected from editing.", + "SSE.Views.FileMenuPanels.ProtectDoc.txtSignedInvalid": "Some of the digital signatures in workbook are invalid or could not be verified. The workbook is protected from editing.", + "SSE.Views.FileMenuPanels.ProtectDoc.txtRequestedSignatures": "This workbook needs to be signed.", + "SSE.Views.FileMenuPanels.ProtectDoc.notcriticalErrorTitle": "Warning", + "SSE.Views.FileMenuPanels.ProtectDoc.txtEditWarning": "Editing will remove the signatures from the workbook.
    Are you sure you want to continue?", + "SSE.Views.FileMenuPanels.ProtectDoc.strEncrypt": "Password", + "SSE.Views.FileMenuPanels.ProtectDoc.txtEncrypted": "This workbook has been protected by password", "SSE.Views.FormatSettingsDialog.textCancel": "Cancel", "SSE.Views.FormatSettingsDialog.textCategory": "Category", "SSE.Views.FormatSettingsDialog.textDecimal": "Decimal", @@ -1161,6 +1261,7 @@ "SSE.Views.FormatSettingsDialog.txtUpto1": "Up to one digit (1/3)", "SSE.Views.FormatSettingsDialog.txtUpto2": "Up to two digits (12/25)", "SSE.Views.FormatSettingsDialog.txtUpto3": "Up to three digits (131/135)", + "SSE.Views.FormatSettingsDialog.txtNone": "None", "SSE.Views.FormulaDialog.cancelButtonText": "Cancel", "SSE.Views.FormulaDialog.okButtonText": "OK", "SSE.Views.FormulaDialog.sCategoryAll": "All", @@ -1381,6 +1482,7 @@ "SSE.Views.RightMenu.txtSparklineSettings": "Sparkline Settings", "SSE.Views.RightMenu.txtTableSettings": "Table settings", "SSE.Views.RightMenu.txtTextArtSettings": "Text Art settings", + "SSE.Views.RightMenu.txtSignatureSettings": "Signature Settings", "SSE.Views.SetValueDialog.cancelButtonText": "Cancel", "SSE.Views.SetValueDialog.okButtonText": "OK", "SSE.Views.SetValueDialog.txtMaxText": "The maximum value for this field is {0}", @@ -1428,6 +1530,20 @@ "SSE.Views.ShapeSettings.txtNoBorders": "No Line", "SSE.Views.ShapeSettings.txtPapyrus": "Papyrus", "SSE.Views.ShapeSettings.txtWood": "Wood", + "SSE.Views.SignatureSettings.strSignature": "Signature", + "SSE.Views.SignatureSettings.strRequested": "Requested signatures", + "SSE.Views.SignatureSettings.strValid": "Valid signatures", + "SSE.Views.SignatureSettings.strInvalid": "Invalid signatures", + "SSE.Views.SignatureSettings.strSign": "Sign", + "SSE.Views.SignatureSettings.strDetails": "Signature Details", + "SSE.Views.SignatureSettings.strDelete": "Remove Signature", + "SSE.Views.SignatureSettings.strSetup": "Signature Setup", + "SSE.Views.SignatureSettings.txtSigned": "Valid signatures has been added to the workbook. The workbook is protected from editing.", + "SSE.Views.SignatureSettings.txtSignedInvalid": "Some of the digital signatures in workbook are invalid or could not be verified. The workbook is protected from editing.", + "SSE.Views.SignatureSettings.txtRequestedSignatures": "This workbook needs to be signed.", + "SSE.Views.SignatureSettings.txtContinueEditing": "Edit anyway", + "SSE.Views.SignatureSettings.notcriticalErrorTitle": "Warning", + "SSE.Views.SignatureSettings.txtEditWarning": "Editing will remove the signatures from the workbook.
    Are you sure you want to continue?", "SSE.Views.ShapeSettingsAdvanced.cancelButtonText": "Cancel", "SSE.Views.ShapeSettingsAdvanced.okButtonText": "OK", "SSE.Views.ShapeSettingsAdvanced.strColumns": "Columns", @@ -1653,6 +1769,8 @@ "SSE.Views.Toolbar.textTabFile": "File", "SSE.Views.Toolbar.textTabHome": "Home", "SSE.Views.Toolbar.textTabInsert": "Insert", + "SSE.Views.Toolbar.textTabCollaboration": "Collaboration", + "SSE.Views.Toolbar.textTabProtect": "Protection", "SSE.Views.Toolbar.textTopBorders": "Top Borders", "SSE.Views.Toolbar.textUnderline": "Underline", "SSE.Views.Toolbar.textWinLossSpark": "Win/Loss", @@ -1669,6 +1787,7 @@ "SSE.Views.Toolbar.tipBack": "Back", "SSE.Views.Toolbar.tipBorders": "Borders", "SSE.Views.Toolbar.tipCellStyle": "Cell Style", + "SSE.Views.Toolbar.tipChangeChart": "Change Chart Type", "SSE.Views.Toolbar.tipClearStyle": "Clear", "SSE.Views.Toolbar.tipColorSchemas": "Change color scheme", "SSE.Views.Toolbar.tipCopy": "Copy", diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar-menu.png b/apps/spreadsheeteditor/main/resources/img/toolbar-menu.png index 91577a92e..86b28d397 100644 Binary files a/apps/spreadsheeteditor/main/resources/img/toolbar-menu.png and b/apps/spreadsheeteditor/main/resources/img/toolbar-menu.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar-menu@2x.png b/apps/spreadsheeteditor/main/resources/img/toolbar-menu@2x.png index 0b67bd39b..749fd5ca1 100644 Binary files a/apps/spreadsheeteditor/main/resources/img/toolbar-menu@2x.png and b/apps/spreadsheeteditor/main/resources/img/toolbar-menu@2x.png differ diff --git a/apps/spreadsheeteditor/main/resources/less/leftmenu.less b/apps/spreadsheeteditor/main/resources/less/leftmenu.less index 100eaaa2d..59e7c6ba8 100644 --- a/apps/spreadsheeteditor/main/resources/less/leftmenu.less +++ b/apps/spreadsheeteditor/main/resources/less/leftmenu.less @@ -266,7 +266,8 @@ width: 30%; label { - font:bold 12px tahoma, arial, verdana, sans-serif; + font-weight: bold; + font-size: 12px; } } @@ -517,7 +518,26 @@ } label, span { - font: 12px tahoma, arial, verdana, sans-serif; + font-size: 12px; + } + } + + #panel-protect { + label, span { + font-size: 12px; + } + + padding: 30px 30px; + + .header { + font-weight: bold; + margin: 30px 0 10px; + } + + table { + td { + padding: 5px 0; + } } } } @@ -537,4 +557,4 @@ -webkit-transform: rotate(180deg); -o-transform: rotate(180deg); transform: rotate(180deg); -} \ No newline at end of file +} diff --git a/apps/spreadsheeteditor/main/resources/less/rightmenu.less b/apps/spreadsheeteditor/main/resources/less/rightmenu.less index d50c9bf07..afde9fd69 100644 --- a/apps/spreadsheeteditor/main/resources/less/rightmenu.less +++ b/apps/spreadsheeteditor/main/resources/less/rightmenu.less @@ -23,6 +23,9 @@ /*menuTable*/ .toolbar-btn-icon(btn-menu-table, 80, @toolbar-icon-size); + + /**menuSignature*/ + .toolbar-btn-icon(btn-menu-signature, 83, @toolbar-icon-size); } } @@ -331,4 +334,112 @@ button:active:not(.disabled) .btn-change-shape {background-position: -56px - #table-combo-template .combo-dataview{ .combo-template(60px); +} + +.pivot-check-listview { + background-color: #fff; + width: 100%; + height: 250px; + + .item { + padding-right: 3px; + } + + .list-item { + width: 146px; + margin-left:20px; + display: inline-block; + white-space: pre; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: middle; + } + + .listitem-icon { + vertical-align: middle; + width: 16px; + height: 16px; + background-position: -1px -274px; + display: inline-block; + } +} + +.pivot-listview { + background-color: #fff; + width: 95px; + height: 130px; + + .item { + padding: 3px; + } + + .list-item > div:nth-child(1) { + width:70px; + padding-right: 5px; + display: inline-block; + white-space: pre; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: middle; + } + + .listitem-icon { + vertical-align: middle; + width: 16px; + height: 16px; + background-position: -1px -274px; + display: inline-block; + } +} + +#signature-requested-sign, +#signature-valid-sign, +#signature-invalid-sign { + height: 100%; + overflow: hidden; + margin: 0 -10px 0 -15px; + + .item { + display: block; + border: none; + width: 100%; + .box-shadow(none); + margin: 0; + + &:hover, + &.over { + background-color: @secondary; + } + } + + .signature-item { + padding: 5px 2px 5px 15px; + text-overflow: ellipsis; + min-height: 25px; + + .name { + width: 100%; + white-space: nowrap; + overflow: hidden; + cursor: pointer; + max-width: 160px; + text-overflow: ellipsis; + } + + .caret { + width: 23px; + height: 14px; + border: 0; + background-position: -43px -150px; + margin: 8px 15px; + display: inline-block; + position: absolute; + right: 0; + + &.nomargin { + margin-top: 0; + margin-bottom: 0; + } + } + } } \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/resources/less/toolbar.less b/apps/spreadsheeteditor/main/resources/less/toolbar.less index 4dbf880eb..85e94bb2b 100644 --- a/apps/spreadsheeteditor/main/resources/less/toolbar.less +++ b/apps/spreadsheeteditor/main/resources/less/toolbar.less @@ -2,7 +2,7 @@ .toolbar { &:not(.cover) { - z-index: 510; + z-index: 1001; } &.masked { @@ -238,7 +238,8 @@ .background-ximage('@{app-image-path}/toolbar/math.png', '@{app-image-path}/toolbar/math@2x.png', 1500px); } -#special-paste-container { +#special-paste-container, +#autocorrect-paste-container { position: absolute; z-index: @zindex-dropdown - 20; background-color: @gray-light; diff --git a/apps/spreadsheeteditor/mobile/app/controller/Main.js b/apps/spreadsheeteditor/mobile/app/controller/Main.js index d750dae1d..5c2bb4b17 100644 --- a/apps/spreadsheeteditor/mobile/app/controller/Main.js +++ b/apps/spreadsheeteditor/mobile/app/controller/Main.js @@ -962,6 +962,8 @@ define([ } } else { + Common.Gateway.reportWarning(id, config.msg); + config.title = this.notcriticalErrorTitle; // config.iconCls = 'warn'; // config.buttons = ['ok']; diff --git a/apps/spreadsheeteditor/mobile/app/controller/edit/EditCell.js b/apps/spreadsheeteditor/mobile/app/controller/edit/EditCell.js index c643f8edb..7778ecf49 100644 --- a/apps/spreadsheeteditor/mobile/app/controller/edit/EditCell.js +++ b/apps/spreadsheeteditor/mobile/app/controller/edit/EditCell.js @@ -232,19 +232,32 @@ define([ initTextFormat: function () { var me = this, $pageTextFormat = $('.page[data-page=edit-text-format]'), - hAlign = _cellInfo.asc_getHorAlign() || 'left', - vAlign = _cellInfo.asc_getVertAlign() || 'bottom', + hAlign = _cellInfo.asc_getHorAlign(), + vAlign = _cellInfo.asc_getVertAlign(), + hAlignStr = 'left', + vAlignStr = 'bottom', isWrapText = _cellInfo.asc_getFlags().asc_getWrapText(); - $('#text-format .item-media i').removeClass().addClass(Common.Utils.String.format('icon icon-text-align-{0}', hAlign == 'none' ? 'left' : hAlign)); + if (vAlign == Asc.c_oAscVAlign.Top) + vAlignStr = 'top'; + else if (vAlign == Asc.c_oAscVAlign.Center) + vAlignStr = 'center'; + + switch (hAlign) { + case AscCommon.align_Center: hAlignStr = 'center'; break; + case AscCommon.align_Right: hAlignStr = 'right'; break; + case AscCommon.align_Justify: hAlignStr = 'justify'; break; + } + + $('#text-format .item-media i').removeClass().addClass(Common.Utils.String.format('icon icon-text-align-{0}', hAlignStr)); if ($pageTextFormat.length > 0) { var $radioHAlign = $pageTextFormat.find('input:radio[name=text-halign]'), $radioVAlign = $pageTextFormat.find('input:radio[name=text-valign]'), $switchWrapText = $pageTextFormat.find('#edit-cell-wrap-text input'); - $radioHAlign.val([hAlign]); - $radioVAlign.val([vAlign]); + $radioHAlign.val([hAlignStr]); + $radioVAlign.val([vAlignStr]); $switchWrapText.prop('checked', isWrapText); $radioHAlign.single('change', _.bind(me.onHAlignChange, me)); @@ -419,14 +432,29 @@ define([ onHAlignChange: function (e) { var $target = $(e.currentTarget), - type = $target.prop('value'); + value = $target.prop('value'), + type = AscCommon.align_Left; + + if (value == 'center') + type = AscCommon.align_Center; + else if (value == 'right') + type = AscCommon.align_Right; + else if (value == 'justify') + type = AscCommon.align_Justify; this.api.asc_setCellAlign(type); }, onVAlignChange: function (e) { var $target = $(e.currentTarget), - type = $target.prop('value'); + value = $target.prop('value'), + type = Asc.c_oAscVAlign.Bottom; + + if (value == 'top') { + type = Asc.c_oAscVAlign.Top; + } else if (value == 'center') { + type = Asc.c_oAscVAlign.Center; + } this.api.asc_setCellVertAlign(type); }, diff --git a/apps/spreadsheeteditor/mobile/app/controller/edit/EditText.js b/apps/spreadsheeteditor/mobile/app/controller/edit/EditText.js index 08f41ec1b..ac6f5b8da 100644 --- a/apps/spreadsheeteditor/mobile/app/controller/edit/EditText.js +++ b/apps/spreadsheeteditor/mobile/app/controller/edit/EditText.js @@ -156,28 +156,28 @@ define([ // Align $('#edit-text-align-block').css('display', (_textIn == TextType.inShape) ? 'block' : 'none'); - var hAlign = _cellInfo.asc_getHorAlign() || 'left', - vAlign = _cellInfo.asc_getVertAlign() || 'bottom'; + var hAlign = _cellInfo.asc_getHorAlign(), + vAlign = _cellInfo.asc_getVertAlign(); - $('#font-left').toggleClass('active', hAlign==='left'); - $('#font-center').toggleClass('active', hAlign==='center'); - $('#font-right').toggleClass('active', hAlign==='right'); - $('#font-just').toggleClass('active', hAlign==='justify'); - $('#font-top').toggleClass('active', vAlign==='top'); - $('#font-middle').toggleClass('active', vAlign==='center'); - $('#font-bottom').toggleClass('active', vAlign==='bottom'); + $('#font-left').toggleClass('active', hAlign===AscCommon.align_Left); + $('#font-center').toggleClass('active', hAlign===AscCommon.align_Center); + $('#font-right').toggleClass('active', hAlign===AscCommon.align_Right); + $('#font-just').toggleClass('active', hAlign===AscCommon.align_Justify); + $('#font-top').toggleClass('active', vAlign===Asc.c_oAscVAlign.Top); + $('#font-middle').toggleClass('active', vAlign===Asc.c_oAscVAlign.Center); + $('#font-bottom').toggleClass('active', vAlign===Asc.c_oAscVAlign.Bottom); // Handlers $('#font-bold').single('click', _.bind(me.onBold, me)); $('#font-italic').single('click', _.bind(me.onItalic, me)); $('#font-underline').single('click', _.bind(me.onUnderline, me)); - $('#font-left').single('click', _.bind(me.onHAlign, me, 'left')); - $('#font-center').single('click', _.bind(me.onHAlign, me, 'center')); - $('#font-right').single('click', _.bind(me.onHAlign, me, 'right')); - $('#font-just').single('click', _.bind(me.onHAlign, me, 'justify')); - $('#font-top').single('click', _.bind(me.onVAlign, me, 'top')); - $('#font-middle').single('click', _.bind(me.onVAlign, me, 'center')); - $('#font-bottom').single('click', _.bind(me.onVAlign, me, 'bottom')); + $('#font-left').single('click', _.bind(me.onHAlign, me, AscCommon.align_Left)); + $('#font-center').single('click', _.bind(me.onHAlign, me, AscCommon.align_Center)); + $('#font-right').single('click', _.bind(me.onHAlign, me, AscCommon.align_Right)); + $('#font-just').single('click', _.bind(me.onHAlign, me, AscCommon.align_Justify)); + $('#font-top').single('click', _.bind(me.onVAlign, me, Asc.c_oAscVAlign.Top)); + $('#font-middle').single('click', _.bind(me.onVAlign, me, Asc.c_oAscVAlign.Center)); + $('#font-bottom').single('click', _.bind(me.onVAlign, me, Asc.c_oAscVAlign.Bottom)); }, initFontsPage: function () { @@ -283,14 +283,29 @@ define([ onHAlignChange: function (e) { var $target = $(e.currentTarget), - type = $target.prop('value'); + value = $target.prop('value'), + type = AscCommon.align_Left; + + if (value == 'center') + type = AscCommon.align_Center; + else if (value == 'right') + type = AscCommon.align_Right; + else if (value == 'justify') + type = AscCommon.align_Justify; this.api.asc_setCellAlign(type); }, onVAlignChange: function (e) { var $target = $(e.currentTarget), - type = $target.prop('value'); + value = $target.prop('value'), + type = Asc.c_oAscVAlign.Bottom; + + if (value == 'top') { + type = Asc.c_oAscVAlign.Top; + } else if (value == 'center') { + type = Asc.c_oAscVAlign.Center; + } this.api.asc_setCellVertAlign(type); }, diff --git a/apps/spreadsheeteditor/sdk_dev_scripts.js b/apps/spreadsheeteditor/sdk_dev_scripts.js index e53e7e8f5..59f1003ac 100644 --- a/apps/spreadsheeteditor/sdk_dev_scripts.js +++ b/apps/spreadsheeteditor/sdk_dev_scripts.js @@ -125,18 +125,21 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/cell/model/DrawingObjects/Format/ChartSpacePrototype.js", "../../../../sdkjs/cell/model/PivotTables.js", "../../../../sdkjs/word/Editor/DocumentContentElementBase.js", + "../../../../sdkjs/word/Editor/ParagraphContentBase.js", "../../../../sdkjs/word/Editor/Comments.js", "../../../../sdkjs/word/Editor/CommentsChanges.js", + "../../../../sdkjs/word/Editor/Bookmarks.js", "../../../../sdkjs/word/Editor/Styles.js", "../../../../sdkjs/word/Editor/StylesChanges.js", "../../../../sdkjs/word/Editor/RevisionsChange.js", "../../../../sdkjs/word/Editor/FlowObjects.js", - "../../../../sdkjs/word/Editor/ParagraphContent.js", - "../../../../sdkjs/word/Editor/ParagraphContentBase.js", + "../../../../sdkjs/word/Editor/ParagraphContent.js", "../../../../sdkjs/word/Editor/Paragraph/ParaTextPr.js", "../../../../sdkjs/word/Editor/Paragraph/ParaTextPrChanges.js", "../../../../sdkjs/word/Editor/Paragraph/ParaDrawing.js", "../../../../sdkjs/word/Editor/Paragraph/ParaDrawingChanges.js", + "../../../../sdkjs/word/Editor/Paragraph/ComplexFieldInstruction.js", + "../../../../sdkjs/word/Editor/Paragraph/ComplexField.js", "../../../../sdkjs/word/Editor/Hyperlink.js", "../../../../sdkjs/word/Editor/HyperlinkChanges.js", "../../../../sdkjs/word/Editor/Field.js", diff --git a/vendor/underscore/underscore-min.js b/vendor/underscore/underscore-min.js index f01025b7b..3c3eec027 100644 --- a/vendor/underscore/underscore-min.js +++ b/vendor/underscore/underscore-min.js @@ -3,4 +3,3 @@ // (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. (function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this); -//# sourceMappingURL=underscore-min.map \ No newline at end of file