diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js index 8743ff9d9..6a68577cc 100644 --- a/apps/api/documents/api.js +++ b/apps/api/documents/api.js @@ -362,10 +362,11 @@ if (!!result && result.length) { if (result[1] == 'desktop') { _config.editorConfig.targetApp = result[1]; - _config.editorConfig.canBackToFolder = false; - _config.editorConfig.canUseHistory = false; + // _config.editorConfig.canBackToFolder = false; if (!_config.editorConfig.customization) _config.editorConfig.customization = {}; _config.editorConfig.customization.about = false; + + if ( window.AscDesktopEditor ) window.AscDesktopEditor.execCommand('webapps:events', 'loading'); } } })(); diff --git a/apps/api/documents/index.html.desktop b/apps/api/documents/index.html.desktop index 454ad8a28..28857deae 100644 --- a/apps/api/documents/index.html.desktop +++ b/apps/api/documents/index.html.desktop @@ -55,7 +55,10 @@ height: '100%', documentType: urlParams['doctype'] || 'text', document: doc, - editorConfig: cfg + editorConfig: cfg, + events: { + onInternalMessage: onInternalMessage, + } }); @@ -91,6 +94,9 @@ function getEditorConfig(urlParams) { return { + customization : { + goback: { url: "onlyoffice.com" } + }, mode : urlParams["mode"] || 'edit', lang : urlParams["lang"] || 'en', user: { @@ -144,6 +150,21 @@ } }; + function onInternalMessage(event) { + let info = event.data; + if ( info.type == 'goback' ) { + if ( window.AscDesktopEditor ) { + window.AscDesktopEditor.execCommand('go:folder', info.data.status); + } + } + }; + + function onDocumentReady() { + if ( window.AscDesktopEditor ) { + window.AscDesktopEditor.execCommand('doc:onready', ''); + } + } + if (isMobile()){ window.addEventListener('load', fixSize); window.addEventListener('resize', fixSize); diff --git a/apps/common/main/lib/component/Button.js b/apps/common/main/lib/component/Button.js index c766a8d7e..f1c5de25b 100644 --- a/apps/common/main/lib/component/Button.js +++ b/apps/common/main/lib/component/Button.js @@ -119,6 +119,65 @@ define([ ], function () { 'use strict'; + window.createButtonSet = function() { + function ButtonsArray(args) {}; + ButtonsArray.prototype = new Array; + ButtonsArray.prototype.constructor = ButtonsArray; + + var _disabled = false; + + ButtonsArray.prototype.add = function(button) { + button.setDisabled(_disabled); + this.push(button); + }; + + ButtonsArray.prototype.setDisabled = function(disable) { + if ( _disabled != disable ) { + _disabled = disable; + + this.forEach( function(button) { + button.setDisabled(disable); + }); + } + }; + + ButtonsArray.prototype.toggle = function(state, suppress) { + this.forEach(function(button) { + button.toggle(state, suppress); + }); + }; + + ButtonsArray.prototype.pressed = function() { + return this.some(function(button) { + return button.pressed; + }); + }; + + ButtonsArray.prototype.contains = function(id) { + return this.some(function(button) { + return button.id == id; + }); + }; + + ButtonsArray.prototype.concat = function () { + var args = Array.prototype.slice.call(arguments); + var result = Array.prototype.slice.call(this); + + args.forEach(function(sub){ + Array.prototype.push.apply(result, sub); + }); + + return result; + } + + var _out_array = Object.create(ButtonsArray.prototype); + for ( var i in arguments ) { + _out_array.add(arguments[i]); + } + + return _out_array; + }; + var templateBtnIcon = '<% if ( iconImg ) { %>' + '' + @@ -291,6 +350,7 @@ define([ me.menu.render(me.cmpEl); parentEl.html(me.cmpEl); + me.$icon = me.$el.find('.icon'); } } @@ -536,6 +596,13 @@ define([ } } } + + if ( !!me.options.signals ) { + var opts = me.options.signals; + if ( !(opts.indexOf('disabled') < 0) ) { + me.trigger('disabled', me, disabled); + } + } } this.disabled = disabled; diff --git a/apps/common/main/lib/component/DataView.js b/apps/common/main/lib/component/DataView.js index 0d75d97fa..210e829ab 100644 --- a/apps/common/main/lib/component/DataView.js +++ b/apps/common/main/lib/component/DataView.js @@ -140,9 +140,10 @@ define([ el.html(this.template(this.model.toJSON())); el.addClass('item'); el.toggleClass('selected', this.model.get('selected') && this.model.get('allowSelected')); - el.off('click').on('click', _.bind(this.onClick, this)); - el.off('dblclick').on('dblclick', _.bind(this.onDblClick, this)); - el.off('contextmenu').on('contextmenu', _.bind(this.onContextMenu, this)); + el.off('click dblclick contextmenu'); + el.on({ 'click': _.bind(this.onClick, this), + 'dblclick': _.bind(this.onDblClick, this), + 'contextmenu': _.bind(this.onContextMenu, this) }); el.toggleClass('disabled', !!this.model.get('disabled')); if (!_.isUndefined(this.model.get('cls'))) diff --git a/apps/common/main/lib/component/Layout.js b/apps/common/main/lib/component/Layout.js index e620f4820..3a58b30fa 100644 --- a/apps/common/main/lib/component/Layout.js +++ b/apps/common/main/lib/component/Layout.js @@ -187,6 +187,13 @@ define([ return parseInt(el.css('width')); }, + getItem: function (alias) { + for (var p in this.panels) { + var panel = this.panels[p]; + if ( panel.alias == alias ) return panel; + } + }, + onSelectStart: function(e) { if (e.preventDefault) e.preventDefault(); return false; diff --git a/apps/common/main/lib/component/Mixtbar.js b/apps/common/main/lib/component/Mixtbar.js index f9c921d8c..efa156028 100644 --- a/apps/common/main/lib/component/Mixtbar.js +++ b/apps/common/main/lib/component/Mixtbar.js @@ -257,7 +257,7 @@ define([ return config.tabs[index].action; } - var _tabTemplate = _.template(''); + var _tabTemplate = _.template(''); config.tabs[after + 1] = tab; var _after_action = _get_tab_action(after); diff --git a/apps/common/main/lib/controller/Desktop.js b/apps/common/main/lib/controller/Desktop.js new file mode 100644 index 000000000..add4de842 --- /dev/null +++ b/apps/common/main/lib/controller/Desktop.js @@ -0,0 +1,73 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +/** + * Controller wraps up interaction with desktop app + * + * Created by Maxim.Kadushkin on 2/16/2018. + */ + +define([ + 'core' +], function () { + 'use strict'; + + var Desktop = function () { + var config = {}; + var app = window.AscDesktopEditor; + + return { + init: function (opts) { + _.extend(config, opts); + + if ( config.isDesktopApp ) { + Common.NotificationCenter.on('app:ready', function (config) { + !!app && app.execCommand('doc:onready', ''); + }); + } + }, + process: function (opts) { + if ( opts == 'goback' ) { + if ( config.isDesktopApp && !!app ) { + app.execCommand('go:folder', + config.isOffline ? 'offline' : config.customization.goback.url); + return true; + } + + return false; + } + } + }; + }; + + Common.Controllers.Desktop = new Desktop(); +}); \ No newline at end of file diff --git a/apps/common/main/lib/util/utils.js b/apps/common/main/lib/util/utils.js index 190e8c80c..0d2bf70f9 100644 --- a/apps/common/main/lib/util/utils.js +++ b/apps/common/main/lib/util/utils.js @@ -758,14 +758,22 @@ Common.Utils.InternalSettings = new(function() { var settings = {}; var _get = function(name) { - return settings[name]; - }, - _set = function(name, value) { - settings[name] = value; - }; + return settings[name]; + }, + _set = function(name, value) { + settings[name] = value; + }; return { get: _get, set: _set } -}); \ No newline at end of file +}); + +Common.Utils.InternalSettings.set('toolbar-height-tabs', 32); +Common.Utils.InternalSettings.set('toolbar-height-tabs-top-title', 28); +Common.Utils.InternalSettings.set('toolbar-height-controls', 67); +Common.Utils.InternalSettings.set('document-title-height', 28); + +Common.Utils.InternalSettings.set('toolbar-height-compact', Common.Utils.InternalSettings.get('toolbar-height-tabs')); +Common.Utils.InternalSettings.set('toolbar-height-normal', Common.Utils.InternalSettings.get('toolbar-height-tabs') + Common.Utils.InternalSettings.get('toolbar-height-controls')); diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js index ca5fe4918..6ebc539ba 100644 --- a/apps/common/main/lib/view/Header.js +++ b/apps/common/main/lib/view/Header.js @@ -71,7 +71,7 @@ define([ var templateRightBox = '
' + '
' + - '' + + '' + '
' + '<%= textSaveEnd %>' + '
' + @@ -95,6 +95,7 @@ define([ '
' + '
' + '
' + + '
' + '
' + '
'; @@ -102,6 +103,18 @@ define([ '' + ''; + var templateTitleBox = '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '' + + '' + + '
'; + function onAddUser(model, collection, opts) { if ( $userList ) { var $ul = $userList.find('ul'); @@ -204,6 +217,8 @@ define([ } } + function onAppShowed(config) {} + function onAppReady(mode) { appConfig = mode; @@ -261,6 +276,34 @@ define([ } } + if ( me.btnPrint ) { + me.btnPrint.updateHint(me.tipPrint + Common.Utils.String.platformKey('Ctrl+P')); + me.btnPrint.on('click', function (e) { + me.fireEvent('print', me); + }); + } + + if ( me.btnSave ) { + me.btnSave.updateHint(me.tipSave + Common.Utils.String.platformKey('Ctrl+S')); + me.btnSave.on('click', function (e) { + me.fireEvent('save', me); + }); + } + + if ( me.btnUndo ) { + me.btnUndo.updateHint(me.tipUndo + Common.Utils.String.platformKey('Ctrl+Z')); + me.btnUndo.on('click', function (e) { + me.fireEvent('undo', me); + }); + } + + if ( me.btnRedo ) { + me.btnRedo.updateHint(me.tipRedo + Common.Utils.String.platformKey('Ctrl+Y')); + me.btnRedo.on('click', function (e) { + me.fireEvent('redo', me); + }); + } + if ( !mode.isEdit ) { if ( me.btnDownload ) { me.btnDownload.updateHint(me.tipDownload); @@ -269,13 +312,6 @@ define([ }); } - if ( me.btnPrint ) { - me.btnPrint.updateHint(me.tipPrint + Common.Utils.String.platformKey('Ctrl+P')); - me.btnPrint.on('click', function (e) { - me.fireEvent('print', me); - }); - } - if ( me.btnEdit ) { me.btnEdit.updateHint(me.tipGoEdit); me.btnEdit.on('click', function (e) { @@ -283,6 +319,9 @@ define([ }); } } + + if ( me.btnOptions ) + me.btnOptions.updateHint(me.tipViewSettings); } function onDocNameKeyDown(e) { @@ -322,7 +361,6 @@ define([ return { options: { branding: {}, - headerCaption: 'Default Caption', documentCaption: '', canBack: false }, @@ -339,11 +377,9 @@ define([ initialize: function (options) { var me = this; - this.options = this.options ? _({}).extend(this.options, options) : options; + this.options = this.options ? _.extend(this.options, options) : options; - this.headerCaption = this.options.headerCaption; this.documentCaption = this.options.documentCaption; - this.canBack = this.options.canBack; this.branding = this.options.customization; this.isModified = false; @@ -361,9 +397,20 @@ define([ reset : onResetUsers }); + me.btnOptions = new Common.UI.Button({ + cls: 'btn-header no-caret', + iconCls: 'svgicon svg-btn-options', + menu: true + }); + + me.mnuZoom = {options: {value: 100}}; + Common.NotificationCenter.on('app:ready', function(mode) { Common.Utils.asyncCall(onAppReady, me, mode); }); + Common.NotificationCenter.on('app:face', function(mode) { + Common.Utils.asyncCall(onAppShowed, me, mode); + }); }, render: function (el, role) { @@ -373,6 +420,16 @@ define([ }, getPanel: function (role, config) { + var me = this; + + function createTitleButton(iconid, slot, disabled) { + return (new Common.UI.Button({ + cls: 'btn-header', + iconCls: 'svgicon ' + iconid, + disabled: disabled === true + })).render(slot); + } + if ( role == 'left' && (!config || !config.isDesktopApp)) { $html = $(templateLeftBox); this.logo = $html.find('#header-logo'); @@ -391,64 +448,43 @@ define([ textSaveEnd: this.textSaveEnd })); - if ( this.labelDocName ) this.labelDocName.off(); - this.labelDocName = $html.find('#rib-doc-name'); - // this.labelDocName.attr('maxlength', 50); - this.labelDocName.text = function (text) { - this.val(text).attr('size', text.length); - } + if ( !me.labelDocName ) { + me.labelDocName = $html.find('#rib-doc-name'); + // this.labelDocName.attr('maxlength', 50); + me.labelDocName.text = function (text) { + this.val(text).attr('size', text.length); + } - if ( this.documentCaption ) { - this.labelDocName.text( this.documentCaption ); + if ( me.documentCaption ) { + me.labelDocName.text(me.documentCaption); + } } if ( !_.isUndefined(this.options.canRename) ) { this.setCanRename(this.options.canRename); } - $saveStatus = $html.find('#rib-save-status'); - $saveStatus.hide(); + // $saveStatus = $html.find('#rib-save-status'); + $html.find('#rib-save-status').hide(); + // if ( config.isOffline ) $saveStatus = false; - if ( config && config.isDesktopApp ) { - $html.addClass('desktop'); - $html.find('#slot-btn-back').hide(); - this.labelDocName.hide(); - - if ( config.isOffline ) - $saveStatus = false; + if ( this.options.canBack === true ) { + me.btnGoBack.render($html.find('#slot-btn-back')); } else { - if ( this.canBack === true ) { - this.btnGoBack.render($html.find('#slot-btn-back')); - } else { - $html.find('#slot-btn-back').hide(); - } + $html.find('#slot-btn-back').hide(); } if ( !config.isEdit ) { - if ( (config.canDownload || config.canDownloadOrigin) && !config.isOffline ) { - this.btnDownload = new Common.UI.Button({ - cls: 'btn-header', - iconCls: 'svgicon svg-btn-download' - }); + if ( (config.canDownload || config.canDownloadOrigin) && !config.isOffline ) + this.btnDownload = createTitleButton('svg-btn-download', $html.find('#slot-hbtn-download')); - this.btnDownload.render($html.find('#slot-hbtn-download')); - } + if ( config.canPrint ) + this.btnPrint = createTitleButton('svg-btn-print', $html.find('#slot-hbtn-print')); - if ( config.canPrint ) { - this.btnPrint = new Common.UI.Button({ - cls: 'btn-header', - iconCls: 'svgicon svg-btn-print' - }); - - this.btnPrint.render($html.find('#slot-hbtn-print')); - } - - if ( config.canEdit && config.canRequestEditRights ) { - (this.btnEdit = new Common.UI.Button({ - cls: 'btn-header', - iconCls: 'svgicon svg-btn-edit' - })).render($html.find('#slot-hbtn-edit')); - } + if ( config.canEdit && config.canRequestEditRights ) + this.btnEdit = createTitleButton('svg-btn-edit', $html.find('#slot-hbtn-edit')); + } else { + me.btnOptions.render($html.find('#slot-btn-options')); } $userList = $html.find('.cousers-list'); @@ -457,6 +493,40 @@ define([ $panelUsers.hide(); + return $html; + } else + if ( role == 'title' ) { + var $html = $(_.template(templateTitleBox)()); + + !!me.labelDocName && me.labelDocName.hide().off(); // hide document title if it was created in right box + me.labelDocName = $html.find('> #title-doc-name'); + me.labelDocName.text = function (str) {this.val(str);}; // redefine text function to lock temporaly rename docuemnt option + me.labelDocName.text( me.documentCaption ); + + me.labelUserName = $('> #title-user-name', $html); + me.setUserName(me.options.userName); + + if ( config.canPrint && config.isEdit ) { + me.btnPrint = createTitleButton('svg-btn-print', $('#slot-btn-dt-print', $html)); + } + + me.btnSave = createTitleButton('svg-btn-save', $('#slot-btn-dt-save', $html), true); + me.btnUndo = createTitleButton('svg-btn-undo', $('#slot-btn-dt-undo', $html), true); + me.btnRedo = createTitleButton('svg-btn-redo', $('#slot-btn-dt-redo', $html), true); + + if ( me.btnSave.$icon.is('svg') ) { + me.btnSave.$icon.addClass('icon-save'); + var _create_use = function (extid, intid) { + var _use = document.createElementNS('http://www.w3.org/2000/svg', 'use'); + _use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', extid); + _use.setAttribute('id', intid); + + return $(_use); + }; + + _create_use('#svg-btn-save-coauth', 'coauth').appendTo(me.btnSave.$icon); + _create_use('#svg-btn-save-sync', 'sync').appendTo(me.btnSave.$icon); + } return $html; } }, @@ -483,16 +553,6 @@ define([ } }, - setHeaderCaption: function (value) { - this.headerCaption = value; - - return value; - }, - - getHeaderCaption: function () { - return this.headerCaption; - }, - setDocumentCaption: function(value) { !value && (value = ''); @@ -522,15 +582,16 @@ define([ }, setCanBack: function (value, text) { - this.canBack = value; - + this.options.canBack = value; this.btnGoBack[value ? 'show' : 'hide'](); if (value) this.btnGoBack.updateHint((text && typeof text == 'string') ? text : this.textBack); + + return this; }, getCanBack: function () { - return this.canBack; + return this.options.canBack; }, setCanRename: function (rename) { @@ -581,6 +642,61 @@ define([ } }, + setUserName: function(name) { + if ( !!this.labelUserName ) { + if ( !!name ) { + this.labelUserName.text(name).show(); + } else this.labelUserName.hide(); + } else { + this.options.userName = name; + } + + return this; + }, + + getButton: function(type) { + if (type == 'save') + return this.btnSave; + }, + + lockHeaderBtns: function (alias, lock) { + var me = this; + if ( alias == 'users' ) { + if ( lock ) + $btnUsers.addClass('disabled').attr('disabled', 'disabled'); else + $btnUsers.removeClass('disabled').attr('disabled', ''); + } else { + function _lockButton(btn) { + if ( btn ) { + if ( lock ) { + btn.keepState = { + disabled: btn.isDisabled() + }; + btn.setDisabled( true ); + } else { + btn.setDisabled( btn.keepState.disabled ); + delete btn.keepState; + } + } + } + + switch ( alias ) { + case 'undo': _lockButton(me.btnUndo); break; + case 'redo': _lockButton(me.btnRedo); break; + case 'opts': _lockButton(me.btnOptions); break; + default: break; + } + } + }, + + fakeMenuItem: function() { + return { + conf: {checked: false}, + setChecked: function (val) { this.conf.checked = val; }, + isChecked: function () { return this.conf.checked; } + }; + }, + textBack: 'Go to Documents', txtRename: 'Rename', textSaveBegin: 'Saving...', @@ -593,7 +709,16 @@ define([ tipViewUsers: 'View users and manage document access rights', tipDownload: 'Download file', tipPrint: 'Print file', - tipGoEdit: 'Edit current file' + tipGoEdit: 'Edit current file', + tipSave: 'Save', + tipUndo: 'Undo', + tipRedo: 'Redo', + textCompactView: 'Hide Toolbar', + textHideStatusBar: 'Hide Status Bar', + textHideLines: 'Hide Rulers', + textZoom: 'Zoom', + textAdvSettings: 'Advanced Settings', + tipViewSettings: 'View Settings' } }(), Common.Views.Header || {})) }); diff --git a/apps/common/main/resources/img/header/buttons.svg b/apps/common/main/resources/img/header/buttons.svg index 3b82b4ee7..637a73f15 100644 --- a/apps/common/main/resources/img/header/buttons.svg +++ b/apps/common/main/resources/img/header/buttons.svg @@ -11,10 +11,10 @@ - - - - + + + + @@ -32,4 +32,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less index b105a0702..782457e60 100644 --- a/apps/common/main/resources/less/header.less +++ b/apps/common/main/resources/less/header.less @@ -43,7 +43,6 @@ line-height: 20px; height: 100%; display: flex; - align-items: center; } &.left { @@ -53,11 +52,6 @@ &.right { flex-grow: 1; min-width: 100px; - - .desktop { - padding: 10px 0; - text-align: right; - } } .status-label { @@ -68,6 +62,12 @@ color: #fff; } + .dropdown-menu { + label { + color: @gray-deep; + } + } + .btn-users, .btn-header { &:hover { @@ -76,7 +76,7 @@ } } - &:active { + &:active, &.active { &:not(.disabled) { background-color: rgba(0,0,0,0.2); } @@ -85,7 +85,7 @@ #box-doc-name { flex-grow: 1; - text-align: center; + display: flex; } #rib-doc-name { @@ -151,7 +151,6 @@ } #tlb-box-users { - height: @height-tabs; } #tlb-change-rights { @@ -159,9 +158,11 @@ } .btn-users { - display: inline-flex; + display: flex; + align-items: center; cursor: pointer; - padding: 6px 12px; + padding: 0 12px; + height: 100%; .icon { display: inline-block; @@ -173,6 +174,11 @@ cursor: pointer; font-size: 14px; } + + &.disabled { + opacity: 0.65; + pointer-events: none; + } } .cousers-menu { @@ -185,6 +191,12 @@ width: 285px; font-size: 12px; + z-index: 1042; + + .top-title & { + top: @height-title + @height-tabs - 8px; + } + > label { white-space: normal; } @@ -235,16 +247,113 @@ .hedset { font-size: 0; + display: flex; + + .btn-group { + height: 100%; + } + } .btn-header { - border: 0 none; - height: @height-tabs; + height: 100%; background-color: transparent; - padding: 6px 12px; + width: 40px; .icon { width: 20px; height: 20px; } -} \ No newline at end of file + + svg.icon { + display: inline-block; + vertical-align: middle; + } + + .btn&[disabled], + &.disabled { + opacity: 0.65; + } + + &:hover { + &:not(.disabled) { + background-color: rgba(255,255,255,0.2); + } + } + + &:active { + &:not(.disabled) { + background-color: rgba(0,0,0,0.2); + } + } + + &.no-caret { + .inner-box-caret { + display: none; + } + } +} + +#box-document-title { + background-color: @tabs-bg-color; + display: flex; + height: 100%; + color:#fff; + position: relative; + + .btn-slot { + display: inline-block; + } + + svg.icon { + fill: #fff; + + &.icon-save { + &.btn-save-coauth, &.btn-synch { + use:first-child { + display: none; + } + } + + &:not(.btn-save-coauth) { + use#coauth { + display: none; + } + } + &:not(.btn-synch) { + use#sync { + display: none; + } + } + } + } + + #title-doc-name { + position: absolute; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + text-align: center; + font-size: 12px; + height: 100%; + width: 100%; + background-color: transparent; + border: 0 none; + cursor: default; + } + #title-user-name { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + text-align: right; + font-size: 11px; + max-width: 50%; + height: 100%; + padding: 0 12px; + line-height: @height-title; + } + + .lr-separator { + flex-grow: 1; + } +} diff --git a/apps/common/main/resources/less/synchronize-tip.less b/apps/common/main/resources/less/synchronize-tip.less index df5b141c9..b018a7aff 100644 --- a/apps/common/main/resources/less/synchronize-tip.less +++ b/apps/common/main/resources/less/synchronize-tip.less @@ -9,16 +9,19 @@ } &.right { - margin: -32px 0 0 15px; + margin: 0 0 0 15px; .tip-arrow { left: -15px; - top: 20px; - width: 15px; - height: 30px; + top: 0; + width: 16px; + height: 15px; + .box-shadow(0 -5px 8px -5px rgba(0, 0, 0, 0.2)); + &:after { - top: 5px; - left: 8px; + top: -7px; + left: 6px; + width: 16px; } } } @@ -42,13 +45,15 @@ margin: 0 -32px 15px 0; .tip-arrow { - right: 15px; + right: 0; bottom: -15px; - width: 30px; + width: 15px; height: 15px; + .box-shadow(5px 0 8px -5px rgba(0, 0, 0, 0.2)); + &:after { top: -8px; - left: 5px; + left: 8px; } } } @@ -60,6 +65,14 @@ background-color: #fcfed7; overflow: visible; + .right & { + border-top-left-radius: 0; + } + + .top & { + border-bottom-right-radius: 0; + } + .box-shadow(0 4px 15px -2px rgba(0, 0, 0, 0.5)); font-size: 11px; } diff --git a/apps/common/main/resources/less/toolbar.less b/apps/common/main/resources/less/toolbar.less index 96baf8e3f..4d9c22a4d 100644 --- a/apps/common/main/resources/less/toolbar.less +++ b/apps/common/main/resources/less/toolbar.less @@ -1,3 +1,4 @@ +@height-title: 28px; @height-tabs: 32px; @height-controls: 67px; @@ -21,11 +22,11 @@ } &:not(.expanded):not(.cover){ - .ribtab.active { - > a { - font-weight: normal; + .ribtab.active { + > a { + font-weight: normal; + } } - } } } @@ -58,90 +59,73 @@ overflow: hidden; display: flex; - > ul { - padding: 0; - margin: 0; - white-space: nowrap; - overflow: hidden; - list-style: none; - font-size: 0; - } - - li { - display: inline-block; - height: 100%; - //background-color: #a6c995; - - position: relative; - .tab-bg { - position: absolute; - height: 28px; - width: 100%; - top: 4px; - background-color: @tabs-bg-color; + > ul { + padding: 4px 0 0; + margin: 0; + white-space: nowrap; + overflow: hidden; + list-style: none; + font-size: 0; } - &:hover { - .tab-bg { + li { + display: inline-flex; + align-items: center; + height: 100%; + + &:hover { background-color: rgba(255,255,255,0.2); } - } - &.active { - .tab-bg { + &.active { background-color: @gray-light; } + + + > a { + display: inline-block; + padding: 0 12px; + text-decoration: none; + cursor: default; + font-size: 12px; + text-align: center; + color: #fff; + } + + &.active { + > a { + color: #444; + } + } } - - > a { - display: inline-block; - line-height: @height-tabs; - height: 100%; - padding: 1px 12px; - text-decoration: none; - cursor: default; - font-size: 12px; - text-align: center; - color: #fff; - - position: relative; - } - - &.active { - > a { - color: #444; + &:not(.short) { + .scroll { + display: none; + } + } + + .scroll { + line-height: @height-tabs; + min-width: 20px; + text-align: center; + z-index: 1; + cursor: pointer; + color: #fff; + + &:hover { + text-decoration: none; + } + + &.left{ + box-shadow: 5px 0 20px 5px @tabs-bg-color + } + &.right{ + box-shadow: -5px 0 20px 5px @tabs-bg-color + } } - } } - &:not(.short) { - .scroll { - display: none; - } - } - - .scroll { - line-height: @height-tabs; - min-width: 20px; - text-align: center; - z-index: 1; - cursor: pointer; - color: #fff; - - &:hover { - text-decoration: none; - } - - &.left{ - box-shadow: 5px 0 20px 5px @tabs-bg-color - } - &.right{ - box-shadow: -5px 0 20px 5px @tabs-bg-color - } - } - } - .box-controls { //height: @height-controls; // button has strange offset in IE when odd height padding: 10px 0; @@ -229,11 +213,33 @@ margin-top: 3px; } } + + .top-title > & { + &:not(.folded) { + height: 28 + @height-controls; + } + + &.folded { + height: 28px; + + &.expanded { + height: 28 + @height-controls; + } + } + + .tabs > ul { + padding-top: 0; + } + + .box-tabs { + height: 28px; + } + } + } .toolbar-fullview-panel { position: absolute; - top: @height-tabs; bottom: 0; width: 100%; z-index: 1041; diff --git a/apps/documenteditor/main/app.js b/apps/documenteditor/main/app.js index f5e4e8fbc..a996e4714 100644 --- a/apps/documenteditor/main/app.js +++ b/apps/documenteditor/main/app.js @@ -203,6 +203,7 @@ require([ ,'common/main/lib/controller/ExternalMergeEditor' ,'common/main/lib/controller/ReviewChanges' ,'common/main/lib/controller/Protection' + ,'common/main/lib/controller/Desktop' ], function() { app.start(); }); diff --git a/apps/documenteditor/main/app/collection/ShapeGroups.js b/apps/documenteditor/main/app/collection/ShapeGroups.js index f453d8f93..40ae2e80f 100644 --- a/apps/documenteditor/main/app/collection/ShapeGroups.js +++ b/apps/documenteditor/main/app/collection/ShapeGroups.js @@ -46,6 +46,7 @@ define([ var Common = {}; Common.Collections = Common.Collections || {}; + DE.Collections = DE.Collections || {}; DE.Collections.ShapeGroups = Backbone.Collection.extend({ model: DE.Models.ShapeGroup diff --git a/apps/documenteditor/main/app/controller/LeftMenu.js b/apps/documenteditor/main/app/controller/LeftMenu.js index e7a349a7b..2be1b2a1c 100644 --- a/apps/documenteditor/main/app/controller/LeftMenu.js +++ b/apps/documenteditor/main/app/controller/LeftMenu.js @@ -62,6 +62,7 @@ define([ }, 'Common.Views.Header': { 'click:users': _.bind(this.clickStatusbarUsers, this), + 'file:settings': _.bind(this.clickToolbarSettings,this), 'history:show': function () { if ( !this.leftMenu.panelHistory.isVisible() ) this.clickMenuFileItem('header', 'history'); @@ -91,7 +92,8 @@ define([ 'Toolbar': { 'file:settings': _.bind(this.clickToolbarSettings,this), 'file:open': this.clickToolbarTab.bind(this, 'file'), - 'file:close': this.clickToolbarTab.bind(this, 'other') + 'file:close': this.clickToolbarTab.bind(this, 'other'), + 'save:disabled': this.changeToolbarSaveState.bind(this) }, 'SearchDialog': { 'hide': _.bind(this.onSearchDlgHide, this), @@ -392,6 +394,10 @@ define([ this.leftMenu.menuFile.hide(); }, + changeToolbarSaveState: function (state) { + this.leftMenu.menuFile.getButton('save').setDisabled(state); + }, + /** coauthoring begin **/ clickStatusbarUsers: function() { this.leftMenu.menuFile.panels['rights'].changeAccessRights(); diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js index 9c5477232..2d20955d0 100644 --- a/apps/documenteditor/main/app/controller/Main.js +++ b/apps/documenteditor/main/app/controller/Main.js @@ -313,13 +313,16 @@ define([ this.plugins = this.editorConfig.plugins; appHeader = this.getApplication().getController('Viewport').getView('Common.Views.Header'); - appHeader.setCanBack(this.appOptions.canBackToFolder === true, (this.appOptions.canBackToFolder) ? this.editorConfig.customization.goback.text : ''); + appHeader.setCanBack(this.appOptions.canBackToFolder === true, (this.appOptions.canBackToFolder) ? this.editorConfig.customization.goback.text : '') + .setUserName(this.appOptions.user.fullname); if (this.editorConfig.lang) this.api.asc_setLocale(this.editorConfig.lang); if (this.appOptions.location == 'us' || this.appOptions.location == 'ca') Common.Utils.Metric.setDefaultMetric(Common.Utils.Metric.c_MetricUnits.inch); + + Common.Controllers.Desktop.init(this.appOptions); }, loadDocument: function(data) { @@ -588,11 +591,13 @@ define([ }, goBack: function() { - var href = this.appOptions.customization.goback.url; - if (this.appOptions.customization.goback.blank!==false) { - window.open(href, "_blank"); - } else { - parent.location.href = href; + if ( !Common.Controllers.Desktop.process('goback') ) { + var href = this.appOptions.customization.goback.url; + if (this.appOptions.customization.goback.blank!==false) { + window.open(href, "_blank"); + } else { + parent.location.href = href; + } } }, @@ -622,12 +627,7 @@ define([ forcesave = this.appOptions.forcesave, isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'), isDisabled = !cansave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave; - if (toolbarView.btnSave.isDisabled() !== isDisabled) - toolbarView.btnsSave.forEach(function(button) { - if ( button ) { - button.setDisabled(isDisabled); - } - }); + toolbarView.btnSave.setDisabled(isDisabled); } }, @@ -1072,7 +1072,7 @@ define([ (!this.appOptions.isReviewOnly || this.appOptions.canLicense); // if isReviewOnly==true -> canLicense must be true this.appOptions.isEdit = this.appOptions.canLicense && this.appOptions.canEdit && this.editorConfig.mode !== 'view'; this.appOptions.canReview = this.permissions.review === true && this.appOptions.canLicense && this.appOptions.isEdit; - this.appOptions.canUseHistory = this.appOptions.canLicense && this.editorConfig.canUseHistory && this.appOptions.canCoAuthoring && !this.appOptions.isDesktopApp; + this.appOptions.canUseHistory = this.appOptions.canLicense && this.editorConfig.canUseHistory && this.appOptions.canCoAuthoring; this.appOptions.canHistoryClose = this.editorConfig.canHistoryClose; this.appOptions.canHistoryRestore= this.editorConfig.canHistoryRestore && !!this.permissions.changeHistory; this.appOptions.canUseMailMerge= this.appOptions.canLicense && this.appOptions.canEdit && !this.appOptions.isOffline; @@ -1518,15 +1518,10 @@ define([ var toolbarView = this.getApplication().getController('Toolbar').getView(); if (toolbarView && !toolbarView._state.previewmode) { - var isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'), + var isSyncButton = toolbarView.btnSave.$icon.hasClass('btn-synch'), forcesave = this.appOptions.forcesave, isDisabled = !isModified && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave; - if (toolbarView.btnSave.isDisabled() !== isDisabled) - toolbarView.btnsSave.forEach(function(button) { - if ( button ) { - button.setDisabled(isDisabled); - } - }); + toolbarView.btnSave.setDisabled(isDisabled); } /** coauthoring begin **/ @@ -1536,20 +1531,13 @@ define([ /** coauthoring end **/ }, onDocumentCanSaveChanged: function (isCanSave) { - var application = this.getApplication(), - toolbarController = application.getController('Toolbar'), - toolbarView = toolbarController.getView(); + var toolbarView = this.getApplication().getController('Toolbar').getView(); if (toolbarView && this.api && !toolbarView._state.previewmode) { var isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'), forcesave = this.appOptions.forcesave, isDisabled = !isCanSave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave; - if (toolbarView.btnSave.isDisabled() !== isDisabled) - toolbarView.btnsSave.forEach(function(button) { - if ( button ) { - button.setDisabled(isDisabled); - } - }); + toolbarView.btnSave.setDisabled(isDisabled); } }, diff --git a/apps/documenteditor/main/app/controller/Statusbar.js b/apps/documenteditor/main/app/controller/Statusbar.js index d195a7620..35237e80c 100644 --- a/apps/documenteditor/main/app/controller/Statusbar.js +++ b/apps/documenteditor/main/app/controller/Statusbar.js @@ -55,6 +55,7 @@ define([ ], initialize: function() { + var me = this; this.addListeners({ 'Statusbar': { 'langchanged': this.onLangMenu, @@ -62,6 +63,15 @@ define([ this.api.zoom(value); Common.NotificationCenter.trigger('edit:complete', this.statusbar); }.bind(this) + }, + 'Common.Views.Header': { + 'statusbar:hide': function (view, status) { + me.statusbar.setVisible(!status); + Common.localStorage.setBool('de-hidden-status', status); + + Common.NotificationCenter.trigger('layout:changed', 'status'); + Common.NotificationCenter.trigger('edit:complete', this.statusbar); + } } }); }, diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js index 8bbcb8a47..87bbe2826 100644 --- a/apps/documenteditor/main/app/controller/Toolbar.js +++ b/apps/documenteditor/main/app/controller/Toolbar.js @@ -114,10 +114,16 @@ define([ 'menu:show': this.onFileMenu.bind(this, 'show') }, 'Common.Views.Header': { + 'toolbar:setcompact': this.onChangeCompactView.bind(this), 'print': function (opts) { var _main = this.getApplication().getController('Main'); _main.onPrint(); }, + 'save': function (opts) { + this.api.asc_Save(); + }, + 'undo': this.onUndo, + 'redo': this.onRedo, 'downloadas': function (opts) { var _main = this.getApplication().getController('Main'); var _file_type = _main.document.fileType, @@ -228,7 +234,9 @@ define([ toolbar.btnPrint.on('click', _.bind(this.onPrint, this)); toolbar.btnSave.on('click', _.bind(this.onSave, this)); toolbar.btnUndo.on('click', _.bind(this.onUndo, this)); + toolbar.btnUndo.on('disabled', _.bind(this.onBtnChangeState, this, 'undo:disabled')); toolbar.btnRedo.on('click', _.bind(this.onRedo, this)); + toolbar.btnRedo.on('disabled', _.bind(this.onBtnChangeState, this, 'redo:disabled')); toolbar.btnCopy.on('click', _.bind(this.onCopyPaste, this, true)); toolbar.btnPaste.on('click', _.bind(this.onCopyPaste, this, false)); toolbar.btnIncFontSize.on('click', _.bind(this.onIncrease, this)); @@ -289,7 +297,6 @@ define([ toolbar.btnPageMargins.menu.on('item:click', _.bind(this.onPageMarginsSelect, this)); toolbar.btnClearStyle.on('click', _.bind(this.onClearStyleClick, this)); toolbar.btnCopyStyle.on('toggle', _.bind(this.onCopyStyleToggle, this)); - toolbar.btnAdvSettings.on('click', _.bind(this.onAdvSettingsClick, this)); toolbar.mnuPageSize.on('item:click', _.bind(this.onPageSizeClick, this)); toolbar.mnuColorSchema.on('item:click', _.bind(this.onColorSchemaClick, this)); toolbar.btnMailRecepients.on('click', _.bind(this.onSelectRecepientsClick, this)); @@ -301,13 +308,6 @@ define([ toolbar.listStyles.on('click', _.bind(this.onListStyleSelect, this)); toolbar.listStyles.on('contextmenu', _.bind(this.onListStyleContextMenu, this)); toolbar.styleMenu.on('hide:before', _.bind(this.onListStyleBeforeHide, this)); - toolbar.mnuitemHideStatusBar.on('toggle', _.bind(this.onHideStatusBar, this)); - toolbar.mnuitemHideRulers.on('toggle', _.bind(this.onHideRulers, this)); - toolbar.mnuitemCompactToolbar.on('toggle', _.bind(this.onChangeCompactView, this)); - toolbar.btnFitPage.on('toggle', _.bind(this.onZoomToPageToggle, this)); - toolbar.btnFitWidth.on('toggle', _.bind(this.onZoomToWidthToggle, this)); - toolbar.mnuZoomIn.on('click', _.bind(this.onZoomInClick, this)); - toolbar.mnuZoomOut.on('click', _.bind(this.onZoomOutClick, this)); toolbar.btnInsertEquation.on('click', _.bind(this.onInsertEquationClick, this)); $('#id-save-style-plus, #id-save-style-link', toolbar.$el).on('click', this.onMenuSaveStyle.bind(this)); @@ -372,7 +372,6 @@ define([ var me = this; setTimeout(function () { me.onChangeCompactView(null, !me.toolbar.isCompact()); - me.toolbar.mnuitemCompactToolbar.setChecked(me.toolbar.isCompact(), true); }, 0); } }, @@ -518,14 +517,9 @@ define([ var btnHorizontalAlign = this.toolbar.btnHorizontalAlign; - if (btnHorizontalAlign.rendered) { - var iconEl = $('.icon', btnHorizontalAlign.cmpEl); - - if (iconEl) { - iconEl.removeClass(btnHorizontalAlign.options.icls); - btnHorizontalAlign.options.icls = align; - iconEl.addClass(btnHorizontalAlign.options.icls); - } + if ( btnHorizontalAlign.rendered && btnHorizontalAlign.$icon ) { + btnHorizontalAlign.$icon.removeClass(btnHorizontalAlign.options.icls).addClass(align); + btnHorizontalAlign.options.icls = align; } if (v === null || v===undefined) { @@ -740,7 +734,7 @@ define([ 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; - toolbar.btnsPageBreak.disable(need_disable); + toolbar.btnsPageBreak.setDisabled(need_disable); need_disable = paragraph_locked || header_locked || !can_add_image || in_equation || control_plain; toolbar.btnInsertImage.setDisabled(need_disable); @@ -773,10 +767,8 @@ define([ toolbar.listStylesAdditionalMenuItem.setDisabled(frame_pr===undefined); need_disable = (paragraph_locked || header_locked) && this.api.can_AddQuotedComment() || image_locked; - if (this.btnsComment && this.btnsComment.length>0 && need_disable != this.btnsComment[0].isDisabled()) - _.each (this.btnsComment, function(item){ - item.setDisabled(need_disable); - }, this); + if ( this.btnsComment && this.btnsComment.length > 0 ) + this.btnsComment.setDisabled(need_disable); this._state.in_equation = in_equation; }, @@ -845,12 +837,7 @@ define([ this.toolbar.mnuInsertPageNum.setDisabled(false); }, - onApiZoomChange: function(percent, type) { - this.toolbar.btnFitPage.setChecked(type == 2, true); - this.toolbar.btnFitWidth.setChecked(type == 1, true); - this.toolbar.mnuZoom.options.value = percent; - $('.menu-zoom .zoom', this.toolbar.el).html(percent + '%'); - }, + onApiZoomChange: function(percent, type) {}, onApiStartHighlight: function(pressed) { this.toolbar.btnHighlightColor.toggle(pressed, true); @@ -921,18 +908,14 @@ define([ var toolbar = this.toolbar; if (this.api) { var isModified = this.api.asc_isDocumentCanSave(); - var isSyncButton = $('.icon', toolbar.btnSave.cmpEl).hasClass('btn-synch'); + var isSyncButton = toolbar.btnCollabChanges.$icon.hasClass('btn-synch'); if (!isModified && !isSyncButton && !toolbar.mode.forcesave) return; this.api.asc_Save(); } - toolbar.btnsSave.forEach(function(button) { - if ( button ) { - button.setDisabled(!toolbar.mode.forcesave); - } - }); + toolbar.btnSave.setDisabled(!toolbar.mode.forcesave); Common.NotificationCenter.trigger('edit:complete', toolbar); @@ -940,6 +923,13 @@ define([ Common.component.Analytics.trackEvent('ToolBar', 'Save'); }, + onBtnChangeState: function(prop) { + if ( /\:disabled$/.test(prop) ) { + var _is_disabled = arguments[2]; + this.toolbar.fireEvent(prop, [_is_disabled]); + } + }, + onUndo: function(btn, e) { if (this.api) this.api.Undo(); @@ -1078,14 +1068,11 @@ define([ onMenuHorizontalAlignSelect: function(menu, item) { this._state.pralign = undefined; - var btnHorizontalAlign = this.toolbar.btnHorizontalAlign, - iconEl = $('.icon', btnHorizontalAlign.cmpEl); + var btnHorizontalAlign = this.toolbar.btnHorizontalAlign; - if (iconEl) { - iconEl.removeClass(btnHorizontalAlign.options.icls); - btnHorizontalAlign.options.icls = !item.checked ? 'btn-align-left' : item.options.icls; - iconEl.addClass(btnHorizontalAlign.options.icls); - } + btnHorizontalAlign.$icon.removeClass(btnHorizontalAlign.options.icls); + btnHorizontalAlign.options.icls = !item.checked ? 'btn-align-left' : item.options.icls; + btnHorizontalAlign.$icon.addClass(btnHorizontalAlign.options.icls); if (this.api && item.checked) this.api.put_PrAlign(item.value); @@ -1415,11 +1402,6 @@ define([ this.modeAlwaysSetStyle = state; }, - onAdvSettingsClick: function(btn, e) { - this.toolbar.fireEvent('file:settings', this); - btn.cmpEl.blur(); - }, - onPageSizeClick: function(menu, item, state) { if (this.api && state) { this._state.pgsize = [0, 0]; @@ -1993,61 +1975,6 @@ define([ // Common.NotificationCenter.trigger('edit:complete', this.toolbar); // }, - onHideStatusBar: function(item, checked) { - var headerView = this.getApplication().getController('Statusbar').getView('Statusbar'); - headerView && headerView.setVisible(!checked); - - Common.localStorage.setBool('de-hidden-status', checked); - - Common.NotificationCenter.trigger('layout:changed', 'status'); - Common.NotificationCenter.trigger('edit:complete', this.toolbar); - }, - - onHideRulers: function(item, checked) { - if (this.api) { - this.api.asc_SetViewRulers(!checked); - } - - Common.localStorage.setBool('de-hidden-rulers', checked); - - Common.NotificationCenter.trigger('layout:changed', 'rulers'); - Common.NotificationCenter.trigger('edit:complete', this.toolbar); - }, - - onZoomToPageToggle: function(item, state) { - if (this.api) { - if (state) - this.api.zoomFitToPage(); - else - this.api.zoomCustomMode(); - } - Common.NotificationCenter.trigger('edit:complete', this.toolbar); - }, - - onZoomToWidthToggle: function(item, state) { - if (this.api) { - if (state) - this.api.zoomFitToWidth(); - else - this.api.zoomCustomMode(); - } - Common.NotificationCenter.trigger('edit:complete', this.toolbar); - }, - - onZoomInClick: function(btn) { - if (this.api) - this.api.zoomIn(); - - Common.NotificationCenter.trigger('edit:complete', this.toolbar); - }, - - onZoomOutClick: function(btn) { - if (this.api) - this.api.zoomOut(); - - Common.NotificationCenter.trigger('edit:complete', this.toolbar); - }, - _clearBullets: function() { this.toolbar.btnMarkers.toggle(false, true); this.toolbar.btnNumbers.toggle(false, true); @@ -2716,17 +2643,12 @@ define([ disable = disable || (reviewmode ? toolbar_mask.length>0 : group_mask.length>0); toolbar.$el.find('.toolbar').toggleClass('masked', disable); - toolbar.btnHide.setDisabled(disable); if ( toolbar.synchTooltip ) toolbar.synchTooltip.hide(); toolbar._state.previewmode = reviewmode && disable; if (reviewmode) { - toolbar._state.previewmode && toolbar.btnsSave.forEach(function(button) { - if ( button ) { - button.setDisabled(true); - } - }); + toolbar._state.previewmode && toolbar.btnSave.setDisabled(true); if (toolbar.needShowSynchTip) { toolbar.needShowSynchTip = false; @@ -2783,12 +2705,25 @@ define([ if ( $panel ) me.toolbar.addTab(tab, $panel, 4); - if (config.isDesktopApp && config.isOffline) { - tab = {action: 'protect', caption: me.toolbar.textTabProtect}; - $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel(); + if ( config.isDesktopApp ) { + me.toolbar.btnSave.on('disabled', _.bind(me.onBtnChangeState, me, 'save:disabled')); - if ( $panel ) - me.toolbar.addTab(tab, $panel, 5); + // hide 'print' and 'save' buttons group and next separator + me.toolbar.btnPrint.$el.parents('.group').hide().next().hide(); + + // hide 'undo' and 'redo' buttons and retrieve parent container + var $box = me.toolbar.btnUndo.$el.hide().next().hide().parent(); + + // move 'paste' button to the container instead of 'undo' and 'redo' + me.toolbar.btnPaste.$el.detach().appendTo($box); + me.toolbar.btnCopy.$el.removeClass('split'); + + if ( config.isOffline ) { + tab = {action: 'protect', caption: me.toolbar.textTabProtect}; + $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel(); + + if ($panel) me.toolbar.addTab(tab, $panel, 5); + } } var links = me.getApplication().getController('Links'); @@ -2801,7 +2736,7 @@ define([ var me = this; if ( config.canCoAuthoring && config.canComments ) { - this.btnsComment = []; + this.btnsComment = createButtonSet(); var slots = me.toolbar.$el.find('.slot-comment'); slots.each(function(index, el) { var _cls = 'btn-toolbar'; @@ -2814,7 +2749,7 @@ define([ caption: me.toolbar.capBtnComment }).render( slots.eq(index) ); - me.btnsComment.push(button); + me.btnsComment.add(button); }); if ( this.btnsComment.length ) { diff --git a/apps/documenteditor/main/app/controller/Viewport.js b/apps/documenteditor/main/app/controller/Viewport.js index 22f988845..43b07abda 100644 --- a/apps/documenteditor/main/app/controller/Viewport.js +++ b/apps/documenteditor/main/app/controller/Viewport.js @@ -49,7 +49,7 @@ define([ ], function (Viewport) { 'use strict'; - DE.Controllers.Viewport = Backbone.Controller.extend({ + DE.Controllers.Viewport = Backbone.Controller.extend(_.assign({ // Specifying a Viewport model models: [], @@ -68,6 +68,10 @@ define([ var me = this; this.addListeners({ + 'FileMenu': { + 'menu:hide': me.onFileMenu.bind(me, 'hide'), + 'menu:show': me.onFileMenu.bind(me, 'show') + }, 'Toolbar': { 'render:before' : function (toolbar) { var config = DE.getController('Main').appOptions; @@ -75,7 +79,26 @@ define([ toolbar.setExtra('left', me.header.getPanel('left', config)); }, 'view:compact' : function (toolbar, state) { - me.viewport.vlayout.panels[0].height = state ? 32 : 32+67; + me.header.mnuitemCompactToolbar.setChecked(state, true); + me.viewport.vlayout.getItem('toolbar').height = state ? + Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal'); + }, + 'undo:disabled' : function (state) { + if ( me.header.btnUndo ) { + if ( me.header.btnUndo.keepState ) + me.header.btnUndo.keepState.disabled = state; + else me.header.btnUndo.setDisabled(state); + } + }, + 'redo:disabled' : function (state) { + if ( me.header.btnRedo ) + if ( me.header.btnRedo.keepState ) + me.header.btnRedo.keepState.disabled = state; + else me.header.btnRedo.setDisabled(state); + }, + 'save:disabled' : function (state) { + if ( me.header.btnSave ) + me.header.btnSave.setDisabled(state); } } }); @@ -83,6 +106,7 @@ define([ setApi: function(api) { this.api = api; + this.api.asc_registerCallback('asc_onZoomChange', this.onApiZoomChange.bind(this)); }, @@ -108,16 +132,151 @@ define([ this.boxSdk = $('#editor_sdk'); this.boxSdk.css('border-left', 'none'); + this.header.mnuitemFitPage = this.header.fakeMenuItem(); + this.header.mnuitemFitWidth = this.header.fakeMenuItem(); + Common.NotificationCenter.on('app:face', this.onAppShowed.bind(this)); + Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); }, onAppShowed: function (config) { var me = this; + me.appConfig = config; + + var _intvars = Common.Utils.InternalSettings; + var $filemenu = $('.toolbar-fullview-panel'); + $filemenu.css('top', _intvars.get('toolbar-height-tabs')); if ( !config.isEdit || ( !Common.localStorage.itemExists("de-compact-toolbar") && config.customization && config.customization.compactToolbar )) { - me.viewport.vlayout.panels[0].height = 32; + + var panel = me.viewport.vlayout.getItem('toolbar'); + if ( panel ) panel.height = _intvars.get('toolbar-height-tabs'); + } + + if ( config.isDesktopApp && config.isEdit ) { + var $title = me.viewport.vlayout.getItem('title').el; + $title.html(me.header.getPanel('title', config)).show(); + + var toolbar = me.viewport.vlayout.getItem('toolbar'); + toolbar.el.addClass('top-title'); + toolbar.height -= _intvars.get('toolbar-height-tabs') - _intvars.get('toolbar-height-tabs-top-title'); + + var _tabs_new_height = _intvars.get('toolbar-height-tabs-top-title'); + _intvars.set('toolbar-height-tabs', _tabs_new_height); + _intvars.set('toolbar-height-compact', _tabs_new_height); + _intvars.set('toolbar-height-normal', _tabs_new_height + _intvars.get('toolbar-height-controls')); + + $filemenu.css('top', _tabs_new_height + _intvars.get('document-title-height')); + + toolbar = me.getApplication().getController('Toolbar').getView(); + toolbar.btnCollabChanges = me.header.btnSave; + } + }, + + onAppReady: function (config) { + var me = this; + if ( me.header.btnOptions ) { + var compactview = !config.isEdit; + if ( config.isEdit ) { + if ( Common.localStorage.itemExists("de-compact-toolbar") ) { + compactview = Common.localStorage.getBool("de-compact-toolbar"); + } else + if ( config.customization && config.customization.compactToolbar ) + compactview = true; + } + + me.header.mnuitemCompactToolbar = new Common.UI.MenuItem({ + caption: me.header.textCompactView, + checked: compactview, + checkable: true, + value: 'toolbar' + }); + + var mnuitemHideStatusBar = new Common.UI.MenuItem({ + caption: me.header.textHideStatusBar, + checked: Common.localStorage.getBool("de-hidden-status"), + checkable: true, + value: 'statusbar' + }); + + if ( config.canBrandingExt && config.customization && config.customization.statusBar === false ) + mnuitemHideStatusBar.hide(); + + var mnuitemHideRulers = new Common.UI.MenuItem({ + caption: me.header.textHideLines, + checked: Common.localStorage.getBool("de-hidden-rulers"), + checkable: true, + value: 'rulers' + }); + + me.header.mnuitemFitPage = new Common.UI.MenuItem({ + caption: me.textFitPage, + checkable: true, + checked: me.header.mnuitemFitPage.isChecked(), + value: 'zoom:page' + }); + + me.header.mnuitemFitWidth = new Common.UI.MenuItem({ + caption: me.textFitWidth, + checkable: true, + checked: me.header.mnuitemFitWidth.isChecked(), + value: 'zoom:width' + }); + + me.header.mnuZoom = new Common.UI.MenuItem({ + template: _.template([ + '' + ].join('')), + stopPropagation: true, + value: me.header.mnuZoom.options.value + }); + + me.header.btnOptions.setMenu(new Common.UI.Menu({ + cls: 'pull-right', + style: 'min-width: 180px;', + items: [ + me.header.mnuitemCompactToolbar, + mnuitemHideStatusBar, + mnuitemHideRulers, + {caption:'--'}, + me.header.mnuitemFitPage, + me.header.mnuitemFitWidth, + me.header.mnuZoom, + {caption:'--'}, + new Common.UI.MenuItem({ + caption: me.header.textAdvSettings, + value: 'advanced' + }) + ] + }) + ); + + var _on_btn_zoom = function (btn) { + btn == 'up' ? me.api.zoomIn() : me.api.zoomOut(); + Common.NotificationCenter.trigger('edit:complete', me.header); + }; + + (new Common.UI.Button({ + el : $('#hdr-menu-zoom-out', me.header.mnuZoom.$el), + cls : 'btn-toolbar' + })).on('click', _on_btn_zoom.bind(me, 'down')); + + (new Common.UI.Button({ + el : $('#hdr-menu-zoom-in', me.header.mnuZoom.$el), + cls : 'btn-toolbar' + })).on('click', _on_btn_zoom.bind(me, 'up')); + + me.header.btnOptions.menu.on('item:click', me.onOptionsItemClick.bind(this)); } }, @@ -161,6 +320,51 @@ define([ onWindowResize: function(e) { this.onLayoutChanged('window'); Common.NotificationCenter.trigger('window:resize'); - } - }); + }, + + onFileMenu: function (opts) { + var me = this; + var _need_disable = opts == 'show'; + + me.header.lockHeaderBtns( 'undo', _need_disable ); + me.header.lockHeaderBtns( 'redo', _need_disable ); + me.header.lockHeaderBtns( 'opts', _need_disable ); + }, + + onApiZoomChange: function(percent, type) { + this.header.mnuitemFitPage.setChecked(type == 2, true); + this.header.mnuitemFitWidth.setChecked(type == 1, true); + this.header.mnuZoom.options.value = percent; + + if ( this.header.mnuZoom.$el ) + $('.menu-zoom label.zoom', this.header.mnuZoom.$el).html(percent + '%'); + }, + + onOptionsItemClick: function (menu, item, e) { + var me = this; + + switch ( item.value ) { + case 'toolbar': me.header.fireEvent('toolbar:setcompact', [menu, item.isChecked()]); break; + case 'statusbar': me.header.fireEvent('statusbar:hide', [item, item.isChecked()]); break; + case 'rulers': + me.api.asc_SetViewRulers(!item.isChecked()); + Common.localStorage.setBool('de-hidden-rulers', item.isChecked()); + Common.NotificationCenter.trigger('layout:changed', 'rulers'); + Common.NotificationCenter.trigger('edit:complete', me.header); + break; + case 'zoom:page': + item.isChecked() ? me.api.zoomFitToPage() : me.api.zoomCustomMode(); + Common.NotificationCenter.trigger('edit:complete', me.header); + break; + case 'zoom:width': + item.isChecked() ? me.api.zoomFitToWidth() : me.api.zoomCustomMode(); + Common.NotificationCenter.trigger('edit:complete', me.header); + break; + case 'advanced': me.header.fireEvent('file:settings', me.header); break; + } + }, + + textFitPage: 'Fit to Page', + textFitWidth: 'Fit to Width' + }, DE.Controllers.Viewport)); }); diff --git a/apps/documenteditor/main/app/template/Toolbar.template b/apps/documenteditor/main/app/template/Toolbar.template index 75f5398ae..7c1ed23c5 100644 --- a/apps/documenteditor/main/app/template/Toolbar.template +++ b/apps/documenteditor/main/app/template/Toolbar.template @@ -8,7 +8,6 @@