diff --git a/apps/common/main/lib/component/CheckBox.js b/apps/common/main/lib/component/CheckBox.js index 0bba394025..428224d03d 100644 --- a/apps/common/main/lib/component/CheckBox.js +++ b/apps/common/main/lib/component/CheckBox.js @@ -99,10 +99,32 @@ define([ initialize : function(options) { Common.UI.BaseView.prototype.initialize.call(this, options); + if (this.options.el) + this.render(); + }, + + render: function (parentEl) { var me = this, el = $(this.el); + if (!me.rendered) { + if (parentEl) { + this.setElement(parentEl, false); + parentEl.html(this.template({ + labelText: this.options.labelText + })); + el = $(this.el); + } else { + el.html(this.template({ + labelText: this.options.labelText + })); + } - this.render(); + this.$chk = el.find('input[type=button]'); + this.$label = el.find('label'); + this.$chk.on('click', _.bind(this.onItemCheck, this)); + } + + this.rendered = true; if (this.options.disabled) this.setDisabled(this.options.disabled); @@ -111,20 +133,6 @@ define([ this.setValue(this.options.value, true); // handle events - this.$chk.on('click', _.bind(this.onItemCheck, this)); - }, - - render: function () { - var el = $(this.el); - el.html(this.template({ - labelText: this.options.labelText - })); - - this.$chk = el.find('input[type=button]'); - this.$label = el.find('label'); - - this.rendered = true; - return this; }, diff --git a/apps/common/main/lib/component/ListView.js b/apps/common/main/lib/component/ListView.js index b080a51006..39bb03d0b0 100644 --- a/apps/common/main/lib/component/ListView.js +++ b/apps/common/main/lib/component/ListView.js @@ -64,6 +64,7 @@ define([ onResetItems : function() { this.innerEl = null; Common.UI.DataView.prototype.onResetItems.call(this); + this.trigger('items:reset', this); }, onAddItem: function(record, index) { @@ -97,6 +98,16 @@ define([ this.listenTo(view, 'dblclick',this.onDblClickItem); this.listenTo(view, 'select', this.onSelectItem); + if (record.get('tip')) { + var view_el = $(view.el); + view_el.attr('data-toggle', 'tooltip'); + view_el.tooltip({ + title : record.get('tip'), + placement : 'cursor', + zIndex : this.tipZIndex + }); + } + if (!this.isSuspendEvents) this.trigger('item:add', this, view, record); } diff --git a/apps/common/main/lib/util/utils.js b/apps/common/main/lib/util/utils.js index 86a7c10d3f..08cab9ccdb 100644 --- a/apps/common/main/lib/util/utils.js +++ b/apps/common/main/lib/util/utils.js @@ -102,7 +102,8 @@ Common.Utils = _.extend(new(function() { Slide : 6, Chart : 7, MailMerge : 8, - Signature : 9 + Signature : 9, + Pivot : 10 }, isMobile = /android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent || navigator.vendor || window.opera), me = this, diff --git a/apps/common/main/resources/less/combo-dataview.less b/apps/common/main/resources/less/combo-dataview.less index d098973e72..4a390c4c33 100644 --- a/apps/common/main/resources/less/combo-dataview.less +++ b/apps/common/main/resources/less/combo-dataview.less @@ -275,4 +275,15 @@ } } } +} + +.combo-pivot-template { + .combo-template(60px); + + margin-top: -6px; + margin-bottom: -6px; + + .view .dataview { + padding: 1px; + } } \ No newline at end of file diff --git a/apps/common/main/resources/less/toolbar.less b/apps/common/main/resources/less/toolbar.less index 5b02b5efff..df297f9b4f 100644 --- a/apps/common/main/resources/less/toolbar.less +++ b/apps/common/main/resources/less/toolbar.less @@ -224,6 +224,10 @@ width: 22px; height: 22px; } + + .checkbox-indeterminate { + margin-top: 3px; + } } } diff --git a/apps/spreadsheeteditor/main/app.js b/apps/spreadsheeteditor/main/app.js index d38cfe1aca..ce515d97ff 100644 --- a/apps/spreadsheeteditor/main/app.js +++ b/apps/spreadsheeteditor/main/app.js @@ -155,6 +155,7 @@ require([ 'RightMenu', 'LeftMenu', 'Main', + 'PivotTable', 'Common.Controllers.Fonts', 'Common.Controllers.Chat', 'Common.Controllers.Comments', @@ -174,12 +175,16 @@ require([ 'spreadsheeteditor/main/app/controller/LeftMenu', 'spreadsheeteditor/main/app/controller/Main', 'spreadsheeteditor/main/app/controller/Print', + 'spreadsheeteditor/main/app/controller/PivotTable', 'spreadsheeteditor/main/app/view/FileMenuPanels', 'spreadsheeteditor/main/app/view/ParagraphSettings', 'spreadsheeteditor/main/app/view/ImageSettings', 'spreadsheeteditor/main/app/view/ChartSettings', 'spreadsheeteditor/main/app/view/ShapeSettings', 'spreadsheeteditor/main/app/view/TextArtSettings', + 'spreadsheeteditor/main/app/view/PivotSettings', + 'spreadsheeteditor/main/app/view/FieldSettingsDialog', + 'spreadsheeteditor/main/app/view/ValueFieldSettingsDialog', 'common/main/lib/util/utils', 'common/main/lib/util/LocalStorage', 'common/main/lib/controller/Fonts', diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js index f3fc70bf34..69b9d7eed9 100644 --- a/apps/spreadsheeteditor/main/app/controller/Main.js +++ b/apps/spreadsheeteditor/main/app/controller/Main.js @@ -946,6 +946,9 @@ define([ statusbarController.getView('Statusbar').changeViewMode(true); } + if (!me.appOptions.isEditMailMerge && !me.appOptions.isEditDiagram) + application.getController('PivotTable').setMode(me.appOptions).setConfig({config: me.editorConfig}, me.api); + var viewport = this.getApplication().getController('Viewport').getView('Viewport'); viewport.applyEditorMode(); rightmenuController.getView('RightMenu').setMode(me.appOptions).setApi(me.api); diff --git a/apps/spreadsheeteditor/main/app/controller/PivotTable.js b/apps/spreadsheeteditor/main/app/controller/PivotTable.js new file mode 100644 index 0000000000..ee2b75727c --- /dev/null +++ b/apps/spreadsheeteditor/main/app/controller/PivotTable.js @@ -0,0 +1,348 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * PivotTable.js + * + * Created by Julia.Radzhabova on 06.27.17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'core', + 'spreadsheeteditor/main/app/view/PivotTable' +], function () { + 'use strict'; + + SSE.Controllers.PivotTable = Backbone.Controller.extend(_.extend({ + models : [], + views : [ + 'PivotTable' + ], + sdkViewName : '#id_main', + + initialize: function () { + + this.addListeners({ + 'PivotTable': { + // comments handlers + 'pivottable:rowscolumns': _.bind(this.onCheckTemplateChange, this), + 'pivottable:create': _.bind(this.onCreateClick, this), + 'pivottable:refresh': _.bind(this.onRefreshClick, this), + 'pivottable:style': _.bind(this.onPivotStyleSelect, this), + 'pivottable:layout': _.bind(this.onPivotLayout, this), + 'pivottable:blankrows': _.bind(this.onPivotBlankRows, this), + 'pivottable:subtotals': _.bind(this.onPivotSubtotals, this), + 'pivottable:grandtotals': _.bind(this.onPivotGrandTotals, this) + } + }); + }, + onLaunch: function () { + this._state = { + TableName: '', + TemplateName: '', + RowHeader: undefined, + RowBanded: undefined, + ColHeader: undefined, + ColBanded: undefined, + DisabledControls: false + }; + this._originalProps = null; + + this.view = this.createView('PivotTable'); + + Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); + Common.NotificationCenter.on('api:disconnect', _.bind(this.SetDisabled, this)); + }, + + setConfig: function (data, api) { + this.setApi(api); + + if (data) { + this.sdkViewName = data['sdkviewname'] || this.sdkViewName; + } + }, + + setApi: function (api) { + if (api) { + this.api = api; + this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.SetDisabled, this)); + this.api.asc_registerCallback('asc_onSendThemeColors', _.bind(this.onSendThemeColors, this)); + this.api.asc_registerCallback('asc_onSelectionChanged', _.bind(this.onSelectionChanged, this)); + } + }, + + setMode: function(mode) { + this.appConfig = mode; + return this; + }, + + SetDisabled: function() { + this.view && this.view.SetDisabled(true); + }, + + // helpers + + onCheckTemplateChange: function(type, value) { + // this._state[stateName] = undefined; + // if (this.api) + // this.api.asc_changeFormatTableInfo(this._state.TableName, type, value=='checked'); + // for test + switch (type) { + case 0: + this._originalProps.asc_getStyleInfo().asc_setShowRowHeaders(this.api, this._originalProps, value=='checked'); + break; + case 1: + this._originalProps.asc_getStyleInfo().asc_setShowColHeaders(this.api, this._originalProps, value=='checked'); + break; + case 2: + this._originalProps.asc_getStyleInfo().asc_setShowRowStripes(this.api, this._originalProps, value=='checked'); + break; + case 3: + this._originalProps.asc_getStyleInfo().asc_setShowColStripes(this.api, this._originalProps, value=='checked'); + break; + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onCreateClick: function(btn, opts){ + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onRefreshClick: function(btn, opts){ + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onPivotStyleSelect: function(record){ + if (this.api) { + this._originalProps.asc_getStyleInfo().asc_setName(this.api, this._originalProps, record.get('name')); + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onPivotBlankRows: function(type){ + if (this.api) { + if (type === 'insert'){ + + } else { + + } + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onPivotLayout: function(type){ + if (this.api) { + switch (type){ + case 0: + break; + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + } + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onPivotGrandTotals: function(type){ + if (this.api) { + var props = new Asc.CT_pivotTableDefinition(); + props.asc_setColGrandTotals(type == 1 || type == 2); + props.asc_setRowGrandTotals(type == 1 || type == 3); + this._originalProps.asc_set(this.api, props); + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + onPivotSubtotals: function(type){ + if (this.api) { + switch (type){ + case 0: + break; + case 1: + break; + case 2: + break; + } + } + Common.NotificationCenter.trigger('edit:complete', this); + }, + + ChangeSettings: function(props) { + if (props ) + { + this._originalProps = props; + + var view = this.view, + needTablePictures = false, + styleInfo = props.asc_getStyleInfo(), + value = styleInfo.asc_getShowRowHeaders(); + if (this._state.RowHeader!==value) { + view.chRowHeader.setValue(value, true); + this._state.RowHeader=value; + needTablePictures = true; + } + + value = styleInfo.asc_getShowColHeaders(); + if (this._state.ColHeader!==value) { + view.chColHeader.setValue(value, true); + this._state.ColHeader=value; + needTablePictures = true; + } + + value = styleInfo.asc_getShowColStripes(); + if (this._state.ColBanded!==value) { + view.chColBanded.setValue(value, true); + this._state.ColBanded=value; + needTablePictures = true; + } + + value = styleInfo.asc_getShowRowStripes(); + if (this._state.RowBanded!==value) { + view.chRowBanded.setValue(value, true); + this._state.RowBanded=value; + needTablePictures = true; + } + + value = props.asc_getColGrandTotals(); + if (this._state.ColGrandTotals!==value) { + this._state.ColGrandTotals=value; + needTablePictures = true; + } + + value = props.asc_getRowGrandTotals(); + if (this._state.RowGrandTotals!==value) { + this._state.RowGrandTotals=value; + needTablePictures = true; + } + + if (needTablePictures) + this.onApiInitPivotStyles(this.api.asc_getTablePictures(this._originalProps, true)); + + //for table-template + value = styleInfo.asc_getName(); + if (this._state.TemplateName!==value || this._isTemplatesChanged) { + view.pivotStyles.suspendEvents(); + var rec = view.pivotStyles.menuPicker.store.findWhere({ + name: value + }); + view.pivotStyles.menuPicker.selectRecord(rec); + view.pivotStyles.resumeEvents(); + + if (this._isTemplatesChanged) { + if (rec) + view.pivotStyles.fillComboView(view.pivotStyles.menuPicker.getSelectedRec()[0],true); + else + view.pivotStyles.fillComboView(view.pivotStyles.menuPicker.store.at(0), true); + } + this._state.TemplateName=value; + } + this._isTemplatesChanged = false; + } + }, + + onSendThemeColors: function() { + // get new table templates + if (this.view.pivotStyles && this._originalProps) { + this.onApiInitPivotStyles(this.api.asc_getTablePictures(this._originalProps, true)); + this.view.pivotStyles.menuPicker.scroller.update({alwaysVisibleY: true}); + } + }, + + onApiInitPivotStyles: function(Templates){ + var self = this, + styles = this.view.pivotStyles; + this._isTemplatesChanged = true; + + var count = styles.menuPicker.store.length; + if (count>0 && count==Templates.length) { + var data = styles.menuPicker.store.models; + _.each(Templates, function(template, index){ + data[index].set('imageUrl', template.asc_getImage()); + }); + } else { + styles.menuPicker.store.reset([]); + var arr = []; + _.each(Templates, function(template){ + arr.push({ + id : Common.UI.getId(), + name : template.asc_getName(), + caption : template.asc_getDisplayName(), + type : template.asc_getType(), + imageUrl : template.asc_getImage(), + allowSelected : true, + selected : false, + tip : template.asc_getDisplayName() + }); + }); + styles.menuPicker.store.add(arr); + } + }, + + onSelectionChanged: function(info) { + if (this.rangeSelectionMode || !this.appConfig.isEdit) return; + + var selectType = info.asc_getFlags().asc_getSelectionType(), + pivotInfo = info.asc_getPivotTableInfo(); + + var need_disable = info.asc_getLocked(); + + this.view.SetDisabled(!pivotInfo); + if (pivotInfo) + this.ChangeSettings(pivotInfo); + }, + + createToolbarPanel: function() { + return this.view.getPanel(); + }, + + getView: function(name) { + return !name && this.view ? + this.view : Backbone.Controller.prototype.getView.call(this, name); + }, + + onAppReady: function (config) { + var me = this; + (new Promise(function (resolve) { + resolve(); + })).then(function () { + }); + } + + }, SSE.Controllers.PivotTable || {})); +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/controller/RightMenu.js b/apps/spreadsheeteditor/main/app/controller/RightMenu.js index 9a5c5acf2c..4221359db1 100644 --- a/apps/spreadsheeteditor/main/app/controller/RightMenu.js +++ b/apps/spreadsheeteditor/main/app/controller/RightMenu.js @@ -85,6 +85,7 @@ define([ this._settings[Common.Utils.documentSettingsType.TextArt] = {panelId: "id-textart-settings", panel: rightMenu.textartSettings, btn: rightMenu.btnTextArt, hidden: 1, locked: false}; this._settings[Common.Utils.documentSettingsType.Chart] = {panelId: "id-chart-settings", panel: rightMenu.chartSettings, btn: rightMenu.btnChart, hidden: 1, locked: false}; this._settings[Common.Utils.documentSettingsType.Table] = {panelId: "id-table-settings", panel: rightMenu.tableSettings, btn: rightMenu.btnTable, hidden: 1, locked: false}; + this._settings[Common.Utils.documentSettingsType.Pivot] = {panelId: "id-pivot-settings", panel: rightMenu.pivotSettings, btn: rightMenu.btnPivot, hidden: 1, locked: false}; this._settings[Common.Utils.documentSettingsType.Signature] = {panelId: "id-signature-settings", panel: rightMenu.signatureSettings, btn: rightMenu.btnSignature, hidden: (rightMenu.signatureSettings) ? 0 : 1, props: {}, locked: false}; }, @@ -115,14 +116,15 @@ define([ var SelectedObjects = [], selectType = info.asc_getFlags().asc_getSelectionType(), formatTableInfo = info.asc_getFormatTableInfo(), - sparkLineInfo = info.asc_getSparklineInfo(); + sparkLineInfo = info.asc_getSparklineInfo(), + pivotInfo = info.asc_getPivotTableInfo(); if (selectType == Asc.c_oAscSelectionType.RangeImage || selectType == Asc.c_oAscSelectionType.RangeShape || selectType == Asc.c_oAscSelectionType.RangeChart || selectType == Asc.c_oAscSelectionType.RangeChartText || selectType == Asc.c_oAscSelectionType.RangeShapeText) { SelectedObjects = this.api.asc_getGraphicObjectProps(); } - if (SelectedObjects.length<=0 && !formatTableInfo && !sparkLineInfo && !this.rightmenu.minimizedMode) { + if (SelectedObjects.length<=0 && !formatTableInfo && !sparkLineInfo && !pivotInfo && !this.rightmenu.minimizedMode) { this.rightmenu.clearSelection(); this._openRightMenu = true; } @@ -131,10 +133,10 @@ define([ need_disable_table = (info.asc_getLockedTable()===true), need_disable_spark = (info.asc_getLockedSparkline()===true); - this.onFocusObject(SelectedObjects, formatTableInfo, sparkLineInfo, need_disable, need_disable_table, need_disable_spark); + this.onFocusObject(SelectedObjects, formatTableInfo, sparkLineInfo, pivotInfo, need_disable, need_disable_table, need_disable_spark); }, - onFocusObject: function(SelectedObjects, formatTableInfo, sparkLineInfo, isCellLocked, isTableLocked, isSparkLocked) { + onFocusObject: function(SelectedObjects, formatTableInfo, sparkLineInfo, pivotInfo, isCellLocked, isTableLocked, isSparkLocked) { if (!this.editMode) return; @@ -192,6 +194,13 @@ define([ this._settings[settingsType].btn.updateHint(this.rightmenu.txtSparklineSettings); } + if (pivotInfo && false) { // disable pivot settings + settingsType = Common.Utils.documentSettingsType.Pivot; + this._settings[settingsType].props = pivotInfo; + this._settings[settingsType].locked = isCellLocked; + this._settings[settingsType].hidden = 0; + } + var lastactive = -1, currentactive, priorityactive = -1, activePane = this.rightmenu.GetActivePane(); for (i=0; iAre you sure you want to continue?', txtInvalidRange: 'ERROR! Invalid cells range', errorMaxRows: 'ERROR! The maximum number of data series per chart is 255.', - errorStockChart: 'Incorrect row order. To build a stock chart place the data on the sheet in the following order:
opening price, max price, min price, closing price.' + errorStockChart: 'Incorrect row order. To build a stock chart place the data on the sheet in the following order:
opening price, max price, min price, closing price.', + textPivot: 'Pivot Table' }, SSE.Controllers.Toolbar || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/template/FieldSettingsDialog.template b/apps/spreadsheeteditor/main/app/template/FieldSettingsDialog.template new file mode 100644 index 0000000000..d9c5bcb3fc --- /dev/null +++ b/apps/spreadsheeteditor/main/app/template/FieldSettingsDialog.template @@ -0,0 +1,134 @@ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/spreadsheeteditor/main/app/template/PivotSettings.template b/apps/spreadsheeteditor/main/app/template/PivotSettings.template new file mode 100644 index 0000000000..975e846759 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/template/PivotSettings.template @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+ + + +
+
+
+
+
+ + + +
+
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/template/PivotSettingsAdvanced.template b/apps/spreadsheeteditor/main/app/template/PivotSettingsAdvanced.template new file mode 100644 index 0000000000..ffc7f6aa1a --- /dev/null +++ b/apps/spreadsheeteditor/main/app/template/PivotSettingsAdvanced.template @@ -0,0 +1,100 @@ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+ + + + + + + + +
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + +
+ +
+
+ + +
+ +
+
+
\ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/template/RightMenu.template b/apps/spreadsheeteditor/main/app/template/RightMenu.template index 24c8de9ca0..475b9af915 100644 --- a/apps/spreadsheeteditor/main/app/template/RightMenu.template +++ b/apps/spreadsheeteditor/main/app/template/RightMenu.template @@ -12,6 +12,8 @@
+
+
@@ -23,6 +25,7 @@ + \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/FieldSettingsDialog.js b/apps/spreadsheeteditor/main/app/view/FieldSettingsDialog.js new file mode 100644 index 0000000000..95783eedb3 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/FieldSettingsDialog.js @@ -0,0 +1,331 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * FieldSettingsDialog.js + * + * Created by Julia Radzhabova on 17.07.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ 'text!spreadsheeteditor/main/app/template/FieldSettingsDialog.template', + 'common/main/lib/util/utils', + 'common/main/lib/component/InputField', + 'common/main/lib/component/ComboBox', + 'common/main/lib/component/CheckBox', + 'common/main/lib/view/AdvancedSettingsWindow' +], function (contentTemplate) { 'use strict'; + + SSE.Views.FieldSettingsDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({ + options: { + contentWidth: 284, + height: 440, + toggleGroup: 'pivot-field-settings-group', + storageName: 'sse-pivot-field-settings-category' + }, + + initialize : function(options) { + var me = this; + + _.extend(this.options, { + title: this.textTitle, + items: [ + {panelId: 'id-pivot-field-settings-layout', panelCaption: this.strLayout}, + {panelId: 'id-pivot-field-settings-subtotals', panelCaption: this.strSubtotals} + ], + contentTemplate: _.template(contentTemplate)({ + scope: this + }) + }, options); + + this.api = options.api; + this.handler = options.handler; + this.props = options.props; + this.fieldIndex = options.fieldIndex || 0; + this.names = options.names || []; + this.type = options.type || 0; // 0 - columns, 1 - rows, 3 - filters + + Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.Views.AdvancedSettingsWindow.prototype.render.call(this); + var me = this; + + this.inputCustomName = new Common.UI.InputField({ + el : $('#field-settings-custom'), + allowBlank : true, + validateOnBlur: false, + style : 'width: 100%;' + }); + + this.lblSourceName = this.$window.find('#field-settings-source'); + + this.radioTabular = new Common.UI.RadioBox({ + el: $('#field-settings-radio-tab'), + labelText: this.txtTabular, + name: 'asc-radio-report-form' + }); + + this.radioOutline = new Common.UI.RadioBox({ + el: $('#field-settings-radio-outline'), + labelText: this.txtOutline, + name: 'asc-radio-report-form', + checked: true + }); + + this.chCompact = new Common.UI.CheckBox({ + el: $('#field-settings-chk-compact'), + labelText: this.txtCompact + }); + + this.chRepeat = new Common.UI.CheckBox({ + el: $('#field-settings-chk-repeat'), + labelText: this.txtRepeat + }); + + this.chBlank = new Common.UI.CheckBox({ + el: $('#field-settings-chk-blank'), + labelText: this.txtBlank + }); + + this.chSubtotals = new Common.UI.CheckBox({ + el: $('#field-settings-chk-subtotals'), + labelText: this.txtShowSubtotals + }); + + this.radioTop = new Common.UI.RadioBox({ + el: $('#field-settings-radio-top'), + labelText: this.txtTop, + name: 'asc-radio-show-subtotals' + }); + + this.radioBottom = new Common.UI.RadioBox({ + el: $('#field-settings-radio-bottom'), + labelText: this.txtBottom, + name: 'asc-radio-show-subtotals', + checked: true + }); + + this.chEmpty = new Common.UI.CheckBox({ + el: $('#field-settings-chk-empty'), + labelText: this.txtEmpty + }); + + this.chSum = new Common.UI.CheckBox({ + el: $('#field-settings-chk-sum'), + labelText: this.txtSum + }); + // this.chSum.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Sum)); + + this.chCount = new Common.UI.CheckBox({ + el: $('#field-settings-chk-count'), + labelText: this.txtCount + }); + // this.chCount.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Count)); + + this.chAve = new Common.UI.CheckBox({ + el: $('#field-settings-chk-ave'), + labelText: this.txtAverage + }); + // this.chAve.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Average)); + + this.chMax = new Common.UI.CheckBox({ + el: $('#field-settings-chk-max'), + labelText: this.txtMax + }); + // this.chMax.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Max)); + + this.chMin = new Common.UI.CheckBox({ + el: $('#field-settings-chk-min'), + labelText: this.txtMin + }); + // this.chMin.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Min)); + + this.chProduct = new Common.UI.CheckBox({ + el: $('#field-settings-chk-product'), + labelText: this.txtProduct + }); + // this.chProduct.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Product)); + + this.chNum = new Common.UI.CheckBox({ + el: $('#field-settings-chk-num'), + labelText: this.txtCountNums + }); + // this.chNum.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.CountNums)); + + this.chDev = new Common.UI.CheckBox({ + el: $('#field-settings-chk-dev'), + labelText: this.txtStdDev + }); + // this.chDev.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.StdDev)); + + this.chDevp = new Common.UI.CheckBox({ + el: $('#field-settings-chk-devp'), + labelText: this.txtStdDevp + }); + // this.chDevp.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.StdDevp)); + + this.chVar = new Common.UI.CheckBox({ + el: $('#field-settings-chk-var'), + labelText: this.txtVar + }); + // this.chVar.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Var)); + + this.chVarp = new Common.UI.CheckBox({ + el: $('#field-settings-chk-varp'), + labelText: this.txtVarp + }); + // this.chVarp.on('change', _.bind(this.onFunctionChange, this, Asc.c_oAscDataConsolidateFunction.Varp)); + + this.afterRender(); + }, + + afterRender: function() { + this._setDefaults(this.props); + if (this.storageName) { + var value = Common.localStorage.getItem(this.storageName); + this.setActiveCategory((value!==null) ? parseInt(value) : 0); + } + }, + + show: function() { + Common.Views.AdvancedSettingsWindow.prototype.show.apply(this, arguments); + }, + + _setDefaults: function (props) { + if (props) { + var me = this, + cache_names = props.asc_getCacheFields(), + field = props.asc_getPivotFields()[this.fieldIndex]; + + this.lblSourceName.html(Common.Utils.String.htmlEncode(cache_names[this.fieldIndex].asc_getName())); + this.inputCustomName.setValue(Common.Utils.String.htmlEncode((field || cache_names[this.fieldIndex]).asc_getName())); + + (field.asc_getSubtotalTop()) ? this.radioTop.setValue(true) : this.radioBottom.setValue(true); + + var arr = field.asc_getSubtotals(); + if (arr) { + _.each(arr, function(item) { + switch(item) { + case Asc.c_oAscItemType.Sum: + me.chSum.setValue(true); + break; + case Asc.c_oAscItemType.Count: + me.chCount.setValue(true); + break; + case Asc.c_oAscItemType.Avg: + me.chAve.setValue(true); + break; + case Asc.c_oAscItemType.Max: + me.chMax.setValue(true); + break; + case Asc.c_oAscItemType.Min: + me.chMin.setValue(true); + break; + case Asc.c_oAscItemType.Product: + me.chProduct.setValue(true); + break; + case Asc.c_oAscItemType.CountA: + me.chNum.setValue(true); + break; + case Asc.c_oAscItemType.StdDev: + me.chDev.setValue(true); + break; + case Asc.c_oAscItemType.StdDevP: + me.chDevp.setValue(true); + break; + case Asc.c_oAscItemType.Var: + me.chVar.setValue(true); + break; + case Asc.c_oAscItemType.VarP: + me.chVarp.setValue(true); + break; + } + }); + } + } + }, + + getSettings: function () { + return {}; + }, + + onDlgBtnClick: function(event) { + var me = this; + var state = (typeof(event) == 'object') ? event.currentTarget.attributes['result'].value : event; + if (state == 'ok') { + this.handler && this.handler.call(this, state, (state == 'ok') ? this.getSettings() : undefined); + } + + this.close(); + }, + + onPrimary: function() { + this.onDlgBtnClick('ok'); + return false; + }, + + textTitle: 'Field Settings', + textCancel: 'Cancel', + textOk: 'OK', + strSubtotals: 'Subtotals', + strLayout: 'Layout', + txtSourceName: 'Source name: ', + txtCustomName: 'Custom name', + textReport: 'Report Form', + txtTabular: 'Tabular', + txtOutline: 'Outline', + txtCompact: 'Compact', + txtRepeat: 'Repeat items labels at each row', + txtBlank: 'Insert blank rows after each item', + txtShowSubtotals: 'Show subtotals', + txtTop: 'Show at top of group', + txtBottom: 'Show at bottom of group', + txtEmpty: 'Show items with no data', + txtSummarize: 'Functions for Subtotals', + txtAverage: 'Average', + txtCount: 'Count', + txtCountNums: 'Count Numbers', + txtMax: 'Max', + txtMin: 'Min', + txtProduct: 'Product', + txtStdDev: 'StdDev', + txtStdDevp: 'StdDevp', + txtSum: 'Sum', + txtVar: 'Var', + txtVarp: 'Varp' + + }, SSE.Views.FieldSettingsDialog || {})) +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/PivotSettings.js b/apps/spreadsheeteditor/main/app/view/PivotSettings.js new file mode 100644 index 0000000000..afb1cca3d5 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/PivotSettings.js @@ -0,0 +1,673 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * PivotSettings.js + * + * Created by Julia Radzhabova on 7/10/17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'text!spreadsheeteditor/main/app/template/PivotSettings.template', + 'jquery', + 'underscore', + 'backbone', + 'common/main/lib/component/Button', + 'common/main/lib/component/ListView', + 'spreadsheeteditor/main/app/view/FieldSettingsDialog', + 'spreadsheeteditor/main/app/view/ValueFieldSettingsDialog', + 'spreadsheeteditor/main/app/view/PivotSettingsAdvanced' +], function (menuTemplate, $, _, Backbone, Sortable) { + 'use strict'; + + SSE.Views.PivotSettings = Backbone.View.extend(_.extend({ + el: '#id-pivot-settings', + + // Compile our stats template + template: _.template(menuTemplate), + + // Delegated events for creating new items, and clearing completed ones. + events: { + }, + + options: { + alias: 'PivotSettings' + }, + + initialize: function () { + this._initSettings = true; + + this._state = { + names: [], + DisabledControls: false, + field: {} + }; + this.lockedControls = []; + this._locked = false; + + this._originalProps = null; + this._noApply = false; + + this.render(); + }, + + render: function () { + var el = $(this.el); + el.html(this.template({ + scope: this + })); + + this.linkAdvanced = $('#pivot-advanced-link'); + }, + + setApi: function(o) { + this.api = o; + return this; + }, + + createDelayedControls: function() { + var me = this; + this.fieldsList = new Common.UI.ListView({ + el: $('#pivot-list-fields'), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + template: _.template(['
'].join('')), + itemTemplate: _.template([ + '
', + '', + '
<%= Common.Utils.String.htmlEncode(value) %>
', + '
', + '
' + ].join('')) + }); + this.fieldsList.on('item:click', _.bind(this.onFieldsCheck, this)); + // this.fieldsList.onKeyDown = _.bind(this.onFieldsListKeyDown, this); + this.lockedControls.push(this.fieldsList); + + // Sortable.create(this.fieldsList.$el.find('.listview')[0], {}); + + var itemTemplate = _.template([ + '
', + '
<%= Common.Utils.String.htmlEncode(value) %>
', + '
', + '
' + ].join('')); + this.columnsList = new Common.UI.ListView({ + el: $('#pivot-list-columns'), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + template: _.template(['
'].join('')), + itemTemplate: itemTemplate + }); + this.columnsList.on('item:click', _.bind(this.onColumnsSelect, this, 0)); + // this.columnsList.onKeyDown = _.bind(this.onColumnsListKeyDown, this); + this.lockedControls.push(this.columnsList); + + this.rowsList = new Common.UI.ListView({ + el: $('#pivot-list-rows'), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + template: _.template(['
'].join('')), + itemTemplate: itemTemplate + }); + this.rowsList.on('item:click', _.bind(this.onColumnsSelect, this, 1)); + // this.rowsList.onKeyDown = _.bind(this.onRowsListKeyDown, this); + this.lockedControls.push(this.rowsList); + + this.valuesList = new Common.UI.ListView({ + el: $('#pivot-list-values'), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + template: _.template(['
'].join('')), + itemTemplate: itemTemplate + }); + this.valuesList.on('item:click', _.bind(this.onColumnsSelect, this, 2)); + // this.valuesList.onKeyDown = _.bind(this.onValuesListKeyDown, this); + this.lockedControls.push(this.valuesList); + + this.filtersList = new Common.UI.ListView({ + el: $('#pivot-list-filters'), + store: new Common.UI.DataViewStore(), + simpleAddMode: true, + template: _.template(['
'].join('')), + itemTemplate: itemTemplate + }); + this.filtersList.on('item:click', _.bind(this.onColumnsSelect, this,3)); + // this.filtersList.onKeyDown = _.bind(this.onFiltersListKeyDown, this); + this.lockedControls.push(this.filtersList); + + $(this.el).on('click', '#pivot-advanced-link', _.bind(this.openAdvancedSettings, this)); + + this._initSettings = false; + }, + + openAdvancedSettings: function(e) { + if (this.linkAdvanced.hasClass('disabled')) return; + + var me = this; + var win; + if (me.api && !this._locked){ + (new SSE.Views.PivotSettingsAdvanced( + { + props: me._originalProps, + api: me.api, + handler: function(result, value) { + if (result == 'ok' && me.api && value) { + me._originalProps.asc_set(me.api, value); + } + + Common.NotificationCenter.trigger('edit:complete', me); + } + })).show(); + } + }, + + ChangeSettings: function(props) { + if (this._initSettings) + this.createDelayedControls(); + + this.disableControls(this._locked); // need to update combodataview after disabled state + + if (props )//formatTableInfo + { + this._originalProps = props; + + this._state.TableName=props.asc_getName(); + + var me = this, + cache_names = props.asc_getCacheFields(), + pivot_names = props.asc_getPivotFields(); + + this._state.names = []; + pivot_names.forEach(function (item, index) { + me._state.names[index] = item.asc_getName() || cache_names[index].asc_getName(); + }); + + var arr = [], isChecked = [], + value = props.asc_getColumnFields(); + value && value.forEach(function (item, index) { + var pivotIndex = item.asc_getIndex(); + if (pivotIndex>-1 || pivotIndex == -2) { + var name = (pivotIndex>-1) ? me._state.names[pivotIndex] : me.textValues; + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : false, + pivotIndex : pivotIndex, + index : index, + value : name, + tip : (name.length>10) ? name : '' + })); + isChecked[name] = true; + } + }); + this.columnsList.store.reset(arr); + this.columnsList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + + arr = []; + value = props.asc_getRowFields(); + value && value.forEach(function (item, index) { + var pivotIndex = item.asc_getIndex(); + if (pivotIndex>-1 || pivotIndex == -2) { + var name = (pivotIndex>-1) ? me._state.names[pivotIndex] : me.textValues; + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : false, + pivotIndex : pivotIndex, + index : index, + value : name, + tip : (name.length>10) ? name : '' + })); + isChecked[name] = true; + } + }); + this.rowsList.store.reset(arr); + this.rowsList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + + arr = []; + value = props.asc_getDataFields(); + value && value.forEach(function (item, index) { + var pivotIndex = item.asc_getIndex(); + if (pivotIndex>-1) { + var name = item.asc_getName(); + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : false, + pivotIndex : pivotIndex, + index : index, + value : name, + tip : (name.length>10) ? name : '' + })); + isChecked[me._state.names[pivotIndex]] = true; + } + }); + this.valuesList.store.reset(arr); + this.valuesList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + + arr = []; + value = props.asc_getPageFields(); + value && value.forEach(function (item, index) { + var pivotIndex = item.asc_getIndex(); + if (pivotIndex>-1) { + var name = me._state.names[pivotIndex]; + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : false, + pivotIndex : pivotIndex, + index : index, + value : name, + tip : (name.length>10) ? name : '' + })); + isChecked[name] = true; + } + }); + this.filtersList.store.reset(arr); + this.filtersList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + + arr = []; + me._state.names.forEach(function (item, index) { + arr.push(new Common.UI.DataViewModel({ + selected : false, + allowSelected : false, + value : item, + index : index, + tip : (item.length>25) ? item : '', + check : isChecked[item] + })); + }); + this.fieldsList.store.reset(arr); + this.fieldsList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + } + }, + + onFieldsCheck: function (listView, itemView, record) { + if (this.checkCellTrigerBlock) + return; + + var target = '', type = '', isLabel = false, bound = null; + + var event = window.event ? window.event : window._event; + if (event) { + + var btn = $(event.target); + if (btn && btn.hasClass('listitem-icon')) { + this._state.field = {record: record}; + if (this.pivotFieldsMenu) { + if (this.pivotFieldsMenu.isVisible()) { + this.pivotFieldsMenu.hide(); + return; + } + } else { + this.miAddFilter = new Common.UI.MenuItem({ + caption : this.txtAddFilter, + checkable : false + }); + this.miAddFilter.on('click', _.bind(this.onAddFilter, this)); + this.miAddRow = new Common.UI.MenuItem({ + caption : this.txtAddRow, + checkable : false + }); + // this.miAddRow.on('click', _.bind(this.onAddRow, this)); + this.miAddColumn = new Common.UI.MenuItem({ + caption : this.txtAddColumn, + checkable : false + }); + // this.miAddColumn.on('click', _.bind(this.onAddColumn, this)); + this.miAddValues = new Common.UI.MenuItem({ + caption : this.txtAddValues, + checkable : false + }); + // this.miAddValues.on('click', _.bind(this.onAddValues, this)); + + this.pivotFieldsMenu = new Common.UI.Menu({ + menuAlign: 'tr-br', + items: [ + this.miAddFilter, + this.miAddRow, + this.miAddColumn, + this.miAddValues + ] + }); + } + + var recIndex = (record != undefined) ? record.get('index') : -1; + + var menu = this.pivotFieldsMenu, + showPoint, me = this, + currentTarget = $(event.currentTarget), + parent = $(this.el), + offset = currentTarget.offset(), + offsetParent = parent.offset(); + + showPoint = [offset.left - offsetParent.left + currentTarget.width(), offset.top - offsetParent.top + currentTarget.height()/2]; + + var menuContainer = parent.find('#menu-pivot-fields-container'); + if (!menu.rendered) { + if (menuContainer.length < 1) { + menuContainer = $('', menu.id); + parent.append(menuContainer); + } + menu.render(menuContainer); + menu.cmpEl.attr({tabindex: "-1"}); + + menu.on('show:after', function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', true); + }).on('hide:after', function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', false); + }); + } + + menu.menuAlignEl = currentTarget; + menu.setOffset(-20, -currentTarget.height()/2 - 3); + menu.show(); + _.delay(function() { + menu.cmpEl.focus(); + }, 10); + event.stopPropagation(); + event.preventDefault(); + return; + } + + type = event.target.type; + target = $(event.currentTarget).find('.list-item'); + + if (target.length) { + bound = target.get(0).getBoundingClientRect(); + var _clientX = event.clientX*Common.Utils.zoom(), + _clientY = event.clientY*Common.Utils.zoom(); + if (bound.left < _clientX && _clientX < bound.right && + bound.top < _clientY && _clientY < bound.bottom) { + isLabel = true; + } + } + + if (type === 'button' || isLabel) { + this.updateFieldCheck(listView, record); + + _.delay(function () { + listView.$el.find('.listview').focus(); + }, 100, this); + } + } + }, + + updateFieldCheck: function (listView, record) { + if (record && listView) { + listView.isSuspendEvents = true; + + record.set('check', !record.get('check')); + + listView.isSuspendEvents = false; + listView.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true, suppressScrollX: true}); + } + }, + + onColumnsSelect: function(type, picker, item, record, e){ + var btn = $(e.target); + if (btn && btn.hasClass('listitem-icon')) { + this._state.field = {record: record, type: type}; + if (this.fieldsMenu) { + if (this.fieldsMenu.isVisible()) { + this.fieldsMenu.hide(); + return; + } + } else { + this.miMoveUp = new Common.UI.MenuItem({ + caption : this.txtMoveUp, + checkable : false + }); + // this.miMoveUp.on('click', _.bind(this.onMoveUp, this)); + this.miMoveDown = new Common.UI.MenuItem({ + caption : this.txtMoveDown, + checkable : false + }); + // this.miMoveDown.on('click', _.bind(this.onMoveDown, this)); + this.miMoveBegin = new Common.UI.MenuItem({ + caption : this.txtMoveBegin, + checkable : false + }); + // this.miMoveBegin.on('click', _.bind(this.onMoveBegin, this)); + this.miMoveEnd = new Common.UI.MenuItem({ + caption : this.txtMoveEnd, + checkable : false + }); + // this.miMoveEnd.on('click', _.bind(this.onMoveEnd, this)); + + this.miMoveFilter = new Common.UI.MenuItem({ + caption : this.txtMoveFilter, + checkable : false + }); + // this.miMoveFilter.on('click', _.bind(this.onMoveFilter, this)); + this.miMoveRow = new Common.UI.MenuItem({ + caption : this.txtMoveRow, + checkable : false + }); + // this.miMoveRow.on('click', _.bind(this.onMoveRow, this)); + this.miMoveColumn = new Common.UI.MenuItem({ + caption : this.txtMoveColumn, + checkable : false + }); + // this.miMoveColumn.on('click', _.bind(this.onMoveColumn, this)); + this.miMoveValues = new Common.UI.MenuItem({ + caption : this.txtMoveValues, + checkable : false + }); + // this.miMoveValues.on('click', _.bind(this.onMoveValues, this)); + + this.miRemove = new Common.UI.MenuItem({ + caption : this.txtRemove, + checkable : false + }); + this.miRemove.on('click', _.bind(this.onRemove, this)); + + this.miFieldSettings = new Common.UI.MenuItem({ + caption : this.txtFieldSettings, + checkable : false + }); + this.miFieldSettings.on('click', _.bind(this.onFieldSettings, this)); + + this.fieldsMenu = new Common.UI.Menu({ + menuAlign: 'tr-br', + items: [ + this.miMoveUp, + this.miMoveDown, + this.miMoveBegin, + this.miMoveEnd, + {caption : '--'}, + this.miMoveFilter, + this.miMoveRow, + this.miMoveColumn, + this.miMoveValues, + {caption : '--'}, + this.miRemove, + {caption : '--'}, + this.miFieldSettings + ] + }); + } + + this.miMoveFilter.setDisabled(type == 3); // menu for filter + this.miMoveRow.setDisabled(type == 1); // menu for row + this.miMoveColumn.setDisabled(type == 0); // menu for column + this.miMoveValues.setDisabled(type == 2); // menu for value + + var recIndex = (record != undefined) ? record.get('index') : -1, + len = picker.store.length; + this.miMoveUp.setDisabled(recIndex<1); + this.miMoveDown.setDisabled(recIndex>len-2 || recIndex<0); + this.miMoveBegin.setDisabled(recIndex<1); + this.miMoveEnd.setDisabled(recIndex>len-2 || recIndex<0); + + this.miFieldSettings.setDisabled(record.get('pivotIndex')==-2); + + var menu = this.fieldsMenu, + showPoint, me = this, + currentTarget = $(e.currentTarget), + parent = $(this.el), + offset = currentTarget.offset(), + offsetParent = parent.offset(); + + showPoint = [offset.left - offsetParent.left + currentTarget.width(), offset.top - offsetParent.top + currentTarget.height()/2]; + + var menuContainer = parent.find('#menu-pivot-container'); + if (!menu.rendered) { + if (menuContainer.length < 1) { + menuContainer = $('', menu.id); + parent.append(menuContainer); + } + menu.render(menuContainer); + menu.cmpEl.attr({tabindex: "-1"}); + + menu.on('show:after', function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', true); + }).on('hide:after', function(cmp) { + if (cmp && cmp.menuAlignEl) + cmp.menuAlignEl.toggleClass('over', false); + }); + } + + menu.menuAlignEl = currentTarget; + menu.setOffset(-20, -currentTarget.height()/2 - 3); + menu.show(); + _.delay(function() { + menu.cmpEl.focus(); + }, 10); + e.stopPropagation(); + e.preventDefault(); + } + }, + + setLocked: function (locked) { + this._locked = locked; + }, + + onFieldSettings: function(record, type, e) { + var me = this; + var win; + if (me.api && !this._locked && me._state.field){ + if (me._state.field.type == 2) { // value field + var field = me._originalProps.asc_getDataFields()[me._state.field.record.get('index')]; + (new SSE.Views.ValueFieldSettingsDialog( + { + props: me._originalProps, + field: field, + names: me._state.names, + api: me.api, + handler: function(result, value) { + if (result == 'ok' && me.api && value) { + field.asc_set(me.api, me._originalProps, value); + } + + Common.NotificationCenter.trigger('edit:complete', me); + } + })).show(); + } else { + (new SSE.Views.FieldSettingsDialog( + { + props: me._originalProps, + fieldIndex: me._state.field.record.get('pivotIndex'), + names: me._state.names, + api: me.api, + type: me._state.field.type, + handler: function(result, value) { + if (result == 'ok' && me.api && value) { + // me.api.asc_changeFormatTableInfo(me._state.TableName, Asc.c_oAscChangeTableStyleInfo.advancedSettings, value); + } + + Common.NotificationCenter.trigger('edit:complete', me); + } + })).show(); + } + } + }, + + onAddFilter: function() { + if (this.api && !this._locked && this._state.field){ + this._originalProps.asc_addPageField(this.api, this._state.field.record.get('index')); + } + }, + + onRemove: function() { + if (this.api && !this._locked && this._state.field){ + this._originalProps.asc_removeField(this.api, this._state.field.record.get('pivotIndex')); + } + }, + + disableControls: function(disable) { + if (this._initSettings) return; + + if (this._state.DisabledControls!==disable) { + this._state.DisabledControls = disable; + _.each(this.lockedControls, function(item) { + item.setDisabled(disable); + }); + this.linkAdvanced.toggleClass('disabled', disable); + } + }, + + textFields: 'Select Fields', + textOK : 'OK', + textCancel : 'Cancel', + textValues : 'Values', + textRows : 'Rows', + textColumns : 'Columns', + textFilters : 'Filters', + notcriticalErrorTitle : 'Warning', + textAdvanced: 'Show advanced settings', + txtMoveUp: 'Move Up', + txtMoveDown: 'Move Down', + txtMoveBegin: 'Move to Beginning', + txtMoveEnd: 'Move to End', + txtMoveFilter: 'Move to Filters', + txtMoveRow: 'Move to Rows', + txtMoveColumn: 'Move to Columns', + txtMoveValues: 'Move to Values', + txtRemove: 'Remove Field', + txtFieldSettings: 'Field Settings', + txtAddFilter: 'Add to Filters', + txtAddRow: 'Add to Rows', + txtAddColumn: 'Add to Columns', + txtAddValues: 'Add to Values' + + }, SSE.Views.PivotSettings || {})); +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/PivotSettingsAdvanced.js b/apps/spreadsheeteditor/main/app/view/PivotSettingsAdvanced.js new file mode 100644 index 0000000000..8bff50b9b7 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/PivotSettingsAdvanced.js @@ -0,0 +1,312 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * PivotSettingsAdvanced.js + * + * Created by Julia Radzhabova on 17.07.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ 'text!spreadsheeteditor/main/app/template/PivotSettingsAdvanced.template', + 'common/main/lib/util/utils', + 'common/main/lib/component/InputField', + 'common/main/lib/component/ComboBox', + 'common/main/lib/component/CheckBox', + 'common/main/lib/component/MetricSpinner', + 'common/main/lib/view/AdvancedSettingsWindow' +], function (contentTemplate) { 'use strict'; + + SSE.Views.PivotSettingsAdvanced = Common.Views.AdvancedSettingsWindow.extend(_.extend({ + options: { + contentWidth: 300, + height: 395, + toggleGroup: 'pivot-adv-settings-group', + storageName: 'sse-pivot-adv-settings-category' + }, + + initialize : function(options) { + var me = this; + + _.extend(this.options, { + title: this.textTitle, + items: [ + {panelId: 'id-adv-pivot-layout', panelCaption: this.strLayout}, + {panelId: 'id-adv-pivot-data', panelCaption: this.textDataSource}, + {panelId: 'id-adv-pivot-alttext', panelCaption: this.textAlt} + ], + contentTemplate: _.template(contentTemplate)({ + scope: this + }) + }, options); + + this.api = options.api; + this.handler = options.handler; + this.props = options.props; + + Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.Views.AdvancedSettingsWindow.prototype.render.call(this); + var me = this; + + this.inputName = new Common.UI.InputField({ + el : $('#pivot-adv-name'), + allowBlank : true, + validateOnBlur: false, + style : 'width: 100%;' + }); + + this.radioDown = new Common.UI.RadioBox({ + el: $('#pivot-adv-radio-down'), + labelText: this.textDown, + name: 'asc-radio-display-field', + checked: true + }); + this.radioDown.on('change', _.bind(function(field, newValue, eOpts) { + if (newValue) { + this.lblPageWrap.html(this.textWrapCol); + } + }, this)); + + this.radioOver = new Common.UI.RadioBox({ + el: $('#pivot-adv-radio-over'), + labelText: this.textOver, + name: 'asc-radio-display-field' + }); + this.radioOver.on('change', _.bind(function(field, newValue, eOpts) { + if (newValue) { + this.lblPageWrap.html(this.textWrapRow); + } + }, this)); + + this.chRows = new Common.UI.CheckBox({ + el: $('#pivot-adv-chk-show-rows'), + labelText: this.textShowRows + }); + + this.chCols = new Common.UI.CheckBox({ + el: $('#pivot-adv-chk-show-columns'), + labelText: this.textShowCols + }); + + this.numWrap = new Common.UI.MetricSpinner({ + el: $('#pivot-adv-spin-wrap'), + step: 1, + width: 85, + allowDecimal: false, + defaultUnit : "", + value: '0', + maxValue: 255, + minValue: 0 + }); + + this.lblPageWrap = this.$window.find('#pivot-adv-label-wrap'); + + this.chHeaders = new Common.UI.CheckBox({ + el: $('#pivot-adv-chk-show-headers'), + labelText: this.textShowHeaders + }); + + this.txtDataRange = new Common.UI.InputField({ + el : $('#pivot-adv-txt-range'), + name : 'range', + style : 'width: 100%;', + allowBlank : true, + blankError : this.txtEmpty, + validateOnChange: true + }); + + this.btnSelectData = new Common.UI.Button({ + el: $('#pivot-adv-btn-data') + }); + this.btnSelectData.on('click', _.bind(this.onSelectData, this)); + + // Alt Text + + this.inputAltTitle = new Common.UI.InputField({ + el : $('#pivot-advanced-alt-title'), + allowBlank : true, + validateOnBlur: false, + style : 'width: 100%;' + }).on('changed:after', function() { + me.isAltTitleChanged = true; + }); + + this.textareaAltDescription = this.$window.find('textarea'); + this.textareaAltDescription.keydown(function (event) { + if (event.keyCode == Common.UI.Keys.RETURN) { + event.stopPropagation(); + } + me.isAltDescChanged = true; + }); + + this.afterRender(); + }, + + afterRender: function() { + this._setDefaults(this.props); + if (this.storageName) { + var value = Common.localStorage.getItem(this.storageName); + this.setActiveCategory((value!==null) ? parseInt(value) : 0); + } + }, + + show: function() { + Common.Views.AdvancedSettingsWindow.prototype.show.apply(this, arguments); + }, + + _setDefaults: function (props) { + if (props) { + var me = this; + this.inputName.setValue(Common.Utils.String.htmlEncode(props.asc_getName())); + + this.chCols.setValue(props.asc_getRowGrandTotals(), true); + this.chRows.setValue(props.asc_getColGrandTotals(), true); + + (props.asc_getPageOverThenDown()) ? this.radioOver.setValue(true) : this.radioDown.setValue(true); + this.lblPageWrap.html((props.asc_getPageOverThenDown()) ? this.textWrapRow : this.textWrapCol); + + this.numWrap.setValue(props.asc_getPageWrap()); + + this.chHeaders.setValue(props.asc_getShowHeaders(), true); + + // var value = props.getRange(); + // this.txtDataRange.setValue((value) ? value : ''); + // this.dataRangeValid = value; + + this.txtDataRange.validation = function(value) { + // var isvalid = me.api.asc_checkDataRange(Asc.c_oAscSelectionDialogType.Pivot, value, false); + // return (isvalid==Asc.c_oAscError.ID.DataRangeError) ? me.textInvalidRange : true; + return true; + }; + } + }, + + getSettings: function () { + var props = new Asc.CT_pivotTableDefinition(); + props.asc_setRowGrandTotals(this.chCols.getValue() == 'checked'); + props.asc_setColGrandTotals(this.chRows.getValue() == 'checked'); + + return props; + }, + + onDlgBtnClick: function(event) { + var me = this; + var state = (typeof(event) == 'object') ? event.currentTarget.attributes['result'].value : event; + if (state == 'ok' && this.isRangeValid()) { + this.handler && this.handler.call(this, state, (state == 'ok') ? this.getSettings() : undefined); + } + + this.close(); + }, + + onPrimary: function() { + this.onDlgBtnClick('ok'); + return false; + }, + + isRangeValid: function() { + if (this.isChart) { + var isvalid; + if (!_.isEmpty(this.txtDataRange.getValue())) { + isvalid = this.api.asc_checkDataRange(Asc.c_oAscSelectionDialogType.Pivot, this.txtDataRange.getValue()); + if (isvalid == Asc.c_oAscError.ID.No) + return true; + } else + this.txtDataRange.showError([this.txtEmpty]); + + this.setActiveCategory(1); + this.txtDataRange.cmpEl.find('input').focus(); + return false; + } else + return true; + }, + + onSelectData: function() { + var me = this; + if (me.api) { + var handlerDlg = function(dlg, result) { + if (result == 'ok') { + me.dataRangeValid = dlg.getSettings(); + me.txtDataRange.setValue(me.dataRangeValid); + me.txtDataRange.checkValidate(); + } + }; + + var win = new SSE.Views.CellRangeDialog({ + handler: handlerDlg + }).on('close', function() { + me.show(); + }); + + var xy = me.$window.offset(); + me.hide(); + win.show(xy.left + 160, xy.top + 125); + win.setSettings({ + api : me.api, + range : (!_.isEmpty(me.txtDataRange.getValue()) && (me.txtDataRange.checkValidate()==true)) ? me.txtDataRange.getValue() : me.dataRangeValid, + type : Asc.c_oAscSelectionDialogType.Pivot + }); + } + }, + + textTitle: 'Pivot Table - Advanced Settings', + textCancel: 'Cancel', + textOk: 'OK', + strLayout: 'Name and Layout', + txtName: 'Name', + textGrandTotals: 'Grand Totals', + textShowRows: 'Show for rows', + textShowCols: 'Show for columns', + textDataSource: 'Data Source', + textDataRange: 'Data Range', + textSelectData: 'Select Data', + textAlt: 'Alternative Text', + textAltTitle: 'Title', + textAltDescription: 'Description', + textAltTip: 'The alternative text-based representation of the visual object information, which will be read to the people with vision or cognitive impairments to help them better understand what information there is in the image, autoshape, chart or table.', + txtEmpty: 'This field is required', + textInvalidRange: 'ERROR! Invalid cells range', + textDisplayFields: 'Display fields in report filter area', + textDown: 'Down, then over', + textOver: 'Over, then down', + textWrapCol: 'Report filter fields per column', + textWrapRow: 'Report filter fields per row', + textHeaders: 'Field Headers', + textShowHeaders: 'Show field headers for rows and columns' + + }, SSE.Views.PivotSettingsAdvanced || {})) +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/PivotTable.js b/apps/spreadsheeteditor/main/app/view/PivotTable.js new file mode 100644 index 0000000000..62459e5e37 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/PivotTable.js @@ -0,0 +1,347 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * PivotTable.js + * + * View + * + * Created by Julia.Radzhabova on 06.27.17 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + // 'text!spreadsheeteditor/main/app/template/PivotTableSettings.template', + 'common/main/lib/util/utils', + 'common/main/lib/component/Button', + 'common/main/lib/component/ComboDataView', + 'common/main/lib/component/Layout' +], function (menuTemplate) { + 'use strict'; + + SSE.Views.PivotTable = Common.UI.BaseView.extend(_.extend((function(){ + var template = + '
' + + '
' + + '' + + '
' + + '
' + + '
' + + '' + + '' + + '' + + '' + + '
' + + '
' + + '
' + + '' + + '
' + + '
' + + '
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + + '
' + + '
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + + '
' + + '
' + + '
' + + '
'; + + function setEvents() { + var me = this; + + this.btnAddPivot.on('click', function (e) { + me.fireEvent('pivottable:create'); + }); + + this.btnPivotLayout.menu.on('item:click', function (menu, item, e) { + me.fireEvent('pivottable:layout', [item.value]); + }); + + this.btnPivotBlankRows.menu.on('item:click', function (menu, item, e) { + me.fireEvent('pivottable:blankrows', [item.value]); + }); + + this.btnPivotSubtotals.menu.on('item:click', function (menu, item, e) { + me.fireEvent('pivottable:subtotals', [item.value]); + }); + + this.btnPivotGrandTotals.menu.on('item:click', function (menu, item, e) { + me.fireEvent('pivottable:grandtotals', [item.value]); + }); + + this.btnRefreshPivot.on('click', function (e) { + me.fireEvent('pivottable:refresh'); + }); + + this.chRowHeader.on('change', function (field, value) { + me.fireEvent('pivottable:rowscolumns', [0, value]); + }); + this.chColHeader.on('change', function (field, value) { + me.fireEvent('pivottable:rowscolumns', [1, value]); + }); + this.chRowBanded.on('change', function (field, value) { + me.fireEvent('pivottable:rowscolumns', [2, value]); + }); + this.chColBanded.on('change', function (field, value) { + me.fireEvent('pivottable:rowscolumns', [3, value]); + }); + + this.pivotStyles.on('click', function (combo, record) { + me.fireEvent('pivottable:style', [record]); + }); + this.pivotStyles.openButton.menu.on('show:after', function () { + me.pivotStyles.menuPicker.scroller.update({alwaysVisibleY: true}); + }); + } + + return { + options: {}, + + initialize: function (options) { + Common.UI.BaseView.prototype.initialize.call(this, options); + + this.appConfig = options.mode; + this.lockedControls = []; + + this.chRowHeader = new Common.UI.CheckBox({ + labelText: this.textRowHeader + }); + this.lockedControls.push(this.chRowHeader); + + this.chColHeader = new Common.UI.CheckBox({ + labelText: this.textColHeader + }); + this.lockedControls.push(this.chColHeader); + + this.chRowBanded = new Common.UI.CheckBox({ + labelText: this.textRowBanded + }); + this.lockedControls.push(this.chRowBanded); + + this.chColBanded = new Common.UI.CheckBox({ + labelText: this.textColBanded + }); + this.lockedControls.push(this.chColBanded); + + this.btnAddPivot = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-docspell', + caption: this.txtCreate, + disabled : true + }); + // this.lockedControls.push(this.btnAddPivot); + + this.btnPivotLayout = new Common.UI.Button({ + cls : 'btn-toolbar x-huge icon-top', + iconCls : 'btn-insertimage', + caption : this.capLayout, + disabled : true, + menu : new Common.UI.Menu({ + items: [ + { caption: this.mniLayoutCompact, value: 0 }, + { caption: this.mniLayoutOutline, value: 1 }, + { caption: this.mniLayoutTabular, value: 2 }, + { caption: '--' }, + { caption: this.mniLayoutRepeat, value: 3 }, + { caption: this.mniLayoutNoRepeat, value: 4 } + ] + }) + }); + // this.lockedControls.push(this.btnPivotLayout); // remove commentings after enabled option + + this.btnPivotBlankRows = new Common.UI.Button({ + cls : 'btn-toolbar x-huge icon-top', + iconCls : 'btn-insertimage', + caption : this.capBlankRows, + disabled : true, + menu : new Common.UI.Menu({ + items: [ + { caption: this.mniInsertBlankLine, value: 'insert' }, + { caption: this.mniRemoveBlankLine, value: 'remove' } + ] + }) + }); + // this.lockedControls.push(this.btnPivotBlankRows); // remove commentings after enabled option + + this.btnPivotSubtotals = new Common.UI.Button({ + cls : 'btn-toolbar x-huge icon-top', + iconCls : 'btn-insertimage', + caption : this.capSubtotals, + disabled : true, + menu : new Common.UI.Menu({ + items: [ + { caption: this.mniNoSubtotals, value: 0 }, + { caption: this.mniBottomSubtotals, value: 1 }, + { caption: this.mniTopSubtotals, value: 2 } + ] + }) + }); + // this.lockedControls.push(this.btnPivotSubtotals); // remove commentings after enabled option + + this.btnPivotGrandTotals = new Common.UI.Button({ + cls : 'btn-toolbar x-huge icon-top', + iconCls : 'btn-insertimage', + caption : this.capGrandTotals, + disabled : true, + menu : new Common.UI.Menu({ + items: [ + { caption: this.mniOffTotals, value: 0 }, + { caption: this.mniOnTotals, value: 1 }, + { caption: this.mniOnRowsTotals, value: 2 }, + { caption: this.mniOnColumnsTotals, value: 3 } + ] + }) + }); + // this.lockedControls.push(this.btnPivotGrandTotals); // remove commentings after enabled option + + this.btnRefreshPivot = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-ic-docspell', + caption: this.txtRefresh, + disabled : true + }); + // this.lockedControls.push(this.btnRefreshPivot); + + this.pivotStyles = new Common.UI.ComboDataView({ + cls : 'combo-pivot-template', + enableKeyEvents : true, + itemWidth : 61, + itemHeight : 49, + menuMaxHeight : 300 + // lock : [_set.editCell, _set.selChart, _set.selChartText, _set.selShape, _set.selShapeText, _set.selImage, _set.lostConnect, _set.coAuth] + }); + this.lockedControls.push(this.pivotStyles); + + Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); + }, + + render: function (el) { + this.boxSdk = $('#editor_sdk'); + if ( el ) el.html( this.getPanel() ); + + return this; + }, + + onAppReady: function (config) { + var me = this; + (new Promise(function (accept, reject) { + accept(); + })).then(function(){ + me.btnAddPivot.updateHint(me.tipCreatePivot); + me.btnRefreshPivot.updateHint(me.tipRefresh); + me.btnPivotLayout.updateHint(me.capLayout); + me.btnPivotBlankRows.updateHint(me.capBlankRows); + me.btnPivotSubtotals.updateHint(me.tipSubtotals); + me.btnPivotGrandTotals.updateHint(me.tipGrandTotals); + + setEvents.call(me); + }); + }, + + getPanel: function () { + this.$el = $(_.template(template)( {} )); + + this.chRowHeader.render(this.$el.find('#slot-chk-header-row')); + this.chColHeader.render(this.$el.find('#slot-chk-header-column')); + this.chRowBanded.render(this.$el.find('#slot-chk-banded-row')); + this.chColBanded.render(this.$el.find('#slot-chk-banded-column')); + + this.btnAddPivot.render(this.$el.find('#slot-btn-add-pivot')); + this.btnRefreshPivot.render(this.$el.find('#slot-btn-refresh-pivot')); + this.btnPivotLayout.render(this.$el.find('#slot-btn-pivot-report-layout')); + this.btnPivotBlankRows.render(this.$el.find('#slot-btn-pivot-blank-rows')); + this.btnPivotSubtotals.render(this.$el.find('#slot-btn-pivot-subtotals')); + this.btnPivotGrandTotals.render(this.$el.find('#slot-btn-pivot-grand-totals')); + this.pivotStyles.render(this.$el.find('#slot-field-pivot-styles')); + + return this.$el; + }, + + show: function () { + Common.UI.BaseView.prototype.show.call(this); + this.fireEvent('show', this); + }, + + getButton: function(type, parent) { + }, + + SetDisabled: function (state) { + this.lockedControls && this.lockedControls.forEach(function(button) { + if ( button ) { + button.setDisabled(state); + } + }, this); + }, + + txtCreate: 'Insert Table', + tipCreatePivot: 'Insert Pivot Table', + textRowHeader: 'Row Headers', + textColHeader: 'Column Headers', + textRowBanded: 'Banded Rows', + textColBanded: 'Banded Columns', + capBlankRows: 'Blank Rows', + mniInsertBlankLine: 'Insert Blank Line after Each Item', + mniRemoveBlankLine: 'Remove Blank Line after Each Item', + capGrandTotals: 'Grand Totals', + mniOffTotals: 'Off for Rows and Columns', + mniOnTotals: 'On for Rows and Columns', + mniOnRowsTotals: 'On for Rows Only', + mniOnColumnsTotals: 'On for Columns Only', + capLayout: 'Report Layout', + capSubtotals: 'Subtotals', + mniLayoutCompact: 'Show in Compact Form', + mniLayoutOutline: 'Show in Outline Form', + mniLayoutTabular: 'Show in Tabular Form', + mniLayoutRepeat: 'Repeat All Item Labels', + mniLayoutNoRepeat: 'Don\'t Repeat All Item Labels', + mniNoSubtotals: 'Don\'t Show Subtotals', + mniBottomSubtotals: 'Show all Subtotals at Bottom of Group', + mniTopSubtotals: 'Show all Subtotals at Top of Group', + txtRefresh: 'Refresh', + tipRefresh: 'Update the information from data source', + tipGrandTotals: 'Show or hide grand totals', + tipSubtotals: 'Show or hide subtotals' + } + }()), SSE.Views.PivotTable || {})); +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/RightMenu.js b/apps/spreadsheeteditor/main/app/view/RightMenu.js index fe331911a4..d21e71c169 100644 --- a/apps/spreadsheeteditor/main/app/view/RightMenu.js +++ b/apps/spreadsheeteditor/main/app/view/RightMenu.js @@ -55,6 +55,7 @@ define([ 'spreadsheeteditor/main/app/view/ShapeSettings', 'spreadsheeteditor/main/app/view/TextArtSettings', 'spreadsheeteditor/main/app/view/TableSettings', + 'spreadsheeteditor/main/app/view/PivotSettings', 'spreadsheeteditor/main/app/view/SignatureSettings', 'common/main/lib/component/Scroller' ], function (menuTemplate, $, _, Backbone) { @@ -124,6 +125,15 @@ define([ allowMouseEventsOnDisabled: true }); + this.btnPivot = new Common.UI.Button({ + hint: this.txtPivotSettings, + asctype: Common.Utils.documentSettingsType.Pivot, + enableToggle: true, + disabled: true, + toggleGroup: 'tabpanelbtnsGroup', + allowMouseEventsOnDisabled: true + }); + this._settings = []; this._settings[Common.Utils.documentSettingsType.Paragraph] = {panel: "id-paragraph-settings", btn: this.btnText}; this._settings[Common.Utils.documentSettingsType.Image] = {panel: "id-image-settings", btn: this.btnImage}; @@ -131,6 +141,7 @@ define([ this._settings[Common.Utils.documentSettingsType.Chart] = {panel: "id-chart-settings", btn: this.btnChart}; this._settings[Common.Utils.documentSettingsType.TextArt] = {panel: "id-textart-settings", btn: this.btnTextArt}; this._settings[Common.Utils.documentSettingsType.Table] = {panel: "id-table-settings", btn: this.btnTable}; + this._settings[Common.Utils.documentSettingsType.Pivot] = {panel: "id-pivot-settings", btn: this.btnPivot}; return this; }, @@ -152,6 +163,7 @@ define([ this.btnShape.setElement($('#id-right-menu-shape'), false); this.btnShape.render(); this.btnTextArt.setElement($('#id-right-menu-textart'), false); this.btnTextArt.render(); this.btnTable.setElement($('#id-right-menu-table'), false); this.btnTable.render(); + this.btnPivot.setElement($('#id-right-menu-pivot'), false); this.btnPivot.render(); this.btnText.on('click', _.bind(this.onBtnMenuClick, this)); this.btnImage.on('click', _.bind(this.onBtnMenuClick, this)); @@ -159,6 +171,7 @@ define([ this.btnShape.on('click', _.bind(this.onBtnMenuClick, this)); this.btnTextArt.on('click', _.bind(this.onBtnMenuClick, this)); this.btnTable.on('click', _.bind(this.onBtnMenuClick, this)); + this.btnPivot.on('click', _.bind(this.onBtnMenuClick, this)); this.paragraphSettings = new SSE.Views.ParagraphSettings(); this.imageSettings = new SSE.Views.ImageSettings(); @@ -166,6 +179,7 @@ define([ this.shapeSettings = new SSE.Views.ShapeSettings(); this.textartSettings = new SSE.Views.TextArtSettings(); this.tableSettings = new SSE.Views.TableSettings(); + this.pivotSettings = new SSE.Views.PivotSettings(); if (mode && mode.canProtect) { this.btnSignature = new Common.UI.Button({ @@ -203,6 +217,7 @@ define([ this.shapeSettings.setApi(api); this.textartSettings.setApi(api); this.tableSettings.setApi(api); + this.pivotSettings.setApi(api); if (this.signatureSettings) this.signatureSettings.setApi(api); return this; }, @@ -281,6 +296,7 @@ define([ txtChartSettings: 'Chart Settings', txtSparklineSettings: 'Sparkline Settings', txtTableSettings: 'Table Settings', + txtPivotSettings: 'Pivot Table Settings', txtSignatureSettings: 'Signature Settings' }, SSE.Views.RightMenu || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/ValueFieldSettingsDialog.js b/apps/spreadsheeteditor/main/app/view/ValueFieldSettingsDialog.js new file mode 100644 index 0000000000..6bf42ce395 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/ValueFieldSettingsDialog.js @@ -0,0 +1,309 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * ValueFieldSettingsDialog.js + * + * Created by Julia Radzhabova on 14.07.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'common/main/lib/util/utils', + 'common/main/lib/component/InputField', + 'common/main/lib/component/ComboBox', + 'common/main/lib/view/AdvancedSettingsWindow' +], function () { 'use strict'; + + SSE.Views.ValueFieldSettingsDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({ + options: { + contentWidth: 284, + height: 340 + }, + + initialize : function(options) { + var me = this; + + _.extend(this.options, { + title: this.textTitle, + template: [ + '
', + '
', + '
', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '
', + '', + '', + '
', + '', + '
', + '
', + '
', + '', + '
', + '
', + '
', + '', + '
', + '
', + '', + '
', + '
', + '', + '
', + '
', + '
', + '
', + '
', + '
', + '' + ].join('') + }, options); + + this.api = options.api; + this.handler = options.handler; + this.props = options.props; + this.field = options.field || 0; + this.names = options.names || []; + + Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.Views.AdvancedSettingsWindow.prototype.render.call(this); + var me = this; + + this.inputCustomName = new Common.UI.InputField({ + el : $('#value-field-settings-custom'), + allowBlank : true, + validateOnBlur: false, + style : 'width: 100%;' + }); + + this.cmbSummarize = new Common.UI.ComboBox({ + el: $('#value-field-settings-summarize'), + cls: 'input-group-nr', + menuStyle: 'min-width: 264px;', + editable: false, + data: [ + { value: Asc.c_oAscDataConsolidateFunction.Sum, displayValue: this.txtSum }, + { value: Asc.c_oAscDataConsolidateFunction.Count, displayValue: this.txtCount }, + { value: Asc.c_oAscDataConsolidateFunction.Average, displayValue: this.txtAverage }, + { value: Asc.c_oAscDataConsolidateFunction.Max, displayValue: this.txtMax }, + { value: Asc.c_oAscDataConsolidateFunction.Min, displayValue: this.txtMin }, + { value: Asc.c_oAscDataConsolidateFunction.Product, displayValue: this.txtProduct }, + { value: Asc.c_oAscDataConsolidateFunction.CountNums,displayValue: this.txtCountNums }, + { value: Asc.c_oAscDataConsolidateFunction.StdDev, displayValue: this.txtStdDev }, + { value: Asc.c_oAscDataConsolidateFunction.StdDevp, displayValue: this.txtStdDevp }, + { value: Asc.c_oAscDataConsolidateFunction.Var, displayValue: this.txtVar }, + { value: Asc.c_oAscDataConsolidateFunction.Varp, displayValue: this.txtVarp } + ] + }); + this.cmbSummarize.setValue(Asc.c_oAscDataConsolidateFunction.Sum); + this.cmbSummarize.on('selected', _.bind(this.onSummarizeSelect, this)); + + this.cmbShowAs = new Common.UI.ComboBox({ + el: $('#value-field-settings-showas'), + cls: 'input-group-nr', + menuStyle: 'min-width: 264px;', + editable: false, + data: [ + { value: Asc.c_oAscShowDataAs.Normal, displayValue: this.txtNormal }, + { value: Asc.c_oAscShowDataAs.PercentOfRow, displayValue: this.txtPercentOfRow }, + { value: Asc.c_oAscShowDataAs.PercentOfCol, displayValue: this.txtPercentOfCol }, + { value: Asc.c_oAscShowDataAs.PercentOfTotal, displayValue: this.txtPercentOfTotal }, + { value: Asc.c_oAscShowDataAs.Percent, displayValue: this.txtPercent }, + { value: Asc.c_oAscShowDataAs.Difference, displayValue: this.txtDifference }, + { value: Asc.c_oAscShowDataAs.PercentDiff, displayValue: this.txtPercentDiff }, + { value: Asc.c_oAscShowDataAs.RunTotal, displayValue: this.txtRunTotal }, + { value: Asc.c_oAscShowDataAs.Index, displayValue: this.txtIndex } + ] + }); + this.cmbShowAs.setValue(Asc.c_oAscDataConsolidateFunction.Normal); + this.cmbShowAs.on('selected', _.bind(this.onShowAsSelect, this)); + + this.cmbBaseField = new Common.UI.ComboBox({ + el: $('#value-field-settings-field'), + cls: 'input-group-nr', + menuStyle: 'min-width: 264px;max-height:235px;', + editable: false, + data: [], + scrollAlwaysVisible: true + }); + this.cmbBaseField.on('selected', _.bind(this.onBaseFieldSelect, this)); + + this.cmbBaseItem = new Common.UI.ComboBox({ + el: $('#value-field-settings-item'), + cls: 'input-group-nr', + menuStyle: 'min-width: 264px;max-height:235px;', + editable: false, + data: [], + scrollAlwaysVisible: true + }); + this.cmbBaseItem.on('selected', _.bind(this.onBaseItemSelect, this)); + + this.lblSourceName = this.$window.find('#value-field-settings-source'); + + this.afterRender(); + }, + + afterRender: function() { + this._setDefaults(this.props); + }, + + show: function() { + Common.Views.AdvancedSettingsWindow.prototype.show.apply(this, arguments); + }, + + _setDefaults: function (props) { + if (props) { + var field = this.field, + cache_names = props.asc_getCacheFields(), + show_as = field.asc_getShowDataAs(); + + this.lblSourceName.html(Common.Utils.String.htmlEncode(cache_names[field.asc_getIndex()].asc_getName())); + this.inputCustomName.setValue(Common.Utils.String.htmlEncode(field.asc_getName())); + + this.cmbSummarize.setValue(field.asc_getSubtotal()); + this.cmbShowAs.setValue(show_as); + + var data = []; + this.names.forEach(function(item){ + data.push({value: item, displayValue: item}); + }); + this.cmbBaseField.setData(data); + this.cmbBaseField.setValue(this.names[0]); + this.cmbBaseField.setDisabled(show_as != c_oAscShowDataAs.Difference && show_as != c_oAscShowDataAs.Percent && + show_as != c_oAscShowDataAs.PercentDiff && show_as != c_oAscShowDataAs.RunTotal); + + // this.cmbBaseItem.setData(data); + this.cmbBaseItem.setDisabled(show_as != c_oAscShowDataAs.Difference && show_as != c_oAscShowDataAs.Percent && + show_as != c_oAscShowDataAs.PercentDiff); + } + }, + + getSettings: function () { + var field = new Asc.CT_DataField(); + field.asc_setName(this.inputCustomName.getValue()); + field.asc_setSubtotal(this.cmbSummarize.getValue()); + + return field; + }, + + onDlgBtnClick: function(event) { + var me = this; + var state = (typeof(event) == 'object') ? event.currentTarget.attributes['result'].value : event; + if (state == 'ok') { + this.handler && this.handler.call(this, state, (state == 'ok') ? this.getSettings() : undefined); + } + + this.close(); + }, + + onPrimary: function() { + this.onDlgBtnClick('ok'); + return false; + }, + + onSummarizeSelect: function(combo, record) { + this.inputCustomName.setValue(record.displayValue + ' ' + this.txtByField + ' ' + this.lblSourceName.text()); + }, + + onShowAsSelect: function(combo, record) { + }, + + onBaseFieldSelect: function(combo, record) { + }, + + onBaseItemSelect: function(combo, record) { + }, + + textTitle: 'Value Field Settings', + textCancel: 'Cancel', + textOk: 'OK', + txtSourceName: 'Source name: ', + txtCustomName: 'Custom name', + txtSummarize: 'Summarize value field by', + txtShowAs: 'Show values as', + txtBaseField: 'Base field', + txtBaseItem: 'Base item', + txtAverage: 'Average', + txtCount: 'Count', + txtCountNums: 'Count Numbers', + txtMax: 'Max', + txtMin: 'Min', + txtProduct: 'Product', + txtStdDev: 'StdDev', + txtStdDevp: 'StdDevp', + txtSum: 'Sum', + txtVar: 'Var', + txtVarp: 'Varp', + txtNormal: 'No Calculation', + txtDifference: 'The Difference From', + txtPercent: 'Percent of', + txtPercentDiff: 'Percent Difference From', + txtRunTotal: 'Running Total In', + txtPercentOfRow: 'Percent of Total', + txtPercentOfCol: 'Percent of Column', + txtPercentOfTotal: 'Percent of Row', + txtIndex: 'Index', + txtByField: 'by field' + + }, SSE.Views.ValueFieldSettingsDialog || {})) +}); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app_dev.js b/apps/spreadsheeteditor/main/app_dev.js index f541535a30..cc88f835af 100644 --- a/apps/spreadsheeteditor/main/app_dev.js +++ b/apps/spreadsheeteditor/main/app_dev.js @@ -145,6 +145,7 @@ require([ 'RightMenu', 'LeftMenu', 'Main', + 'PivotTable', 'Common.Controllers.Fonts', 'Common.Controllers.Chat', 'Common.Controllers.Comments', @@ -164,12 +165,16 @@ require([ 'spreadsheeteditor/main/app/controller/LeftMenu', 'spreadsheeteditor/main/app/controller/Main', 'spreadsheeteditor/main/app/controller/Print', + 'spreadsheeteditor/main/app/controller/PivotTable', 'spreadsheeteditor/main/app/view/FileMenuPanels', 'spreadsheeteditor/main/app/view/ParagraphSettings', 'spreadsheeteditor/main/app/view/ImageSettings', 'spreadsheeteditor/main/app/view/ChartSettings', 'spreadsheeteditor/main/app/view/ShapeSettings', 'spreadsheeteditor/main/app/view/TextArtSettings', + 'spreadsheeteditor/main/app/view/PivotSettings', + 'spreadsheeteditor/main/app/view/FieldSettingsDialog', + 'spreadsheeteditor/main/app/view/ValueFieldSettingsDialog', 'common/main/lib/util/utils', 'common/main/lib/util/LocalStorage', 'common/main/lib/controller/Fonts', diff --git a/apps/spreadsheeteditor/main/resources/less/rightmenu.less b/apps/spreadsheeteditor/main/resources/less/rightmenu.less index ea2ef2037d..2d7c0bb6c8 100644 --- a/apps/spreadsheeteditor/main/resources/less/rightmenu.less +++ b/apps/spreadsheeteditor/main/resources/less/rightmenu.less @@ -334,4 +334,60 @@ button:active:not(.disabled) .btn-change-shape {background-position: -56px - #table-combo-template .combo-dataview{ .combo-template(60px); -} \ No newline at end of file +} + +.pivot-check-listview { + background-color: #fff; + width: 100%; + height: 250px; + + .item { + padding-right: 3px; + } + + .list-item { + width: 146px; + margin-left:20px; + display: inline-block; + white-space: pre; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: middle; + } + + .listitem-icon { + vertical-align: middle; + width: 16px; + height: 16px; + background-position: -1px -274px; + display: inline-block; + } +} + +.pivot-listview { + background-color: #fff; + width: 95px; + height: 130px; + + .item { + padding: 3px; + } + + .list-item > div:nth-child(1) { + width:70px; + padding-right: 5px; + display: inline-block; + white-space: pre; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: middle; + } + + .listitem-icon { + vertical-align: middle; + width: 16px; + height: 16px; + background-position: -1px -274px; + display: inline-block; + } +}