diff --git a/apps/common/main/lib/component/DataView.js b/apps/common/main/lib/component/DataView.js index 507dc24bf..beb4fa81e 100644 --- a/apps/common/main/lib/component/DataView.js +++ b/apps/common/main/lib/component/DataView.js @@ -143,11 +143,17 @@ define([ 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.toggleClass('disabled', this.model.get('disabled')); + el.toggleClass('disabled', !!this.model.get('disabled')); if (!_.isUndefined(this.model.get('cls'))) el.addClass(this.model.get('cls')); + var tip = el.data('bs.tooltip'); + if (tip) { + if (tip.dontShow===undefined) + tip.dontShow = true; + } + this.trigger('change', this, this.model); return this; @@ -441,7 +447,11 @@ define([ onResetItems: function() { _.each(this.dataViewItems, function(item) { var tip = item.$el.data('bs.tooltip'); - if (tip) (tip.tip()).remove(); + if (tip) { + if (tip.dontShow===undefined) + tip.dontShow = true; + (tip.tip()).remove(); + } }, this); $(this.el).html(this.template({ diff --git a/apps/common/main/lib/component/TreeView.js b/apps/common/main/lib/component/TreeView.js new file mode 100644 index 000000000..eb382a14b --- /dev/null +++ b/apps/common/main/lib/component/TreeView.js @@ -0,0 +1,269 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * TreeView.js + * + * Created by Julia Radzhabova on 12/14/17 + * + */ + +if (Common === undefined) + var Common = {}; + +define([ + 'common/main/lib/component/DataView' +], function () { + 'use strict'; + + Common.UI.TreeViewModel = Common.UI.DataViewModel.extend({ + defaults: function() { + return { + id: Common.UI.getId(), + name: '', + isNotHeader: false, + hasSubItems: false, + hasParent: false, + isEmptyItem: false, + isExpanded: true, + isVisible: true, + selected: false, + allowSelected: true, + disabled: false, + level: 0, + index: 0 + } + } + }); + + Common.UI.TreeViewStore = Backbone.Collection.extend({ + model: Common.UI.TreeViewModel, + + expandSubItems: function(record) { + var me = this; + var _expand_sub_items = function(idx, expanded, level) { + for (var i=idx+1; ilevel) { + if (expanded) + item.set('isVisible', true); + if (item.get('hasSubItems')) + i = _expand_sub_items(i, item.get('isExpanded'), item_level ); + } else { + return (i-1); + } + } + }; + + record.set('isExpanded', true); + _expand_sub_items(record.get('index'), true, record.get('level')); + }, + + collapseSubItems: function(record) { + var start_level = record.get('level'), + index = record.get('index'); + for (var i=index+1; istart_level) { + item.set('isVisible', false); + } else { + break; + } + } + return i-1; + }, + + expandAll: function() { + this.each(function(item) { + item.set('isExpanded', true); + item.set('isVisible', true); + }); + }, + + collapseAll: function() { + for (var i=0; ilevel) { + if (item_level<=expandLevel) + parent.set('isExpanded', true); + item.set('isVisible', item_level<=expandLevel); + if (item.get('hasSubItems')) + i = _expand_sub_items(i, item_level ); + } else { + return (i-1); + } + } + }; + + for (var j=0; j' + ].join('')), + + initialize : function(options) { + options.store = options.store || new Common.UI.TreeViewStore(); + options.emptyItemText = options.emptyItemText || ''; + options.itemTemplate = options.itemTemplate || _.template([ + '
', + '<% if (hasSubItems) { %>', + '
', + '<% } %>', + '<% if (isNotHeader) { %>', + '
<%= name %>
', + '<% } else if (isEmptyItem) { %>', + '
' + options.emptyItemText + '
', + '<% } else { %>', + '
<%= name %>
', + '<% } %>', + '
' + ].join('')); + Common.UI.DataView.prototype.initialize.call(this, options); + }, + + onAddItem: function(record, store, opts) { + var view = new Common.UI.DataViewItem({ + template: this.itemTemplate, + model: record + }); + + if (view) { + var innerEl = $(this.el).find('.inner').addBack().filter('.inner'); + if (innerEl) { + innerEl.find('.empty-text').remove(); + + if (opts && opts.at!==undefined) { + var idx = opts.at; + var innerDivs = innerEl.find('> div'); + if (idx > 0) + $(innerDivs.get(idx - 1)).after(view.render().el); + else { + (innerDivs.length > 0) ? $(innerDivs[idx]).before(view.render().el) : innerEl.append(view.render().el); + } + this.dataViewItems = this.dataViewItems.slice(0, idx).concat(view).concat(this.dataViewItems.slice(idx)); + } else { + innerEl.append(view.render().el); + this.dataViewItems.push(view); + } + + var name = record.get('name'); + if (name.length > 37 - record.get('level')*2) + record.set('tip', name); + if (record.get('tip')) { + var view_el = $(view.el); + view_el.attr('data-toggle', 'tooltip'); + view_el.tooltip({ + title : record.get('tip'), + placement : 'cursor', + zIndex : this.tipZIndex + }); + } + + this.listenTo(view, 'change', this.onChangeItem); + this.listenTo(view, 'remove', this.onRemoveItem); + this.listenTo(view, 'click', this.onClickItem); + this.listenTo(view, 'dblclick', this.onDblClickItem); + this.listenTo(view, 'select', this.onSelectItem); + this.listenTo(view, 'contextmenu', this.onContextMenuItem); + + if (!this.isSuspendEvents) + this.trigger('item:add', this, view, record); + } + } + }, + + onClickItem: function(view, record, e) { + var btn = $(e.target); + if (btn && btn.hasClass('tree-caret')) { + var tip = view.$el.data('bs.tooltip'); + if (tip) (tip.tip()).remove(); + + var isExpanded = !record.get('isExpanded'); + record.set('isExpanded', isExpanded); + this.store[(isExpanded) ? 'expandSubItems' : 'collapseSubItems'](record); + this.scroller.update({minScrollbarLength: 40}); + } else + Common.UI.DataView.prototype.onClickItem.call(this, view, record, e); + }, + + expandAll: function() { + this.store.expandAll(); + this.scroller.update({minScrollbarLength: 40}); + }, + + collapseAll: function() { + this.store.collapseAll(); + this.scroller.update({minScrollbarLength: 40}); + }, + + expandToLevel: function(expandLevel) { + this.store.expandToLevel(expandLevel); + this.scroller.update({minScrollbarLength: 40}); + } + } + })()); +}); \ No newline at end of file diff --git a/apps/common/main/lib/util/Tip.js b/apps/common/main/lib/util/Tip.js index 9a197eee0..f4ce19e4a 100644 --- a/apps/common/main/lib/util/Tip.js +++ b/apps/common/main/lib/util/Tip.js @@ -154,11 +154,15 @@ if (typeof at == 'object') { var tp = {top: at[1] + 15, left: at[0] + 18}, - innerWidth = Common.Utils.innerWidth(); + innerWidth = Common.Utils.innerWidth(), + innerHeight = Common.Utils.innerHeight(); if (tp.left + $tip.width() > innerWidth) { tp.left = innerWidth - $tip.width() - 30; } + if (tp.top + $tip.height() > innerHeight) { + tp.top = innerHeight - $tip.height() - 30; + } $tip.offset(tp).addClass('in'); } else { diff --git a/apps/common/main/resources/less/asc-mixins.less b/apps/common/main/resources/less/asc-mixins.less index 447654e4b..fccee9993 100644 --- a/apps/common/main/resources/less/asc-mixins.less +++ b/apps/common/main/resources/less/asc-mixins.less @@ -146,7 +146,7 @@ @common-controls-width: 100px; .img-commonctrl, .theme-colorpalette .color-transparent, .palette-color-ext .color-transparent, .dropdown-menu li .checked:before, .input-error:before, - .btn-toolbar .icon.img-commonctrl { + .btn-toolbar .icon.img-commonctrl, .list-item div.checked:before { background-image: data-uri(%("%s",'@{common-image-path}/@{common-controls}')); background-repeat: no-repeat; diff --git a/apps/common/main/resources/less/toolbar.less b/apps/common/main/resources/less/toolbar.less index ae8fb66fa..5fc463277 100644 --- a/apps/common/main/resources/less/toolbar.less +++ b/apps/common/main/resources/less/toolbar.less @@ -278,19 +278,6 @@ .button-normal-icon(btn-addslide, 11, @toolbar-big-icon-size); .button-normal-icon(~'x-huge .btn-ic-docspell', 12, @toolbar-big-icon-size); .button-normal-icon(~'x-huge .btn-ic-review', 13, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-ic-reviewview', 30, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-ic-sharing', 31, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-ic-coedit', 32, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-ic-chat', 33, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-ic-history', 34, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-ic-protect', 35, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-ic-signature', 36, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-add-pivot', 37, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-update-pivot', 38, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-pivot-layout', 39, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-blank-rows', 43, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-subtotals', 46, @toolbar-big-icon-size); -.button-normal-icon(~'x-huge .btn-grand-totals', 52, @toolbar-big-icon-size); .button-normal-icon(review-save, 14, @toolbar-big-icon-size); .button-normal-icon(review-deny, 15, @toolbar-big-icon-size); .button-normal-icon(review-next, 16, @toolbar-big-icon-size); @@ -307,4 +294,19 @@ .button-normal-icon(btn-img-bkwd, 27, @toolbar-big-icon-size); .button-normal-icon(btn-img-frwd, 28, @toolbar-big-icon-size); .button-normal-icon(btn-img-wrap, 29, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-reviewview', 30, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-sharing', 31, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-coedit', 32, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-chat', 33, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-history', 34, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-protect', 35, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-ic-signature', 36, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-add-pivot', 37, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-update-pivot', 38, @toolbar-big-icon-size); +.button-normal-icon(btn-contents-update, 38, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-pivot-layout', 39, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-blank-rows', 43, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-subtotals', 46, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-grand-totals', 52, @toolbar-big-icon-size); +.button-normal-icon(~'x-huge .btn-contents', 53, @toolbar-big-icon-size); .button-normal-icon(btn-controls, 54, @toolbar-big-icon-size); diff --git a/apps/common/main/resources/less/treeview.less b/apps/common/main/resources/less/treeview.less new file mode 100644 index 000000000..0deb15644 --- /dev/null +++ b/apps/common/main/resources/less/treeview.less @@ -0,0 +1,66 @@ +.treeview { + &.inner { + width: 100%; + height: 100%; + position: relative; + overflow: hidden; + + .empty-text { + text-align: center; + height: 100%; + width: 100%; + color: #b2b2b2; + } + } + + > .item { + display: block; + width: 100%; + .box-shadow(none); + margin: 0; + + &:hover, + &.over, + &.selected { + background-color: @secondary; + } + + &.selected .empty { + display: none; + } + + } + + .tree-item { + width: 100%; + min-height: 28px; + padding: 0px 0 0 24px; + } + + .name { + width: 100%; + padding: 5px 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + &.empty { + color: #999; + font-style: italic; + } + } + + .tree-caret { + width: 24px; + height: 24px; + background-position: 3px -270px; + display: inline-block; + position: absolute; + left: 0; + cursor: pointer; + + &.up { + transform: rotate(270deg); + } + } +} \ No newline at end of file diff --git a/apps/documenteditor/main/app.js b/apps/documenteditor/main/app.js index bc6d337c9..1c13c3c9b 100644 --- a/apps/documenteditor/main/app.js +++ b/apps/documenteditor/main/app.js @@ -150,6 +150,8 @@ require([ 'DocumentHolder', 'Toolbar', 'Statusbar', + 'Links', + 'Navigation', 'RightMenu', 'LeftMenu', 'Main', @@ -174,6 +176,8 @@ require([ 'documenteditor/main/app/controller/DocumentHolder', 'documenteditor/main/app/controller/Toolbar', 'documenteditor/main/app/controller/Statusbar', + 'documenteditor/main/app/controller/Links', + 'documenteditor/main/app/controller/Navigation', 'documenteditor/main/app/controller/RightMenu', 'documenteditor/main/app/controller/LeftMenu', 'documenteditor/main/app/controller/Main', diff --git a/apps/documenteditor/main/app/collection/EquationGroups.js b/apps/documenteditor/main/app/collection/EquationGroups.js index 60b8d0597..70e7e9bd8 100644 --- a/apps/documenteditor/main/app/collection/EquationGroups.js +++ b/apps/documenteditor/main/app/collection/EquationGroups.js @@ -42,10 +42,7 @@ define([ 'backbone', 'documenteditor/main/app/model/EquationGroup' ], function(Backbone){ 'use strict'; - if (Common === undefined) - var Common = {}; - - Common.Collections = Common.Collections || {}; + DE.Collections = DE.Collections || {}; DE.Collections.EquationGroups = Backbone.Collection.extend({ model: DE.Models.EquationGroup diff --git a/apps/documenteditor/main/app/collection/Navigation.js b/apps/documenteditor/main/app/collection/Navigation.js new file mode 100644 index 000000000..29d450535 --- /dev/null +++ b/apps/documenteditor/main/app/collection/Navigation.js @@ -0,0 +1,50 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * User: Julia.Radzhabova + * Date: 14.12.17 + */ + +DE.Collections = DE.Collections || {}; + +define([ + 'underscore', + 'backbone', + 'common/main/lib/component/TreeView' +], function(_, Backbone){ + 'use strict'; + + DE.Collections.Navigation = Common.UI.TreeViewStore.extend({ + model: Common.UI.TreeViewModel + }); +}); diff --git a/apps/documenteditor/main/app/controller/LeftMenu.js b/apps/documenteditor/main/app/controller/LeftMenu.js index 7f4b65826..51e78b6db 100644 --- a/apps/documenteditor/main/app/controller/LeftMenu.js +++ b/apps/documenteditor/main/app/controller/LeftMenu.js @@ -199,6 +199,8 @@ define([ if (this.mode.canUseHistory) this.leftMenu.setOptionsPanel('history', this.getApplication().getController('Common.Controllers.History').getView('Common.Views.History')); + this.leftMenu.setOptionsPanel('navigation', this.getApplication().getController('Navigation').getView('Navigation')); + this.mode.trialMode && this.leftMenu.setDeveloperMode(this.mode.trialMode); Common.util.Shortcuts.resumeEvents(); @@ -499,6 +501,7 @@ define([ this.leftMenu.btnChat.setDisabled(true); /** coauthoring end **/ this.leftMenu.btnPlugins.setDisabled(true); + this.leftMenu.btnNavigation.setDisabled(true); this.leftMenu.getMenu('file').setMode({isDisconnected: true, disableDownload: !!disableDownload}); if ( this.dlgSearch ) { @@ -516,6 +519,7 @@ define([ this.leftMenu.btnChat.setDisabled(disable); /** coauthoring end **/ this.leftMenu.btnPlugins.setDisabled(disable); + this.leftMenu.btnNavigation.setDisabled(disable); if (disableFileMenu) this.leftMenu.getMenu('file').SetDisabled(disable); }, diff --git a/apps/documenteditor/main/app/controller/Links.js b/apps/documenteditor/main/app/controller/Links.js new file mode 100644 index 000000000..1310227ac --- /dev/null +++ b/apps/documenteditor/main/app/controller/Links.js @@ -0,0 +1,305 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * Links.js + * + * Created by Julia Radzhabova on 22.12.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'core', + 'documenteditor/main/app/view/Links', + 'documenteditor/main/app/view/NoteSettingsDialog', + 'documenteditor/main/app/view/HyperlinkSettingsDialog', + 'documenteditor/main/app/view/TableOfContentsSettings' +], function () { + 'use strict'; + + DE.Controllers.Links = Backbone.Controller.extend(_.extend({ + models : [], + collections : [ + ], + views : [ + 'Links' + ], + sdkViewName : '#id_main', + + initialize: function () { + + this.addListeners({ + 'Links': { + 'links:contents': this.onTableContents, + 'links:update': this.onTableContentsUpdate, + 'links:notes': this.onNotesClick, + 'links:hyperlink': this.onHyperlinkClick + } + }); + }, + onLaunch: function () { + this._state = { + prcontrolsdisable:undefined + }; + }, + + setApi: function (api) { + if (api) { + this.api = api; + this.api.asc_registerCallback('asc_onFocusObject', this.onApiFocusObject.bind(this)); + this.api.asc_registerCallback('asc_onCanAddHyperlink', _.bind(this.onApiCanAddHyperlink, this)); + this.api.asc_registerCallback('asc_onCoAuthoringDisconnect',_.bind(this.onCoAuthoringDisconnect, this)); + Common.NotificationCenter.on('api:disconnect', _.bind(this.onCoAuthoringDisconnect, this)); + } + return this; + }, + + setConfig: function(config) { + this.toolbar = config.toolbar; + this.view = this.createView('Links', { + toolbar: this.toolbar.toolbar + }); + }, + + SetDisabled: function(state) { + this.view && this.view.SetDisabled(state); + }, + + getView: function(name) { + return !name && this.view ? + this.view : Backbone.Controller.prototype.getView.call(this, name); + }, + + onCoAuthoringDisconnect: function() { + this.SetDisabled(true); + }, + + onApiFocusObject: function(selectedObjects) { + if (!this.toolbar.editMode) return; + + var pr, i = -1, type, + paragraph_locked = false, + header_locked = false, + in_header = false, + in_equation = false, + in_image = false; + + while (++i < selectedObjects.length) { + type = selectedObjects[i].get_ObjectType(); + pr = selectedObjects[i].get_ObjectValue(); + + if (type === Asc.c_oAscTypeSelectElement.Paragraph) { + paragraph_locked = pr.get_Locked(); + } else if (type === Asc.c_oAscTypeSelectElement.Header) { + header_locked = pr.get_Locked(); + in_header = true; + } else if (type === Asc.c_oAscTypeSelectElement.Image) { + in_image = true; + } else if (type === Asc.c_oAscTypeSelectElement.Math) { + in_equation = true; + } + } + + this._state.prcontrolsdisable = paragraph_locked || header_locked; + + var need_disable = paragraph_locked || in_equation || in_image || in_header; + _.each (this.view.btnsNotes, function(item){ + item.setDisabled(need_disable); + }, this); + }, + + onApiCanAddHyperlink: function(value) { + var need_disable = !value || this._state.prcontrolsdisable; + + if ( this.toolbar.editMode ) { + _.each (this.view.btnsHyperlink, function(item){ + item.setDisabled(need_disable); + }, this); + } + }, + + onHyperlinkClick: function(btn) { + var me = this, + win, props, text; + + if (me.api){ + + var handlerDlg = function(dlg, result) { + if (result == 'ok') { + props = dlg.getSettings(); + (text!==false) + ? me.api.add_Hyperlink(props) + : me.api.change_Hyperlink(props); + } + + Common.NotificationCenter.trigger('edit:complete', me.toolbar); + }; + + text = me.api.can_AddHyperlink(); + + if (text !== false) { + win = new DE.Views.HyperlinkSettingsDialog({ + api: me.api, + handler: handlerDlg + }); + + props = new Asc.CHyperlinkProperty(); + props.put_Text(text); + + win.show(); + win.setSettings(props); + } else { + var selectedElements = me.api.getSelectedElements(); + if (selectedElements && _.isArray(selectedElements)){ + _.each(selectedElements, function(el, i) { + if (selectedElements[i].get_ObjectType() == Asc.c_oAscTypeSelectElement.Hyperlink) + props = selectedElements[i].get_ObjectValue(); + }); + } + if (props) { + win = new DE.Views.HyperlinkSettingsDialog({ + api: me.api, + handler: handlerDlg + }); + win.show(); + win.setSettings(props); + } + } + } + + Common.component.Analytics.trackEvent('ToolBar', 'Add Hyperlink'); + }, + + onTableContents: function(type){ + switch (type) { + case 0: + var props = this.api.asc_GetTableOfContentsPr(), + hasTable = !!props; + if (!props) { + props = new Asc.CTableOfContentsPr(); + props.put_OutlineRange(1, 9); + } + props.put_Hyperlink(true); + props.put_ShowPageNumbers(true); + props.put_RightAlignTab(true); + props.put_TabLeader( Asc.c_oAscTabLeader.Dot); + (hasTable) ? this.api.asc_SetTableOfContentsPr(props) : this.api.asc_AddTableOfContents(null, props); + break; + case 1: + var props = this.api.asc_GetTableOfContentsPr(), + hasTable = !!props; + if (!props) { + props = new Asc.CTableOfContentsPr(); + props.put_OutlineRange(1, 9); + } + props.put_Hyperlink(true); + props.put_ShowPageNumbers(false); + props.put_TabLeader( Asc.c_oAscTabLeader.None); + (hasTable) ? this.api.asc_SetTableOfContentsPr(props) : this.api.asc_AddTableOfContents(null, props); + break; + case 'settings': + var props = this.api.asc_GetTableOfContentsPr(), + me = this; + var win = new DE.Views.TableOfContentsSettings({ + api: this.api, + props: props, + handler: function(result, value) { + if (result == 'ok') { + (props) ? me.api.asc_SetTableOfContentsPr(value) : me.api.asc_AddTableOfContents(null, value); + } + Common.NotificationCenter.trigger('edit:complete', me.toolbar); + } + }); + win.show(); + break; + case 'remove': + this.api.asc_RemoveTableOfContents(); + break; + } + }, + + onTableContentsUpdate: function(type){ + this.api.asc_UpdateTableOfContents(type == 'pages'); + }, + + onNotesClick: function(type) { + var me = this; + switch (type) { + case 'ins_footnote': + this.api.asc_AddFootnote(); + break; + case 'delele': + Common.UI.warning({ + msg: this.view.confirmDeleteFootnotes, + buttons: ['yes', 'no'], + primary: 'yes', + callback: _.bind(function (btn) { + if (btn == 'yes') { + this.api.asc_RemoveAllFootnotes(); + } + Common.NotificationCenter.trigger('edit:complete', this.toolbar); + }, this) + }); + break; + case 'settings': + (new DE.Views.NoteSettingsDialog({ + api: me.api, + handler: function (result, settings) { + if (settings) { + me.api.asc_SetFootnoteProps(settings.props, settings.applyToAll); + if (result == 'insert') + me.api.asc_AddFootnote(settings.custom); + } + Common.NotificationCenter.trigger('edit:complete', me.toolbar); + }, + props: me.api.asc_GetFootnoteProps() + })).show(); + break; + case 'prev': + this.api.asc_GotoFootnote(false); + setTimeout(function() { + Common.NotificationCenter.trigger('edit:complete', me.toolbar); + }, 50); + break; + case 'next': + this.api.asc_GotoFootnote(true); + setTimeout(function() { + Common.NotificationCenter.trigger('edit:complete', me.toolbar); + }, 50); + break; + } + } + + }, DE.Controllers.Links || {})); +}); \ No newline at end of file diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js index ede2f5d60..76b9ae693 100644 --- a/apps/documenteditor/main/app/controller/Main.js +++ b/apps/documenteditor/main/app/controller/Main.js @@ -893,7 +893,8 @@ define([ rightmenuController = application.getController('RightMenu'), leftmenuController = application.getController('LeftMenu'), chatController = application.getController('Common.Controllers.Chat'), - pluginsController = application.getController('Common.Controllers.Plugins'); + pluginsController = application.getController('Common.Controllers.Plugins'), + navigationController = application.getController('Navigation'); leftmenuController.getView('LeftMenu').getMenu('file').loadDocument({doc:me.document}); leftmenuController.setMode(me.appOptions).createDelayedElements().setApi(me.api); @@ -907,6 +908,8 @@ define([ me.api.asc_registerCallback('asc_onPluginsInit', _.bind(me.updatePluginsList, me)); me.api.asc_registerCallback('asc_onPluginsReset', _.bind(me.resetPluginsList, me)); + navigationController.setApi(me.api); + documentHolderController.setApi(me.api); documentHolderController.createDelayedElements(); statusbarController.createDelayedElements(); diff --git a/apps/documenteditor/main/app/controller/Navigation.js b/apps/documenteditor/main/app/controller/Navigation.js new file mode 100644 index 000000000..d1b098645 --- /dev/null +++ b/apps/documenteditor/main/app/controller/Navigation.js @@ -0,0 +1,231 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * User: Julia.Radzhabova + * Date: 14.12.17 + */ + +define([ + 'core', + 'documenteditor/main/app/collection/Navigation', + 'documenteditor/main/app/view/Navigation' +], function () { + 'use strict'; + + DE.Controllers.Navigation = Backbone.Controller.extend(_.extend({ + models: [], + collections: [ + 'Navigation' + ], + views: [ + 'Navigation' + ], + + initialize: function() { + var me = this; + this.addListeners({ + 'Navigation': { + 'show': function() { + var obj = me.api.asc_ShowDocumentOutline(); + if (!me._navigationObject) + me._navigationObject = obj; + me.updateNavigation(); + }, + 'hide': function() { + me.api.asc_HideDocumentOutline(); + } + } + }); + }, + + events: function() { + }, + + onLaunch: function() { + this.panelNavigation= this.createView('Navigation', { + storeNavigation: this.getApplication().getCollection('Navigation') + }); + this.panelNavigation.on('render:after', _.bind(this.onAfterRender, this)); + this._navigationObject = null; + }, + + setApi: function(api) { + this.api = api; + this.api.asc_registerCallback('asc_onDocumentOutlineUpdate', _.bind(this.updateNavigation, this)); + this.api.asc_registerCallback('asc_onDocumentOutlineCurrentPosition', _.bind(this.onChangeOutlinePosition, this)); + this.api.asc_registerCallback('asc_onDocumentOutlineUpdateAdd', _.bind(this.updateNavigation, this)); + this.api.asc_registerCallback('asc_onDocumentOutlineUpdateChange', _.bind(this.updateChangeNavigation, this)); + this.api.asc_registerCallback('asc_onDocumentOutlineUpdateRemove', _.bind(this.updateNavigation, this)); + return this; + }, + + setMode: function(mode) { + }, + + onAfterRender: function(panelNavigation) { + panelNavigation.viewNavigationList.on('item:click', _.bind(this.onSelectItem, this)); + panelNavigation.viewNavigationList.on('item:contextmenu', _.bind(this.onItemContextMenu, this)); + panelNavigation.navigationMenu.on('item:click', _.bind(this.onMenuItemClick, this)); + panelNavigation.navigationMenu.items[11].menu.on('item:click', _.bind(this.onMenuLevelsItemClick, this)); + }, + + updateNavigation: function() { + if (!this._navigationObject) return; + + var count = this._navigationObject.get_ElementsCount(), + prev_level = -1, + header_level = -1, + first_header = !this._navigationObject.isFirstItemNotHeader(), + arr = []; + for (var i=0; iprev_level && i>0) + arr[i-1].set('hasSubItems', true); + if (header_level<0 || level<=header_level) { + if (i>0 || first_header) + header_level = level; + hasParent = false; + } + arr.push(new Common.UI.TreeViewModel({ + name : this._navigationObject.get_Text(i), + level: level, + index: i, + hasParent: hasParent, + isEmptyItem: this._navigationObject.isEmptyItem(i) + })); + prev_level = level; + } + if (count>0 && !first_header) { + arr[0].set('hasSubItems', false); + arr[0].set('isNotHeader', true); + arr[0].set('name', this.txtBeginning); + arr[0].set('tip', this.txtGotoBeginning); + } + this.getApplication().getCollection('Navigation').reset(arr); + }, + + updateChangeNavigation: function(index) { + if (!this._navigationObject) return; + + var item = this.getApplication().getCollection('Navigation').at(index); + if (item.get('level') !== this._navigationObject.get_Level(index) || + index==0 && item.get('isNotHeader') !== this._navigationObject.isFirstItemNotHeader()) { + this.updateNavigation(); + } else { + item.set('name', this._navigationObject.get_Text(index)); + item.set('isEmptyItem', this._navigationObject.isEmptyItem(index)); + } + }, + + onChangeOutlinePosition: function(index) { + this.panelNavigation.viewNavigationList.selectByIndex(index); + }, + + onItemContextMenu: function(picker, item, record, e){ + var showPoint; + var menu = this.panelNavigation.navigationMenu; + if (menu.isVisible()) { + menu.hide(); + } + + var parentOffset = this.panelNavigation.$el.offset(), + top = e.clientY*Common.Utils.zoom(); + showPoint = [e.clientX*Common.Utils.zoom() + 5, top - parentOffset.top + 5]; + + var isNotHeader = record.get('isNotHeader'); + menu.items[0].setDisabled(isNotHeader); + menu.items[1].setDisabled(isNotHeader); + menu.items[3].setDisabled(isNotHeader); + menu.items[7].setDisabled(isNotHeader); + + if (showPoint != undefined) { + var menuContainer = this.panelNavigation.$el.find('#menu-navigation-container'); + if (!menu.rendered) { + if (menuContainer.length < 1) { + menuContainer = $('', menu.id); + $(this.panelNavigation.$el).append(menuContainer); + } + menu.render(menuContainer); + menu.cmpEl.attr({tabindex: "-1"}); + } + menu.cmpEl.attr('data-value', record.get('index')); + menuContainer.css({ + left: showPoint[0], + top: showPoint[1] + }); + menu.show(); + _.delay(function() { + menu.cmpEl.focus(); + }, 10); + } + + }, + + onSelectItem: function(picker, item, record, e){ + if (!this._navigationObject) return; + this._navigationObject.goto(record.get('index')); + }, + + onMenuItemClick: function (menu, item) { + if (!this._navigationObject) return; + + var index = parseInt(menu.cmpEl.attr('data-value')); + if (item.value == 'promote') { + this._navigationObject.promote(index); + } else if (item.value == 'demote') { + this._navigationObject.demote(index); + } else if (item.value == 'before') { + this._navigationObject.insertHeader(index, true); + } else if (item.value == 'after') { + this._navigationObject.insertHeader(index, false); + } else if (item.value == 'new') { + this._navigationObject.insertSubHeader(index); + } else if (item.value == 'select') { + this._navigationObject.selectContent(index); + } else if (item.value == 'expand') { + this.panelNavigation.viewNavigationList.expandAll(); + } else if (item.value == 'collapse') { + this.panelNavigation.viewNavigationList.collapseAll(); + } + }, + + onMenuLevelsItemClick: function (menu, item) { + this.panelNavigation.viewNavigationList.expandToLevel(item.value-1); + }, + + txtBeginning: 'Beginning of document', + txtGotoBeginning: 'Go to the beginning of the document' + + }, DE.Controllers.Navigation || {})); +}); diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js index fa16fe48b..3f89c5caa 100644 --- a/apps/documenteditor/main/app/controller/Toolbar.js +++ b/apps/documenteditor/main/app/controller/Toolbar.js @@ -48,13 +48,11 @@ define([ 'common/main/lib/view/InsertTableDialog', 'common/main/lib/util/define', 'documenteditor/main/app/view/Toolbar', - 'documenteditor/main/app/view/HyperlinkSettingsDialog', 'documenteditor/main/app/view/DropcapSettingsAdvanced', 'documenteditor/main/app/view/MailMergeRecepients', 'documenteditor/main/app/view/StyleTitleDialog', 'documenteditor/main/app/view/PageMarginsDialog', 'documenteditor/main/app/view/PageSizeDialog', - 'documenteditor/main/app/view/NoteSettingsDialog', 'documenteditor/main/app/controller/PageLayout', 'documenteditor/main/app/view/CustomColumnsDialog', 'documenteditor/main/app/view/ControlSettingsDialog' @@ -277,7 +275,6 @@ define([ toolbar.mnuLineSpace.on('item:toggle', _.bind(this.onLineSpaceToggle, this)); toolbar.mnuNonPrinting.on('item:toggle', _.bind(this.onMenuNonPrintingToggle, this)); toolbar.btnShowHidenChars.on('toggle', _.bind(this.onNonPrintingToggle, this)); - toolbar.btnInsertHyperlink.on('click', _.bind(this.onHyperlinkClick, this)); toolbar.mnuTablePicker.on('select', _.bind(this.onTablePickerSelect, this)); toolbar.mnuInsertTable.on('item:click', _.bind(this.onInsertTableClick, this)); toolbar.mnuInsertImage.on('item:click', _.bind(this.onInsertImageClick, this)); @@ -311,10 +308,6 @@ define([ toolbar.mnuZoomIn.on('click', _.bind(this.onZoomInClick, this)); toolbar.mnuZoomOut.on('click', _.bind(this.onZoomOutClick, this)); toolbar.btnInsertEquation.on('click', _.bind(this.onInsertEquationClick, this)); - toolbar.btnNotes.on('click', _.bind(this.onNotesClick, this)); - toolbar.btnNotes.menu.on('item:click', _.bind(this.onNotesMenuClick, this)); - toolbar.mnuGotoFootPrev.on('click', _.bind(this.onFootnotePrevClick, this)); - toolbar.mnuGotoFootNext.on('click', _.bind(this.onFootnoteNextClick, this)); $('#id-save-style-plus, #id-save-style-link', toolbar.$el).on('click', this.onMenuSaveStyle.bind(this)); @@ -338,7 +331,6 @@ define([ this.api.asc_registerCallback('asc_onPrAlign', _.bind(this.onApiParagraphAlign, this)); this.api.asc_registerCallback('asc_onTextColor', _.bind(this.onApiTextColor, this)); this.api.asc_registerCallback('asc_onParaSpacingLine', _.bind(this.onApiLineSpacing, this)); - this.api.asc_registerCallback('asc_onCanAddHyperlink', _.bind(this.onApiCanAddHyperlink, this)); this.api.asc_registerCallback('asc_onFocusObject', _.bind(this.onApiFocusObject, this)); this.api.asc_registerCallback('asc_onDocSize', _.bind(this.onApiPageSize, this)); this.api.asc_registerCallback('asc_onPaintFormatChanged', _.bind(this.onApiStyleChange, this)); @@ -574,14 +566,6 @@ define([ } }, - onApiCanAddHyperlink: function(value) { - var need_disable = !value || this._state.prcontrolsdisable; - - if ( this.editMode ) { - this.toolbar.btnInsertHyperlink.setDisabled(need_disable); - } - }, - onApiPageSize: function(w, h) { var width = this._state.pgorient ? w : h, height = this._state.pgorient ? h : w; @@ -770,10 +754,6 @@ define([ toolbar.btnEditHeader.setDisabled(in_equation); - need_disable = paragraph_locked || in_equation || in_image || in_header || control_plain; - if (need_disable !== toolbar.btnNotes.isDisabled()) - toolbar.btnNotes.setDisabled(need_disable); - need_disable = paragraph_locked || header_locked || in_image || control_plain; if (need_disable != toolbar.btnColumns.isDisabled()) toolbar.btnColumns.setDisabled(need_disable); @@ -1314,58 +1294,6 @@ define([ Common.NotificationCenter.trigger('edit:complete', this.toolbar); }, - onHyperlinkClick: function(btn) { - var me = this, - win, props, text; - - if (me.api){ - - var handlerDlg = function(dlg, result) { - if (result == 'ok') { - props = dlg.getSettings(); - (text!==false) - ? me.api.add_Hyperlink(props) - : me.api.change_Hyperlink(props); - } - - Common.NotificationCenter.trigger('edit:complete', me.toolbar); - }; - - text = me.api.can_AddHyperlink(); - - if (text !== false) { - win = new DE.Views.HyperlinkSettingsDialog({ - api: me.api, - handler: handlerDlg - }); - - props = new Asc.CHyperlinkProperty(); - props.put_Text(text); - - win.show(); - win.setSettings(props); - } else { - var selectedElements = me.api.getSelectedElements(); - if (selectedElements && _.isArray(selectedElements)){ - _.each(selectedElements, function(el, i) { - if (selectedElements[i].get_ObjectType() == Asc.c_oAscTypeSelectElement.Hyperlink) - props = selectedElements[i].get_ObjectValue(); - }); - } - if (props) { - win = new DE.Views.HyperlinkSettingsDialog({ - api: me.api, - handler: handlerDlg - }); - win.show(); - win.setSettings(props); - } - } - } - - Common.component.Analytics.trackEvent('ToolBar', 'Add Hyperlink'); - }, - onTablePickerSelect: function(picker, columns, rows, e) { if (this.api) { this.toolbar.fireEvent('inserttable', this.toolbar); @@ -2109,68 +2037,6 @@ define([ Common.NotificationCenter.trigger('edit:complete', this.toolbar); }, - onNotesClick: function() { - if (this.api) - this.api.asc_AddFootnote(); - }, - - onNotesMenuClick: function(menu, item) { - if (this.api) { - if (item.value == 'ins_footnote') - this.api.asc_AddFootnote(); - else if (item.value == 'delele') - Common.UI.warning({ - msg: this.confirmDeleteFootnotes, - buttons: ['yes', 'no'], - primary: 'yes', - callback: _.bind(function(btn) { - if (btn == 'yes') { - this.api.asc_RemoveAllFootnotes(); - } - Common.NotificationCenter.trigger('edit:complete', this.toolbar); - }, this) - }); - else if (item.value == 'settings') { - var me = this; - (new DE.Views.NoteSettingsDialog({ - api: me.api, - handler: function(result, settings) { - if (settings) { - me.api.asc_SetFootnoteProps(settings.props, settings.applyToAll); - if (result == 'insert') - me.api.asc_AddFootnote(settings.custom); - } - Common.NotificationCenter.trigger('edit:complete', me.toolbar); - }, - props : me.api.asc_GetFootnoteProps() - })).show(); - } else - return; - - Common.NotificationCenter.trigger('edit:complete', this.toolbar); - } - }, - - onFootnotePrevClick: function(btn) { - if (this.api) - this.api.asc_GotoFootnote(false); - - var me = this; - setTimeout(function() { - Common.NotificationCenter.trigger('edit:complete', me.toolbar); - }, 50); - }, - - onFootnoteNextClick: function(btn) { - if (this.api) - this.api.asc_GotoFootnote(true); - - var me = this; - setTimeout(function() { - Common.NotificationCenter.trigger('edit:complete', me.toolbar); - }, 50); - }, - _clearBullets: function() { this.toolbar.btnMarkers.toggle(false, true); this.toolbar.btnNumbers.toggle(false, true); @@ -2895,15 +2761,19 @@ define([ var $panel = this.getApplication().getController('Common.Controllers.ReviewChanges').createToolbarPanel(); if ( $panel ) - me.toolbar.addTab(tab, $panel, 3); + 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 ( $panel ) - me.toolbar.addTab(tab, $panel, 4); + me.toolbar.addTab(tab, $panel, 5); } + + var links = me.getApplication().getController('Links'); + links.setApi(me.api).setConfig({toolbar: me}); + Array.prototype.push.apply(me.toolbar.toolbarControls, links.getView('Links').getButtons()); } }, @@ -3309,8 +3179,7 @@ define([ confirmAddFontName: 'The font you are going to save is not available on the current device.
The text style will be displayed using one of the device fonts, the saved font will be used when it is available.
Do you want to continue?', 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', - confirmDeleteFootnotes: 'Do you want to delete all footnotes?' + txtMarginsH: 'Top and bottom margins are too high for a given page height' }, DE.Controllers.Toolbar || {})); }); \ No newline at end of file diff --git a/apps/documenteditor/main/app/template/LeftMenu.template b/apps/documenteditor/main/app/template/LeftMenu.template index 70f94a475..ad40fa7e8 100644 --- a/apps/documenteditor/main/app/template/LeftMenu.template +++ b/apps/documenteditor/main/app/template/LeftMenu.template @@ -6,6 +6,7 @@ + @@ -15,5 +16,6 @@ +
+
+ + +
+
+
+ +
+
+
+ +
+
\ No newline at end of file diff --git a/apps/documenteditor/main/app/view/LeftMenu.js b/apps/documenteditor/main/app/view/LeftMenu.js index 40da13f04..470a9a8b0 100644 --- a/apps/documenteditor/main/app/view/LeftMenu.js +++ b/apps/documenteditor/main/app/view/LeftMenu.js @@ -53,7 +53,8 @@ define([ 'common/main/lib/view/Plugins', 'common/main/lib/view/About', 'common/main/lib/view/SearchDialog', - 'documenteditor/main/app/view/FileMenu' + 'documenteditor/main/app/view/FileMenu', + 'documenteditor/main/app/view/Navigation' ], function (menuTemplate, $, _, Backbone) { 'use strict'; @@ -73,6 +74,7 @@ define([ 'click #left-btn-chat': _.bind(this.onCoauthOptions, this), /** coauthoring end **/ 'click #left-btn-plugins': _.bind(this.onCoauthOptions, this), + 'click #left-btn-navigation': _.bind(this.onCoauthOptions, this), 'click #left-btn-support': function() { var config = this.mode.customization; config && !!config.feedback && !!config.feedback.url ? @@ -151,6 +153,15 @@ define([ this.btnPlugins.hide(); this.btnPlugins.on('click', _.bind(this.onBtnMenuClick, this)); + this.btnNavigation = new Common.UI.Button({ + el: $('#left-btn-navigation'), + hint: this.tipNavigation, + enableToggle: true, + disabled: true, + toggleGroup: 'leftMenuGroup' + }); + this.btnNavigation.on('click', _.bind(this.onBtnMenuClick, this)); + this.btnSearch.on('click', _.bind(this.onBtnMenuClick, this)); this.btnAbout.on('toggle', _.bind(this.onBtnMenuToggle, this)); @@ -222,6 +233,12 @@ define([ this.panelChat['hide'](); } } + if (this.panelNavigation) { + if (this.btnNavigation.pressed) { + this.panelNavigation.show(); + } else + this.panelNavigation['hide'](); + } /** coauthoring end **/ // if (this.mode.canPlugins && this.panelPlugins) { // if (this.btnPlugins.pressed) { @@ -243,6 +260,9 @@ define([ } else if (name == 'plugins' && !this.panelPlugins) { this.panelPlugins = panel.render(/*'#left-panel-plugins'*/); + } else + if (name == 'navigation' && !this.panelNavigation) { + this.panelNavigation = panel.render('#left-panel-navigation'); } }, @@ -284,6 +304,10 @@ define([ this.panelPlugins['hide'](); this.btnPlugins.toggle(false, true); } + if (this.panelNavigation) { + this.panelNavigation['hide'](); + this.btnNavigation.toggle(false, true); + } } }, @@ -304,6 +328,7 @@ define([ this.btnChat.setDisabled(false); /** coauthoring end **/ this.btnPlugins.setDisabled(false); + this.btnNavigation.setDisabled(false); }, showMenu: function(menu, opts) { @@ -385,6 +410,7 @@ define([ tipSearch : 'Search', tipPlugins : 'Plugins', txtDeveloper: 'DEVELOPER MODE', - txtTrial: 'TRIAL MODE' + txtTrial: 'TRIAL MODE', + tipNavigation: 'Navigation' }, DE.Views.LeftMenu || {})); }); diff --git a/apps/documenteditor/main/app/view/Links.js b/apps/documenteditor/main/app/view/Links.js new file mode 100644 index 000000000..896d07fa0 --- /dev/null +++ b/apps/documenteditor/main/app/view/Links.js @@ -0,0 +1,272 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * Links.js + * + * Created by Julia Radzhabova on 22.12.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'common/main/lib/util/utils', + 'common/main/lib/component/BaseView', + 'common/main/lib/component/Layout' +], function () { + 'use strict'; + + DE.Views.Links = Common.UI.BaseView.extend(_.extend((function(){ + function setEvents() { + var me = this; + this.btnsContents.forEach(function(button) { + button.menu.on('item:click', function (menu, item, e) { + me.fireEvent('links:contents', [item.value]); + }); + button.on('click', function (b, e) { + me.fireEvent('links:contents', [0]); + }); + }); + + this.btnContentsUpdate.menu.on('item:click', function (menu, item, e) { + me.fireEvent('links:update', [item.value]); + }); + this.btnContentsUpdate.on('click', function (b, e) { + me.fireEvent('links:update', ['all']); + }); + + this.btnsNotes.forEach(function(button) { + button.menu.on('item:click', function (menu, item, e) { + me.fireEvent('links:notes', [item.value]); + }); + button.on('click', function (b, e) { + me.fireEvent('links:notes', ['ins_footnote']); + }); + }); + + this.btnsPrevNote.forEach(function(button) { + button.on('click', function (b, e) { + me.fireEvent('links:notes', ['prev']); + }); + }); + + this.btnsNextNote.forEach(function(button) { + button.on('click', function (b, e) { + me.fireEvent('links:notes', ['next']); + }); + }); + + this.btnsHyperlink.forEach(function(button) { + button.on('click', function (b, e) { + me.fireEvent('links:hyperlink'); + }); + }); + } + + return { + + options: {}, + + initialize: function (options) { + Common.UI.BaseView.prototype.initialize.call(this); + this.toolbar = options.toolbar; + + this.btnsContents = []; + this.btnsNotes = []; + this.btnsPrevNote = []; + this.btnsNextNote = []; + this.btnsHyperlink = []; + this.paragraphControls = []; + + var me = this, + $host = me.toolbar.$el; + var _injectComponent = function (id, cmp) { + var $slot = $host.find(id); + if ($slot.length) + cmp.rendered ? $slot.append(cmp.$el) : cmp.render($slot); + }; + + var _injectComponents = function ($slots, iconCls, split, menu, caption, btnsArr) { + $slots.each(function(index, el) { + var _cls = 'btn-toolbar'; + /x-huge/.test(el.className) && (_cls += ' x-huge icon-top'); + + var button = new Common.UI.Button({ + cls: _cls, + iconCls: iconCls, + caption: caption, + split: split, + menu: menu, + disabled: true + }).render( $slots.eq(index) ); + + btnsArr.push(button); + me.paragraphControls.push(button); + }); + }; + + _injectComponents($host.find('.btn-slot.btn-contents'), 'btn-contents', true, true, me.capBtnInsContents, me.btnsContents); + _injectComponents($host.find('.btn-slot.slot-notes'), 'btn-notes', true, true, me.capBtnInsFootnote, me.btnsNotes); + _injectComponents($host.find('.btn-slot.slot-inshyperlink'), 'btn-inserthyperlink', false, false, me.capBtnInsLink, me.btnsHyperlink); + + this.btnContentsUpdate = new Common.UI.Button({ + cls: 'btn-toolbar x-huge icon-top', + iconCls: 'btn-contents-update', + caption: this.capBtnContentsUpdate, + split: true, + menu: true, + disabled: true + }); + _injectComponent('#slot-btn-contents-update', this.btnContentsUpdate); + this.paragraphControls.push(this.btnContentsUpdate); + + this._state = {disabled: false}; + Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this)); + }, + + render: function (el) { + return this; + }, + + onAppReady: function (config) { + var me = this; + (new Promise(function (accept, reject) { + accept(); + })).then(function(){ + var contentsTemplate = _.template('
'); + me.btnsContents.forEach( function(btn) { + btn.updateHint( me.tipContents ); + + var _menu = new Common.UI.Menu({ + items: [ + {template: contentsTemplate, offsety: 0, value: 0}, + {template: contentsTemplate, offsety: 72, value: 1}, + {caption: me.textContentsSettings, value: 'settings'}, + {caption: me.textContentsRemove, value: 'remove'} + ] + }); + + btn.setMenu(_menu); + }); + + me.btnContentsUpdate.updateHint(me.tipContentsUpdate); + me.btnContentsUpdate.setMenu(new Common.UI.Menu({ + items: [ + {caption: me.textUpdateAll, value: 'all'}, + {caption: me.textUpdatePages, value: 'pages'} + ] + })); + + me.btnsNotes.forEach( function(btn, index) { + btn.updateHint( me.tipNotes ); + + var _menu = new Common.UI.Menu({ + items: [ + {caption: me.mniInsFootnote, value: 'ins_footnote'}, + {caption: '--'}, + new Common.UI.MenuItem({ + template: _.template([ + '' + ].join('')), + stopPropagation: true + }), + {caption: '--'}, + {caption: me.mniDelFootnote, value: 'delele'}, + {caption: me.mniNoteSettings, value: 'settings'} + ] + }); + btn.setMenu(_menu); + + me.btnsPrevNote.push(new Common.UI.Button({ + el: $('#id-menu-goto-footnote-prev-'+index), + cls: 'btn-toolbar' + })); + me.btnsNextNote.push(me.mnuGotoFootNext = new Common.UI.Button({ + el: $('#id-menu-goto-footnote-next-'+index), + cls: 'btn-toolbar' + })); + }); + + me.btnsHyperlink.forEach( function(btn) { + btn.updateHint(me.tipInsertHyperlink + Common.Utils.String.platformKey('Ctrl+K')); + }); + + setEvents.call(me); + }); + }, + + show: function () { + Common.UI.BaseView.prototype.show.call(this); + this.fireEvent('show', this); + }, + + getButtons: function() { + return this.paragraphControls; + }, + + SetDisabled: function (state) { + this._state.disabled = state; + this.paragraphControls.forEach(function(button) { + if ( button ) { + button.setDisabled(state); + } + }, this); + }, + + capBtnInsContents: 'Table of Contents', + tipContents: 'Insert table of contents', + textContentsSettings: 'Settings', + textContentsRemove: 'Remove table of contents', + capBtnContentsUpdate: 'Update', + tipContentsUpdate: 'Update table of contents', + textUpdateAll: 'Update entire table', + textUpdatePages: 'Update page numbers only', + tipNotes: 'Footnotes', + mniInsFootnote: 'Insert Footnote', + mniDelFootnote: 'Delete All Footnotes', + mniNoteSettings: 'Notes Settings', + textGotoFootnote: 'Go to Footnotes', + capBtnInsFootnote: 'Footnotes', + confirmDeleteFootnotes: 'Do you want to delete all footnotes?', + capBtnInsLink: 'Hyperlink', + tipInsertHyperlink: 'Add Hyperlink' + } + }()), DE.Views.Links || {})); +}); \ No newline at end of file diff --git a/apps/documenteditor/main/app/view/Navigation.js b/apps/documenteditor/main/app/view/Navigation.js new file mode 100644 index 000000000..a6a14f123 --- /dev/null +++ b/apps/documenteditor/main/app/view/Navigation.js @@ -0,0 +1,163 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * +*/ +/** + * User: Julia.Radzhabova + * Date: 14.12.17 + */ + +define([ + 'common/main/lib/util/utils', + 'common/main/lib/component/BaseView', + 'common/main/lib/component/Layout', + 'common/main/lib/component/TreeView' +], function (template) { + 'use strict'; + + DE.Views.Navigation = Common.UI.BaseView.extend(_.extend({ + el: '#left-panel-navigation', + + storeNavigation: undefined, + template: _.template([ + '' + ].join('')), + + initialize: function(options) { + _.extend(this, options); + Common.UI.BaseView.prototype.initialize.call(this, arguments); + }, + + render: function(el) { + el = el || this.el; + $(el).html(this.template({scope: this})); + this.$el = $(el); + + this.viewNavigationList = new Common.UI.TreeView({ + el: $('#navigation-list'), + store: this.storeNavigation, + enableKeyEvents: false, + emptyText: this.txtEmpty, + emptyItemText: this.txtEmptyItem + }); + this.viewNavigationList.cmpEl.off('click'); + this.navigationMenu = new Common.UI.Menu({ + items: [{ + caption : this.txtPromote, + value: 'promote' + }, + { + caption : this.txtDemote, + value: 'demote' + }, + { + caption : '--' + }, + { + caption : this.txtHeadingBefore, + value: 'before' + }, + { + caption : this.txtHeadingAfter, + value: 'after' + }, + { + caption : this.txtNewHeading, + value: 'new' + }, + { + caption : '--' + }, + { + caption : this.txtSelect, + value: 'select' + }, + { + caption : '--' + }, + { + caption : this.txtExpand, + value: 'expand' + }, + { + caption : this.txtCollapse, + value: 'collapse' + }, + { + caption : this.txtExpandToLevel, + menu: new Common.UI.Menu({ + menuAlign: 'tl-tr', + style: 'min-width: 60px;', + items: [{ caption : '1', value: 1 }, { caption : '2', value: 2 }, { caption : '3', value: 3 }, + { caption : '4', value: 4 }, { caption : '5', value: 5 }, { caption : '6', value: 6 }, + { caption : '7', value: 7 }, { caption : '8', value: 8 }, { caption : '9', value: 9 } + ] + }) + } + ] + }); + + this.trigger('render:after', this); + return this; + }, + + show: function () { + Common.UI.BaseView.prototype.show.call(this,arguments); + this.fireEvent('show', this ); + }, + + hide: function () { + Common.UI.BaseView.prototype.hide.call(this,arguments); + this.fireEvent('hide', this ); + }, + + ChangeSettings: function(props) { + }, + + strNavigate: 'Table of Contents', + txtPromote: 'Promote', + txtDemote: 'Demote', + txtHeadingBefore: 'New heading before', + txtHeadingAfter: 'New heading after', + txtNewHeading: 'New subheading', + txtSelect: 'Select content', + txtExpand: 'Expand all', + txtCollapse: 'Collapse all', + txtExpandToLevel: 'Expand to level...', + txtEmpty: 'This document doesn\'t contain headings', + txtEmptyItem: 'Empty Heading' + + }, DE.Views.Navigation || {})); +}); \ No newline at end of file diff --git a/apps/documenteditor/main/app/view/TableOfContentsSettings.js b/apps/documenteditor/main/app/view/TableOfContentsSettings.js new file mode 100644 index 000000000..ca0ab8aca --- /dev/null +++ b/apps/documenteditor/main/app/view/TableOfContentsSettings.js @@ -0,0 +1,615 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2017 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * TableOfContentsSettings.js.js + * + * Created by Julia Radzhabova on 26.12.2017 + * Copyright (c) 2017 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'common/main/lib/util/utils', + 'common/main/lib/component/MetricSpinner', + 'common/main/lib/component/ComboBox', + 'common/main/lib/view/AdvancedSettingsWindow' +], function () { 'use strict'; + + DE.Views.TableOfContentsSettings = Common.Views.AdvancedSettingsWindow.extend(_.extend({ + options: { + contentWidth: 500, + height: 455 + }, + + initialize : function(options) { + var me = this; + + _.extend(this.options, { + title: this.textTitle, + template: [ + '
', + '
', + '
', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '', + '
', + '
', + '', + '
', + '', + '
', + '
', + '
', + '
', + '', + '
', + '
', + '', + '
', + '', + '
', + '
', + '
', + '
', + '
', + '
', + '' + ].join('') + }, options); + + this.api = options.api; + this.handler = options.handler; + this.props = options.props; + this.startLevel = 1; + this.endLevel = 3; + this._noApply = true; + this._originalProps = null; + + Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.Views.AdvancedSettingsWindow.prototype.render.call(this); + var me = this; + + this.chPages = new Common.UI.CheckBox({ + el: $('#tableofcontents-chb-pages'), + labelText: this.strShowPages, + value: 'checked' + }); + this.chPages.on('change', _.bind(function(field, newValue, oldValue, eOpts){ + var checked = (field.getValue()=='checked'); + this.chAlign.setDisabled(!checked); + this.cmbLeader.setDisabled(!checked); + if (this.api && !this._noApply) { + var properties = (this._originalProps) ? this._originalProps : new Asc.CTableOfContentsPr(); + properties.put_ShowPageNumbers(checked); + if (checked) { + properties.put_RightAlignTab(this.chAlign.getValue() == 'checked'); + properties.put_TabLeader(this.cmbLeader.getValue()); + } + // this.api.SetDrawImagePlaceContents('tableofcontents-img', properties); + } + }, this)); + + this.chAlign = new Common.UI.CheckBox({ + el: $('#tableofcontents-chb-align'), + labelText: this.strAlign, + value: 'checked' + }); + this.chAlign.on('change', _.bind(function(field, newValue, oldValue, eOpts){ + var checked = (field.getValue()=='checked'); + this.cmbLeader.setDisabled(!checked); + if (this.api && !this._noApply) { + var properties = (this._originalProps) ? this._originalProps : new Asc.CTableOfContentsPr(); + properties.put_RightAlignTab(checked); + if (checked) { + properties.put_TabLeader(this.cmbLeader.getValue()); + } + // this.api.SetDrawImagePlaceContents('tableofcontents-img', properties); + } + }, this)); + + this.cmbLeader = new Common.UI.ComboBox({ + el : $('#tableofcontents-combo-leader'), + style : 'width: 85px;', + menuStyle : 'min-width: 85px;', + editable : false, + cls : 'input-group-nr', + data : [ + { value: Asc.c_oAscTabLeader.None, displayValue: this.textNone }, + { value: Asc.c_oAscTabLeader.Dot, displayValue: '....................' }, + { value: Asc.c_oAscTabLeader.Hyphen, displayValue: '-----------------' }, + { value: Asc.c_oAscTabLeader.Underscore,displayValue: '__________' } + ] + }); + this.cmbLeader.setValue(Asc.c_oAscTabLeader.Dot); + this.cmbLeader.on('selected', _.bind(function(combo, record) { + if (this.api && !this._noApply) { + var properties = (this._originalProps) ? this._originalProps : new Asc.CTableOfContentsPr(); + properties.put_TabLeader(record.value); + // this.api.SetDrawImagePlaceContents('tableofcontents-img', properties); + } + }, this)); + + this.chLinks = new Common.UI.CheckBox({ + el: $('#tableofcontents-chb-links'), + labelText: this.strLinks, + value: 'checked' + }); + this.chLinks.on('change', _.bind(function(field, newValue, oldValue, eOpts){ + if (this.api && !this._noApply) { + var properties = (this._originalProps) ? this._originalProps : new Asc.CTableOfContentsPr(); + properties.put_Hyperlink(field.getValue()=='checked'); + // this.api.SetDrawImagePlaceContents('tableofcontents-img', properties); + } + }, this)); + + this.radioLevels = new Common.UI.RadioBox({ + el: $('#tableofcontents-radio-levels'), + labelText: this.textRadioLevels, + name: 'asc-radio-content-build', + checked: true + }); + this.radioLevels.on('change', _.bind(function(field, newValue, eOpts) { + if (newValue) { + this.levelsContainer.toggleClass('hidden', !newValue); + this.stylesContainer.toggleClass('hidden', newValue); + if (this._needUpdateOutlineLevels) + this.synchronizeLevelsFromStyles(); + } + }, this)); + + this.radioStyles = new Common.UI.RadioBox({ + el: $('#tableofcontents-radio-styles'), + labelText: this.textRadioStyles, + name: 'asc-radio-content-build' + }); + this.radioStyles.on('change', _.bind(function(field, newValue, eOpts) { + if (newValue) { + this.stylesContainer.toggleClass('hidden', !newValue); + this.levelsContainer.toggleClass('hidden', newValue); + if (this._needUpdateStyles) + this.synchronizeLevelsFromOutline(); + this.stylesList.scroller.update({alwaysVisibleY: true}); + setTimeout(function(){ + var rec = me.stylesLevels.findWhere({checked: true}); + if (rec) + me.stylesList.scrollToRecord(rec); + }, 10); + } + }, this)); + + this.cmbStyles = new Common.UI.ComboBox({ + el: $('#tableofcontents-combo-styles'), + cls: 'input-group-nr', + menuStyle: 'min-width: 150px;', + editable: false, + data: [ + { displayValue: this.txtCurrent, value: Asc.c_oAscTOCStylesType.Current }, + { displayValue: this.txtSimple, value: Asc.c_oAscTOCStylesType.Simple }, + { displayValue: this.txtStandard, value: Asc.c_oAscTOCStylesType.Standard }, + { displayValue: this.txtModern, value: Asc.c_oAscTOCStylesType.Modern }, + { displayValue: this.txtClassic, value: Asc.c_oAscTOCStylesType.Classic } + ] + }); + this.cmbStyles.setValue(Asc.c_oAscTOCStylesType.Current); + this.cmbStyles.on('selected', _.bind(function(combo, record) { + if (this.api && !this._noApply) { + var properties = (this._originalProps) ? this._originalProps : new Asc.CTableOfContentsPr(); + properties.put_StylesType(record.value); + // this.api.SetDrawImagePlaceContents('tableofcontents-img', properties); + } + }, this)); + + this.spnLevels = new Common.UI.CustomSpinner({ + el: $('#tableofcontents-spin-levels'), + step: 1, + width: 85, + defaultUnit : "", + value: 3, + maxValue: 9, + minValue: 1, + allowDecimal: false, + maskExp: /[1-9]/ + }); + this.spnLevels.on('change', _.bind(function(field, newValue, oldValue, eOpts){ + this._needUpdateStyles = true; + this.startLevel = 1; + this.endLevel = field.getNumberValue(); + + if (this.api && !this._noApply) { + var properties = (this._originalProps) ? this._originalProps : new Asc.CTableOfContentsPr(); + properties.clear_Styles(); + properties.put_OutlineRange(this.startLevel, this.endLevel); + // this.api.SetDrawImagePlaceContents('tableofcontents-img', properties); + } + }, this)); + + this.stylesLevels = new Common.UI.DataViewStore(); + + if (this.stylesLevels) { + this.stylesList = new Common.UI.ListView({ + el: $('#tableofcontents-styles-list', this.$window), + store: this.stylesLevels, + simpleAddMode: true, + showLast: false, + template: _.template(['
'].join('')), + itemTemplate: _.template([ + '
', + '
<%= name %>
', + '
', + '
', + '
', + '
', + '
' + ].join('')) + }); + this.stylesList.on('item:change', _.bind(this.onItemChange, this)); + this.stylesList.on('item:add', _.bind(this.addEvents, this)); + } + + this.levelsContainer = $('#tableofcontents-from-levels'); + this.stylesContainer = $('#tableofcontents-from-styles'); + this.afterRender(); + }, + + afterRender: function() { + this._setDefaults(this.props); + }, + + show: function() { + Common.Views.AdvancedSettingsWindow.prototype.show.apply(this, arguments); + }, + + _setDefaults: function (props) { + this._noApply = true; + + var me = this, + docStyles = this.api.asc_GetStylesArray(), + styles = []; + _.each(docStyles, function (style) { + var name = style.get_Name(), + level = me.api.asc_GetHeadingLevel(name); + if (style.get_QFormat() || level>=0) { + styles.push({ + name: name, + allowSelected: false, + checked: false, + value: '', + headerLevel: (level>=0) ? level+1 : -1 // -1 if is not header + }); + } + }); + + if (props) { + var value = props.get_Hyperlink(); + this.chLinks.setValue((value !== null && value !== undefined) ? value : 'indeterminate', true); + value = props.get_StylesType(); + this.cmbStyles.setValue((value!==null) ? value : Asc.c_oAscTOCStylesType.Current); + + var start = props.get_OutlineStart(), + end = props.get_OutlineEnd(), + count = props.get_StylesCount(); + + this.startLevel = start; + this.endLevel = end; + + if ((start<0 || end<0) && count<1) { + start = 1; + end = 9; + this.spnLevels.setValue(end, true); + } + + var disable_outlines = false; + for (var i=0; i0 && end>0) { + for (var i=start; i<=end; i++) { + var rec = _.findWhere(styles, {headerLevel: i}); + if (rec) { + rec.checked = true; + rec.value = i; + } + } + } + var new_start = -1, new_end = -1, empty_index = -1; + for (var i=0; i<9; i++) { + var rec = _.findWhere(styles, {headerLevel: i+1}); + if (rec) { + var headerLevel = rec.headerLevel, + level = rec.value; + if (headerLevel == level) { + if (empty_index<1) { + if (new_start<1) + new_start = level; + new_end = level; + } else { + new_start = new_end = -1; + disable_outlines = true; + break; + } + } else if (!rec.checked) { + (new_start>0) && (empty_index = i+1); + } else { + new_start = new_end = -1; + disable_outlines = true; + break; + } + } + } + + this.spnLevels.setValue(new_end>0 ? new_end : '', true); + this.spnLevels.setDisabled(disable_outlines || new_start>1 ); + } + this.stylesLevels.reset(styles); + if (this.spnLevels.isDisabled()) { + this.radioStyles.setValue(true); + this.stylesList.scroller.update({alwaysVisibleY: true}); + var rec = this.stylesLevels.findWhere({checked: true}); + if (rec) + this.stylesList.scrollToRecord(rec); + } + + // Show Pages is always true when window is opened + this._originalProps = (props) ? props : new Asc.CTableOfContentsPr(); + if (!props) { + this._originalProps.put_OutlineRange(this.startLevel, this.endLevel); + this._originalProps.put_Hyperlink(this.chLinks.getValue() == 'checked'); + } + this._originalProps.put_ShowPageNumbers(this.chPages.getValue() == 'checked'); + if (this.chPages.getValue() == 'checked') { + this._originalProps.put_RightAlignTab(this.chAlign.getValue() == 'checked'); + this._originalProps.put_TabLeader(this.cmbLeader.getValue()); + } + + // this.api.SetDrawImagePlaceContents('tableofcontents-img', this._originalProps); + + this._noApply = false; + }, + + synchronizeLevelsFromOutline: function() { + var start = 1, end = this.spnLevels.getNumberValue(); + this.stylesLevels.each(function (style) { + var header = style.get('headerLevel'); + if (header>=start && header<=end) { + style.set('checked', true); + style.set('value', header); + } else { + style.set('checked', false); + style.set('value', ''); + } + }); + this._needUpdateStyles = false; + }, + + synchronizeLevelsFromStyles: function() { + var new_start = -1, new_end = -1, empty_index = -1, + disable_outlines = false; + + for (var i=0; i<9; i++) { + var rec = this.stylesLevels.findWhere({headerLevel: i+1}); + if (rec) { + var headerLevel = rec.get('headerLevel'), + level = rec.get('value'); + if (headerLevel == level) { + if (empty_index<1) { + if (new_start<1) + new_start = level; + new_end = level; + } else { + new_start = new_end = -1; + disable_outlines = true; + break; + } + } else if (!rec.get('checked')) { + (new_start>0) && (empty_index = i+1); + } else { + new_start = new_end = -1; + disable_outlines = true; + break; + } + } + } + if (new_start<0 && new_end<0) { + var rec = this.stylesLevels.findWhere({checked: true}); + if (rec) { // has checked style + disable_outlines = true; + } else { // all levels are empty + new_start = 1; + new_end = 9; + } + } + + this.startLevel = new_start; + this.endLevel = new_end; + + this.spnLevels.setValue(new_end>0 ? new_end : '', true); + this.spnLevels.setDisabled(disable_outlines || new_start>1 ); + this._needUpdateOutlineLevels = false; + }, + + getSettings: function () { + var props = new Asc.CTableOfContentsPr(); + + props.put_Hyperlink(this.chLinks.getValue() == 'checked'); + props.put_ShowPageNumbers(this.chPages.getValue() == 'checked'); + if (this.chPages.getValue() == 'checked') { + props.put_RightAlignTab(this.chAlign.getValue() == 'checked'); + props.put_TabLeader(this.cmbLeader.getValue()); + } + props.put_StylesType(this.cmbStyles.getValue()); + + props.clear_Styles(); + if (this._needUpdateOutlineLevels) { + this.synchronizeLevelsFromStyles(); + } + if (!this._needUpdateStyles) // if this._needUpdateStyles==true - fill only OutlineRange + this.stylesLevels.each(function (style) { + if (style.get('checked')) + props.add_Style(style.get('name'), style.get('value')); + }); + props.put_OutlineRange(this.startLevel, this.endLevel); + return props; + }, + + addEvents: function(listView, itemView, record) { + var input = itemView.$el.find('input'), + me = this; + input.on('keypress', function(e) { + var charCode = String.fromCharCode(e.which); + if(!/[1-9]/.test(charCode) && !e.ctrlKey && e.keyCode !== Common.UI.Keys.DELETE && e.keyCode !== Common.UI.Keys.BACKSPACE && + e.keyCode !== Common.UI.Keys.LEFT && e.keyCode !== Common.UI.Keys.RIGHT && e.keyCode !== Common.UI.Keys.HOME && + e.keyCode !== Common.UI.Keys.END && e.keyCode !== Common.UI.Keys.ESC && e.keyCode !== Common.UI.Keys.INSERT && + e.keyCode !== Common.UI.Keys.TAB || input.val().length>1){ + e.preventDefault(); + e.stopPropagation(); + } + + }); + input.on('input', function(e) { + // console.log(input.val()); + var isEmpty = _.isEmpty(input.val()); + if (record.get('checked') !== !isEmpty) { + record.set('checked', !isEmpty); + } + record.set('value', (isEmpty) ? '' : parseInt(input.val())); + me._needUpdateOutlineLevels = true; + + if (me.api && !me._noApply) { + var properties = (me._originalProps) ? me._originalProps : new Asc.CTableOfContentsPr(); + properties.clear_Styles(); + me.stylesLevels.each(function (style) { + if (style.get('checked')) + properties.add_Style(style.get('name'), style.get('value')); + }); + if (properties.get_StylesCount()>0) + properties.put_OutlineRange(-1, -1); + else + properties.put_OutlineRange(1, 9); + // this.api.SetDrawImagePlaceContents('tableofcontents-img', properties); + } + + }); + }, + + onItemChange: function(listView, itemView, record) { + this.addEvents(listView, itemView, record); + setTimeout(function(){ + itemView.$el.find('input').focus(); + }, 10); + }, + + textTitle: 'Table of Contents', + textLeader: 'Leader', + textBuildTable: 'Build table of contents from', + textLevels: 'Levels', + textStyles: 'Styles', + strShowPages: 'Show page numbers', + strAlign: 'Right align page numbers', + strLinks: 'Format Table of Contents as links', + textNone: 'None', + textRadioLevels: 'Outline levels', + textRadioStyles: 'Selected styles', + textStyle: 'Style', + textLevel: 'Level', + cancelButtonText: 'Cancel', + okButtonText : 'Ok', + txtCurrent: 'Current', + txtSimple: 'Simple', + txtStandard: 'Standard', + txtModern: 'Modern', + txtClassic: 'Classic' + + }, DE.Views.TableOfContentsSettings || {})) +}); \ 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 6783aa4d9..0d631857d 100644 --- a/apps/documenteditor/main/app/view/Toolbar.js +++ b/apps/documenteditor/main/app/view/Toolbar.js @@ -83,7 +83,8 @@ define([ { caption: me.textTabFile, action: 'file', extcls: 'canedit'}, { caption: me.textTabHome, action: 'home', extcls: 'canedit'}, { caption: me.textTabInsert, action: 'ins', extcls: 'canedit'}, - { caption: me.textTabLayout, action: 'layout', extcls: 'canedit'} + { caption: me.textTabLayout, action: 'layout', extcls: 'canedit'}, + { caption: me.textTabLinks, action: 'links', extcls: 'canedit'} ]} ); @@ -520,14 +521,6 @@ define([ }); this.paragraphControls.push(this.btnInsertTextArt); - this.btnInsertHyperlink = new Common.UI.Button({ - id: 'tlbtn-insertlink', - cls: 'btn-toolbar x-huge icon-top', - caption: me.capBtnInsLink, - iconCls: 'btn-inserthyperlink' - }); - this.paragraphControls.push(this.btnInsertHyperlink); - this.btnEditHeader = new Common.UI.Button({ id: 'id-toolbar-btn-editheader', cls: 'btn-toolbar x-huge icon-top', @@ -942,16 +935,6 @@ define([ }); this.toolbarControls.push(this.btnColorSchemas); - this.btnNotes = new Common.UI.Button({ - id: 'id-toolbar-btn-notes', - cls: 'btn-toolbar x-huge icon-top', - iconCls: 'btn-notes', - caption: me.capBtnInsFootnote, - split: true, - menu: true - }); - this.paragraphControls.push(this.btnNotes); - this.btnMailRecepients = new Common.UI.Button({ id: 'id-toolbar-btn-mailrecepients', cls: 'btn-toolbar', @@ -1293,7 +1276,6 @@ define([ _injectComponent('#slot-btn-dropcap', this.btnDropCap); _injectComponent('#slot-btn-controls', this.btnContentControls); _injectComponent('#slot-btn-columns', this.btnColumns); - _injectComponent('#slot-btn-inshyperlink', this.btnInsertHyperlink); _injectComponent('#slot-btn-editheader', this.btnEditHeader); _injectComponent('#slot-btn-insshape', this.btnInsertShape); _injectComponent('#slot-btn-insequation', this.btnInsertEquation); @@ -1309,7 +1291,6 @@ define([ _injectComponent('#slot-field-styles', this.listStyles); _injectComponent('#slot-btn-halign', this.btnHorizontalAlign); _injectComponent('#slot-btn-mailrecepients', this.btnMailRecepients); - _injectComponent('#slot-btn-notes', this.btnNotes); _injectComponent('#slot-img-align', this.btnImgAlign); _injectComponent('#slot-img-group', this.btnImgGroup); _injectComponent('#slot-img-movefrwd', this.btnImgForward); @@ -1544,7 +1525,6 @@ define([ this.btnInsertChart.updateHint(this.tipInsertChart); this.btnInsertText.updateHint(this.tipInsertText); this.btnInsertTextArt.updateHint(this.tipInsertTextArt); - this.btnInsertHyperlink.updateHint(this.tipInsertHyperlink + Common.Utils.String.platformKey('Ctrl+K')); this.btnEditHeader.updateHint(this.tipEditHeader); this.btnInsertShape.updateHint(this.tipInsertShape); this.btnInsertEquation.updateHint(this.tipInsertEquation); @@ -1560,7 +1540,6 @@ define([ this.btnMailRecepients.updateHint(this.tipMailRecepients); this.btnHide.updateHint(this.tipViewSettings); this.btnAdvSettings.updateHint(this.tipAdvSettings); - this.btnNotes.updateHint(this.tipNotes); // set menus @@ -1685,40 +1664,6 @@ define([ cls: 'btn-toolbar' }); - this.btnNotes.setMenu( - new Common.UI.Menu({ - items: [ - {caption: this.mniInsFootnote, value: 'ins_footnote'}, - {caption: '--'}, - this.mnuGotoFootnote = new Common.UI.MenuItem({ - template: _.template([ - '' - ].join('')), - stopPropagation: true - }), - {caption: '--'}, - {caption: this.mniDelFootnote, value: 'delele'}, - {caption: this.mniNoteSettings, value: 'settings'} - ] - }) - ); - - this.mnuGotoFootPrev = new Common.UI.Button({ - el: $('#id-menu-goto-footnote-prev'), - cls: 'btn-toolbar' - }); - this.mnuGotoFootNext = new Common.UI.Button({ - el: $('#id-menu-goto-footnote-next'), - cls: 'btn-toolbar' - }); - // set dataviews var _conf = this.mnuMarkersPicker.conf; @@ -2362,7 +2307,6 @@ define([ tipEditHeader: 'Edit Document Header or Footer', mniEditHeader: 'Edit Document Header', mniEditFooter: 'Edit Document Footer', - tipInsertHyperlink: 'Add Hyperlink', mniHiddenChars: 'Nonprinting Characters', mniHiddenBorders: 'Hidden Table Borders', tipSynchronize: 'The document has been changed by another user. Please click to save your changes and reload the updates.', @@ -2453,17 +2397,11 @@ define([ textLandscape: 'Landscape', textInsertPageCount: 'Insert number of pages', textCharts: 'Charts', - tipNotes: 'Footnotes', - mniInsFootnote: 'Insert Footnote', - mniDelFootnote: 'Delete All Footnotes', - mniNoteSettings: 'Notes Settings', - textGotoFootnote: 'Go to Footnotes', tipChangeChart: 'Change Chart Type', capBtnInsPagebreak: 'Page Break', capBtnInsImage: 'Picture', capBtnInsTable: 'Table', capBtnInsChart: 'Chart', - capBtnInsLink: 'Hyperlink', textTabFile: 'File', textTabHome: 'Home', textTabInsert: 'Insert', @@ -2473,7 +2411,6 @@ define([ capBtnInsTextbox: 'Text Box', capBtnInsTextart: 'Text Art', capBtnInsDropcap: 'Drop Cap', - capBtnInsFootnote: 'Footnotes', capBtnInsEquation: 'Equation', capBtnInsHeader: 'Headers/Footers', capBtnColumns: 'Columns', @@ -2495,6 +2432,7 @@ define([ textSurface: 'Surface', textTabCollaboration: 'Collaboration', textTabProtect: 'Protection', + textTabLinks: 'Links', capBtnInsControls: 'Content Control', textRichControl: 'Rich text', textPlainControl: 'Plain text', diff --git a/apps/documenteditor/main/app_dev.js b/apps/documenteditor/main/app_dev.js index 6e444ed4c..9450b3f55 100644 --- a/apps/documenteditor/main/app_dev.js +++ b/apps/documenteditor/main/app_dev.js @@ -140,6 +140,8 @@ require([ 'DocumentHolder', 'Toolbar', 'Statusbar', + 'Links', + 'Navigation', 'RightMenu', 'LeftMenu', 'Main', @@ -163,6 +165,8 @@ require([ 'documenteditor/main/app/controller/Viewport', 'documenteditor/main/app/controller/DocumentHolder', 'documenteditor/main/app/controller/Toolbar', + 'documenteditor/main/app/controller/Links', + 'documenteditor/main/app/controller/Navigation', 'documenteditor/main/app/controller/Statusbar', 'documenteditor/main/app/controller/RightMenu', 'documenteditor/main/app/controller/LeftMenu', diff --git a/apps/documenteditor/main/locale/en.json b/apps/documenteditor/main/locale/en.json index 17bb4acb0..4d2152fc9 100644 --- a/apps/documenteditor/main/locale/en.json +++ b/apps/documenteditor/main/locale/en.json @@ -436,7 +436,7 @@ "DE.Controllers.Statusbar.tipReview": "Track changes", "DE.Controllers.Statusbar.zoomText": "Zoom {0}%", "DE.Controllers.Toolbar.confirmAddFontName": "The font you are going to save is not available on the current device.
The text style will be displayed using one of the system fonts, the saved font will be used when it is available.
Do you want to continue?", - "DE.Controllers.Toolbar.confirmDeleteFootnotes": "Do you want to delete all footnotes?", + "del_DE.Controllers.Toolbar.confirmDeleteFootnotes": "Do you want to delete all footnotes?", "DE.Controllers.Toolbar.notcriticalErrorTitle": "Warning", "DE.Controllers.Toolbar.textAccent": "Accents", "DE.Controllers.Toolbar.textBracket": "Brackets", @@ -1252,6 +1252,23 @@ "DE.Views.LeftMenu.tipTitles": "Titles", "DE.Views.LeftMenu.txtDeveloper": "DEVELOPER MODE", "DE.Views.LeftMenu.txtTrial": "TRIAL MODE", + "DE.Views.Links.capBtnContentsUpdate": "Update", + "DE.Views.Links.capBtnInsContents": "Table of Contents", + "DE.Views.Links.capBtnInsFootnote": "Footnote", + "DE.Views.Links.capBtnInsLink": "Hyperlink", + "DE.Views.Links.confirmDeleteFootnotes": "Do you want to delete all footnotes?", + "DE.Views.Links.mniDelFootnote": "Delete All Footnotes", + "DE.Views.Links.mniInsFootnote": "Insert Footnote", + "DE.Views.Links.mniNoteSettings": "Notes Settings", + "DE.Views.Links.textContentsRemove": "Remove table of contents", + "DE.Views.Links.textContentsSettings": "Settings", + "DE.Views.Links.textGotoFootnote": "Go to Footnotes", + "DE.Views.Links.textUpdateAll": "Update entire table", + "DE.Views.Links.textUpdatePages": "Update page numbers only", + "DE.Views.Links.tipContents": "Insert table of contents", + "DE.Views.Links.tipContentsUpdate": "Update table of contents", + "DE.Views.Links.tipInsertHyperlink": "Add hyperlink", + "DE.Views.Links.tipNotes": "Insert or edit footnotes", "DE.Views.MailMergeEmailDlg.cancelButtonText": "Cancel", "DE.Views.MailMergeEmailDlg.filePlaceholder": "PDF", "DE.Views.MailMergeEmailDlg.okButtonText": "Send", @@ -1643,10 +1660,10 @@ "DE.Views.Toolbar.capBtnInsControls": "Content Controls", "DE.Views.Toolbar.capBtnInsDropcap": "Drop Cap", "DE.Views.Toolbar.capBtnInsEquation": "Equation", - "DE.Views.Toolbar.capBtnInsFootnote": "Footnote", + "del_DE.Views.Toolbar.capBtnInsFootnote": "Footnote", "DE.Views.Toolbar.capBtnInsHeader": "Header/Footer", "DE.Views.Toolbar.capBtnInsImage": "Picture", - "DE.Views.Toolbar.capBtnInsLink": "Hyperlink", + "del_DE.Views.Toolbar.capBtnInsLink": "Hyperlink", "DE.Views.Toolbar.capBtnInsPagebreak": "Breaks", "DE.Views.Toolbar.capBtnInsShape": "Shape", "DE.Views.Toolbar.capBtnInsTable": "Table", @@ -1661,7 +1678,7 @@ "DE.Views.Toolbar.capImgGroup": "Group", "DE.Views.Toolbar.capImgWrapping": "Wrapping", "DE.Views.Toolbar.mniCustomTable": "Insert Custom Table", - "DE.Views.Toolbar.mniDelFootnote": "Delete All Footnotes", + "del_DE.Views.Toolbar.mniDelFootnote": "Delete All Footnotes", "DE.Views.Toolbar.mniEditControls": "Control Settings", "DE.Views.Toolbar.mniEditDropCap": "Drop Cap Settings", "DE.Views.Toolbar.mniEditFooter": "Edit Footer", @@ -1670,8 +1687,8 @@ "DE.Views.Toolbar.mniHiddenChars": "Nonprinting Characters", "DE.Views.Toolbar.mniImageFromFile": "Picture from File", "DE.Views.Toolbar.mniImageFromUrl": "Picture from URL", - "DE.Views.Toolbar.mniInsFootnote": "Insert Footnote", - "DE.Views.Toolbar.mniNoteSettings": "Notes Settings", + "del_DE.Views.Toolbar.mniInsFootnote": "Insert Footnote", + "del_DE.Views.Toolbar.mniNoteSettings": "Notes Settings", "DE.Views.Toolbar.strMenuNoFill": "No Fill", "DE.Views.Toolbar.textArea": "Area", "DE.Views.Toolbar.textAutoColor": "Automatic", @@ -1691,7 +1708,7 @@ "DE.Views.Toolbar.textEvenPage": "Even Page", "DE.Views.Toolbar.textFitPage": "Fit to Page", "DE.Views.Toolbar.textFitWidth": "Fit to Width", - "DE.Views.Toolbar.textGotoFootnote": "Go to Footnotes", + "del_DE.Views.Toolbar.textGotoFootnote": "Go to Footnotes", "DE.Views.Toolbar.textHideLines": "Hide Rulers", "DE.Views.Toolbar.textHideStatusBar": "Hide Status Bar", "DE.Views.Toolbar.textHideTitleBar": "Hide Title Bar", @@ -1777,7 +1794,7 @@ "DE.Views.Toolbar.tipIncPrLeft": "Increase indent", "DE.Views.Toolbar.tipInsertChart": "Insert chart", "DE.Views.Toolbar.tipInsertEquation": "Insert equation", - "DE.Views.Toolbar.tipInsertHyperlink": "Add hyperlink", + "del_DE.Views.Toolbar.tipInsertHyperlink": "Add hyperlink", "DE.Views.Toolbar.tipInsertImage": "Insert picture", "DE.Views.Toolbar.tipInsertNum": "Insert Page Number", "DE.Views.Toolbar.tipInsertShape": "Insert autoshape", @@ -1788,7 +1805,7 @@ "DE.Views.Toolbar.tipMailRecepients": "Mail merge", "DE.Views.Toolbar.tipMarkers": "Bullets", "DE.Views.Toolbar.tipMultilevels": "Multilevel list", - "DE.Views.Toolbar.tipNotes": "Insert or edit footnotes", + "del_DE.Views.Toolbar.tipNotes": "Insert or edit footnotes", "DE.Views.Toolbar.tipNumbers": "Numbering", "DE.Views.Toolbar.tipPageBreak": "Insert page or section break", "DE.Views.Toolbar.tipPageMargins": "Page margins", diff --git a/apps/documenteditor/main/resources/img/toolbar-menu.png b/apps/documenteditor/main/resources/img/toolbar-menu.png index 262b0d758..558dd83d4 100644 Binary files a/apps/documenteditor/main/resources/img/toolbar-menu.png and b/apps/documenteditor/main/resources/img/toolbar-menu.png differ diff --git a/apps/documenteditor/main/resources/img/toolbar-menu@2x.png b/apps/documenteditor/main/resources/img/toolbar-menu@2x.png index d93c424e8..7f29f381c 100644 Binary files a/apps/documenteditor/main/resources/img/toolbar-menu@2x.png and b/apps/documenteditor/main/resources/img/toolbar-menu@2x.png differ diff --git a/apps/documenteditor/main/resources/img/toolbar/contents.png b/apps/documenteditor/main/resources/img/toolbar/contents.png new file mode 100644 index 000000000..83210bd7a Binary files /dev/null and b/apps/documenteditor/main/resources/img/toolbar/contents.png differ diff --git a/apps/documenteditor/main/resources/img/toolbar/contents@2x.png b/apps/documenteditor/main/resources/img/toolbar/contents@2x.png new file mode 100644 index 000000000..e1946694c Binary files /dev/null and b/apps/documenteditor/main/resources/img/toolbar/contents@2x.png differ diff --git a/apps/documenteditor/main/resources/less/advanced-settings.less b/apps/documenteditor/main/resources/less/advanced-settings.less index 5b15b0632..374a3293f 100644 --- a/apps/documenteditor/main/resources/less/advanced-settings.less +++ b/apps/documenteditor/main/resources/less/advanced-settings.less @@ -75,6 +75,36 @@ height:20px; } +.header-styles-tableview { + .list-item > div{ + &:nth-child(1) { + width:160px; + height: 16px; + padding-left:16px; + padding-right: 5px; + + &.checked { + &:before { + content: ''; + width: 16px; + height: 16px; + display: inline-block; + float: left; + margin-left: -18px; + background-position: @menu-check-offset-x @menu-check-offset-y; + } + } + } + + padding-right: 6px; + vertical-align: middle; + display: inline-block; + text-overflow: ellipsis; + overflow: hidden; + white-space: pre; + } +} + diff --git a/apps/documenteditor/main/resources/less/app.less b/apps/documenteditor/main/resources/less/app.less index 4166e8bf3..8d6040fa7 100644 --- a/apps/documenteditor/main/resources/less/app.less +++ b/apps/documenteditor/main/resources/less/app.less @@ -88,6 +88,7 @@ @import "../../../../common/main/resources/less/radiobox.less"; @import "../../../../common/main/resources/less/dataview.less"; @import "../../../../common/main/resources/less/listview.less"; +@import "../../../../common/main/resources/less/treeview.less"; @import "../../../../common/main/resources/less/colorpalette.less"; @import "../../../../common/main/resources/less/theme-colorpalette.less"; @import "../../../../common/main/resources/less/dimension-picker.less"; @@ -127,6 +128,7 @@ @import "filemenu.less"; @import "rightmenu.less"; @import "advanced-settings.less"; +@import "navigation.less"; .font-size-small { .fontsize(@font-size-small); diff --git a/apps/documenteditor/main/resources/less/leftmenu.less b/apps/documenteditor/main/resources/less/leftmenu.less index 1a58d8c97..cfcbbdaee 100644 --- a/apps/documenteditor/main/resources/less/leftmenu.less +++ b/apps/documenteditor/main/resources/less/leftmenu.less @@ -22,6 +22,7 @@ button.notify .btn-menu-comments {background-position: -0*@toolbar-icon-size -60 .button-normal-icon(btn-menu-about, 68, @toolbar-icon-size); .button-normal-icon(btn-menu-support, 70, @toolbar-icon-size); .button-normal-icon(btn-menu-plugin, 77, @toolbar-icon-size); +.button-normal-icon(btn-menu-navigation, 83, @toolbar-icon-size); .tool-menu-btns { width: 40px; diff --git a/apps/documenteditor/main/resources/less/navigation.less b/apps/documenteditor/main/resources/less/navigation.less new file mode 100644 index 000000000..4825ecc32 --- /dev/null +++ b/apps/documenteditor/main/resources/less/navigation.less @@ -0,0 +1,27 @@ +#navigation-box { + position: relative; + width: 100%; + height: 100%; + + #navigation-header { + position: absolute; + height: 38px; + left: 0; + top: 0; + width: 100%; + font-weight: bold; + padding: 10px 12px; + border-bottom: 1px solid @gray-dark; + } + + #navigation-list { + height: 100%; + overflow: hidden; + padding: 8px 0; + font-size: 12px; + + .name.not-header { + font-style: italic; + } + } +} diff --git a/apps/documenteditor/main/resources/less/toolbar.less b/apps/documenteditor/main/resources/less/toolbar.less index 3f3d0b079..b27e7141f 100644 --- a/apps/documenteditor/main/resources/less/toolbar.less +++ b/apps/documenteditor/main/resources/less/toolbar.less @@ -54,6 +54,37 @@ height: 38px; } +a.item-contents { +} + +.btn-contents { + .dropdown-menu { + > li > a.item-contents { + div { + .background-ximage('@{app-image-path}/toolbar/contents.png', '@{app-image-path}/toolbar/contents@2x.png', 246px); + width: 246px; + height: 72px; + + .box-shadow(0 0 0 1px @gray); + + &:hover, + &.selected { + .box-shadow(0 0 0 2px @primary); + } + } + + &:hover, &:focus { + background-color: transparent; + + div { + .box-shadow(0 0 0 2px @primary); + } + } + } + } +} + + .color-schemas-menu { span { &.colors {