diff --git a/apps/common/main/lib/controller/Protection.js b/apps/common/main/lib/controller/Protection.js index d7a45c1c6a..cb144953f4 100644 --- a/apps/common/main/lib/controller/Protection.js +++ b/apps/common/main/lib/controller/Protection.js @@ -153,7 +153,6 @@ define([ 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); diff --git a/apps/common/main/lib/view/OpenDialog.js b/apps/common/main/lib/view/OpenDialog.js index fce9a2ee19..5d7d7ba19d 100644 --- a/apps/common/main/lib/view/OpenDialog.js +++ b/apps/common/main/lib/view/OpenDialog.js @@ -91,6 +91,8 @@ define([ }, options); + this.txtOpenFile = options.txtOpenFile || this.txtOpenFile; + this.template = options.template || [ '
', '
', diff --git a/apps/common/main/lib/view/PasswordDialog.js b/apps/common/main/lib/view/PasswordDialog.js index 05545ad1bc..862446e9cf 100644 --- a/apps/common/main/lib/view/PasswordDialog.js +++ b/apps/common/main/lib/view/PasswordDialog.js @@ -64,13 +64,15 @@ define([ }, options); + this.handler = options.handler; + this.template = options.template || [ '
', '
', '', '
', '
', - '', + '', '
', '
', '
', @@ -81,9 +83,6 @@ define([ '
' ].join(''); - this.handler = options.handler; - this.settings = options.settings; - _options.tpl = _.template(this.template)(_options); Common.UI.Window.prototype.initialize.call(this, _options); diff --git a/apps/common/main/lib/view/Protection.js b/apps/common/main/lib/view/Protection.js index 7c607a539e..603d5bf13d 100644 --- a/apps/common/main/lib/view/Protection.js +++ b/apps/common/main/lib/view/Protection.js @@ -121,7 +121,10 @@ define([ this.btnAddPwd = new Common.UI.Button({ cls: 'btn-toolbar x-huge icon-top', iconCls: 'toolbar__icon btn-ic-protect', - caption: this.txtEncrypt + caption: this.txtEncrypt, + dataHint : '1', + dataHintDirection: 'bottom', + dataHintOffset: 'small' }); this.btnsAddPwd.push(this.btnAddPwd); @@ -130,7 +133,10 @@ define([ iconCls: 'toolbar__icon btn-ic-protect', caption: this.txtEncrypt, menu: true, - visible: false + visible: false, + dataHint : '1', + dataHintDirection: 'bottom', + dataHintOffset: 'small' }); } if (this.appConfig.isSignatureSupport) { @@ -138,7 +144,10 @@ define([ cls: 'btn-toolbar x-huge icon-top', iconCls: 'toolbar__icon btn-ic-signature', caption: this.txtSignature, - menu: (this.appPrefix !== 'pe-') + menu: (this.appPrefix !== 'pe-'), + dataHint : '1', + dataHintDirection: 'bottom', + dataHintOffset: 'small' }); if (!this.btnSignature.menu) this.btnsInvisibleSignature.push(this.btnSignature); diff --git a/apps/spreadsheeteditor/main/app.js b/apps/spreadsheeteditor/main/app.js index 2adb3fef18..74d7630244 100644 --- a/apps/spreadsheeteditor/main/app.js +++ b/apps/spreadsheeteditor/main/app.js @@ -159,6 +159,7 @@ require([ 'PivotTable', 'DataTab', 'ViewTab', + 'WBProtection', 'Common.Controllers.Fonts', 'Common.Controllers.History', 'Common.Controllers.Chat', @@ -184,6 +185,7 @@ require([ 'spreadsheeteditor/main/app/controller/PivotTable', 'spreadsheeteditor/main/app/controller/DataTab', 'spreadsheeteditor/main/app/controller/ViewTab', + 'spreadsheeteditor/main/app/controller/WBProtection', 'spreadsheeteditor/main/app/view/FileMenuPanels', 'spreadsheeteditor/main/app/view/ParagraphSettings', 'spreadsheeteditor/main/app/view/ImageSettings', diff --git a/apps/spreadsheeteditor/main/app/controller/CellEditor.js b/apps/spreadsheeteditor/main/app/controller/CellEditor.js index f6f88365fb..ba3f04cc04 100644 --- a/apps/spreadsheeteditor/main/app/controller/CellEditor.js +++ b/apps/spreadsheeteditor/main/app/controller/CellEditor.js @@ -316,6 +316,7 @@ define([ } prev_name = name; }); + this.editor.btnNamedRanges.menu.items[0].setDisabled(!!this.api.asc_isProtectedSheet()); this.editor.btnNamedRanges.menu.items[1].setVisible(rangesMenu.items.length>2); }, diff --git a/apps/spreadsheeteditor/main/app/controller/DataTab.js b/apps/spreadsheeteditor/main/app/controller/DataTab.js index bc2c3bbb29..5e965b1cc0 100644 --- a/apps/spreadsheeteditor/main/app/controller/DataTab.js +++ b/apps/spreadsheeteditor/main/app/controller/DataTab.js @@ -71,8 +71,11 @@ define([ this.api = api; this.api.asc_registerCallback('asc_onSelectionChanged', _.bind(this.onSelectionChanged, this)); this.api.asc_registerCallback('asc_onWorksheetLocked', _.bind(this.onWorksheetLocked, this)); + this.api.asc_registerCallback('asc_onChangeProtectWorkbook',_.bind(this.onChangeProtectWorkbook, this)); this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.onCoAuthoringDisconnect, this)); Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); + Common.NotificationCenter.on('protect:wslock', _.bind(this.onChangeProtectSheet, this)); + Common.NotificationCenter.on('document:ready', _.bind(this.onDocumentReady, this)); } return this; }, @@ -276,29 +279,52 @@ define([ }, onCustomSort: function() { + Common.NotificationCenter.trigger('protect:check', this.onCustomSortCallback, this); + }, + + onCustomSortCallback: function() { var me = this; if (this.api) { var res = this.api.asc_sortCellsRangeExpand(); - if (res) { - var config = { - width: 500, - title: this.toolbar.txtSorting, - msg: this.toolbar.txtExpandSort, - - buttons: [ {caption: this.toolbar.txtExpand, primary: true, value: 'expand'}, - {caption: this.toolbar.txtSortSelected, primary: true, value: 'sort'}, - 'cancel'], - callback: function(btn){ - if (btn == 'expand' || btn == 'sort') { - setTimeout(function(){ - me.showCustomSort(btn == 'expand'); - },1); + switch (res) { + case Asc.c_oAscSelectionSortExpand.showExpandMessage: + var config = { + width: 500, + title: this.toolbar.txtSorting, + msg: this.toolbar.txtExpandSort, + buttons: [ {caption: this.toolbar.txtExpand, primary: true, value: 'expand'}, + {caption: this.toolbar.txtSortSelected, primary: true, value: 'sort'}, + 'cancel'], + callback: function(btn){ + if (btn == 'expand' || btn == 'sort') { + setTimeout(function(){ + me.showCustomSort(btn == 'expand'); + },1); + } } - } - }; - Common.UI.alert(config); - } else - me.showCustomSort(res !== null); + }; + Common.UI.alert(config); + break; + case Asc.c_oAscSelectionSortExpand.showLockMessage: + var config = { + width: 500, + title: this.toolbar.txtSorting, + msg: this.toolbar.txtLockSort, + buttons: ['yes', 'no'], + primary: 'yes', + callback: function(btn){ + (btn == 'yes') && setTimeout(function(){ + me.showCustomSort(false); + },1); + } + }; + Common.UI.alert(config); + break; + case Asc.c_oAscSelectionSortExpand.expandAndNotShowMessage: + case Asc.c_oAscSelectionSortExpand.notExpandAndNotShowMessage: + me.showCustomSort(res === Asc.c_oAscSelectionSortExpand.expandAndNotShowMessage); + break; + } } }, @@ -323,7 +349,7 @@ define([ var me = this; if (this.api) { var res = this.api.asc_sortCellsRangeExpand(); - if (res) { + if (res===Asc.c_oAscSelectionSortExpand.showExpandMessage) { var config = { width: 500, title: this.txtRemDuplicates, @@ -340,8 +366,8 @@ define([ } }; Common.UI.alert(config); - } else - me.showRemDuplicates(res !== null); + } else if (res !== Asc.c_oAscSelectionSortExpand.showLockMessage) + me.showRemDuplicates(res===Asc.c_oAscSelectionSortExpand.expandAndNotShowMessage); } }, @@ -409,6 +435,10 @@ define([ } }, + onChangeProtectWorkbook: function() { + Common.Utils.lockControls(SSE.enumLock.wbLock, this.api.asc_isProtectedWorkbook(), {array: [this.view.btnDataFromText]}); + }, + onApiSheetChanged: function() { if (!this.toolbar.mode || !this.toolbar.mode.isEdit || this.toolbar.mode.isEditDiagram || this.toolbar.mode.isEditMailMerge) return; @@ -416,6 +446,18 @@ define([ this.onWorksheetLocked(currentSheet, this.api.asc_isWorksheetLockedOrDeleted(currentSheet)); }, + onChangeProtectSheet: function(props) { + if (!props) { + var wbprotect = this.getApplication().getController('WBProtection'); + props = wbprotect ? wbprotect.getWSProps() : null; + } + props && props.wsProps && Common.Utils.lockControls(SSE.enumLock['Sort'], props.wsProps['Sort'], {array: this.view.btnsSortDown.concat(this.view.btnsSortUp, this.view.btnCustomSort)}); + }, + + onDocumentReady: function() { + this.onChangeProtectSheet(); + }, + textWizard: 'Text to Columns Wizard', txtRemDuplicates: 'Remove Duplicates', txtExpandRemDuplicates: 'The data next to the selection will not be removed. Do you want to expand the selection to include the adjacent data or continue with the currently selected cells only?', diff --git a/apps/spreadsheeteditor/main/app/controller/DocumentHolder.js b/apps/spreadsheeteditor/main/app/controller/DocumentHolder.js index 86764f21d8..3706815d0e 100644 --- a/apps/spreadsheeteditor/main/app/controller/DocumentHolder.js +++ b/apps/spreadsheeteditor/main/app/controller/DocumentHolder.js @@ -176,9 +176,9 @@ define([ 'cells:range': function(status){ me.onCellsRange(status); }, - 'tabs:dragend': _.bind(me.onDragEndMouseUp, me) + 'tabs:dragend': _.bind(me.onDragEndMouseUp, me), + 'protect:wslock': _.bind(me.onChangeProtectSheet, me) }); - Common.Gateway.on('processmouse', _.bind(me.onProcessMouse, me)); }, @@ -237,7 +237,7 @@ define([ view.menuParagraphBullets.menu.on('show:after', _.bind(me.onBulletMenuShowAfter, me)); view.menuAddHyperlinkShape.on('click', _.bind(me.onInsHyperlink, me)); view.menuEditHyperlinkShape.on('click', _.bind(me.onInsHyperlink, me)); - view.menuRemoveHyperlinkShape.on('click', _.bind(me.onRemoveHyperlinkShape, me)); + view.menuRemoveHyperlinkShape.on('click', _.bind(me.onDelHyperlink, me)); view.pmiTextAdvanced.on('click', _.bind(me.onTextAdvanced, me)); view.mnuShapeAdvanced.on('click', _.bind(me.onShapeAdvanced, me)); view.mnuChartEdit.on('click', _.bind(me.onChartEdit, me)); @@ -296,6 +296,7 @@ define([ } Common.Utils.isChrome ? addEvent(document, 'mousewheel', _.bind(this.onDocumentWheel,this), { passive: false } ) : $(document).on('mousewheel', _.bind(this.onDocumentWheel, this)); + this.onChangeProtectSheet(); }, loadConfig: function(data) { @@ -425,34 +426,56 @@ define([ }, onSortCells: function(menu, item) { + Common.NotificationCenter.trigger('protect:check', this.onSortCellsCallback, this, [menu, item]); + }, + + onSortCellsCallback: function(menu, item) { if (item.value=='advanced') { Common.NotificationCenter.trigger('data:sortcustom', this); return; } if (this.api) { var res = this.api.asc_sortCellsRangeExpand(); - if (res) { - var config = { - width: 500, - title: this.txtSorting, - msg: this.txtExpandSort, - buttons: [ {caption: this.txtExpand, primary: true, value: 'expand'}, - {caption: this.txtSortSelected, primary: true, value: 'sort'}, - 'cancel'], - callback: _.bind(function(btn){ - if (btn == 'expand' || btn == 'sort') { - this.api.asc_sortColFilter(item.value, '', undefined, (item.value==Asc.c_oAscSortOptions.ByColorFill) ? this.documentHolder.ssMenu.cellColor : this.documentHolder.ssMenu.fontColor, btn == 'expand'); - } - Common.NotificationCenter.trigger('edit:complete', this.documentHolder); - Common.component.Analytics.trackEvent('DocumentHolder', 'Sort Cells'); - }, this) - }; - Common.UI.alert(config); - } else { - this.api.asc_sortColFilter(item.value, '', undefined, (item.value==Asc.c_oAscSortOptions.ByColorFill) ? this.documentHolder.ssMenu.cellColor : this.documentHolder.ssMenu.fontColor, res !== null); - - Common.NotificationCenter.trigger('edit:complete', this.documentHolder); - Common.component.Analytics.trackEvent('DocumentHolder', 'Sort Cells'); + switch (res) { + case Asc.c_oAscSelectionSortExpand.showExpandMessage: + var config = { + width: 500, + title: this.txtSorting, + msg: this.txtExpandSort, + buttons: [ {caption: this.txtExpand, primary: true, value: 'expand'}, + {caption: this.txtSortSelected, primary: true, value: 'sort'}, + 'cancel'], + callback: _.bind(function(btn){ + if (btn == 'expand' || btn == 'sort') { + this.api.asc_sortColFilter(item.value, '', undefined, (item.value==Asc.c_oAscSortOptions.ByColorFill) ? this.documentHolder.ssMenu.cellColor : this.documentHolder.ssMenu.fontColor, btn == 'expand'); + } + Common.NotificationCenter.trigger('edit:complete', this.documentHolder); + Common.component.Analytics.trackEvent('DocumentHolder', 'Sort Cells'); + }, this) + }; + Common.UI.alert(config); + break; + case Asc.c_oAscSelectionSortExpand.showLockMessage: + var config = { + width: 500, + title: this.txtSorting, + msg: this.txtLockSort, + buttons: ['yes', 'no'], + primary: 'yes', + callback: _.bind(function(btn){ + (btn == 'yes') && this.api.asc_sortColFilter(item.value, '', undefined, (item.value==Asc.c_oAscSortOptions.ByColorFill) ? this.documentHolder.ssMenu.cellColor : this.documentHolder.ssMenu.fontColor, false); + Common.NotificationCenter.trigger('edit:complete', this.documentHolder); + Common.component.Analytics.trackEvent('DocumentHolder', 'Sort Cells'); + }, this) + }; + Common.UI.alert(config); + break; + case Asc.c_oAscSelectionSortExpand.expandAndNotShowMessage: + case Asc.c_oAscSelectionSortExpand.notExpandAndNotShowMessage: + this.api.asc_sortColFilter(item.value, '', undefined, (item.value==Asc.c_oAscSortOptions.ByColorFill) ? this.documentHolder.ssMenu.cellColor : this.documentHolder.ssMenu.fontColor, res === Asc.c_oAscSelectionSortExpand.expandAndNotShowMessage); + Common.NotificationCenter.trigger('edit:complete', this.documentHolder); + Common.component.Analytics.trackEvent('DocumentHolder', 'Sort Cells'); + break; } } }, @@ -531,7 +554,16 @@ define([ win.setSettings(rangePr, dateTypes, defRangePr); }, - onClear: function(menu, item) { + onClear: function(menu, item, e) { + if (item.value == Asc.c_oAscCleanOptions.Format && !this._state.wsProps['FormatCells'] || item.value == Asc.c_oAscCleanOptions.All && !this.api.asc_checkLockedCells()) + this.onClearCallback(menu, item); + else if (item.value == Asc.c_oAscCleanOptions.Comments) { + this._state.wsProps['Objects'] ? Common.NotificationCenter.trigger('showerror', Asc.c_oAscError.ID.ChangeOnProtectedSheet, Asc.c_oAscError.Level.NoCritical) : this.onClearCallback(menu, item); + } else + Common.NotificationCenter.trigger('protect:check', this.onClearCallback, this, [menu, item]); + }, + + onClearCallback: function(menu, item) { if (this.api) { if (item.value == Asc.c_oAscCleanOptions.Comments) { this.api.asc_RemoveAllComments(!this.permissions.canDeleteComments, true);// 1 param = true if remove only my comments, 2 param - remove current comments @@ -578,6 +610,10 @@ define([ }, onInsHyperlink: function(item) { + Common.NotificationCenter.trigger('protect:check', this.onInsHyperlinkCallback, this, [item]); + }, + + onInsHyperlinkCallback: function(item) { var me = this; var win, props; @@ -625,6 +661,10 @@ define([ }, onDelHyperlink: function(item) { + Common.NotificationCenter.trigger('protect:check', this.onDelHyperlinkCallback, this); + }, + + onDelHyperlinkCallback: function(item) { if (this.api) { this.api.asc_removeHyperlink(); @@ -684,6 +724,8 @@ define([ }, onAddComment: function(item) { + if (this._state.wsProps['Objects']) return; + if (this.api && this.permissions.canCoAuthoring && this.permissions.canComments) { var controller = SSE.getController('Common.Controllers.Comments'), @@ -887,15 +929,6 @@ define([ Common.component.Analytics.trackEvent('DocumentHolder', 'List Type'); }, - onRemoveHyperlinkShape: function(item) { - if (this.api) { - this.api.asc_removeHyperlink(); - - Common.NotificationCenter.trigger('edit:complete', this.documentHolder); - Common.component.Analytics.trackEvent('DocumentHolder', 'Remove Hyperlink'); - } - }, - onTextAdvanced: function(item) { var me = this; @@ -1507,6 +1540,8 @@ define([ } if (me.permissions.isEdit) { if (!me.dlgFilter) { + if (me._state.wsProps['PivotTables'] && config.asc_getPivotObj() || me._state.wsProps['AutoFilter'] && !config.asc_getPivotObj()) return; + me.dlgFilter = new SSE.Views.AutoFilterDialog({api: this.api}).on({ 'close': function () { if (me.api) { @@ -1804,7 +1839,7 @@ define([ if (!documentHolder.copyPasteMenu || !showMenu && !documentHolder.copyPasteMenu.isVisible()) return; if (showMenu) this.showPopupMenu(documentHolder.copyPasteMenu, {}, event); } else if (isimagemenu || isshapemenu || ischartmenu) { - if (!documentHolder.imgMenu || !showMenu && !documentHolder.imgMenu.isVisible()) return; + if (!documentHolder.imgMenu || !showMenu && !documentHolder.imgMenu.isVisible() || this._state.wsProps['Objects']) return; isimagemenu = isshapemenu = ischartmenu = isslicermenu = false; documentHolder.mnuImgAdvanced.imageInfo = undefined; @@ -1893,7 +1928,7 @@ define([ documentHolder.menuSignatureEditSetup.cmpEl.attr('data-value', signGuid); // edit signature settings } } else if (istextshapemenu || istextchartmenu) { - if (!documentHolder.textInShapeMenu || !showMenu && !documentHolder.textInShapeMenu.isVisible()) return; + if (!documentHolder.textInShapeMenu || !showMenu && !documentHolder.textInShapeMenu.isVisible() || this._state.wsProps['Objects']) return; documentHolder.pmiTextAdvanced.textInfo = undefined; @@ -1970,6 +2005,8 @@ define([ item.setDisabled(isObjLocked); }); documentHolder.pmiTextCopy.setDisabled(false); + documentHolder.menuHyperlinkShape.setDisabled(isObjLocked || this._state.wsProps['InsertHyperlinks']); + documentHolder.menuAddHyperlinkShape.setDisabled(isObjLocked || this._state.wsProps['InsertHyperlinks']); //equation menu var eqlen = 0; @@ -2077,28 +2114,36 @@ define([ item.setDisabled(isCellLocked); }); documentHolder.pmiCopy.setDisabled(false); - documentHolder.pmiCut.setDisabled(isCellLocked); // can't edit pivot cells - documentHolder.pmiPaste.setDisabled(isCellLocked); - documentHolder.pmiInsertEntire.setDisabled(isCellLocked || isTableLocked); - documentHolder.pmiInsertCells.setDisabled(isCellLocked || isTableLocked || inPivot); - documentHolder.pmiInsertTable.setDisabled(isCellLocked || isTableLocked); - documentHolder.pmiDeleteEntire.setDisabled(isCellLocked || isTableLocked); - documentHolder.pmiDeleteCells.setDisabled(isCellLocked || isTableLocked || inPivot); - documentHolder.pmiDeleteTable.setDisabled(isCellLocked || isTableLocked); + documentHolder.pmiSelectTable.setDisabled(this._state.wsLock); + documentHolder.pmiInsertEntire.setDisabled(isCellLocked || isTableLocked || isrowmenu && this._state.wsProps['InsertRows'] || iscolmenu && this._state.wsProps['InsertColumns']); + documentHolder.pmiInsertCells.setDisabled(isCellLocked || isTableLocked || inPivot || this._state.wsLock); + documentHolder.pmiInsertTable.setDisabled(isCellLocked || isTableLocked || this._state.wsLock); + documentHolder.pmiDeleteEntire.setDisabled(isCellLocked || isTableLocked || isrowmenu && this._state.wsProps['DeleteRows'] || iscolmenu && this._state.wsProps['DeleteColumns']); + documentHolder.pmiDeleteCells.setDisabled(isCellLocked || isTableLocked || inPivot || this._state.wsLock); + documentHolder.pmiDeleteTable.setDisabled(isCellLocked || isTableLocked || this._state.wsLock); documentHolder.pmiClear.setDisabled(isCellLocked || 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.pmiFilterCells.setDisabled(isCellLocked || isTableLocked|| (filterInfo==null) || inPivot || !filterInfo && !this.permissions.canModifyFilter || this._state.wsLock); + documentHolder.pmiSortCells.setDisabled(isCellLocked || isTableLocked|| (filterInfo==null) || inPivot || !this.permissions.canModifyFilter || this._state.wsProps['Sort']); documentHolder.pmiReapply.setDisabled(isCellLocked || isTableLocked|| (isApplyAutoFilter!==true)); - documentHolder.pmiCondFormat.setDisabled(isCellLocked || isTableLocked); - documentHolder.menuHyperlink.setDisabled(isCellLocked || inPivot); - documentHolder.menuAddHyperlink.setDisabled(isCellLocked || inPivot); + documentHolder.pmiCondFormat.setDisabled(isCellLocked || isTableLocked || this._state.wsProps['FormatCells']); + documentHolder.menuHyperlink.setDisabled(isCellLocked || inPivot || this._state.wsProps['InsertHyperlinks']); + documentHolder.menuAddHyperlink.setDisabled(isCellLocked || inPivot || this._state.wsProps['InsertHyperlinks']); documentHolder.pmiInsFunction.setDisabled(isCellLocked || inPivot); documentHolder.pmiFreezePanes.setDisabled(this.api.asc_isWorksheetLockedOrDeleted(this.api.asc_getActiveWorksheetIndex())); + documentHolder.pmiRowHeight.setDisabled(isCellLocked || this._state.wsProps['FormatRows']); + documentHolder.pmiColumnWidth.setDisabled(isCellLocked || this._state.wsProps['FormatColumns']); + documentHolder.pmiEntireHide.setDisabled(isCellLocked || iscolmenu && this._state.wsProps['FormatColumns'] || isrowmenu && this._state.wsProps['FormatRows']); + documentHolder.pmiEntireShow.setDisabled(isCellLocked || iscolmenu && this._state.wsProps['FormatColumns'] ||isrowmenu && this._state.wsProps['FormatRows']); + documentHolder.pmiNumFormat.setDisabled(isCellLocked || this._state.wsProps['FormatCells']); + documentHolder.pmiSparklines.setDisabled(isCellLocked || this._state.wsLock); + documentHolder.pmiEntriesList.setDisabled(isCellLocked || this._state.wsLock); + documentHolder.pmiAddNamedRange.setDisabled(isCellLocked || this._state.wsLock); + documentHolder.pmiAddComment.setDisabled(isCellLocked || this._state.wsProps['Objects']); if (inPivot) { var canGroup = this.api.asc_canGroupPivot(); - documentHolder.mnuGroupPivot.setDisabled(isPivotLocked || !canGroup); - documentHolder.mnuUnGroupPivot.setDisabled(isPivotLocked || !canGroup); + documentHolder.mnuGroupPivot.setDisabled(isPivotLocked || !canGroup || this._state.wsLock); + documentHolder.mnuUnGroupPivot.setDisabled(isPivotLocked || !canGroup || this._state.wsLock); } if (showMenu) this.showPopupMenu(documentHolder.ssMenu, {}, event); @@ -2165,7 +2210,7 @@ define([ documentHolder.menuViewAddComment.setVisible(canComment); commentsController && commentsController.blockPopover(true); - documentHolder.menuViewAddComment.setDisabled(isCellLocked || isTableLocked); + documentHolder.menuViewAddComment.setDisabled(isCellLocked || isTableLocked || this._state.wsProps['Objects']); if (showMenu) this.showPopupMenu(documentHolder.viewModeMenu, {}, event); if (isInSign) { @@ -3678,6 +3723,17 @@ define([ } }, + onChangeProtectSheet: function(props) { + if (!props) { + var wbprotect = this.getApplication().getController('WBProtection'); + props = wbprotect ? wbprotect.getWSProps() : null; + } + if (props) { + this._state.wsProps = props.wsProps; + this._state.wsLock = props.wsLock; + } + }, + onShowForeignCursorLabel: function(UserId, X, Y, color) { /** coauthoring begin **/ var src; @@ -3888,7 +3944,8 @@ define([ txtImportWizard: 'Text Import Wizard', textPasteSpecial: 'Paste special', textStopExpand: 'Stop automatically expanding tables', - textAutoCorrectSettings: 'AutoCorrect options' + textAutoCorrectSettings: 'AutoCorrect options', + txtLockSort: 'Data is found next to your selection, but you do not have sufficient permissions to change those cells.
Do you wish to continue with the current selection?' }, SSE.Controllers.DocumentHolder || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js index 37b1ecf8f3..bc87c09553 100644 --- a/apps/spreadsheeteditor/main/app/controller/Main.js +++ b/apps/spreadsheeteditor/main/app/controller/Main.js @@ -213,7 +213,9 @@ define([ Common.NotificationCenter.on('download:advanced', _.bind(this.onAdvancedOptions, this)); Common.NotificationCenter.on('showmessage', _.bind(this.onExternalMessage, this)); Common.NotificationCenter.on('markfavorite', _.bind(this.markFavorite, this)); + Common.NotificationCenter.on('protect:check', _.bind(this.checkProtectedRange, this)); Common.NotificationCenter.on('editing:disable', _.bind(this.onEditingDisable, this)); + Common.NotificationCenter.on('showerror', _.bind(this.onError, this)); this.stackLongActions = new Common.IrregularStack({ strongCompare : this._compareActionStrong, @@ -1370,8 +1372,8 @@ define([ // statusbarController && statusbarController.setApi(me.api); rightmenuController && rightmenuController.setApi(me.api); - if (me.appOptions.canProtect) - application.getController('Common.Controllers.Protection').setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + application.getController('Common.Controllers.Protection').setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + application.getController('WBProtection').setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); if (statusbarController) { statusbarController.getView('Statusbar').changeViewMode(true); @@ -1787,6 +1789,10 @@ define([ config.msg = this.errorPivotWithoutUnderlying; break; + case Asc.c_oAscError.ID.ChangeOnProtectedSheet: + config.msg = this.errorChangeOnProtectedSheet; + break; + case Asc.c_oAscError.ID.SingleColumnOrRowError: config.msg = this.errorSingleColumnOrRowError; break; @@ -1795,12 +1801,23 @@ define([ config.msg = this.errorLocationOrDataRangeError; break; + case Asc.c_oAscError.ID.PasswordIsNotCorrect: + config.msg = this.errorPasswordIsNotCorrect; + break; + + case Asc.c_oAscError.ID.DeleteColumnContainsLockedCell: + config.msg = this.errorDeleteColumnContainsLockedCell; + break; + + case Asc.c_oAscError.ID.DeleteRowContainsLockedCell: + config.msg = this.errorDeleteRowContainsLockedCell; + break; + default: config.msg = (typeof id == 'string') ? id : this.errorDefaultMessage.replace('%1', id); break; } - if (level == Asc.c_oAscError.Level.Critical) { Common.Gateway.reportError(id, config.msg); @@ -2108,7 +2125,7 @@ define([ } }, - onConfirmAction: function(id, apiCallback) { + onConfirmAction: function(id, apiCallback, data) { var me = this; if (id == Asc.c_oAscConfirm.ConfirmReplaceRange || id == Asc.c_oAscConfirm.ConfirmReplaceFormulaInTable) { Common.UI.warning({ @@ -2139,6 +2156,68 @@ define([ me.onEditComplete(me.application.getController('DocumentHolder').getView('DocumentHolder')); }, this) }); + } else if (id == Asc.c_oAscConfirm.ConfirmChangeProtectRange) { + var win = new Common.Views.OpenDialog({ + title: this.txtUnlockRange, + closable: true, + type: Common.Utils.importTextType.DRM, + warning: true, + warningMsg: this.txtUnlockRangeWarning, + txtOpenFile: this.txtUnlockRangeDescription, + validatePwd: false, + handler: function (result, value) { + if (me.api && apiCallback) { + apiCallback((result == 'ok') ? me.api.asc_checkProtectedRangesPassword(value.drmOptions.asc_getPassword(), data) : false, result !== 'ok'); + } + me.onEditComplete(me.application.getController('DocumentHolder').getView('DocumentHolder')); + } + }); + win.show(); + } + }, + + checkProtectedRange: function(callback, scope, args) { + var result = this.api.asc_isProtectedSheet() ? this.api.asc_checkProtectedRange() : false; + if (result===null) { + this.onError(Asc.c_oAscError.ID.ChangeOnProtectedSheet, Asc.c_oAscError.Level.NoCritical); + return; + } + + if (result) { + var me = this; + var win = new Common.Views.OpenDialog({ + title: this.txtUnlockRange, + closable: true, + type: Common.Utils.importTextType.DRM, + warning: true, + warningMsg: this.txtUnlockRangeWarning, + txtOpenFile: this.txtUnlockRangeDescription, + validatePwd: false, + handler: function (result, value) { + if (result == 'ok') { + if (me.api) { + if (me.api.asc_checkActiveCellPassword(value.drmOptions.asc_getPassword())) { + callback && setTimeout(function() { + callback.apply(scope, args); + }, 1); + } else { + Common.UI.warning({ + msg: me.errorWrongPassword, + callback: function() { + Common.NotificationCenter.trigger('edit:complete', me.toolbar); + } + }); + } + } + } + Common.NotificationCenter.trigger('edit:complete', me.toolbar); + } + }); + win.show(); + } else { + callback && setTimeout(function() { + callback.apply(scope, args); + }, 1); } }, @@ -3231,15 +3310,24 @@ define([ errorPivotWithoutUnderlying: 'The Pivot Table report was saved without the underlying data.
Use the \'Refresh\' button to update the report.', txtQuarter: 'Qtr', txtOr: '%1 or %2', - errorLang: 'The interface language is not loaded.
Please contact your Document Server administrator.', confirmReplaceFormulaInTable: 'Formulas in the header row will be removed and converted to static text.
Do you want to continue?', + errorChangeOnProtectedSheet: 'The cell or chart you are trying to change is on a protected sheet.
To make a change, unprotect the sheet. You might be requested to enter a password.', + txtUnlockRange: 'Unlock Range', + txtUnlockRangeWarning: 'A range you are trying to change is password protected.', + txtUnlockRangeDescription: 'Enter the password to change this range:', + txtUnlock: 'Unlock', + errorWrongPassword: 'The password you supplied is not correct.', + errorLang: 'The interface language is not loaded.
Please contact your Document Server administrator.', textDisconnect: 'Connection is lost', textConvertEquation: 'This equation was created with an old version of equation editor which is no longer supported. Converting this equation to Office Math ML format will make it editable.
Do you want to convert this equation?', textApplyAll: 'Apply to all equations', textLearnMore: 'Learn More', errorSingleColumnOrRowError: 'Location reference is not valid because the cells are not all in the same column or row.
Select cells that are all in a single column or row.', errorLocationOrDataRangeError: 'The reference for the location or data range is not valid.', - txtErrorLoadHistory: 'Loading history failed' + txtErrorLoadHistory: 'Loading history failed', + errorPasswordIsNotCorrect: 'The password you supplied is not correct.
Verify that the CAPS LOCK key is off and be sure to use the correct capitalization.', + errorDeleteColumnContainsLockedCell: 'You are trying to delete a column that contains a locked cell. Locked cells cannot be deleted while the worksheet is protected.
To delete a locked cell, unprotect the sheet. You might be requested to enter a password.', + errorDeleteRowContainsLockedCell: 'You are trying to delete a row that contains a locked cell. Locked cells cannot be deleted while the worksheet is protected.
To delete a locked cell, unprotect the sheet. You might be requested to enter a password.' } })(), SSE.Controllers.Main || {})) }); diff --git a/apps/spreadsheeteditor/main/app/controller/RightMenu.js b/apps/spreadsheeteditor/main/app/controller/RightMenu.js index 76477378c7..be2acfa894 100644 --- a/apps/spreadsheeteditor/main/app/controller/RightMenu.js +++ b/apps/spreadsheeteditor/main/app/controller/RightMenu.js @@ -104,6 +104,7 @@ define([ 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)); + Common.NotificationCenter.on('protect:wslock', _.bind(this.onChangeProtectSheet, this)); }, setMode: function(mode) { @@ -138,7 +139,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.Signature) ? undefined : props); + panel.ChangeSettings.call(panel, (type==Common.Utils.documentSettingsType.Signature) ? undefined : props, this._state.wsLock, this._state.wsProps); } Common.NotificationCenter.trigger('layout:changed', 'rightmenu'); }, @@ -171,10 +172,10 @@ define([ if (!this.editMode) return; - var isCellLocked = cellInfo.asc_getLocked(), - isTableLocked = (cellInfo.asc_getLockedTable()===true || !this.rightmenu.mode.canModifyFilter), - isSparkLocked = (cellInfo.asc_getLockedSparkline()===true), - isPivotLocked = (cellInfo.asc_getLockedPivotTable()===true); + var isCellLocked = cellInfo.asc_getLocked() || this._state.wsProps['FormatCells'], + isTableLocked = (cellInfo.asc_getLockedTable()===true || !this.rightmenu.mode.canModifyFilter) || this._state.wsProps['FormatCells'], + isSparkLocked = (cellInfo.asc_getLockedSparkline()===true) || this._state.wsLock, + isPivotLocked = (cellInfo.asc_getLockedPivotTable()===true) || this._state.wsProps['PivotTables']; for (var i=0; i 0) { item = this.statusbar.tabbar.getAt(i); @@ -171,11 +173,12 @@ define([ onWorksheetLocked: function(index,locked) { var count = this.statusbar.tabbar.getCount(), tab; + var wbprotected = this.api.asc_isProtectedWorkbook(); for (var i = count; i-- > 0; ) { tab = this.statusbar.tabbar.getAt(i); if (index == tab.sheetindex) { tab[locked?'addClass':'removeClass']('coauth-locked'); - tab.isLockTheDrag = locked || (this.statusbar.rangeSelectionMode==Asc.c_oAscSelectionDialogType.FormatTable) || (this.statusbar.rangeSelectionMode==Asc.c_oAscSelectionDialogType.PrintTitles); + tab.isLockTheDrag = locked || wbprotected || (this.statusbar.rangeSelectionMode==Asc.c_oAscSelectionDialogType.FormatTable) || (this.statusbar.rangeSelectionMode==Asc.c_oAscSelectionDialogType.PrintTitles); tab.$el.children(':first-child').attr('draggable', tab.isLockTheDrag?'false':'true'); break; } @@ -185,6 +188,19 @@ define([ listItem.setDisabled(locked); } }, + + onChangeProtectWorkbook: function() { + this.statusbar.btnAddWorksheet.setDisabled(this.api.isCellEdited || this.api.asc_isWorkbookLocked() || this.api.asc_isProtectedWorkbook() || this.statusbar.rangeSelectionMode!=Asc.c_oAscSelectionDialogType.None); + var count = this.statusbar.tabbar.getCount(), tab; + var wbprotected = this.api.asc_isProtectedWorkbook(); + for (var i = count; i-- > 0; ) { + tab = this.statusbar.tabbar.getAt(i); + var islocked = tab.hasClass('coauth-locked'); + tab.isLockTheDrag = islocked || wbprotected || (this.statusbar.rangeSelectionMode==Asc.c_oAscSelectionDialogType.FormatTable) || (this.statusbar.rangeSelectionMode==Asc.c_oAscSelectionDialogType.PrintTitles); + tab.$el.children(':first-child').attr('draggable', tab.isLockTheDrag?'false':'true'); + } + }, + /** coauthoring end **/ onApiMathChanged: function(info) { @@ -218,7 +234,7 @@ define([ statusbar.btnZoomUp.setDisabled(disable); statusbar.btnZoomDown.setDisabled(disable); statusbar.labelZoom[disable?'addClass':'removeClass']('disabled'); - statusbar.btnAddWorksheet.setDisabled(disable || this.api.asc_isWorkbookLocked() || statusbar.rangeSelectionMode!=Asc.c_oAscSelectionDialogType.None); + statusbar.btnAddWorksheet.setDisabled(disable || this.api.asc_isWorkbookLocked() || this.api.asc_isProtectedWorkbook() || statusbar.rangeSelectionMode!=Asc.c_oAscSelectionDialogType.None); statusbar.$el.find('#statusbar_bottom li span').attr('oo_editor_input', !disableAdd); @@ -249,16 +265,17 @@ define([ onRangeDialogMode: function (mode) { var islocked = this.statusbar.tabbar.hasClass('coauth-locked'), currentIdx = this.api.asc_getActiveWorksheetIndex(); - this.statusbar.btnAddWorksheet.setDisabled(islocked || this.api.isCellEdited || mode!=Asc.c_oAscSelectionDialogType.None); + this.statusbar.btnAddWorksheet.setDisabled(islocked || this.api.isCellEdited || this.api.asc_isProtectedWorkbook() || mode!=Asc.c_oAscSelectionDialogType.None); this.statusbar.btnSheetList[mode==Asc.c_oAscSelectionDialogType.FormatTable || mode==Asc.c_oAscSelectionDialogType.PrintTitles ? 'addClass' : 'removeClass']('disabled'); var item, i = this.statusbar.tabbar.getCount(); + var wbprotected = this.api.asc_isProtectedWorkbook(); while (i-- > 0) { item = this.statusbar.tabbar.getAt(i); if (item.sheetindex !== currentIdx) { item.disable(mode==Asc.c_oAscSelectionDialogType.FormatTable || mode==Asc.c_oAscSelectionDialogType.PrintTitles); } - item.isLockTheDrag = (item.hasClass('coauth-locked') || (mode!=Asc.c_oAscSelectionDialogType.None)); + item.isLockTheDrag = (item.hasClass('coauth-locked') || wbprotected || (mode!=Asc.c_oAscSelectionDialogType.None)); } this.statusbar.rangeSelectionMode = mode; }, @@ -297,6 +314,9 @@ define([ me.hideWorksheet(true, arrIndex); }, 1); break; + case 'protect': + this.protectWorksheet(); + break; } }, @@ -787,6 +807,10 @@ define([ this._sheetViewTip.hide(); }, + protectWorksheet: function() { + Common.NotificationCenter.trigger('protect:sheet', !this.api.asc_isProtectedSheet()); + }, + zoomText : 'Zoom {0}%', errorLastSheet : 'Workbook must have at least one visible worksheet.', errorRemoveSheet: 'Can\'t delete the worksheet.', diff --git a/apps/spreadsheeteditor/main/app/controller/Toolbar.js b/apps/spreadsheeteditor/main/app/controller/Toolbar.js index 440db16d71..29c9a68bb6 100644 --- a/apps/spreadsheeteditor/main/app/controller/Toolbar.js +++ b/apps/spreadsheeteditor/main/app/controller/Toolbar.js @@ -171,10 +171,6 @@ define([ merge: undefined, angle: undefined, controlsdisabled: { - rows: undefined, - cols: undefined, - cells_right: undefined, - cells_down: undefined, filters: undefined }, selection_type: undefined, @@ -195,7 +191,9 @@ define([ pgorient: undefined, lock_doc: undefined, cf_locked: [], - selectedCells: 0 + selectedCells: 0, + wsLock: false, + wsProps: [] }; this.binding = {}; @@ -913,6 +911,10 @@ define([ }, onHyperlink: function(btn) { + Common.NotificationCenter.trigger('protect:check', this.onHyperlinkCallback, this, [btn]); + }, + + onHyperlinkCallback: function(btn) { var me = this; var win, props; @@ -1181,6 +1183,10 @@ define([ }, onSortType: function(type, btn) { + Common.NotificationCenter.trigger('protect:check', this.onSortTypeCallback, this, [type, btn]); + }, + + onSortTypeCallback: function(type, btn) { if (this.api) { if (this.api.asc_getCellInfo().asc_getSelectionType()==Asc.c_oAscSelectionType.RangeSlicer) { var selectedObjects = this.api.asc_getGraphicObjectProps(); @@ -1196,25 +1202,43 @@ define([ } Common.NotificationCenter.trigger('edit:complete', this.toolbar); } else { + var me = this; var res = this.api.asc_sortCellsRangeExpand(); - if (res) { - var config = { - width: 500, - title: this.txtSorting, - msg: this.txtExpandSort, - - buttons: [ {caption: this.txtExpand, primary: true, value: 'expand'}, - {caption: this.txtSortSelected, primary: true, value: 'sort'}, - 'cancel'], - callback: _.bind(function(btn){ - if (btn == 'expand' || btn == 'sort') { - this.api.asc_sortColFilter(type, '', undefined, undefined, btn == 'expand'); + switch (res) { + case Asc.c_oAscSelectionSortExpand.showExpandMessage: + var config = { + width: 500, + title: this.txtSorting, + msg: this.txtExpandSort, + buttons: [ {caption: this.txtExpand, primary: true, value: 'expand'}, + {caption: this.txtSortSelected, primary: true, value: 'sort'}, + 'cancel'], + callback: function(btn){ + if (btn == 'expand' || btn == 'sort') { + me.api.asc_sortColFilter(type, '', undefined, undefined, btn == 'expand') + } } - }, this) - }; - Common.UI.alert(config); - } else - this.api.asc_sortColFilter(type, '', undefined, undefined, res !== null); + }; + Common.UI.alert(config); + break; + case Asc.c_oAscSelectionSortExpand.showLockMessage: + var config = { + width: 500, + title: this.txtSorting, + msg: this.txtLockSort, + buttons: ['yes', 'no'], + primary: 'yes', + callback: function(btn){ + (btn == 'yes') && me.api.asc_sortColFilter(type, '', undefined, undefined, false); + } + }; + Common.UI.alert(config); + break; + case Asc.c_oAscSelectionSortExpand.expandAndNotShowMessage: + case Asc.c_oAscSelectionSortExpand.notExpandAndNotShowMessage: + this.api.asc_sortColFilter(type, '', undefined, undefined, res === Asc.c_oAscSelectionSortExpand.expandAndNotShowMessage); + break; + } } } }, @@ -1456,6 +1480,16 @@ define([ }, onClearStyleMenu: function(menu, item, e) { + if (item.value == Asc.c_oAscCleanOptions.Format && (!this._state.wsProps['FormatCells'] || !this.api.asc_checkLockedCells()) || + item.value == Asc.c_oAscCleanOptions.All && !this.api.asc_checkLockedCells()) + this.onClearStyleMenuCallback(menu, item); + else if (item.value == Asc.c_oAscCleanOptions.Comments) { + this._state.wsProps['Objects'] ? Common.NotificationCenter.trigger('showerror', Asc.c_oAscError.ID.ChangeOnProtectedSheet, Asc.c_oAscError.Level.NoCritical) : this.onClearStyleMenuCallback(menu, item); + } else + Common.NotificationCenter.trigger('protect:check', this.onClearStyleMenuCallback, this, [menu, item]); + }, + + onClearStyleMenuCallback: function(menu, item, e) { if (this.api) { if (item.value == Asc.c_oAscCleanOptions.Comments) { this.api.asc_RemoveAllComments(!this.mode.canDeleteComments, true);// 1 param = true if remove only my comments, 2 param - remove current comments @@ -1802,6 +1836,7 @@ define([ this.api.asc_registerCallback('asc_onUpdateDocumentProps', _.bind(this.onUpdateDocumentProps, this)); this.api.asc_registerCallback('asc_onLockDocumentProps', _.bind(this.onApiLockDocumentProps, this)); this.api.asc_registerCallback('asc_onUnLockDocumentProps', _.bind(this.onApiUnLockDocumentProps, this)); + Common.NotificationCenter.on('protect:wslock', _.bind(this.onChangeProtectSheet, this)); } if ( !this.appConfig.isEditMailMerge ) { @@ -1817,7 +1852,7 @@ define([ var shortcuts = { 'command+l,ctrl+l': function(e) { - if ( me.editMode && !me._state.multiselect && me.appConfig.canModifyFilter) { + if ( me.editMode && !me._state.multiselect && me.appConfig.canModifyFilter && !me._state.wsLock) { var cellinfo = me.api.asc_getCellInfo(), filterinfo = cellinfo.asc_getAutoFilterInfo(), formattableinfo = cellinfo.asc_getFormatTableInfo(); @@ -1830,7 +1865,7 @@ define([ return false; }, 'command+shift+l,ctrl+shift+l': function(e) { - if (me.editMode && me.api && !me._state.multiselect && me.appConfig.canModifyFilter) { + if (me.editMode && me.api && !me._state.multiselect && me.appConfig.canModifyFilter && !me._state.wsLock) { var state = me._state.filter; me._state.filter = undefined; @@ -1849,7 +1884,7 @@ define([ }, 'command+k,ctrl+k': function (e) { if (me.editMode && !me.toolbar.mode.isEditMailMerge && !me.toolbar.mode.isEditDiagram && !me.api.isCellEdited && !me._state.multiselect && !me._state.inpivot && - !me.getApplication().getController('LeftMenu').leftMenu.menuFile.isVisible()) { + !me.getApplication().getController('LeftMenu').leftMenu.menuFile.isVisible() && !me._state.wsProps['InsertHyperlinks']) { var cellinfo = me.api.asc_getCellInfo(), selectionType = cellinfo.asc_getSelectionType(); if (selectionType !== Asc.c_oAscSelectionType.RangeShapeText || me.api.asc_canAddShapeHyperlink()!==false) @@ -1880,14 +1915,18 @@ define([ var cellinfo = me.api.asc_getCellInfo(), selectionType = cellinfo.asc_getSelectionType(); if (selectionType === Asc.c_oAscSelectionType.RangeRow || selectionType === Asc.c_oAscSelectionType.RangeCol) { - me.api.asc_insertCells(selectionType === Asc.c_oAscSelectionType.RangeRow ? Asc.c_oAscInsertOptions.InsertRows :Asc.c_oAscInsertOptions.InsertColumns ); + (selectionType === Asc.c_oAscSelectionType.RangeRow) && !me.toolbar.btnAddCell.menu.items[2].isDisabled() && me.api.asc_insertCells(Asc.c_oAscInsertOptions.InsertRows); + (selectionType === Asc.c_oAscSelectionType.RangeCol) && !me.toolbar.btnAddCell.menu.items[3].isDisabled() && me.api.asc_insertCells(Asc.c_oAscInsertOptions.InsertColumns); Common.NotificationCenter.trigger('edit:complete', me.toolbar); } else { var items = me.toolbar.btnAddCell.menu.items, - arr = []; - for (var i=0; i<4; i++) + arr = [], + enabled = false; + for (var i=0; i<4; i++) { arr.push({caption: items[i].caption, value: items[i].value, disabled: items[i].isDisabled()}); - (new Common.Views.OptionsDialog({ + !items[i].isDisabled() && (enabled = true); + } + enabled && (new Common.Views.OptionsDialog({ title: me.txtInsertCells, items: arr, handler: function (dlg, result) { @@ -1911,10 +1950,13 @@ define([ Common.NotificationCenter.trigger('edit:complete', me.toolbar); } else { var items = me.toolbar.btnDeleteCell.menu.items, - arr = []; - for (var i=0; i<4; i++) + arr = [], + enabled = false; + for (var i=0; i<4; i++) { arr.push({caption: items[i].caption, value: items[i].value, disabled: items[i].isDisabled()}); - (new Common.Views.OptionsDialog({ + !items[i].isDisabled() && (enabled = true); + } + enabled && (new Common.Views.OptionsDialog({ title: me.txtDeleteCells, items: arr, handler: function (dlg, result) { @@ -1931,7 +1973,7 @@ define([ }; Common.util.Shortcuts.delegateShortcuts({shortcuts: shortcuts}); - this.onApiSelectionChanged(this.api.asc_getCellInfo()); + this.onChangeProtectSheet(); this.attachToControlEvents(); this.onApiSheetChanged(); @@ -2486,6 +2528,15 @@ define([ toolbar.btnImgAlign.menu.items[7].setDisabled(objcount<3); toolbar.btnImgAlign.menu.items[8].setDisabled(objcount<3); + // disable on protected sheet + // lock formatting controls in cell with FormatCells protection or in shape and Objects protection + need_disable = (selectionType === Asc.c_oAscSelectionType.RangeImage || selectionType === Asc.c_oAscSelectionType.RangeChart || selectionType === Asc.c_oAscSelectionType.RangeChartText || + selectionType === Asc.c_oAscSelectionType.RangeShape || selectionType === Asc.c_oAscSelectionType.RangeShapeText || selectionType === Asc.c_oAscSelectionType.RangeSlicer); + toolbar.lockToolbar(SSE.enumLock.wsLockFormat, need_disable && !!this._state.wsProps['Objects'] || !need_disable && !!this._state.wsProps['FormatCells']); + + toolbar.lockToolbar(SSE.enumLock['Objects'], !!this._state.wsProps['Objects']); + toolbar.lockToolbar(SSE.enumLock['FormatCells'], !!this._state.wsProps['FormatCells']); + if (editOptionsDisabled) return; /* read font params */ @@ -2798,30 +2849,48 @@ define([ } } - val = (selectionType==Asc.c_oAscSelectionType.RangeRow); - if ( this._state.controlsdisabled.rows!==val ) { - this._state.controlsdisabled.rows=val; - toolbar.btnAddCell.menu.items[3].setDisabled(val); - toolbar.btnDeleteCell.menu.items[3].setDisabled(val); - } - val = (selectionType==Asc.c_oAscSelectionType.RangeCol); - if ( this._state.controlsdisabled.cols!==val ) { - this._state.controlsdisabled.cols=val; - toolbar.btnAddCell.menu.items[2].setDisabled(val); - toolbar.btnDeleteCell.menu.items[2].setDisabled(val); - } + var selCol = selectionType==Asc.c_oAscSelectionType.RangeCol, + selRow = selectionType==Asc.c_oAscSelectionType.RangeRow, + selMax = selectionType==Asc.c_oAscSelectionType.RangeMax; + + need_disable = selRow || selMax && this._state.wsLock || this._state.wsProps['InsertColumns']; + toolbar.btnAddCell.menu.items[3].setDisabled(need_disable); + + need_disable = selRow || selMax && this._state.wsLock || !selCol && this._state.wsLock || this._state.wsProps['DeleteColumns']; + toolbar.btnDeleteCell.menu.items[3].setDisabled(need_disable); + + need_disable = selCol || selMax && this._state.wsLock || this._state.wsProps['InsertRows']; + toolbar.btnAddCell.menu.items[2].setDisabled(need_disable); + + need_disable = selCol || selMax && this._state.wsLock || !selRow && this._state.wsLock || this._state.wsProps['DeleteRows']; + toolbar.btnDeleteCell.menu.items[2].setDisabled(need_disable); val = filterInfo && filterInfo.asc_getIsApplyAutoFilter(); - if ( this._state.controlsdisabled.cells_right!==(this._state.controlsdisabled.rows || val) ) { - this._state.controlsdisabled.cells_right = (this._state.controlsdisabled.rows || val); - toolbar.btnAddCell.menu.items[0].setDisabled(this._state.controlsdisabled.cells_right); - toolbar.btnDeleteCell.menu.items[0].setDisabled(this._state.controlsdisabled.cells_right); + need_disable = selRow || val || !(selCol || selMax) && this._state.wsLock || selCol && this._state.wsProps['InsertColumns'] || selMax && this._state.wsProps['InsertColumns'] && this._state.wsProps['InsertRows']; + toolbar.btnAddCell.menu.items[0].setDisabled(need_disable); + + need_disable = selRow || val || !(selCol || selMax) && this._state.wsLock || selCol && this._state.wsProps['DeleteColumns'] || selMax && this._state.wsProps['DeleteColumns'] && this._state.wsProps['DeleteRows']; + toolbar.btnDeleteCell.menu.items[0].setDisabled(need_disable); + + need_disable = selCol || val || !(selRow || selMax) && this._state.wsLock || selRow && this._state.wsProps['InsertRows'] || selMax && this._state.wsProps['InsertColumns'] && this._state.wsProps['InsertRows']; + toolbar.btnAddCell.menu.items[1].setDisabled(need_disable); + + need_disable = selCol || val || !(selRow || selMax) && this._state.wsLock || selRow && this._state.wsProps['DeleteRows'] || selMax && this._state.wsProps['DeleteColumns'] && this._state.wsProps['DeleteRows']; + toolbar.btnDeleteCell.menu.items[1].setDisabled(need_disable); + + var items = toolbar.btnAddCell.menu.items, + enabled = false; + for (var i=0; i<4; i++) { + !items[i].isDisabled() && (enabled = true); } - if ( this._state.controlsdisabled.cells_down!==(this._state.controlsdisabled.cols || val) ) { - this._state.controlsdisabled.cells_down = (this._state.controlsdisabled.cols || val); - toolbar.btnAddCell.menu.items[1].setDisabled(this._state.controlsdisabled.cells_down); - toolbar.btnDeleteCell.menu.items[1].setDisabled(this._state.controlsdisabled.cells_down); + toolbar.lockToolbar(SSE.enumLock.itemsDisabled, !enabled, {array: [toolbar.btnAddCell]}); + + items = me.toolbar.btnDeleteCell.menu.items; + enabled = false; + for (var i=0; i<4; i++) { + !items[i].isDisabled() && (enabled = true); } + toolbar.lockToolbar(SSE.enumLock.itemsDisabled, !enabled, {array: [toolbar.btnDeleteCell]}); // info.asc_getComments()===null - has comment, but no permissions to view it toolbar.lockToolbar(SSE.enumLock.commentLock, (selectionType == Asc.c_oAscSelectionType.RangeCells) && (!info.asc_getComments() || info.asc_getComments().length>0 || info.asc_getLocked()) || @@ -3185,6 +3254,10 @@ define([ }, onInsertSymbolClick: function() { + Common.NotificationCenter.trigger('protect:check', this.onInsertSymbolClickCallback, this, []); + }, + + onInsertSymbolClickCallback: function() { if (this.api) { var me = this, selected = me.api.asc_GetSelectedText(), @@ -3690,13 +3763,14 @@ define([ me.toolbar.btnCopy.$el.removeClass('split'); } - if ( config.isDesktopApp ) { - if ( config.canProtect ) { - var tab = {action: 'protect', caption: me.toolbar.textTabProtect}; - var $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel(); - if ($panel) - me.toolbar.addTab(tab, $panel, 7); - } + var tab = {action: 'protect', caption: me.toolbar.textTabProtect}; + var $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel(); + if ($panel) { + config.canProtect && $panel.append($('
')); + var wbtab = me.getApplication().getController('WBProtection'); + $panel.append(wbtab.createToolbarPanel()); + me.toolbar.addTab(tab, $panel, 7); + Array.prototype.push.apply(me.toolbar.lockControls, wbtab.getView('WBProtection').getButtons()); } var viewtab = me.getApplication().getController('ViewTab'); @@ -3713,7 +3787,8 @@ define([ this.btnsComment = []; if ( config.canCoAuthoring && config.canComments ) { var _set = SSE.enumLock; - this.btnsComment = Common.Utils.injectButtons(this.toolbar.$el.find('.slot-comment'), 'tlbtn-addcomment-', 'toolbar__icon btn-menu-comments', this.toolbar.capBtnComment, [_set.lostConnect, _set.commentLock, _set.editCell], undefined, undefined, undefined, '1', 'bottom', 'small'); + this.btnsComment = Common.Utils.injectButtons(this.toolbar.$el.find('.slot-comment'), 'tlbtn-addcomment-', 'toolbar__icon btn-menu-comments', this.toolbar.capBtnComment, + [_set.lostConnect, _set.commentLock, _set.editCell, _set['Objects']], undefined, undefined, undefined, '1', 'bottom', 'small'); if ( this.btnsComment.length ) { var _comments = SSE.getController('Common.Controllers.Comments').getView(); @@ -3967,6 +4042,21 @@ define([ Common.NotificationCenter.trigger('edit:complete', this.toolbar); }, + onChangeProtectSheet: function(props) { + if (!props) { + var wbprotect = this.getApplication().getController('WBProtection'); + props = wbprotect ? wbprotect.getWSProps() : null; + } + if (props) { + this._state.wsProps = props.wsProps; + this._state.wsLock = props.wsLock; + + this.toolbar.lockToolbar(SSE.enumLock.wsLock, this._state.wsLock); + this.toolbar.lockToolbar(SSE.enumLock['InsertHyperlinks'], this._state.wsProps['InsertHyperlinks'], {array: [this.toolbar.btnInsertHyperlink]}); + this.onApiSelectionChanged(this.api.asc_getCellInfo()); + } + }, + textEmptyImgUrl : 'You need to specify image URL.', warnMergeLostData : 'Operation can destroy data in the selected cells.
Continue?', textWarning : 'Warning', @@ -4333,7 +4423,8 @@ define([ textDirectional: 'Directional', textShapes: 'Shapes', textIndicator: 'Indicators', - textRating: 'Ratings' + textRating: 'Ratings', + txtLockSort: 'Data is found next to your selection, but you do not have sufficient permissions to change those cells.
Do you wish to continue with the current selection?' }, SSE.Controllers.Toolbar || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/controller/WBProtection.js b/apps/spreadsheeteditor/main/app/controller/WBProtection.js new file mode 100644 index 0000000000..53ae60bd0c --- /dev/null +++ b/apps/spreadsheeteditor/main/app/controller/WBProtection.js @@ -0,0 +1,362 @@ +/* + * + * (c) Copyright Ascensio System SIA 2010-2021 + * + * 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 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * 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 + * + */ + +/** + * WBProtection.js + * + * Created by Julia Radzhabova on 21.06.2021 + * Copyright (c) 2021Ascensio System SIA. All rights reserved. + * + */ +define([ + 'core', + 'common/main/lib/view/Protection', + 'spreadsheeteditor/main/app/view/WBProtection', + 'spreadsheeteditor/main/app/view/ProtectDialog', + 'spreadsheeteditor/main/app/view/ProtectRangesDlg' +], function () { + 'use strict'; + + SSE.Controllers.WBProtection = Backbone.Controller.extend(_.extend({ + models : [], + collections : [ + ], + views : [ + 'WBProtection' + ], + sdkViewName : '#id_main', + + initialize: function () { + + this.addListeners({ + 'WBProtection': { + 'protect:workbook': _.bind(this.onWorkbookClick, this), + 'protect:sheet': _.bind(this.onSheetClick, this), + 'protect:ranges': _.bind(this.onRangesClick, this), + 'protect:lock-options': _.bind(this.onLockOptionClick, this) + } + }); + }, + onLaunch: function () { + this._state = {}; + this.wsLockOptions = ['SelectLockedCells', 'SelectUnlockedCells', 'FormatCells', 'FormatColumns', 'FormatRows', 'InsertColumns', 'InsertRows', 'InsertHyperlinks', 'DeleteColumns', + 'DeleteRows', 'Sort', 'AutoFilter', 'PivotTables', 'Objects', 'Scenarios']; + SSE.enumLock && this.wsLockOptions.forEach(function(item){ + SSE.enumLock[item] = item; + }); + + Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); + Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); + Common.NotificationCenter.on('protect:sheet', _.bind(this.onSheetClick, 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_onChangeProtectWorkbook',_.bind(this.onChangeProtectWorkbook, this)); + this.api.asc_registerCallback('asc_onChangeProtectWorksheet',_.bind(this.onChangeProtectSheet, this)); + this.api.asc_registerCallback('asc_onActiveSheetChanged', _.bind(this.onActiveSheetChanged, this)); + this.api.asc_registerCallback('asc_onSelectionChanged', _.bind(this.onApiSelectionChanged, this)); + this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.onCoAuthoringDisconnect, this)); + } + }, + + setMode: function(mode) { + this.appConfig = mode; + + this.view = this.createView('WBProtection', { + mode: mode + }); + + return this; + }, + + createToolbarPanel: function() { + return this.view.getPanel(); + }, + + getView: function(name) { + return !name && this.view ? + this.view : Backbone.Controller.prototype.getView.call(this, name); + }, + + onWorkbookClick: function(state) { + if (state) { + var me = this, + btn, + win = new SSE.Views.ProtectDialog({ + type: 'workbook', + handler: function(result, value) { + btn = result; + if (result == 'ok') { + var props = me.api.asc_getProtectedWorkbook(); + props.asc_setLockStructure(true); + value && props.asc_setPassword(value); + me.api.asc_setProtectedWorkbook(props); + } + Common.NotificationCenter.trigger('edit:complete'); + } + }).on('close', function() { + if (btn!=='ok') + me.view.btnProtectWB.toggle(false, true); + }); + + win.show(); + } else { + var me = this, + btn, + props = me.api.asc_getProtectedWorkbook(); + if (props.asc_isPassword()) { + var win = new Common.Views.OpenDialog({ + title: me.view.txtWBUnlockTitle, + closable: true, + type: Common.Utils.importTextType.DRM, + txtOpenFile: me.view.txtWBUnlockDescription, + validatePwd: false, + handler: function (result, value) { + btn = result; + if (result == 'ok') { + if (me.api) { + props.asc_setLockStructure(false, value); + me.api.asc_setProtectedWorkbook(props); + } + Common.NotificationCenter.trigger('edit:complete'); + } + } + }).on('close', function() { + if (btn!=='ok') + me.view.btnProtectWB.toggle(true, true); + }); + + win.show(); + } else { + props.asc_setLockStructure(false); + me.api.asc_setProtectedWorkbook(props); + } + } + }, + + onSheetClick: function(state) { + if (state) { + var me = this, + btn, + props = me.api.asc_getProtectedSheet(), + win = new SSE.Views.ProtectDialog({ + type: 'sheet', + props: props, + handler: function(result, value, props) { + btn = result; + if (result == 'ok') { + props.asc_setSheet(true); + value && props.asc_setPassword(value); + me.api.asc_setProtectedSheet(props); + } + Common.NotificationCenter.trigger('edit:complete'); + } + }).on('close', function() { + if (btn!=='ok') + me.view.btnProtectSheet.toggle(false, true); + }); + + win.show(); + } else { + var me = this, + btn, + props = me.api.asc_getProtectedSheet(); + if (props.asc_isPassword()) { + var win = new Common.Views.OpenDialog({ + title: me.view.txtSheetUnlockTitle, + closable: true, + type: Common.Utils.importTextType.DRM, + txtOpenFile: me.view.txtSheetUnlockDescription, + validatePwd: false, + handler: function (result, value) { + btn = result; + if (result == 'ok') { + if (me.api) { + props.asc_setSheet(false, value); + me.api.asc_setProtectedSheet(props); + } + Common.NotificationCenter.trigger('edit:complete'); + } + } + }).on('close', function() { + if (btn!=='ok') + me.view.btnProtectSheet.toggle(true, true); + }); + + win.show(); + } else { + props.asc_setSheet(false); + me.api.asc_setProtectedSheet(props); + } + } + }, + + onRangesClick: function() { + var me = this, + props = me.api.asc_getProtectedRanges(), + win = new SSE.Views.ProtectRangesDlg({ + api: me.api, + props: props, + handler: function(result, settings) { + if (result=='protect-sheet') { + me.api.asc_setProtectedRanges(settings.arr, settings.deletedArr); + me.onSheetClick(true); + } else if (result == 'ok') { + me.api.asc_setProtectedRanges(settings.arr, settings.deletedArr); + } + Common.NotificationCenter.trigger('edit:complete'); + } + }); + + win.show(); + }, + + onLockOptionClick: function(type, value) { + switch (type) { + case 0: // cell + this.api.asc_setCellLocked(value=='checked'); + break; + case 1: // shape + var props = new Asc.asc_CImgProperty(); + props.asc_putProtectionLocked(value=='checked'); + this.api.asc_setGraphicObjectProps(props); + break; + case 2: // text + var props = new Asc.asc_CImgProperty(); + props.asc_putProtectionLockText(value=='checked'); + this.api.asc_setGraphicObjectProps(props); + break; + case 3: // formula + this.api.asc_setCellHiddenFormulas(value=='checked'); + break; + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onAppReady: function (config) { + var me = this; + (new Promise(function (resolve) { + resolve(); + })).then(function () { + me.view.btnProtectWB.toggle(me.api.asc_isProtectedWorkbook(), true); + + var props = me.getWSProps(); + me.view.btnProtectSheet.toggle(props.wsLock, true); //current sheet + Common.Utils.lockControls(SSE.enumLock['Objects'], props.wsProps['Objects'], { array: [me.view.chLockedText, me.view.chLockedShape]}); + Common.Utils.lockControls(SSE.enumLock.wsLock, props.wsLock, { array: [me.view.btnAllowRanges]}); + }); + }, + + onChangeProtectWorkbook: function() { + this.view.btnProtectWB.toggle(this.api.asc_isProtectedWorkbook(), true); + }, + + onChangeProtectSheet: function() { + var props = this.getWSProps(true); + + this.view.btnProtectSheet.toggle(props.wsLock, true); //current sheet + Common.Utils.lockControls(SSE.enumLock['Objects'], props.wsProps['Objects'], { array: [this.view.chLockedText, this.view.chLockedShape]}); + Common.Utils.lockControls(SSE.enumLock.wsLock, props.wsLock, { array: [this.view.btnAllowRanges]}); + Common.NotificationCenter.trigger('protect:wslock', props); + }, + + onActiveSheetChanged: function() { + this.onChangeProtectSheet(); //current sheet + }, + + getWSProps: function(update) { + if (update || !this._state.protection) { + var wsProtected = !!this.api.asc_isProtectedSheet(); + var arr = []; + if (wsProtected) { + arr = []; + var props = this.api.asc_getProtectedSheet(); + props && this.wsLockOptions.forEach(function(item){ + arr[item] = props['asc_get' + item] ? props['asc_get' + item]() : false; + }); + } else { + this.wsLockOptions.forEach(function(item){ + arr[item] = false; + }); + } + this._state.protection = {wsLock: wsProtected, wsProps: arr}; + } + + return this._state.protection; + }, + + onApiSelectionChanged: function(info) { + if ($('.asc-window.enable-key-events:visible').length>0) return; + + var selectionType = info.asc_getSelectionType(); + var need_disable = (selectionType === Asc.c_oAscSelectionType.RangeCells || selectionType === Asc.c_oAscSelectionType.RangeCol || + selectionType === Asc.c_oAscSelectionType.RangeRow || selectionType === Asc.c_oAscSelectionType.RangeMax); + Common.Utils.lockControls(SSE.enumLock.selRange, need_disable, { array: [this.view.chLockedText, this.view.chLockedShape]}); + + var xfs = info.asc_getXfs(); + this.view.chLockedCell.setValue(!!xfs.asc_getLocked(), true); + this.view.chHiddenFormula.setValue(!!xfs.asc_getHidden(), true); + + if (selectionType === Asc.c_oAscSelectionType.RangeSlicer || selectionType === Asc.c_oAscSelectionType.RangeImage || + selectionType === Asc.c_oAscSelectionType.RangeShape || selectionType === Asc.c_oAscSelectionType.RangeShapeText || + selectionType === Asc.c_oAscSelectionType.RangeChart || selectionType === Asc.c_oAscSelectionType.RangeChartText) { + var selectedObjects = this.api.asc_getGraphicObjectProps(); + for (var i = 0; i < selectedObjects.length; i++) { + if (selectedObjects[i].asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image) { + var elValue = selectedObjects[i].asc_getObjectValue(); + var locktext = elValue.asc_getProtectionLockText(), + lock = elValue.asc_getProtectionLocked(); + this.view.chLockedText.setValue(locktext!==undefined ? !!locktext : 'indeterminate', true); + this.view.chLockedShape.setValue(lock!==undefined ? !!lock : 'indeterminate', true); + Common.Utils.lockControls(SSE.enumLock.wsLockText, locktext===null, { array: [this.view.chLockedText]}); + Common.Utils.lockControls(SSE.enumLock.wsLockShape, lock===null, { array: [this.view.chLockedShape]}); + break; + } + } + } + }, + + onCoAuthoringDisconnect: function() { + this.SetDisabled(true); + } + + }, SSE.Controllers.WBProtection || {})); +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/template/ProtectRangesDlg.template b/apps/spreadsheeteditor/main/app/template/ProtectRangesDlg.template new file mode 100644 index 0000000000..fee4ace453 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/template/ProtectRangesDlg.template @@ -0,0 +1,35 @@ +
+
+ + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+
+ + + + +
+
+
\ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/DataTab.js b/apps/spreadsheeteditor/main/app/view/DataTab.js index 294e011e6c..b5c4f8d0dd 100644 --- a/apps/spreadsheeteditor/main/app/view/DataTab.js +++ b/apps/spreadsheeteditor/main/app/view/DataTab.js @@ -130,7 +130,7 @@ define([ caption: this.capDataFromText, menu: !this.toolbar.mode.isDesktopApp, disabled: true, - lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.sheetLock, _set.lostConnect, _set.coAuth], + lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.sheetLock, _set.wbLock, _set.lostConnect, _set.coAuth, _set.wsLock], dataHint: '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -145,7 +145,7 @@ define([ split: true, menu: true, disabled: true, - lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.sheetLock, _set.lostConnect, _set.coAuth], + lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.sheetLock, _set.lostConnect, _set.coAuth, _set.wsLock], dataHint: '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -160,7 +160,7 @@ define([ split: true, menu: true, disabled: true, - lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.sheetLock, _set.lostConnect, _set.coAuth], + lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.sheetLock, _set.lostConnect, _set.coAuth, _set.wsLock], dataHint: '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -174,7 +174,7 @@ define([ caption: this.capBtnTextToCol, split: false, disabled: true, - lock: [_set.multiselect, _set.multiselectCols, _set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth], + lock: [_set.multiselect, _set.multiselectCols, _set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.wsLock], dataHint: '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -207,7 +207,7 @@ define([ iconCls: 'toolbar__icon btn-remove-duplicates', caption: this.capBtnTextRemDuplicates, disabled: true, - lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter, _set.sheetLock], + lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter, _set.sheetLock, _set.wsLock], dataHint: '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -220,7 +220,7 @@ define([ iconCls: 'toolbar__icon btn-data-validation', caption: this.capBtnTextDataValidation, disabled: true, - lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter, _set.sheetLock], + lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter, _set.sheetLock, _set.wsLock], dataHint: '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -233,7 +233,7 @@ define([ iconCls: 'toolbar__icon btn-custom-sort', caption: this.capBtnTextCustomSort, disabled: true, - lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter, _set.sheetLock], + lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter, _set.sheetLock, _set['Sort']], dataHint: '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -241,17 +241,17 @@ define([ this.lockedControls.push(this.btnCustomSort); this.btnsSortDown = Common.Utils.injectButtons($host.find('.slot-sortdesc'), '', 'toolbar__icon btn-sort-down', '', - [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.cantModifyFilter, _set.sheetLock, _set.cantSort], undefined, undefined, undefined, '1', 'top', undefined, 'D'); + [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.cantModifyFilter, _set.sheetLock, _set.cantSort, _set['Sort']], undefined, undefined, undefined, '1', 'top', undefined, 'D'); this.btnsSortUp = Common.Utils.injectButtons($host.find('.slot-sortasc'), '', 'toolbar__icon btn-sort-up', '', - [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.cantModifyFilter, _set.sheetLock, _set.cantSort], undefined, undefined, undefined, '1', 'top', undefined, 'U'); + [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.cantModifyFilter, _set.sheetLock, _set.cantSort, _set['Sort']], undefined, undefined, undefined, '1', 'top', undefined, 'U'); this.btnsSetAutofilter = Common.Utils.injectButtons($host.find('.slot-btn-setfilter'), '', 'toolbar__icon btn-autofilter', '', - [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter, _set.tableHasSlicer], + [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.editPivot, _set.cantModifyFilter, _set.tableHasSlicer, _set.wsLock], false, false, true, '1', 'bottom', undefined, 'F'); this.btnsClearAutofilter = Common.Utils.injectButtons($host.find('.slot-btn-clear-filter'), '', 'toolbar__icon btn-clear-filter', '', - [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleDelFilter], undefined, undefined, undefined, '1', 'bottom', undefined, 'N'); + [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.ruleDelFilter, _set.wsLock], undefined, undefined, undefined, '1', 'bottom', undefined, 'N'); Array.prototype.push.apply(this.lockedControls, this.btnsSortDown.concat(this.btnsSortUp, this.btnsSetAutofilter,this.btnsClearAutofilter)); diff --git a/apps/spreadsheeteditor/main/app/view/FormulaTab.js b/apps/spreadsheeteditor/main/app/view/FormulaTab.js index cdfba9a761..8c89c952cc 100644 --- a/apps/spreadsheeteditor/main/app/view/FormulaTab.js +++ b/apps/spreadsheeteditor/main/app/view/FormulaTab.js @@ -293,7 +293,7 @@ define([ hint: this.toolbar.txtNamedRange, split: false, disabled: true, - lock : [_set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.selRangeEdit], + lock : [_set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.selRangeEdit, _set.wsLock], menu: new Common.UI.Menu({ items: [ { diff --git a/apps/spreadsheeteditor/main/app/view/PivotTable.js b/apps/spreadsheeteditor/main/app/view/PivotTable.js index 0f58239559..9043c9ba51 100644 --- a/apps/spreadsheeteditor/main/app/view/PivotTable.js +++ b/apps/spreadsheeteditor/main/app/view/PivotTable.js @@ -157,11 +157,11 @@ define([ var _set = SSE.enumLock; this.btnsAddPivot = Common.Utils.injectButtons(this.toolbar.$el.find('.btn-slot.slot-add-pivot'), '', 'toolbar__icon btn-pivot-sum', this.txtPivotTable, - [_set.lostConnect, _set.coAuth, _set.editPivot, _set.selRangeEdit, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.editCell], undefined, undefined, undefined, '1', 'bottom', 'small'); + [_set.lostConnect, _set.coAuth, _set.editPivot, _set.selRangeEdit, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.editCell, _set.wsLock], undefined, undefined, undefined, '1', 'bottom', 'small'); this.chRowHeader = new Common.UI.CheckBox({ labelText: this.textRowHeader, - lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock], + lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock, _set['FormatCells'], _set['PivotTables']], dataHint : '1', dataHintDirection: 'left', dataHintOffset: 'small' @@ -170,7 +170,7 @@ define([ this.chColHeader = new Common.UI.CheckBox({ labelText: this.textColHeader, - lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock], + lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock, _set['FormatCells'], _set['PivotTables']], dataHint : '1', dataHintDirection: 'left', dataHintOffset: 'small' @@ -179,7 +179,7 @@ define([ this.chRowBanded = new Common.UI.CheckBox({ labelText: this.textRowBanded, - lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock], + lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock, _set['FormatCells'], _set['PivotTables']], dataHint : '1', dataHintDirection: 'left', dataHintOffset: 'small' @@ -188,7 +188,7 @@ define([ this.chColBanded = new Common.UI.CheckBox({ labelText: this.textColBanded, - lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock], + lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock, _set['FormatCells'], _set['PivotTables']], dataHint : '1', dataHintDirection: 'left', dataHintOffset: 'small' @@ -200,7 +200,7 @@ define([ iconCls : 'toolbar__icon btn-pivot-layout', caption : this.capLayout, disabled : true, - lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock], + lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock, _set.wsLock], menu : true, dataHint : '1', dataHintDirection: 'bottom', @@ -213,7 +213,7 @@ define([ iconCls : 'toolbar__icon btn-blank-rows', caption : this.capBlankRows, disabled : true, - lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock], + lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock, _set.wsLock], menu : true, dataHint : '1', dataHintDirection: 'bottom', @@ -226,7 +226,7 @@ define([ iconCls : 'toolbar__icon btn-subtotals', caption : this.capSubtotals, disabled : true, - lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock], + lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock, _set.wsLock], menu : true, dataHint : '1', dataHintDirection: 'bottom', @@ -239,7 +239,7 @@ define([ iconCls : 'toolbar__icon btn-grand-totals', caption : this.capGrandTotals, disabled : true, - lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock], + lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock, _set.wsLock], menu : true, dataHint : '1', dataHintDirection: 'bottom', @@ -252,7 +252,7 @@ define([ iconCls: 'toolbar__icon btn-update', caption: this.txtRefresh, disabled : true, - lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock], + lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock, _set.wsLock], dataHint : '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -263,7 +263,7 @@ define([ cls: 'btn-toolbar x-huge icon-top', iconCls: 'toolbar__icon btn-select-pivot', caption: this.txtSelect, - lock: [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit], + lock: [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set['PivotTables']], dataHint: '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -276,7 +276,7 @@ define([ itemWidth : 61, itemHeight : 49, menuMaxHeight : 300, - lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock], + lock : [_set.lostConnect, _set.coAuth, _set.noPivot, _set.selRangeEdit, _set.pivotLock, _set['FormatCells'], _set['PivotTables']], beforeOpenHandler: function(e) { var cmp = this, menu = cmp.openButton.menu; @@ -359,7 +359,7 @@ define([ var _set = SSE.enumLock; this.btnsAddPivot = this.btnsAddPivot.concat(Common.Utils.injectButtons(this.$el.find('.btn-slot.slot-add-pivot'), '', 'toolbar__icon btn-pivot-sum', this.txtCreate, - [_set.lostConnect, _set.coAuth, _set.editPivot, _set.selRangeEdit, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.editCell], undefined, undefined, undefined, '1', 'bottom', 'small')); + [_set.lostConnect, _set.coAuth, _set.editPivot, _set.selRangeEdit, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.editCell, _set.wsLock], undefined, undefined, undefined, '1', 'bottom', 'small')); this.chRowHeader.render(this.$el.find('#slot-chk-header-row')); this.chColHeader.render(this.$el.find('#slot-chk-header-column')); diff --git a/apps/spreadsheeteditor/main/app/view/ProtectDialog.js b/apps/spreadsheeteditor/main/app/view/ProtectDialog.js new file mode 100644 index 0000000000..b6ada38676 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/ProtectDialog.js @@ -0,0 +1,435 @@ +/* + * + * (c) Copyright Ascensio System SIA 2010-2021 + * + * 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 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * 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 + * + */ +/** + * ProtectDialog.js + * + * Created by Julia Radzhabova on 21.06.2021 + * Copyright (c) 2021 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'common/main/lib/component/Window' +], function () { + 'use strict'; + + SSE.Views.ProtectDialog = Common.UI.Window.extend(_.extend({ + + initialize : function (options) { + var t = this, + _options = {}; + + _.extend(_options, { + title: options.title ? options.title : (options.type=='sheet' ? this.txtSheetTitle : this.txtWBTitle), + cls: 'modal-dlg', + width: 350, + height: options.type=='sheet' ? 447 : (options.type=='range' ? 338 : 306), + buttons: options.buttons ? options.buttons : [{ + value: 'ok', + caption: this.txtProtect + }, 'cancel'] + }, options); + + this.handler = options.handler; + this.txtDescription = options.txtDescription || ''; + this.type = options.type || 'workbook'; + this.props = options.props; + this.api = options.api; + + this.template = options.template || [ + '
', + '<% if (type=="range") { %>', + '
', + '', + '
', + '
', + '
', + '', + '
', + '
', + '<% } else { %>', + '
', + '', + '
', + '<% } %>', + '
', + '', + '
', + '
', + '
', + '', + '
', + '
', + '<% if (type=="sheet") { %>', + '
', + '', + '
', + '
', + '<% } %>', + '', + '
' + ].join(''); + + _options.tpl = _.template(this.template)(_options); + + Common.UI.Window.prototype.initialize.call(this, _options); + }, + render: function () { + Common.UI.Window.prototype.render.call(this); + + var me = this; + this.$window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this)); + this.inputPwd = new Common.UI.InputField({ + el: $('#id-password-txt'), + type: 'password', + allowBlank : true, + style : 'width: 100%;', + maxLength: 255, + validateOnBlur: false + }); + this.repeatPwd = new Common.UI.InputField({ + el: $('#id-repeat-txt'), + type: 'password', + allowBlank : true, + style : 'width: 100%;', + maxLength: 255, + validateOnBlur: false, + validation : function(value) { + return me.txtIncorrectPwd; + } + }); + + if (this.type == 'sheet') { + this.optionsList = new Common.UI.ListView({ + el: $('#protect-dlg-options', this.$window), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + scrollAlwaysVisible: true, + template: _.template(['
'].join('')), + itemTemplate: _.template([ + '
', + '', + '
', + '
<%= Common.Utils.String.htmlEncode(value) %>
', + '
', + '
' + ].join('')) + }); + this.optionsList.on({ + 'item:change': this.onItemChanged.bind(this), + 'item:add': this.onItemChanged.bind(this), + 'item:select': this.onCellCheck.bind(this) + }); + this.optionsList.onKeyDown = _.bind(this.onListKeyDown, this); + this.optionsList.on('entervalue', _.bind(this.onPrimary, this)); + } + + if (this.type == 'range') { + this.inputRangeName = new Common.UI.InputField({ + el: $('#id-range-name-txt'), + allowBlank : false, + blankError : this.txtEmpty, + style : 'width: 100%;', + maxLength: 255, + validateOnBlur: false + }); + this.txtDataRange = new Common.UI.InputFieldBtn({ + el : $('#id-range-txt'), + name : 'range', + style : 'width: 100%;', + allowBlank : false, + btnHint : this.textSelectData, + blankError : this.txtEmpty, + validateOnChange: true, + validateOnBlur: false, + validation : function(value) { + var isvalid = me.api.asc_checkDataRange(Asc.c_oAscSelectionDialogType.ConditionalFormattingRule, value, true); + return (isvalid!==Asc.c_oAscError.ID.DataRangeError) ? true : me.textInvalidRange; + } + }); + this.txtDataRange.on('button:click', _.bind(this.onSelectData, this)); + } + this.afterRender(); + }, + + getFocusedComponents: function() { + var arr = []; + (this.type == 'range') && (arr = arr.concat([this.inputRangeName, this.txtDataRange])); + arr = arr.concat([this.inputPwd, this.repeatPwd]); + (this.type == 'sheet') && (arr = arr.concat([this.optionsList])); + return arr; + }, + + getDefaultFocusableComponent: function () { + return (this.type == 'range') ? this.inputRangeName : this.inputPwd; + }, + + afterRender: function() { + this._setDefaults(this.props); + }, + + onPrimary: function(event) { + this._handleInput('ok'); + return false; + }, + + onBtnClick: function(event) { + this._handleInput(event.currentTarget.attributes['result'].value); + }, + + _handleInput: function(state) { + if (this.handler) { + if (state == 'ok') { + if (this.inputRangeName && this.inputRangeName.checkValidate() !== true) { + this.inputRangeName.focus(); + return; + } + if (this.txtDataRange && this.txtDataRange.checkValidate() !== true) { + this.txtDataRange.focus(); + return; + } + if (this.inputPwd.checkValidate() !== true) { + this.inputPwd.focus(); + return; + } + if (this.inputPwd.getValue() !== this.repeatPwd.getValue()) { + this.repeatPwd.checkValidate(); + this.repeatPwd.focus(); + return; + } + } + this.handler.call(this, state, this.inputPwd.getValue(), (state == 'ok') ? this.getSettings() : undefined); + } + + this.close(); + }, + + _setDefaults: function (props) { + this.optionsList && this.updateOptionsList(props); + (this.type=='range') && this.updateRangeSettings(props); + }, + + onItemChanged: function (view, record) { + var state = record.model.get('check'); + if ( state == 'indeterminate' ) + $('input[type=checkbox]', record.$el).prop('indeterminate', true); + else $('input[type=checkbox]', record.$el).prop({checked: state, indeterminate: false}); + }, + + onCellCheck: function (listView, itemView, record) { + if (this.checkCellTrigerBlock) + return; + + var target = '', isLabel = false, bound = null; + + var event = window.event ? window.event : window._event; + if (event) { + 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 (isLabel || event.target.className.match('checkbox')) { + this.updateCellCheck(listView, record); + + _.delay(function () { + listView.focus(); + }, 100, this); + } + } + }, + + onListKeyDown: function (e, data) { + var record = null, listView = this.optionsList; + + if (listView.disabled) return; + if (_.isUndefined(undefined)) data = e; + + if (data.keyCode == Common.UI.Keys.SPACE) { + data.preventDefault(); + data.stopPropagation(); + + this.updateCellCheck(listView, listView.getSelectedRec()); + + } else { + Common.UI.DataView.prototype.onKeyDown.call(this.optionsList, e, data); + } + }, + + updateCellCheck: function (listView, record) { + if (record && listView) { + record.set('check', !record.get('check')); + if (record.get('optionName') == 'SelectLockedCells' && record.get('check')) + this.optionsList.store.findWhere({optionName: 'SelectUnlockedCells'}).set('check', true); + if (record.get('optionName') == 'SelectUnlockedCells' && !record.get('check')) + this.optionsList.store.findWhere({optionName: 'SelectLockedCells'}).set('check', false); + // listView.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + } + }, + updateRangeSettings: function (props) { + if (props) { + this.inputRangeName.setValue(props.asc_getName()); + this.txtDataRange.setValue(props.asc_getSqref()); + } + }, + + updateOptionsList: function(props) { + var optionsArr = [ + { value: this.txtSelLocked, optionName: 'SelectLockedCells'}, + { value: this.txtSelUnLocked, optionName: 'SelectUnlockedCells'}, + { value: this.txtFormatCells, optionName: 'FormatCells'}, + { value: this.txtFormatCols, optionName: 'FormatColumns'}, + { value: this.txtFormatRows, optionName: 'FormatRows'}, + { value: this.txtInsCols, optionName: 'InsertColumns'}, + { value: this.txtInsRows, optionName: 'InsertRows'}, + { value: this.txtInsHyper, optionName: 'InsertHyperlinks'}, + { value: this.txtDelCols, optionName: 'DeleteColumns'}, + { value: this.txtDelRows, optionName: 'DeleteRows'}, + { value: this.txtSort, optionName: 'Sort'}, + { value: this.txtAutofilter, optionName: 'AutoFilter'}, + { value: this.txtPivot, optionName: 'PivotTables'}, + { value: this.txtObjs, optionName: 'Objects'}, + { value: this.txtScen, optionName: 'Scenarios'} + ]; + + var arr = []; + optionsArr.forEach(function (item, index) { + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : true, + value : item.value, + optionName : item.optionName, + check : props && props['asc_get' + item.optionName] ? !props['asc_get' + item.optionName]() : false + })); + }); + + this.optionsList.store.reset(arr); + this.optionsList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + }, + + getSettings: function() { + if (this.type == 'sheet') return this.getSheetSettings(); + if (this.type == 'range') return this.getRangeSettings(); + }, + + getSheetSettings: function() { + var props = this.props ? this.props : new Asc.CSheetProtection(); + this.optionsList.store.each(function (item, index) { + props && props['asc_set' + item.get('optionName')] && props['asc_set' + item.get('optionName')](!item.get('check')); + }); + return props; + }, + + getRangeSettings: function() { + var props = this.props ? this.props : new Asc.CProtectedRange(); + props.asc_setName(this.inputRangeName.getValue()); + props.asc_setSqref(this.txtDataRange.getValue()); + return props; + }, + + 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(); + _.delay(function(){ + me.txtDataRange.focus(); + },1); + }); + + var xy = me.$window.offset(); + me.hide(); + win.show(xy.left + 65, xy.top + 77); + win.setSettings({ + api : me.api, + range : (!_.isEmpty(me.txtDataRange.getValue()) && (me.txtDataRange.checkValidate()==true)) ? me.txtDataRange.getValue() : me.dataRangeValid, + type : Asc.c_oAscSelectionDialogType.ConditionalFormattingRule, + validation: function() {return true;} + }); + } + }, + + txtPassword : "Password", + txtRepeat: 'Repeat password', + txtIncorrectPwd: 'Confirmation password is not identical', + txtWarning: 'Warning: If you lose or forget the password, it cannot be recovered. Please keep it in a safe place.', + txtOptional: 'optional', + txtProtect: 'Protect', + txtSelLocked: 'Select locked cells', + txtSelUnLocked: 'Select unlocked cells', + txtFormatCells: 'Format cells', + txtFormatCols: 'Format columns', + txtFormatRows: 'Format rows', + txtInsCols: 'Insert columns', + txtInsRows: 'Insert rows', + txtInsHyper: 'Insert hyperlink', + txtDelCols: 'Delete columns', + txtDelRows: 'Delete rows', + txtSort: 'Sort', + txtAutofilter: 'Use AutoFilter', + txtPivot: 'Use PivotTable and PivotChart', + txtObjs: 'Edit objects', + txtScen: 'Edit scenarios', + txtWBDescription: 'To prevent other users from viewing hidden worksheets, adding, moving, deleting, or hiding worksheets and renaming worksheets, you can protect the structure of your workbook with a password.', + txtWBTitle: 'Protect Workbook structure', + txtSheetDescription: 'Prevent unwanted changes from others by limiting their ability to edit.', + txtSheetTitle: 'Protect Sheet', + txtAllow: 'Allow all users of this sheet to', + txtRangeName: 'Title', + txtRange: 'Range', + txtEmpty: 'This field is required', + textSelectData: 'Select Data', + textInvalidRange: 'ERROR! Invalid cells range' + + }, SSE.Views.ProtectDialog || {})); +}); diff --git a/apps/spreadsheeteditor/main/app/view/ProtectRangesDlg.js b/apps/spreadsheeteditor/main/app/view/ProtectRangesDlg.js new file mode 100644 index 0000000000..66701f65f6 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/ProtectRangesDlg.js @@ -0,0 +1,439 @@ +/* + * + * (c) Copyright Ascensio System SIA 2010-2021 + * + * 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 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * 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 + * +*/ +/** + * + * ProtectRangesDlg.js + * + * Created by Julia.Radzhabova on 22.06.21 + * Copyright (c) 2021 Ascensio System SIA. All rights reserved. + * + */ + +define([ 'text!spreadsheeteditor/main/app/template/ProtectRangesDlg.template', + 'common/main/lib/view/AdvancedSettingsWindow', + 'common/main/lib/component/ListView' +], function (contentTemplate) { + 'use strict'; + + SSE.Views = SSE.Views || {}; + + SSE.Views.ProtectRangesDlg = Common.Views.AdvancedSettingsWindow.extend(_.extend({ + options: { + alias: 'ProtectRangesDlg', + contentWidth: 480, + height: 353 + }, + + initialize: function (options) { + var me = this; + _.extend(this.options, { + title: this.txtTitle, + template: [ + '
', + '
' + _.template(contentTemplate)({scope: this}) + '
', + '
', + '
' + ].join(''), + buttons: [{ + value: 'protect-sheet', + caption: this.textProtect + }, 'ok','cancel'], + primary: 'protect-sheet' + }, options); + + this.api = options.api; + this.handler = options.handler; + this.props = options.props; + this.locked = options.locked || false; + this.userTooltip = true; + this.currentRange = undefined; + this.deletedArr = []; + + this.wrapEvents = { + onLockProtectedRangeManager: _.bind(this.onLockProtectedRangeManager, this), + onUnLockProtectedRangeManager: _.bind(this.onUnLockProtectedRangeManager, this), + onLockProtectedRange: _.bind(this.onLockProtectedRange, this), + onUnLockProtectedRange: _.bind(this.onUnLockProtectedRange, this) + }; + + Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options); + }, + render: function () { + Common.Views.AdvancedSettingsWindow.prototype.render.call(this); + var me = this; + + this.rangeList = new Common.UI.ListView({ + el: $('#protect-ranges-list', this.$window), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + emptyText: this.textEmpty, + itemTemplate: _.template([ + '
', + '
<%= Common.Utils.String.htmlEncode(name) %>
', + '
<%= range %>
', + '
<% if (pwd) { %>', me.txtYes, '<% } else { %>', me.txtNo, '<% } %>
', + '<% if (lock) { %>', + '
<%=lockuser%>
', + '<% } %>', + '
' + ].join('')), + tabindex: 1 + }); + this.rangeList.store.comparator = function(item1, item2) { + var n1 = item1.get('name').toLowerCase(), + n2 = item2.get('name').toLowerCase(); + if (n1==n2) return 0; + return (n10) { + if (selectedItem===undefined || selectedItem===null) selectedItem = 0; + if (_.isNumber(selectedItem)) { + if (selectedItem>val-1) selectedItem = val-1; + this.rangeList.selectByIndex(selectedItem); + setTimeout(function() { + me.rangeList.scrollToRecord(store.at(selectedItem)); + }, 50); + + } else if (selectedItem){ // object + var rec = store.findWhere({name: selectedItem.asc_getName(true)}); + if (rec) { + this.rangeList.selectRecord(rec); + setTimeout(function() { + me.rangeList.scrollToRecord(rec); + }, 50); + } + } + + if (this.userTooltip===true && this.rangeList.cmpEl.find('.lock-user').length>0) + this.rangeList.cmpEl.on('mouseover', _.bind(me.onMouseOverLock, me)).on('mouseout', _.bind(me.onMouseOutLock, me)); + } + this.updateButtons(); + _.delay(function () { + me.rangeList.scroller.update({alwaysVisibleY: true}); + }, 100, this); + }, + + onMouseOverLock: function (evt, el, opt) { + if (this.userTooltip===true && $(evt.target).hasClass('lock-user')) { + var me = this, + tipdata = $(evt.target).tooltip({title: this.tipIsLocked,trigger:'manual'}).data('bs.tooltip'); + + this.userTooltip = tipdata.tip(); + this.userTooltip.css('z-index', parseInt(this.$window.css('z-index')) + 10); + tipdata.show(); + + setTimeout(function() { me.userTipHide(); }, 5000); + } + }, + + userTipHide: function () { + if (typeof this.userTooltip == 'object') { + this.userTooltip.remove(); + this.userTooltip = undefined; + this.rangeList.cmpEl.off('mouseover').off('mouseout'); + } + }, + + onMouseOutLock: function (evt, el, opt) { + if (typeof this.userTooltip == 'object') this.userTipHide(); + }, + + onEditRange: function (isEdit) { + if (this._isWarningVisible) return; + + if (this.locked) { + Common.NotificationCenter.trigger('namedrange:locked'); + return; + } + var me = this, + xy = me.$window.offset(), + rec = this.rangeList.getSelectedRec(), + props; + if (isEdit) + props = rec.get('props'); + else { + props = new Asc.CProtectedRange(); + props.asc_setSqref(me.api.asc_getActiveRangeStr(Asc.referenceType.A)); + } + + var win = new SSE.Views.ProtectDialog({ + title : isEdit ? me.txtEditRange : me.txtNewRange, + type : 'range', + props : props, + isEdit : isEdit, + api : me.api, + buttons : ['ok', 'cancel'], + handler : function(result, value, props) { + if (result == 'ok') { + value && props.asc_setPassword(value); + if (isEdit) { + rec.set('props', props); + rec.set('name', props.asc_getName()); + rec.set('range', props.asc_getSqref()); + rec.set('pwd', props.asc_isPassword()); + } else { + rec = me.rangeList.store.add({ + name: props.asc_getName(), + pwd: props.asc_isPassword(), + range: props.asc_getSqref(), + props: props, + isNew: true, + lock: false, + lockuser: this.guestText + }); + me.rangeList.selectRecord(rec); + me.rangeList.scrollToRecord(me.rangeList.getSelectedRec()); + me.updateButtons(); + } + } + } + }).on('close', function() { + me.show(); + setTimeout(function(){ me.getDefaultFocusableComponent().focus(); }, 100); + }); + + me.hide(); + win.show(xy.left + 65, xy.top + 77); + }, + + onDeleteRange: function () { + var store = this.rangeList.store, + rec = this.rangeList.getSelectedRec(); + if (rec) { + !rec.get('isNew') && this.deletedArr.push(rec.get('props')); + var index = store.indexOf(rec); + store.remove(rec); + (store.length>0) && this.rangeList.selectByIndex(index); + this.rangeList.scrollToRecord(this.rangeList.getSelectedRec()); + } + this.updateButtons(); + }, + + getSettings: function() { + var arr = []; + this.rangeList.store.each(function(item){ + arr.push(item.get('props')); + }); + return {arr: arr, deletedArr: this.deletedArr}; + }, + + onPrimary: function() { + return true; + }, + + onDlgBtnClick: function(event) { + this.handler && this.handler.call(this, event.currentTarget.attributes['result'].value, this.getSettings()); + this.close(); + }, + + getUserName: function(id){ + var usersStore = SSE.getCollection('Common.Collections.Users'); + if (usersStore){ + var rec = usersStore.findUser(id); + if (rec) + return AscCommon.UserInfoParser.getParsedName(rec.get('username')); + } + return this.guestText; + }, + + onSelectRangeItem: function(lisvView, itemView, record) { + if (!record) return; + + this.userTipHide(); + var rawData = {}, + isViewSelect = _.isFunction(record.toJSON); + + if (isViewSelect){ + if (record.get('selected')) { + rawData = record.toJSON(); + } else {// record deselected + return; + } + this.currentNamedRange = _.indexOf(this.rangeList.store.models, record); + } + this.updateButtons(); + }, + + hide: function () { + this.userTipHide(); + Common.UI.Window.prototype.hide.call(this); + }, + + close: function () { + this.userTipHide(); + this.api.asc_unregisterCallback('asc_onLockProtectedRangeManager', this.wrapEvents.onLockProtectedRangeManager); + this.api.asc_unregisterCallback('asc_onUnLockProtectedRangeManager', this.wrapEvents.onUnLockProtectedRangeManager); + this.api.asc_unregisterCallback('asc_onLockProtectedRange', this.wrapEvents.onLockProtectedRange); + this.api.asc_unregisterCallback('asc_onUnLockProtectedRange', this.wrapEvents.onUnLockProtectedRange); + Common.UI.Window.prototype.close.call(this); + }, + + onKeyDown: function (lisvView, record, e) { + if (e.keyCode==Common.UI.Keys.DELETE && !this.btnDeleteRange.isDisabled()) + this.onDeleteRange(); + }, + + onDblClickItem: function (lisvView, record, e) { + if (!this.btnEditRange.isDisabled()) + this.onEditRange(true); + }, + + onLockProtectedRangeManager: function(index) { + if (this.currentSheet !== index) return; + this.locked = true; + this.updateButtons(); + if (this.userTooltip===true && this.rulesList.cmpEl.find('.lock-user').length>0) + this.rulesList.cmpEl.on('mouseover', _.bind(this.onMouseOverLock, this)).on('mouseout', _.bind(this.onMouseOutLock, this)); + }, + + onUnLockProtectedRangeManager: function(index) { + if (this.currentSheet !== index) return; + this.locked = false; + this.updateButtons(); + }, + + onLockProtectedRange: function(index, ruleId, userId) { + if (this.currentSheet !== index) return; + var store = this.rulesList.store, + rec = store.findWhere({ruleId: ruleId}); + if (rec) { + rec.set('lockuser', (userId) ? this.getUserName(userId) : this.guestText); + rec.set('lock', true); + this.updateButtons(); + } + if (this.userTooltip===true && this.rulesList.cmpEl.find('.lock-user').length>0) + this.rulesList.cmpEl.on('mouseover', _.bind(this.onMouseOverLock, this)).on('mouseout', _.bind(this.onMouseOutLock, this)); + }, + + onUnLockProtectedRange: function(index, ruleId) { + if (this.currentSheet !== index) return; + var store = this.rulesList.store, + rec = store.findWhere({ruleId: ruleId}); + if (rec) { + rec.set('lockuser', ''); + rec.set('lock', false); + this.updateButtons(); + } + }, + + updateButtons: function() { + var rec = this.rangeList.getSelectedRec(), + lock = rec ? rec.get('lock') : false, + length = this.rangeList.store.length; + this.btnDeleteRange.setDisabled(length<1 || lock); + this.btnEditRange.setDisabled(length<1 || lock); + }, + + txtTitle: 'Allow Users to Edit Ranges', + textRangesDesc: 'Ranges unlocked by a password when sheet is protected (this works only for locked cells)', + textTitle: 'Title', + textRange: 'Range', + textPwd: 'Password', + textNew: 'New', + textEdit: 'Edit', + textDelete: 'Delete', + textEmpty: 'No ranges allowed for edit.', + guestText: 'Guest', + tipIsLocked: 'This element is being edited by another user.', + warnDelete: 'Are you sure you want to delete the name {0}?', + textProtect: 'Protect Sheet', + txtYes: 'Yes', + txtNo: 'No', + txtEditRange: 'Edit Range', + txtNewRange: 'New Range' + + }, SSE.Views.ProtectRangesDlg || {})); +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/Statusbar.js b/apps/spreadsheeteditor/main/app/view/Statusbar.js index 59f08fc415..43848e2d93 100644 --- a/apps/spreadsheeteditor/main/app/view/Statusbar.js +++ b/apps/spreadsheeteditor/main/app/view/Statusbar.js @@ -371,6 +371,7 @@ define([ caption: this.itemHidden, menu: menuHiddenItems }, + {caption: this.itemProtect, value: 'protect'}, { caption: this.itemTabColor, menu: menuColorItems @@ -528,6 +529,7 @@ define([ var wc = this.api.asc_getWorksheetsCount(), i = -1; var hidentems = [], items = [], allItems = [], tab, locked, name; var sindex = this.api.asc_getActiveWorksheetIndex(); + var wbprotected = this.api.asc_isProtectedWorkbook(); while (++i < wc) { locked = me.api.asc_isWorksheetLockedOrDeleted(i); @@ -539,7 +541,7 @@ define([ label : me.api.asc_getWorksheetName(i), // reorderable : !locked, cls : locked ? 'coauth-locked':'', - isLockTheDrag : locked || me.mode.isDisconnected, + isLockTheDrag : locked || me.mode.isDisconnected || wbprotected, iconCls : 'btn-sheet-view', iconTitle : name, iconVisible : name!=='' @@ -591,9 +593,9 @@ define([ if (!this.tabbar.isTabVisible(sindex)) this.tabbar.setTabVisible(sindex); + this.btnAddWorksheet.setDisabled(me.mode.isDisconnected || me.api.asc_isWorkbookLocked() || me.api.asc_isProtectedWorkbook() || me.api.isCellEdited); this.tabbar.addDataHint(_.findIndex(items, function (item) { return item.sheetindex === sindex; })); - this.btnAddWorksheet.setDisabled(me.mode.isDisconnected || me.api.asc_isWorkbookLocked() || me.api.isCellEdited); $('#status-label-zoom').text(Common.Utils.String.format(this.zoomText, Math.floor((this.api.asc_getZoom() +.005)*100))); me.fireEvent('sheet:changed', [me, sindex]); @@ -704,24 +706,28 @@ define([ } var isdoclocked = this.api.asc_isWorkbookLocked(); + var isdocprotected = this.api.asc_isProtectedWorkbook(); - this.tabMenu.items[0].setDisabled(isdoclocked); - this.tabMenu.items[1].setDisabled(issheetlocked); - this.tabMenu.items[2].setDisabled(issheetlocked); - this.tabMenu.items[3].setDisabled(issheetlocked); - this.tabMenu.items[4].setDisabled(issheetlocked); - this.tabMenu.items[5].setDisabled(issheetlocked); - this.tabMenu.items[6].setDisabled(isdoclocked); - this.tabMenu.items[7].setDisabled(issheetlocked); + this.tabMenu.items[0].setDisabled(isdoclocked || isdocprotected); + this.tabMenu.items[1].setDisabled(issheetlocked || isdocprotected); + this.tabMenu.items[2].setDisabled(issheetlocked || isdocprotected); + this.tabMenu.items[3].setDisabled(issheetlocked || isdocprotected); + this.tabMenu.items[4].setDisabled(issheetlocked || isdocprotected); + this.tabMenu.items[5].setDisabled(issheetlocked || isdocprotected); + this.tabMenu.items[6].setDisabled(isdoclocked || isdocprotected); + this.tabMenu.items[7].setDisabled(select.length>1); + this.tabMenu.items[8].setDisabled(issheetlocked || isdocprotected); + + this.tabMenu.items[7].setCaption(this.api.asc_isProtectedSheet() ? this.itemUnProtect : this.itemProtect); if (select.length === 1) { - this.tabMenu.items[10].hide(); + this.tabMenu.items[11].hide(); } else { - this.tabMenu.items[10].show(); + this.tabMenu.items[11].show(); } - this.tabMenu.items[9].setDisabled(issheetlocked); - this.tabMenu.items[10].setDisabled(issheetlocked); + this.tabMenu.items[10].setDisabled(issheetlocked || isdocprotected); + this.tabMenu.items[11].setDisabled(issheetlocked || isdocprotected); this.api.asc_closeCellEditor(); this.api.asc_enableKeyEvents(false); @@ -913,7 +919,9 @@ define([ itemCount : 'Count', itemMinimum : 'Minimum', itemMaximum : 'Maximum', - itemSum : 'Sum' + itemSum : 'Sum', + itemProtect : 'Protect', + itemUnProtect : 'Unprotect' }, SSE.Views.Statusbar || {})); SSE.Views.Statusbar.RenameDialog = Common.UI.Window.extend(_.extend({ diff --git a/apps/spreadsheeteditor/main/app/view/TableSettings.js b/apps/spreadsheeteditor/main/app/view/TableSettings.js index a912ed04b7..705c35feb1 100644 --- a/apps/spreadsheeteditor/main/app/view/TableSettings.js +++ b/apps/spreadsheeteditor/main/app/view/TableSettings.js @@ -86,6 +86,8 @@ define([ }; this.lockedControls = []; this._locked = false; + this.wsLock = false; + this.wsProps = []; this.isEditCell = false; this._originalProps = null; @@ -403,10 +405,12 @@ define([ } }, - ChangeSettings: function(props) { + ChangeSettings: function(props, wsLock, wsProps) { if (this._initSettings) this.createDelayedControls(); + this.wsLock = wsLock; + this.wsProps = wsProps; this.disableControls(this._locked); // need to update combodataview after disabled state if (props )//formatTableInfo @@ -470,7 +474,7 @@ define([ this._state.CheckFilter=value; } if (this.chFilter.isDisabled() !== (!this._state.CheckHeader || this._locked || value===null)) - this.chFilter.setDisabled(!this._state.CheckHeader || this._locked || value===null); + this.chFilter.setDisabled(!this._state.CheckHeader || this._locked || value===null || this.wsLock); if (needTablePictures || !this.mnuTableTemplatePicker) this.onApiInitTableTemplates(this.api.asc_getTablePictures(props)); @@ -533,7 +537,7 @@ define([ this.btnTableTemplate.render($('#table-btn-template')); this.lockedControls.push(this.btnTableTemplate); this.mnuTableTemplatePicker.on('item:click', _.bind(this.onTableTemplateSelect, this, this.btnTableTemplate)); - if (this._locked) this.btnTableTemplate.setDisabled(this._locked); + if (this._locked) this.btnTableTemplate.setDisabled(this._locked || this.wsProps['FormatCells']); } @@ -636,13 +640,16 @@ define([ if (this._initSettings) return; disable = disable || this.isEditCell; - if (this._state.DisabledControls!==disable) { - this._state.DisabledControls = disable; - _.each(this.lockedControls, function(item) { - item.setDisabled(disable); - }); - this.linkAdvanced.toggleClass('disabled', disable); - } + var me = this; + _.each(this.lockedControls, function(item) { + item.setDisabled(disable || me.wsLock); + }); + this.linkAdvanced.toggleClass('disabled', disable || this.wsLock); + this.btnTableTemplate && this.btnTableTemplate.setDisabled(disable || this.wsProps['FormatCells']); + this.chBanded.setDisabled(disable || this.wsProps['FormatCells']); + this.chFirst.setDisabled(disable || this.wsProps['FormatCells']); + this.chLast.setDisabled(disable || this.wsProps['FormatCells']); + this.chColBanded.setDisabled(disable || this.wsProps['FormatCells']); }, textEdit: 'Rows & Columns', diff --git a/apps/spreadsheeteditor/main/app/view/Toolbar.js b/apps/spreadsheeteditor/main/app/view/Toolbar.js index 800054ac36..a11d75f43a 100644 --- a/apps/spreadsheeteditor/main/app/view/Toolbar.js +++ b/apps/spreadsheeteditor/main/app/view/Toolbar.js @@ -98,7 +98,13 @@ define([ cantSort: 'cant-sort', pivotLock: 'pivot-lock', tableHasSlicer: 'table-has-slicer', - sheetView: 'sheet-view' + sheetView: 'sheet-view', + wbLock: 'workbook-lock', + wsLock: 'worksheet-lock', + itemsDisabled: 'all-items-disabled', + wsLockText: 'worksheet-lock-text', + wsLockShape: 'worksheet-lock-shape', + wsLockFormat: 'worksheet-lock-format' }; SSE.Views.Toolbar = Common.UI.Mixtbar.extend(_.extend({ @@ -417,7 +423,7 @@ define([ id : 'id-toolbar-btn-incfont', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-incfont', - lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect], + lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect, _set.wsLockFormat], dataHint : '1', dataHintDirection: 'top' }); @@ -426,7 +432,7 @@ define([ id : 'id-toolbar-btn-decfont', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-decfont', - lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect], + lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect, _set.wsLockFormat], dataHint : '1', dataHintDirection: 'top' }); @@ -435,7 +441,7 @@ define([ id : 'id-toolbar-btn-bold', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-bold', - lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect], + lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect, _set.wsLockFormat], enableToggle: true, dataHint : '1', dataHintDirection: 'bottom' @@ -445,7 +451,7 @@ define([ id : 'id-toolbar-btn-italic', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-italic', - lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect], + lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect, _set.wsLockFormat], enableToggle: true, dataHint : '1', dataHintDirection: 'bottom' @@ -455,7 +461,7 @@ define([ id : 'id-toolbar-btn-underline', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-underline', - lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect], + lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect, _set.wsLockFormat], enableToggle: true, dataHint : '1', dataHintDirection: 'bottom' @@ -465,7 +471,7 @@ define([ id: 'id-toolbar-btn-strikeout', cls: 'btn-toolbar', iconCls: 'toolbar__icon btn-strikeout', - lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect], + lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect, _set.wsLockFormat], enableToggle: true, dataHint : '1', dataHintDirection: 'bottom' @@ -478,7 +484,7 @@ define([ icls : 'btn-subscript', split : true, enableToggle: true, - lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect], + lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect, _set.wsLockFormat], menu : new Common.UI.Menu({ items: [ { @@ -514,7 +520,7 @@ define([ cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-fontcolor', split : true, - lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect], + lock : [_set.selImage, _set.editFormula, _set.selRangeEdit, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect, _set.wsLockFormat], menu: true, auto: true, dataHint : '1', @@ -528,7 +534,7 @@ define([ cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-paracolor', split : true, - lock : [_set.selImage, _set.editCell, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect], + lock : [_set.selImage, _set.editCell, _set.selSlicer, _set.coAuth, _set.coAuthText, _set.lostConnect, _set.wsLockFormat], transparent: true, menu: true, dataHint: '1', @@ -543,7 +549,7 @@ define([ icls : 'btn-border-out', borderId : 'outer', borderswidth: Asc.c_oAscBorderStyles.Thin, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set['FormatCells']], split : true, menu : true, dataHint : '1', @@ -556,7 +562,7 @@ define([ cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-align-left', enableToggle: true, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText, _set.wsLockFormat], toggleGroup : 'alignGroup', dataHint : '1', dataHintDirection: 'bottom' @@ -567,7 +573,7 @@ define([ cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-align-center', enableToggle: true, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText, _set.wsLockFormat], toggleGroup : 'alignGroup', dataHint : '1', dataHintDirection: 'bottom' @@ -578,7 +584,7 @@ define([ cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-align-right', enableToggle: true, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText, _set.wsLockFormat], toggleGroup : 'alignGroup', dataHint : '1', dataHintDirection: 'bottom' @@ -589,7 +595,7 @@ define([ cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-align-just', enableToggle: true, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText, _set.wsLockFormat], toggleGroup: 'alignGroup', dataHint : '1', dataHintDirection: 'bottom' @@ -602,7 +608,7 @@ define([ enableToggle: true, allowDepress: true, split : true, - lock : [_set.editCell, _set.selShape, _set.selShapeText, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleMerge, _set.editPivot], + lock : [_set.editCell, _set.selShape, _set.selShapeText, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleMerge, _set.editPivot, _set.wsLock], menu : new Common.UI.Menu({ items: [ { @@ -636,7 +642,7 @@ define([ id : 'id-toolbar-rtn-valign-top', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-align-top', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText, _set.wsLockFormat], enableToggle: true, toggleGroup : 'vAlignGroup', dataHint : '1', @@ -648,7 +654,7 @@ define([ cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-align-middle', enableToggle: true, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText, _set.wsLockFormat], toggleGroup : 'vAlignGroup', dataHint : '1', dataHintDirection: 'top' @@ -658,7 +664,7 @@ define([ id : 'id-toolbar-rtn-valign-bottom', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-align-bottom', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText, _set.wsLockFormat], enableToggle: true, toggleGroup : 'vAlignGroup', dataHint : '1', @@ -669,7 +675,7 @@ define([ id : 'id-toolbar-rtn-wrap', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-wrap', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set['FormatCells']], enableToggle: true, allowDepress: true, dataHint : '1', @@ -680,7 +686,7 @@ define([ id : 'id-toolbar-rtn-textorient', cls : 'btn-toolbar', iconCls : 'toolbar__icon text-orient-ccw', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.coAuthText, _set.wsLockFormat], menu : new Common.UI.Menu({ items: [ { @@ -742,7 +748,7 @@ define([ cls : 'btn-toolbar x-huge icon-top', iconCls : 'toolbar__icon btn-insertimage', caption : me.capInsertImage, - lock : [_set.editCell, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.lostConnect, _set.coAuth, _set['Objects']], menu : new Common.UI.Menu({ items: [ { caption: me.mniImageFromFile, value: 'file' }, @@ -760,7 +766,7 @@ define([ cls : 'btn-toolbar x-huge icon-top', iconCls : 'toolbar__icon btn-inserthyperlink', caption : me.capInsertHyperlink, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selShape, _set.cantHyperlink, _set.selSlicer, _set.multiselect, _set.lostConnect, _set.coAuth, _set.editPivot], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selShape, _set.cantHyperlink, _set.selSlicer, _set.multiselect, _set.lostConnect, _set.coAuth, _set.editPivot, _set['InsertHyperlinks']], dataHint : '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -770,7 +776,7 @@ define([ id : 'tlbtn-insertchart', cls : 'btn-toolbar x-huge icon-top', iconCls : 'toolbar__icon btn-insertchart', - lock : [_set.editCell, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.editCell, _set.lostConnect, _set.coAuth, _set.coAuthText, _set['Objects']], caption : me.capInsertChart, menu : true, dataHint : '1', @@ -782,7 +788,7 @@ define([ id : 'tlbtn-insertsparkline', cls : 'btn-toolbar x-huge icon-top', iconCls : 'toolbar__icon btn-sparkline', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selShape, _set.selSlicer, _set.multiselect, _set.lostConnect, _set.coAuth, _set.coAuthText, _set.editPivot], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selImage, _set.selShape, _set.selSlicer, _set.multiselect, _set.lostConnect, _set.coAuth, _set.coAuthText, _set.editPivot, _set.wsLock], caption : me.capInsertSpark, menu : true, dataHint : '1', @@ -796,7 +802,7 @@ define([ iconCls : 'toolbar__icon btn-insertshape', enableToggle: true, caption : me.capInsertShape, - lock : [_set.editCell, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.lostConnect, _set.coAuth, _set['Objects']], menu : new Common.UI.Menu({cls: 'menu-shapes'}), dataHint : '1', dataHintDirection: 'bottom', @@ -808,7 +814,7 @@ define([ cls : 'btn-toolbar x-huge icon-top', iconCls : 'toolbar__icon btn-text', caption : me.capInsertText, - lock : [_set.editCell, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.lostConnect, _set.coAuth, _set['Objects']], enableToggle: true, dataHint : '1', dataHintDirection: 'bottom', @@ -820,7 +826,7 @@ define([ cls : 'btn-toolbar x-huge icon-top', iconCls : 'toolbar__icon btn-textart', caption : me.capInsertTextart, - lock : [_set.editCell, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.lostConnect, _set.coAuth, _set['Objects']], menu : new Common.UI.Menu({ cls: 'menu-shapes', items: [ @@ -861,7 +867,7 @@ define([ cls: 'btn-toolbar x-huge icon-top', iconCls: 'toolbar__icon btn-slicer', caption: me.capBtnInsSlicer, - lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.multiselect, _set.noSlicerSource], + lock: [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.multiselect, _set.noSlicerSource, _set.wsLock], dataHint: '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -871,7 +877,7 @@ define([ id : 'id-toolbar-btn-ttempl', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-menu-table', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.multiselect, _set.cantModifyFilter], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.multiselect, _set.cantModifyFilter, _set.wsLock], menu : new Common.UI.Menu({ items: [ { template: _.template('
') } @@ -887,7 +893,7 @@ define([ cls : 'btn-toolbar x-huge icon-top', iconCls : 'toolbar__icon btn-inserttable', caption : me.capInsertTable, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.multiselect, _set.cantModifyFilter, _set.ruleMerge, _set.editPivot], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set.ruleFilter, _set.multiselect, _set.cantModifyFilter, _set.ruleMerge, _set.editPivot, _set.wsLock], dataHint: '1', dataHintDirection: 'bottom', dataHintOffset: 'small' @@ -899,7 +905,7 @@ define([ itemWidth : 112, itemHeight : 38, menuMaxHeight : 226, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set['FormatCells']], dataHint : '1', dataHintDirection: 'bottom', dataHintOffset : '-16, 0', @@ -950,7 +956,7 @@ define([ cls : 'input-group-nr', menuStyle : 'min-width: 180px;', hint : me.tipNumFormat, - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.selRangeEdit, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.selRangeEdit, _set.lostConnect, _set.coAuth, _set['FormatCells']], itemsTemplate: formatTemplate, editable : false, data : me.numFormatData, @@ -962,7 +968,7 @@ define([ id : 'id-toolbar-btn-percent-style', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-percent-style', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set['FormatCells']], styleName : 'Percent', dataHint : '1', dataHintDirection: 'bottom' @@ -972,7 +978,7 @@ define([ id : 'id-toolbar-btn-accounting-style', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-currency-style', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set['FormatCells']], styleName : 'Currency', split : true, menu : new Common.UI.Menu({ @@ -1013,7 +1019,7 @@ define([ id : 'id-toolbar-btn-decdecimal', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-decdecimal', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set['FormatCells']], dataHint : '1', dataHintDirection: 'bottom' }); @@ -1022,7 +1028,7 @@ define([ id : 'id-toolbar-btn-incdecimal', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-incdecimal', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth, _set['FormatCells']], dataHint : '1', dataHintDirection: 'bottom' }); @@ -1058,7 +1064,7 @@ define([ id : 'id-toolbar-btn-insertrange', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-named-range', - lock : [_set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.selRangeEdit], + lock : [_set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set.selRangeEdit, _set.wsLock], menu : new Common.UI.Menu({ style : 'min-width: 110px', items : [ @@ -1137,16 +1143,18 @@ define([ id : 'id-toolbar-btn-addcell', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-addcell', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.itemsDisabled, _set.lostConnect, _set.coAuth], menu : new Common.UI.Menu({ items : [ { caption : me.textInsRight, - value : Asc.c_oAscInsertOptions.InsertCellsAndShiftRight + value : Asc.c_oAscInsertOptions.InsertCellsAndShiftRight, + lock : [_set.wsLock] }, { caption : me.textInsDown, - value : Asc.c_oAscInsertOptions.InsertCellsAndShiftDown + value : Asc.c_oAscInsertOptions.InsertCellsAndShiftDown, + lock : [_set.wsLock] }, { caption : me.textEntireRow, @@ -1167,16 +1175,18 @@ define([ id : 'id-toolbar-btn-delcell', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-delcell', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.itemsDisabled, _set.lostConnect, _set.coAuth], menu : new Common.UI.Menu({ items : [ { caption : me.textDelLeft, - value : Asc.c_oAscDeleteOptions.DeleteCellsAndShiftLeft + value : Asc.c_oAscDeleteOptions.DeleteCellsAndShiftLeft, + lock : [_set.wsLock] }, { caption : me.textDelUp, - value : Asc.c_oAscDeleteOptions.DeleteCellsAndShiftTop + value : Asc.c_oAscDeleteOptions.DeleteCellsAndShiftTop, + lock : [_set.wsLock] }, { caption : me.textEntireRow, @@ -1197,7 +1207,7 @@ define([ id : 'id-toolbar-btn-condformat', cls : 'btn-toolbar', iconCls : 'toolbar__icon btn-cond-format', - lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth, _set['FormatCells']], menu : true, dataHint : '1', dataHintDirection: 'top', @@ -1209,7 +1219,7 @@ define([ cls : 'btn-toolbar x-huge icon-top', iconCls : 'toolbar__icon btn-colorschemas', caption : me.capBtnColorSchemas, - lock : [_set.editCell, _set.lostConnect, _set.coAuth], + lock : [_set.editCell, _set.lostConnect, _set.coAuth, _set.wsLock], menu : new Common.UI.Menu({ cls: 'shifted-left', items: [], @@ -1561,7 +1571,7 @@ define([ cls: 'btn-toolbar x-huge icon-top', iconCls: 'toolbar__icon btn-img-align', caption: me.capImgAlign, - lock : [_set.selRange, _set.selRangeEdit, _set.cantGroup, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.selRange, _set.selRangeEdit, _set.cantGroup, _set.lostConnect, _set.coAuth, _set.coAuthText, _set["Objects"]], menu: true, dataHint: '1', dataHintDirection: 'bottom', @@ -1572,7 +1582,7 @@ define([ cls: 'btn-toolbar x-huge icon-top', iconCls: 'toolbar__icon btn-img-group', caption: me.capImgGroup, - lock : [_set.selRange, _set.selRangeEdit, _set.cantGroupUngroup, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.selRange, _set.selRangeEdit, _set.cantGroupUngroup, _set.lostConnect, _set.coAuth, _set.coAuthText, _set["Objects"]], menu: true, dataHint: '1', dataHintDirection: 'bottom', @@ -1583,7 +1593,7 @@ define([ iconCls: 'toolbar__icon btn-img-frwd', caption: me.capImgForward, split: true, - lock : [_set.selRange, _set.selRangeEdit, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.selRange, _set.selRangeEdit, _set.lostConnect, _set.coAuth, _set.coAuthText, _set["Objects"]], menu: true, dataHint: '1', dataHintDirection: 'bottom', @@ -1593,7 +1603,7 @@ define([ cls: 'btn-toolbar x-huge icon-top', iconCls: 'toolbar__icon btn-img-bkwd', caption: me.capImgBackward, - lock : [_set.selRange, _set.selRangeEdit, _set.lostConnect, _set.coAuth, _set.coAuthText], + lock : [_set.selRange, _set.selRangeEdit, _set.lostConnect, _set.coAuth, _set.coAuthText, _set["Objects"]], split: true, menu: true, dataHint: '1', diff --git a/apps/spreadsheeteditor/main/app/view/WBProtection.js b/apps/spreadsheeteditor/main/app/view/WBProtection.js new file mode 100644 index 0000000000..f1a076f307 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/WBProtection.js @@ -0,0 +1,246 @@ +/* + * + * (c) Copyright Ascensio System SIA 2010-2021 + * + * 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 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * 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 + * + */ + +/** + * WBProtection.js + * + * Created by Julia Radzhabova on 21.06.2021 + * Copyright (c) 2021Ascensio System SIA. All rights reserved. + * + */ +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'; + + SSE.Views.WBProtection = Common.UI.BaseView.extend(_.extend((function(){ + var template = + '
' + + '' + + '' + + '' + + '
' + + '
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + + '
' + + '
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + + '
'; + + function setEvents() { + var me = this; + + this.btnProtectWB.on('click', function (btn, e) { + me.fireEvent('protect:workbook', [btn.pressed]); + }); + this.btnProtectSheet.on('click', function (btn, e) { + me.fireEvent('protect:sheet', [btn.pressed]); + }); + this.btnAllowRanges.on('click', function (btn, e) { + me.fireEvent('protect:ranges'); + }); + this.chLockedCell.on('change', function (field, value) { + me.fireEvent('protect:lock-options', [0, value]); + }); + this.chLockedShape.on('change', function (field, value) { + me.fireEvent('protect:lock-options', [1, value]); + }); + this.chLockedText.on('change', function (field, value) { + me.fireEvent('protect:lock-options', [2, value]); + }); + this.chHiddenFormula.on('change', function (field, value) { + me.fireEvent('protect:lock-options', [3, value]); + }); + + me._isSetEvents = true; + } + + return { + + options: {}, + + initialize: function (options) { + Common.UI.BaseView.prototype.initialize.call(this, options); + + this.appConfig = options.mode; + + var _set = SSE.enumLock; + this.lockedControls = []; + this._state = {disabled: false}; + + this.btnProtectWB = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'toolbar__icon protect-workbook', + enableToggle: true, + caption: this.txtProtectWB, + lock : [_set.selRangeEdit, _set.lostConnect, _set.coAuth], + dataHint : '1', + dataHintDirection: 'bottom', + dataHintOffset: 'small' + }); + this.lockedControls.push(this.btnProtectWB); + + this.btnProtectSheet = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'toolbar__icon protect-sheet', + enableToggle: true, + caption: this.txtProtectSheet, + lock : [_set.selRangeEdit, _set.lostConnect, _set.coAuth], + dataHint : '1', + dataHintDirection: 'bottom', + dataHintOffset: 'small' + }); + this.lockedControls.push(this.btnProtectSheet); + + this.btnAllowRanges = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'toolbar__icon allow-edit-ranges', + caption: this.txtAllowRanges, + lock : [_set.selRangeEdit, _set.lostConnect, _set.coAuth, _set.wsLock], + dataHint : '1', + dataHintDirection: 'bottom', + dataHintOffset: 'small' + }); + this.lockedControls.push(this.btnAllowRanges); + + this.chLockedCell = new Common.UI.CheckBox({ + labelText: this.txtLockedCell, + lock : [_set.editCell, _set.selRangeEdit, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.wsLock, _set.wbLock, _set.lostConnect, _set.coAuth], + dataHint : '1', + dataHintDirection: 'left', + dataHintOffset: 'small' + }); + this.lockedControls.push(this.chLockedCell); + + this.chLockedShape = new Common.UI.CheckBox({ + labelText: this.txtLockedShape, + lock : [_set.selRange, _set.selRangeEdit, _set.wbLock, _set.lostConnect, _set.coAuth, _set['Objects'], _set.wsLockShape], + dataHint : '1', + dataHintDirection: 'left', + dataHintOffset: 'small' + }); + this.lockedControls.push(this.chLockedShape); + + this.chLockedText = new Common.UI.CheckBox({ + labelText: this.txtLockedText, + lock : [_set.selRange, _set.selRangeEdit, _set.selRangeEdit, _set.selImage, _set.selSlicer, _set.wbLock, _set.lostConnect, _set.coAuth, _set['Objects'], _set.wsLockText], + dataHint : '1', + dataHintDirection: 'left', + dataHintOffset: 'small' + }); + this.lockedControls.push(this.chLockedText); + + this.chHiddenFormula = new Common.UI.CheckBox({ + labelText: this.txtHiddenFormula, + lock : [_set.editCell, _set.selRangeEdit, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.selSlicer, _set.wsLock, _set.wbLock, _set.lostConnect, _set.coAuth], + dataHint : '1', + dataHintDirection: 'left', + dataHintOffset: 'small' + }); + this.lockedControls.push(this.chHiddenFormula); + + Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); + }, + + render: function (el) { + return this; + }, + + onAppReady: function (config) { + var me = this; + (new Promise(function (accept, reject) { + accept(); + })).then(function(){ + me.btnProtectWB.updateHint(me.hintProtectWB); + me.btnProtectSheet.updateHint(me.hintProtectSheet); + me.btnAllowRanges.updateHint(me.hintAllowRanges); + + setEvents.call(me); + }); + }, + + getPanel: function () { + this.$el = $(_.template(template)( {} )); + + this.btnProtectWB.render(this.$el.find('#slot-btn-protect-wb')); + this.btnProtectSheet.render(this.$el.find('#slot-btn-protect-sheet')); + this.btnAllowRanges.render(this.$el.find('#slot-btn-allow-ranges')); + this.chLockedCell.render(this.$el.find('#slot-chk-locked-cell')); + this.chLockedShape.render(this.$el.find('#slot-chk-locked-shape')); + this.chLockedText.render(this.$el.find('#slot-chk-locked-text')); + this.chHiddenFormula.render(this.$el.find('#slot-chk-hidden-formula')); + + return this.$el; + }, + + getButtons: function(type) { + if (type===undefined) + return this.lockedControls; + return []; + }, + + show: function () { + Common.UI.BaseView.prototype.show.call(this); + this.fireEvent('show', this); + }, + + txtProtectWB: 'Protect Workbook', + txtProtectSheet: 'Protect Sheet', + txtAllowRanges: 'Allow Edit Ranges', + hintProtectWB: 'Protect workbook', + hintProtectSheet: 'Protect sheet', + hintAllowRanges: 'Allow edit ranges', + txtLockedCell: 'Locked Cell', + txtLockedShape: 'Shape Locked', + txtLockedText: 'Lock Text', + txtHiddenFormula: 'Hidden Formulas', + txtWBUnlockTitle: 'Unprotect Workbook', + txtWBUnlockDescription: 'Enter a password to unprotect workbook', + txtSheetUnlockTitle: 'Unprotect Sheet', + txtSheetUnlockDescription: 'Enter a password to unprotect sheet' + } + }()), SSE.Views.WBProtection || {})); +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app_dev.js b/apps/spreadsheeteditor/main/app_dev.js index a5a63c7e54..c3253a8fe0 100644 --- a/apps/spreadsheeteditor/main/app_dev.js +++ b/apps/spreadsheeteditor/main/app_dev.js @@ -149,6 +149,7 @@ require([ 'PivotTable', 'DataTab', 'ViewTab', + 'WBProtection', 'Common.Controllers.Fonts', 'Common.Controllers.History', 'Common.Controllers.Chat', @@ -174,6 +175,7 @@ require([ 'spreadsheeteditor/main/app/controller/PivotTable', 'spreadsheeteditor/main/app/controller/DataTab', 'spreadsheeteditor/main/app/controller/ViewTab', + 'spreadsheeteditor/main/app/controller/WBProtection', 'spreadsheeteditor/main/app/view/FileMenuPanels', 'spreadsheeteditor/main/app/view/ParagraphSettings', 'spreadsheeteditor/main/app/view/ImageSettings', diff --git a/apps/spreadsheeteditor/main/locale/en.json b/apps/spreadsheeteditor/main/locale/en.json index c28901e3eb..4b005a3d8c 100644 --- a/apps/spreadsheeteditor/main/locale/en.json +++ b/apps/spreadsheeteditor/main/locale/en.json @@ -587,6 +587,7 @@ "SSE.Controllers.DocumentHolder.txtUndoExpansion": "Undo table autoexpansion", "SSE.Controllers.DocumentHolder.txtUseTextImport": "Use text import wizard", "SSE.Controllers.DocumentHolder.txtWidth": "Width", + "SSE.Controllers.DocumentHolder.txtLockSort": "Data is found next to your selection, but you do not have sufficient permissions to change those cells.
Do you wish to continue with the current selection?", "SSE.Controllers.FormulaDialog.sCategoryAll": "All", "SSE.Controllers.FormulaDialog.sCategoryCube": "Cube", "SSE.Controllers.FormulaDialog.sCategoryDatabase": "Database", @@ -707,6 +708,9 @@ "SSE.Controllers.Main.errorViewerDisconnect": "Connection is lost. You can still view the document,
but will not be able to download or print it until the connection is restored and page is reloaded.", "SSE.Controllers.Main.errorWrongBracketsCount": "An error in the entered formula.
Wrong number of brackets is used.", "SSE.Controllers.Main.errorWrongOperator": "An error in the entered formula. Wrong operator is used.
Please correct the error.", + "SSE.Controllers.Main.errorPasswordIsNotCorrect": "The password you supplied is not correct.
Verify that the CAPS LOCK key is off and be sure to use the correct capitalization.", + "SSE.Controllers.Main.errorDeleteColumnContainsLockedCell": "You are trying to delete a column that contains a locked cell. Locked cells cannot be deleted while the worksheet is protected.
To delete a locked cell, unprotect the sheet. You might be requested to enter a password.", + "SSE.Controllers.Main.errorDeleteRowContainsLockedCell": "You are trying to delete a row that contains a locked cell. Locked cells cannot be deleted while the worksheet is protected.
To delete a locked cell, unprotect the sheet. You might be requested to enter a password.", "SSE.Controllers.Main.errRemDuplicates": "Duplicate values found and deleted: {0}, unique values left: {1}.", "SSE.Controllers.Main.leavePageText": "You have unsaved changes in this spreadsheet. Click 'Stay on this Page' then 'Save' to save them. Click 'Leave this Page' to discard all the unsaved changes.", "SSE.Controllers.Main.leavePageTextOnClose": "All unsaved changes in this spreadsheet will be lost.
Click \"Cancel\" then \"Save\" to save them. Click \"OK\" to discard all the unsaved changes.", @@ -1398,6 +1402,7 @@ "SSE.Controllers.Toolbar.txtTable_TableStyleMedium": "Table Style Medium", "SSE.Controllers.Toolbar.warnLongOperation": "The operation you are about to perform might take rather much time to complete.
Are you sure you want to continue?", "SSE.Controllers.Toolbar.warnMergeLostData": "Only the data from the upper-left cell will remain in the merged cell.
Are you sure you want to continue?", + "SSE.Controllers.Toolbar.txtLockSort": "Data is found next to your selection, but you do not have sufficient permissions to change those cells.
Do you wish to continue with the current selection?", "SSE.Controllers.Viewport.textFreezePanes": "Freeze Panes", "SSE.Controllers.Viewport.textFreezePanesShadow": "Show Frozen Panes Shadow", "SSE.Controllers.Viewport.textHideFBar": "Hide Formula Bar", @@ -3010,6 +3015,8 @@ "SSE.Views.Statusbar.itemRename": "Rename", "SSE.Views.Statusbar.itemSum": "Sum", "SSE.Views.Statusbar.itemTabColor": "Tab Color", + "SSE.Views.Statusbar.itemProtect": "Protect", + "SSE.Views.Statusbar.itemUnProtect": "Unprotect", "SSE.Views.Statusbar.RenameDialog.errNameExists": "Worksheet with such a name already exists.", "SSE.Views.Statusbar.RenameDialog.errNameWrongChar": "A sheet name cannot contain the following characters: \\/*?[]:", "SSE.Views.Statusbar.RenameDialog.labelSheetName": "Sheet Name", diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1.25x/big/allow-edit-ranges.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1.25x/big/allow-edit-ranges.png new file mode 100644 index 0000000000..5ca1006cfb Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1.25x/big/allow-edit-ranges.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1.25x/big/protect-sheet.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1.25x/big/protect-sheet.png new file mode 100644 index 0000000000..8635630cb6 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1.25x/big/protect-sheet.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1.25x/big/protect-workbook.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1.25x/big/protect-workbook.png new file mode 100644 index 0000000000..3a79456b78 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1.25x/big/protect-workbook.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1.5x/big/allow-edit-ranges.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1.5x/big/allow-edit-ranges.png new file mode 100644 index 0000000000..d4bfc9f5a4 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1.5x/big/allow-edit-ranges.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1.5x/big/protect-sheet.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1.5x/big/protect-sheet.png new file mode 100644 index 0000000000..ad5d815049 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1.5x/big/protect-sheet.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1.5x/big/protect-workbook.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1.5x/big/protect-workbook.png new file mode 100644 index 0000000000..dac23614c5 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1.5x/big/protect-workbook.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1.75x/big/allow-edit-ranges.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1.75x/big/allow-edit-ranges.png new file mode 100644 index 0000000000..713d290ca0 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1.75x/big/allow-edit-ranges.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1.75x/big/protect-sheet.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1.75x/big/protect-sheet.png new file mode 100644 index 0000000000..b6bdb51c39 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1.75x/big/protect-sheet.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1.75x/big/protect-workbook.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1.75x/big/protect-workbook.png new file mode 100644 index 0000000000..c58415e062 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1.75x/big/protect-workbook.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1x/big/allow-edit-ranges.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1x/big/allow-edit-ranges.png new file mode 100644 index 0000000000..8aac863726 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1x/big/allow-edit-ranges.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1x/big/protect-sheet.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1x/big/protect-sheet.png new file mode 100644 index 0000000000..fb3caef38b Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1x/big/protect-sheet.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/1x/big/protect-workbook.png b/apps/spreadsheeteditor/main/resources/img/toolbar/1x/big/protect-workbook.png new file mode 100644 index 0000000000..2995d14608 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/1x/big/protect-workbook.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/2x/big/allow-edit-ranges.png b/apps/spreadsheeteditor/main/resources/img/toolbar/2x/big/allow-edit-ranges.png new file mode 100644 index 0000000000..30706da3be Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/2x/big/allow-edit-ranges.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/2x/big/protect-sheet.png b/apps/spreadsheeteditor/main/resources/img/toolbar/2x/big/protect-sheet.png new file mode 100644 index 0000000000..cc5e80c465 Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/2x/big/protect-sheet.png differ diff --git a/apps/spreadsheeteditor/main/resources/img/toolbar/2x/big/protect-workbook.png b/apps/spreadsheeteditor/main/resources/img/toolbar/2x/big/protect-workbook.png new file mode 100644 index 0000000000..b96369801f Binary files /dev/null and b/apps/spreadsheeteditor/main/resources/img/toolbar/2x/big/protect-workbook.png differ diff --git a/apps/spreadsheeteditor/mobile/locale/en.json b/apps/spreadsheeteditor/mobile/locale/en.json index a048a689c9..9211947d1d 100644 --- a/apps/spreadsheeteditor/mobile/locale/en.json +++ b/apps/spreadsheeteditor/mobile/locale/en.json @@ -1,647 +1,650 @@ { - "About": { - "textAbout": "About", - "textAddress": "Address", - "textBack": "Back", - "textEmail": "Email", - "textPoweredBy": "Powered By", - "textTel": "Tel", - "textVersion": "Version" - }, - "Common": { - "Collaboration": { - "notcriticalErrorTitle": "Warning", - "textAddComment": "Add Comment", - "textAddReply": "Add Reply", - "textBack": "Back", - "textCancel": "Cancel", - "textCollaboration": "Collaboration", - "textComments": "Comments", - "textDeleteComment": "Delete Comment", - "textDeleteReply": "Delete Reply", - "textDone": "Done", - "textEdit": "Edit", - "textEditComment": "Edit Comment", - "textEditReply": "Edit Reply", - "textEditUser": "Users who are editing the file:", - "textMessageDeleteComment": "Do you really want to delete this comment?", - "textMessageDeleteReply": "Do you really want to delete this reply?", - "textNoComments": "This document doesn't contain comments", - "textReopen": "Reopen", - "textResolve": "Resolve", - "textTryUndoRedo": "The Undo/Redo functions are disabled for the Fast co-editing mode.", - "textUsers": "Users" + "About": { + "textAbout": "About", + "textAddress": "Address", + "textBack": "Back", + "textEmail": "Email", + "textPoweredBy": "Powered By", + "textTel": "Tel", + "textVersion": "Version" }, - "ThemeColorPalette": { - "textCustomColors": "Custom Colors", - "textStandartColors": "Standard Colors", - "textThemeColors": "Theme Colors" - } - }, - "ContextMenu": { - "errorCopyCutPaste": "Copy, cut, and paste actions using the context menu will be performed within the current file only.", - "menuAddComment": "Add Comment", - "menuAddLink": "Add Link", - "menuCancel": "Cancel", - "menuCell": "Cell", - "menuDelete": "Delete", - "menuEdit": "Edit", - "menuFreezePanes": "Freeze Panes", - "menuHide": "Hide", - "menuMerge": "Merge", - "menuMore": "More", - "menuOpenLink": "Open Link", - "menuShow": "Show", - "menuUnfreezePanes": "Unfreeze Panes", - "menuUnmerge": "Unmerge", - "menuUnwrap": "Unwrap", - "menuViewComment": "View Comment", - "menuWrap": "Wrap", - "notcriticalErrorTitle": "Warning", - "textCopyCutPasteActions": "Copy, Cut and Paste Actions", - "textDoNotShowAgain": "Don't show again", - "warnMergeLostData": "The operation can destroy data in the selected cells. Continue?" - }, - "Controller": { - "Main": { - "criticalErrorTitle": "Error", - "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please, contact your admin.", - "errorProcessSaveResult": "Saving is failed.", - "errorServerVersion": "The editor version has been updated. The page will be reloaded to apply the changes.", - "errorUpdateVersion": "The file version has been changed. The page will be reloaded.", - "leavePageText": "You have unsaved changes in this document. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.", - "notcriticalErrorTitle": "Warning", - "SDK": { - "txtAccent": "Accent", - "txtAll": "(All)", - "txtArt": "Your text here", - "txtBlank": "(blank)", - "txtByField": "%1 of %2", - "txtClearFilter": "Clear Filter (Alt+C)", - "txtColLbls": "Column Labels", - "txtColumn": "Column", - "txtConfidential": "Confidential", - "txtDate": "Date", - "txtDays": "Days", - "txtDiagramTitle": "Chart Title", - "txtFile": "File", - "txtGrandTotal": "Grand Total", - "txtGroup": "Group", - "txtHours": "Hours", - "txtMinutes": "Minutes", - "txtMonths": "Months", - "txtMultiSelect": "Multi-Select (Alt+S)", - "txtOr": "%1 or %2", - "txtPage": "Page", - "txtPageOf": "Page %1 of %2", - "txtPages": "Pages", - "txtPreparedBy": "Prepared by", - "txtPrintArea": "Print_Area", - "txtQuarter": "Qtr", - "txtQuarters": "Quarters", - "txtRow": "Row", - "txtRowLbls": "Row Labels", - "txtSeconds": "Seconds", - "txtSeries": "Series", - "txtStyle_Bad": "Bad", - "txtStyle_Calculation": "Calculation", - "txtStyle_Check_Cell": "Check Cell", - "txtStyle_Comma": "Comma", - "txtStyle_Currency": "Currency", - "txtStyle_Explanatory_Text": "Explanatory Text", - "txtStyle_Good": "Good", - "txtStyle_Heading_1": "Heading 1", - "txtStyle_Heading_2": "Heading 2", - "txtStyle_Heading_3": "Heading 3", - "txtStyle_Heading_4": "Heading 4", - "txtStyle_Input": "Input", - "txtStyle_Linked_Cell": "Linked Cell", - "txtStyle_Neutral": "Neutral", - "txtStyle_Normal": "Normal", - "txtStyle_Note": "Note", - "txtStyle_Output": "Output", - "txtStyle_Percent": "Percent", - "txtStyle_Title": "Title", - "txtStyle_Total": "Total", - "txtStyle_Warning_Text": "Warning Text", - "txtTab": "Tab", - "txtTable": "Table", - "txtTime": "Time", - "txtValues": "Values", - "txtXAxis": "X Axis", - "txtYAxis": "Y Axis", - "txtYears": "Years" - }, - "textAnonymous": "Anonymous", - "textBuyNow": "Visit website", - "textClose": "Close", - "textContactUs": "Contact sales", - "textCustomLoader": "Sorry, you are not entitled to change the loader. Please, contact our sales department to get a quote.", - "textGuest": "Guest", - "textHasMacros": "The file contains automatic macros.
Do you want to run macros?", - "textNo": "No", - "textNoLicenseTitle": "License limit reached", - "textPaidFeature": "Paid feature", - "textRemember": "Remember my choice", - "textYes": "Yes", - "titleServerVersion": "Editor updated", - "titleUpdateVersion": "Version changed", - "warnLicenseExceeded": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only. Contact your administrator to learn more.", - "warnLicenseLimitedNoAccess": "License expired. You have no access to document editing functionality. Please, contact your admin.", - "warnLicenseLimitedRenewed": "License needs to be renewed. You have limited access to document editing functionality.
Please contact your administrator to get full access", - "warnLicenseUsersExceeded": "You've reached the user limit for %1 editors. Contact your administrator to learn more.", - "warnNoLicense": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only. Contact %1 sales team for personal upgrade terms.", - "warnNoLicenseUsers": "You've reached the user limit for %1 editors. Contact %1 sales team for personal upgrade terms.", - "warnProcessRightsChange": "You don't have permission to edit the file." - } - }, - "Error": { - "convertationTimeoutText": "Conversion timeout exceeded.", - "criticalErrorExtText": "Press 'OK' to go back to the document list.", - "criticalErrorTitle": "Error", - "downloadErrorText": "Download failed.", - "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please, contact your admin.", - "errorArgsRange": "An error in the formula.
Incorrect arguments range.", - "errorAutoFilterChange": "The operation is not allowed as it is attempting to shift cells in a table on your worksheet.", - "errorAutoFilterChangeFormatTable": "The operation could not be done for the selected cells as you cannot move a part of a table.
Select another data range so that the whole table is shifted and try again.", - "errorAutoFilterDataRange": "The operation could not be done for the selected range of cells.
Select a uniform data range inside or outside the table and try again.", - "errorAutoFilterHiddenRange": "The operation cannot be performed because the area contains filtered cells.
Please, unhide the filtered elements and try again.", - "errorBadImageUrl": "Image url is incorrect", - "errorChangeArray": "You cannot change part of an array.", - "errorConnectToServer": "Can't save this doc. Check your connection settings or contact your admin.
When you click the 'OK' button, you will be prompted to download the document.", - "errorCopyMultiselectArea": "This command cannot be used with multiple selections.
Select a single range and try again.", - "errorCountArg": "An error in the formula.
Invalid number of arguments.", - "errorCountArgExceed": "An error in the formula.
Maximum number of arguments exceeded.", - "errorCreateDefName": "The existing named ranges cannot be edited and the new ones cannot be created
at the moment as some of them are being edited.", - "errorDatabaseConnection": "External error.
Database connection error. Please, contact support.", - "errorDataEncrypted": "Encrypted changes have been received, they cannot be deciphered.", - "errorDataRange": "Incorrect data range.", - "errorDataValidate": "The value you entered is not valid.
A user has restricted values that can be entered into this cell.", - "errorDefaultMessage": "Error code: %1", - "errorEditingDownloadas": "An error occurred during the work with the document.
Use the 'Download' option to save the file backup copy locally.", - "errorFilePassProtect": "The file is password protected and could not be opened.", - "errorFileRequest": "External error.
File Request. Please, contact support.", - "errorFileSizeExceed": "The file size exceeds your server limitation.
Please, contact your admin for details.", - "errorFileVKey": "External error.
Incorrect security key. Please, contact support.", - "errorFillRange": "Could not fill the selected range of cells.
All the merged cells need to be the same size.", - "errorFormulaName": "An error in the formula.
Incorrect formula name.", - "errorFormulaParsing": "Internal error while the formula parsing.", - "errorFrmlMaxLength": "You cannot add this formula as its length exceeds the allowed number of characters.
Please, edit it and try again.", - "errorFrmlMaxReference": "You cannot enter this formula because it has too many values,
cell references, and/or names.", - "errorFrmlMaxTextLength": "Text values in formulas are limited to 255 characters.
Use the CONCATENATE function or concatenation operator (&)", - "errorFrmlWrongReferences": "The function refers to a sheet that does not exist.
Please, check the data and try again.", - "errorInvalidRef": "Enter a correct name for the selection or a valid reference to go to.", - "errorKeyEncrypt": "Unknown key descriptor", - "errorKeyExpire": "Key descriptor expired", - "errorLockedAll": "The operation could not be done as the sheet has been locked by another user.", - "errorLockedCellPivot": "You cannot change data inside a pivot table.", - "errorLockedWorksheetRename": "The sheet cannot be renamed at the moment as it is being renamed by another user", - "errorMaxPoints": "The maximum number of points in series per chart is 4096.", - "errorMoveRange": "Cannot change a part of a merged cell", - "errorMultiCellFormula": "Multi-cell array formulas are not allowed in tables.", - "errorOpenWarning": "The length of one of the formulas in the file exceeded
the allowed number of characters and it was removed.", - "errorOperandExpected": "The entered function syntax is not correct. Please, check if you missed one of the parentheses - '(' or ')'.", - "errorPasteMaxRange": "The copy and paste area does not match. Please, select an area of the same size or click the first cell in a row to paste the copied cells.", - "errorPrintMaxPagesCount": "Unfortunately, it’s not possible to print more than 1500 pages at once in the current version of the program.
This restriction will be eliminated in upcoming releases.", - "errorSessionAbsolute": "The document editing session has expired. Please, reload the page.", - "errorSessionIdle": "The document has not been edited for quite a long time. Please, reload the page.", - "errorSessionToken": "The connection to the server has been interrupted. Please, reload the page.", - "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.", - "errorUnexpectedGuid": "External error.
Unexpected Guid. Please, contact support.", - "errorUpdateVersionOnDisconnect": "Internet connection has been restored, and the file version has been changed.
Before you can continue working, you need to download the file or copy its content to make sure nothing is lost, and then reload this page.", - "errorUserDrop": "The file cannot be accessed right now.", - "errorUsersExceed": "The number of users allowed by the pricing plan was exceeded", - "errorViewerDisconnect": "Connection is lost. You can still view the document,
but you won't be able to download it until the connection is restored and the page is reloaded.", - "errorWrongBracketsCount": "An error in the formula.
Wrong number of brackets.", - "errorWrongOperator": "An error in the entered formula. The wrong operator is used.
Correct the error or use the Esc button to cancel the formula editing.", - "notcriticalErrorTitle": "Warning", - "openErrorText": "An error has occurred while opening the file", - "pastInMergeAreaError": "Cannot change a part of a merged cell", - "saveErrorText": "An error has occurred while saving the file", - "scriptLoadError": "The connection is too slow, some of the components could not be loaded. Please, reload the page.", - "unknownErrorText": "Unknown error.", - "uploadImageExtMessage": "Unknown image format.", - "uploadImageFileCountMessage": "No images uploaded.", - "uploadImageSizeMessage": "The image is too big. The maximum size is 25 MB." - }, - "LongActions": { - "applyChangesTextText": "Loading data...", - "applyChangesTitleText": "Loading Data", - "confirmMoveCellRange": "The destination cells range can contain data. Continue the operation?", - "confirmPutMergeRange": "The source data contains merged cells.
They will be unmerged before they are pasted into the table.", - "confirmReplaceFormulaInTable": "Formulas in the header row will be removed and converted to static text.
Do you want to continue?", - "downloadTextText": "Downloading document...", - "downloadTitleText": "Downloading Document", - "loadFontsTextText": "Loading data...", - "loadFontsTitleText": "Loading Data", - "loadFontTextText": "Loading data...", - "loadFontTitleText": "Loading Data", - "loadImagesTextText": "Loading images...", - "loadImagesTitleText": "Loading Images", - "loadImageTextText": "Loading image...", - "loadImageTitleText": "Loading Image", - "loadingDocumentTextText": "Loading document...", - "loadingDocumentTitleText": "Loading document", - "notcriticalErrorTitle": "Warning", - "openTextText": "Opening document...", - "openTitleText": "Opening Document", - "printTextText": "Printing document...", - "printTitleText": "Printing Document", - "savePreparingText": "Preparing to save", - "savePreparingTitle": "Preparing to save. Please wait...", - "saveTextText": "Saving document...", - "saveTitleText": "Saving Document", - "textLoadingDocument": "Loading document", - "textNo": "No", - "textOk": "Ok", - "textYes": "Yes", - "txtEditingMode": "Set editing mode...", - "uploadImageTextText": "Uploading image...", - "uploadImageTitleText": "Uploading Image", - "waitText": "Please, wait..." - }, - "Statusbar": { - "notcriticalErrorTitle": "Warning", - "textCancel": "Cancel", - "textDelete": "Delete", - "textDuplicate": "Duplicate", - "textErrNameExists": "Worksheet with this name already exists.", - "textErrNameWrongChar": "A sheet name cannot contains characters: \\, /, *, ?, [, ], :", - "textErrNotEmpty": "Sheet name must not be empty", - "textErrorLastSheet": "The workbook must have at least one visible worksheet.", - "textErrorRemoveSheet": "Can't delete the worksheet.", - "textHide": "Hide", - "textMore": "More", - "textRename": "Rename", - "textRenameSheet": "Rename Sheet", - "textSheet": "Sheet", - "textSheetName": "Sheet Name", - "textUnhide": "Unhide", - "textWarnDeleteSheet": "The worksheet maybe has data. Proceed operation?" - }, - "Toolbar": { - "dlgLeaveMsgText": "You have unsaved changes in this document. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.", - "dlgLeaveTitleText": "You leave the application", - "leaveButtonText": "Leave this Page", - "stayButtonText": "Stay on this Page" - }, - "View": { - "Add": { - "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.", - "notcriticalErrorTitle": "Warning", - "sCatDateAndTime": "Date and time", - "sCatEngineering": "Engineering", - "sCatFinancial": "Financial", - "sCatInformation": "Information", - "sCatLogical": "Logical", - "sCatLookupAndReference": "Lookup and Reference", - "sCatMathematic": "Math and trigonometry", - "sCatStatistical": "Statistical", - "sCatTextAndData": "Text and data", - "textAddLink": "Add Link", - "textAddress": "Address", - "textBack": "Back", - "textCancel": "Cancel", - "textChart": "Chart", - "textComment": "Comment", - "textDisplay": "Display", - "textEmptyImgUrl": "You need to specify the image URL.", - "textExternalLink": "External Link", - "textFilter": "Filter", - "textFunction": "Function", - "textGroups": "CATEGORIES", - "textImage": "Image", - "textImageURL": "Image URL", - "textInsert": "Insert", - "textInsertImage": "Insert Image", - "textInternalDataRange": "Internal Data Range", - "textInvalidRange": "ERROR! Invalid cells range", - "textLink": "Link", - "textLinkSettings": "Link Settings", - "textLinkType": "Link Type", - "textOther": "Other", - "textPictureFromLibrary": "Picture from library", - "textPictureFromURL": "Picture from URL", - "textRange": "Range", - "textRequired": "Required", - "textScreenTip": "Screen Tip", - "textShape": "Shape", - "textSheet": "Sheet", - "textSortAndFilter": "Sort and Filter", - "txtExpand": "Expand and sort", - "txtExpandSort": "The data next to the selection will not be sorted. Do you want to expand the selection to include the adjacent data or continue with sorting the currently selected cells only?", - "txtNotUrl": "This field should be a URL in the format \"http://www.example.com\"", - "txtSorting": "Sorting", - "txtSortSelected": "Sort selected" + "Common": { + "Collaboration": { + "notcriticalErrorTitle": "Warning", + "textAddComment": "Add Comment", + "textAddReply": "Add Reply", + "textBack": "Back", + "textCancel": "Cancel", + "textCollaboration": "Collaboration", + "textComments": "Comments", + "textDeleteComment": "Delete Comment", + "textDeleteReply": "Delete Reply", + "textDone": "Done", + "textEdit": "Edit", + "textEditComment": "Edit Comment", + "textEditReply": "Edit Reply", + "textEditUser": "Users who are editing the file:", + "textMessageDeleteComment": "Do you really want to delete this comment?", + "textMessageDeleteReply": "Do you really want to delete this reply?", + "textNoComments": "This document doesn't contain comments", + "textReopen": "Reopen", + "textResolve": "Resolve", + "textTryUndoRedo": "The Undo/Redo functions are disabled for the Fast co-editing mode.", + "textUsers": "Users" + }, + "ThemeColorPalette": { + "textCustomColors": "Custom Colors", + "textStandartColors": "Standard Colors", + "textThemeColors": "Theme Colors" + } }, - "Edit": { - "notcriticalErrorTitle": "Warning", - "textAccounting": "Accounting", - "textActualSize": "Actual Size", - "textAddCustomColor": "Add Custom Color", - "textAddress": "Address", - "textAlign": "Align", - "textAlignBottom": "Align Bottom", - "textAlignCenter": "Align Center", - "textAlignLeft": "Align Left", - "textAlignMiddle": "Align Middle", - "textAlignRight": "Align Right", - "textAlignTop": "Align Top", - "textAllBorders": "All Borders", - "textAngleClockwise": "Angle Clockwise", - "textAngleCounterclockwise": "Angle Counterclockwise", - "textAuto": "Auto", - "textAxisCrosses": "Axis Crosses", - "textAxisOptions": "Axis Options", - "textAxisPosition": "Axis Position", - "textAxisTitle": "Axis Title", - "textBack": "Back", - "textBetweenTickMarks": "Between Tick Marks", - "textBillions": "Billions", - "textBorder": "Border", - "textBorderStyle": "Border Style", - "textBottom": "Bottom", - "textBottomBorder": "Bottom Border", - "textBringToForeground": "Bring to Foreground", - "textCell": "Cell", - "textCellStyles": "Cell Styles", - "textCenter": "Center", - "textChart": "Chart", - "textChartTitle": "Chart Title", - "textClearFilter": "Clear Filter", - "textColor": "Color", - "textCross": "Cross", - "textCrossesValue": "Crosses Value", - "textCurrency": "Currency", - "textCustomColor": "Custom Color", - "textDataLabels": "Data Labels", - "textDate": "Date", - "textDefault": "Selected range", - "textDeleteFilter": "Delete Filter", - "textDesign": "Design", - "textDiagonalDownBorder": "Diagonal Down Border", - "textDiagonalUpBorder": "Diagonal Up Border", - "textDisplay": "Display", - "textDisplayUnits": "Display Units", - "textDollar": "Dollar", - "textEditLink": "Edit Link", - "textEffects": "Effects", - "textEmptyImgUrl": "You need to specify the image URL.", - "textEmptyItem": "{Blanks}", - "textErrorMsg": "You must choose at least one value", - "textErrorTitle": "Warning", - "textEuro": "Euro", - "textExternalLink": "External Link", - "textFill": "Fill", - "textFillColor": "Fill Color", - "textFilterOptions": "Filter Options", - "textFit": "Fit Width", - "textFonts": "Fonts", - "textFormat": "Format", - "textFraction": "Fraction", - "textFromLibrary": "Picture from Library", - "textFromURL": "Picture from URL", - "textGeneral": "General", - "textGridlines": "Gridlines", - "textHigh": "High", - "textHorizontal": "Horizontal", - "textHorizontalAxis": "Horizontal Axis", - "textHorizontalText": "Horizontal Text", - "textHundredMil": "100 000 000", - "textHundreds": "Hundreds", - "textHundredThousands": "100 000", - "textHyperlink": "Hyperlink", - "textImage": "Image", - "textImageURL": "Image URL", - "textIn": "In", - "textInnerBottom": "Inner Bottom", - "textInnerTop": "Inner Top", - "textInsideBorders": "Inside Borders", - "textInsideHorizontalBorder": "Inside Horizontal Border", - "textInsideVerticalBorder": "Inside Vertical Border", - "textInteger": "Integer", - "textInternalDataRange": "Internal Data Range", - "textInvalidRange": "Invalid cells range", - "textJustified": "Justified", - "textLabelOptions": "Label Options", - "textLabelPosition": "Label Position", - "textLayout": "Layout", - "textLeft": "Left", - "textLeftBorder": "Left Border", - "textLeftOverlay": "Left Overlay", - "textLegend": "Legend", - "textLink": "Link", - "textLinkSettings": "Link Settings", - "textLinkType": "Link Type", - "textLow": "Low", - "textMajor": "Major", - "textMajorAndMinor": "Major And Minor", - "textMajorType": "Major Type", - "textMaximumValue": "Maximum Value", - "textMedium": "Medium", - "textMillions": "Millions", - "textMinimumValue": "Minimum Value", - "textMinor": "Minor", - "textMinorType": "Minor Type", - "textMoveBackward": "Move Backward", - "textMoveForward": "Move Forward", - "textNextToAxis": "Next to Axis", - "textNoBorder": "No Border", - "textNone": "None", - "textNoOverlay": "No Overlay", - "textNotUrl": "This field should be a URL in the format \"http://www.example.com\"", - "textNumber": "Number", - "textOnTickMarks": "On Tick Marks", - "textOpacity": "Opacity", - "textOut": "Out", - "textOuterTop": "Outer Top", - "textOutsideBorders": "Outside Borders", - "textOverlay": "Overlay", - "textPercentage": "Percentage", - "textPictureFromLibrary": "Picture from Library", - "textPictureFromURL": "Picture from URL", - "textPound": "Pound", - "textPt": "pt", - "textRange": "Range", - "textRemoveChart": "Remove Chart", - "textRemoveImage": "Remove Image", - "textRemoveLink": "Remove Link", - "textRemoveShape": "Remove Shape", - "textReorder": "Reorder", - "textReplace": "Replace", - "textReplaceImage": "Replace Image", - "textRequired": "Required", - "textRight": "Right", - "textRightBorder": "Right Border", - "textRightOverlay": "Right Overlay", - "textRotated": "Rotated", - "textRotateTextDown": "Rotate Text Down", - "textRotateTextUp": "Rotate Text Up", - "textRouble": "Rouble", - "textScientific": "Scientific", - "textScreenTip": "Screen Tip", - "textSelectAll": "Select All", - "textSelectObjectToEdit": "Select object to edit", - "textSendToBackground": "Send to Background", - "textSettings": "Settings", - "textShape": "Shape", - "textSheet": "Sheet", - "textSize": "Size", - "textStyle": "Style", - "textTenMillions": "10 000 000", - "textTenThousands": "10 000", - "textText": "Text", - "textTextColor": "Text Color", - "textTextFormat": "Text Format", - "textTextOrientation": "Text Orientation", - "textThick": "Thick", - "textThin": "Thin", - "textThousands": "Thousands", - "textTickOptions": "Tick Options", - "textTime": "Time", - "textTop": "Top", - "textTopBorder": "Top Border", - "textTrillions": "Trillions", - "textType": "Type", - "textValue": "Value", - "textValuesInReverseOrder": "Values in Reverse Order", - "textVertical": "Vertical", - "textVerticalAxis": "Vertical Axis", - "textVerticalText": "Vertical Text", - "textWrapText": "Wrap Text", - "textYen": "Yen", - "txtNotUrl": "This field should be a URL in the format \"http://www.example.com\"", - "txtSortHigh2Low": "Sort Highest to Lowest", - "txtSortLow2High": "Sort Lowest to Highest" + "ContextMenu": { + "errorCopyCutPaste": "Copy, cut, and paste actions using the context menu will be performed within the current file only.", + "menuAddComment": "Add Comment", + "menuAddLink": "Add Link", + "menuCancel": "Cancel", + "menuCell": "Cell", + "menuDelete": "Delete", + "menuEdit": "Edit", + "menuFreezePanes": "Freeze Panes", + "menuHide": "Hide", + "menuMerge": "Merge", + "menuMore": "More", + "menuOpenLink": "Open Link", + "menuShow": "Show", + "menuUnfreezePanes": "Unfreeze Panes", + "menuUnmerge": "Unmerge", + "menuUnwrap": "Unwrap", + "menuViewComment": "View Comment", + "menuWrap": "Wrap", + "notcriticalErrorTitle": "Warning", + "textCopyCutPasteActions": "Copy, Cut and Paste Actions", + "textDoNotShowAgain": "Don't show again", + "warnMergeLostData": "The operation can destroy data in the selected cells. Continue?" }, - "Settings": { - "advCSVOptions": "Choose CSV options", - "advDRMEnterPassword": "Your password, please:", - "advDRMOptions": "Protected File", - "advDRMPassword": "Password", - "closeButtonText": "Close File", - "notcriticalErrorTitle": "Warning", - "textAbout": "About", - "textAddress": "Address", - "textApplication": "Application", - "textApplicationSettings": "Application Settings", - "textAuthor": "Author", - "textBack": "Back", - "textBottom": "Bottom", - "textByColumns": "By columns", - "textByRows": "By rows", - "textCancel": "Cancel", - "textCentimeter": "Centimeter", - "textCollaboration": "Collaboration", - "textColorSchemes": "Color Schemes", - "textComment": "Comment", - "textCommentingDisplay": "Commenting Display", - "textComments": "Comments", - "textCreated": "Created", - "textCustomSize": "Custom Size", - "textDisableAll": "Disable All", - "textDisableAllMacrosWithNotification": "Disable all macros with a notification", - "textDisableAllMacrosWithoutNotification": "Disable all macros without a notification", - "textDone": "Done", - "textDownload": "Download", - "textDownloadAs": "Download As", - "textEmail": "Email", - "textEnableAll": "Enable All", - "textEnableAllMacrosWithoutNotification": "Enable all macros without a notification", - "textFind": "Find", - "textFindAndReplace": "Find and Replace", - "textFindAndReplaceAll": "Find and Replace All", - "textFormat": "Format", - "textFormulaLanguage": "Formula Language", - "textFormulas": "Formulas", - "textHelp": "Help", - "textHideGridlines": "Hide Gridlines", - "textHideHeadings": "Hide Headings", - "textHighlightRes": "Highlight results", - "textInch": "Inch", - "textLandscape": "Landscape", - "textLastModified": "Last Modified", - "textLastModifiedBy": "Last Modified By", - "textLeft": "Left", - "textLocation": "Location", - "textLookIn": "Look In", - "textMacrosSettings": "Macros Settings", - "textMargins": "Margins", - "textMatchCase": "Match Case", - "textMatchCell": "Match Cell", - "textNoTextFound": "Text not found", - "textOpenFile": "Enter a password to open the file", - "textOrientation": "Orientation", - "textOwner": "Owner", - "textPoint": "Point", - "textPortrait": "Portrait", - "textPoweredBy": "Powered By", - "textPrint": "Print", - "textR1C1Style": "R1C1 Reference Style", - "textRegionalSettings": "Regional Settings", - "textReplace": "Replace", - "textReplaceAll": "Replace All", - "textResolvedComments": "Resolved Comments", - "textRight": "Right", - "textSearch": "Search", - "textSearchBy": "Search", - "textSearchIn": "Search In", - "textSettings": "Settings", - "textSheet": "Sheet", - "textShowNotification": "Show Notification", - "textSpreadsheetFormats": "Spreadsheet Formats", - "textSpreadsheetInfo": "Spreadsheet Info", - "textSpreadsheetSettings": "Spreadsheet Settings", - "textSpreadsheetTitle": "Spreadsheet Title", - "textSubject": "Subject", - "textTel": "Tel", - "textTitle": "Title", - "textTop": "Top", - "textUnitOfMeasurement": "Unit Of Measurement", - "textUploaded": "Uploaded", - "textValues": "Values", - "textVersion": "Version", - "textWorkbook": "Workbook", - "txtDelimiter": "Delimiter", - "txtEncoding": "Encoding", - "txtIncorrectPwd": "Password is incorrect", - "txtProtected": "Once you enter the password and open the file, the current password to the file will be reset", - "txtScheme1": "Office", - "txtScheme10": "Median", - "txtScheme11": "Metro", - "txtScheme12": "Module", - "txtScheme13": "Opulent", - "txtScheme14": "Oriel", - "txtScheme15": "Origin", - "txtScheme16": "Paper", - "txtScheme17": "Solstice", - "txtScheme18": "Technic", - "txtScheme19": "Trek", - "txtScheme2": "Grayscale", - "txtScheme20": "Urban", - "txtScheme21": "Verve", - "txtScheme22": "New Office", - "txtScheme3": "Apex", - "txtScheme4": "Aspect", - "txtScheme5": "Civic", - "txtScheme6": "Concourse", - "txtScheme7": "Equity", - "txtScheme8": "Flow", - "txtScheme9": "Foundry", - "txtSpace": "Space", - "txtTab": "Tab", - "warnDownloadAs": "If you continue saving in this format all features except the text will be lost.
Are you sure you want to continue?", - "textChooseCsvOptions": "Choose CSV Options", - "txtDownloadCsv": "Download CSV", - "textDelimeter": "Delimeter", - "textEncoding": "Encoding", - "textChooseEncoding": "Choose Encoding", - "textChooseDelimeter": "Choose Delimeter", - "txtComma": "Comma", - "txtSemicolon": "Semicolon", - "txtColon": "Colon", - "txtOk": "Ok" + "Controller": { + "Main": { + "criticalErrorTitle": "Error", + "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please, contact your admin.", + "errorProcessSaveResult": "Saving is failed.", + "errorServerVersion": "The editor version has been updated. The page will be reloaded to apply the changes.", + "errorUpdateVersion": "The file version has been changed. The page will be reloaded.", + "leavePageText": "You have unsaved changes in this document. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.", + "notcriticalErrorTitle": "Warning", + "SDK": { + "txtAccent": "Accent", + "txtAll": "(All)", + "txtArt": "Your text here", + "txtBlank": "(blank)", + "txtByField": "%1 of %2", + "txtClearFilter": "Clear Filter (Alt+C)", + "txtColLbls": "Column Labels", + "txtColumn": "Column", + "txtConfidential": "Confidential", + "txtDate": "Date", + "txtDays": "Days", + "txtDiagramTitle": "Chart Title", + "txtFile": "File", + "txtGrandTotal": "Grand Total", + "txtGroup": "Group", + "txtHours": "Hours", + "txtMinutes": "Minutes", + "txtMonths": "Months", + "txtMultiSelect": "Multi-Select (Alt+S)", + "txtOr": "%1 or %2", + "txtPage": "Page", + "txtPageOf": "Page %1 of %2", + "txtPages": "Pages", + "txtPreparedBy": "Prepared by", + "txtPrintArea": "Print_Area", + "txtQuarter": "Qtr", + "txtQuarters": "Quarters", + "txtRow": "Row", + "txtRowLbls": "Row Labels", + "txtSeconds": "Seconds", + "txtSeries": "Series", + "txtStyle_Bad": "Bad", + "txtStyle_Calculation": "Calculation", + "txtStyle_Check_Cell": "Check Cell", + "txtStyle_Comma": "Comma", + "txtStyle_Currency": "Currency", + "txtStyle_Explanatory_Text": "Explanatory Text", + "txtStyle_Good": "Good", + "txtStyle_Heading_1": "Heading 1", + "txtStyle_Heading_2": "Heading 2", + "txtStyle_Heading_3": "Heading 3", + "txtStyle_Heading_4": "Heading 4", + "txtStyle_Input": "Input", + "txtStyle_Linked_Cell": "Linked Cell", + "txtStyle_Neutral": "Neutral", + "txtStyle_Normal": "Normal", + "txtStyle_Note": "Note", + "txtStyle_Output": "Output", + "txtStyle_Percent": "Percent", + "txtStyle_Title": "Title", + "txtStyle_Total": "Total", + "txtStyle_Warning_Text": "Warning Text", + "txtTab": "Tab", + "txtTable": "Table", + "txtTime": "Time", + "txtValues": "Values", + "txtXAxis": "X Axis", + "txtYAxis": "Y Axis", + "txtYears": "Years" + }, + "textAnonymous": "Anonymous", + "textBuyNow": "Visit website", + "textClose": "Close", + "textContactUs": "Contact sales", + "textCustomLoader": "Sorry, you are not entitled to change the loader. Please, contact our sales department to get a quote.", + "textGuest": "Guest", + "textHasMacros": "The file contains automatic macros.
Do you want to run macros?", + "textNo": "No", + "textNoLicenseTitle": "License limit reached", + "textPaidFeature": "Paid feature", + "textRemember": "Remember my choice", + "textYes": "Yes", + "titleServerVersion": "Editor updated", + "titleUpdateVersion": "Version changed", + "warnLicenseExceeded": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only. Contact your administrator to learn more.", + "warnLicenseLimitedNoAccess": "License expired. You have no access to document editing functionality. Please, contact your admin.", + "warnLicenseLimitedRenewed": "License needs to be renewed. You have limited access to document editing functionality.
Please contact your administrator to get full access", + "warnLicenseUsersExceeded": "You've reached the user limit for %1 editors. Contact your administrator to learn more.", + "warnNoLicense": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only. Contact %1 sales team for personal upgrade terms.", + "warnNoLicenseUsers": "You've reached the user limit for %1 editors. Contact %1 sales team for personal upgrade terms.", + "warnProcessRightsChange": "You don't have permission to edit the file." + } + }, + "Error": { + "convertationTimeoutText": "Conversion timeout exceeded.", + "criticalErrorExtText": "Press 'OK' to go back to the document list.", + "criticalErrorTitle": "Error", + "downloadErrorText": "Download failed.", + "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please, contact your admin.", + "errorArgsRange": "An error in the formula.
Incorrect arguments range.", + "errorAutoFilterChange": "The operation is not allowed as it is attempting to shift cells in a table on your worksheet.", + "errorAutoFilterChangeFormatTable": "The operation could not be done for the selected cells as you cannot move a part of a table.
Select another data range so that the whole table is shifted and try again.", + "errorAutoFilterDataRange": "The operation could not be done for the selected range of cells.
Select a uniform data range inside or outside the table and try again.", + "errorAutoFilterHiddenRange": "The operation cannot be performed because the area contains filtered cells.
Please, unhide the filtered elements and try again.", + "errorBadImageUrl": "Image url is incorrect", + "errorChangeArray": "You cannot change part of an array.", + "errorConnectToServer": "Can't save this doc. Check your connection settings or contact your admin.
When you click the 'OK' button, you will be prompted to download the document.", + "errorCopyMultiselectArea": "This command cannot be used with multiple selections.
Select a single range and try again.", + "errorCountArg": "An error in the formula.
Invalid number of arguments.", + "errorCountArgExceed": "An error in the formula.
Maximum number of arguments exceeded.", + "errorCreateDefName": "The existing named ranges cannot be edited and the new ones cannot be created
at the moment as some of them are being edited.", + "errorDatabaseConnection": "External error.
Database connection error. Please, contact support.", + "errorDataEncrypted": "Encrypted changes have been received, they cannot be deciphered.", + "errorDataRange": "Incorrect data range.", + "errorDataValidate": "The value you entered is not valid.
A user has restricted values that can be entered into this cell.", + "errorDefaultMessage": "Error code: %1", + "errorEditingDownloadas": "An error occurred during the work with the document.
Use the 'Download' option to save the file backup copy locally.", + "errorFilePassProtect": "The file is password protected and could not be opened.", + "errorFileRequest": "External error.
File Request. Please, contact support.", + "errorFileSizeExceed": "The file size exceeds your server limitation.
Please, contact your admin for details.", + "errorFileVKey": "External error.
Incorrect security key. Please, contact support.", + "errorFillRange": "Could not fill the selected range of cells.
All the merged cells need to be the same size.", + "errorFormulaName": "An error in the formula.
Incorrect formula name.", + "errorFormulaParsing": "Internal error while the formula parsing.", + "errorFrmlMaxLength": "You cannot add this formula as its length exceeds the allowed number of characters.
Please, edit it and try again.", + "errorFrmlMaxReference": "You cannot enter this formula because it has too many values,
cell references, and/or names.", + "errorFrmlMaxTextLength": "Text values in formulas are limited to 255 characters.
Use the CONCATENATE function or concatenation operator (&)", + "errorFrmlWrongReferences": "The function refers to a sheet that does not exist.
Please, check the data and try again.", + "errorInvalidRef": "Enter a correct name for the selection or a valid reference to go to.", + "errorKeyEncrypt": "Unknown key descriptor", + "errorKeyExpire": "Key descriptor expired", + "errorLockedAll": "The operation could not be done as the sheet has been locked by another user.", + "errorLockedCellPivot": "You cannot change data inside a pivot table.", + "errorLockedWorksheetRename": "The sheet cannot be renamed at the moment as it is being renamed by another user", + "errorMaxPoints": "The maximum number of points in series per chart is 4096.", + "errorMoveRange": "Cannot change a part of a merged cell", + "errorMultiCellFormula": "Multi-cell array formulas are not allowed in tables.", + "errorOpenWarning": "The length of one of the formulas in the file exceeded
the allowed number of characters and it was removed.", + "errorOperandExpected": "The entered function syntax is not correct. Please, check if you missed one of the parentheses - '(' or ')'.", + "errorPasteMaxRange": "The copy and paste area does not match. Please, select an area of the same size or click the first cell in a row to paste the copied cells.", + "errorPrintMaxPagesCount": "Unfortunately, it’s not possible to print more than 1500 pages at once in the current version of the program.
This restriction will be eliminated in upcoming releases.", + "errorSessionAbsolute": "The document editing session has expired. Please, reload the page.", + "errorSessionIdle": "The document has not been edited for quite a long time. Please, reload the page.", + "errorSessionToken": "The connection to the server has been interrupted. Please, reload the page.", + "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.", + "errorUnexpectedGuid": "External error.
Unexpected Guid. Please, contact support.", + "errorUpdateVersionOnDisconnect": "Internet connection has been restored, and the file version has been changed.
Before you can continue working, you need to download the file or copy its content to make sure nothing is lost, and then reload this page.", + "errorUserDrop": "The file cannot be accessed right now.", + "errorUsersExceed": "The number of users allowed by the pricing plan was exceeded", + "errorViewerDisconnect": "Connection is lost. You can still view the document,
but you won't be able to download it until the connection is restored and the page is reloaded.", + "errorWrongBracketsCount": "An error in the formula.
Wrong number of brackets.", + "errorWrongOperator": "An error in the entered formula. The wrong operator is used.
Correct the error or use the Esc button to cancel the formula editing.", + "notcriticalErrorTitle": "Warning", + "openErrorText": "An error has occurred while opening the file", + "pastInMergeAreaError": "Cannot change a part of a merged cell", + "saveErrorText": "An error has occurred while saving the file", + "scriptLoadError": "The connection is too slow, some of the components could not be loaded. Please, reload the page.", + "unknownErrorText": "Unknown error.", + "uploadImageExtMessage": "Unknown image format.", + "uploadImageFileCountMessage": "No images uploaded.", + "uploadImageSizeMessage": "The image is too big. The maximum size is 25 MB." + }, + "LongActions": { + "applyChangesTextText": "Loading data...", + "applyChangesTitleText": "Loading Data", + "confirmMoveCellRange": "The destination cells range can contain data. Continue the operation?", + "confirmPutMergeRange": "The source data contains merged cells.
They will be unmerged before they are pasted into the table.", + "confirmReplaceFormulaInTable": "Formulas in the header row will be removed and converted to static text.
Do you want to continue?", + "downloadTextText": "Downloading document...", + "downloadTitleText": "Downloading Document", + "loadFontsTextText": "Loading data...", + "loadFontsTitleText": "Loading Data", + "loadFontTextText": "Loading data...", + "loadFontTitleText": "Loading Data", + "loadImagesTextText": "Loading images...", + "loadImagesTitleText": "Loading Images", + "loadImageTextText": "Loading image...", + "loadImageTitleText": "Loading Image", + "loadingDocumentTextText": "Loading document...", + "loadingDocumentTitleText": "Loading document", + "notcriticalErrorTitle": "Warning", + "openTextText": "Opening document...", + "openTitleText": "Opening Document", + "printTextText": "Printing document...", + "printTitleText": "Printing Document", + "savePreparingText": "Preparing to save", + "savePreparingTitle": "Preparing to save. Please wait...", + "saveTextText": "Saving document...", + "saveTitleText": "Saving Document", + "textLoadingDocument": "Loading document", + "textNo": "No", + "textOk": "Ok", + "textYes": "Yes", + "txtEditingMode": "Set editing mode...", + "uploadImageTextText": "Uploading image...", + "uploadImageTitleText": "Uploading Image", + "waitText": "Please, wait..." + }, + "Statusbar": { + "notcriticalErrorTitle": "Warning", + "textCancel": "Cancel", + "textDelete": "Delete", + "textDuplicate": "Duplicate", + "textErrNameExists": "Worksheet with this name already exists.", + "textErrNameWrongChar": "A sheet name cannot contains characters: \\, /, *, ?, [, ], :", + "textErrNotEmpty": "Sheet name must not be empty", + "textErrorLastSheet": "The workbook must have at least one visible worksheet.", + "textErrorRemoveSheet": "Can't delete the worksheet.", + "textHide": "Hide", + "textMore": "More", + "textRename": "Rename", + "textRenameSheet": "Rename Sheet", + "textSheet": "Sheet", + "textSheetName": "Sheet Name", + "textUnhide": "Unhide", + "textWarnDeleteSheet": "The worksheet maybe has data. Proceed operation?" + }, + "Toolbar": { + "dlgLeaveMsgText": "You have unsaved changes in this document. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.", + "dlgLeaveTitleText": "You leave the application", + "leaveButtonText": "Leave this Page", + "stayButtonText": "Stay on this Page" + }, + "View": { + "Add": { + "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.", + "notcriticalErrorTitle": "Warning", + "sCatDateAndTime": "Date and time", + "sCatEngineering": "Engineering", + "sCatFinancial": "Financial", + "sCatInformation": "Information", + "sCatLogical": "Logical", + "sCatLookupAndReference": "Lookup and Reference", + "sCatMathematic": "Math and trigonometry", + "sCatStatistical": "Statistical", + "sCatTextAndData": "Text and data", + "textAddLink": "Add Link", + "textAddress": "Address", + "textBack": "Back", + "textCancel": "Cancel", + "textChart": "Chart", + "textComment": "Comment", + "textDisplay": "Display", + "textEmptyImgUrl": "You need to specify the image URL.", + "textExternalLink": "External Link", + "textFilter": "Filter", + "textFunction": "Function", + "textGroups": "CATEGORIES", + "textImage": "Image", + "textImageURL": "Image URL", + "textInsert": "Insert", + "textInsertImage": "Insert Image", + "textInternalDataRange": "Internal Data Range", + "textInvalidRange": "ERROR! Invalid cells range", + "textLink": "Link", + "textLinkSettings": "Link Settings", + "textLinkType": "Link Type", + "textOther": "Other", + "textPictureFromLibrary": "Picture from library", + "textPictureFromURL": "Picture from URL", + "textRange": "Range", + "textRequired": "Required", + "textScreenTip": "Screen Tip", + "textShape": "Shape", + "textSheet": "Sheet", + "textSortAndFilter": "Sort and Filter", + "txtExpand": "Expand and sort", + "txtExpandSort": "The data next to the selection will not be sorted. Do you want to expand the selection to include the adjacent data or continue with sorting the currently selected cells only?", + "txtNotUrl": "This field should be a URL in the format \"http://www.example.com\"", + "txtSorting": "Sorting", + "txtSortSelected": "Sort selected", + "txtLockSort": "Data is found next to your selection, but you do not have sufficient permissions to change those cells.
Do you wish to continue with the current selection?", + "txtYes": "Yes", + "txtNo": "No" + }, + "Edit": { + "notcriticalErrorTitle": "Warning", + "textAccounting": "Accounting", + "textActualSize": "Actual Size", + "textAddCustomColor": "Add Custom Color", + "textAddress": "Address", + "textAlign": "Align", + "textAlignBottom": "Align Bottom", + "textAlignCenter": "Align Center", + "textAlignLeft": "Align Left", + "textAlignMiddle": "Align Middle", + "textAlignRight": "Align Right", + "textAlignTop": "Align Top", + "textAllBorders": "All Borders", + "textAngleClockwise": "Angle Clockwise", + "textAngleCounterclockwise": "Angle Counterclockwise", + "textAuto": "Auto", + "textAxisCrosses": "Axis Crosses", + "textAxisOptions": "Axis Options", + "textAxisPosition": "Axis Position", + "textAxisTitle": "Axis Title", + "textBack": "Back", + "textBetweenTickMarks": "Between Tick Marks", + "textBillions": "Billions", + "textBorder": "Border", + "textBorderStyle": "Border Style", + "textBottom": "Bottom", + "textBottomBorder": "Bottom Border", + "textBringToForeground": "Bring to Foreground", + "textCell": "Cell", + "textCellStyles": "Cell Styles", + "textCenter": "Center", + "textChart": "Chart", + "textChartTitle": "Chart Title", + "textClearFilter": "Clear Filter", + "textColor": "Color", + "textCross": "Cross", + "textCrossesValue": "Crosses Value", + "textCurrency": "Currency", + "textCustomColor": "Custom Color", + "textDataLabels": "Data Labels", + "textDate": "Date", + "textDefault": "Selected range", + "textDeleteFilter": "Delete Filter", + "textDesign": "Design", + "textDiagonalDownBorder": "Diagonal Down Border", + "textDiagonalUpBorder": "Diagonal Up Border", + "textDisplay": "Display", + "textDisplayUnits": "Display Units", + "textDollar": "Dollar", + "textEditLink": "Edit Link", + "textEffects": "Effects", + "textEmptyImgUrl": "You need to specify the image URL.", + "textEmptyItem": "{Blanks}", + "textErrorMsg": "You must choose at least one value", + "textErrorTitle": "Warning", + "textEuro": "Euro", + "textExternalLink": "External Link", + "textFill": "Fill", + "textFillColor": "Fill Color", + "textFilterOptions": "Filter Options", + "textFit": "Fit Width", + "textFonts": "Fonts", + "textFormat": "Format", + "textFraction": "Fraction", + "textFromLibrary": "Picture from Library", + "textFromURL": "Picture from URL", + "textGeneral": "General", + "textGridlines": "Gridlines", + "textHigh": "High", + "textHorizontal": "Horizontal", + "textHorizontalAxis": "Horizontal Axis", + "textHorizontalText": "Horizontal Text", + "textHundredMil": "100 000 000", + "textHundreds": "Hundreds", + "textHundredThousands": "100 000", + "textHyperlink": "Hyperlink", + "textImage": "Image", + "textImageURL": "Image URL", + "textIn": "In", + "textInnerBottom": "Inner Bottom", + "textInnerTop": "Inner Top", + "textInsideBorders": "Inside Borders", + "textInsideHorizontalBorder": "Inside Horizontal Border", + "textInsideVerticalBorder": "Inside Vertical Border", + "textInteger": "Integer", + "textInternalDataRange": "Internal Data Range", + "textInvalidRange": "Invalid cells range", + "textJustified": "Justified", + "textLabelOptions": "Label Options", + "textLabelPosition": "Label Position", + "textLayout": "Layout", + "textLeft": "Left", + "textLeftBorder": "Left Border", + "textLeftOverlay": "Left Overlay", + "textLegend": "Legend", + "textLink": "Link", + "textLinkSettings": "Link Settings", + "textLinkType": "Link Type", + "textLow": "Low", + "textMajor": "Major", + "textMajorAndMinor": "Major And Minor", + "textMajorType": "Major Type", + "textMaximumValue": "Maximum Value", + "textMedium": "Medium", + "textMillions": "Millions", + "textMinimumValue": "Minimum Value", + "textMinor": "Minor", + "textMinorType": "Minor Type", + "textMoveBackward": "Move Backward", + "textMoveForward": "Move Forward", + "textNextToAxis": "Next to Axis", + "textNoBorder": "No Border", + "textNone": "None", + "textNoOverlay": "No Overlay", + "textNotUrl": "This field should be a URL in the format \"http://www.example.com\"", + "textNumber": "Number", + "textOnTickMarks": "On Tick Marks", + "textOpacity": "Opacity", + "textOut": "Out", + "textOuterTop": "Outer Top", + "textOutsideBorders": "Outside Borders", + "textOverlay": "Overlay", + "textPercentage": "Percentage", + "textPictureFromLibrary": "Picture from Library", + "textPictureFromURL": "Picture from URL", + "textPound": "Pound", + "textPt": "pt", + "textRange": "Range", + "textRemoveChart": "Remove Chart", + "textRemoveImage": "Remove Image", + "textRemoveLink": "Remove Link", + "textRemoveShape": "Remove Shape", + "textReorder": "Reorder", + "textReplace": "Replace", + "textReplaceImage": "Replace Image", + "textRequired": "Required", + "textRight": "Right", + "textRightBorder": "Right Border", + "textRightOverlay": "Right Overlay", + "textRotated": "Rotated", + "textRotateTextDown": "Rotate Text Down", + "textRotateTextUp": "Rotate Text Up", + "textRouble": "Rouble", + "textScientific": "Scientific", + "textScreenTip": "Screen Tip", + "textSelectAll": "Select All", + "textSelectObjectToEdit": "Select object to edit", + "textSendToBackground": "Send to Background", + "textSettings": "Settings", + "textShape": "Shape", + "textSheet": "Sheet", + "textSize": "Size", + "textStyle": "Style", + "textTenMillions": "10 000 000", + "textTenThousands": "10 000", + "textText": "Text", + "textTextColor": "Text Color", + "textTextFormat": "Text Format", + "textTextOrientation": "Text Orientation", + "textThick": "Thick", + "textThin": "Thin", + "textThousands": "Thousands", + "textTickOptions": "Tick Options", + "textTime": "Time", + "textTop": "Top", + "textTopBorder": "Top Border", + "textTrillions": "Trillions", + "textType": "Type", + "textValue": "Value", + "textValuesInReverseOrder": "Values in Reverse Order", + "textVertical": "Vertical", + "textVerticalAxis": "Vertical Axis", + "textVerticalText": "Vertical Text", + "textWrapText": "Wrap Text", + "textYen": "Yen", + "txtNotUrl": "This field should be a URL in the format \"http://www.example.com\"", + "txtSortHigh2Low": "Sort Highest to Lowest", + "txtSortLow2High": "Sort Lowest to Highest" + }, + "Settings": { + "advCSVOptions": "Choose CSV options", + "advDRMEnterPassword": "Your password, please:", + "advDRMOptions": "Protected File", + "advDRMPassword": "Password", + "closeButtonText": "Close File", + "notcriticalErrorTitle": "Warning", + "textAbout": "About", + "textAddress": "Address", + "textApplication": "Application", + "textApplicationSettings": "Application Settings", + "textAuthor": "Author", + "textBack": "Back", + "textBottom": "Bottom", + "textByColumns": "By columns", + "textByRows": "By rows", + "textCancel": "Cancel", + "textCentimeter": "Centimeter", + "textCollaboration": "Collaboration", + "textColorSchemes": "Color Schemes", + "textComment": "Comment", + "textCommentingDisplay": "Commenting Display", + "textComments": "Comments", + "textCreated": "Created", + "textCustomSize": "Custom Size", + "textDisableAll": "Disable All", + "textDisableAllMacrosWithNotification": "Disable all macros with a notification", + "textDisableAllMacrosWithoutNotification": "Disable all macros without a notification", + "textDone": "Done", + "textDownload": "Download", + "textDownloadAs": "Download As", + "textEmail": "Email", + "textEnableAll": "Enable All", + "textEnableAllMacrosWithoutNotification": "Enable all macros without a notification", + "textFind": "Find", + "textFindAndReplace": "Find and Replace", + "textFindAndReplaceAll": "Find and Replace All", + "textFormat": "Format", + "textFormulaLanguage": "Formula Language", + "textFormulas": "Formulas", + "textHelp": "Help", + "textHideGridlines": "Hide Gridlines", + "textHideHeadings": "Hide Headings", + "textHighlightRes": "Highlight results", + "textInch": "Inch", + "textLandscape": "Landscape", + "textLastModified": "Last Modified", + "textLastModifiedBy": "Last Modified By", + "textLeft": "Left", + "textLocation": "Location", + "textLookIn": "Look In", + "textMacrosSettings": "Macros Settings", + "textMargins": "Margins", + "textMatchCase": "Match Case", + "textMatchCell": "Match Cell", + "textNoTextFound": "Text not found", + "textOpenFile": "Enter a password to open the file", + "textOrientation": "Orientation", + "textOwner": "Owner", + "textPoint": "Point", + "textPortrait": "Portrait", + "textPoweredBy": "Powered By", + "textPrint": "Print", + "textR1C1Style": "R1C1 Reference Style", + "textRegionalSettings": "Regional Settings", + "textReplace": "Replace", + "textReplaceAll": "Replace All", + "textResolvedComments": "Resolved Comments", + "textRight": "Right", + "textSearch": "Search", + "textSearchBy": "Search", + "textSearchIn": "Search In", + "textSettings": "Settings", + "textSheet": "Sheet", + "textShowNotification": "Show Notification", + "textSpreadsheetFormats": "Spreadsheet Formats", + "textSpreadsheetInfo": "Spreadsheet Info", + "textSpreadsheetSettings": "Spreadsheet Settings", + "textSpreadsheetTitle": "Spreadsheet Title", + "textSubject": "Subject", + "textTel": "Tel", + "textTitle": "Title", + "textTop": "Top", + "textUnitOfMeasurement": "Unit Of Measurement", + "textUploaded": "Uploaded", + "textValues": "Values", + "textVersion": "Version", + "textWorkbook": "Workbook", + "txtDelimiter": "Delimiter", + "txtEncoding": "Encoding", + "txtIncorrectPwd": "Password is incorrect", + "txtProtected": "Once you enter the password and open the file, the current password to the file will be reset", + "txtScheme1": "Office", + "txtScheme10": "Median", + "txtScheme11": "Metro", + "txtScheme12": "Module", + "txtScheme13": "Opulent", + "txtScheme14": "Oriel", + "txtScheme15": "Origin", + "txtScheme16": "Paper", + "txtScheme17": "Solstice", + "txtScheme18": "Technic", + "txtScheme19": "Trek", + "txtScheme2": "Grayscale", + "txtScheme20": "Urban", + "txtScheme21": "Verve", + "txtScheme22": "New Office", + "txtScheme3": "Apex", + "txtScheme4": "Aspect", + "txtScheme5": "Civic", + "txtScheme6": "Concourse", + "txtScheme7": "Equity", + "txtScheme8": "Flow", + "txtScheme9": "Foundry", + "txtSpace": "Space", + "txtTab": "Tab", + "warnDownloadAs": "If you continue saving in this format all features except the text will be lost.
Are you sure you want to continue?", + "textChooseCsvOptions": "Choose CSV Options", + "txtDownloadCsv": "Download CSV", + "textDelimeter": "Delimeter", + "textEncoding": "Encoding", + "textChooseEncoding": "Choose Encoding", + "textChooseDelimeter": "Choose Delimeter", + "txtComma": "Comma", + "txtSemicolon": "Semicolon", + "txtColon": "Colon", + "txtOk": "Ok" + } } - } } \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/controller/Error.jsx b/apps/spreadsheeteditor/mobile/src/controller/Error.jsx index 702300374f..1dad32e427 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/Error.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/Error.jsx @@ -302,6 +302,10 @@ const ErrorController = inject('storeAppOptions')(({storeAppOptions, LoadingDocu case Asc.c_oAscError.ID.UpdateVersion: config.msg = _t.errorUpdateVersionOnDisconnect; break; + + case Asc.c_oAscError.ID.ChangeOnProtectedSheet: + config.msg = _t.errorChangeOnProtectedSheet; + break; default: config.msg = _t.errorDefaultMessage.replace('%1', id); diff --git a/apps/spreadsheeteditor/mobile/src/controller/add/AddFilter.jsx b/apps/spreadsheeteditor/mobile/src/controller/add/AddFilter.jsx index 634b8d32df..5a94bdccc7 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/add/AddFilter.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/add/AddFilter.jsx @@ -48,7 +48,9 @@ class AddFilterController extends Component { f7.popover.close('#add-popover'); let typeCheck = type == 'down' ? Asc.c_oAscSortOptions.Ascending : Asc.c_oAscSortOptions.Descending; - if( api.asc_sortCellsRangeExpand()) { + let res = api.asc_sortCellsRangeExpand(); + switch (res) { + case Asc.c_oAscSelectionSortExpand.showExpandMessage: f7.dialog.create({ title: _t.txtSorting, text: _t.txtExpandSort, @@ -63,18 +65,41 @@ class AddFilterController extends Component { { text: _t.txtSortSelected, bold: true, - onClick: () => { - api.asc_sortColFilter(typeCheck, '', undefined, undefined); + onClick: () => { + api.asc_sortColFilter(typeCheck, '', undefined, undefined); } }, { text: _t.textCancel } ], - verticalButtons: true, + verticalButtons: true }).open(); - } else - api.asc_sortColFilter(typeCheck, '', undefined, undefined, api.asc_sortCellsRangeExpand() !== null); + break; + case Asc.c_oAscSelectionSortExpand.showLockMessage: + f7.dialog.create({ + title: _t.txtSorting, + text: _t.txtLockSort, + buttons: [ + { + text: _t.txtYes, + bold: true, + onClick: () => { + api.asc_sortColFilter(typeCheck, '', undefined, undefined, false); + } + }, + { + text: _t.txtNo + } + ], + verticalButtons: true + }).open(); + break; + case Asc.c_oAscSelectionSortExpand.expandAndNotShowMessage: + case Asc.c_oAscSelectionSortExpand.notExpandAndNotShowMessage: + api.asc_sortColFilter(typeCheck, '', undefined, undefined, res === Asc.c_oAscSelectionSortExpand.expandAndNotShowMessage); + break; + } } onInsertFilter (checked) {