diff --git a/apps/common/main/lib/controller/ReviewChanges.js b/apps/common/main/lib/controller/ReviewChanges.js index 2e91f7a0be..8f6d95a61a 100644 --- a/apps/common/main/lib/controller/ReviewChanges.js +++ b/apps/common/main/lib/controller/ReviewChanges.js @@ -918,6 +918,8 @@ define([ applySettings: function(menu) { this.view && this.view.turnSpelling( Common.localStorage.getBool(this.view.appPrefix + "settings-spellcheck", true) ); this.view && this.view.turnCoAuthMode( Common.localStorage.getBool(this.view.appPrefix + "settings-coauthmode", true) ); + if ((this.appConfig.canReview || this.appConfig.canViewReview) && this.appConfig.reviewHoverMode) + this.onApiShowChange(); }, synchronizeChanges: function() { diff --git a/apps/documenteditor/forms/app/controller/ApplicationController.js b/apps/documenteditor/forms/app/controller/ApplicationController.js index 49481b2895..f2e5d60994 100644 --- a/apps/documenteditor/forms/app/controller/ApplicationController.js +++ b/apps/documenteditor/forms/app/controller/ApplicationController.js @@ -11,6 +11,8 @@ define([ 'common/main/lib/util/LocalStorage', 'common/main/lib/util/Shortcuts', 'common/main/lib/view/CopyWarningDialog', + 'common/main/lib/view/ImageFromUrlDialog', + 'common/main/lib/view/SelectFileDlg', 'common/forms/lib/view/modals', 'documenteditor/forms/app/view/ApplicationView' ], function (Viewport) { @@ -87,6 +89,7 @@ define([ this.editorConfig = {}; this.embedConfig = {}; this.appOptions = {}; + this.internalFormObj = null; if (this.api){ this.api.asc_registerCallback('asc_onError', this.onError.bind(this)); @@ -352,6 +355,9 @@ define([ this.appOptions.canRequestClose = this.editorConfig.canRequestClose; this.appOptions.canBackToFolder = (this.editorConfig.canBackToFolder!==false) && (typeof (this.editorConfig.customization) == 'object') && (typeof (this.editorConfig.customization.goback) == 'object') && (!_.isEmpty(this.editorConfig.customization.goback.url) || this.editorConfig.customization.goback.requestClose && this.appOptions.canRequestClose); + + this.appOptions.canRequestInsertImage = this.editorConfig.canRequestInsertImage; + this.appOptions.fileChoiceUrl = this.editorConfig.fileChoiceUrl; }, onExternalMessage: function(msg) { @@ -527,17 +533,7 @@ define([ this.api.SetCollaborativeMarksShowType(Asc.c_oAscCollaborativeMarksShowType.None); } - var $parent = labelDocName.parent(); - var _left_width = $parent.position().left, - _right_width = $parent.next().outerWidth(); - - if ( _left_width < _right_width ) - $parent.css('padding-left', _right_width - _left_width); - else - $parent.css('padding-right', _left_width - _right_width); - this.onLongActionBegin(Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument); - this.api.asc_LoadDocument(); this.api.Resize(); }, @@ -862,10 +858,7 @@ define([ if (lock == Asc.c_oAscSdtLockType.SdtContentLocked || lock==Asc.c_oAscSdtLockType.ContentLocked) return; } - this.api.asc_addImage(obj); - setTimeout(function(){ - me.api.asc_UncheckContentControlButtons(); - }, 500); + this.onShowImageActions(obj, x, y); break; case Asc.c_oAscContentControlSpecificType.DropDownList: case Asc.c_oAscContentControlSpecificType.ComboBox: @@ -881,6 +874,125 @@ define([ controlsContainer.hide(); }, + onShowImageActions: function(obj, x, y) { + var menu = this.imageControlMenu, + menuContainer = menu ? this.boxSdk.find(Common.Utils.String.format('#menu-container-{0}', menu.id)) : null, + me = this; + + this.internalFormObj = obj && obj.pr ? obj.pr.get_InternalId() : null; + this._fromShowContentControls = true; + Common.UI.Menu.Manager.hideAll(); + + if (!menu) { + this.imageControlMenu = menu = new Common.UI.Menu({ + maxHeight: 207, + menuAlign: 'tl-bl', + items: [ + {caption: this.mniImageFromFile, value: 'file'}, + {caption: this.mniImageFromUrl, value: 'url'}, + {caption: this.mniImageFromStorage, value: 'storage', visible: this.appOptions.canRequestInsertImage || this.appOptions.fileChoiceUrl && this.appOptions.fileChoiceUrl.indexOf("{documentType}")>-1} + ] + }); + menu.on('item:click', function(menu, item) { + setTimeout(function(){ + me.onImageSelect(menu, item); + }, 1); + setTimeout(function(){ + me.api.asc_UncheckContentControlButtons(); + }, 500); + }); + + // Prepare menu container + if (!menuContainer || menuContainer.length < 1) { + menuContainer = $(Common.Utils.String.format('', menu.id)); + this.boxSdk.append(menuContainer); + } + + menu.render(menuContainer); + menu.cmpEl.attr({tabindex: "-1"}); + menu.on('hide:after', function(){ + if (!me._fromShowContentControls) + me.api.asc_UncheckContentControlButtons(); + }); + } + menuContainer.css({left: x, top : y}); + menuContainer.attr('data-value', 'prevent-canvas-click'); + this._preventClick = true; + menu.show(); + + _.delay(function() { + menu.cmpEl.focus(); + }, 10); + this._fromShowContentControls = false; + }, + + onImageSelect: function(menu, item) { + if (item.value=='url') { + var me = this; + (new Common.Views.ImageFromUrlDialog({ + handler: function(result, value) { + if (result == 'ok') { + if (me.api) { + var checkUrl = value.replace(/ /g, ''); + if (!_.isEmpty(checkUrl)) { + me.setImageUrl(checkUrl); + } + } + } + } + })).show(); + } else if (item.value=='storage') { + Common.NotificationCenter.trigger('storage:image-load', 'control'); + } else { + if (this._isFromFile) return; + this._isFromFile = true; + this.api.asc_addImage(this.internalFormObj); + this._isFromFile = false; + } + }, + + openImageFromStorage: function(type) { + var me = this; + if (this.appOptions.canRequestInsertImage) { + Common.Gateway.requestInsertImage(type); + } else { + (new Common.Views.SelectFileDlg({ + fileChoiceUrl: this.appOptions.fileChoiceUrl.replace("{fileExt}", "").replace("{documentType}", "ImagesOnly") + })).on('selectfile', function(obj, file){ + file && (file.c = type); + !file.images && (file.images = [{fileType: file.fileType, url: file.url}]); // SelectFileDlg uses old format for inserting image + file.url = null; + me.insertImage(file); + }).show(); + } + }, + + setImageUrl: function(url, token) { + this.api.asc_SetContentControlPictureUrl(url, this.internalFormObj && this.internalFormObj.pr ? this.internalFormObj.pr.get_InternalId() : null, token); + }, + + insertImage: function(data) { // gateway + if (data && (data.url || data.images)) { + data.url && console.log("Obsolete: The 'url' parameter of the 'insertImage' method is deprecated. Please use 'images' parameter instead."); + + var arr = []; + if (data.images && data.images.length>0) { + for (var i=0; iContact %1 sales team for personal upgrade terms.", "DE.Controllers.ApplicationController.warnNoLicenseUsers": "You've reached the user limit for %1 editors. Contact %1 sales team for personal upgrade terms.", + "DE.Controllers.ApplicationController.mniImageFromFile": "Image from File", + "DE.Controllers.ApplicationController.mniImageFromStorage": "Image from Storage", + "DE.Controllers.ApplicationController.mniImageFromUrl": "Image from URL", "DE.Views.ApplicationView.textClear": "Clear All Fields", "DE.Views.ApplicationView.textCopy": "Copy", "DE.Views.ApplicationView.textCut": "Cut", diff --git a/apps/documenteditor/forms/locale/ru.json b/apps/documenteditor/forms/locale/ru.json index 1c8bc41a35..f91f3872d6 100644 --- a/apps/documenteditor/forms/locale/ru.json +++ b/apps/documenteditor/forms/locale/ru.json @@ -112,6 +112,9 @@ "DE.Controllers.ApplicationController.warnLicenseUsersExceeded": "Вы достигли лимита на количество пользователей редакторов %1. Свяжитесь с администратором, чтобы узнать больше.", "DE.Controllers.ApplicationController.warnNoLicense": "Вы достигли лимита на одновременные подключения к редакторам %1. Этот документ будет открыт на просмотр.
Напишите в отдел продаж %1, чтобы обсудить индивидуальные условия лицензирования.", "DE.Controllers.ApplicationController.warnNoLicenseUsers": "Вы достигли лимита на количество пользователей редакторов %1. Напишите в отдел продаж %1, чтобы обсудить индивидуальные условия обновления.", + "DE.Controllers.ApplicationController.mniImageFromFile": "Изображение из файла", + "DE.Controllers.ApplicationController.mniImageFromStorage": "Изображение из хранилища", + "DE.Controllers.ApplicationController.mniImageFromUrl": "Изображение по URL", "DE.Views.ApplicationView.textClear": "Очистить все поля", "DE.Views.ApplicationView.textCopy": "Копировать", "DE.Views.ApplicationView.textCut": "Вырезать", diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js index 59fab48b4e..45ae88fe9f 100644 --- a/apps/documenteditor/main/app/controller/Toolbar.js +++ b/apps/documenteditor/main/app/controller/Toolbar.js @@ -3117,6 +3117,7 @@ define([ this.api && this.api.asc_StartMailMerge(); } else if (item.value === 'url') { (new Common.Views.ImageFromUrlDialog({ + title: me.dataUrl, handler: function(result, value) { if (result == 'ok') { if (me.api) { @@ -3654,7 +3655,8 @@ define([ textInsert: 'Insert', textTabForms: 'Forms', textGroup: 'Group', - textEmptyMMergeUrl: 'You need to specify URL.' + textEmptyMMergeUrl: 'You need to specify URL.', + dataUrl: 'Paste a data URL' }, DE.Controllers.Toolbar || {})); }); diff --git a/apps/documenteditor/main/app/view/DocumentHolder.js b/apps/documenteditor/main/app/view/DocumentHolder.js index 01e9ac9172..9b0c979cb4 100644 --- a/apps/documenteditor/main/app/view/DocumentHolder.js +++ b/apps/documenteditor/main/app/view/DocumentHolder.js @@ -533,6 +533,8 @@ define([ ToolTip = ''+ Common.Utils.String.htmlEncode(AscCommon.UserInfoParser.getParsedName(changes.get('username'))) +' '; ToolTip += ''+ changes.get('date') +'
'; ToolTip += changes.get('changetext'); + if (ToolTip.length>1000) + ToolTip = ToolTip.substr(0, 1000) + '...'; } } diff --git a/apps/documenteditor/main/app/view/Statusbar.js b/apps/documenteditor/main/app/view/Statusbar.js index 55b69d8c3e..0c67939551 100644 --- a/apps/documenteditor/main/app/view/Statusbar.js +++ b/apps/documenteditor/main/app/view/Statusbar.js @@ -252,7 +252,10 @@ define([ { caption: "125%", value: 125 }, { caption: "150%", value: 150 }, { caption: "175%", value: 175 }, - { caption: "200%", value: 200 } + { caption: "200%", value: 200 }, + { caption: "300%", value: 300 }, + { caption: "400%", value: 400 }, + { caption: "500%", value: 500 } ] }); diff --git a/apps/documenteditor/main/locale/en.json b/apps/documenteditor/main/locale/en.json index 53e3ca58d7..fb17e2cb59 100644 --- a/apps/documenteditor/main/locale/en.json +++ b/apps/documenteditor/main/locale/en.json @@ -1223,6 +1223,7 @@ "DE.Controllers.Toolbar.txtSymbol_vdots": "Vertical ellipsis", "DE.Controllers.Toolbar.txtSymbol_xsi": "Xi", "DE.Controllers.Toolbar.txtSymbol_zeta": "Zeta", + "DE.Controllers.Toolbar.dataUrl": "Paste a data URL", "DE.Controllers.Viewport.textFitPage": "Fit to Page", "DE.Controllers.Viewport.textFitWidth": "Fit to Width", "DE.Controllers.Viewport.txtDarkMode": "Dark mode", diff --git a/apps/documenteditor/main/locale/ru.json b/apps/documenteditor/main/locale/ru.json index 3d4ca24991..a8fc566d16 100644 --- a/apps/documenteditor/main/locale/ru.json +++ b/apps/documenteditor/main/locale/ru.json @@ -1223,6 +1223,7 @@ "DE.Controllers.Toolbar.txtSymbol_vdots": "Вертикальное многоточие", "DE.Controllers.Toolbar.txtSymbol_xsi": "Кси", "DE.Controllers.Toolbar.txtSymbol_zeta": "Дзета", + "DE.Controllers.Toolbar.dataUrl": "Вставьте URL-адрес данных", "DE.Controllers.Viewport.textFitPage": "По размеру страницы", "DE.Controllers.Viewport.textFitWidth": "По ширине", "DE.Controllers.Viewport.txtDarkMode": "Темный режим", diff --git a/apps/presentationeditor/main/app/view/Statusbar.js b/apps/presentationeditor/main/app/view/Statusbar.js index 8fb959e11b..a4e431da97 100644 --- a/apps/presentationeditor/main/app/view/Statusbar.js +++ b/apps/presentationeditor/main/app/view/Statusbar.js @@ -155,7 +155,10 @@ define([ { caption: "125%", value: 125 }, { caption: "150%", value: 150 }, { caption: "175%", value: 175 }, - { caption: "200%", value: 200 } + { caption: "200%", value: 200 }, + { caption: "300%", value: 300 }, + { caption: "400%", value: 400 }, + { caption: "500%", value: 500 } ] }); this.zoomMenu.render($('.cnt-zoom',this.el)); diff --git a/apps/spreadsheeteditor/main/app/view/Statusbar.js b/apps/spreadsheeteditor/main/app/view/Statusbar.js index 08a1f9cde8..2a9ba723b4 100644 --- a/apps/spreadsheeteditor/main/app/view/Statusbar.js +++ b/apps/spreadsheeteditor/main/app/view/Statusbar.js @@ -192,7 +192,10 @@ define([ { caption: "125%", value: 125 }, { caption: "150%", value: 150 }, { caption: "175%", value: 175 }, - { caption: "200%", value: 200 } + { caption: "200%", value: 200 }, + { caption: "300%", value: 300 }, + { caption: "400%", value: 400 }, + { caption: "500%", value: 500 } ] }); this.zoomMenu.render($('.cnt-zoom',this.el)); diff --git a/apps/spreadsheeteditor/main/app/view/ViewTab.js b/apps/spreadsheeteditor/main/app/view/ViewTab.js index a73c5b6086..24fea701db 100644 --- a/apps/spreadsheeteditor/main/app/view/ViewTab.js +++ b/apps/spreadsheeteditor/main/app/view/ViewTab.js @@ -159,7 +159,10 @@ define([ { displayValue: "125%", value: 125 }, { displayValue: "150%", value: 150 }, { displayValue: "175%", value: 175 }, - { displayValue: "200%", value: 200 } + { displayValue: "200%", value: 200 }, + { displayValue: "300%", value: 300 }, + { displayValue: "400%", value: 400 }, + { displayValue: "500%", value: 500 } ], dataHint : '1', dataHintDirection: 'top',