diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js index ee1428a8b..f70d1565f 100644 --- a/apps/api/documents/api.js +++ b/apps/api/documents/api.js @@ -109,7 +109,8 @@ goback: { url: 'http://...', text: 'Go to London', - blank: true + blank: true, + requestClose: false // if true - goback send onRequestClose event instead opening url }, chat: true, comments: true, @@ -207,6 +208,7 @@ _config.editorConfig.canRequestSaveAs = _config.events && !!_config.events.onRequestSaveAs; _config.editorConfig.canRequestInsertImage = _config.events && !!_config.events.onRequestInsertImage; _config.editorConfig.canRequestMailMergeRecipients = _config.events && !!_config.events.onRequestMailMergeRecipients; + _config.editorConfig.canRequestCompareFile = _config.events && !!_config.events.onRequestCompareFile; _config.frameEditorId = placeholderId; var onMouseUp = function (evt) { @@ -576,6 +578,13 @@ }); }; + var _setRevisedFile = function(data) { + _sendCommand({ + command: 'setRevisedFile', + data: data + }); + }; + var _processMouse = function(evt) { var r = iframe.getBoundingClientRect(); var data = { @@ -620,7 +629,8 @@ showSharingSettings : _showSharingSettings, setSharingSettings : _setSharingSettings, insertImage : _insertImage, - setMailMergeRecipients: _setMailMergeRecipients + setMailMergeRecipients: _setMailMergeRecipients, + setRevisedFile : _setRevisedFile } }; @@ -782,7 +792,14 @@ if (config.frameEditorId) params += "&frameEditorId=" + config.frameEditorId; - + + if (config.editorConfig && config.editorConfig.mode == 'view' || + config.document && config.document.permissions && (config.document.permissions.edit === false && !config.document.permissions.review )) + params += "&mode=view"; + + if (config.editorConfig && config.editorConfig.customization && !!config.editorConfig.customization.compactHeader) + params += "&compact=true"; + return params; } diff --git a/apps/common/Gateway.js b/apps/common/Gateway.js index b8e90ebad..6d45aa3a7 100644 --- a/apps/common/Gateway.js +++ b/apps/common/Gateway.js @@ -118,6 +118,10 @@ if (Common === undefined) { 'setMailMergeRecipients': function(data) { $me.trigger('setmailmergerecipients', data); + }, + + 'setRevisedFile': function(data) { + $me.trigger('setrevisedfile', data); } }; @@ -308,6 +312,10 @@ if (Common === undefined) { _postMessage({event:'onRequestMailMergeRecipients'}) }, + requestCompareFile: function () { + _postMessage({event:'onRequestCompareFile'}) + }, + on: function(event, handler){ var localHandler = function(event, data){ handler.call(me, data) diff --git a/apps/common/main/lib/component/Calendar.js b/apps/common/main/lib/component/Calendar.js new file mode 100644 index 000000000..71b282a13 --- /dev/null +++ b/apps/common/main/lib/component/Calendar.js @@ -0,0 +1,491 @@ +/* + * + * (c) Copyright Ascensio System SIA 2010-2019 + * + * 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 + * +*/ +if (Common === undefined) + var Common = {}; + +define([ + 'common/main/lib/component/BaseView', + 'common/main/lib/util/utils' +], function () { + 'use strict'; + + Common.UI.Calendar = Common.UI.BaseView.extend(_.extend({ + + template : + _.template([ + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
' + ].join('')), + + options: { + date: undefined, + firstday: 0 // 0 - sunday, 1 - monday + }, + + initialize : function(options) { + Common.UI.BaseView.prototype.initialize.call(this, options); + + var me = this; + + this.monthNames = [this.textJanuary, this.textFebruary, this.textMarch, this.textApril, this.textMay, this.textJune, this.textJuly, this.textAugust, this.textSeptember, this.textOctober, this.textNovember, this.textDecember]; + this.dayNamesShort = [this.textShortSunday, this.textShortMonday, this.textShortTuesday, this.textShortWednesday, this.textShortThursday, this.textShortFriday, this.textShortSaturday]; + this.monthShortNames = [this.textShortJanuary, this.textShortFebruary, this.textShortMarch, this.textShortApril, this.textShortMay, this.textShortJune, this.textShortJuly, this.textShortAugust, this.textShortSeptember, this.textShortOctober, this.textShortNovember, this.textShortDecember]; + + me.options.date = options.date; + if (!_.isUndefined(options.firstday) && (options.firstday === 0 || options.firstday === 1)) { + me.options.firstday = options.firstday; + } + + me.enableKeyEvents= me.options.enableKeyEvents; + + me._state = undefined; // 0 - month, 1 - months, 2 - years + + me.render(); + }, + + render: function () { + var me = this; + me.cmpEl = me.$el || $(this.el); + me.cmpEl.html(this.template()); + + me.currentDate = me.options.date || new Date(); + + me.btnPrev = new Common.UI.Button({ + cls: '', + iconCls: 'arrow-prev img-commonctrl' + }); + me.btnPrev.render(me.cmpEl.find('#prev-arrow')); + me.btnPrev.on('click', _.bind(me.onClickPrev, me)); + + me.btnNext = new Common.UI.Button({ + cls: '', + iconCls: 'arrow-next img-commonctrl' + }); + me.btnNext.render(me.cmpEl.find('#next-arrow')); + me.btnNext.on('click', _.bind(me.onClickNext, me)); + + me.cmpEl.on('keydown', function(e) { + me.trigger('calendar:keydown', me, e); + }); + + me.renderMonth(me.currentDate); + + this.trigger('render:after', this); + return this; + }, + + onClickPrev: function () { + var me = this; + if (me._state === 0) { + var d = new Date(me.currentDate); + d.setMonth(d.getMonth() - 1); + if (d.getFullYear() > 0) { + me.renderMonth(d); + } + } else if (me._state === 1) { + var d = new Date(me.currentDate); + d.setFullYear(d.getFullYear() - 1); + if (d.getFullYear() > 0) { + me.renderMonths(d); + } + } else if (me._state === 2) { + var year = me.currentDate.getFullYear(), + newYear; + if (year % 10 !== 0) { + newYear = String(year); + newYear = Number(newYear.slice(0, -1) + '0') - 1; + } else { + newYear = year - 1; + } + if (newYear > 0) { + me.currentDate.setFullYear(newYear); + me.renderYears(newYear); + } + } + }, + + onClickNext: function () { + var me = this; + if (me._state === 0) { + var d = new Date(me.currentDate); + d.setMonth(d.getMonth() + 1); + if (d.getFullYear() > 0) { + me.renderMonth(d); + } + } else if (me._state === 1) { + var d = new Date(me.currentDate); + d.setFullYear(d.getFullYear() + 1); + if (d.getFullYear() > 0) { + me.renderMonths(d); + } + } else if (me._state === 2) { + var year = me.currentDate.getFullYear(), + newYear; + if (year % 10 !== 9) { + newYear = String(year); + newYear = Number(newYear.slice(0, -1) + '9') + 1; + } else { + newYear = year + 1; + } + if (newYear > 0) { + me.currentDate.setFullYear(newYear); + me.renderYears(newYear); + } + } + }, + + renderYears: function (year) { + var me = this, + year = _.isNumber(year) ? year : (me.currentDate ? me.currentDate.getFullYear() : new Date().getFullYear()); + + me._state = 2; + + var firstYear = year, + lastYear = year; + if ((firstYear % 10) !== 0) { + var strYear = String(year); + firstYear = Number(strYear.slice(0, -1) + '0'); + } + if ((lastYear % 10) !== 9) { + var strYear = String(year); + lastYear = Number(strYear.slice(0, -1) + '9'); + } + + me.topTitle = _.template([ + '' + ].join('')); + me.cmpEl.find('.calendar-header .title').html(me.topTitle); + + me.bottomTitle = _.template([ + '' + ].join('')); + me.cmpEl.find('.calendar-header .bottom-row').html(me.bottomTitle); + + var arrYears = []; + var tmpYear = firstYear - 3; + + for (var i = 0; i < 16; i++) { + arrYears.push({ + year: (tmpYear > 0) ? tmpYear : '', + isCurrentDecade: ((tmpYear >= firstYear) && (tmpYear <= lastYear)) ? true : false, + disabled: (tmpYear > 0) ? false : true, + selected: (_.isDate(me.selectedDate)) ? + (tmpYear === me.selectedDate.getFullYear()) : + (tmpYear === new Date().getFullYear()) + }); + tmpYear++; + } + + if (!me.yearPicker) { + me.yearPicker = new Common.UI.DataView({ + el: me.cmpEl.find('.calendar-content'), + store: new Common.UI.DataViewStore(arrYears), + itemTemplate: _.template('
<%= year %>
') + }); + me.yearPicker.on('item:click', function (picker, item, record, e) { + var year = record.get('year'), + date = new Date(); + date.setFullYear(year); + me.renderMonths(date); + }); + me.enableKeyEvents && this.yearPicker.on('item:keydown', function(view, record, e) { + if (e.keyCode==Common.UI.Keys.ESC) { + Common.NotificationCenter.trigger('dataview:blur'); + } + }); + } else + me.yearPicker.store.reset(arrYears); + + me.enableKeyEvents && _.delay(function() { + me.monthPicker.cmpEl.find('.dataview').focus(); + }, 10); + }, + + renderMonths: function (date) { + var me = this, + curDate = (_.isDate(date)) ? date : (me.currentDate ? me.currentDate : new Date()), + year = curDate.getFullYear(); + + me._state = 1; + me.currentDate = curDate; + + // Number of year + me.topTitle = _.template([ + '
' + ].join('')); + me.cmpEl.find('.calendar-header .title').html(me.topTitle); + me.cmpEl.find('.calendar-header .title').off(); + me.cmpEl.find('.calendar-header .title').on('click', _.bind(me.renderYears, me)); + + me.bottomTitle = _.template([ + '' + ].join('')); + me.cmpEl.find('.calendar-header .bottom-row').html(me.bottomTitle); + + var arrMonths = []; + var today = new Date(); + + for (var ind = 0; ind < 12; ind++) { + arrMonths.push({ + indexMonth: ind, + nameMonth: me.monthShortNames[ind], + year: year, + curYear: true, + isCurrentMonth: (ind === curDate.getMonth()), + selected: (_.isDate(me.selectedDate)) ? + (ind === me.selectedDate.getMonth() && year === me.selectedDate.getFullYear()) : + (ind === today.getMonth() && year === today.getFullYear()) + }); + } + year = year + 1; + for (var ind = 0; ind < 4; ind++) { + arrMonths.push({ + indexMonth: ind, + nameMonth: me.monthShortNames[ind], + year: year, + curYear: false, + selected: (_.isDate(me.selectedDate)) ? + (ind === me.selectedDate.getMonth() && year === me.selectedDate.getFullYear()) : + (ind === today.getMonth() && year === today.getFullYear()) + }); + } + + if (!me.monthsPicker) { + me.monthsPicker = new Common.UI.DataView({ + el: me.cmpEl.find('.calendar-content'), + store: new Common.UI.DataViewStore(arrMonths), + itemTemplate: _.template('
<%= nameMonth %>
') + }); + me.monthsPicker.on('item:click', function (picker, item, record, e) { + var month = record.get('indexMonth'), + year = record.get('year'), + date = new Date(); + date.setFullYear(year, month); + me.renderMonth(date); + }); + me.enableKeyEvents && this.monthsPicker.on('item:keydown', function(view, record, e) { + if (e.keyCode==Common.UI.Keys.ESC) { + Common.NotificationCenter.trigger('dataview:blur'); + } + }); + } else + me.monthsPicker.store.reset(arrMonths); + + me.enableKeyEvents && _.delay(function() { + me.monthPicker.cmpEl.find('.dataview').focus(); + }, 10); + }, + + renderMonth: function (date) { + var me = this; + me._state = 0; + var firstDay = me.options.firstday; + + // Current date + var curDate = date || new Date(), + curMonth = curDate.getMonth(), + curIndexDayInWeek = curDate.getDay(), + curNumberDayInMonth = curDate.getDate(), + curYear = curDate.getFullYear(); + + me.currentDate = curDate; + + // Name month + me.topTitle = _.template([ + '
', + '', + '
' + ].join('')); + me.cmpEl.find('.calendar-header .title').html(me.topTitle); + me.cmpEl.find('.calendar-header .title').off(); + me.cmpEl.find('.calendar-header .title').on('click', _.bind(me.renderMonths, me)); + + // Name days of week + var dayNamesTemplate = ''; + for (var i = firstDay; i < 7; i++) { + dayNamesTemplate += ''; + } + if (firstDay > 0) { + dayNamesTemplate += ''; + } + me.cmpEl.find('.calendar-header .bottom-row').html(_.template(dayNamesTemplate)); + + // Month + var rows = 6, + cols = 7; + + var arrDays = []; + + var d = new Date(curDate); + d.setDate(1); + var firstDayOfMonthIndex = d.getDay(); + + var daysInPrevMonth = me.daysInMonth(d.getTime() - (10 * 24 * 60 * 60 * 1000)), + numberDay, + month, + year; + if (firstDay === 0) { + numberDay = (firstDayOfMonthIndex > 0) ? (daysInPrevMonth - (firstDayOfMonthIndex - 1)) : 1; + } else { + if (firstDayOfMonthIndex === 0) { + numberDay = daysInPrevMonth - 5; + } else { + numberDay = daysInPrevMonth - (firstDayOfMonthIndex - 2); + } + } + if ((firstDayOfMonthIndex > 0 && firstDay === 0) || firstDay === 1) { + if (curMonth - 1 >= 0) { + month = curMonth - 1; + year = curYear; + } else { + month = 11; + year = curYear - 1; + } + } else { + month = curMonth; + year = curYear; + } + + var tmp = new Date(); + tmp.setFullYear(year, month, numberDay); + var today = new Date(); + + for(var r = 0; r < rows; r++) { + for(var c = 0; c < cols; c++) { + var tmpDay = tmp.getDay(), + tmpNumber = tmp.getDate(), + tmpMonth = tmp.getMonth(), + tmpYear = tmp.getFullYear(); + arrDays.push({ + indexInWeek: tmpDay, + dayNumber: tmpNumber, + month: tmpMonth, + year: tmpYear, + isCurrentMonth: tmpMonth === curMonth, + selected: (_.isDate(me.selectedDate)) ? + (tmpNumber === me.selectedDate.getDate() && tmpMonth === me.selectedDate.getMonth() && tmpYear === me.selectedDate.getFullYear()) : + (tmpNumber === today.getDate() && tmpMonth === today.getMonth() && tmpYear === today.getFullYear()) + }); + tmp.setDate(tmpNumber + 1); + } + } + + if (!me.monthPicker) { + me.monthPicker = new Common.UI.DataView({ + el: me.cmpEl.find('.calendar-content'), + store: new Common.UI.DataViewStore(arrDays), + itemTemplate: _.template('
<%= dayNumber %>
') + }); + me.monthPicker.on('item:click', function(picker, item, record, e) { + var day = record.get('dayNumber'), + month = record.get('month'), + year = record.get('year'); + if (_.isUndefined(me.selectedDate)) { + me.selectedDate = new Date(); + } + me.selectedDate.setFullYear(year, month, day); + me.trigger('date:click', me, me.selectedDate); + }); + me.enableKeyEvents && this.monthPicker.on('item:keydown', function(view, record, e) { + if (e.keyCode==Common.UI.Keys.ESC) { + Common.NotificationCenter.trigger('dataview:blur'); + } + }); + } else + me.monthPicker.store.reset(arrDays); + + me.enableKeyEvents && _.delay(function() { + me.monthPicker.cmpEl.find('.dataview').focus(); + }, 10); + }, + + daysInMonth: function (date) { + var d; + d = date ? new Date(date) : new Date(); + var result = new Date(); + result.setFullYear(d.getFullYear(), d.getMonth() + 1, 0); + return result.getDate(); + }, + + setDate: function (date) { + if (_.isDate(date)) { + this.selectedDate = new Date(date); + this.renderMonth(this.selectedDate); + } + }, + + textJanuary: 'January', + textFebruary: 'February', + textMarch: 'March', + textApril: 'April', + textMay: 'May', + textJune: 'June', + textJuly: 'July', + textAugust: 'August', + textSeptember: 'September', + textOctober: 'October', + textNovember: 'November', + textDecember: 'December', + textShortJanuary: 'Jan', + textShortFebruary: 'Feb', + textShortMarch: 'Mar', + textShortApril: 'Apr', + textShortMay: 'May', + textShortJune: 'Jun', + textShortJuly: 'Jul', + textShortAugust: 'Aug', + textShortSeptember: 'Sep', + textShortOctober: 'Oct', + textShortNovember: 'Nov', + textShortDecember: 'Dec', + textShortSunday: 'Su', + textShortMonday: 'Mo', + textShortTuesday: 'Tu', + textShortWednesday: 'We', + textShortThursday: 'Th', + textShortFriday: 'Fr', + textShortSaturday: 'Sa', + textMonths: 'Months', + textYears: 'Years' + }, Common.UI.Calendar || {})); +}); \ No newline at end of file diff --git a/apps/common/main/lib/component/ComboBox.js b/apps/common/main/lib/component/ComboBox.js index 7da1a35b5..a243b9895 100644 --- a/apps/common/main/lib/component/ComboBox.js +++ b/apps/common/main/lib/component/ComboBox.js @@ -348,6 +348,8 @@ define([ this.onAfterHideMenu(e); return false; } else if (this.search && e.keyCode > 64 && e.keyCode < 91 && e.key){ + if (typeof this._search !== 'object') return; + var me = this; clearTimeout(this._search.timer); this._search.timer = setTimeout(function () { me._search = {}; }, 1000); diff --git a/apps/common/main/lib/component/DimensionPicker.js b/apps/common/main/lib/component/DimensionPicker.js index dab30a9d2..c508a90e9 100644 --- a/apps/common/main/lib/component/DimensionPicker.js +++ b/apps/common/main/lib/component/DimensionPicker.js @@ -47,31 +47,6 @@ define([ 'use strict'; Common.UI.DimensionPicker = Common.UI.BaseView.extend((function(){ - var me, - rootEl, - areaMouseCatcher, - areaUnHighLighted, - areaHighLighted, - areaStatus, - curColumns = 0, - curRows = 0; - - var onMouseMove = function(event){ - me.setTableSize( - Math.ceil((event.offsetX === undefined ? event.originalEvent.layerX : event.offsetX*Common.Utils.zoom()) / me.itemSize), - Math.ceil((event.offsetY === undefined ? event.originalEvent.layerY : event.offsetY*Common.Utils.zoom()) / me.itemSize), - event - ); - }; - - var onMouseLeave = function(event){ - me.setTableSize(0, 0, event); - }; - - var onHighLightedMouseClick = function(e){ - me.trigger('select', me, curColumns, curRows, e); - }; - return { options: { itemSize : 18, @@ -95,9 +70,13 @@ define([ initialize : function(options) { Common.UI.BaseView.prototype.initialize.call(this, options); - me = this; + var me = this; - rootEl = me.$el || $(this.el); + this.render(); + + this.cmpEl = me.$el || $(this.el); + + var rootEl = this.cmpEl; me.itemSize = me.options.itemSize; me.minRows = me.options.minRows; @@ -105,31 +84,48 @@ define([ me.maxRows = me.options.maxRows; me.maxColumns = me.options.maxColumns; - this.render(); + me.curColumns = 0; + me.curRows = 0; + + var onMouseMove = function(event){ + me.setTableSize( + Math.ceil((event.offsetX === undefined ? event.originalEvent.layerX : event.offsetX*Common.Utils.zoom()) / me.itemSize), + Math.ceil((event.offsetY === undefined ? event.originalEvent.layerY : event.offsetY*Common.Utils.zoom()) / me.itemSize), + event + ); + }; + + var onMouseLeave = function(event){ + me.setTableSize(0, 0, event); + }; + + var onHighLightedMouseClick = function(e){ + me.trigger('select', me, me.curColumns, me.curRows, e); + }; if (rootEl){ - areaMouseCatcher = rootEl.find('.dimension-picker-mousecatcher'); - areaUnHighLighted = rootEl.find('.dimension-picker-unhighlighted'); - areaHighLighted = rootEl.find('.dimension-picker-highlighted'); - areaStatus = rootEl.find('.dimension-picker-status'); + var areaMouseCatcher = rootEl.find('.dimension-picker-mousecatcher'); + me.areaUnHighLighted = rootEl.find('.dimension-picker-unhighlighted'); + me.areaHighLighted = rootEl.find('.dimension-picker-highlighted'); + me.areaStatus = rootEl.find('.dimension-picker-status'); rootEl.css({width: me.minColumns + 'em'}); areaMouseCatcher.css('z-index', 1); areaMouseCatcher.width(me.maxColumns + 'em').height(me.maxRows + 'em'); - areaUnHighLighted.width(me.minColumns + 'em').height(me.minRows + 'em'); - areaStatus.html(curColumns + ' x ' + curRows); - areaStatus.width(areaUnHighLighted.width()); - } + me.areaUnHighLighted.width(me.minColumns + 'em').height(me.minRows + 'em'); + me.areaStatus.html(me.curColumns + ' x ' + me.curRows); + me.areaStatus.width(me.areaUnHighLighted.width()); - areaMouseCatcher.on('mousemove', onMouseMove); - areaHighLighted.on('mousemove', onMouseMove); - areaUnHighLighted.on('mousemove', onMouseMove); - areaMouseCatcher.on('mouseleave', onMouseLeave); - areaHighLighted.on('mouseleave', onMouseLeave); - areaUnHighLighted.on('mouseleave', onMouseLeave); - areaMouseCatcher.on('click', onHighLightedMouseClick); - areaHighLighted.on('click', onHighLightedMouseClick); - areaUnHighLighted.on('click', onHighLightedMouseClick); + areaMouseCatcher.on('mousemove', onMouseMove); + me.areaHighLighted.on('mousemove', onMouseMove); + me.areaUnHighLighted.on('mousemove', onMouseMove); + areaMouseCatcher.on('mouseleave', onMouseLeave); + me.areaHighLighted.on('mouseleave', onMouseLeave); + me.areaUnHighLighted.on('mouseleave', onMouseLeave); + areaMouseCatcher.on('click', onHighLightedMouseClick); + me.areaHighLighted.on('click', onHighLightedMouseClick); + me.areaUnHighLighted.on('click', onHighLightedMouseClick); + } }, render: function() { @@ -142,38 +138,38 @@ define([ if (columns > this.maxColumns) columns = this.maxColumns; if (rows > this.maxRows) rows = this.maxRows; - if (curColumns != columns || curRows != rows){ - curColumns = columns; - curRows = rows; + if (this.curColumns != columns || this.curRows != rows){ + this.curColumns = columns; + this.curRows = rows; - areaHighLighted.width(curColumns + 'em').height(curRows + 'em'); - areaUnHighLighted.width( - ((curColumns < me.minColumns) - ? me.minColumns - : ((curColumns + 1 > me.maxColumns) - ? me.maxColumns - : curColumns + 1)) + 'em' - ).height(((curRows < me.minRows) - ? me.minRows - : ((curRows + 1 > me.maxRows) - ? me.maxRows - : curRows + 1)) + 'em' + this.areaHighLighted.width(this.curColumns + 'em').height(this.curRows + 'em'); + this.areaUnHighLighted.width( + ((this.curColumns < this.minColumns) + ? this.minColumns + : ((this.curColumns + 1 > this.maxColumns) + ? this.maxColumns + : this.curColumns + 1)) + 'em' + ).height(((this.curRows < this.minRows) + ? this.minRows + : ((this.curRows + 1 > this.maxRows) + ? this.maxRows + : this.curRows + 1)) + 'em' ); - rootEl.width(areaUnHighLighted.width()); - areaStatus.html(curColumns + ' x ' + curRows); - areaStatus.width(areaUnHighLighted.width()); + this.cmpEl.width(this.areaUnHighLighted.width()); + this.areaStatus.html(this.curColumns + ' x ' + this.curRows); + this.areaStatus.width(this.areaUnHighLighted.width()); - me.trigger('change', me, curColumns, curRows, event); + this.trigger('change', this, this.curColumns, this.curRows, event); } }, getColumnsCount: function() { - return curColumns; + return this.curColumns; }, getRowsCount: function() { - return curRows; + return this.curRows; } } })()) diff --git a/apps/common/main/lib/component/Tab.js b/apps/common/main/lib/component/Tab.js index b3b5644ef..108672047 100644 --- a/apps/common/main/lib/component/Tab.js +++ b/apps/common/main/lib/component/Tab.js @@ -52,7 +52,7 @@ define([ this.label = 'Tab'; this.cls = ''; this.template = _.template(['
  • ', - '<%- label %>', + '<%- label %>', '
  • '].join('')); this.initialize.call(this, opts); diff --git a/apps/common/main/lib/controller/ReviewChanges.js b/apps/common/main/lib/controller/ReviewChanges.js index 52901cea5..3be1d3449 100644 --- a/apps/common/main/lib/controller/ReviewChanges.js +++ b/apps/common/main/lib/controller/ReviewChanges.js @@ -78,7 +78,8 @@ define([ 'reviewchange:reject': _.bind(this.onRejectClick, this), 'reviewchange:delete': _.bind(this.onDeleteClick, this), 'reviewchange:preview': _.bind(this.onBtnPreviewClick, this), - 'reviewchanges:view': _.bind(this.onReviewViewClick, this), + 'reviewchange:view': _.bind(this.onReviewViewClick, this), + 'reviewchange:compare': _.bind(this.onCompareClick, this), 'lang:document': _.bind(this.onDocLanguage, this), 'collaboration:coauthmode': _.bind(this.onCoAuthMode, this) }, @@ -99,7 +100,7 @@ define([ this.collection = this.getApplication().getCollection('Common.Collections.ReviewChanges'); this.userCollection = this.getApplication().getCollection('Common.Collections.Users'); - this._state = {posx: -1000, posy: -1000, popoverVisible: false, previewMode: false}; + this._state = {posx: -1000, posy: -1000, popoverVisible: false, previewMode: false, compareSettings: null /*new AscCommon.CComparisonPr()*/}; Common.NotificationCenter.on('reviewchanges:turn', this.onTurnPreview.bind(this)); Common.NotificationCenter.on('spelling:turn', this.onTurnSpelling.bind(this)); @@ -127,8 +128,13 @@ define([ if (this.appConfig.canReview || this.appConfig.canViewReview) { this.api.asc_registerCallback('asc_onShowRevisionsChange', _.bind(this.onApiShowChange, this)); this.api.asc_registerCallback('asc_onUpdateRevisionsChangesPosition', _.bind(this.onApiUpdateChangePosition, this)); + this.api.asc_registerCallback('asc_onAuthParticipantsChanged', _.bind(this.onAuthParticipantsChanged, this)); + this.api.asc_registerCallback('asc_onParticipantsChanged', _.bind(this.onAuthParticipantsChanged, this)); } + this.api.asc_registerCallback('asc_onAcceptChangesBeforeCompare',_.bind(this.onAcceptChangesBeforeCompare, this)); this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.onCoAuthoringDisconnect, this)); + + Common.Gateway.on('setrevisedfile', _.bind(this.setRevisedFile, this)); } }, @@ -568,6 +574,84 @@ define([ Common.NotificationCenter.trigger('edit:complete', this.view); }, + onCompareClick: function(item) { + if (this.api) { + var me = this; + if (!this._state.compareSettings) { + this._state.compareSettings = new AscCommonWord.ComparisonOptions(); + this._state.compareSettings.putWords(!Common.localStorage.getBool("de-compare-char")); + } + if (item === 'file') { + if (this.api) + this.api.asc_CompareDocumentFile(this._state.compareSettings); + Common.NotificationCenter.trigger('edit:complete', this.view); + } else if (item === 'url') { + (new Common.Views.ImageFromUrlDialog({ + title: me.textUrl, + handler: function(result, value) { + if (result == 'ok') { + if (me.api) { + var checkUrl = value.replace(/ /g, ''); + if (!_.isEmpty(checkUrl)) { + me.api.asc_CompareDocumentUrl(checkUrl, me._state.compareSettings); + } + } + Common.NotificationCenter.trigger('edit:complete', me.view); + } + } + })).show(); + } else if (item === 'storage') { + if (this.appConfig.canRequestCompareFile) { + Common.Gateway.requestCompareFile(); + } else { + (new Common.Views.SelectFileDlg({ + fileChoiceUrl: this.appConfig.fileChoiceUrl.replace("{fileExt}", "").replace("{documentType}", "DocumentsOnly") + })).on('selectfile', function(obj, file){ + me.setRevisedFile(file, me._state.compareSettings); + }).show(); + } + } else if (item === 'settings') { + (new DE.Views.CompareSettingsDialog({ + props: me._state.compareSettings, + handler: function(result, value) { + if (result == 'ok') { + me._state.compareSettings = value; + } + + Common.NotificationCenter.trigger('edit:complete', me.toolbar); + } + })).show(); + } + } + Common.NotificationCenter.trigger('edit:complete', this.view); + }, + + setRevisedFile: function(data) { + if (!this._state.compareSettings) { + this._state.compareSettings = new AscCommonWord.ComparisonOptions(); + this._state.compareSettings.putWords(!Common.localStorage.getBool("de-compare-char")); + } + if (data && data.url) { + this.api.asc_CompareDocumentUrl(data.url, this._state.compareSettings, data.token);// for loading from storage + } + }, + + onAcceptChangesBeforeCompare: function(callback) { + var me = this; + Common.UI.warning({ + width: 550, + msg: this.textAcceptBeforeCompare, + buttons: ['yes', 'no'], + primary: 'yes', + callback: function(result) { + _.defer(function() { + if (callback) callback(result=='yes'); + }); + Common.NotificationCenter.trigger('edit:complete', this.view); + } + }); + }, + turnDisplayMode: function(mode) { if (this.api) { if (mode === 'final') @@ -780,6 +864,17 @@ define([ }); }, + onAuthParticipantsChanged: function(users) { + if (this.view && this.view.btnCompare) { + var length = 0; + _.each(users, function(item){ + if (!item.asc_getView()) + length++; + }); + this.view.btnCompare.setDisabled(length>1 || this.viewmode); + } + }, + commentsShowHide: function(mode) { if (!this.view) return; var value = Common.Utils.InternalSettings.get(this.view.appPrefix + "settings-livecomment"); @@ -844,6 +939,8 @@ define([ textTableRowsDel: 'Table Rows Deleted', textParaMoveTo: 'Moved:', textParaMoveFromUp: 'Moved Up:', - textParaMoveFromDown: 'Moved Down:' + textParaMoveFromDown: 'Moved Down:', + textUrl: 'Paste a document URL', + textAcceptBeforeCompare: 'In order to compare documents all the tracked changes in them will be considered to have been accepted. Do you want to continue?' }, Common.Controllers.ReviewChanges || {})); }); \ No newline at end of file diff --git a/apps/common/main/lib/view/ExternalDiagramEditor.js b/apps/common/main/lib/view/ExternalDiagramEditor.js index c5f26a44c..280f002a5 100644 --- a/apps/common/main/lib/view/ExternalDiagramEditor.js +++ b/apps/common/main/lib/view/ExternalDiagramEditor.js @@ -88,6 +88,11 @@ define([ this.$window.find('.dlg-btn').on('click', _.bind(this.onDlgBtnClick, this)); }, + show: function() { + this.setPlaceholder(); + Common.UI.Window.prototype.show.apply(this, arguments); + }, + setChartData: function(data) { this._chartData = data; if (this._isExternalDocReady) @@ -143,6 +148,14 @@ define([ } }, + setPlaceholder: function(placeholder) { + this._placeholder = placeholder; + }, + + getPlaceholder: function() { + return this._placeholder; + }, + textSave: 'Save & Exit', textClose: 'Close', textTitle: 'Chart Editor' diff --git a/apps/common/main/lib/view/ImageFromUrlDialog.js b/apps/common/main/lib/view/ImageFromUrlDialog.js index beffb0fc8..0287417f0 100644 --- a/apps/common/main/lib/view/ImageFromUrlDialog.js +++ b/apps/common/main/lib/view/ImageFromUrlDialog.js @@ -56,7 +56,7 @@ define([ this.template = [ '
    ', '
    ', - '', + '', '
    ', '
    ', '
    ' diff --git a/apps/common/main/lib/view/InsertTableDialog.js b/apps/common/main/lib/view/InsertTableDialog.js index b4b65d017..a9d1e8501 100644 --- a/apps/common/main/lib/view/InsertTableDialog.js +++ b/apps/common/main/lib/view/InsertTableDialog.js @@ -110,8 +110,8 @@ define([ onBtnClick: function(event) { if (this.options.handler) { this.options.handler.call(this, event.currentTarget.attributes['result'].value, { - columns : this.udColumns.getValue(), - rows : this.udRows.getValue() + columns : this.udColumns.getNumberValue(), + rows : this.udRows.getNumberValue() }); } @@ -121,8 +121,8 @@ define([ onPrimary: function() { if (this.options.handler) { this.options.handler.call(this, 'ok', { - columns : this.udColumns.getValue(), - rows : this.udRows.getValue() + columns : this.udColumns.getNumberValue(), + rows : this.udRows.getNumberValue() }); } diff --git a/apps/common/main/lib/view/ListSettingsDialog.js b/apps/common/main/lib/view/ListSettingsDialog.js index e0820cd4d..8f783c8d0 100644 --- a/apps/common/main/lib/view/ListSettingsDialog.js +++ b/apps/common/main/lib/view/ListSettingsDialog.js @@ -46,15 +46,16 @@ define([ 'common/main/lib/component/Window', 'common/main/lib/component/MetricSpinner', 'common/main/lib/component/ThemeColorPalette', - 'common/main/lib/component/ColorButton' + 'common/main/lib/component/ColorButton', + 'common/main/lib/view/SymbolTableDialog' ], function () { 'use strict'; Common.Views.ListSettingsDialog = Common.UI.Window.extend(_.extend({ options: { type: 0, // 0 - markers, 1 - numbers width: 230, - height: 156, - style: 'min-width: 230px;', + height: 200, + style: 'min-width: 240px;', cls: 'modal-dlg', split: false, buttons: ['ok', 'cancel'] @@ -64,20 +65,25 @@ define([ this.type = options.type || 0; _.extend(this.options, { - title: this.txtTitle, - height: this.type==1 ? 190 : 156 + title: this.txtTitle }, options || {}); this.template = [ '
    ', - '
    ', + '
    ', '
    ', '
    ', - '
    ', + '
    ', '
    ', '
    ', + '<% if (type == 0) { %>', + '
    ', + '', + '', + '
    ', + '<% } %>', '<% if (type == 1) { %>', - '
    ', + '
    ', '
    ', '
    ', '<% } %>', @@ -163,6 +169,13 @@ define([ } }); + this.btnEdit = new Common.UI.Button({ + el: $window.find('#id-dlg-list-edit'), + hint: this.tipChange + }); + this.btnEdit.on('click', _.bind(this.onEditBullet, this)); + this.btnEdit.cmpEl.css({'font-size': '12px'}); + this.afterRender(); }, @@ -186,6 +199,36 @@ define([ } }, + onEditBullet: function() { + var me = this, + props = me.bulletProps, + handler = function(dlg, result, settings) { + if (result == 'ok') { + props.changed = true; + props.code = settings.code; + props.font = settings.font; + props.symbol = settings.symbol; + props.font && me.btnEdit.cmpEl.css('font-family', props.font); + settings.symbol && me.btnEdit.setCaption(settings.symbol); + if (me._changedProps) { + me._changedProps.asc_putBulletFont(props.font); + me._changedProps.asc_putBulletSymbol(props.symbol); + } + } + }, + win = new Common.Views.SymbolTableDialog({ + api: me.options.api, + lang: me.options.interfaceLang, + modal: true, + type: 0, + font: props.font, + symbol: props.symbol, + handler: handler + }); + win.show(); + win.on('symbol:dblclick', handler); + }, + _handleInput: function(state) { if (this.options.handler) { this.options.handler.call(this, state, this._changedProps); @@ -228,6 +271,12 @@ define([ if (!isselected) this.colors.clearSelection(); } else this.colors.select(color,true); + + if (this.type==0) { + this.bulletProps = {symbol: props.asc_getBulletSymbol(), font: props.asc_getBulletFont()}; + this.bulletProps.font && this.btnEdit.cmpEl.css('font-family', this.bulletProps.font); + this.bulletProps.symbol && this.btnEdit.setCaption(this.bulletProps.symbol); + } } this._changedProps = new Asc.asc_CParagraphProperty(); }, @@ -237,6 +286,8 @@ define([ txtColor: 'Color', txtOfText: '% of text', textNewColor: 'Add New Custom Color', - txtStart: 'Start at' + txtStart: 'Start at', + txtBullet: 'Bullet', + tipChange: 'Change bullet' }, Common.Views.ListSettingsDialog || {})) }); \ No newline at end of file diff --git a/apps/common/main/lib/view/ReviewChanges.js b/apps/common/main/lib/view/ReviewChanges.js index f24941211..b8943753d 100644 --- a/apps/common/main/lib/view/ReviewChanges.js +++ b/apps/common/main/lib/view/ReviewChanges.js @@ -80,6 +80,10 @@ define([ '' + '
    ' + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + '
    ' + '' + '
    ' + @@ -116,6 +120,16 @@ define([ me.fireEvent('reviewchange:reject', [menu, item]); }); + if (me.appConfig.canFeatureComparison) { + this.btnCompare.on('click', function (e) { + me.fireEvent('reviewchange:compare', ['file']); + }); + + this.btnCompare.menu.on('item:click', function (menu, item, e) { + me.fireEvent('reviewchange:compare', [item.value]); + }); + } + this.btnsTurnReview.forEach(function (button) { button.on('click', _click_turnpreview.bind(me)); }); @@ -130,7 +144,7 @@ define([ }); this.btnReviewView && this.btnReviewView.menu.on('item:click', function (menu, item, e) { - me.fireEvent('reviewchanges:view', [menu, item]); + me.fireEvent('reviewchange:view', [menu, item]); }); } @@ -199,6 +213,14 @@ define([ iconCls: 'review-deny' }); + if (this.appConfig.canFeatureComparison) + this.btnCompare = new Common.UI.Button({ + cls : 'btn-toolbar x-huge icon-top', + caption : this.txtCompare, + split : true, + iconCls: 'btn-compare' + }); + this.btnTurnOn = new Common.UI.Button({ cls: 'btn-toolbar x-huge icon-top', iconCls: 'btn-ic-review', @@ -368,6 +390,20 @@ define([ ); me.btnReject.updateHint([me.tipRejectCurrent, me.txtRejectChanges]); + if (config.canFeatureComparison) { + me.btnCompare.setMenu(new Common.UI.Menu({ + items: [ + {caption: me.mniFromFile, value: 'file'}, + {caption: me.mniFromUrl, value: 'url'}, + {caption: me.mniFromStorage, value: 'storage'} + // ,{caption: '--'}, + // {caption: me.mniSettings, value: 'settings'} + ] + })); + me.btnCompare.menu.items[2].setVisible(me.appConfig.canRequestCompareFile || me.appConfig.fileChoiceUrl && me.appConfig.fileChoiceUrl.indexOf("{documentType}")>-1); + me.btnCompare.updateHint(me.tipCompare); + } + me.btnAccept.setDisabled(config.isReviewOnly); me.btnReject.setDisabled(config.isReviewOnly); } @@ -442,6 +478,7 @@ define([ var separator_sharing = !(me.btnSharing || me.btnCoAuthMode) ? me.$el.find('.separator.sharing') : '.separator.sharing', separator_comments = !(config.canComments && config.canCoAuthoring) ? me.$el.find('.separator.comments') : '.separator.comments', separator_review = !(config.canReview || config.canViewReview) ? me.$el.find('.separator.review') : '.separator.review', + separator_compare = !(config.canReview && config.canFeatureComparison) ? me.$el.find('.separator.compare') : '.separator.compare', separator_chat = !me.btnChat ? me.$el.find('.separator.chat') : '.separator.chat', separator_last; @@ -460,6 +497,11 @@ define([ else separator_last = separator_review; + if (typeof separator_compare == 'object') + separator_compare.hide().prev('.group').hide(); + else + separator_last = separator_compare; + if (typeof separator_chat == 'object') separator_chat.hide().prev('.group').hide(); else @@ -480,6 +522,7 @@ define([ if ( this.appConfig.canReview ) { this.btnAccept.render(this.$el.find('#btn-change-accept')); this.btnReject.render(this.$el.find('#btn-change-reject')); + this.appConfig.canFeatureComparison && this.btnCompare.render(this.$el.find('#btn-compare')); this.btnTurnOn.render(this.$el.find('#btn-review-on')); } this.btnPrev && this.btnPrev.render(this.$el.find('#btn-change-prev')); @@ -654,6 +697,12 @@ define([ txtOriginalCap: 'Original', strFastDesc: 'Real-time co-editing. All changes are saved automatically.', strStrictDesc: 'Use the \'Save\' button to sync the changes you and others make.', + txtCompare: 'Compare', + tipCompare: 'Compare current document with another one', + mniFromFile: 'Document from File', + mniFromUrl: 'Document from URL', + mniFromStorage: 'Document from Storage', + mniSettings: 'Comparison Settings', txtCommentRemove: 'Remove', tipCommentRemCurrent: 'Remove current comments', tipCommentRem: 'Remove comments', diff --git a/apps/common/main/lib/view/SymbolTableDialog.js b/apps/common/main/lib/view/SymbolTableDialog.js index 0e02835bd..a0e808329 100644 --- a/apps/common/main/lib/view/SymbolTableDialog.js +++ b/apps/common/main/lib/view/SymbolTableDialog.js @@ -453,6 +453,15 @@ define([ var init = (aFontSelects.length<1); init && this.initFonts(); + if (options.font) { + for(var i = 0; i < aFontSelects.length; ++i){ + if(aFontSelects[i].displayValue === options.font){ + nCurrentFont = i; + break; + } + } + } + if (nCurrentFont < 0) nCurrentFont = 0; @@ -477,6 +486,12 @@ define([ nCurrentSymbol = aRanges[0].Start; } + if (options.code) { + nCurrentSymbol = options.code; + } else if (options.symbol) { + nCurrentSymbol = this.fixedCharCodeAt(options.symbol, 0); + } + if (init && this.options.lang && this.options.lang != 'en') { var me = this; loadTranslation(this.options.lang, function(){ @@ -536,6 +551,7 @@ define([ for(i = 0; i < aFontSelects.length; ++i){ aFontSelects[i].value = i; } + if(!oFontsByName[sInitFont]){ if(oFontsByName['Cambria Math']){ sInitFont = 'Cambria Math'; diff --git a/apps/common/main/resources/less/buttons.less b/apps/common/main/resources/less/buttons.less index 3642c73af..8771a15a0 100644 --- a/apps/common/main/resources/less/buttons.less +++ b/apps/common/main/resources/less/buttons.less @@ -400,8 +400,10 @@ } } .dropdown-menu { - li.disabled { - opacity: 0.65; + &.scale-menu { + li.disabled { + opacity: 0.65; + } } } } diff --git a/apps/common/main/resources/less/calendar.less b/apps/common/main/resources/less/calendar.less new file mode 100644 index 000000000..5f0fd3c21 --- /dev/null +++ b/apps/common/main/resources/less/calendar.less @@ -0,0 +1,128 @@ +@calendar-bg-color: @tabs-bg-color; + +.calendar-window { + border-radius: 0; + box-shadow: none; +} +.calendar-box { + width: 198px; + height: 220px; + border: 1px solid @calendar-bg-color; + .top-row { + padding: 0 5px; + } + .btn { + background-color: transparent; + border: none; + height: 20px; + width: 20px; + margin-top: 4px; + display: flex; + justify-content: center; + align-items: center; + .icon { + width: 16px; + height: 16px; + display: block; + position: relative; + &.arrow-prev { + background-position: -55px -96px; + } + &.arrow-next { + background-position: -52px -112px; + } + } + &:hover { + background-color: rgba(255,255,255,0.2); + cursor: pointer; + } + } + .calendar-header { + height: 50px; + background-color: @calendar-bg-color; + color: #FFFFFF; + .top-row { + display: flex; + justify-content: space-between; + } + .bottom-row { + display: flex; + justify-content: space-around; + padding: 0; + } + .title { + width: 100%; + margin: 4px 6px 3px 6px; + text-align: center; + font-size: 13px; + label { + padding: 2px 10px 0; + display: block; + font-weight: bold; + &:not(:last-of-type) { + margin-right: 6px; + } + } + .button { + height: 100%; + width: 100%; + &:hover { + background-color: rgba(255,255,255,0.2); + cursor: pointer; + label { + cursor: pointer; + } + } + } + + } + } + .calendar-content { + .item { + margin: 0; + padding: 0; + height: auto; + width: auto; + box-shadow: none; + border: 1px solid #fff; + .name-month, .name-year { + height: 40px; + width: 47px; + background-color: #F1F1F1; + display: flex; + justify-content: center; + align-items: center; + font-size: 13px; + } + .number-day { + height: 26px; + width: 26px; + background-color: #F1F1F1; + display: flex; + justify-content: center; + align-items: center; + } + &.selected { + .number-day, .name-month, .name-year { + color: #fff; + background-color: #7D858C; + } + } + .weekend { + color: #D25252; + } + .no-current-month, .no-cur-year, .no-current-decade { + color: #A5A5A5; + } + &:not(.disabled):not(.selected) { + .number-day, .name-month, .name-year { + &:hover { + background-color: #D9D9D9; + } + } + } + + + } + } +} \ No newline at end of file diff --git a/apps/common/main/resources/less/tabbar.less b/apps/common/main/resources/less/tabbar.less index 66af233d2..f7059ca7b 100644 --- a/apps/common/main/resources/less/tabbar.less +++ b/apps/common/main/resources/less/tabbar.less @@ -27,6 +27,13 @@ padding-top: 0; padding-bottom: 0; white-space: pre-wrap; + text-align: center; + + &::after { + content: attr(title); + font-weight: bold; + display: block; + } &:hover, &:focus { background-color: #7a7a7a; diff --git a/apps/common/main/resources/less/toolbar.less b/apps/common/main/resources/less/toolbar.less index 74da8eb05..67d8f706b 100644 --- a/apps/common/main/resources/less/toolbar.less +++ b/apps/common/main/resources/less/toolbar.less @@ -533,6 +533,7 @@ .button-normal-icon(btn-caption, 76, @toolbar-big-icon-size); .button-normal-icon(btn-calculation, 80, @toolbar-big-icon-size); .button-normal-icon(btn-scale, 81, @toolbar-big-icon-size); +.button-normal-icon(btn-compare, 82, @toolbar-big-icon-size); .button-normal-icon(btn-rem-comment, 83, @toolbar-big-icon-size); .button-normal-icon(btn-symbol, 84, @toolbar-big-icon-size); diff --git a/apps/documenteditor/embed/js/ApplicationController.js b/apps/documenteditor/embed/js/ApplicationController.js index db428d1c5..877d5a0dc 100644 --- a/apps/documenteditor/embed/js/ApplicationController.js +++ b/apps/documenteditor/embed/js/ApplicationController.js @@ -75,7 +75,7 @@ DE.ApplicationController = new(function(){ $('#editor_sdk').addClass('top'); } - if (config.canBackToFolder === false || !(config.customization && config.customization.goback && config.customization.goback.url)) { + if (config.canBackToFolder === false || !(config.customization && config.customization.goback && (config.customization.goback.url || config.customization.goback.requestClose && config.canRequestClose))) { $('#id-btn-close').hide(); // Hide last separator @@ -266,8 +266,12 @@ DE.ApplicationController = new(function(){ }); $('#id-btn-close').on('click', function(){ - if (config.customization && config.customization.goback && config.customization.goback.url) - window.parent.location.href = config.customization.goback.url; + if (config.customization && config.customization.goback) { + if (config.customization.goback.requestClose && config.canRequestClose) + Common.Gateway.requestClose(); + else if (config.customization.goback.url) + window.parent.location.href = config.customization.goback.url; + } }); $('#id-btn-zoom-in').on('click', api.zoomIn.bind(this)); diff --git a/apps/documenteditor/main/app/controller/Links.js b/apps/documenteditor/main/app/controller/Links.js index f6d37fd4c..05b657ec5 100644 --- a/apps/documenteditor/main/app/controller/Links.js +++ b/apps/documenteditor/main/app/controller/Links.js @@ -41,6 +41,7 @@ define([ 'core', + 'common/main/lib/component/Calendar', 'documenteditor/main/app/view/Links', 'documenteditor/main/app/view/NoteSettingsDialog', 'documenteditor/main/app/view/HyperlinkSettingsDialog', @@ -129,7 +130,8 @@ define([ in_header = false, in_equation = false, in_image = false, - in_table = false; + in_table = false, + frame_pr = null; while (++i < selectedObjects.length) { type = selectedObjects[i].get_ObjectType(); @@ -137,6 +139,7 @@ define([ if (type === Asc.c_oAscTypeSelectElement.Paragraph) { paragraph_locked = pr.get_Locked(); + frame_pr = pr; } else if (type === Asc.c_oAscTypeSelectElement.Header) { header_locked = pr.get_Locked(); in_header = true; @@ -153,12 +156,19 @@ define([ var control_props = this.api.asc_IsContentControl() ? this.api.asc_GetContentControlProperties() : null, control_plain = (control_props) ? (control_props.get_ContentControlType()==Asc.c_oAscSdtLevelType.Inline) : false; + var rich_del_lock = (frame_pr) ? !frame_pr.can_DeleteBlockContentControl() : true, + rich_edit_lock = (frame_pr) ? !frame_pr.can_EditBlockContentControl() : true, + plain_del_lock = (frame_pr) ? !frame_pr.can_DeleteInlineContentControl() : true, + plain_edit_lock = (frame_pr) ? !frame_pr.can_EditInlineContentControl() : true; - var need_disable = paragraph_locked || in_equation || in_image || in_header || control_plain; + var need_disable = paragraph_locked || in_equation || in_image || in_header || control_plain || rich_edit_lock || plain_edit_lock; this.view.btnsNotes.setDisabled(need_disable); need_disable = paragraph_locked || header_locked || in_header || control_plain; this.view.btnBookmarks.setDisabled(need_disable); + + need_disable = in_header || rich_edit_lock || plain_edit_lock || rich_del_lock || plain_del_lock; + this.view.btnsContents.setDisabled(need_disable); }, onApiCanAddHyperlink: function(value) { @@ -351,8 +361,9 @@ define([ })).show(); }, - onShowContentControlsActions: function(action, x, y) { - var menu = (action==1) ? this.view.contentsUpdateMenu : this.view.contentsMenu, + onShowTOCActions: function(obj, x, y) { + var action = obj.button, + menu = (action==AscCommon.CCButtonType.Toc) ? this.view.contentsUpdateMenu : this.view.contentsMenu, documentHolderView = this.getApplication().getController('DocumentHolder').documentHolder, menuContainer = documentHolderView.cmpEl.find(Common.Utils.String.format('#menu-container-{0}', menu.id)), me = this; @@ -391,6 +402,155 @@ define([ onHideContentControlsActions: function() { this.view.contentsMenu && this.view.contentsMenu.hide(); this.view.contentsUpdateMenu && this.view.contentsUpdateMenu.hide(); + this.view.listControlMenu && this.view.listControlMenu.isVisible() && this.view.listControlMenu.hide(); + var controlsContainer = this.getApplication().getController('DocumentHolder').documentHolder.cmpEl.find('#calendar-control-container'); + if (controlsContainer.is(':visible')) + controlsContainer.hide(); + }, + + onShowDateActions: function(obj, x, y) { + var props = obj.pr, + specProps = props.get_DateTimePr(), + documentHolderView = this.getApplication().getController('DocumentHolder').documentHolder, + controlsContainer = documentHolderView.cmpEl.find('#calendar-control-container'), + me = this; + + this._state.dateObj = props; + + if (controlsContainer.length < 1) { + controlsContainer = $('
    '); + documentHolderView.cmpEl.append(controlsContainer); + } + + Common.UI.Menu.Manager.hideAll(); + + controlsContainer.css({left: x, top : y}); + controlsContainer.show(); + + if (!this.cmpCalendar) { + this.cmpCalendar = new Common.UI.Calendar({ + el: documentHolderView.cmpEl.find('#id-document-calendar-control'), + enableKeyEvents: true, + firstday: 1 + }); + this.cmpCalendar.on('date:click', function (cmp, date) { + var props = me._state.dateObj, + specProps = props.get_DateTimePr(), + id = props.get_InternalId(); + specProps.put_FullDate(new Date(date)); + me.api.asc_SetContentControlProperties(props, id); + controlsContainer.hide(); + me.api.asc_UncheckContentControlButtons(); + }); + this.cmpCalendar.on('calendar:keydown', function (cmp, e) { + if (e.keyCode==Common.UI.Keys.ESC) { + controlsContainer.hide(); + me.api.asc_UncheckContentControlButtons(); + } + }); + } + this.cmpCalendar.setDate(new Date(specProps ? specProps.get_FullDate() : undefined)); + + // align + var offset = controlsContainer.offset(), + docW = Common.Utils.innerWidth(), + docH = Common.Utils.innerHeight() - 10, // Yep, it's magic number + menuW = this.cmpCalendar.cmpEl.outerWidth(), + menuH = this.cmpCalendar.cmpEl.outerHeight(), + buttonOffset = 22, + left = offset.left - menuW, + top = offset.top; + if (top + menuH > docH) { + top = docH - menuH; + left -= buttonOffset; + } + if (top < 0) + top = 0; + if (left + menuW > docW) + left = docW - menuW; + this.cmpCalendar.cmpEl.css({left: left, top : top}); + + documentHolderView._preventClick = true; + }, + + onShowListActions: function(obj, x, y) { + var type = obj.type, + props = obj.pr, + specProps = (type == Asc.c_oAscContentControlSpecificType.ComboBox) ? props.get_ComboBoxPr() : props.get_DropDownListPr(), + menu = this.view.listControlMenu, + documentHolderView = this.getApplication().getController('DocumentHolder').documentHolder, + menuContainer = menu ? documentHolderView.cmpEl.find(Common.Utils.String.format('#menu-container-{0}', menu.id)) : null, + me = this; + + this._state.listObj = props; + + this._fromShowContentControls = true; + Common.UI.Menu.Manager.hideAll(); + + if (!menu) { + this.view.listControlMenu = menu = new Common.UI.Menu({ + menuAlign: 'tr-bl', + items: [] + }); + menu.on('item:click', function(menu, item) { + setTimeout(function(){ + me.api.asc_SelectContentControlListItem(item.value, me._state.listObj.get_InternalId()); + }, 1); + }); + + // Prepare menu container + if (!menuContainer || menuContainer.length < 1) { + menuContainer = $(Common.Utils.String.format('', menu.id)); + documentHolderView.cmpEl.append(menuContainer); + } + + menu.render(menuContainer); + menu.cmpEl.attr({tabindex: "-1"}); + menu.on('hide:after', function(){ + me.view.listControlMenu.removeAll(); + if (!me._fromShowContentControls) + me.api.asc_UncheckContentControlButtons(); + }); + } + if (specProps) { + var count = specProps.get_ItemsCount(); + for (var i=0; i canRequestEditRights must be defined (!this.appOptions.isReviewOnly || this.appOptions.canLicense); // if isReviewOnly==true -> canLicense must be true @@ -1387,6 +1394,18 @@ define([ config.msg = this.uploadImageFileCountMessage; break; + case Asc.c_oAscError.ID.UplDocumentSize: + config.msg = this.uploadDocSizeMessage; + break; + + case Asc.c_oAscError.ID.UplDocumentExt: + config.msg = this.uploadDocExtMessage; + break; + + case Asc.c_oAscError.ID.UplDocumentFileCount: + config.msg = this.uploadDocFileCountMessage; + break; + case Asc.c_oAscError.ID.SplitCellMaxRows: config.msg = this.splitMaxRowsErrorText.replace('%1', errData.get_Value()); break; @@ -2165,7 +2184,7 @@ define([ uploadImageTextText: 'Uploading image...', savePreparingText: 'Preparing to save', savePreparingTitle: 'Preparing to save. Please wait...', - uploadImageSizeMessage: 'Maximium image size limit exceeded.', + uploadImageSizeMessage: 'Maximum image size limit exceeded.', uploadImageExtMessage: 'Unknown image format.', uploadImageFileCountMessage: 'No images uploaded.', reloadButtonText: 'Reload Page', @@ -2481,6 +2500,9 @@ define([ txtMainDocOnly: 'Error! Main Document Only.', txtNotValidBookmark: 'Error! Not a valid bookmark self-reference.', txtNoText: 'Error! No text of specified style in document.', + uploadDocSizeMessage: 'Maximum document size limit exceeded.', + uploadDocExtMessage: 'Unknown document format.', + uploadDocFileCountMessage: 'No documents uploaded.', 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.' } })(), DE.Controllers.Main || {})) diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js index 8d20b388a..dfded77bd 100644 --- a/apps/documenteditor/main/app/controller/Toolbar.js +++ b/apps/documenteditor/main/app/controller/Toolbar.js @@ -57,7 +57,8 @@ define([ 'documenteditor/main/app/controller/PageLayout', 'documenteditor/main/app/view/CustomColumnsDialog', 'documenteditor/main/app/view/ControlSettingsDialog', - 'documenteditor/main/app/view/WatermarkSettingsDialog' + 'documenteditor/main/app/view/WatermarkSettingsDialog', + 'documenteditor/main/app/view/CompareSettingsDialog' ], function () { 'use strict'; @@ -380,7 +381,10 @@ define([ this.api.asc_registerCallback('asc_onContextMenu', _.bind(this.onContextMenu, this)); this.api.asc_registerCallback('asc_onShowParaMarks', _.bind(this.onShowParaMarks, this)); this.api.asc_registerCallback('asc_onChangeSdtGlobalSettings', _.bind(this.onChangeSdtGlobalSettings, this)); + this.api.asc_registerCallback('asc_onTextLanguage', _.bind(this.onTextLanguage, this)); Common.NotificationCenter.on('fonts:change', _.bind(this.onApiChangeFont, this)); + this.api.asc_registerCallback('asc_onTableDrawModeChanged', _.bind(this.onTableDraw, this)); + this.api.asc_registerCallback('asc_onTableEraseModeChanged', _.bind(this.onTableErase, this)); } else if (this.mode.isRestrictedEdit) { this.api.asc_registerCallback('asc_onFocusObject', _.bind(this.onApiFocusObjectRestrictedEdit, this)); this.api.asc_registerCallback('asc_onCoAuthoringDisconnect', _.bind(this.onApiCoAuthoringDisconnect, this)); @@ -736,7 +740,11 @@ define([ if (sh) this.onParagraphColor(sh); - var need_disable = paragraph_locked || header_locked; + var rich_del_lock = (frame_pr) ? !frame_pr.can_DeleteBlockContentControl() : true, + rich_edit_lock = (frame_pr) ? !frame_pr.can_EditBlockContentControl() : true, + plain_del_lock = (frame_pr) ? !frame_pr.can_DeleteInlineContentControl() : true, + plain_edit_lock = (frame_pr) ? !frame_pr.can_EditInlineContentControl() : true; + var need_disable = paragraph_locked || header_locked || rich_edit_lock || plain_edit_lock; if (this._state.prcontrolsdisable != need_disable) { if (this._state.activated) this._state.prcontrolsdisable = need_disable; @@ -750,15 +758,18 @@ define([ lock_type = (in_control&&control_props) ? control_props.get_Lock() : Asc.c_oAscSdtLockType.Unlocked, control_plain = (in_control&&control_props) ? (control_props.get_ContentControlType()==Asc.c_oAscSdtLevelType.Inline) : false; (lock_type===undefined) && (lock_type = Asc.c_oAscSdtLockType.Unlocked); + var content_locked = lock_type==Asc.c_oAscSdtLockType.SdtContentLocked || lock_type==Asc.c_oAscSdtLockType.ContentLocked; - if (!paragraph_locked && !header_locked) { - toolbar.btnContentControls.menu.items[0].setDisabled(control_plain || lock_type==Asc.c_oAscSdtLockType.SdtContentLocked || lock_type==Asc.c_oAscSdtLockType.ContentLocked); - toolbar.btnContentControls.menu.items[1].setDisabled(control_plain || lock_type==Asc.c_oAscSdtLockType.SdtContentLocked || lock_type==Asc.c_oAscSdtLockType.ContentLocked); - toolbar.btnContentControls.menu.items[3].setDisabled(!in_control || lock_type==Asc.c_oAscSdtLockType.SdtContentLocked || lock_type==Asc.c_oAscSdtLockType.SdtLocked); - toolbar.btnContentControls.menu.items[5].setDisabled(!in_control); + toolbar.btnContentControls.setDisabled(paragraph_locked || header_locked); + if (!(paragraph_locked || header_locked)) { + var control_disable = control_plain || content_locked; + for (var i=0; i<7; i++) + toolbar.btnContentControls.menu.items[i].setDisabled(control_disable); + toolbar.btnContentControls.menu.items[8].setDisabled(!in_control || lock_type==Asc.c_oAscSdtLockType.SdtContentLocked || lock_type==Asc.c_oAscSdtLockType.SdtLocked); + toolbar.btnContentControls.menu.items[10].setDisabled(!in_control); } - var need_text_disable = paragraph_locked || header_locked || in_chart; + var need_text_disable = paragraph_locked || header_locked || in_chart || rich_edit_lock || plain_edit_lock; if (this._state.textonlycontrolsdisable != need_text_disable) { if (this._state.activated) this._state.textonlycontrolsdisable = need_text_disable; if (!need_disable) { @@ -766,7 +777,7 @@ define([ item.setDisabled(need_text_disable); }, this); } - toolbar.btnCopyStyle.setDisabled(need_text_disable); + // toolbar.btnCopyStyle.setDisabled(need_text_disable); toolbar.btnClearStyle.setDisabled(need_text_disable); } @@ -792,22 +803,22 @@ define([ if ( !toolbar.btnDropCap.isDisabled() ) toolbar.mnuDropCapAdvanced.setDisabled(disable_dropcapadv); - need_disable = !can_add_table || header_locked || in_equation || control_plain; + need_disable = !can_add_table || header_locked || in_equation || control_plain || rich_edit_lock || plain_edit_lock || rich_del_lock || plain_del_lock; toolbar.btnInsertTable.setDisabled(need_disable); need_disable = toolbar.mnuPageNumCurrentPos.isDisabled() && toolbar.mnuPageNumberPosPicker.isDisabled() || control_plain; toolbar.mnuInsertPageNum.setDisabled(need_disable); var in_footnote = this.api.asc_IsCursorInFootnote(); - need_disable = paragraph_locked || header_locked || in_header || in_image || in_equation && !btn_eq_state || in_footnote || in_control; + need_disable = paragraph_locked || header_locked || in_header || in_image || in_equation && !btn_eq_state || in_footnote || in_control || rich_edit_lock || plain_edit_lock || rich_del_lock; toolbar.btnsPageBreak.setDisabled(need_disable); toolbar.btnBlankPage.setDisabled(need_disable); - need_disable = paragraph_locked || header_locked || in_equation || control_plain; + need_disable = paragraph_locked || header_locked || in_equation || control_plain || content_locked; toolbar.btnInsertShape.setDisabled(need_disable); toolbar.btnInsertText.setDisabled(need_disable); - need_disable = paragraph_locked || header_locked || in_para && !can_add_image || in_equation || control_plain; + need_disable = paragraph_locked || header_locked || in_para && !can_add_image || in_equation || control_plain || rich_del_lock || plain_del_lock || content_locked; toolbar.btnInsertImage.setDisabled(need_disable); toolbar.btnInsertTextArt.setDisabled(need_disable || in_footnote); @@ -816,28 +827,28 @@ define([ this._state.in_chart = in_chart; } - need_disable = in_chart && image_locked || !in_chart && need_disable || control_plain; + need_disable = in_chart && image_locked || !in_chart && need_disable || control_plain || rich_del_lock || plain_del_lock || content_locked; toolbar.btnInsertChart.setDisabled(need_disable); - need_disable = paragraph_locked || header_locked || in_chart || !can_add_image&&!in_equation || control_plain; + need_disable = paragraph_locked || header_locked || in_chart || !can_add_image&&!in_equation || control_plain || rich_edit_lock || plain_edit_lock || rich_del_lock || plain_del_lock; toolbar.btnInsertEquation.setDisabled(need_disable); - toolbar.btnInsertSymbol.setDisabled(!in_para || paragraph_locked || header_locked); + toolbar.btnInsertSymbol.setDisabled(!in_para || paragraph_locked || header_locked || rich_edit_lock || plain_edit_lock || rich_del_lock || plain_del_lock); - need_disable = paragraph_locked || header_locked || in_equation; + need_disable = paragraph_locked || header_locked || in_equation || rich_edit_lock || plain_edit_lock; toolbar.btnSuperscript.setDisabled(need_disable); toolbar.btnSubscript.setDisabled(need_disable); toolbar.btnEditHeader.setDisabled(in_equation); - need_disable = paragraph_locked || header_locked || in_image || control_plain; + need_disable = paragraph_locked || header_locked || in_image || control_plain || rich_edit_lock || plain_edit_lock; if (need_disable != toolbar.btnColumns.isDisabled()) toolbar.btnColumns.setDisabled(need_disable); if (toolbar.listStylesAdditionalMenuItem && (frame_pr===undefined) !== toolbar.listStylesAdditionalMenuItem.isDisabled()) toolbar.listStylesAdditionalMenuItem.setDisabled(frame_pr===undefined); - need_disable = !this.api.can_AddQuotedComment() || paragraph_locked || header_locked || image_locked; + need_disable = !this.api.can_AddQuotedComment() || paragraph_locked || header_locked || image_locked || rich_del_lock || rich_edit_lock || plain_del_lock || plain_edit_lock; if (this.mode.compatibleFeatures) { need_disable = need_disable || in_image; } @@ -854,6 +865,13 @@ define([ this.modeAlwaysSetStyle = false; }, + onTableDraw: function(v) { + this.toolbar.mnuInsertTable && this.toolbar.mnuInsertTable.items[2].setChecked(!!v, true); + }, + onTableErase: function(v) { + this.toolbar.mnuInsertTable && this.toolbar.mnuInsertTable.items[3].setChecked(!!v, true); + }, + onApiParagraphStyleChange: function(name) { if (this._state.prstyle != name) { var listStyle = this.toolbar.listStyles, @@ -1410,6 +1428,12 @@ define([ Common.NotificationCenter.trigger('edit:complete', me.toolbar); } })).show(); + } else if (item.value == 'draw') { + item.isChecked() && menu.items[3].setChecked(false, true); + this.api.SetTableDrawMode(item.isChecked()); + } else if (item.value == 'erase') { + item.isChecked() && menu.items[2].setChecked(false, true); + this.api.SetTableEraseMode(item.isChecked()); } }, @@ -1733,6 +1757,8 @@ define([ (new DE.Views.ControlSettingsDialog({ props: props, api: me.api, + controlLang: me._state.lang, + interfaceLang: me.mode.lang, handler: function(result, value) { if (result == 'ok') { me.api.asc_SetContentControlProperties(value, id); @@ -1749,7 +1775,17 @@ define([ } } } else { - this.api.asc_AddContentControl(item.value); + if (item.value == 'plain' || item.value == 'rich') + this.api.asc_AddContentControl((item.value=='plain') ? Asc.c_oAscSdtLevelType.Inline : Asc.c_oAscSdtLevelType.Block); + else if (item.value == 'picture') + this.api.asc_AddContentControlPicture(); + else if (item.value == 'checkbox') + this.api.asc_AddContentControlCheckBox(); + else if (item.value == 'date') + this.api.asc_AddContentControlDatePicker(); + else if (item.value == 'combobox' || item.value == 'dropdown') + this.api.asc_AddContentControlList(item.value == 'combobox'); + Common.component.Analytics.trackEvent('ToolBar', 'Add Content Control'); } @@ -2952,6 +2988,10 @@ define([ } }, + onTextLanguage: function(langId) { + this._state.lang = langId; + }, + textEmptyImgUrl : 'You need to specify image URL.', textWarning : 'Warning', textFontSizeErr : 'The entered value is incorrect.
    Please enter a numeric value between 1 and 100', diff --git a/apps/documenteditor/main/app/template/ControlSettingsDialog.template b/apps/documenteditor/main/app/template/ControlSettingsDialog.template new file mode 100644 index 000000000..70df12159 --- /dev/null +++ b/apps/documenteditor/main/app/template/ControlSettingsDialog.template @@ -0,0 +1,151 @@ +
    +
    + + + + + + + + + + +
    + +
    +
    + +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    + +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + +
    + + +
    +
    +
    + + + + + +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + +
    + + +
    +
    + +
    + + +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/apps/documenteditor/main/app/template/ImageSettings.template b/apps/documenteditor/main/app/template/ImageSettings.template index 8abc9eaf0..9fae4b54e 100644 --- a/apps/documenteditor/main/app/template/ImageSettings.template +++ b/apps/documenteditor/main/app/template/ImageSettings.template @@ -14,17 +14,17 @@ - + - + -
    +
    diff --git a/apps/documenteditor/main/app/view/CompareSettingsDialog.js b/apps/documenteditor/main/app/view/CompareSettingsDialog.js new file mode 100644 index 000000000..d7c9f84ba --- /dev/null +++ b/apps/documenteditor/main/app/view/CompareSettingsDialog.js @@ -0,0 +1,150 @@ +/* + * + * (c) Copyright Ascensio System SIA 2010-2019 + * + * 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 + * + */ + +/** + * CompareSettingsDialog.js.js + * + * Created by Julia Radzhabova on 14.08.2019 + * Copyright (c) 2019 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'common/main/lib/util/utils', + 'common/main/lib/component/CheckBox', + 'common/main/lib/component/InputField', + 'common/main/lib/view/AdvancedSettingsWindow' +], function () { 'use strict'; + + DE.Views.CompareSettingsDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({ + options: { + contentWidth: 220, + height: 160 + }, + + initialize : function(options) { + var me = this; + + _.extend(this.options, { + title: this.textTitle, + template: [ + '
    ', + '
    ', + '
    ', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ' + ].join('') + }, options); + + 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.radioChar = new Common.UI.RadioBox({ + el: $('#compare-settings-radio-char'), + labelText: this.textChar, + name: 'asc-radio-compare-show' + }); + + this.radioWord = new Common.UI.RadioBox({ + el: $('#compare-settings-radio-word'), + labelText: this.textWord, + name: 'asc-radio-compare-show' + }); + + this.afterRender(); + }, + + afterRender: function() { + this._setDefaults(this.props); + }, + + show: function() { + Common.Views.AdvancedSettingsWindow.prototype.show.apply(this, arguments); + }, + + _setDefaults: function (props) { + if (props) { + var value = props.getWords(); + (value==false) ? this.radioChar.setValue(true, true) : this.radioWord.setValue(true, true); + } + }, + + getSettings: function () { + var props = new AscCommonWord.ComparisonOptions(); + props.putWords(this.radioWord.getValue()); + return props; + }, + + 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, this.getSettings()); + Common.localStorage.setBool("de-compare-char", this.radioChar.getValue()); + } + + this.close(); + }, + + textTitle: 'Comparison Settings', + textShow: 'Show changes at', + textChar: 'Character level', + textWord: 'Word level' + + }, DE.Views.CompareSettingsDialog || {})) +}); \ No newline at end of file diff --git a/apps/documenteditor/main/app/view/ControlSettingsDialog.js b/apps/documenteditor/main/app/view/ControlSettingsDialog.js index d82b927ee..99d10656c 100644 --- a/apps/documenteditor/main/app/view/ControlSettingsDialog.js +++ b/apps/documenteditor/main/app/view/ControlSettingsDialog.js @@ -39,17 +39,21 @@ * */ -define([ +define([ 'text!documenteditor/main/app/template/ControlSettingsDialog.template', 'common/main/lib/util/utils', 'common/main/lib/component/CheckBox', 'common/main/lib/component/InputField', - 'common/main/lib/view/AdvancedSettingsWindow' -], function () { 'use strict'; + 'common/main/lib/view/AdvancedSettingsWindow', + 'common/main/lib/view/SymbolTableDialog', + 'documenteditor/main/app/view/EditListItemDialog' +], function (contentTemplate) { 'use strict'; DE.Views.ControlSettingsDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({ options: { contentWidth: 310, - height: 412 + height: 392, + toggleGroup: 'control-adv-settings-group', + storageName: 'de-control-settings-adv-category' }, initialize : function(options) { @@ -57,83 +61,16 @@ define([ _.extend(this.options, { title: this.textTitle, - template: [ - '
    ', - '
    ', - '
    ', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '
    ', - '', - '
    ', - '
    ', - '', - '
    ', - '
    ', - '
    ', - '
    ', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '
    ', - '', - '
    ', - '', - '', - '
    ', - '
    ', - '', - '', - '
    ', - '
    ', - '', - '
    ', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '
    ', - '
    ', - '
    ', - '', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ' - ].join('') + items: [ + {panelId: 'id-adv-control-settings-general', panelCaption: this.strGeneral}, + {panelId: 'id-adv-control-settings-lock', panelCaption: this.textLock}, + {panelId: 'id-adv-control-settings-list', panelCaption: this.textCombobox}, + {panelId: 'id-adv-control-settings-date', panelCaption: this.textDate}, + {panelId: 'id-adv-control-settings-checkbox',panelCaption: this.textCheckbox} + ], + contentTemplate: _.template(contentTemplate)({ + scope: this + }) }, options); this.handler = options.handler; @@ -222,6 +159,117 @@ define([ labelText: this.txtLockEdit }); + // combobox & dropdown list + this.list = new Common.UI.ListView({ + el: $('#control-settings-list', this.$window), + store: new Common.UI.DataViewStore(), + emptyText: '', + template: _.template(['
    '].join('')), + itemTemplate: _.template([ + '
    ', + '
    <%= name %>
    ', + '
    <%= value %>
    ', + '
    ' + ].join('')) + }); + this.list.on('item:select', _.bind(this.onSelectItem, this)); + + this.btnAdd = new Common.UI.Button({ + el: $('#control-settings-btn-add') + }); + this.btnAdd.on('click', _.bind(this.onAddItem, this)); + + this.btnChange = new Common.UI.Button({ + el: $('#control-settings-btn-change') + }); + this.btnChange.on('click', _.bind(this.onChangeItem, this)); + + this.btnDelete = new Common.UI.Button({ + el: $('#control-settings-btn-delete') + }); + this.btnDelete.on('click', _.bind(this.onDeleteItem, this)); + + this.btnUp = new Common.UI.Button({ + el: $('#control-settings-btn-up') + }); + this.btnUp.on('click', _.bind(this.onMoveItem, this, true)); + + this.btnDown = new Common.UI.Button({ + el: $('#control-settings-btn-down') + }); + this.btnDown.on('click', _.bind(this.onMoveItem, this, false)); + + // date picker + var data = [{ value: 0x042C }, { value: 0x0402 }, { value: 0x0405 }, { value: 0x0407 }, {value: 0x0807}, { value: 0x0408 }, { value: 0x0C09 }, { value: 0x0809 }, { value: 0x0409 }, { value: 0x0C0A }, { value: 0x080A }, + { value: 0x040B }, { value: 0x040C }, { value: 0x0410 }, { value: 0x0411 }, { value: 0x0412 }, { value: 0x0426 }, { value: 0x0413 }, { value: 0x0415 }, { value: 0x0416 }, + { value: 0x0816 }, { value: 0x0419 }, { value: 0x041B }, { value: 0x0424 }, { value: 0x081D }, { value: 0x041D }, { value: 0x041F }, { value: 0x0422 }, { value: 0x042A }, { value: 0x0804 }]; + data.forEach(function(item) { + var langinfo = Common.util.LanguageInfo.getLocalLanguageName(item.value); + item.displayValue = langinfo[1]; + item.langName = langinfo[0]; + }); + + this.cmbLang = new Common.UI.ComboBox({ + el : $('#control-settings-lang'), + menuStyle : 'min-width: 100%; max-height: 185px;', + cls : 'input-group-nr', + editable : false, + data : data + }); + this.cmbLang.setValue(0x0409); + this.cmbLang.on('selected',function(combo, record) { + me.updateFormats(record.value); + }); + + this.listFormats = new Common.UI.ListView({ + el: $('#control-settings-format'), + store: new Common.UI.DataViewStore(), + scrollAlwaysVisible: true + }); + this.listFormats.on('item:select', _.bind(this.onSelectFormat, this)); + + this.txtDate = new Common.UI.InputField({ + el : $('#control-settings-txt-format'), + allowBlank : true, + validateOnChange: false, + validateOnBlur: false, + style : 'width: 100%;', + value : '' + }); + + // Check Box + this.txtChecked = new Common.UI.InputField({ + el : $('#control-settings-input-checked'), + allowBlank : true, + validateOnChange: false, + validateOnBlur: false, + style : 'width: 30px;', + value : '' + }); + this.txtChecked._input.attr('disabled', true); + this.txtChecked._input.css({'text-align': 'center', 'font-size': '16px'}); + + this.txtUnchecked = new Common.UI.InputField({ + el : $('#control-settings-input-unchecked'), + allowBlank : true, + validateOnChange: false, + validateOnBlur: false, + style : 'width: 30px;', + value : '' + }); + this.txtUnchecked._input.attr('disabled', true); + this.txtUnchecked._input.css({'text-align': 'center', 'font-size': '16px'}); + + this.btnEditChecked = new Common.UI.Button({ + el: $('#control-settings-btn-checked-edit') + }); + this.btnEditChecked.on('click', _.bind(this.onEditCheckbox, this, true)); + + this.btnEditUnchecked = new Common.UI.Button({ + el: $('#control-settings-btn-unchecked-edit') + }); + this.btnEditUnchecked.on('click', _.bind(this.onEditCheckbox, this, false)); + this.afterRender(); }, @@ -252,6 +300,10 @@ define([ afterRender: function() { this.updateThemeColors(); this._setDefaults(this.props); + if (this.storageName) { + var value = Common.localStorage.getItem(this.storageName); + this.setActiveCategory((value!==null) ? parseInt(value) : 0); + } }, show: function() { @@ -286,6 +338,69 @@ define([ (val===undefined) && (val = Asc.c_oAscSdtLockType.Unlocked); this.chLockDelete.setValue(val==Asc.c_oAscSdtLockType.SdtContentLocked || val==Asc.c_oAscSdtLockType.SdtLocked); this.chLockEdit.setValue(val==Asc.c_oAscSdtLockType.SdtContentLocked || val==Asc.c_oAscSdtLockType.ContentLocked); + + var type = props.get_SpecificType(); + + //for list controls + this.btnsCategory[2].setVisible(type == Asc.c_oAscContentControlSpecificType.ComboBox || type == Asc.c_oAscContentControlSpecificType.DropDownList); + if (type == Asc.c_oAscContentControlSpecificType.ComboBox || type == Asc.c_oAscContentControlSpecificType.DropDownList) { + this.btnsCategory[2].setCaption(type == Asc.c_oAscContentControlSpecificType.ComboBox ? this.textCombobox : this.textDropDown); + var specProps = (type == Asc.c_oAscContentControlSpecificType.ComboBox) ? props.get_ComboBoxPr() : props.get_DropDownListPr(); + if (specProps) { + var count = specProps.get_ItemsCount(); + var arr = []; + for (var i=0; istore.length-1) idx = store.length-1; + if (store.length>0) { + this.list.selectByIndex(idx); + this.list.scrollToRecord(store.at(idx)); + } + } + this.disableListButtons(); + this.list.cmpEl.find('.listview').focus(); + }, + + onMoveItem: function(up) { + var store = this.list.store, + length = store.length, + rec = this.list.getSelectedRec(); + if (rec) { + var index = store.indexOf(rec); + store.add(store.remove(rec), {at: up ? Math.max(0, index-1) : Math.min(length-1, index+1)}); + this.list.selectRecord(rec); + this.list.scrollToRecord(rec); + } + this.list.cmpEl.find('.listview').focus(); + }, + + updateFormats: function(lang) { + if (this.datetime) { + var props = this.datetime, + formats = props.get_FormatsExamples(), + arr = []; + for (var i = 0, len = formats.length; i < len; i++) + { + props.get_String(formats[i], undefined, lang); + var rec = new Common.UI.DataViewModel(); + rec.set({ + format: formats[i], + value: props.get_String(formats[i], undefined, lang) + }); + arr.push(rec); + } + this.listFormats.store.reset(arr); + this.listFormats.selectByIndex(0); + var rec = this.listFormats.getSelectedRec(); + this.listFormats.scrollToRecord(rec); + this.txtDate.setValue(rec.get('format')); + } + }, + + onEditCheckbox: function(checked) { + if (this.api) { + var me = this, + props = (checked) ? me.checkedBox : me.uncheckedBox, + cmp = (checked) ? me.txtChecked : me.txtUnchecked, + handler = function(dlg, result, settings) { + if (result == 'ok') { + props.changed = true; + props.code = settings.code; + props.font = settings.font; + props.font && cmp.cmpEl.css('font-family', props.font); + settings.symbol && cmp.setValue(settings.symbol); + } + }, + win = new Common.Views.SymbolTableDialog({ + api: me.api, + lang: me.options.interfaceLang, + modal: true, + type: 0, + font: props.font, + code: props.code, + handler: handler + }); + win.show(); + win.on('symbol:dblclick', handler); + } + }, + + onSelectFormat: function(lisvView, itemView, record) { + if (!record) return; + this.txtDate.setValue(record.get('format')); + }, + textTitle: 'Content Control Settings', textName: 'Title', textTag: 'Tag', @@ -352,7 +641,23 @@ define([ textNewColor: 'Add New Custom Color', textApplyAll: 'Apply to All', textAppearance: 'Appearance', - textSystemColor: 'System' + textSystemColor: 'System', + strGeneral: 'General', + textAdd: 'Add', + textChange: 'Edit', + textDelete: 'Delete', + textUp: 'Up', + textDown: 'Down', + textCombobox: 'Combo box', + textDropDown: 'Drop-down list', + textDisplayName: 'Display name', + textValue: 'Value', + textDate: 'Date format', + textLang: 'Language', + textFormat: 'Display the date like this', + textCheckbox: 'Check box', + textChecked: 'Checked symbol', + textUnchecked: 'Unchecked symbol' }, DE.Views.ControlSettingsDialog || {})) }); \ No newline at end of file diff --git a/apps/documenteditor/main/app/view/EditListItemDialog.js b/apps/documenteditor/main/app/view/EditListItemDialog.js new file mode 100644 index 000000000..56b05eca2 --- /dev/null +++ b/apps/documenteditor/main/app/view/EditListItemDialog.js @@ -0,0 +1,175 @@ +/* + * + * (c) Copyright Ascensio System SIA 2010-2019 + * + * 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 + * + */ + +/** + * EditListItemDialog.js + * + * Created by Julia Radzhabova on 05.11.2019 + * Copyright (c) 2019 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'common/main/lib/component/Window', + 'common/main/lib/component/InputField' +], function () { 'use strict'; + + DE.Views.EditListItemDialog = Common.UI.Window.extend(_.extend({ + options: { + width: 330, + header: false, + cls: 'modal-dlg', + buttons: ['ok', 'cancel'] + }, + + initialize : function(options) { + _.extend(this.options, options || {}); + + this.template = [ + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ' + ].join(''); + + this.options.tpl = _.template(this.template)(this.options); + Common.UI.Window.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.UI.Window.prototype.render.call(this); + + var me = this; + me.inputName = new Common.UI.InputField({ + el : $('#id-dlg-label-name'), + allowBlank : false, + blankError : me.textNameError, + style : 'width: 100%;', + validateOnBlur: false, + validation : function(value) { + return value ? true : ''; + } + }); + me.inputName._input.on('input', function (e) { + if (me.copyvalue==undefined && me.inputValue.getValue()==me.inputName.getValue()) { + me.copyvalue = 1; + } + if (me.copyvalue==1) + me.inputValue.setValue($(e.target).val()); + else if (me.copyvalue==2) + me.copyvalue = 0; + }); + + me.inputValue = new Common.UI.InputField({ + el : $('#id-dlg-label-value'), + style : 'width: 100%;', + validateOnBlur: false, + validation : function(value) { + if (value!=='' && me.options.store) { + var rec = me.options.store.findWhere({value: value}); + if (rec) + return me.textValueError + } + return true; + } + }); + me.inputValue._input.on('input', function (e) { + if (me.copyvalue==undefined && me.inputValue.getValue()==me.inputName.getValue()) { + me.copyvalue = 2; + } + if (me.copyvalue==2) + me.inputName.setValue($(e.target).val()); + else if (me.copyvalue==1) + me.copyvalue = 0; + }); + + var $window = this.getChild(); + $window.find('.btn').on('click', _.bind(this.onBtnClick, this)); + }, + + show: function() { + Common.UI.Window.prototype.show.apply(this, arguments); + + var me = this; + _.delay(function(){ + me.inputName.cmpEl.find('input').focus(); + },50); + }, + + onPrimary: function(event) { + this._handleInput('ok'); + return false; + }, + + onBtnClick: function(event) { + this._handleInput(event.currentTarget.attributes['result'].value); + }, + + _handleInput: function(state) { + if (this.options.handler) { + if (state == 'ok') { + if (this.inputName.checkValidate() !== true) { + this.inputName.cmpEl.find('input').focus(); + return; + } + if (this.inputValue.checkValidate() !== true) { + this.inputValue.cmpEl.find('input').focus(); + return; + } + } + + this.options.handler.call(this, state, this.inputName.getValue(), this.inputValue.getValue()); + } + + this.close(); + }, + + setSettings: function (props) { + if (props) { + this.inputName.setValue(props.name || ''); + this.inputValue.setValue(props.value || ''); + } + }, + + textDisplayName: 'Display name', + textValue: 'Value', + textNameError: 'Display name must not be empty.', + textValueError: 'An item with the same value already exists.' + }, DE.Views.EditListItemDialog || {})); +}); \ No newline at end of file diff --git a/apps/documenteditor/main/app/view/ImageSettings.js b/apps/documenteditor/main/app/view/ImageSettings.js index 527037a2b..562e7557d 100644 --- a/apps/documenteditor/main/app/view/ImageSettings.js +++ b/apps/documenteditor/main/app/view/ImageSettings.js @@ -105,10 +105,10 @@ define([ updateMetricUnit: function() { var value = Common.Utils.Metric.fnRecalcFromMM(this._state.Width); - this.labelWidth[0].innerHTML = this.textWidth + ': ' + value.toFixed(1) + ' ' + Common.Utils.Metric.getCurrentMetricName(); + this.labelWidth[0].innerHTML = this.textWidth + ': ' + value.toFixed(2) + ' ' + Common.Utils.Metric.getCurrentMetricName(); value = Common.Utils.Metric.fnRecalcFromMM(this._state.Height); - this.labelHeight[0].innerHTML = this.textHeight + ': ' + value.toFixed(1) + ' ' + Common.Utils.Metric.getCurrentMetricName(); + this.labelHeight[0].innerHTML = this.textHeight + ': ' + value.toFixed(2) + ' ' + Common.Utils.Metric.getCurrentMetricName(); }, createDelayedControls: function() { @@ -159,6 +159,10 @@ define([ }); this.lockedControls.push(this.btnFitMargins); + var w = Math.max(this.btnOriginalSize.cmpEl.width(), this.btnFitMargins.cmpEl.width()); + this.btnOriginalSize.cmpEl.width(w); + this.btnFitMargins.cmpEl.width(w); + this.btnInsertFromFile = new Common.UI.Button({ el: $('#image-button-from-file') }); @@ -229,6 +233,7 @@ define([ this.btnFlipH.on('click', _.bind(this.onBtnFlipClick, this)); this.lockedControls.push(this.btnFlipH); + var w = this.btnOriginalSize.cmpEl.outerWidth(); this.btnCrop = new Common.UI.Button({ cls: 'btn-text-split-default', caption: this.textCrop, @@ -236,9 +241,9 @@ define([ enableToggle: true, allowDepress: true, pressed: this._state.cropMode, - width: 100, + width: w, menu : new Common.UI.Menu({ - style : 'min-width: 100px;', + style : 'min-width:' + w + 'px;', items: [ { caption: this.textCrop, @@ -311,13 +316,13 @@ define([ value = props.get_Width(); if ( Math.abs(this._state.Width-value)>0.001 ) { - this.labelWidth[0].innerHTML = this.textWidth + ': ' + Common.Utils.Metric.fnRecalcFromMM(value).toFixed(1) + ' ' + Common.Utils.Metric.getCurrentMetricName(); + this.labelWidth[0].innerHTML = this.textWidth + ': ' + Common.Utils.Metric.fnRecalcFromMM(value).toFixed(2) + ' ' + Common.Utils.Metric.getCurrentMetricName(); this._state.Width = value; } value = props.get_Height(); if ( Math.abs(this._state.Height-value)>0.001 ) { - this.labelHeight[0].innerHTML = this.textHeight + ': ' + Common.Utils.Metric.fnRecalcFromMM(value).toFixed(1) + ' ' + Common.Utils.Metric.getCurrentMetricName(); + this.labelHeight[0].innerHTML = this.textHeight + ': ' + Common.Utils.Metric.fnRecalcFromMM(value).toFixed(2) + ' ' + Common.Utils.Metric.getCurrentMetricName(); this._state.Height = value; } @@ -391,8 +396,8 @@ define([ var w = imgsize.get_ImageWidth(); var h = imgsize.get_ImageHeight(); - this.labelWidth[0].innerHTML = this.textWidth + ': ' + Common.Utils.Metric.fnRecalcFromMM(w).toFixed(1) + ' ' + Common.Utils.Metric.getCurrentMetricName(); - this.labelHeight[0].innerHTML = this.textHeight + ': ' + Common.Utils.Metric.fnRecalcFromMM(h).toFixed(1) + ' ' + Common.Utils.Metric.getCurrentMetricName(); + this.labelWidth[0].innerHTML = this.textWidth + ': ' + Common.Utils.Metric.fnRecalcFromMM(w).toFixed(2) + ' ' + Common.Utils.Metric.getCurrentMetricName(); + this.labelHeight[0].innerHTML = this.textHeight + ': ' + Common.Utils.Metric.fnRecalcFromMM(h).toFixed(2) + ' ' + Common.Utils.Metric.getCurrentMetricName(); var properties = new Asc.asc_CImgProperty(); properties.put_Width(w); @@ -423,8 +428,8 @@ define([ h = pageh; } - this.labelWidth[0].innerHTML = this.textWidth + ': ' + Common.Utils.Metric.fnRecalcFromMM(w).toFixed(1) + ' ' + Common.Utils.Metric.getCurrentMetricName(); - this.labelHeight[0].innerHTML = this.textHeight + ': ' + Common.Utils.Metric.fnRecalcFromMM(h).toFixed(1) + ' ' + Common.Utils.Metric.getCurrentMetricName(); + this.labelWidth[0].innerHTML = this.textWidth + ': ' + Common.Utils.Metric.fnRecalcFromMM(w).toFixed(2) + ' ' + Common.Utils.Metric.getCurrentMetricName(); + this.labelHeight[0].innerHTML = this.textHeight + ': ' + Common.Utils.Metric.fnRecalcFromMM(h).toFixed(2) + ' ' + Common.Utils.Metric.getCurrentMetricName(); var properties = new Asc.asc_CImgProperty(); properties.put_Width(w); diff --git a/apps/documenteditor/main/app/view/PageMarginsDialog.js b/apps/documenteditor/main/app/view/PageMarginsDialog.js index b1c6f83cb..a195a093f 100644 --- a/apps/documenteditor/main/app/view/PageMarginsDialog.js +++ b/apps/documenteditor/main/app/view/PageMarginsDialog.js @@ -45,9 +45,9 @@ define([ DE.Views.PageMarginsDialog = Common.UI.Window.extend(_.extend({ options: { - width: 215, + width: 404, header: true, - style: 'min-width: 216px;', + style: 'min-width: 404px;', cls: 'modal-dlg', id: 'window-page-margins', buttons: ['ok', 'cancel'] @@ -59,31 +59,50 @@ define([ }, options || {}); this.template = [ - '
    ', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', '', '
    ', - '
    ', + '', + '
    ', '', '
    ', - '
    ', - '', + '', + '', + '
    ', + '
    ', + '', '
    ', - '
    ', - '', + '', + '
    ', + '', '
    ', - '
    ', - '
    ', - '
    ' + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ' ].join(''); this.options.tpl = _.template(this.template)(this.options); @@ -107,6 +126,13 @@ define([ maxValue: 55.88, minValue: -55.87 }); + this.spnTop.on('change', _.bind(function (field, newValue, oldValue) { + if (this.api) { + this.properties = (this.properties) ? this.properties : new Asc.CDocumentSectionProps(); + this.properties.put_TopMargin(Common.Utils.Metric.fnRecalcToMM(field.getNumberValue())); + //this.api.SetDrawImagePreviewMargins('page-margins-preview', this.properties); + } + }, this)); this.spinners.push(this.spnTop); this.spnBottom = new Common.UI.MetricSpinner({ @@ -118,6 +144,13 @@ define([ maxValue: 55.88, minValue: -55.87 }); + this.spnBottom.on('change', _.bind(function (field, newValue, oldValue) { + if (this.api) { + this.properties = (this.properties) ? this.properties : new Asc.CDocumentSectionProps(); + this.properties.put_BottomMargin(Common.Utils.Metric.fnRecalcToMM(field.getNumberValue())); + //this.api.SetDrawImagePreviewMargins('page-margins-preview', this.properties); + } + }, this)); this.spinners.push(this.spnBottom); this.spnLeft = new Common.UI.MetricSpinner({ @@ -129,6 +162,13 @@ define([ maxValue: 55.88, minValue: 0 }); + this.spnLeft.on('change', _.bind(function (field, newValue, oldValue) { + if (this.api) { + this.properties = (this.properties) ? this.properties : new Asc.CDocumentSectionProps(); + this.properties.put_LeftMargin(Common.Utils.Metric.fnRecalcToMM(field.getNumberValue())); + //this.api.SetDrawImagePreviewMargins('page-margins-preview', this.properties); + } + }, this)); this.spinners.push(this.spnLeft); this.spnRight = new Common.UI.MetricSpinner({ @@ -140,10 +180,102 @@ define([ maxValue: 55.88, minValue: 0 }); + this.spnRight.on('change', _.bind(function (field, newValue, oldValue) { + if (this.api) { + this.properties = (this.properties) ? this.properties : new Asc.CDocumentSectionProps(); + this.properties.put_RightMargin(Common.Utils.Metric.fnRecalcToMM(field.getNumberValue())); + //this.api.SetDrawImagePreviewMargins('page-margins-preview', this.properties); + } + }, this)); this.spinners.push(this.spnRight); - var $window = this.getChild(); - $window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this)); + this.spnGutter = new Common.UI.MetricSpinner({ + el: $('#page-margins-spin-gutter'), + step: .1, + width: 86, + defaultUnit : "cm", + value: '1 cm', + maxValue: 55.88, + minValue: 0 + }); + this.spnGutter.on('change', _.bind(function (field, newValue, oldValue) { + if (this.api) { + this.properties = (this.properties) ? this.properties : new Asc.CDocumentSectionProps(); + this.properties.put_Gutter(Common.Utils.Metric.fnRecalcToMM(field.getNumberValue())); + //this.api.SetDrawImagePreviewMargins('page-margins-preview', this.properties); + } + }, this)); + this.spinners.push(this.spnGutter); + + this.cmbGutterPosition = new Common.UI.ComboBox({ + el : $('#page-margins-spin-gutter-position'), + menuStyle : 'min-width: 86px;', + style : 'width: 86px;', + editable : false, + cls : 'input-group-nr', + data : [ + { value: 0, displayValue: this.textLeft }, + { value: 1, displayValue: this.textTop } + ] + }); + this.cmbGutterPosition.on('selected', _.bind(function (combo, record) { + if (this.api) { + this.properties = (this.properties) ? this.properties : new Asc.CDocumentSectionProps(); + this.properties.put_GutterAtTop(record.value); + //this.api.SetDrawImagePreviewMargins('page-margins-preview', this.properties); + } + }, this)); + + this.cmbOrientation = new Common.UI.ComboBox({ + el : $('#page-margins-cmb-orientation'), + menuStyle : 'min-width: 180px;', + style : 'width: 180px;', + editable : false, + cls : 'input-group-nr', + data : [ + { value: 0, displayValue: this.textPortrait }, + { value: 1, displayValue: this.textLandscape } + ] + }); + this.cmbOrientation.on('selected', _.bind(function (combo, record) { + if (this.api) { + this.properties = (this.properties) ? this.properties : new Asc.CDocumentSectionProps(); + this.properties.put_Orientation(record.value); + //this.api.SetDrawImagePreviewMargins('page-margins-preview', this.properties); + } + }, this)); + + this.cmbMultiplePages = new Common.UI.ComboBox({ + el : $('#page-margins-cmb-multiple-pages'), + menuStyle : 'min-width: 180px;', + style : 'width: 180px;', + editable : false, + cls : 'input-group-nr', + data : [ + { value: 0, displayValue: this.textNormal }, + { value: 1, displayValue: this.textMirrorMargins } + ] + }); + this.cmbMultiplePages.on('selected', _.bind(function(combo, record) { + if (record.value === 0) { + this.window.find('#margin-left-label').html(this.textLeft); + this.window.find('#margin-right-label').html(this.textRight); + this.cmbGutterPosition.setDisabled(false); + } else { + this.window.find('#margin-left-label').html(this.textInside); + this.window.find('#margin-right-label').html(this.textOutside); + this.cmbGutterPosition.setValue(0); + this.cmbGutterPosition.setDisabled(true); + } + if (this.api) { + this.properties = (this.properties) ? this.properties : new Asc.CDocumentSectionProps(); + this.properties.put_MirrorMargins(record.value); + //this.api.SetDrawImagePreviewMargins('page-margins-preview', this.properties); + } + }, this)); + + this.window = this.getChild(); + this.window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this)); this.updateMetricUnit(); }, @@ -181,6 +313,7 @@ define([ setSettings: function (props) { if (props) { + this.properties = props; this.maxMarginsH = Common.Utils.Metric.fnRecalcFromMM(props.get_H() - 2.6); this.maxMarginsW = Common.Utils.Metric.fnRecalcFromMM(props.get_W() - 12.7); this.spnTop.setMaxValue(this.maxMarginsH); @@ -192,6 +325,23 @@ define([ this.spnBottom.setValue(Common.Utils.Metric.fnRecalcFromMM(props.get_BottomMargin()), true); this.spnLeft.setValue(Common.Utils.Metric.fnRecalcFromMM(props.get_LeftMargin()), true); this.spnRight.setValue(Common.Utils.Metric.fnRecalcFromMM(props.get_RightMargin()), true); + this.cmbOrientation.setValue(props.get_Orientation()); + + this.spnGutter.setValue(Common.Utils.Metric.fnRecalcFromMM(props.get_Gutter()), true); + this.cmbGutterPosition.setValue(props.get_GutterAtTop() ? 1 : 0); + var mirrorMargins = props.get_MirrorMargins(); + this.cmbMultiplePages.setValue(mirrorMargins ? 1 : 0); + + if (mirrorMargins) { + this.window.find('#margin-left-label').html(this.textInside); + this.window.find('#margin-right-label').html(this.textOutside); + this.cmbGutterPosition.setValue(0); + } + this.cmbGutterPosition.setDisabled(mirrorMargins); + + if (this.api) { + //this.api.SetDrawImagePreviewMargins('page-margins-preview', this.properties); + } } }, @@ -201,6 +351,10 @@ define([ props.put_BottomMargin(Common.Utils.Metric.fnRecalcToMM(this.spnBottom.getNumberValue())); props.put_LeftMargin(Common.Utils.Metric.fnRecalcToMM(this.spnLeft.getNumberValue())); props.put_RightMargin(Common.Utils.Metric.fnRecalcToMM(this.spnRight.getNumberValue())); + props.put_Orientation(this.cmbOrientation.getValue()); + props.put_Gutter(Common.Utils.Metric.fnRecalcToMM(this.spnGutter.getNumberValue())); + props.put_GutterAtTop(this.cmbGutterPosition.getValue() ? true : false); + props.put_MirrorMargins(this.cmbMultiplePages.getValue() ? true : false); return props; }, @@ -221,6 +375,17 @@ define([ textRight: 'Right', notcriticalErrorTitle: 'Warning', txtMarginsW: 'Left and right margins are too high for a given page wight', - txtMarginsH: 'Top and bottom margins are too high for a given page height' + txtMarginsH: 'Top and bottom margins are too high for a given page height', + textMultiplePages: 'Multiple pages', + textGutter: 'Gutter', + textGutterPosition: 'Gutter position', + textOrientation: 'Orientation', + textPreview: 'Preview', + textPortrait: 'Portrait', + textLandscape: 'Landscape', + textMirrorMargins: 'Mirror margins', + textNormal: 'Normal', + textInside: 'Inside', + textOutside: 'Outside' }, DE.Views.PageMarginsDialog || {})) }); \ No newline at end of file diff --git a/apps/documenteditor/main/app/view/Toolbar.js b/apps/documenteditor/main/app/view/Toolbar.js index 7d3e06267..f2d27a750 100644 --- a/apps/documenteditor/main/app/view/Toolbar.js +++ b/apps/documenteditor/main/app/view/Toolbar.js @@ -480,7 +480,9 @@ define([ menu: new Common.UI.Menu({ items: [ {template: _.template('
    ')}, - {caption: this.mniCustomTable, value: 'custom'} + {caption: this.mniCustomTable, value: 'custom'}, + {caption: this.mniDrawTable, value: 'draw', checkable: true}, + {caption: this.mniEraseTable, value: 'erase', checkable: true} ] }) }); @@ -638,18 +640,43 @@ define([ items: [ { caption: this.textPlainControl, - iconCls: 'mnu-control-plain', - value: Asc.c_oAscSdtLevelType.Inline + // iconCls: 'mnu-control-plain', + value: 'plain' }, { caption: this.textRichControl, - iconCls: 'mnu-control-rich', - value: Asc.c_oAscSdtLevelType.Block + // iconCls: 'mnu-control-rich', + value: 'rich' + }, + { + caption: this.textPictureControl, + // iconCls: 'mnu-control-rich', + value: 'picture' + }, + { + caption: this.textComboboxControl, + // iconCls: 'mnu-control-rich', + value: 'combobox' + }, + { + caption: this.textDropdownControl, + // iconCls: 'mnu-control-rich', + value: 'dropdown' + }, + { + caption: this.textDateControl, + // iconCls: 'mnu-control-rich', + value: 'date' + }, + { + caption: this.textCheckboxControl, + // iconCls: 'mnu-control-rich', + value: 'checkbox' }, {caption: '--'}, { caption: this.textRemoveControl, - iconCls: 'mnu-control-remove', + // iconCls: 'mnu-control-remove', value: 'remove' }, {caption: '--'}, @@ -677,7 +704,7 @@ define([ ] }) }); - this.paragraphControls.push(this.btnContentControls); + // this.paragraphControls.push(this.btnContentControls); this.btnColumns = new Common.UI.Button({ id: 'tlbtn-columns', @@ -1928,8 +1955,7 @@ define([ this.btnMailRecepients.setVisible(mode.canCoAuthoring == true && mode.canUseMailMerge); this.listStylesAdditionalMenuItem.setVisible(mode.canEditStyles); - this.btnContentControls.menu.items[4].setVisible(mode.canEditContentControl); - this.btnContentControls.menu.items[5].setVisible(mode.canEditContentControl); + this.btnContentControls.menu.items[10].setVisible(mode.canEditContentControl); this.mnuInsertImage.items[2].setVisible(this.mode.canRequestInsertImage || this.mode.fileChoiceUrl && this.mode.fileChoiceUrl.indexOf("{documentType}")>-1); }, @@ -2149,8 +2175,8 @@ define([ tipBack: 'Back', tipInsertShape: 'Insert Autoshape', tipInsertEquation: 'Insert Equation', - mniImageFromFile: 'Image from file', - mniImageFromUrl: 'Image from url', + mniImageFromFile: 'Image from File', + mniImageFromUrl: 'Image from URL', mniCustomTable: 'Insert Custom Table', textTitleError: 'Error', textInsertPageNumber: 'Insert page number', @@ -2286,9 +2312,16 @@ define([ textEditWatermark: 'Custom Watermark', textRemWatermark: 'Remove Watermark', tipWatermark: 'Edit watermark', + textPictureControl: 'Picture', + textComboboxControl: 'Combo box', + textCheckboxControl: 'Check box', + textDropdownControl: 'Drop-down list', + textDateControl: 'Date', capBtnAddComment: 'Add Comment', capBtnInsSymbol: 'Symbol', - tipInsertSymbol: 'Insert symbol' + tipInsertSymbol: 'Insert symbol', + mniDrawTable: 'Draw table', + mniEraseTable: 'Erase table' } })(), DE.Views.Toolbar || {})); }); diff --git a/apps/documenteditor/main/index.html b/apps/documenteditor/main/index.html index 48fe2d650..b33401e7f 100644 --- a/apps/documenteditor/main/index.html +++ b/apps/documenteditor/main/index.html @@ -18,7 +18,7 @@ width: 100%; overflow: hidden; border: none; - background: #f1f1f1; + background: #e2e2e2; z-index: 1001; } @@ -101,10 +101,10 @@ .loadmask > .placeholder { background: #fbfbfb; - width: 796px; + width: 794px; margin: 46px auto; height: 100%; - border: 1px solid #dfdfdf; + border: 1px solid #bebebe; padding-top: 50px; } @@ -223,10 +223,14 @@