From 106afacb6eb57417fc6bbcf334f75eadeca3a113 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Tue, 23 Jan 2018 20:33:59 +0300
Subject: [PATCH 01/41] [common] added nessesary utils

---
 apps/common/main/lib/component/Layout.js |  7 +++++++
 apps/common/main/lib/util/utils.js       | 22 +++++++++++++++++++++-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/apps/common/main/lib/component/Layout.js b/apps/common/main/lib/component/Layout.js
index bb294def8..3eb230841 100644
--- a/apps/common/main/lib/component/Layout.js
+++ b/apps/common/main/lib/component/Layout.js
@@ -185,6 +185,13 @@ define([
             return parseInt(el.css('width'));
         },
 
+        getItem: function (alias) {
+            for (var p in this.panels) {
+                var panel = this.panels[p];
+                if ( panel.alias == alias ) return panel;
+            }
+        },
+
         onSelectStart: function(e) {
             if (e.preventDefault) e.preventDefault();
             return false;
diff --git a/apps/common/main/lib/util/utils.js b/apps/common/main/lib/util/utils.js
index 45d89d50e..e8f9b7263 100644
--- a/apps/common/main/lib/util/utils.js
+++ b/apps/common/main/lib/util/utils.js
@@ -735,4 +735,24 @@ String.prototype.strongMatch = function(regExp){
     }
 
     return false;
-};
\ No newline at end of file
+};
+
+Common.Utils.InternalSettings = new(function() {
+    var settings = {};
+
+    var _get = function(name) {
+            return settings[name];
+        },
+        _set = function(name, value) {
+            settings[name] = value;
+        };
+
+    return {
+        get: _get,
+        set: _set
+    }
+});
+
+Common.Utils.InternalSettings.set('toolbar-height-compact', 32);
+Common.Utils.InternalSettings.set('toolbar-height-normal', 32+67);
+Common.Utils.InternalSettings.set('doc-title-height', 26);
\ No newline at end of file

From 826ac6aef18c9b217c2d876cc5892aca1458ea2a Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Tue, 23 Jan 2018 20:35:16 +0300
Subject: [PATCH 02/41] new design changes

---
 apps/common/main/lib/view/Header.js           |  8 ++++++
 apps/common/main/resources/less/header.less   | 25 ++++++++++++++++++-
 .../main/app/controller/Viewport.js           | 12 +++++++--
 .../main/app/template/Viewport.template       |  3 +++
 apps/documenteditor/main/app/view/Viewport.js | 12 +++++++--
 .../main/resources/less/toolbar.less          |  3 ++-
 .../main/app/controller/Viewport.js           | 10 ++++++--
 .../main/app/template/Viewport.template       |  3 +++
 .../main/app/view/Viewport.js                 | 18 +++++++++----
 .../main/app/controller/Viewport.js           | 12 ++++++---
 .../main/app/template/Viewport.template       |  3 +++
 .../main/app/view/Viewport.js                 | 18 +++++++------
 12 files changed, 104 insertions(+), 23 deletions(-)

diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js
index 42fdf831c..eca408c00 100644
--- a/apps/common/main/lib/view/Header.js
+++ b/apps/common/main/lib/view/Header.js
@@ -414,6 +414,14 @@ define([
                         $html.find('#slot-btn-back').hide();
                         this.labelDocName.hide();
 
+                        //TODO: for new design representation only
+                        this.labelDocName = $('#box-document-title > #title-doc-name');
+                        this.labelDocName.text = function (str) {this.val(str);};
+                        this.labelDocName.text( this.documentCaption );
+
+                        $('.toolbar-fullview-panel').addClass('new-doctitle-offset');
+                        /***********/
+
                         if ( config.isOffline )
                             $saveStatus = false;
                     } else {
diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less
index 67c665f3a..af24cab25 100644
--- a/apps/common/main/resources/less/header.less
+++ b/apps/common/main/resources/less/header.less
@@ -239,4 +239,27 @@
         width: 20px;
         height: 20px;
     }
-}
\ No newline at end of file
+}
+
+#box-document-title {
+    background-color: @tabs-bg-color;
+
+    #title-doc-name {
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        text-align: center;
+        font-size: 12px;
+        width: 100%;
+        height: 100%;
+
+        color: #d3d9e3;
+        background-color: transparent;
+        border: 0 none;
+        cursor: default;
+   }
+}
+
+.toolbar-fullview-panel.new-doctitle-offset {
+    top: @height-tabs + 26;
+}
diff --git a/apps/documenteditor/main/app/controller/Viewport.js b/apps/documenteditor/main/app/controller/Viewport.js
index fe6907548..b34a955f8 100644
--- a/apps/documenteditor/main/app/controller/Viewport.js
+++ b/apps/documenteditor/main/app/controller/Viewport.js
@@ -75,7 +75,8 @@ define([
                         toolbar.setExtra('left', me.header.getPanel('left', config));
                     },
                     'view:compact'  : function (toolbar, state) {
-                        me.viewport.vlayout.panels[0].height = state ? 32 : 32+67;
+                        me.viewport.vlayout.getItem('toolbar').height = state ?
+                                Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
                     }
                 }
             });
@@ -113,11 +114,18 @@ define([
 
         onAppShowed: function (config) {
             var me = this;
+            me.appConfig = config;
 
             if ( !config.isEdit ||
                 ( !Common.localStorage.itemExists("de-compact-toolbar") &&
                 config.customization && config.customization.compactToolbar )) {
-                me.viewport.vlayout.panels[0].height = 32;
+
+                var panel = me.viewport.vlayout.getItem('toolbar');
+                if ( panel ) panel.height = Common.Utils.InternalSettings.get('toolbar-height-compact');
+            }
+
+            if ( config.isDesktopApp ) {
+                me.viewport.vlayout.getItem('doc-title').el.show();
             }
         },
 
diff --git a/apps/documenteditor/main/app/template/Viewport.template b/apps/documenteditor/main/app/template/Viewport.template
index a0d2cb205..2535307dd 100644
--- a/apps/documenteditor/main/app/template/Viewport.template
+++ b/apps/documenteditor/main/app/template/Viewport.template
@@ -1,5 +1,8 @@
 <div class="layout-region">
     <div id="viewport-vbox-layout" class="layout-ct vbox">
+        <section id="box-document-title" class="layout-item">
+            <input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false">
+        </section>
         <section class="layout-ct">
             <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
         </section>
diff --git a/apps/documenteditor/main/app/view/Viewport.js b/apps/documenteditor/main/app/view/Viewport.js
index b4547c48a..8c4b6ba1a 100644
--- a/apps/documenteditor/main/app/view/Viewport.js
+++ b/apps/documenteditor/main/app/view/Viewport.js
@@ -82,10 +82,18 @@ define([
             var $container = $('#viewport-vbox-layout', this.$el);
             this.vlayout = new Common.UI.VBoxLayout({
                 box: $container,
-                items: [{
+                items: [
+                    {
+                        el: $container.find(' > .layout-item#box-document-title').hide(),
+                        alias: 'doc-title',
+                        height: Common.Utils.InternalSettings.get('doc-title-height')
+                    },
+                    {
                         el: $container.find(' > .layout-item#toolbar'),
+                        alias: 'toolbar',
                         // rely: true
-                        height: Common.localStorage.getBool('de-compact-toolbar') ? 32 : 32+67
+                        height: Common.localStorage.getBool('de-compact-toolbar') ?
+                            Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal')
                     }, {
                         el: $container.find(' > .layout-item.middle'),
                         stretch: true
diff --git a/apps/documenteditor/main/resources/less/toolbar.less b/apps/documenteditor/main/resources/less/toolbar.less
index fd84706f4..2b1c918b5 100644
--- a/apps/documenteditor/main/resources/less/toolbar.less
+++ b/apps/documenteditor/main/resources/less/toolbar.less
@@ -1,5 +1,6 @@
 
-@tabs-bg-color: #4f6279;
+//@tabs-bg-color: #4f6279;
+@tabs-bg-color: #446995;
 
 #toolbar {
     //z-index: 101;
diff --git a/apps/presentationeditor/main/app/controller/Viewport.js b/apps/presentationeditor/main/app/controller/Viewport.js
index 9d90c4485..c07ca3bec 100644
--- a/apps/presentationeditor/main/app/controller/Viewport.js
+++ b/apps/presentationeditor/main/app/controller/Viewport.js
@@ -76,7 +76,8 @@ define([
                         toolbar.setExtra('left', me.header.getPanel('left', config));
                     },
                     'view:compact'  : function (toolbar, state) {
-                        me.viewport.vlayout.panels[0].height = state ? 32 : 32+67;
+                        me.viewport.vlayout.getItem('toolbar').height = state ?
+                            Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
                     }
                 },
                 // Events generated by main view
@@ -116,12 +117,17 @@ define([
 
         onAppShowed: function (config) {
             var me = this;
+            me.appConfig = config;
 
             if ( !config.isEdit ||
                 ( !Common.localStorage.itemExists("pe-compact-toolbar") &&
                     config.customization && config.customization.compactToolbar ))
             {
-                me.viewport.vlayout.panels[0].height = 32;
+                me.viewport.vlayout.getItem('toolbar').height = Common.Utils.InternalSettings.get('toolbar-height-compact');
+            }
+
+            if ( config.isDesktopApp ) {
+                me.viewport.vlayout.getItem('doc-title').el.show();
             }
         },
 
diff --git a/apps/presentationeditor/main/app/template/Viewport.template b/apps/presentationeditor/main/app/template/Viewport.template
index 2a5121016..40c80aae5 100644
--- a/apps/presentationeditor/main/app/template/Viewport.template
+++ b/apps/presentationeditor/main/app/template/Viewport.template
@@ -4,6 +4,9 @@
         <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
     </section>
     <div id="viewport-vbox-layout" class="layout-ct vbox">
+        <section id="box-document-title" class="layout-item">
+            <input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false">
+        </section>
         <div id="toolbar" class="layout-item"></div>
         <div class="layout-item middle">
             <div id="viewport-hbox-layout" class="layout-ct hbox">
diff --git a/apps/presentationeditor/main/app/view/Viewport.js b/apps/presentationeditor/main/app/view/Viewport.js
index e1be9b2d2..20de5b753 100644
--- a/apps/presentationeditor/main/app/view/Viewport.js
+++ b/apps/presentationeditor/main/app/view/Viewport.js
@@ -85,14 +85,22 @@ define([
             var items = $container.find(' > .layout-item');
             this.vlayout = new Common.UI.VBoxLayout({
                 box: $container,
-                items: [{
-                    el: items[0],
-                    height: Common.localStorage.getBool('pe-compact-toolbar') ? 32 : 32+67
-                }, {
+                items: [
+                {
+                    el: $container.find(' > .layout-item#box-document-title').hide(),
+                    alias: 'doc-title',
+                    height: Common.Utils.InternalSettings.get('doc-title-height')
+                },
+                {
                     el: items[1],
-                    stretch: true
+                    alias: 'toolbar',
+                    height: Common.localStorage.getBool('pe-compact-toolbar') ?
+                        Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal')
                 }, {
                     el: items[2],
+                    stretch: true
+                }, {
+                    el: items[3],
                     height: 25
                 }]
             });
diff --git a/apps/spreadsheeteditor/main/app/controller/Viewport.js b/apps/spreadsheeteditor/main/app/controller/Viewport.js
index 3d2095fc1..412d34df2 100644
--- a/apps/spreadsheeteditor/main/app/controller/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/controller/Viewport.js
@@ -74,7 +74,8 @@ define([
                         toolbar.setExtra('left', me.header.getPanel('left', config));
                     },
                     'view:compact'  : function (toolbar, state) {
-                        me.viewport.vlayout.panels[0].height = state ? 32 : 32+67;
+                        me.viewport.vlayout.getItem('toolbar').height = state ?
+                            Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
                     }
                 }
             });
@@ -88,15 +89,20 @@ define([
 
         onAppShowed: function (config) {
             var me = this;
+            me.appConfig = config;
 
             if ( !config.isEdit ||
                     ( !Common.localStorage.itemExists("sse-compact-toolbar") &&
                         config.customization && config.customization.compactToolbar ))
             {
-                me.viewport.vlayout.panels[0].height = 32;
+                me.viewport.vlayout.getItem('toolbar').height = Common.Utils.InternalSettings.get('toolbar-height-compact');
             } else
             if ( config.isEditDiagram || config.isEditMailMerge ) {
-                me.viewport.vlayout.panels[0].height = 41;
+                me.viewport.vlayout.getItem('toolbar').height = 41;
+            }
+
+            if ( config.isDesktopApp ) {
+                me.viewport.vlayout.getItem('doc-title').el.show();
             }
         },
 
diff --git a/apps/spreadsheeteditor/main/app/template/Viewport.template b/apps/spreadsheeteditor/main/app/template/Viewport.template
index b6c6b4ce5..17a3911e8 100644
--- a/apps/spreadsheeteditor/main/app/template/Viewport.template
+++ b/apps/spreadsheeteditor/main/app/template/Viewport.template
@@ -1,5 +1,8 @@
 <div class="layout-region">
     <div id="viewport-vbox-layout" class="layout-ct vbox">
+        <section id="box-document-title" class="layout-item">
+            <input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false">
+        </section>
         <section class="layout-ct">
             <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
         </section>
diff --git a/apps/spreadsheeteditor/main/app/view/Viewport.js b/apps/spreadsheeteditor/main/app/view/Viewport.js
index 86c059741..499bd7b9e 100644
--- a/apps/spreadsheeteditor/main/app/view/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/view/Viewport.js
@@ -87,16 +87,20 @@ define([
                 box: $container,
                 items: [
                 {
-                    // el: items[0],    // decorative element for view mode for desktop
-                    // height: 5
-                // }, {
-                    el: items[0],
-                    height: Common.localStorage.getBool('sse-compact-toolbar') ? 32 : 32+67
-                }, {
+                    el: $container.find(' > .layout-item#box-document-title').hide(),
+                    alias: 'doc-title',
+                    height: Common.Utils.InternalSettings.get('doc-title-height')
+                },
+                {
                     el: items[1],
-                    stretch: true
+                    alias: 'toolbar',
+                    height: Common.localStorage.getBool('sse-compact-toolbar') ?
+                        Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal')
                 }, {
                     el: items[2],
+                    stretch: true
+                }, {
+                    el: items[3],
                     height: 25
                 }]
             });

From bb36c63c13221b882602f66b96d3d89890efa810 Mon Sep 17 00:00:00 2001
From: Julia Radzhabova <Julia.Radzhabova@onlyoffice.com>
Date: Wed, 24 Jan 2018 13:57:58 +0300
Subject: [PATCH 03/41] [DE] Added print, save, undo, redo buttons and user
 name to header panel.

---
 apps/api/documents/api.js                     |  2 +-
 apps/common/main/lib/view/Header.js           | 89 ++++++++++++++++---
 .../main/resources/img/header/buttons.svg     | 15 ++++
 apps/common/main/resources/less/header.less   | 48 +++++++++-
 .../main/app/controller/Main.js               |  1 +
 .../main/app/controller/Toolbar.js            |  5 ++
 .../main/app/template/Viewport.template       | 10 ++-
 apps/documenteditor/main/app/view/Toolbar.js  |  7 ++
 8 files changed, 161 insertions(+), 16 deletions(-)

diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js
index 7e18427ef..0299e3a1a 100644
--- a/apps/api/documents/api.js
+++ b/apps/api/documents/api.js
@@ -358,7 +358,7 @@
             if (!!result && result.length) {
                 if (result[1] == 'desktop') {
                     _config.editorConfig.targetApp = result[1];
-                    _config.editorConfig.canBackToFolder = false;
+                    // _config.editorConfig.canBackToFolder = false;
                     _config.editorConfig.canUseHistory = false;
                     if (!_config.editorConfig.customization) _config.editorConfig.customization = {};
                     _config.editorConfig.customization.about = false;
diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js
index eca408c00..780dda4db 100644
--- a/apps/common/main/lib/view/Header.js
+++ b/apps/common/main/lib/view/Header.js
@@ -260,6 +260,34 @@ define([
                 }
             }
 
+            if ( me.btnPrint ) {
+                me.btnPrint.updateHint(me.tipPrint + Common.Utils.String.platformKey('Ctrl+P'));
+                me.btnPrint.on('click', function (e) {
+                    me.fireEvent('print', me);
+                });
+            }
+
+            if ( me.btnSave ) {
+                me.btnSave.updateHint(me.tipSave + Common.Utils.String.platformKey('Ctrl+S'));
+                me.btnSave.on('click', function (e) {
+                    me.fireEvent('save', me);
+                });
+            }
+
+            if ( me.btnUndo ) {
+                me.btnUndo.updateHint(me.tipUndo + Common.Utils.String.platformKey('Ctrl+Z'));
+                me.btnUndo.on('click', function (e) {
+                    me.fireEvent('undo', me);
+                });
+            }
+
+            if ( me.btnRedo ) {
+                me.btnRedo.updateHint(me.tipRedo + Common.Utils.String.platformKey('Ctrl+Y'));
+                me.btnRedo.on('click', function (e) {
+                    me.fireEvent('redo', me);
+                });
+            }
+
             if ( !mode.isEdit ) {
                 if ( me.btnDownload ) {
                     me.btnDownload.updateHint(me.tipDownload);
@@ -268,13 +296,6 @@ define([
                     });
                 }
 
-                if ( me.btnPrint ) {
-                    me.btnPrint.updateHint(me.tipPrint + Common.Utils.String.platformKey('Ctrl+P'));
-                    me.btnPrint.on('click', function (e) {
-                        me.fireEvent('print', me);
-                    });
-                }
-
                 if ( me.btnEdit ) {
                     me.btnEdit.updateHint(me.tipGoEdit);
                     me.btnEdit.on('click', function (e) {
@@ -325,6 +346,7 @@ define([
                 branding: {},
                 headerCaption: 'Default Caption',
                 documentCaption: '',
+                userName: '',
                 canBack: false
             },
 
@@ -344,6 +366,7 @@ define([
 
                 this.headerCaption = this.options.headerCaption;
                 this.documentCaption = this.options.documentCaption;
+                this.userName = this.options.userName;
                 this.canBack = this.options.canBack;
                 this.branding = this.options.customization;
                 this.isModified = false;
@@ -411,7 +434,7 @@ define([
 
                     if ( config && config.isDesktopApp ) {
                         $html.addClass('desktop');
-                        $html.find('#slot-btn-back').hide();
+                        // $html.find('#slot-btn-back').hide();
                         this.labelDocName.hide();
 
                         //TODO: for new design representation only
@@ -419,18 +442,49 @@ define([
                         this.labelDocName.text = function (str) {this.val(str);};
                         this.labelDocName.text( this.documentCaption );
 
+                        this.labelUserName = $('#box-document-title > #title-user-name');
+                        this.labelUserName.text( this.userName );
+
+                        if ( config.canPrint ) {
+                            this.btnPrint = new Common.UI.Button({
+                                cls: 'btn-header',
+                                iconCls: 'svgicon svg-btn-print'
+                            });
+
+                            this.btnPrint.render($('#box-document-title #slot-btn-dt-print'));
+                        }
+
+                        this.btnSave = new Common.UI.Button({
+                            cls: 'btn-header',
+                            iconCls: 'svgicon svg-btn-save'
+                        });
+                        this.btnSave.render($('#box-document-title #slot-btn-dt-save'));
+
+                        this.btnUndo = new Common.UI.Button({
+                            cls: 'btn-header',
+                            iconCls: 'svgicon svg-btn-undo'
+                        });
+                        this.btnUndo.render($('#box-document-title #slot-btn-dt-undo'));
+
+                        this.btnRedo = new Common.UI.Button({
+                            cls: 'btn-header',
+                            iconCls: 'svgicon svg-btn-redo'
+                        });
+                        this.btnRedo.render($('#box-document-title #slot-btn-dt-redo'));
+
                         $('.toolbar-fullview-panel').addClass('new-doctitle-offset');
                         /***********/
 
                         if ( config.isOffline )
                             $saveStatus = false;
-                    } else {
+                    }
+                    // else {
                         if ( this.canBack === true ) {
                             this.btnGoBack.render($html.find('#slot-btn-back'));
                         } else {
                             $html.find('#slot-btn-back').hide();
                         }
-                    }
+                    // }
 
                     if ( !config.isEdit ) {
                         if ( (config.canDownload || config.canDownloadOrigin) && !config.isOffline  ) {
@@ -576,6 +630,16 @@ define([
                 }
             },
 
+            setUserName: function (value) {
+                this.userName = value.fullname;
+                return value;
+            },
+
+            getButton: function(type) {
+                if (type == 'save')
+                    return this.btnSave;
+            },
+
             textBack: 'Go to Documents',
             txtRename: 'Rename',
             textSaveBegin: 'Saving...',
@@ -588,7 +652,10 @@ define([
             tipViewUsers: 'View users and manage document access rights',
             tipDownload: 'Download file',
             tipPrint: 'Print file',
-            tipGoEdit: 'Edit current file'
+            tipGoEdit: 'Edit current file',
+            tipSave: 'Save',
+            tipUndo: 'Undo',
+            tipRedo: 'Redo'
         }
     }(), Common.Views.Header || {}))
 });
diff --git a/apps/common/main/resources/img/header/buttons.svg b/apps/common/main/resources/img/header/buttons.svg
index 28656d8d3..369f84b66 100644
--- a/apps/common/main/resources/img/header/buttons.svg
+++ b/apps/common/main/resources/img/header/buttons.svg
@@ -32,4 +32,19 @@
 	<path d="M15.273,8.598l-2.121-2.121l1.414-1.414c0.391-0.391,1.023-0.391,1.414,0l0.707,0.707
 		c0.391,0.391,0.391,1.023,0,1.414L15.273,8.598z"/>
     </symbol>
+    <symbol id="svg-btn-save" viewBox="0 0 20 20">
+        <polygon points="11.738,7.891 6.434,13.195 5.02,14.859 4.5,17.5 7,17.5 8.555,15.566 13.859,10.137"/>
+	<path d="M15.273,8.598l-2.121-2.121l1.414-1.414c0.391-0.391,1.023-0.391,1.414,0l0.707,0.707
+		c0.391,0.391,0.391,1.023,0,1.414L15.273,8.598z"/>
+    </symbol>
+    <symbol id="svg-btn-undo" viewBox="0 0 20 20">
+        <polygon points="11.738,7.891 6.434,13.195 5.02,14.859 4.5,17.5 7,17.5 8.555,15.566 13.859,10.137"/>
+	<path d="M15.273,8.598l-2.121-2.121l1.414-1.414c0.391-0.391,1.023-0.391,1.414,0l0.707,0.707
+		c0.391,0.391,0.391,1.023,0,1.414L15.273,8.598z"/>
+    </symbol>
+    <symbol id="svg-btn-redo" viewBox="0 0 20 20">
+        <polygon points="11.738,7.891 6.434,13.195 5.02,14.859 4.5,17.5 7,17.5 8.555,15.566 13.859,10.137"/>
+	<path d="M15.273,8.598l-2.121-2.121l1.414-1.414c0.391-0.391,1.023-0.391,1.414,0l0.707,0.707
+		c0.391,0.391,0.391,1.023,0,1.414L15.273,8.598z"/>
+    </symbol>
 </svg>
diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less
index af24cab25..4f2db9623 100644
--- a/apps/common/main/resources/less/header.less
+++ b/apps/common/main/resources/less/header.less
@@ -243,16 +243,62 @@
 
 #box-document-title {
     background-color: @tabs-bg-color;
+    display: flex;
+
+    .btn-slot {
+        display: inline-block;
+    }
+
+    .btn-header {
+        height: 26px;
+        padding: 3px 6px;
+
+        &[disabled],
+        &.disabled {
+            opacity: 0.65;
+        }
+
+        &:hover {
+            &:not(.disabled) {
+                background-color: rgba(255,255,255,0.2);
+            }
+        }
+
+        &:active {
+            &:not(.disabled) {
+                background-color: rgba(0,0,0,0.2);
+            }
+        }
+    }
+
+    svg.icon {
+        fill: #fff;
+    }
 
     #title-doc-name {
+        flex-grow: 1;
         white-space: nowrap;
         text-overflow: ellipsis;
         overflow: hidden;
         text-align: center;
         font-size: 12px;
-        width: 100%;
         height: 100%;
 
+        color: #d3d9e3;
+        background-color: transparent;
+        border: 0 none;
+        cursor: default;
+   }
+    #title-user-name {
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        text-align: right;
+        font-size: 12px;
+        width: 150px;
+        height: 100%;
+        padding: 4px 12px 4px 0;
+
         color: #d3d9e3;
         background-color: transparent;
         border: 0 none;
diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js
index e6ff4095c..ea85aeee7 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -290,6 +290,7 @@ define([
 
                 appHeader = this.getApplication().getController('Viewport').getView('Common.Views.Header');
                 appHeader.setCanBack(this.appOptions.canBackToFolder === true);
+                appHeader.setUserName(this.appOptions.user);
 
                 if (this.editorConfig.lang)
                     this.api.asc_setLocale(this.editorConfig.lang);
diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js
index 5175353b7..fc1ca9983 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -119,6 +119,11 @@ define([
                         var _main = this.getApplication().getController('Main');
                         _main.onPrint();
                     },
+                    'save': function (opts) {
+                        this.api.asc_Save();
+                    },
+                    'undo': this.onUndo,
+                    'redo': this.onRedo,
                     'downloadas': function (opts) {
                         var _main = this.getApplication().getController('Main');
                         var _file_type = _main.document.fileType,
diff --git a/apps/documenteditor/main/app/template/Viewport.template b/apps/documenteditor/main/app/template/Viewport.template
index 2535307dd..1a2830b4a 100644
--- a/apps/documenteditor/main/app/template/Viewport.template
+++ b/apps/documenteditor/main/app/template/Viewport.template
@@ -1,10 +1,14 @@
 <div class="layout-region">
     <div id="viewport-vbox-layout" class="layout-ct vbox">
         <section id="box-document-title" class="layout-item">
+            <div class="hedset">
+                <div class="btn-slot" id="slot-btn-dt-save"></div>
+                <div class="btn-slot" id="slot-btn-dt-print"></div>
+                <div class="btn-slot" id="slot-btn-dt-undo"></div>
+                <div class="btn-slot" id="slot-btn-dt-redo"></div>
+            </div>
             <input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false">
-        </section>
-        <section class="layout-ct">
-            <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
+            <label id="title-user-name"></label>
         </section>
         <div id="toolbar" class="layout-item"></div>
         <div class="layout-item middle">
diff --git a/apps/documenteditor/main/app/view/Toolbar.js b/apps/documenteditor/main/app/view/Toolbar.js
index 7750149ba..66bbf7273 100644
--- a/apps/documenteditor/main/app/view/Toolbar.js
+++ b/apps/documenteditor/main/app/view/Toolbar.js
@@ -2037,6 +2037,13 @@ define([
                     this.toolbarControls.push(btnsave);
                     btnsave.setDisabled(this.btnsSave[0].isDisabled());
                 }
+
+                btnsave = DE.getController('Viewport').getView('Common.Views.Header').getButton('save');
+                if (btnsave && this.btnsSave) {
+                    this.btnsSave.push(btnsave);
+                    this.toolbarControls.push(btnsave);
+                    btnsave.setDisabled(this.btnsSave[0].isDisabled());
+                }
             },
 
             onToolbarAfterRender: function(toolbar) {

From fc6504f5acc675dc2d401f71dcbda964b0205dcd Mon Sep 17 00:00:00 2001
From: Julia Radzhabova <Julia.Radzhabova@onlyoffice.com>
Date: Wed, 24 Jan 2018 14:10:33 +0300
Subject: [PATCH 04/41] [PE][SSE] Added print, save, undo, redo buttons and
 user name to header panel.

---
 apps/presentationeditor/main/app/controller/Main.js |  1 +
 .../main/app/controller/Toolbar.js                  |  5 +++++
 .../main/app/template/Viewport.template             |  7 +++++++
 apps/presentationeditor/main/app/view/Toolbar.js    |  6 ++++++
 apps/spreadsheeteditor/main/app/controller/Main.js  |  1 +
 .../main/app/controller/Toolbar.js                  |  5 +++++
 .../main/app/template/Viewport.template             | 13 ++++++++++---
 apps/spreadsheeteditor/main/app/view/Toolbar.js     |  5 +++++
 8 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js
index 7df2dbad6..766a46523 100644
--- a/apps/presentationeditor/main/app/controller/Main.js
+++ b/apps/presentationeditor/main/app/controller/Main.js
@@ -284,6 +284,7 @@ define([
 
                 appHeader = this.getApplication().getController('Viewport').getView('Common.Views.Header');
                 appHeader.setCanBack(this.appOptions.canBackToFolder === true);
+                appHeader.setUserName(this.appOptions.user);
 
                 if (this.editorConfig.lang)
                     this.api.asc_setLocale(this.editorConfig.lang);
diff --git a/apps/presentationeditor/main/app/controller/Toolbar.js b/apps/presentationeditor/main/app/controller/Toolbar.js
index 96c767fd0..9f6e10f44 100644
--- a/apps/presentationeditor/main/app/controller/Toolbar.js
+++ b/apps/presentationeditor/main/app/controller/Toolbar.js
@@ -132,6 +132,11 @@ define([
                         var _main = this.getApplication().getController('Main');
                         _main.onPrint();
                     },
+                    'save': function (opts) {
+                        this.api.asc_Save();
+                    },
+                    'undo': this.onUndo,
+                    'redo': this.onRedo,
                     'downloadas': function (opts) {
                         var _main = this.getApplication().getController('Main');
                         var _file_type = _main.document.fileType,
diff --git a/apps/presentationeditor/main/app/template/Viewport.template b/apps/presentationeditor/main/app/template/Viewport.template
index 40c80aae5..faff999e6 100644
--- a/apps/presentationeditor/main/app/template/Viewport.template
+++ b/apps/presentationeditor/main/app/template/Viewport.template
@@ -5,7 +5,14 @@
     </section>
     <div id="viewport-vbox-layout" class="layout-ct vbox">
         <section id="box-document-title" class="layout-item">
+            <div class="hedset">
+                <div class="btn-slot" id="slot-btn-dt-save"></div>
+                <div class="btn-slot" id="slot-btn-dt-print"></div>
+                <div class="btn-slot" id="slot-btn-dt-undo"></div>
+                <div class="btn-slot" id="slot-btn-dt-redo"></div>
+            </div>
             <input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false">
+            <label id="title-user-name"></label>
         </section>
         <div id="toolbar" class="layout-item"></div>
         <div class="layout-item middle">
diff --git a/apps/presentationeditor/main/app/view/Toolbar.js b/apps/presentationeditor/main/app/view/Toolbar.js
index d2c80229a..c2778d251 100644
--- a/apps/presentationeditor/main/app/view/Toolbar.js
+++ b/apps/presentationeditor/main/app/view/Toolbar.js
@@ -1411,6 +1411,12 @@ define([
                     this.lockControls.push(btnsave);
                     btnsave.setDisabled(this.btnsSave[0].isDisabled());
                 }
+                btnsave = PE.getController('Viewport').getView('Common.Views.Header').getButton('save');
+                if (btnsave && this.btnsSave) {
+                    this.btnsSave.push(btnsave);
+                    this.lockControls.push(btnsave);
+                    btnsave.setDisabled(this.btnsSave[0].isDisabled());
+                }
 
                 /** coauthoring begin **/
                 this.showSynchTip = !Common.localStorage.getBool('pe-hide-synch');
diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js
index 3c2c2ec8a..3b5f02e14 100644
--- a/apps/spreadsheeteditor/main/app/controller/Main.js
+++ b/apps/spreadsheeteditor/main/app/controller/Main.js
@@ -305,6 +305,7 @@ define([
 
                 this.headerView = this.getApplication().getController('Viewport').getView('Common.Views.Header');
                 this.headerView.setCanBack(this.appOptions.canBackToFolder === true);
+                this.headerView.setUserName(this.appOptions.user);
 
                 var value = Common.localStorage.getItem("sse-settings-reg-settings");
                 if (value!==null)
diff --git a/apps/spreadsheeteditor/main/app/controller/Toolbar.js b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
index 947e2db9d..a55351eb3 100644
--- a/apps/spreadsheeteditor/main/app/controller/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
@@ -83,6 +83,11 @@ define([
                         var _main = this.getApplication().getController('Main');
                         _main.onPrint();
                     },
+                    'save': function (opts) {
+                        this.api.asc_Save();
+                    },
+                    'undo': this.onUndo,
+                    'redo': this.onRedo,
                     'downloadas': function (opts) {
                         var _main = this.getApplication().getController('Main');
                         var _file_type = _main.appOptions.spreadsheet.fileType,
diff --git a/apps/spreadsheeteditor/main/app/template/Viewport.template b/apps/spreadsheeteditor/main/app/template/Viewport.template
index 17a3911e8..2f7e2e59b 100644
--- a/apps/spreadsheeteditor/main/app/template/Viewport.template
+++ b/apps/spreadsheeteditor/main/app/template/Viewport.template
@@ -1,11 +1,18 @@
 <div class="layout-region">
     <div id="viewport-vbox-layout" class="layout-ct vbox">
-        <section id="box-document-title" class="layout-item">
-            <input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false">
-        </section>
         <section class="layout-ct">
             <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
         </section>
+        <section id="box-document-title" class="layout-item">
+            <div class="hedset">
+                <div class="btn-slot" id="slot-btn-dt-save"></div>
+                <div class="btn-slot" id="slot-btn-dt-print"></div>
+                <div class="btn-slot" id="slot-btn-dt-undo"></div>
+                <div class="btn-slot" id="slot-btn-dt-redo"></div>
+            </div>
+            <input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false">
+            <label id="title-user-name"></label>
+        </section>
         <div id="toolbar" class="layout-item"></div>
         <div class="layout-item">
             <div id="viewport-hbox-layout" class="layout-ct hbox">
diff --git a/apps/spreadsheeteditor/main/app/view/Toolbar.js b/apps/spreadsheeteditor/main/app/view/Toolbar.js
index ee92da09a..751c842b1 100644
--- a/apps/spreadsheeteditor/main/app/view/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/view/Toolbar.js
@@ -1723,6 +1723,11 @@ define([
                 this.btnsSave.push(btnsave);
                 btnsave.setDisabled(this.btnsSave[0].isDisabled());
             }
+            btnsave = SSE.getController('Viewport').getView('Common.Views.Header').getButton('save');
+            if (btnsave && this.btnsSave) {
+                this.btnsSave.push(btnsave);
+                btnsave.setDisabled(this.btnsSave[0].isDisabled());
+            }
         },
 
         onToolbarAfterRender: function(toolbar) {

From 1cdc4f1e6dd403ed3459eadcf72ff7d91ad8686e Mon Sep 17 00:00:00 2001
From: Julia Radzhabova <Julia.Radzhabova@onlyoffice.com>
Date: Wed, 24 Jan 2018 17:31:47 +0300
Subject: [PATCH 05/41] [DE] Fix bug with file menu.

---
 apps/documenteditor/main/app/template/Viewport.template | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/apps/documenteditor/main/app/template/Viewport.template b/apps/documenteditor/main/app/template/Viewport.template
index 1a2830b4a..d0c9b55e8 100644
--- a/apps/documenteditor/main/app/template/Viewport.template
+++ b/apps/documenteditor/main/app/template/Viewport.template
@@ -1,5 +1,8 @@
 <div class="layout-region">
     <div id="viewport-vbox-layout" class="layout-ct vbox">
+        <section class="layout-ct">
+            <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
+        </section>
         <section id="box-document-title" class="layout-item">
             <div class="hedset">
                 <div class="btn-slot" id="slot-btn-dt-save"></div>

From 26eae05fa79e8848f13185de06c093b023b3c646 Mon Sep 17 00:00:00 2001
From: Julia Radzhabova <Julia.Radzhabova@onlyoffice.com>
Date: Wed, 24 Jan 2018 17:35:28 +0300
Subject: [PATCH 06/41] Update icons in header.

---
 .../main/resources/img/header/buttons.svg       | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/apps/common/main/resources/img/header/buttons.svg b/apps/common/main/resources/img/header/buttons.svg
index 369f84b66..7ee0aa6aa 100644
--- a/apps/common/main/resources/img/header/buttons.svg
+++ b/apps/common/main/resources/img/header/buttons.svg
@@ -33,18 +33,17 @@
 		c0.391,0.391,0.391,1.023,0,1.414L15.273,8.598z"/>
     </symbol>
     <symbol id="svg-btn-save" viewBox="0 0 20 20">
-        <polygon points="11.738,7.891 6.434,13.195 5.02,14.859 4.5,17.5 7,17.5 8.555,15.566 13.859,10.137"/>
-	<path d="M15.273,8.598l-2.121-2.121l1.414-1.414c0.391-0.391,1.023-0.391,1.414,0l0.707,0.707
-		c0.391,0.391,0.391,1.023,0,1.414L15.273,8.598z"/>
+        <rect x="7" y="13" width="6" height="1"/>
+	    <rect x="7" y="11" width="6" height="1"/>
+	    <path fill="#FFFFFF" d="M13,4H5C4.447,4,4,4.447,4,5v10c0,0.553,0.447,1,1,1h10c0.553,0,1-0.447,1-1V7L13,4z M11,5v2h-1V5H11z
+		 M15,15H5V5h2v3h5V5h0.5L15,7.5V15z"/>
     </symbol>
     <symbol id="svg-btn-undo" viewBox="0 0 20 20">
-        <polygon points="11.738,7.891 6.434,13.195 5.02,14.859 4.5,17.5 7,17.5 8.555,15.566 13.859,10.137"/>
-	<path d="M15.273,8.598l-2.121-2.121l1.414-1.414c0.391-0.391,1.023-0.391,1.414,0l0.707,0.707
-		c0.391,0.391,0.391,1.023,0,1.414L15.273,8.598z"/>
+        <path d="M11.355,7.625c-1.965,0-3.864,0.777-5.151,2.033L4,7.625V14h6.407l-2.091-2.219
+		c0.845-1.277,2.313-2.215,3.99-2.215c2.461,0,5.405,1.78,5.694,4.119C17.601,10.291,14.966,7.625,11.355,7.625z"/>
     </symbol>
     <symbol id="svg-btn-redo" viewBox="0 0 20 20">
-        <polygon points="11.738,7.891 6.434,13.195 5.02,14.859 4.5,17.5 7,17.5 8.555,15.566 13.859,10.137"/>
-	<path d="M15.273,8.598l-2.121-2.121l1.414-1.414c0.391-0.391,1.023-0.391,1.414,0l0.707,0.707
-		c0.391,0.391,0.391,1.023,0,1.414L15.273,8.598z"/>
+    	<path d="M10.645,7.625c1.965,0,3.863,0.777,5.15,2.033L18,7.625V14h-6.406l2.09-2.219
+		c-0.845-1.277-2.313-2.215-3.989-2.215c-2.461,0-5.405,1.78-5.694,4.119C4.399,10.291,7.034,7.625,10.645,7.625z"/>
     </symbol>
 </svg>

From c5da1082bb19bbba20465b695046b780334d6dfa Mon Sep 17 00:00:00 2001
From: maxkadushkin <maxim.kadushkin@onlyoffice.com>
Date: Thu, 25 Jan 2018 11:22:47 +0300
Subject: [PATCH 07/41] set button "back to documents" visible

---
 apps/api/documents/index.html.desktop | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/apps/api/documents/index.html.desktop b/apps/api/documents/index.html.desktop
index 454ad8a28..3b6a293bd 100644
--- a/apps/api/documents/index.html.desktop
+++ b/apps/api/documents/index.html.desktop
@@ -91,6 +91,9 @@
 
             function getEditorConfig(urlParams) {
                 return {
+                    customization   : {
+                        goback: { url:"https://onlyoffice.com" }
+                    },
                     mode            : urlParams["mode"] || 'edit',
                     lang            : urlParams["lang"] || 'en',
                     user: {

From f328e83a4f1010fcc11d76617f11abd835f2a953 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Sat, 3 Feb 2018 16:10:38 +0300
Subject: [PATCH 08/41] refactoring

---
 apps/common/main/lib/view/Header.js           | 184 ++++++++----------
 apps/common/main/resources/less/header.less   |   5 -
 .../main/app/controller/Main.js               |   4 +-
 .../main/app/controller/Viewport.js           |   7 +-
 .../main/app/template/Viewport.template       |  11 +-
 apps/documenteditor/main/app/view/Viewport.js |   4 +-
 .../main/app/controller/Main.js               |   4 +-
 .../main/app/controller/Viewport.js           |   7 +-
 .../main/app/template/Viewport.template       |  11 +-
 .../main/app/view/Viewport.js                 |   4 +-
 .../main/app/controller/Main.js               |   4 +-
 .../main/app/controller/Viewport.js           |   7 +-
 .../main/app/template/Viewport.template       |  11 +-
 .../main/app/view/Viewport.js                 |   4 +-
 14 files changed, 108 insertions(+), 159 deletions(-)

diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js
index 3f94ab154..f19778d6f 100644
--- a/apps/common/main/lib/view/Header.js
+++ b/apps/common/main/lib/view/Header.js
@@ -71,7 +71,7 @@ define([
 
         var templateRightBox = '<section>' +
                             '<section id="box-doc-name">' +
-                                '<input type="text" id="rib-doc-name" spellcheck="false" data-can-copy="false"></input>' +
+                                '<input type="text" id="rib-doc-name" spellcheck="false" data-can-copy="false" style="pointer-events: none;">' +
                             '</section>' +
                             '<a id="rib-save-status" class="status-label locked"><%= textSaveEnd %></a>' +
                             '<div class="hedset">' +
@@ -102,6 +102,17 @@ define([
                                 '<div id="header-logo"><i /></div>' +
                             '</section>';
 
+        var templateTitleBox = '<section id="box-document-title">' +
+                                '<div class="hedset">' +
+                                    '<div class="btn-slot" id="slot-btn-dt-save"></div>' +
+                                    '<div class="btn-slot" id="slot-btn-dt-print"></div>' +
+                                    '<div class="btn-slot" id="slot-btn-dt-undo"></div>' +
+                                    '<div class="btn-slot" id="slot-btn-dt-redo"></div>' +
+                                '</div>' +
+                                '<input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false" style="pointer-events: none;">' +
+                                '<label id="title-user-name" style="pointer-events: none;"></label>' +
+                            '</section>';
+
         function onAddUser(model, collection, opts) {
             if ( $userList ) {
                 var $ul = $userList.find('ul');
@@ -346,9 +357,7 @@ define([
         return {
             options: {
                 branding: {},
-                headerCaption: 'Default Caption',
                 documentCaption: '',
-                userName: '',
                 canBack: false
             },
 
@@ -366,10 +375,7 @@ define([
                 var me = this;
                 this.options = this.options ? _({}).extend(this.options, options) : options;
 
-                this.headerCaption = this.options.headerCaption;
                 this.documentCaption = this.options.documentCaption;
-                this.userName = this.options.userName;
-                this.canBack = this.options.canBack;
                 this.branding = this.options.customization;
                 this.isModified = false;
 
@@ -399,6 +405,15 @@ define([
             },
 
             getPanel: function (role, config) {
+                var me = this;
+
+                function createTitleButton(iconid, slot) {
+                    return (new Common.UI.Button({
+                        cls: 'btn-header',
+                        iconCls: 'svgicon ' + iconid
+                    })).render(slot);
+                }
+
                 if ( role == 'left' && (!config || !config.isDesktopApp)) {
                     $html = $(templateLeftBox);
                     this.logo = $html.find('#header-logo');
@@ -417,103 +432,41 @@ define([
                         textSaveEnd: this.textSaveEnd
                     }));
 
-                    if ( this.labelDocName ) this.labelDocName.off();
-                    this.labelDocName = $html.find('#rib-doc-name');
-                    // this.labelDocName.attr('maxlength', 50);
-                    this.labelDocName.text = function (text) {
-                        this.val(text).attr('size', text.length);
-                    }
+                    if ( !me.labelDocName ) {
+                        me.labelDocName = $html.find('#rib-doc-name');
+                        // this.labelDocName.attr('maxlength', 50);
+                        me.labelDocName.text = function (text) {
+                            this.val(text).attr('size', text.length);
+                        }
 
-                    if ( this.documentCaption ) {
-                        this.labelDocName.text( this.documentCaption );
+                        if ( me.documentCaption ) {
+                            me.labelDocName.text(me.documentCaption);
+                        }
                     }
 
                     if ( !_.isUndefined(this.options.canRename) ) {
                         this.setCanRename(this.options.canRename);
                     }
 
-                    $saveStatus = $html.find('#rib-save-status');
-                    $saveStatus.hide();
+                    // $saveStatus = $html.find('#rib-save-status');
+                    $html.find('#rib-save-status').hide();
+                    // if ( config.isOffline ) $saveStatus = false;
 
-                    if ( config && config.isDesktopApp ) {
-                        $html.addClass('desktop');
-                        // $html.find('#slot-btn-back').hide();
-                        this.labelDocName.hide();
-
-                        //TODO: for new design representation only
-                        this.labelDocName = $('#box-document-title > #title-doc-name');
-                        this.labelDocName.text = function (str) {this.val(str);};
-                        this.labelDocName.text( this.documentCaption );
-
-                        this.labelUserName = $('#box-document-title > #title-user-name');
-                        this.labelUserName.text( this.userName );
-
-                        if ( config.canPrint ) {
-                            this.btnPrint = new Common.UI.Button({
-                                cls: 'btn-header',
-                                iconCls: 'svgicon svg-btn-print'
-                            });
-
-                            this.btnPrint.render($('#box-document-title #slot-btn-dt-print'));
-                        }
-
-                        this.btnSave = new Common.UI.Button({
-                            cls: 'btn-header',
-                            iconCls: 'svgicon svg-btn-save'
-                        });
-                        this.btnSave.render($('#box-document-title #slot-btn-dt-save'));
-
-                        this.btnUndo = new Common.UI.Button({
-                            cls: 'btn-header',
-                            iconCls: 'svgicon svg-btn-undo'
-                        });
-                        this.btnUndo.render($('#box-document-title #slot-btn-dt-undo'));
-
-                        this.btnRedo = new Common.UI.Button({
-                            cls: 'btn-header',
-                            iconCls: 'svgicon svg-btn-redo'
-                        });
-                        this.btnRedo.render($('#box-document-title #slot-btn-dt-redo'));
-
-                        $('.toolbar-fullview-panel').addClass('new-doctitle-offset');
-                        /***********/
-
-                        if ( config.isOffline )
-                            $saveStatus = false;
+                    if ( this.options.canBack === true ) {
+                        me.btnGoBack.render($html.find('#slot-btn-back'));
+                    } else {
+                        $html.find('#slot-btn-back').hide();
                     }
-                    // else {
-                        if ( this.canBack === true ) {
-                            this.btnGoBack.render($html.find('#slot-btn-back'));
-                        } else {
-                            $html.find('#slot-btn-back').hide();
-                        }
-                    // }
 
                     if ( !config.isEdit ) {
-                        if ( (config.canDownload || config.canDownloadOrigin) && !config.isOffline  ) {
-                            this.btnDownload = new Common.UI.Button({
-                                cls: 'btn-header',
-                                iconCls: 'svgicon svg-btn-download'
-                            });
+                        if ( (config.canDownload || config.canDownloadOrigin) && !config.isOffline  )
+                            this.btnDownload = createTitleButton('svg-btn-download', $html.find('#slot-hbtn-download'));
 
-                            this.btnDownload.render($html.find('#slot-hbtn-download'));
-                        }
+                        if ( config.canPrint )
+                            this.btnPrint = createTitleButton('svg-btn-print', $html.find('#slot-hbtn-print'));
 
-                        if ( config.canPrint ) {
-                            this.btnPrint = new Common.UI.Button({
-                                cls: 'btn-header',
-                                iconCls: 'svgicon svg-btn-print'
-                            });
-
-                            this.btnPrint.render($html.find('#slot-hbtn-print'));
-                        }
-
-                        if ( config.canEdit && config.canRequestEditRights ) {
-                            (this.btnEdit = new Common.UI.Button({
-                                cls: 'btn-header',
-                                iconCls: 'svgicon svg-btn-edit'
-                            })).render($html.find('#slot-hbtn-edit'));
-                        }
+                        if ( config.canEdit && config.canRequestEditRights )
+                            this.btnEdit = createTitleButton('svg-btn-edit', $html.find('#slot-hbtn-edit'));
                     }
 
                     $userList = $html.find('.cousers-list');
@@ -522,6 +475,27 @@ define([
 
                     $panelUsers.hide();
 
+                    return $html;
+                } else
+                if ( role == 'title' ) {
+                    var $html = $(_.template(templateTitleBox)());
+
+                    !!me.labelDocName && me.labelDocName.hide().off();                  // hide document title if it was created in right box
+                    me.labelDocName = $html.find('> #title-doc-name');
+                    me.labelDocName.text = function (str) {this.val(str);};             // redefine text function to lock temporaly rename docuemnt option
+                    me.labelDocName.text( me.documentCaption );
+
+                    me.labelUserName = $('> #title-user-name', $html);
+                    me.setUserName(me.options.userName);
+
+                    if ( config.canPrint && config.isEdit ) {
+                        me.btnPrint = createTitleButton('svg-btn-print', $('#slot-btn-dt-print', $html));
+                    }
+
+                    me.btnSave = createTitleButton('svg-btn-save', $('#slot-btn-dt-save', $html));
+                    me.btnUndo = createTitleButton('svg-btn-undo', $('#slot-btn-dt-undo', $html));
+                    me.btnRedo = createTitleButton('svg-btn-redo', $('#slot-btn-dt-redo', $html));
+
                     return $html;
                 }
             },
@@ -546,16 +520,6 @@ define([
                 }
             },
 
-            setHeaderCaption: function (value) {
-                this.headerCaption = value;
-
-                return value;
-            },
-
-            getHeaderCaption: function () {
-                return this.headerCaption;
-            },
-
             setDocumentCaption: function(value) {
                 !value && (value = '');
 
@@ -585,13 +549,14 @@ define([
             },
 
             setCanBack: function (value) {
-                this.canBack = value;
-
+                this.options.canBack = value;
                 this.btnGoBack[value ? 'show' : 'hide']();
+
+                return this;
             },
 
             getCanBack: function () {
-                return this.canBack;
+                return this.options.canBack;
             },
 
             setCanRename: function (rename) {
@@ -642,9 +607,16 @@ define([
                 }
             },
 
-            setUserName: function (value) {
-                this.userName = value.fullname;
-                return value;
+            setUserName: function(name) {
+                if ( !!this.labelUserName ) {
+                    if ( !!name ) {
+                        this.labelUserName.text(name).show();
+                    } else this.labelUserName.hide();
+                } else {
+                    this.options.userName = name;
+                }
+
+                return this;
             },
 
             getButton: function(type) {
diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less
index 943f95fb9..ae854c85d 100644
--- a/apps/common/main/resources/less/header.less
+++ b/apps/common/main/resources/less/header.less
@@ -53,11 +53,6 @@
     &.right {
         flex-grow: 1;
         min-width: 100px;
-
-        .desktop {
-            padding: 10px 0;
-            text-align: right;
-        }
     }
 
     .status-label {
diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js
index 707d43910..173cce5c6 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -306,8 +306,8 @@ define([
                 this.plugins                    = this.editorConfig.plugins;
 
                 appHeader = this.getApplication().getController('Viewport').getView('Common.Views.Header');
-                appHeader.setCanBack(this.appOptions.canBackToFolder === true);
-                appHeader.setUserName(this.appOptions.user);
+                appHeader.setCanBack(this.appOptions.canBackToFolder === true)
+                            .setUserName(this.appOptions.user.fullname);
 
                 if (this.editorConfig.lang)
                     this.api.asc_setLocale(this.editorConfig.lang);
diff --git a/apps/documenteditor/main/app/controller/Viewport.js b/apps/documenteditor/main/app/controller/Viewport.js
index b34a955f8..ad5398e82 100644
--- a/apps/documenteditor/main/app/controller/Viewport.js
+++ b/apps/documenteditor/main/app/controller/Viewport.js
@@ -124,8 +124,11 @@ define([
                 if ( panel ) panel.height = Common.Utils.InternalSettings.get('toolbar-height-compact');
             }
 
-            if ( config.isDesktopApp ) {
-                me.viewport.vlayout.getItem('doc-title').el.show();
+            if ( config.isDesktopApp && config.isEdit ) {
+                var $title = me.viewport.vlayout.getItem('title').el;
+                $title.html(me.header.getPanel('title', config)).show();
+
+                $('.toolbar-fullview-panel').addClass('new-doctitle-offset');
             }
         },
 
diff --git a/apps/documenteditor/main/app/template/Viewport.template b/apps/documenteditor/main/app/template/Viewport.template
index d0c9b55e8..7b9070236 100644
--- a/apps/documenteditor/main/app/template/Viewport.template
+++ b/apps/documenteditor/main/app/template/Viewport.template
@@ -3,16 +3,7 @@
         <section class="layout-ct">
             <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
         </section>
-        <section id="box-document-title" class="layout-item">
-            <div class="hedset">
-                <div class="btn-slot" id="slot-btn-dt-save"></div>
-                <div class="btn-slot" id="slot-btn-dt-print"></div>
-                <div class="btn-slot" id="slot-btn-dt-undo"></div>
-                <div class="btn-slot" id="slot-btn-dt-redo"></div>
-            </div>
-            <input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false">
-            <label id="title-user-name"></label>
-        </section>
+        <section id="title" class="layout-item"></section>
         <div id="toolbar" class="layout-item"></div>
         <div class="layout-item middle">
             <div id="viewport-hbox-layout" class="layout-ct hbox">
diff --git a/apps/documenteditor/main/app/view/Viewport.js b/apps/documenteditor/main/app/view/Viewport.js
index 8c4b6ba1a..061d4771e 100644
--- a/apps/documenteditor/main/app/view/Viewport.js
+++ b/apps/documenteditor/main/app/view/Viewport.js
@@ -84,8 +84,8 @@ define([
                 box: $container,
                 items: [
                     {
-                        el: $container.find(' > .layout-item#box-document-title').hide(),
-                        alias: 'doc-title',
+                        el: $container.find('> .layout-item#title').hide(),
+                        alias: 'title',
                         height: Common.Utils.InternalSettings.get('doc-title-height')
                     },
                     {
diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js
index 0f41bddf4..c1c12a7f6 100644
--- a/apps/presentationeditor/main/app/controller/Main.js
+++ b/apps/presentationeditor/main/app/controller/Main.js
@@ -287,8 +287,8 @@ define([
                 this.plugins                    = this.editorConfig.plugins;
 
                 appHeader = this.getApplication().getController('Viewport').getView('Common.Views.Header');
-                appHeader.setCanBack(this.appOptions.canBackToFolder === true);
-                appHeader.setUserName(this.appOptions.user);
+                appHeader.setCanBack(this.appOptions.canBackToFolder === true)
+                            .setUserName(this.appOptions.user.fullname);
 
                 if (this.editorConfig.lang)
                     this.api.asc_setLocale(this.editorConfig.lang);
diff --git a/apps/presentationeditor/main/app/controller/Viewport.js b/apps/presentationeditor/main/app/controller/Viewport.js
index c07ca3bec..5a3b09f68 100644
--- a/apps/presentationeditor/main/app/controller/Viewport.js
+++ b/apps/presentationeditor/main/app/controller/Viewport.js
@@ -126,8 +126,11 @@ define([
                 me.viewport.vlayout.getItem('toolbar').height = Common.Utils.InternalSettings.get('toolbar-height-compact');
             }
 
-            if ( config.isDesktopApp ) {
-                me.viewport.vlayout.getItem('doc-title').el.show();
+            if ( config.isDesktopApp && config.isEdit ) {
+                var $title = me.viewport.vlayout.getItem('title').el;
+                $title.html(me.header.getPanel('title', config)).show();
+
+                $('.toolbar-fullview-panel').addClass('new-doctitle-offset');
             }
         },
 
diff --git a/apps/presentationeditor/main/app/template/Viewport.template b/apps/presentationeditor/main/app/template/Viewport.template
index faff999e6..064d0a777 100644
--- a/apps/presentationeditor/main/app/template/Viewport.template
+++ b/apps/presentationeditor/main/app/template/Viewport.template
@@ -4,16 +4,7 @@
         <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
     </section>
     <div id="viewport-vbox-layout" class="layout-ct vbox">
-        <section id="box-document-title" class="layout-item">
-            <div class="hedset">
-                <div class="btn-slot" id="slot-btn-dt-save"></div>
-                <div class="btn-slot" id="slot-btn-dt-print"></div>
-                <div class="btn-slot" id="slot-btn-dt-undo"></div>
-                <div class="btn-slot" id="slot-btn-dt-redo"></div>
-            </div>
-            <input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false">
-            <label id="title-user-name"></label>
-        </section>
+        <section id="title" class="layout-item"></section>
         <div id="toolbar" class="layout-item"></div>
         <div class="layout-item middle">
             <div id="viewport-hbox-layout" class="layout-ct hbox">
diff --git a/apps/presentationeditor/main/app/view/Viewport.js b/apps/presentationeditor/main/app/view/Viewport.js
index 20de5b753..521065fb7 100644
--- a/apps/presentationeditor/main/app/view/Viewport.js
+++ b/apps/presentationeditor/main/app/view/Viewport.js
@@ -87,8 +87,8 @@ define([
                 box: $container,
                 items: [
                 {
-                    el: $container.find(' > .layout-item#box-document-title').hide(),
-                    alias: 'doc-title',
+                    el: $container.find('> .layout-item#title').hide(),
+                    alias: 'title',
                     height: Common.Utils.InternalSettings.get('doc-title-height')
                 },
                 {
diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js
index 96ac05d7f..299461f04 100644
--- a/apps/spreadsheeteditor/main/app/controller/Main.js
+++ b/apps/spreadsheeteditor/main/app/controller/Main.js
@@ -309,8 +309,8 @@ define([
                 this.plugins                    = this.editorConfig.plugins;
 
                 this.headerView = this.getApplication().getController('Viewport').getView('Common.Views.Header');
-                this.headerView.setCanBack(this.appOptions.canBackToFolder === true);
-                this.headerView.setUserName(this.appOptions.user);
+                this.headerView.setCanBack(this.appOptions.canBackToFolder === true)
+                                .setUserName(this.appOptions.user.fullname);
 
                 var value = Common.localStorage.getItem("sse-settings-reg-settings");
                 if (value!==null)
diff --git a/apps/spreadsheeteditor/main/app/controller/Viewport.js b/apps/spreadsheeteditor/main/app/controller/Viewport.js
index 412d34df2..e6f334054 100644
--- a/apps/spreadsheeteditor/main/app/controller/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/controller/Viewport.js
@@ -101,8 +101,11 @@ define([
                 me.viewport.vlayout.getItem('toolbar').height = 41;
             }
 
-            if ( config.isDesktopApp ) {
-                me.viewport.vlayout.getItem('doc-title').el.show();
+            if ( config.isDesktopApp && config.isEdit ) {
+                var $title = me.viewport.vlayout.getItem('title').el;
+                $title.html(me.header.getPanel('title', config)).show();
+
+                $('.toolbar-fullview-panel').addClass('new-doctitle-offset');
             }
         },
 
diff --git a/apps/spreadsheeteditor/main/app/template/Viewport.template b/apps/spreadsheeteditor/main/app/template/Viewport.template
index 2f7e2e59b..90a065c83 100644
--- a/apps/spreadsheeteditor/main/app/template/Viewport.template
+++ b/apps/spreadsheeteditor/main/app/template/Viewport.template
@@ -3,16 +3,7 @@
         <section class="layout-ct">
             <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
         </section>
-        <section id="box-document-title" class="layout-item">
-            <div class="hedset">
-                <div class="btn-slot" id="slot-btn-dt-save"></div>
-                <div class="btn-slot" id="slot-btn-dt-print"></div>
-                <div class="btn-slot" id="slot-btn-dt-undo"></div>
-                <div class="btn-slot" id="slot-btn-dt-redo"></div>
-            </div>
-            <input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false">
-            <label id="title-user-name"></label>
-        </section>
+        <section id="title" class="layout-item"></section>
         <div id="toolbar" class="layout-item"></div>
         <div class="layout-item">
             <div id="viewport-hbox-layout" class="layout-ct hbox">
diff --git a/apps/spreadsheeteditor/main/app/view/Viewport.js b/apps/spreadsheeteditor/main/app/view/Viewport.js
index 499bd7b9e..70f2e5c3d 100644
--- a/apps/spreadsheeteditor/main/app/view/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/view/Viewport.js
@@ -87,8 +87,8 @@ define([
                 box: $container,
                 items: [
                 {
-                    el: $container.find(' > .layout-item#box-document-title').hide(),
-                    alias: 'doc-title',
+                    el: $container.find('> .layout-item#title').hide(),
+                    alias: 'title',
                     height: Common.Utils.InternalSettings.get('doc-title-height')
                 },
                 {

From d3b23c19f89692fa482c2f35a9bbb2e81ed6e97c Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Tue, 6 Feb 2018 01:01:29 +0300
Subject: [PATCH 09/41] implement changes according to draft design

---
 apps/common/main/lib/util/utils.js           |  2 +-
 apps/common/main/resources/less/header.less  | 76 ++++++++++----------
 apps/common/main/resources/less/toolbar.less |  1 +
 3 files changed, 38 insertions(+), 41 deletions(-)

diff --git a/apps/common/main/lib/util/utils.js b/apps/common/main/lib/util/utils.js
index 3dcb5bf85..aa22b54be 100644
--- a/apps/common/main/lib/util/utils.js
+++ b/apps/common/main/lib/util/utils.js
@@ -772,4 +772,4 @@ Common.Utils.InternalSettings = new(function() {
 
 Common.Utils.InternalSettings.set('toolbar-height-compact', 32);
 Common.Utils.InternalSettings.set('toolbar-height-normal', 32+67);
-Common.Utils.InternalSettings.set('doc-title-height', 26);
\ No newline at end of file
+Common.Utils.InternalSettings.set('doc-title-height', 28);
\ No newline at end of file
diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less
index ae854c85d..14e60c00b 100644
--- a/apps/common/main/resources/less/header.less
+++ b/apps/common/main/resources/less/header.less
@@ -43,7 +43,6 @@
         line-height: 20px;
         height: 100%;
         display: flex;
-        align-items: center;
     }
 
     &.left {
@@ -80,7 +79,7 @@
 
     #box-doc-name {
         flex-grow: 1;
-        text-align: center;
+        display: flex;
     }
 
     #rib-doc-name {
@@ -146,7 +145,6 @@
 }
 
 #tlb-box-users {
-    height: @height-tabs;
 }
 
 #tlb-change-rights {
@@ -154,9 +152,11 @@
 }
 
 .btn-users {
-    display: inline-flex;
+    display: flex;
+    align-items: center;
     cursor: pointer;
-    padding: 6px 12px;
+    padding: 0 12px;
+    height: 100%;
 
     .icon {
         display: inline-block;
@@ -230,50 +230,52 @@
 
 .hedset {
     font-size: 0;
+    display: flex;
 }
 
 .btn-header {
-    border: 0 none;
-    height: @height-tabs;
+    height: 100%;
     background-color: transparent;
-    padding: 6px 12px;
+    width: 40px;
 
     .icon {
         width: 20px;
         height: 20px;
     }
+
+    svg.icon {
+        display: inline-block;
+        vertical-align: middle;
+    }
+
+    .btn&[disabled],
+    &.disabled {
+        opacity: 0.65;
+    }
+
+    &:hover {
+        &:not(.disabled) {
+            background-color: rgba(255,255,255,0.2);
+        }
+    }
+
+    &:active {
+        &:not(.disabled) {
+            background-color: rgba(0,0,0,0.2);
+        }
+    }
 }
 
 #box-document-title {
     background-color: @tabs-bg-color;
     display: flex;
+    height: 100%;
+    color:#fff;
 
     .btn-slot {
         display: inline-block;
     }
 
-    .btn-header {
-        height: 26px;
-        padding: 3px 6px;
-
-        &[disabled],
-        &.disabled {
-            opacity: 0.65;
-        }
-
-        &:hover {
-            &:not(.disabled) {
-                background-color: rgba(255,255,255,0.2);
-            }
-        }
-
-        &:active {
-            &:not(.disabled) {
-                background-color: rgba(0,0,0,0.2);
-            }
-        }
-    }
-
     svg.icon {
         fill: #fff;
     }
@@ -286,8 +288,6 @@
         text-align: center;
         font-size: 12px;
         height: 100%;
-
-        color: #d3d9e3;
         background-color: transparent;
         border: 0 none;
         cursor: default;
@@ -297,15 +297,11 @@
         text-overflow: ellipsis;
         overflow: hidden;
         text-align: right;
-        font-size: 12px;
-        width: 150px;
+        font-size: 11px;
+        max-width: 50%;
         height: 100%;
-        padding: 4px 12px 4px 0;
-
-        color: #d3d9e3;
-        background-color: transparent;
-        border: 0 none;
-        cursor: default;
+        padding: 0 12px;
+        line-height: @height-title;
    }
 }
 
diff --git a/apps/common/main/resources/less/toolbar.less b/apps/common/main/resources/less/toolbar.less
index 5fc463277..00a4ce170 100644
--- a/apps/common/main/resources/less/toolbar.less
+++ b/apps/common/main/resources/less/toolbar.less
@@ -1,3 +1,4 @@
+@height-title: 28px;
 @height-tabs: 32px;
 @height-controls: 67px;
 

From 14c19f8369b9561cdfdeb4cad10b292cd91a214a Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 7 Feb 2018 00:55:24 +0300
Subject: [PATCH 10/41] changed toolbar's markup

---
 apps/common/main/lib/component/Mixtbar.js     |   2 +-
 apps/common/main/resources/less/toolbar.less  | 159 +++++++++---------
 .../main/app/template/Toolbar.template        |   1 -
 .../main/app/template/Toolbar.template        |   1 -
 .../main/app/template/Toolbar.template        |   1 -
 5 files changed, 83 insertions(+), 81 deletions(-)

diff --git a/apps/common/main/lib/component/Mixtbar.js b/apps/common/main/lib/component/Mixtbar.js
index 0edc4d482..89f646ce0 100644
--- a/apps/common/main/lib/component/Mixtbar.js
+++ b/apps/common/main/lib/component/Mixtbar.js
@@ -257,7 +257,7 @@ define([
                     return config.tabs[index].action;
                 }
 
-                var _tabTemplate = _.template('<li class="ribtab" style="display: none;"><div class="tab-bg" /><a href="#" data-tab="<%= action %>" data-title="<%= caption %>"><%= caption %></a></li>');
+                var _tabTemplate = _.template('<li class="ribtab" style="display: none;"><a href="#" data-tab="<%= action %>" data-title="<%= caption %>"><%= caption %></a></li>');
 
                 config.tabs[after + 1] = tab;
                 var _after_action = _get_tab_action(after);
diff --git a/apps/common/main/resources/less/toolbar.less b/apps/common/main/resources/less/toolbar.less
index 00a4ce170..50d1f9741 100644
--- a/apps/common/main/resources/less/toolbar.less
+++ b/apps/common/main/resources/less/toolbar.less
@@ -22,11 +22,11 @@
         }
 
         &:not(.expanded):not(.cover){
-          .ribtab.active {
-            > a {
-              font-weight: normal;
+            .ribtab.active {
+                > a {
+                    font-weight: normal;
+                }
             }
-          }
         }
     }
 
@@ -59,90 +59,73 @@
         overflow: hidden;
         display: flex;
 
-    > ul {
-      padding: 0;
-      margin: 0;
-      white-space: nowrap;
-      overflow: hidden;
-      list-style: none;
-      font-size: 0;
-    }
-
-    li {
-      display: inline-block;
-      height: 100%;
-      //background-color: #a6c995;
-
-        position: relative;
-        .tab-bg {
-            position: absolute;
-            height: 28px;
-            width: 100%;
-            top: 4px;
-            background-color: @tabs-bg-color;
+        > ul {
+            padding: 4px 0 0;
+            margin: 0;
+            white-space: nowrap;
+            overflow: hidden;
+            list-style: none;
+            font-size: 0;
         }
 
-        &:hover {
-            .tab-bg {
+        li {
+            display: inline-flex;
+            align-items: center;
+            height: 100%;
+
+            &:hover {
                 background-color: rgba(255,255,255,0.2);
             }
-        }
 
-        &.active {
-            .tab-bg {
+            &.active {
                 background-color: @gray-light;
             }
+
+
+            > a {
+                display: inline-block;
+                padding: 0 12px;
+                text-decoration: none;
+                cursor: default;
+                font-size: 12px;
+                text-align: center;
+                color: #fff;
+            }
+
+            &.active {
+                > a {
+                    color: #444;
+                }
+            }
         }
 
-
-      > a {
-        display: inline-block;
-        line-height: @height-tabs;
-        height: 100%;
-        padding: 1px 12px;
-        text-decoration: none;
-        cursor: default;
-        font-size: 12px;
-        text-align: center;
-        color: #fff;
-
-          position: relative;
-      }
-
-      &.active {
-        > a {
-            color: #444;
+        &:not(.short) {
+            .scroll {
+                display: none;
+            }
+        }
+
+        .scroll {
+            line-height: @height-tabs;
+            min-width: 20px;
+            text-align: center;
+            z-index: 1;
+            cursor: pointer;
+            color: #fff;
+
+            &:hover {
+                text-decoration: none;
+            }
+
+            &.left{
+                box-shadow: 5px 0 20px 5px @tabs-bg-color
+            }
+            &.right{
+                box-shadow: -5px 0 20px 5px @tabs-bg-color
+            }
         }
-      }
     }
 
-    &:not(.short) {
-      .scroll {
-        display: none;
-      }
-    }
-
-    .scroll {
-      line-height: @height-tabs;
-      min-width: 20px;
-      text-align: center;
-      z-index: 1;
-      cursor: pointer;
-      color: #fff;
-
-      &:hover {
-        text-decoration: none;
-      }
-
-      &.left{
-        box-shadow: 5px 0 20px 5px @tabs-bg-color
-      }
-      &.right{
-        box-shadow: -5px 0 20px 5px @tabs-bg-color
-      }
-    }
-  }
-
     .box-controls {
         //height: @height-controls;         // button has strange offset in IE when odd height
         padding: 10px 0;
@@ -230,11 +213,33 @@
             margin-top: 3px;
         }
     }
+
+    .top-title > & {
+        &:not(.folded) {
+            height: 28 + @height-controls;
+        }
+
+        &.folded {
+            height: 28px;
+
+            &.expanded {
+                height: 28 + @height-controls;
+            }
+        }
+
+        .tabs > ul {
+            padding-top: 0;
+        }
+
+        .box-tabs {
+            height: 28px;
+        }
+    }
+
 }
 
 .toolbar-fullview-panel {
     position: absolute;
-    top: @height-tabs;
     bottom: 0;
     width: 100%;
     z-index: 1041;
diff --git a/apps/documenteditor/main/app/template/Toolbar.template b/apps/documenteditor/main/app/template/Toolbar.template
index 0cb15cfe0..14e1db5aa 100644
--- a/apps/documenteditor/main/app/template/Toolbar.template
+++ b/apps/documenteditor/main/app/template/Toolbar.template
@@ -8,7 +8,6 @@
             <ul>
                 <% for(var i in tabs) { %>
                     <li class="ribtab<% if (tabs[i].extcls) print(' ' + tabs[i].extcls) %>">
-                        <div class="tab-bg" />
                         <a data-tab="<%= tabs[i].action %>" data-title="<%= tabs[i].caption %>"><%= tabs[i].caption %></a>
                     </li>
                 <% } %>
diff --git a/apps/presentationeditor/main/app/template/Toolbar.template b/apps/presentationeditor/main/app/template/Toolbar.template
index a66ccad0e..7cae88f91 100644
--- a/apps/presentationeditor/main/app/template/Toolbar.template
+++ b/apps/presentationeditor/main/app/template/Toolbar.template
@@ -8,7 +8,6 @@
             <ul>
                 <% for(var i in tabs) { %>
                     <li class="ribtab<% if (tabs[i].extcls) print(' ' + tabs[i].extcls) %>">
-                        <div class="tab-bg" />
                         <a data-tab="<%= tabs[i].action %>" data-title="<%= tabs[i].caption %>"><%= tabs[i].caption %></a>
                     </li>
                 <% } %>
diff --git a/apps/spreadsheeteditor/main/app/template/Toolbar.template b/apps/spreadsheeteditor/main/app/template/Toolbar.template
index b4c6605f6..6fc9e087c 100644
--- a/apps/spreadsheeteditor/main/app/template/Toolbar.template
+++ b/apps/spreadsheeteditor/main/app/template/Toolbar.template
@@ -8,7 +8,6 @@
             <ul>
                 <% for(var i in tabs) { %>
                 <li class="ribtab<% if (tabs[i].extcls) print(' ' + tabs[i].extcls) %>">
-                    <div class="tab-bg" />
                     <a data-tab="<%= tabs[i].action %>" data-title="<%= tabs[i].caption %>"><%= tabs[i].caption %></a>
                 </li>
                 <% } %>

From c3260dfc385abf968510eb2e2a6562ccc6d52154 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 7 Feb 2018 01:37:23 +0300
Subject: [PATCH 11/41] initialized app's strart params

---
 apps/common/main/lib/util/utils.js              | 10 +++++++---
 apps/common/main/resources/less/header.less     |  4 ----
 .../main/app/controller/Viewport.js             | 17 +++++++++++++++--
 apps/documenteditor/main/app/view/Viewport.js   |  8 +++-----
 .../main/app/controller/Viewport.js             | 17 +++++++++++++++--
 .../main/app/view/Viewport.js                   |  8 +++-----
 .../main/app/controller/Viewport.js             | 17 +++++++++++++++--
 .../spreadsheeteditor/main/app/view/Viewport.js |  8 +++-----
 8 files changed, 61 insertions(+), 28 deletions(-)

diff --git a/apps/common/main/lib/util/utils.js b/apps/common/main/lib/util/utils.js
index aa22b54be..0619142f6 100644
--- a/apps/common/main/lib/util/utils.js
+++ b/apps/common/main/lib/util/utils.js
@@ -770,6 +770,10 @@ Common.Utils.InternalSettings = new(function() {
     }
 });
 
-Common.Utils.InternalSettings.set('toolbar-height-compact', 32);
-Common.Utils.InternalSettings.set('toolbar-height-normal', 32+67);
-Common.Utils.InternalSettings.set('doc-title-height', 28);
\ No newline at end of file
+Common.Utils.InternalSettings.set('toolbar-height-tabs', 32);
+Common.Utils.InternalSettings.set('toolbar-height-tabs-top-title', 28);
+Common.Utils.InternalSettings.set('toolbar-height-controls', 67);
+Common.Utils.InternalSettings.set('document-title-height', 28);
+
+Common.Utils.InternalSettings.set('toolbar-height-compact', Common.Utils.InternalSettings.get('toolbar-height-tabs'));
+Common.Utils.InternalSettings.set('toolbar-height-normal', Common.Utils.InternalSettings.get('toolbar-height-tabs') + Common.Utils.InternalSettings.get('toolbar-height-controls'));
diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less
index 14e60c00b..73243b7f6 100644
--- a/apps/common/main/resources/less/header.less
+++ b/apps/common/main/resources/less/header.less
@@ -304,7 +304,3 @@
         line-height: @height-title;
    }
 }
-
-.toolbar-fullview-panel.new-doctitle-offset {
-    top: @height-tabs + 26;
-}
diff --git a/apps/documenteditor/main/app/controller/Viewport.js b/apps/documenteditor/main/app/controller/Viewport.js
index ad5398e82..98281ba0a 100644
--- a/apps/documenteditor/main/app/controller/Viewport.js
+++ b/apps/documenteditor/main/app/controller/Viewport.js
@@ -116,19 +116,32 @@ define([
             var me = this;
             me.appConfig = config;
 
+            var _intvars = Common.Utils.InternalSettings;
+            var $filemenu = $('.toolbar-fullview-panel');
+            $filemenu.css('top', _intvars.get('toolbar-height-tabs'));
+
             if ( !config.isEdit ||
                 ( !Common.localStorage.itemExists("de-compact-toolbar") &&
                 config.customization && config.customization.compactToolbar )) {
 
                 var panel = me.viewport.vlayout.getItem('toolbar');
-                if ( panel ) panel.height = Common.Utils.InternalSettings.get('toolbar-height-compact');
+                if ( panel ) panel.height = _intvars.get('toolbar-height-tabs');
             }
 
             if ( config.isDesktopApp && config.isEdit ) {
                 var $title = me.viewport.vlayout.getItem('title').el;
                 $title.html(me.header.getPanel('title', config)).show();
 
-                $('.toolbar-fullview-panel').addClass('new-doctitle-offset');
+                var toolbar = me.viewport.vlayout.getItem('toolbar');
+                toolbar.el.addClass('top-title');
+                toolbar.height -= _intvars.get('toolbar-height-tabs') - _intvars.get('toolbar-height-tabs-top-title');
+
+                var _tabs_new_height = _intvars.get('toolbar-height-tabs-top-title');
+                _intvars.set('toolbar-height-tabs', _tabs_new_height);
+                _intvars.set('toolbar-height-compact', _tabs_new_height);
+                _intvars.set('toolbar-height-normal', _tabs_new_height + _intvars.get('toolbar-height-controls'));
+
+                $filemenu.css('top', _tabs_new_height + _intvars.get('document-title-height'));
             }
         },
 
diff --git a/apps/documenteditor/main/app/view/Viewport.js b/apps/documenteditor/main/app/view/Viewport.js
index 061d4771e..fb1fd87d8 100644
--- a/apps/documenteditor/main/app/view/Viewport.js
+++ b/apps/documenteditor/main/app/view/Viewport.js
@@ -82,13 +82,11 @@ define([
             var $container = $('#viewport-vbox-layout', this.$el);
             this.vlayout = new Common.UI.VBoxLayout({
                 box: $container,
-                items: [
-                    {
+                items: [{
                         el: $container.find('> .layout-item#title').hide(),
                         alias: 'title',
-                        height: Common.Utils.InternalSettings.get('doc-title-height')
-                    },
-                    {
+                        height: Common.Utils.InternalSettings.get('document-title-height')
+                    }, {
                         el: $container.find(' > .layout-item#toolbar'),
                         alias: 'toolbar',
                         // rely: true
diff --git a/apps/presentationeditor/main/app/controller/Viewport.js b/apps/presentationeditor/main/app/controller/Viewport.js
index 5a3b09f68..046d7550b 100644
--- a/apps/presentationeditor/main/app/controller/Viewport.js
+++ b/apps/presentationeditor/main/app/controller/Viewport.js
@@ -119,18 +119,31 @@ define([
             var me = this;
             me.appConfig = config;
 
+            var _intvars = Common.Utils.InternalSettings;
+            var $filemenu = $('.toolbar-fullview-panel');
+            $filemenu.css('top', _intvars.get('toolbar-height-tabs'));
+
             if ( !config.isEdit ||
                 ( !Common.localStorage.itemExists("pe-compact-toolbar") &&
                     config.customization && config.customization.compactToolbar ))
             {
-                me.viewport.vlayout.getItem('toolbar').height = Common.Utils.InternalSettings.get('toolbar-height-compact');
+                me.viewport.vlayout.getItem('toolbar').height = _intvars.get('toolbar-height-compact');
             }
 
             if ( config.isDesktopApp && config.isEdit ) {
                 var $title = me.viewport.vlayout.getItem('title').el;
                 $title.html(me.header.getPanel('title', config)).show();
 
-                $('.toolbar-fullview-panel').addClass('new-doctitle-offset');
+                var toolbar = me.viewport.vlayout.getItem('toolbar');
+                toolbar.el.addClass('top-title');
+                toolbar.height -= _intvars.get('toolbar-height-tabs') - _intvars.get('toolbar-height-tabs-top-title');
+
+                var _tabs_new_height = _intvars.get('toolbar-height-tabs-top-title');
+                _intvars.set('toolbar-height-tabs', _tabs_new_height);
+                _intvars.set('toolbar-height-compact', _tabs_new_height);
+                _intvars.set('toolbar-height-normal', _tabs_new_height + _intvars.get('toolbar-height-controls'));
+
+                $filemenu.css('top', _tabs_new_height + _intvars.get('document-title-height'));
             }
         },
 
diff --git a/apps/presentationeditor/main/app/view/Viewport.js b/apps/presentationeditor/main/app/view/Viewport.js
index 521065fb7..926a4ef3a 100644
--- a/apps/presentationeditor/main/app/view/Viewport.js
+++ b/apps/presentationeditor/main/app/view/Viewport.js
@@ -85,13 +85,11 @@ define([
             var items = $container.find(' > .layout-item');
             this.vlayout = new Common.UI.VBoxLayout({
                 box: $container,
-                items: [
-                {
+                items: [{
                     el: $container.find('> .layout-item#title').hide(),
                     alias: 'title',
-                    height: Common.Utils.InternalSettings.get('doc-title-height')
-                },
-                {
+                    height: Common.Utils.InternalSettings.get('document-title-height')
+                }, {
                     el: items[1],
                     alias: 'toolbar',
                     height: Common.localStorage.getBool('pe-compact-toolbar') ?
diff --git a/apps/spreadsheeteditor/main/app/controller/Viewport.js b/apps/spreadsheeteditor/main/app/controller/Viewport.js
index e6f334054..dd05bf1ed 100644
--- a/apps/spreadsheeteditor/main/app/controller/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/controller/Viewport.js
@@ -91,11 +91,15 @@ define([
             var me = this;
             me.appConfig = config;
 
+            var _intvars = Common.Utils.InternalSettings;
+            var $filemenu = $('.toolbar-fullview-panel');
+            $filemenu.css('top', _intvars.get('toolbar-height-tabs'));
+
             if ( !config.isEdit ||
                     ( !Common.localStorage.itemExists("sse-compact-toolbar") &&
                         config.customization && config.customization.compactToolbar ))
             {
-                me.viewport.vlayout.getItem('toolbar').height = Common.Utils.InternalSettings.get('toolbar-height-compact');
+                me.viewport.vlayout.getItem('toolbar').height = _intvars.get('toolbar-height-compact');
             } else
             if ( config.isEditDiagram || config.isEditMailMerge ) {
                 me.viewport.vlayout.getItem('toolbar').height = 41;
@@ -105,7 +109,16 @@ define([
                 var $title = me.viewport.vlayout.getItem('title').el;
                 $title.html(me.header.getPanel('title', config)).show();
 
-                $('.toolbar-fullview-panel').addClass('new-doctitle-offset');
+                var toolbar = me.viewport.vlayout.getItem('toolbar');
+                toolbar.el.addClass('top-title');
+                toolbar.height -= _intvars.get('toolbar-height-tabs') - _intvars.get('toolbar-height-tabs-top-title');
+
+                var _tabs_new_height = _intvars.get('toolbar-height-tabs-top-title');
+                _intvars.set('toolbar-height-tabs', _tabs_new_height);
+                _intvars.set('toolbar-height-compact', _tabs_new_height);
+                _intvars.set('toolbar-height-normal', _tabs_new_height + _intvars.get('toolbar-height-controls'));
+
+                $filemenu.css('top', _tabs_new_height + _intvars.get('document-title-height'));
             }
         },
 
diff --git a/apps/spreadsheeteditor/main/app/view/Viewport.js b/apps/spreadsheeteditor/main/app/view/Viewport.js
index 70f2e5c3d..416239c73 100644
--- a/apps/spreadsheeteditor/main/app/view/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/view/Viewport.js
@@ -85,13 +85,11 @@ define([
             var items = $container.find(' > .layout-item');
             this.vlayout = new Common.UI.VBoxLayout({
                 box: $container,
-                items: [
-                {
+                items: [{
                     el: $container.find('> .layout-item#title').hide(),
                     alias: 'title',
-                    height: Common.Utils.InternalSettings.get('doc-title-height')
-                },
-                {
+                    height: Common.Utils.InternalSettings.get('document-title-height')
+                },{
                     el: items[1],
                     alias: 'toolbar',
                     height: Common.localStorage.getBool('sse-compact-toolbar') ?

From 472e5edcb71dc1c1c03f75b8e74e51ce36c0b66e Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 7 Feb 2018 01:37:40 +0300
Subject: [PATCH 12/41] debug

---
 apps/spreadsheeteditor/main/app/controller/Main.js | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js
index 299461f04..3fd553372 100644
--- a/apps/spreadsheeteditor/main/app/controller/Main.js
+++ b/apps/spreadsheeteditor/main/app/controller/Main.js
@@ -913,8 +913,7 @@ define([
                     statusbarView   = app.getController('Statusbar').getView('Statusbar');
 
                 if (this.headerView) {
-                    this.headerView.setHeaderCaption(this.appOptions.isEdit ? 'Spreadsheet Editor' : 'Spreadsheet Viewer');
-                    this.headerView.setVisible(!this.appOptions.nativeApp && !value && !this.appOptions.isEditMailMerge && 
+                    this.headerView.setVisible(!this.appOptions.nativeApp && !value && !this.appOptions.isEditMailMerge &&
                             !this.appOptions.isDesktopApp && !this.appOptions.isEditDiagram);
                 }
 

From b5a5c9773544180caa1ca1e845bb16df98651d80 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 7 Feb 2018 18:30:45 +0300
Subject: [PATCH 13/41] hide some buttons for desktop mode

---
 .../main/app/controller/Toolbar.js            | 21 +++++++++++++-----
 .../main/app/controller/Toolbar.js            | 22 ++++++++++++++-----
 .../main/app/controller/Toolbar.js            | 22 ++++++++++++++-----
 3 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js
index 765074d53..8343f7f10 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -2768,12 +2768,23 @@ define([
                 if ( $panel )
                     me.toolbar.addTab(tab, $panel, 4);
 
-                if (config.isDesktopApp && config.isOffline) {
-                    tab = {action: 'protect', caption: me.toolbar.textTabProtect};
-                    $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel();
+                if ( config.isDesktopApp ) {
+                    // hide 'print' and 'save' buttons group and next separator
+                    me.toolbar.btnPrint.$el.parents('.group').hide().next().hide();
 
-                    if ( $panel )
-                        me.toolbar.addTab(tab, $panel, 5);
+                    // hide 'undo' and 'redo' buttons and get container
+                    var $box =  me.toolbar.btnUndo.$el.hide().next().hide().parent();
+
+                    // move 'paste' button to the container instead of 'undo' and 'redo'
+                    me.toolbar.btnPaste.$el.detach().appendTo($box);
+                    me.toolbar.btnCopy.$el.removeClass('split');
+
+                    if ( config.isOffline ) {
+                        tab = {action: 'protect', caption: me.toolbar.textTabProtect};
+                        $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel();
+
+                        if ($panel) me.toolbar.addTab(tab, $panel, 5);
+                    }
                 }
 
                 var links = me.getApplication().getController('Links');
diff --git a/apps/presentationeditor/main/app/controller/Toolbar.js b/apps/presentationeditor/main/app/controller/Toolbar.js
index 913546750..4ffa5d50f 100644
--- a/apps/presentationeditor/main/app/controller/Toolbar.js
+++ b/apps/presentationeditor/main/app/controller/Toolbar.js
@@ -2091,11 +2091,23 @@ define([
                 if ( $panel )
                     me.toolbar.addTab(tab, $panel, 3);
 
-                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);
+                if ( config.isDesktopApp ) {
+                    // hide 'print' and 'save' buttons group and next separator
+                    me.toolbar.btnPrint.$el.parents('.group').hide().next().hide();
+
+                    // hide 'undo' and 'redo' buttons and get container
+                    var $box =  me.toolbar.btnUndo.$el.hide().next().hide().parent();
+
+                    // move 'paste' button to the container instead of 'undo' and 'redo'
+                    me.toolbar.btnPaste.$el.detach().appendTo($box);
+                    me.toolbar.btnCopy.$el.removeClass('split');
+
+                    if ( config.isOffline ) {
+                        tab = {action: 'protect', caption: me.toolbar.textTabProtect};
+                        $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel();
+                        if ($panel)
+                            me.toolbar.addTab(tab, $panel, 4);
+                    }
                 }
             }
         },
diff --git a/apps/spreadsheeteditor/main/app/controller/Toolbar.js b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
index 173d7d9b3..0f6d1d44a 100644
--- a/apps/spreadsheeteditor/main/app/controller/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
@@ -3054,11 +3054,23 @@ define([
                         if ( $panel )
                             me.toolbar.addTab(tab, $panel, 4);
 
-                        if (config.isDesktopApp && config.isOffline) {
-                            tab = {action: 'protect', caption: me.toolbar.textTabProtect};
-                            var $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel();
-                            if ( $panel )
-                                me.toolbar.addTab(tab, $panel, 5);
+                        if ( config.isDesktopApp ) {
+                            // hide 'print' and 'save' buttons group and next separator
+                            me.toolbar.btnPrint.$el.parents('.group').hide().next().hide();
+
+                            // hide 'undo' and 'redo' buttons and get container
+                            var $box =  me.toolbar.btnUndo.$el.hide().next().hide().parent();
+
+                            // move 'paste' button to the container instead of 'undo' and 'redo'
+                            me.toolbar.btnPaste.$el.detach().appendTo($box);
+                            me.toolbar.btnCopy.$el.removeClass('split');
+
+                            if ( config.isOffline ) {
+                                tab = {action: 'protect', caption: me.toolbar.textTabProtect};
+                                var $panel = me.getApplication().getController('Common.Controllers.Protection').createToolbarPanel();
+                                if ($panel)
+                                    me.toolbar.addTab(tab, $panel, 5);
+                            }
                         }
                     }
                 }

From 753afc350df953316c2b1d1af26939add9465fff Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Tue, 13 Feb 2018 11:23:53 +0300
Subject: [PATCH 14/41] refactoring. send commands to desktop app

---
 apps/api/documents/index.html.desktop         | 24 +++++++++++++++++--
 .../main/app/controller/Main.js               | 14 +++++++----
 .../main/app/controller/Main.js               | 18 +++++++++-----
 .../main/app/controller/Main.js               | 14 +++++++----
 4 files changed, 54 insertions(+), 16 deletions(-)

diff --git a/apps/api/documents/index.html.desktop b/apps/api/documents/index.html.desktop
index 3b6a293bd..03edba6c1 100644
--- a/apps/api/documents/index.html.desktop
+++ b/apps/api/documents/index.html.desktop
@@ -55,7 +55,12 @@
                 height: '100%',
                 documentType: urlParams['doctype'] || 'text',
                 document: doc,
-                editorConfig: cfg
+                editorConfig: cfg,
+                events: {
+                    onInternalMessage: onInternalMessage,
+                    onDocumentReady: onDocumentReady
+
+                }
             });
 
 
@@ -92,7 +97,7 @@
             function getEditorConfig(urlParams) {
                 return {
                     customization   : {
-                        goback: { url:"https://onlyoffice.com" }
+                        goback: { url: "callback" }
                     },
                     mode            : urlParams["mode"] || 'edit',
                     lang            : urlParams["lang"] || 'en',
@@ -147,6 +152,21 @@
                 }
             };
 
+            function onInternalMessage(event) {
+                let info = event.data;
+                if ( info.type == 'goback' ) {
+                    if ( window.AscDesktopEditor ) {
+                        window.AscDesktopEditor.execCommand('go:folder', info.data.status);
+                    }
+                }
+            };
+
+            function onDocumentReady() {
+                if ( window.AscDesktopEditor ) {
+                    window.AscDesktopEditor.execCommand('doc:onready', '');
+                }
+            }
+
             if (isMobile()){
                 window.addEventListener('load', fixSize);
                 window.addEventListener('resize', fixSize);
diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js
index 173cce5c6..e167c20db 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -582,11 +582,17 @@ define([
             },
 
             goBack: function(blank) {
-                var href = this.appOptions.customization.goback.url;
-                if (blank) {
-                    window.open(href, "_blank");
+                var me = this;
+                if ( me.appOptions.customization.goback.url == 'callback' ) {
+                    Common.Gateway.internalMessage( 'goback',
+                        {status: me.appOptions.isOffline ? 'offline' : 'online'} );
                 } else {
-                    parent.location.href = href;
+                    var href = this.appOptions.customization.goback.url;
+                    if (blank) {
+                        window.open(href, "_blank");
+                    } else {
+                        parent.location.href = href;
+                    }
                 }
             },
 
diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js
index c1c12a7f6..56a972c43 100644
--- a/apps/presentationeditor/main/app/controller/Main.js
+++ b/apps/presentationeditor/main/app/controller/Main.js
@@ -393,12 +393,18 @@ define([
             },
 
             goBack: function(blank) {
-                 var href = this.appOptions.customization.goback.url;
-                 if (blank) {
-                     window.open(href, "_blank");
-                 } else {
-                     parent.location.href = href;
-                 }
+                var me = this;
+                if ( me.appOptions.customization.goback.url == 'callback' ) {
+                    Common.Gateway.internalMessage( 'goback',
+                            {status: me.appOptions.isOffline ? 'offline' : 'online'} );
+                } else {
+                    var href = me.appOptions.customization.goback.url;
+                    if (blank) {
+                        window.open(href, "_blank");
+                    } else {
+                        parent.location.href = href;
+                    }
+                }
              },
 
             onEditComplete: function(cmp) {
diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js
index 3fd553372..23444269e 100644
--- a/apps/spreadsheeteditor/main/app/controller/Main.js
+++ b/apps/spreadsheeteditor/main/app/controller/Main.js
@@ -428,11 +428,17 @@ define([
             },
 
             goBack: function(blank) {
-                var href = this.appOptions.customization.goback.url;
-                if (blank) {
-                    window.open(href, "_blank");
+                var me = this;
+                if ( me.appOptions.customization.goback.url == 'callback' ) {
+                    Common.Gateway.internalMessage( 'goback',
+                        {status: me.appOptions.isOffline ? 'offline' : 'online'} );
                 } else {
-                    parent.location.href = href;
+                    var href = me.appOptions.customization.goback.url;
+                    if (blank) {
+                        window.open(href, "_blank");
+                    } else {
+                        parent.location.href = href;
+                    }
                 }
             },
 

From 0fb072b9fab0eca92064f28ea39a2af4802aa3b5 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Tue, 13 Feb 2018 17:37:22 +0300
Subject: [PATCH 15/41] refactoring. created controller for set of buttons

---
 apps/common/main/lib/component/Button.js      | 59 +++++++++++++++++
 .../main/app/controller/Toolbar.js            | 24 +++----
 apps/documenteditor/main/app/view/Toolbar.js  | 35 +++--------
 .../main/app/controller/Toolbar.js            |  6 +-
 .../main/app/view/Toolbar.js                  | 63 +++----------------
 .../main/app/view/Toolbar.js                  | 20 ++----
 6 files changed, 87 insertions(+), 120 deletions(-)

diff --git a/apps/common/main/lib/component/Button.js b/apps/common/main/lib/component/Button.js
index e55b50942..013f7f78e 100644
--- a/apps/common/main/lib/component/Button.js
+++ b/apps/common/main/lib/component/Button.js
@@ -119,6 +119,65 @@ define([
 ], function () {
     'use strict';
 
+    window.createButtonSet = function() {
+        function ButtonsArray(args) {};
+        ButtonsArray.prototype = new Array;
+        ButtonsArray.prototype.constructor = ButtonsArray;
+
+        var _disabled = false;
+
+        ButtonsArray.prototype.add = function(button) {
+            button.setDisabled(_disabled);
+            this.push(button);
+        };
+
+        ButtonsArray.prototype.setDisabled = function(disable) {
+            if ( _disabled != disable ) {
+                _disabled = disable;
+
+                this.forEach( function(button) {
+                    button.setDisabled(disable);
+                });
+            }
+        };
+
+        ButtonsArray.prototype.toggle = function(state, suppress) {
+            this.forEach(function(button) {
+                button.toggle(state, suppress);
+            });
+        };
+
+        ButtonsArray.prototype.pressed = function() {
+            return this.some(function(button) {
+                return button.pressed;
+            });
+        };
+
+        ButtonsArray.prototype.contains = function(id) {
+            return this.some(function(button) {
+                return button.id == id;
+            });
+        };
+
+        ButtonsArray.prototype.concat = function () {
+            var args = Array.prototype.slice.call(arguments);
+            var result = Array.prototype.slice.call(this);
+
+            args.forEach(function(sub){
+                Array.prototype.push.apply(result, sub);
+            });
+
+            return result;
+        }
+
+        var _out_array = Object.create(ButtonsArray.prototype);
+        for ( var i in arguments ) {
+            _out_array.add(arguments[i]);
+        }
+
+        return _out_array;
+    };
+
     var templateBtnIcon =
             '<% if ( iconImg ) { %>' +
                 '<img src="<%= iconImg %>">' +
diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js
index 8343f7f10..b50f5e651 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -734,7 +734,7 @@ define([
             toolbar.mnuInsertPageNum.setDisabled(need_disable);
 
             need_disable = paragraph_locked || header_locked || in_header || in_image || in_equation && !btn_eq_state || this.api.asc_IsCursorInFootnote() || in_control;
-            toolbar.btnsPageBreak.disable(need_disable);
+            toolbar.btnsPageBreak.setDisabled(need_disable);
 
             need_disable = paragraph_locked || header_locked || !can_add_image || in_equation || control_plain;
             toolbar.btnInsertImage.setDisabled(need_disable);
@@ -767,10 +767,8 @@ define([
                 toolbar.listStylesAdditionalMenuItem.setDisabled(frame_pr===undefined);
 
             need_disable = (paragraph_locked || header_locked) && this.api.can_AddQuotedComment() || image_locked;
-            if (this.btnsComment && this.btnsComment.length>0 && need_disable != this.btnsComment[0].isDisabled())
-                _.each (this.btnsComment, function(item){
-                    item.setDisabled(need_disable);
-                }, this);
+            if ( this.btnsComment && this.btnsComment.length > 0 )
+                this.btnsComment.setDisabled(need_disable);
 
             this._state.in_equation = in_equation;
         },
@@ -922,11 +920,7 @@ define([
                 this.api.asc_Save();
             }
 
-            toolbar.btnsSave.forEach(function(button) {
-                if ( button ) {
-                    button.setDisabled(!toolbar.mode.forcesave);
-                }
-            });
+            toolbar.btnsSave.setDisabled(!toolbar.mode.forcesave);
 
             Common.NotificationCenter.trigger('edit:complete', toolbar);
 
@@ -2707,11 +2701,7 @@ define([
 
             toolbar._state.previewmode = reviewmode && disable;
             if (reviewmode) {
-                toolbar._state.previewmode && toolbar.btnsSave.forEach(function(button) {
-                    if ( button ) {
-                        button.setDisabled(true);
-                    }
-                });
+                toolbar._state.previewmode && toolbar.btnsSave.setDisabled(true);
 
                 if (toolbar.needShowSynchTip) {
                     toolbar.needShowSynchTip = false;
@@ -2797,7 +2787,7 @@ define([
             var me = this;
 
             if ( config.canCoAuthoring && config.canComments ) {
-                this.btnsComment = [];
+                this.btnsComment = createButtonSet();
                 var slots = me.toolbar.$el.find('.slot-comment');
                 slots.each(function(index, el) {
                     var _cls = 'btn-toolbar';
@@ -2810,7 +2800,7 @@ define([
                         caption: me.toolbar.capBtnComment
                     }).render( slots.eq(index) );
 
-                    me.btnsComment.push(button);
+                    me.btnsComment.add(button);
                 });
 
                 if ( this.btnsComment.length ) {
diff --git a/apps/documenteditor/main/app/view/Toolbar.js b/apps/documenteditor/main/app/view/Toolbar.js
index 56b3daa6b..4fecc3cd1 100644
--- a/apps/documenteditor/main/app/view/Toolbar.js
+++ b/apps/documenteditor/main/app/view/Toolbar.js
@@ -123,7 +123,7 @@ define([
                     iconCls: 'no-mask ' + this.btnSaveCls
                 });
                 this.toolbarControls.push(this.btnSave);
-                this.btnsSave = [this.btnSave];
+                me.btnsSave = createButtonSet( me.btnSave );
 
                 this.btnUndo = new Common.UI.Button({
                     id: 'id-toolbar-btn-undo',
@@ -1300,12 +1300,7 @@ define([
                 +function injectBreakButtons() {
                     var me = this;
 
-                    me.btnsPageBreak = [];
-                    me.btnsPageBreak.disable = function(status) {
-                        this.forEach(function(btn) {
-                            btn.setDisabled(status);
-                        });
-                    };
+                    me.btnsPageBreak = createButtonSet();
 
                     var $slots = $host.find('.btn-slot.btn-pagebreak');
                     $slots.each(function(index, el) {
@@ -1320,7 +1315,7 @@ define([
                             menu: true
                         }).render( $slots.eq(index) );
 
-                        me.btnsPageBreak.push(button);
+                        me.btnsPageBreak.add(button);
                     });
 
                     Array.prototype.push.apply(me.paragraphControls, me.btnsPageBreak);
@@ -1965,16 +1960,14 @@ define([
 
                 var btnsave = DE.getController('LeftMenu').getView('LeftMenu').getMenu('file').getButton('save');
                 if (btnsave && this.btnsSave) {
-                    this.btnsSave.push(btnsave);
+                    this.btnsSave.add(btnsave);
                     this.toolbarControls.push(btnsave);
-                    btnsave.setDisabled(this.btnsSave[0].isDisabled());
                 }
 
                 btnsave = DE.getController('Viewport').getView('Common.Views.Header').getButton('save');
                 if (btnsave && this.btnsSave) {
-                    this.btnsSave.push(btnsave);
+                    this.btnsSave.add(btnsave);
                     this.toolbarControls.push(btnsave);
-                    btnsave.setDisabled(this.btnsSave[0].isDisabled());
                 }
             },
 
@@ -2059,11 +2052,7 @@ define([
 
             setMode: function (mode) {
                 if (mode.isDisconnected) {
-                    this.btnsSave.forEach(function(button) {
-                        if ( button ) {
-                            button.setDisabled(true);
-                        }
-                    });
+                    this.btnsSave.setDisabled(true);
                     if (mode.disableDownload)
                         this.btnPrint.setDisabled(true);
                 }
@@ -2154,11 +2143,7 @@ define([
                     this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                 }
 
-                this.btnsSave.forEach(function(button) {
-                    if ( button ) {
-                        button.setDisabled(false);
-                    }
-                });
+                this.btnsSave.setDisabled(false);
                 Common.Gateway.collaborativeChanges();
             },
 
@@ -2189,11 +2174,7 @@ define([
                         if (this.synchTooltip)
                             this.synchTooltip.hide();
                         this.btnSave.updateHint(this.btnSaveTip);
-                        this.btnsSave.forEach(function(button) {
-                            if ( button ) {
-                                button.setDisabled(!me.mode.forcesave);
-                            }
-                        });
+                        this.btnsSave.setDisabled(!me.mode.forcesave);
                         this._state.hasCollaborativeChanges = false;
                     }
                 }
diff --git a/apps/presentationeditor/main/app/controller/Toolbar.js b/apps/presentationeditor/main/app/controller/Toolbar.js
index 4ffa5d50f..cdd8f02e6 100644
--- a/apps/presentationeditor/main/app/controller/Toolbar.js
+++ b/apps/presentationeditor/main/app/controller/Toolbar.js
@@ -915,11 +915,7 @@ define([
                 this.api.asc_Save();
             }
 
-            toolbar.btnsSave.forEach(function(button) {
-                if ( button ) {
-                    button.setDisabled(!toolbar.mode.forcesave);
-                }
-            });
+            toolbar.btnsSave.setDisabled(!toolbar.mode.forcesave);
 
             Common.NotificationCenter.trigger('edit:complete', this.toolbar);
             Common.component.Analytics.trackEvent('Save');
diff --git a/apps/presentationeditor/main/app/view/Toolbar.js b/apps/presentationeditor/main/app/view/Toolbar.js
index f6abc374f..6bb2695e6 100644
--- a/apps/presentationeditor/main/app/view/Toolbar.js
+++ b/apps/presentationeditor/main/app/view/Toolbar.js
@@ -83,45 +83,6 @@ define([
         commentLock: 'can-comment'
     };
 
-    var buttonsArray = function (opts) {
-        var arr = [];
-        arr.push.apply(arr, arguments);
-        arr.__proto__ = buttonsArray.prototype;
-        return arr;
-    };
-
-    buttonsArray.prototype = new Array;
-
-    buttonsArray.prototype.disable = function (state) {
-        this.forEach(function(btn) {
-            btn.setDisabled(state);
-        });
-    };
-
-    buttonsArray.prototype.toggle = function (state, suppress) {
-        this.forEach(function(btn) {
-            btn.toggle(state, suppress);
-        });
-    };
-
-    buttonsArray.prototype.pressed = function () {
-        return this.some(function(btn) {
-            return btn.pressed;
-        });
-    };
-
-    buttonsArray.prototype.on = function (event, func) {
-        this.forEach(function(btn) {
-            btn.on.apply(btn, arguments);
-        });
-    };
-
-    buttonsArray.prototype.contains = function (id) {
-        return this.some(function(btn) {
-            return btn.id == id;
-        });
-    };
-
     PE.Views.Toolbar =  Common.UI.Mixtbar.extend(_.extend((function(){
 
         return {
@@ -211,7 +172,7 @@ define([
                     iconCls     : 'no-mask ' + me.btnSaveCls,
                     lock        : [_set.lostConnect]
                 });
-                me.btnsSave = [me.btnSave];
+                me.btnsSave = createButtonSet(me.btnSave);
 
                 me.btnUndo = new Common.UI.Button({
                     id          : 'id-toolbar-btn-undo',
@@ -983,7 +944,7 @@ define([
                 _injectComponent('#slot-btn-settings', this.btnAdvSettings);
 
                 function _injectBtns(opts) {
-                    var array = new buttonsArray;
+                    var array = createButtonSet();
                     var $slots = $host.find(opts.slot);
                     var id = opts.btnconfig.id;
                     $slots.each(function(index, el) {
@@ -992,7 +953,7 @@ define([
                         var button = new Common.UI.Button(opts.btnconfig);
                         button.render( $slots.eq(index) );
 
-                        array.push(button);
+                        array.add(button);
                     });
 
                     return array;
@@ -1381,15 +1342,13 @@ define([
 
                 var btnsave = PE.getController('LeftMenu').getView('LeftMenu').getMenu('file').getButton('save');
                 if (btnsave && this.btnsSave) {
-                    this.btnsSave.push(btnsave);
+                    this.btnsSave.add(btnsave);
                     this.lockControls.push(btnsave);
-                    btnsave.setDisabled(this.btnsSave[0].isDisabled());
                 }
                 btnsave = PE.getController('Viewport').getView('Common.Views.Header').getButton('save');
                 if (btnsave && this.btnsSave) {
-                    this.btnsSave.push(btnsave);
+                    this.btnsSave.add(btnsave);
                     this.lockControls.push(btnsave);
-                    btnsave.setDisabled(this.btnsSave[0].isDisabled());
                 }
 
                 /** coauthoring begin **/
@@ -1540,11 +1499,7 @@ define([
                     this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                 }
 
-                this.btnsSave.forEach(function(button) {
-                    if ( button ) {
-                        button.setDisabled(false);
-                    }
-                });
+                this.btnsSave.setDisabled(false);
                 Common.Gateway.collaborativeChanges();
             },
 
@@ -1575,11 +1530,7 @@ define([
                         if (this.synchTooltip)
                             this.synchTooltip.hide();
                         this.btnSave.updateHint(this.btnSaveTip);
-                        this.btnsSave.forEach(function(button) {
-                            if ( button ) {
-                                button.setDisabled(!me.mode.forcesave);
-                            }
-                        });
+                        this.btnsSave.setDisabled(!me.mode.forcesave);
 
                         this._state.hasCollaborativeChanges = false;
                     }
diff --git a/apps/spreadsheeteditor/main/app/view/Toolbar.js b/apps/spreadsheeteditor/main/app/view/Toolbar.js
index 95a1dc88b..24c851321 100644
--- a/apps/spreadsheeteditor/main/app/view/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/view/Toolbar.js
@@ -372,7 +372,7 @@ define([
                     cls         : 'btn-toolbar',
                     iconCls     : 'no-mask ' + me.btnSaveCls
                 });
-                me.btnsSave = [me.btnSave];
+                me.btnsSave = createButtonSet(me.btnSave);
 
                 me.btnIncFontSize = new Common.UI.Button({
                     id          : 'id-toolbar-btn-incfont',
@@ -1709,13 +1709,11 @@ define([
 
             var btnsave = SSE.getController('LeftMenu').getView('LeftMenu').getMenu('file').getButton('save');
             if (btnsave && this.btnsSave) {
-                this.btnsSave.push(btnsave);
-                btnsave.setDisabled(this.btnsSave[0].isDisabled());
+                this.btnsSave.add(btnsave);
             }
             btnsave = SSE.getController('Viewport').getView('Common.Views.Header').getButton('save');
             if (btnsave && this.btnsSave) {
-                this.btnsSave.push(btnsave);
-                btnsave.setDisabled(this.btnsSave[0].isDisabled());
+                this.btnsSave.add(btnsave);
             }
         },
 
@@ -1853,11 +1851,7 @@ define([
                 this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
             }
 
-            this.btnsSave.forEach(function(button) {
-                if ( button ) {
-                    button.setDisabled(false);
-                }
-            });
+            this.btnsSave.setDisabled(false);
             Common.Gateway.collaborativeChanges();
         },
 
@@ -1888,11 +1882,7 @@ define([
                     if (this.synchTooltip)
                         this.synchTooltip.hide();
                     this.btnSave.updateHint(this.btnSaveTip);
-                    this.btnsSave.forEach(function(button) {
-                        if ( button ) {
-                            button.setDisabled(!me.mode.forcesave);
-                        }
-                    });
+                    this.btnsSave.setDisabled(!me.mode.forcesave);
 
                     this._state.hasCollaborativeChanges = false;
                 }

From 6d385730b197f3305a4095eb0206d6215879b5c1 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Fri, 16 Feb 2018 02:46:45 +0300
Subject: [PATCH 16/41] [Common] make created buttons disabled

---
 apps/common/main/lib/view/Header.js | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js
index 083b94536..a77543b9d 100644
--- a/apps/common/main/lib/view/Header.js
+++ b/apps/common/main/lib/view/Header.js
@@ -408,10 +408,11 @@ define([
             getPanel: function (role, config) {
                 var me = this;
 
-                function createTitleButton(iconid, slot) {
+                function createTitleButton(iconid, slot, disabled) {
                     return (new Common.UI.Button({
                         cls: 'btn-header',
-                        iconCls: 'svgicon ' + iconid
+                        iconCls: 'svgicon ' + iconid,
+                        disabled: disabled === true
                     })).render(slot);
                 }
 
@@ -493,9 +494,9 @@ define([
                         me.btnPrint = createTitleButton('svg-btn-print', $('#slot-btn-dt-print', $html));
                     }
 
-                    me.btnSave = createTitleButton('svg-btn-save', $('#slot-btn-dt-save', $html));
-                    me.btnUndo = createTitleButton('svg-btn-undo', $('#slot-btn-dt-undo', $html));
-                    me.btnRedo = createTitleButton('svg-btn-redo', $('#slot-btn-dt-redo', $html));
+                    me.btnSave = createTitleButton('svg-btn-save', $('#slot-btn-dt-save', $html), true);
+                    me.btnUndo = createTitleButton('svg-btn-undo', $('#slot-btn-dt-undo', $html), true);
+                    me.btnRedo = createTitleButton('svg-btn-redo', $('#slot-btn-dt-redo', $html), true);
 
                     return $html;
                 }

From cb82ea8230b0dfa202153383606a1f6b284612bb Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Fri, 16 Feb 2018 02:52:44 +0300
Subject: [PATCH 17/41] [DE PE] refactoring

---
 apps/documenteditor/main/app/controller/Main.js     | 4 +---
 apps/documenteditor/main/app/controller/Toolbar.js  | 2 +-
 apps/presentationeditor/main/app/controller/Main.js | 9 +++------
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js
index 4f46209dd..63cd85a79 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -1543,9 +1543,7 @@ define([
                 /** coauthoring end **/
             },
             onDocumentCanSaveChanged: function (isCanSave) {
-                var application = this.getApplication(),
-                    toolbarController = application.getController('Toolbar'),
-                    toolbarView = toolbarController.getView();
+                var toolbarView = this.getApplication().getController('Toolbar').getView();
 
                 if (toolbarView && this.api && !toolbarView._state.previewmode) {
                     var isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js
index b50f5e651..3f82fca07 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -2762,7 +2762,7 @@ define([
                     // hide 'print' and 'save' buttons group and next separator
                     me.toolbar.btnPrint.$el.parents('.group').hide().next().hide();
 
-                    // hide 'undo' and 'redo' buttons and get container
+                    // hide 'undo' and 'redo' buttons and retrieve parent container
                     var $box =  me.toolbar.btnUndo.$el.hide().next().hide().parent();
 
                     // move 'paste' button to the container instead of 'undo' and 'redo'
diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js
index a248695e2..e33d95aa6 100644
--- a/apps/presentationeditor/main/app/controller/Main.js
+++ b/apps/presentationeditor/main/app/controller/Main.js
@@ -409,8 +409,7 @@ define([
 
             onEditComplete: function(cmp) {
                 var application = this.getApplication(),
-                    toolbarController = application.getController('Toolbar'),
-                    toolbarView = toolbarController.getView('Toolbar');
+                    toolbarView = application.getController('Toolbar').getView('Toolbar');
 
                 application.getController('DocumentHolder').getView('DocumentHolder').focus();
                 if (this.api && this.api.asc_isDocumentCanSave) {
@@ -1281,10 +1280,8 @@ define([
                 }
             },
             onDocumentCanSaveChanged: function (isCanSave) {
-                var application = this.getApplication(),
-                    toolbarController = application.getController('Toolbar'),
-                    toolbarView = toolbarController.getView('Toolbar');
-                if (toolbarView) {
+                var toolbarView = this.getApplication().getController('Toolbar').getView('Toolbar');
+                if ( toolbarView ) {
                     var isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
                         forcesave = this.appOptions.forcesave,
                         isDisabled = !isCanSave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave;

From 5f1b2918861f7c41641effe390b36f19f3e9233f Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Fri, 16 Feb 2018 02:56:17 +0300
Subject: [PATCH 18/41] [DE][PE][SSE] synchronize extra buttons state through
 events

---
 apps/common/main/lib/component/Button.js      |  7 +++++
 .../main/app/controller/LeftMenu.js           |  7 ++++-
 .../main/app/controller/Main.js               | 21 ++------------
 .../main/app/controller/Toolbar.js            | 14 ++++++++--
 .../main/app/controller/Viewport.js           | 12 ++++++++
 apps/documenteditor/main/app/view/Toolbar.js  | 28 ++++++-------------
 .../main/app/controller/LeftMenu.js           |  8 +++++-
 .../main/app/controller/Main.js               | 21 ++------------
 .../main/app/controller/Toolbar.js            | 17 +++++++++--
 .../main/app/controller/Viewport.js           | 13 +++++++++
 .../main/app/view/Toolbar.js                  | 25 ++++++-----------
 .../main/app/controller/LeftMenu.js           |  7 ++++-
 .../main/app/controller/Main.js               | 14 ++--------
 .../main/app/controller/Toolbar.js            | 13 +++++++++
 .../main/app/controller/Viewport.js           | 12 ++++++++
 .../main/app/view/Toolbar.js                  | 27 ++++++------------
 16 files changed, 136 insertions(+), 110 deletions(-)

diff --git a/apps/common/main/lib/component/Button.js b/apps/common/main/lib/component/Button.js
index 013f7f78e..2315c167a 100644
--- a/apps/common/main/lib/component/Button.js
+++ b/apps/common/main/lib/component/Button.js
@@ -595,6 +595,13 @@ define([
                         }
                     }
                 }
+
+                if ( !!me.options.signals ) {
+                    var opts = me.options.signals;
+                    if ( !(opts.indexOf('disabled') < 0) ) {
+                        me.trigger('disabled', me, disabled);
+                    }
+                }
             }
 
             this.disabled = disabled;
diff --git a/apps/documenteditor/main/app/controller/LeftMenu.js b/apps/documenteditor/main/app/controller/LeftMenu.js
index 2180cc6f9..06bf7e080 100644
--- a/apps/documenteditor/main/app/controller/LeftMenu.js
+++ b/apps/documenteditor/main/app/controller/LeftMenu.js
@@ -91,7 +91,8 @@ define([
                 'Toolbar': {
                     'file:settings': _.bind(this.clickToolbarSettings,this),
                     'file:open': this.clickToolbarTab.bind(this, 'file'),
-                    'file:close': this.clickToolbarTab.bind(this, 'other')
+                    'file:close': this.clickToolbarTab.bind(this, 'other'),
+                    'save:disabled': this.changeToolbarSaveState.bind(this)
                 },
                 'SearchDialog': {
                     'hide': _.bind(this.onSearchDlgHide, this),
@@ -398,6 +399,10 @@ define([
                 this.leftMenu.menuFile.hide();
         },
 
+        changeToolbarSaveState: function (state) {
+            this.leftMenu.menuFile.getButton('save').setDisabled(state);
+        },
+
         /** coauthoring begin **/
         clickStatusbarUsers: function() {
             this.leftMenu.menuFile.panels['rights'].changeAccessRights();
diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js
index 63cd85a79..5e0e20d50 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -622,12 +622,7 @@ define([
                         forcesave = this.appOptions.forcesave,
                         isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
                         isDisabled = !cansave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave;
-                    if (toolbarView.btnSave.isDisabled() !== isDisabled)
-                        toolbarView.btnsSave.forEach(function(button) {
-                            if ( button ) {
-                                button.setDisabled(isDisabled);
-                            }
-                        });
+                        toolbarView.btnSave.setDisabled(isDisabled);
                 }
             },
 
@@ -1528,12 +1523,7 @@ define([
                     var isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
                         forcesave = this.appOptions.forcesave,
                         isDisabled = !isModified && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave;
-                    if (toolbarView.btnSave.isDisabled() !== isDisabled)
-                        toolbarView.btnsSave.forEach(function(button) {
-                            if ( button ) {
-                                button.setDisabled(isDisabled);
-                            }
-                        });
+                        toolbarView.btnSave.setDisabled(isDisabled);
                 }
 
                 /** coauthoring begin **/
@@ -1549,12 +1539,7 @@ define([
                     var isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
                         forcesave = this.appOptions.forcesave,
                         isDisabled = !isCanSave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave;
-                    if (toolbarView.btnSave.isDisabled() !== isDisabled)
-                        toolbarView.btnsSave.forEach(function(button) {
-                            if ( button ) {
-                                button.setDisabled(isDisabled);
-                            }
-                        });
+                        toolbarView.btnSave.setDisabled(isDisabled);
                 }
             },
 
diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js
index 3f82fca07..1611b09fa 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -231,8 +231,11 @@ define([
 
             toolbar.btnPrint.on('click',                                _.bind(this.onPrint, this));
             toolbar.btnSave.on('click',                                 _.bind(this.onSave, this));
+            toolbar.btnSave.on('disabled',                              _.bind(this.onBtnChangeState, this, 'save:disabled'));
             toolbar.btnUndo.on('click',                                 _.bind(this.onUndo, this));
+            toolbar.btnUndo.on('disabled',                              _.bind(this.onBtnChangeState, this, 'undo:disabled'));
             toolbar.btnRedo.on('click',                                 _.bind(this.onRedo, this));
+            toolbar.btnRedo.on('disabled',                              _.bind(this.onBtnChangeState, this, 'redo:disabled'));
             toolbar.btnCopy.on('click',                                 _.bind(this.onCopyPaste, this, true));
             toolbar.btnPaste.on('click',                                _.bind(this.onCopyPaste, this, false));
             toolbar.btnIncFontSize.on('click',                          _.bind(this.onIncrease, this));
@@ -920,7 +923,7 @@ define([
                 this.api.asc_Save();
             }
 
-            toolbar.btnsSave.setDisabled(!toolbar.mode.forcesave);
+            toolbar.btnSave.setDisabled(!toolbar.mode.forcesave);
 
             Common.NotificationCenter.trigger('edit:complete', toolbar);
 
@@ -928,6 +931,13 @@ define([
             Common.component.Analytics.trackEvent('ToolBar', 'Save');
         },
 
+        onBtnChangeState: function(prop) {
+            if ( /\:disabled$/.test(prop) ) {
+                var _is_disabled = arguments[2];
+                this.toolbar.fireEvent(prop, [_is_disabled]);
+            }
+        },
+
         onUndo: function(btn, e) {
             if (this.api)
                 this.api.Undo();
@@ -2701,7 +2711,7 @@ define([
 
             toolbar._state.previewmode = reviewmode && disable;
             if (reviewmode) {
-                toolbar._state.previewmode && toolbar.btnsSave.setDisabled(true);
+                toolbar._state.previewmode && toolbar.btnSave.setDisabled(true);
 
                 if (toolbar.needShowSynchTip) {
                     toolbar.needShowSynchTip = false;
diff --git a/apps/documenteditor/main/app/controller/Viewport.js b/apps/documenteditor/main/app/controller/Viewport.js
index 98281ba0a..83097ded2 100644
--- a/apps/documenteditor/main/app/controller/Viewport.js
+++ b/apps/documenteditor/main/app/controller/Viewport.js
@@ -77,6 +77,18 @@ define([
                     'view:compact'  : function (toolbar, state) {
                         me.viewport.vlayout.getItem('toolbar').height = state ?
                                 Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
+                    },
+                    'undo:disabled' : function (state) {
+                        if ( me.header.btnUndo )
+                            me.header.btnUndo.setDisabled(state);
+                    },
+                    'redo:disabled' : function (state) {
+                        if ( me.header.btnRedo )
+                            me.header.btnRedo.setDisabled(state);
+                    },
+                    'save:disabled' : function (state) {
+                        if ( me.header.btnSave )
+                            me.header.btnSave.setDisabled(state);
                     }
                 }
             });
diff --git a/apps/documenteditor/main/app/view/Toolbar.js b/apps/documenteditor/main/app/view/Toolbar.js
index 4fecc3cd1..6125c2e9d 100644
--- a/apps/documenteditor/main/app/view/Toolbar.js
+++ b/apps/documenteditor/main/app/view/Toolbar.js
@@ -120,22 +120,24 @@ define([
                 this.btnSave = new Common.UI.Button({
                     id: 'id-toolbar-btn-save',
                     cls: 'btn-toolbar',
-                    iconCls: 'no-mask ' + this.btnSaveCls
+                    iconCls: 'no-mask ' + this.btnSaveCls,
+                    signals: ['disabled']
                 });
                 this.toolbarControls.push(this.btnSave);
-                me.btnsSave = createButtonSet( me.btnSave );
 
                 this.btnUndo = new Common.UI.Button({
                     id: 'id-toolbar-btn-undo',
                     cls: 'btn-toolbar',
-                    iconCls: 'btn-undo'
+                    iconCls: 'btn-undo',
+                    signals: ['disabled']
                 });
                 this.toolbarControls.push(this.btnUndo);
 
                 this.btnRedo = new Common.UI.Button({
                     id: 'id-toolbar-btn-redo',
                     cls: 'btn-toolbar',
-                    iconCls: 'btn-redo'
+                    iconCls: 'btn-redo',
+                    signals: ['disabled']
                 });
                 this.toolbarControls.push(this.btnRedo);
 
@@ -1957,18 +1959,6 @@ define([
                     maxRows: 8,
                     maxColumns: 10
                 });
-
-                var btnsave = DE.getController('LeftMenu').getView('LeftMenu').getMenu('file').getButton('save');
-                if (btnsave && this.btnsSave) {
-                    this.btnsSave.add(btnsave);
-                    this.toolbarControls.push(btnsave);
-                }
-
-                btnsave = DE.getController('Viewport').getView('Common.Views.Header').getButton('save');
-                if (btnsave && this.btnsSave) {
-                    this.btnsSave.add(btnsave);
-                    this.toolbarControls.push(btnsave);
-                }
             },
 
             onToolbarAfterRender: function(toolbar) {
@@ -2052,7 +2042,7 @@ define([
 
             setMode: function (mode) {
                 if (mode.isDisconnected) {
-                    this.btnsSave.setDisabled(true);
+                    this.btnSave.setDisabled(true);
                     if (mode.disableDownload)
                         this.btnPrint.setDisabled(true);
                 }
@@ -2143,7 +2133,7 @@ define([
                     this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                 }
 
-                this.btnsSave.setDisabled(false);
+                this.btnSave.setDisabled(false);
                 Common.Gateway.collaborativeChanges();
             },
 
@@ -2174,7 +2164,7 @@ define([
                         if (this.synchTooltip)
                             this.synchTooltip.hide();
                         this.btnSave.updateHint(this.btnSaveTip);
-                        this.btnsSave.setDisabled(!me.mode.forcesave);
+                        this.btnSave.setDisabled(!me.mode.forcesave);
                         this._state.hasCollaborativeChanges = false;
                     }
                 }
diff --git a/apps/presentationeditor/main/app/controller/LeftMenu.js b/apps/presentationeditor/main/app/controller/LeftMenu.js
index 3590306ae..81aa86c15 100644
--- a/apps/presentationeditor/main/app/controller/LeftMenu.js
+++ b/apps/presentationeditor/main/app/controller/LeftMenu.js
@@ -89,7 +89,8 @@ define([
                 'Toolbar': {
                     'file:settings': _.bind(this.clickToolbarSettings,this),
                     'file:open': this.clickToolbarTab.bind(this, 'file'),
-                    'file:close': this.clickToolbarTab.bind(this, 'other')
+                    'file:close': this.clickToolbarTab.bind(this, 'other'),
+                    'save:disabled' : this.changeToolbarSaveState.bind(this)
                 },
                 'SearchDialog': {
                     'hide': _.bind(this.onSearchDlgHide, this),
@@ -311,6 +312,11 @@ define([
                 this.leftMenu.menuFile.hide();
         },
 
+        changeToolbarSaveState: function (state) {
+            this.leftMenu.menuFile.getButton('save').setDisabled(state);
+            console.log('save: ' + state);
+        },
+
         /** coauthoring begin **/
         clickStatusbarUsers: function() {
             this.leftMenu.menuFile.panels['rights'].changeAccessRights();
diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js
index e33d95aa6..150a04afa 100644
--- a/apps/presentationeditor/main/app/controller/Main.js
+++ b/apps/presentationeditor/main/app/controller/Main.js
@@ -417,12 +417,7 @@ define([
                         forcesave = this.appOptions.forcesave,
                         isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
                         isDisabled = !cansave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave;
-                    if (toolbarView.btnSave.isDisabled() !== isDisabled)
-                        toolbarView.btnsSave.forEach(function(button) {
-                            if ( button ) {
-                                button.setDisabled(isDisabled);
-                            }
-                        });
+                        toolbarView.btnSave.setDisabled(isDisabled);
                 }
             },
 
@@ -1271,12 +1266,7 @@ define([
                     var isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
                         forcesave = this.appOptions.forcesave,
                         isDisabled = !isModified && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave;
-                    if (toolbarView.btnSave.isDisabled() !== isDisabled)
-                        toolbarView.btnsSave.forEach(function(button) {
-                            if ( button ) {
-                                button.setDisabled(isDisabled);
-                            }
-                        });
+                        toolbarView.btnSave.setDisabled(isDisabled);
                 }
             },
             onDocumentCanSaveChanged: function (isCanSave) {
@@ -1285,12 +1275,7 @@ define([
                     var isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
                         forcesave = this.appOptions.forcesave,
                         isDisabled = !isCanSave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave;
-                    if (toolbarView.btnSave.isDisabled() !== isDisabled)
-                        toolbarView.btnsSave.forEach(function(button) {
-                            if ( button ) {
-                                button.setDisabled(isDisabled);
-                            }
-                        });
+                        toolbarView.btnSave.setDisabled(isDisabled);
                 }
             },
 
diff --git a/apps/presentationeditor/main/app/controller/Toolbar.js b/apps/presentationeditor/main/app/controller/Toolbar.js
index cdd8f02e6..4099bc566 100644
--- a/apps/presentationeditor/main/app/controller/Toolbar.js
+++ b/apps/presentationeditor/main/app/controller/Toolbar.js
@@ -217,10 +217,14 @@ define([
         },
 
         onLaunch: function() {
-            // Create toolbar view
-            this.toolbar = this.createView('Toolbar');
-
             var me = this;
+
+            // Create toolbar view
+            me.toolbar = me.createView('Toolbar');
+            me.toolbar.btnSave.on('disabled', _.bind(this.onBtnChangeState, this, 'save:disabled'));
+            me.toolbar.btnUndo.on('disabled', _.bind(this.onBtnChangeState, this, 'undo:disabled'));
+            me.toolbar.btnRedo.on('disabled', _.bind(this.onBtnChangeState, this, 'redo:disabled'));
+
             Common.NotificationCenter.on('app:ready', me.onAppReady.bind(me));
             Common.NotificationCenter.on('app:face', me.onAppShowed.bind(me));
 
@@ -922,6 +926,13 @@ define([
             Common.component.Analytics.trackEvent('ToolBar', 'Save');
         },
 
+        onBtnChangeState: function(prop) {
+            if ( /\:disabled$/.test(prop) ) {
+                var _is_disabled = arguments[2];
+                this.toolbar.fireEvent(prop, [_is_disabled]);
+            }
+        },
+
         onUndo: function(btn, e) {
             if (this.api) {
                 this.api.Undo();
diff --git a/apps/presentationeditor/main/app/controller/Viewport.js b/apps/presentationeditor/main/app/controller/Viewport.js
index 046d7550b..298096677 100644
--- a/apps/presentationeditor/main/app/controller/Viewport.js
+++ b/apps/presentationeditor/main/app/controller/Viewport.js
@@ -78,6 +78,19 @@ define([
                     'view:compact'  : function (toolbar, state) {
                         me.viewport.vlayout.getItem('toolbar').height = state ?
                             Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
+                    },
+                    'undo:disabled' : function (state) {
+                        if ( me.header.btnUndo )
+                            me.header.btnUndo.setDisabled(state);
+                    },
+                    'redo:disabled' : function (state) {
+                        if ( me.header.btnRedo )
+                            me.header.btnRedo.setDisabled(state);
+                    },
+                    'save:disabled' : function (state) {
+                        if ( me.header.btnSave )
+                            me.header.btnSave.setDisabled(state);
+                        console.log('header save: ' + state);
                     }
                 },
                 // Events generated by main view
diff --git a/apps/presentationeditor/main/app/view/Toolbar.js b/apps/presentationeditor/main/app/view/Toolbar.js
index 6bb2695e6..fd1afe929 100644
--- a/apps/presentationeditor/main/app/view/Toolbar.js
+++ b/apps/presentationeditor/main/app/view/Toolbar.js
@@ -170,15 +170,16 @@ define([
                     id          : 'id-toolbar-btn-save',
                     cls         : 'btn-toolbar',
                     iconCls     : 'no-mask ' + me.btnSaveCls,
-                    lock        : [_set.lostConnect]
+                    lock        : [_set.lostConnect],
+                    signals     : ['disabled']
                 });
-                me.btnsSave = createButtonSet(me.btnSave);
 
                 me.btnUndo = new Common.UI.Button({
                     id          : 'id-toolbar-btn-undo',
                     cls         : 'btn-toolbar',
                     iconCls     : 'btn-undo',
-                    lock        : [_set.undoLock, _set.slideDeleted, _set.lostConnect, _set.disableOnStart]
+                    lock        : [_set.undoLock, _set.slideDeleted, _set.lostConnect, _set.disableOnStart],
+                    signals     : ['disabled']
                 });
                 me.slideOnlyControls.push(me.btnUndo);
 
@@ -186,7 +187,8 @@ define([
                     id          : 'id-toolbar-btn-redo',
                     cls         : 'btn-toolbar',
                     iconCls     : 'btn-redo',
-                    lock        : [_set.redoLock, _set.slideDeleted, _set.lostConnect, _set.disableOnStart]
+                    lock        : [_set.redoLock, _set.slideDeleted, _set.lostConnect, _set.disableOnStart],
+                    signals     : ['disabled']
                 });
                 me.slideOnlyControls.push(me.btnRedo);
 
@@ -1340,17 +1342,6 @@ define([
 //            // Enable none paragraph components
                 this.lockToolbar(PE.enumLock.disableOnStart, false, {array: this.slideOnlyControls.concat(this.shapeControls)});
 
-                var btnsave = PE.getController('LeftMenu').getView('LeftMenu').getMenu('file').getButton('save');
-                if (btnsave && this.btnsSave) {
-                    this.btnsSave.add(btnsave);
-                    this.lockControls.push(btnsave);
-                }
-                btnsave = PE.getController('Viewport').getView('Common.Views.Header').getButton('save');
-                if (btnsave && this.btnsSave) {
-                    this.btnsSave.add(btnsave);
-                    this.lockControls.push(btnsave);
-                }
-
                 /** coauthoring begin **/
                 this.showSynchTip = !Common.localStorage.getBool('pe-hide-synch');
                 this.needShowSynchTip = false;
@@ -1499,7 +1490,7 @@ define([
                     this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                 }
 
-                this.btnsSave.setDisabled(false);
+                this.btnSave.setDisabled(false);
                 Common.Gateway.collaborativeChanges();
             },
 
@@ -1530,7 +1521,7 @@ define([
                         if (this.synchTooltip)
                             this.synchTooltip.hide();
                         this.btnSave.updateHint(this.btnSaveTip);
-                        this.btnsSave.setDisabled(!me.mode.forcesave);
+                        this.btnSave.setDisabled(!me.mode.forcesave);
 
                         this._state.hasCollaborativeChanges = false;
                     }
diff --git a/apps/spreadsheeteditor/main/app/controller/LeftMenu.js b/apps/spreadsheeteditor/main/app/controller/LeftMenu.js
index d64fe5f54..bb40abea2 100644
--- a/apps/spreadsheeteditor/main/app/controller/LeftMenu.js
+++ b/apps/spreadsheeteditor/main/app/controller/LeftMenu.js
@@ -79,7 +79,8 @@ define([
                 'Toolbar': {
                     'file:settings': _.bind(this.clickToolbarSettings,this),
                     'file:open': this.clickToolbarTab.bind(this, 'file'),
-                    'file:close': this.clickToolbarTab.bind(this, 'other')
+                    'file:close': this.clickToolbarTab.bind(this, 'other'),
+                    'save:disabled' : this.changeToolbarSaveState.bind(this)
                 },
                 'SearchDialog': {
                     'hide': _.bind(this.onSearchDlgHide, this),
@@ -348,6 +349,10 @@ define([
                 this.leftMenu.menuFile.hide();
         },
 
+        changeToolbarSaveState: function (state) {
+            this.leftMenu.menuFile.getButton('save').setDisabled(state);
+        },
+
         /** coauthoring begin **/
         clickStatusbarUsers: function() {
             this.leftMenu.menuFile.panels['rights'].changeAccessRights();
diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js
index 2d1744f0e..9d5505a6d 100644
--- a/apps/spreadsheeteditor/main/app/controller/Main.js
+++ b/apps/spreadsheeteditor/main/app/controller/Main.js
@@ -1417,12 +1417,7 @@ define([
                         forcesave = this.appOptions.forcesave,
                         cansave = this.api.asc_isDocumentCanSave(),
                         isDisabled = !cansave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave;
-                    if (this.toolbarView.btnSave.isDisabled() !== isDisabled)
-                        this.toolbarView.btnsSave.forEach(function(button) {
-                            if ( button ) {
-                                button.setDisabled(isDisabled);
-                            }
-                        });
+                        this.toolbarView.btnSave.setDisabled(isDisabled);
                 }
             },
 
@@ -1431,12 +1426,7 @@ define([
                     var isSyncButton = $('.icon', this.toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
                         forcesave = this.appOptions.forcesave,
                         isDisabled = !isCanSave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave;
-                    if (this.toolbarView.btnSave.isDisabled() !== isDisabled)
-                        this.toolbarView.btnsSave.forEach(function(button) {
-                            if ( button ) {
-                                button.setDisabled(isDisabled);
-                            }
-                        });
+                    this.toolbarView.btnSave.setDisabled(isDisabled);
                 }
             },
 
diff --git a/apps/spreadsheeteditor/main/app/controller/Toolbar.js b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
index 0f6d1d44a..f1474829c 100644
--- a/apps/spreadsheeteditor/main/app/controller/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
@@ -247,8 +247,11 @@ define([
             } else {
                 toolbar.btnPrint.on('click',                                _.bind(this.onPrint, this));
                 toolbar.btnSave.on('click',                                 _.bind(this.onSave, this));
+                toolbar.btnSave.on('disabled',                              _.bind(this.onBtnChangeState, this, 'save:disabled'));
                 toolbar.btnUndo.on('click',                                 _.bind(this.onUndo, this));
+                toolbar.btnUndo.on('disabled',                              _.bind(this.onBtnChangeState, this, 'undo:disabled'));
                 toolbar.btnRedo.on('click',                                 _.bind(this.onRedo, this));
+                toolbar.btnRedo.on('disabled',                              _.bind(this.onBtnChangeState, this, 'redo:disabled'));
                 toolbar.btnCopy.on('click',                                 _.bind(this.onCopyPaste, this, true));
                 toolbar.btnPaste.on('click',                                _.bind(this.onCopyPaste, this, false));
                 toolbar.btnIncFontSize.on('click',                          _.bind(this.onIncreaseFontSize, this));
@@ -396,6 +399,13 @@ define([
             Common.component.Analytics.trackEvent('ToolBar', 'Save');
         },
 
+        onBtnChangeState: function(prop) {
+            if ( /\:disabled$/.test(prop) ) {
+                var _is_disabled = arguments[2];
+                this.toolbar.fireEvent(prop, [_is_disabled]);
+            }
+        },
+
         onUndo: function(btn, e) {
             if (this.api)
                 this.api.asc_Undo();
@@ -3039,6 +3049,9 @@ define([
                 me.toolbar.setMode(config);
 
                 if ( config.isEdit ) {
+                    me.toolbar.btnSave && me.toolbar.btnSave.on('disabled', _.bind(me.onBtnChangeState, me, 'save:disabled'));
+                    me.toolbar.btnUndo && me.toolbar.btnUndo.on('disabled', _.bind(me.onBtnChangeState, me, 'undo:disabled'));
+                    me.toolbar.btnRedo && me.toolbar.btnRedo.on('disabled', _.bind(me.onBtnChangeState, me, 'redo:disabled'));
                     me.toolbar.setApi(me.api);
 
                     if ( !config.isEditDiagram && !config.isEditMailMerge ) {
diff --git a/apps/spreadsheeteditor/main/app/controller/Viewport.js b/apps/spreadsheeteditor/main/app/controller/Viewport.js
index dd05bf1ed..dadd49ec1 100644
--- a/apps/spreadsheeteditor/main/app/controller/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/controller/Viewport.js
@@ -76,6 +76,18 @@ define([
                     'view:compact'  : function (toolbar, state) {
                         me.viewport.vlayout.getItem('toolbar').height = state ?
                             Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
+                    },
+                    'undo:disabled' : function (state) {
+                        if ( me.header.btnUndo )
+                            me.header.btnUndo.setDisabled(state);
+                    },
+                    'redo:disabled' : function (state) {
+                        if ( me.header.btnRedo )
+                            me.header.btnRedo.setDisabled(state);
+                    },
+                    'save:disabled' : function (state) {
+                        if ( me.header.btnSave )
+                            me.header.btnSave.setDisabled(state);
                     }
                 }
             });
diff --git a/apps/spreadsheeteditor/main/app/view/Toolbar.js b/apps/spreadsheeteditor/main/app/view/Toolbar.js
index 24c851321..f627aafb7 100644
--- a/apps/spreadsheeteditor/main/app/view/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/view/Toolbar.js
@@ -157,7 +157,8 @@ define([
                 cls         : 'btn-toolbar',
                 iconCls     : 'btn-undo',
                 disabled    : true,
-                lock        : [_set.lostConnect]
+                lock        : [_set.lostConnect],
+                signals     : ['disabled']
             });
 
             me.btnRedo = new Common.UI.Button({
@@ -165,7 +166,8 @@ define([
                 cls         : 'btn-toolbar',
                 iconCls     : 'btn-redo',
                 disabled    : true,
-                lock        : [_set.lostConnect]
+                lock        : [_set.lostConnect],
+                signals     : ['disabled']
             });
 
             return this;
@@ -370,9 +372,9 @@ define([
                 me.btnSave = new Common.UI.Button({
                     id          : 'id-toolbar-btn-save',
                     cls         : 'btn-toolbar',
-                    iconCls     : 'no-mask ' + me.btnSaveCls
+                    iconCls     : 'no-mask ' + me.btnSaveCls,
+                    signals     : ['disabled']
                 });
-                me.btnsSave = createButtonSet(me.btnSave);
 
                 me.btnIncFontSize = new Common.UI.Button({
                     id          : 'id-toolbar-btn-incfont',
@@ -1233,7 +1235,7 @@ define([
                 me.cmbNumberFormat, me.btnBorders, me.btnInsertImage, me.btnInsertHyperlink,
                 me.btnInsertChart, me.btnColorSchemas,
                 me.btnAutofilter, me.btnCopy, me.btnPaste, me.btnSettings, me.listStyles, me.btnPrint, me.btnShowMode,
-                /*me.btnSave, */me.btnClearStyle, me.btnCopyStyle
+                me.btnSave, me.btnClearStyle, me.btnCopyStyle
             ];
 
             var _temp_array = [me.cmbFontName, me.cmbFontSize, me.btnAlignLeft,me.btnAlignCenter,me.btnAlignRight,me.btnAlignJust,me.btnAlignTop,
@@ -1706,15 +1708,6 @@ define([
                     itemTemplate: _.template('<div id="<%= id %>" class="item-chartlist <%= iconCls %>"></div>')
                 });
             }
-
-            var btnsave = SSE.getController('LeftMenu').getView('LeftMenu').getMenu('file').getButton('save');
-            if (btnsave && this.btnsSave) {
-                this.btnsSave.add(btnsave);
-            }
-            btnsave = SSE.getController('Viewport').getView('Common.Views.Header').getButton('save');
-            if (btnsave && this.btnsSave) {
-                this.btnsSave.add(btnsave);
-            }
         },
 
         onToolbarAfterRender: function(toolbar) {
@@ -1758,8 +1751,6 @@ define([
                 this.lockToolbar( SSE.enumLock.lostConnect, true );
                 this.lockToolbar( SSE.enumLock.lostConnect, true,
                     {array:[this.btnEditChart,this.btnUndo,this.btnRedo]} );
-                this.lockToolbar( SSE.enumLock.lostConnect, true,
-                    {array:this.btnsSave} );
                 this.lockToolbar(SSE.enumLock.cantPrint, !mode.canPrint || mode.disableDownload, {array: [this.btnPrint]});
             } else {
                 this.mode = mode;
@@ -1851,7 +1842,7 @@ define([
                 this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
             }
 
-            this.btnsSave.setDisabled(false);
+            this.btnSave.setDisabled(false);
             Common.Gateway.collaborativeChanges();
         },
 
@@ -1882,7 +1873,7 @@ define([
                     if (this.synchTooltip)
                         this.synchTooltip.hide();
                     this.btnSave.updateHint(this.btnSaveTip);
-                    this.btnsSave.setDisabled(!me.mode.forcesave);
+                    this.btnSave.setDisabled(!me.mode.forcesave);
 
                     this._state.hasCollaborativeChanges = false;
                 }

From dcd1589adc65d36abb8207b313caf65752f413bc Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Thu, 22 Feb 2018 02:23:32 +0300
Subject: [PATCH 19/41] [common] added 'Desktop' controller

---
 apps/api/documents/index.html.desktop         |  4 +-
 apps/common/main/lib/controller/Desktop.js    | 77 +++++++++++++++++++
 apps/documenteditor/main/app.js               |  1 +
 .../main/app/controller/Main.js               |  8 +-
 apps/documenteditor/main/app_dev.js           |  1 +
 apps/documenteditor/main/index.html.deploy    |  4 +
 apps/presentationeditor/main/app.js           |  1 +
 .../main/app/controller/Main.js               |  7 +-
 apps/presentationeditor/main/app_dev.js       |  1 +
 .../presentationeditor/main/index.html.deploy |  4 +
 apps/spreadsheeteditor/main/app.js            |  1 +
 .../main/app/controller/Main.js               |  6 +-
 apps/spreadsheeteditor/main/app_dev.js        |  1 +
 apps/spreadsheeteditor/main/index.html.deploy |  4 +
 14 files changed, 104 insertions(+), 16 deletions(-)
 create mode 100644 apps/common/main/lib/controller/Desktop.js

diff --git a/apps/api/documents/index.html.desktop b/apps/api/documents/index.html.desktop
index 03edba6c1..28857deae 100644
--- a/apps/api/documents/index.html.desktop
+++ b/apps/api/documents/index.html.desktop
@@ -58,8 +58,6 @@
                 editorConfig: cfg,
                 events: {
                     onInternalMessage: onInternalMessage,
-                    onDocumentReady: onDocumentReady
-
                 }
             });
 
@@ -97,7 +95,7 @@
             function getEditorConfig(urlParams) {
                 return {
                     customization   : {
-                        goback: { url: "callback" }
+                        goback: { url: "onlyoffice.com" }
                     },
                     mode            : urlParams["mode"] || 'edit',
                     lang            : urlParams["lang"] || 'en',
diff --git a/apps/common/main/lib/controller/Desktop.js b/apps/common/main/lib/controller/Desktop.js
new file mode 100644
index 000000000..a395d131a
--- /dev/null
+++ b/apps/common/main/lib/controller/Desktop.js
@@ -0,0 +1,77 @@
+/*
+ *
+ * (c) Copyright Ascensio System Limited 2010-2018
+ *
+ * This program is a free software product. You can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License (AGPL)
+ * version 3 as published by the Free Software Foundation. In accordance with
+ * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
+ * that Ascensio System SIA expressly excludes the warranty of non-infringement
+ * of any third-party rights.
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
+ * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+ *
+ * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
+ * EU, LV-1021.
+ *
+ * The  interactive user interfaces in modified source and object code versions
+ * of the Program must display Appropriate Legal Notices, as required under
+ * Section 5 of the GNU AGPL version 3.
+ *
+ * Pursuant to Section 7(b) of the License you must retain the original Product
+ * logo when distributing the program. Pursuant to Section 7(e) we decline to
+ * grant you any rights under trademark law for use of our trademarks.
+ *
+ * All the Product's GUI elements, including illustrations and icon sets, as
+ * well as technical writing content are licensed under the terms of the
+ * Creative Commons Attribution-ShareAlike 4.0 International. See the License
+ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+ *
+ */
+/**
+ * Controller wraps up interaction with desktop app
+ *
+ * Created by Maxim.Kadushkin on 2/16/2018.
+ */
+
+define([
+    'core'
+], function () {
+    'use strict';
+
+    var Desktop = function () {
+        var config = {};
+        var app = window.AscDesktopEditor;
+
+        // if ( app ) {
+            // app.execCommand('doc:onload', '');
+        // }
+
+        return {
+            init: function (opts) {
+                _.extend(config, opts);
+
+                if ( config.isDesktopApp ) {
+                    Common.NotificationCenter.on('app:ready', function (config) {
+                        !!app && app.execCommand('doc:onready', '');
+                    });
+                }
+            },
+            process: function (opts) {
+                if ( opts == 'goback' ) {
+                    if ( config.isDesktopApp && !!app ) {
+                        app.execCommand('go:folder',
+                            config.isOffline ? 'offline' : config.customization.goback.url);
+                        return true;
+                    }
+
+                    return false;
+                }
+            }
+        };
+    };
+
+    Common.Controllers.Desktop = new Desktop();
+});
\ No newline at end of file
diff --git a/apps/documenteditor/main/app.js b/apps/documenteditor/main/app.js
index 1c13c3c9b..67777e15e 100644
--- a/apps/documenteditor/main/app.js
+++ b/apps/documenteditor/main/app.js
@@ -203,6 +203,7 @@ require([
         ,'common/main/lib/controller/ExternalMergeEditor'
         ,'common/main/lib/controller/ReviewChanges'
         ,'common/main/lib/controller/Protection'
+        ,'common/main/lib/controller/Desktop'
     ], function() {
         app.start();
     });
diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js
index 5e0e20d50..8e94441c9 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -314,6 +314,8 @@ define([
 
                 if (this.appOptions.location == 'us' || this.appOptions.location == 'ca')
                     Common.Utils.Metric.setDefaultMetric(Common.Utils.Metric.c_MetricUnits.inch);
+
+                Common.Controllers.Desktop.init(this.appOptions);
             },
 
             loadDocument: function(data) {
@@ -582,11 +584,7 @@ define([
             },
 
             goBack: function(blank) {
-                var me = this;
-                if ( me.appOptions.customization.goback.url == 'callback' ) {
-                    Common.Gateway.internalMessage( 'goback',
-                        {status: me.appOptions.isOffline ? 'offline' : 'online'} );
-                } else {
+                if ( !Common.Controllers.Desktop.process('goback') ) {
                     var href = this.appOptions.customization.goback.url;
                     if (blank) {
                         window.open(href, "_blank");
diff --git a/apps/documenteditor/main/app_dev.js b/apps/documenteditor/main/app_dev.js
index 9450b3f55..2648611ab 100644
--- a/apps/documenteditor/main/app_dev.js
+++ b/apps/documenteditor/main/app_dev.js
@@ -193,6 +193,7 @@ require([
         ,'common/main/lib/controller/ExternalMergeEditor'
         ,'common/main/lib/controller/ReviewChanges'
         ,'common/main/lib/controller/Protection'
+        ,'common/main/lib/controller/Desktop'
     ], function() {
         window.compareVersions = true;
         app.start();
diff --git a/apps/documenteditor/main/index.html.deploy b/apps/documenteditor/main/index.html.deploy
index 1feaf1eb7..eaeb02bfa 100644
--- a/apps/documenteditor/main/index.html.deploy
+++ b/apps/documenteditor/main/index.html.deploy
@@ -217,6 +217,10 @@
                     .replace(/>/g, '&gt;');
         }
 
+        if ( window.AscDesktopEditor ) {
+            window.AscDesktopEditor.execCommand('doc:onload', '');
+        }
+
         var params = getUrlParams(),
             lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
             customer = params["customer"] ? ('<div class="loader-page-text-customer">' + encodeUrlParam(params["customer"]) + '</div>') : '',
diff --git a/apps/presentationeditor/main/app.js b/apps/presentationeditor/main/app.js
index 88c9a9a38..330f222e6 100644
--- a/apps/presentationeditor/main/app.js
+++ b/apps/presentationeditor/main/app.js
@@ -190,6 +190,7 @@ require([
         'common/main/lib/controller/ExternalDiagramEditor'
         ,'common/main/lib/controller/ReviewChanges'
         ,'common/main/lib/controller/Protection'
+        ,'common/main/lib/controller/Desktop'
     ], function() {
         app.start();
     });
diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js
index 150a04afa..387287540 100644
--- a/apps/presentationeditor/main/app/controller/Main.js
+++ b/apps/presentationeditor/main/app/controller/Main.js
@@ -295,6 +295,8 @@ define([
 
                 if (this.appOptions.location == 'us' || this.appOptions.location == 'ca')
                     Common.Utils.Metric.setDefaultMetric(Common.Utils.Metric.c_MetricUnits.inch);
+
+                Common.Controllers.Desktop.init(this.appOptions);
             },
 
             loadDocument: function(data) {
@@ -394,10 +396,7 @@ define([
 
             goBack: function(blank) {
                 var me = this;
-                if ( me.appOptions.customization.goback.url == 'callback' ) {
-                    Common.Gateway.internalMessage( 'goback',
-                            {status: me.appOptions.isOffline ? 'offline' : 'online'} );
-                } else {
+                if ( !Common.Controllers.Desktop.process('goback') ) {
                     var href = me.appOptions.customization.goback.url;
                     if (blank) {
                         window.open(href, "_blank");
diff --git a/apps/presentationeditor/main/app_dev.js b/apps/presentationeditor/main/app_dev.js
index d23302912..f87f4a08d 100644
--- a/apps/presentationeditor/main/app_dev.js
+++ b/apps/presentationeditor/main/app_dev.js
@@ -181,6 +181,7 @@ require([
         'common/main/lib/controller/ExternalDiagramEditor'
         ,'common/main/lib/controller/ReviewChanges'
         ,'common/main/lib/controller/Protection'
+        ,'common/main/lib/controller/Desktop'
     ], function() {
         window.compareVersions = true;
         app.start();
diff --git a/apps/presentationeditor/main/index.html.deploy b/apps/presentationeditor/main/index.html.deploy
index a07952daa..cdb86c3cf 100644
--- a/apps/presentationeditor/main/index.html.deploy
+++ b/apps/presentationeditor/main/index.html.deploy
@@ -217,6 +217,10 @@
                     .replace(/>/g, '&gt;');
         }
 
+        if ( window.AscDesktopEditor ) {
+            window.AscDesktopEditor.execCommand('doc:onload', '');
+        }
+
         var params = getUrlParams(),
             lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
             customer = params["customer"] ? ('<div class="loader-page-text-customer">' + encodeUrlParam(params["customer"]) + '</div>') : '',
diff --git a/apps/spreadsheeteditor/main/app.js b/apps/spreadsheeteditor/main/app.js
index 6a342e504..13f09bb8f 100644
--- a/apps/spreadsheeteditor/main/app.js
+++ b/apps/spreadsheeteditor/main/app.js
@@ -196,6 +196,7 @@ require([
         'common/main/lib/controller/Plugins'
         ,'common/main/lib/controller/ReviewChanges'
         ,'common/main/lib/controller/Protection'
+        ,'common/main/lib/controller/Desktop'
     ], function() {
         app.start();
     });
diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js
index 9d5505a6d..e84b3f6aa 100644
--- a/apps/spreadsheeteditor/main/app/controller/Main.js
+++ b/apps/spreadsheeteditor/main/app/controller/Main.js
@@ -335,6 +335,7 @@ define([
                     Common.Utils.Metric.setDefaultMetric(Common.Utils.Metric.c_MetricUnits.inch);
 
                 this.isFrameClosed = (this.appOptions.isEditDiagram || this.appOptions.isEditMailMerge);
+                Common.Controllers.Desktop.init(this.appOptions);
             },
 
             loadDocument: function(data) {
@@ -429,10 +430,7 @@ define([
 
             goBack: function(blank) {
                 var me = this;
-                if ( me.appOptions.customization.goback.url == 'callback' ) {
-                    Common.Gateway.internalMessage( 'goback',
-                        {status: me.appOptions.isOffline ? 'offline' : 'online'} );
-                } else {
+                if ( !Common.Controllers.Desktop.process('goback') ) {
                     var href = me.appOptions.customization.goback.url;
                     if (blank) {
                         window.open(href, "_blank");
diff --git a/apps/spreadsheeteditor/main/app_dev.js b/apps/spreadsheeteditor/main/app_dev.js
index 6971b85b8..e0e30a0b4 100644
--- a/apps/spreadsheeteditor/main/app_dev.js
+++ b/apps/spreadsheeteditor/main/app_dev.js
@@ -186,6 +186,7 @@ require([
         'common/main/lib/controller/Plugins'
         ,'common/main/lib/controller/ReviewChanges'
         ,'common/main/lib/controller/Protection'
+        ,'common/main/lib/controller/Desktop'
     ], function() {
         window.compareVersions = true;
         app.start();
diff --git a/apps/spreadsheeteditor/main/index.html.deploy b/apps/spreadsheeteditor/main/index.html.deploy
index 2d9f8e90a..c64dfce31 100644
--- a/apps/spreadsheeteditor/main/index.html.deploy
+++ b/apps/spreadsheeteditor/main/index.html.deploy
@@ -216,6 +216,10 @@
                     .replace(/>/g, '&gt;');
         }
 
+        if ( window.AscDesktopEditor ) {
+            window.AscDesktopEditor.execCommand('doc:onload', '');
+        }
+
         var params = getUrlParams(),
             lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
             customer = params["customer"] ? ('<div class="loader-page-text-customer">' + encodeUrlParam(params["customer"]) + '</div>') : '',

From 39f29c5ef8f20b3dbd51497874bf9a46f911fdbb Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Fri, 23 Feb 2018 00:19:40 +0300
Subject: [PATCH 20/41] [common] lock/unlock header buttons on file menu events

---
 apps/common/main/lib/view/Header.js           | 29 +++++++++++++++++++
 apps/common/main/resources/less/header.less   | 11 +++++++
 .../main/app/controller/Viewport.js           | 23 +++++++++++++--
 .../main/app/controller/Viewport.js           | 26 ++++++++++++++---
 .../main/app/controller/Viewport.js           | 26 ++++++++++++++---
 5 files changed, 104 insertions(+), 11 deletions(-)

diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js
index 21263f6da..38e2729e0 100644
--- a/apps/common/main/lib/view/Header.js
+++ b/apps/common/main/lib/view/Header.js
@@ -630,6 +630,35 @@ define([
                     return this.btnSave;
             },
 
+            lockHeaderBtns: function (alias, lock) {
+                var me = this;
+                if ( alias == 'users' ) {
+                    if ( lock )
+                        $btnUsers.addClass('disabled').attr('disabled', 'disabled'); else
+                        $btnUsers.removeClass('disabled').attr('disabled', '');
+                } else {
+                    function _lockButton(btn) {
+                        if ( btn ) {
+                            if ( lock ) {
+                                btn.keepState = {
+                                    disabled: btn.isDisabled()
+                                };
+                            } else {
+                                btn.setDisabled( btn.keepState.disabled );
+                                delete me.btnUndo.keepState;
+                            }
+                        }
+                    }
+
+                    if ( alias == 'undo' ) {
+                        _lockButton(me.btnUndo);
+                    } else
+                    if ( alias == 'redo' ) {
+                        _lockButton(me.btnRedo);
+                    }
+                }
+            },
+
             textBack: 'Go to Documents',
             txtRename: 'Rename',
             textSaveBegin: 'Saving...',
diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less
index 73243b7f6..e53a67037 100644
--- a/apps/common/main/resources/less/header.less
+++ b/apps/common/main/resources/less/header.less
@@ -168,6 +168,11 @@
         cursor: pointer;
         font-size: 14px;
     }
+
+    &.disabled {
+        opacity: 0.65;
+        pointer-events: none;
+    }
 }
 
 .cousers-menu {
@@ -180,6 +185,12 @@
     width: 285px;
     font-size: 12px;
 
+    z-index: 1042;
+
+    .top-title & {
+        top: @height-title + @height-tabs - 8px;
+    }
+
     > label {
         white-space: normal;
     }
diff --git a/apps/documenteditor/main/app/controller/Viewport.js b/apps/documenteditor/main/app/controller/Viewport.js
index 83097ded2..c1cc0ea62 100644
--- a/apps/documenteditor/main/app/controller/Viewport.js
+++ b/apps/documenteditor/main/app/controller/Viewport.js
@@ -68,6 +68,10 @@ define([
 
             var me = this;
             this.addListeners({
+                'FileMenu': {
+                    'menu:hide': me.onFileMenu.bind(me, 'hide'),
+                    'menu:show': me.onFileMenu.bind(me, 'show')
+                },
                 'Toolbar': {
                     'render:before' : function (toolbar) {
                         var config = DE.getController('Main').appOptions;
@@ -79,12 +83,17 @@ define([
                                 Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
                     },
                     'undo:disabled' : function (state) {
-                        if ( me.header.btnUndo )
-                            me.header.btnUndo.setDisabled(state);
+                        if ( me.header.btnUndo ) {
+                            if ( me.header.btnUndo.keepState )
+                                me.header.btnUndo.keepState.disabled = state;
+                            else me.header.btnUndo.setDisabled(state);
+                        }
                     },
                     'redo:disabled' : function (state) {
                         if ( me.header.btnRedo )
-                            me.header.btnRedo.setDisabled(state);
+                            if ( me.header.btnRedo.keepState )
+                                me.header.btnRedo.keepState.disabled = state;
+                            else me.header.btnRedo.setDisabled(state);
                     },
                     'save:disabled' : function (state) {
                         if ( me.header.btnSave )
@@ -197,6 +206,14 @@ define([
         onWindowResize: function(e) {
             this.onLayoutChanged('window');
             Common.NotificationCenter.trigger('window:resize');
+        },
+
+        onFileMenu: function (opts) {
+            var me = this;
+            var _need_disable =  opts == 'show';
+
+            me.header.lockHeaderBtns( 'undo', _need_disable );
+            me.header.lockHeaderBtns( 'redo', _need_disable );
         }
     });
 });
diff --git a/apps/presentationeditor/main/app/controller/Viewport.js b/apps/presentationeditor/main/app/controller/Viewport.js
index 298096677..6d80c3200 100644
--- a/apps/presentationeditor/main/app/controller/Viewport.js
+++ b/apps/presentationeditor/main/app/controller/Viewport.js
@@ -69,6 +69,10 @@ define([
 
             // This most important part when we will tell our controller what events should be handled
             this.addListeners({
+                'FileMenu': {
+                    'menu:hide': me.onFileMenu.bind(me, 'hide'),
+                    'menu:show': me.onFileMenu.bind(me, 'show')
+                },
                 'Toolbar': {
                     'render:before' : function (toolbar) {
                         var config = PE.getController('Main').appOptions;
@@ -80,12 +84,18 @@ define([
                             Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
                     },
                     'undo:disabled' : function (state) {
-                        if ( me.header.btnUndo )
-                            me.header.btnUndo.setDisabled(state);
+                        if ( me.header.btnUndo ) {
+                            if ( me.header.btnUndo.keepState )
+                                me.header.btnUndo.keepState.disabled = state;
+                            else me.header.btnUndo.setDisabled(state);
+                        }
                     },
                     'redo:disabled' : function (state) {
-                        if ( me.header.btnRedo )
-                            me.header.btnRedo.setDisabled(state);
+                        if ( me.header.btnRedo ) {
+                            if ( me.header.btnRedo.keepState )
+                                me.header.btnRedo.keepState.disabled = state;
+                            else me.header.btnRedo.setDisabled(state);
+                        }
                     },
                     'save:disabled' : function (state) {
                         if ( me.header.btnSave )
@@ -236,6 +246,14 @@ define([
                     element.msRequestFullscreen();
                 }
             }
+        },
+
+        onFileMenu: function (opts) {
+            var me = this;
+            var _need_disable =  opts == 'show';
+
+            me.header.lockHeaderBtns( 'undo', _need_disable );
+            me.header.lockHeaderBtns( 'redo', _need_disable );
         }
     });
 });
diff --git a/apps/spreadsheeteditor/main/app/controller/Viewport.js b/apps/spreadsheeteditor/main/app/controller/Viewport.js
index dadd49ec1..9998b0722 100644
--- a/apps/spreadsheeteditor/main/app/controller/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/controller/Viewport.js
@@ -67,6 +67,10 @@ define([
 
             // This most important part when we will tell our controller what events should be handled
             this.addListeners({
+                'FileMenu': {
+                    'menu:hide': me.onFileMenu.bind(me, 'hide'),
+                    'menu:show': me.onFileMenu.bind(me, 'show')
+                },
                 'Toolbar': {
                     'render:before' : function (toolbar) {
                         var config = SSE.getController('Main').appOptions;
@@ -78,12 +82,18 @@ define([
                             Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
                     },
                     'undo:disabled' : function (state) {
-                        if ( me.header.btnUndo )
-                            me.header.btnUndo.setDisabled(state);
+                        if ( me.header.btnUndo ) {
+                            if ( me.header.btnUndo.keepState )
+                                me.header.btnUndo.keepState.disabled = state;
+                            else me.header.btnUndo.setDisabled(state);
+                        }
                     },
                     'redo:disabled' : function (state) {
-                        if ( me.header.btnRedo )
-                            me.header.btnRedo.setDisabled(state);
+                        if ( me.header.btnRedo ) {
+                            if ( me.header.btnRedo.keepState )
+                                me.header.btnRedo.keepState.disabled = state;
+                            else me.header.btnRedo.setDisabled(state);
+                        }
                     },
                     'save:disabled' : function (state) {
                         if ( me.header.btnSave )
@@ -205,6 +215,14 @@ define([
         onWindowResize: function(e) {
             this.onLayoutChanged('window');
             Common.NotificationCenter.trigger('window:resize');
+        },
+
+        onFileMenu: function (opts) {
+            var me = this;
+            var _need_disable =  opts == 'show';
+
+            me.header.lockHeaderBtns( 'undo', _need_disable );
+            me.header.lockHeaderBtns( 'redo', _need_disable );
         }
     });
 });

From e239437015b5c96e724f3e0c1554885e08dabb3c Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Fri, 23 Feb 2018 01:01:00 +0300
Subject: [PATCH 21/41] [SSE] updated toolbar color

---
 apps/spreadsheeteditor/main/resources/less/toolbar.less | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/apps/spreadsheeteditor/main/resources/less/toolbar.less b/apps/spreadsheeteditor/main/resources/less/toolbar.less
index 934805ee3..ebacaa1d5 100644
--- a/apps/spreadsheeteditor/main/resources/less/toolbar.less
+++ b/apps/spreadsheeteditor/main/resources/less/toolbar.less
@@ -1,4 +1,4 @@
-@tabs-bg-color: #48795c;
+@tabs-bg-color: #40865c;
 
 .toolbar {
     &:not(.cover) {

From fc6c6c2cb8e531de167bf92300bb7207a83fb79a Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Sun, 25 Feb 2018 01:19:36 +0300
Subject: [PATCH 22/41] refactoring

---
 .../main/app/controller/Toolbar.js            | 24 +++++++------------
 apps/documenteditor/main/app/view/Toolbar.js  | 20 +++++++---------
 .../main/app/view/Toolbar.js                  | 20 +++++++---------
 .../main/app/controller/Toolbar.js            |  2 +-
 .../main/app/view/Toolbar.js                  | 19 ++++++---------
 5 files changed, 32 insertions(+), 53 deletions(-)

diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js
index 49455e079..0bbb5b629 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -524,14 +524,9 @@ define([
 
                 var btnHorizontalAlign = this.toolbar.btnHorizontalAlign;
 
-                if (btnHorizontalAlign.rendered) {
-                    var iconEl = $('.icon', btnHorizontalAlign.cmpEl);
-
-                    if (iconEl) {
-                        iconEl.removeClass(btnHorizontalAlign.options.icls);
-                        btnHorizontalAlign.options.icls = align;
-                        iconEl.addClass(btnHorizontalAlign.options.icls);
-                    }
+                if ( btnHorizontalAlign.rendered && btnHorizontalAlign.$icon ) {
+                    btnHorizontalAlign.$icon.removeClass(btnHorizontalAlign.options.icls).addClass(align);
+                    btnHorizontalAlign.options.icls = align;
                 }
 
                 if (v === null || v===undefined) {
@@ -917,7 +912,7 @@ define([
             var toolbar = this.toolbar;
             if (this.api) {
                 var isModified = this.api.asc_isDocumentCanSave();
-                var isSyncButton = $('.icon', toolbar.btnSave.cmpEl).hasClass('btn-synch');
+                var isSyncButton = toolbar.btnSave.$icon.hasClass('btn-synch');
                 if (!isModified && !isSyncButton && !toolbar.mode.forcesave)
                     return;
 
@@ -1077,14 +1072,11 @@ define([
 
         onMenuHorizontalAlignSelect: function(menu, item) {
             this._state.pralign = undefined;
-            var btnHorizontalAlign = this.toolbar.btnHorizontalAlign,
-                iconEl = $('.icon', btnHorizontalAlign.cmpEl);
+            var btnHorizontalAlign = this.toolbar.btnHorizontalAlign;
 
-            if (iconEl) {
-                iconEl.removeClass(btnHorizontalAlign.options.icls);
-                btnHorizontalAlign.options.icls = !item.checked ? 'btn-align-left' : item.options.icls;
-                iconEl.addClass(btnHorizontalAlign.options.icls);
-            }
+            btnHorizontalAlign.$icon.removeClass(btnHorizontalAlign.options.icls);
+            btnHorizontalAlign.options.icls = !item.checked ? 'btn-align-left' : item.options.icls;
+            btnHorizontalAlign.$icon.addClass(btnHorizontalAlign.options.icls);
 
             if (this.api && item.checked)
                 this.api.put_PrAlign(item.value);
diff --git a/apps/documenteditor/main/app/view/Toolbar.js b/apps/documenteditor/main/app/view/Toolbar.js
index 7f2985549..93474165f 100644
--- a/apps/documenteditor/main/app/view/Toolbar.js
+++ b/apps/documenteditor/main/app/view/Toolbar.js
@@ -1323,6 +1323,8 @@ define([
                     Array.prototype.push.apply(me.paragraphControls, me.btnsPageBreak);
                 }.call(this);
 
+                this.btnSave.$icon = $('.icon', this.btnSave.cmpEl);
+                this.btnHorizontalAlign.$icon = $('.icon', this.btnHorizontalAlign.cmpEl);
                 return $host;
             },
 
@@ -2122,9 +2124,7 @@ define([
                 }
 
                 this._state.hasCollaborativeChanges = true;
-                var iconEl = $('.icon', this.btnSave.cmpEl);
-                iconEl.removeClass(this.btnSaveCls);
-                iconEl.addClass('btn-synch');
+                this.btnSave.$icon.removeClass(this.btnSaveCls).addClass('btn-synch');
                 if (this.showSynchTip) {
                     this.btnSave.updateHint('');
                     if (this.synchTooltip === undefined)
@@ -2157,12 +2157,10 @@ define([
 
             synchronizeChanges: function () {
                 if (!this._state.previewmode && this.btnSave.rendered) {
-                    var iconEl = $('.icon', this.btnSave.cmpEl),
-                        me = this;
+                    var me = this;
 
-                    if (iconEl.hasClass('btn-synch')) {
-                        iconEl.removeClass('btn-synch');
-                        iconEl.addClass(this.btnSaveCls);
+                    if ( me.btnSave.$icon.hasClass('btn-synch') ) {
+                        me.btnSave.$icon.removeClass('btn-synch').addClass(me.btnSaveCls);
                         if (this.synchTooltip)
                             this.synchTooltip.hide();
                         this.btnSave.updateHint(this.btnSaveTip);
@@ -2184,10 +2182,8 @@ define([
                 if (cls !== this.btnSaveCls && this.btnSave.rendered) {
                     this.btnSaveTip = ((length > 1) ? this.tipSaveCoauth : this.tipSave ) + Common.Utils.String.platformKey('Ctrl+S');
 
-                    var iconEl = $('.icon', this.btnSave.cmpEl);
-                    if (!iconEl.hasClass('btn-synch')) {
-                        iconEl.removeClass(this.btnSaveCls);
-                        iconEl.addClass(cls);
+                    if ( !this.btnSave.$icon.hasClass('btn-synch') ) {
+                        this.btnSave.$icon.removeClass(this.btnSaveCls).addClass(cls);
                         this.btnSave.updateHint(this.btnSaveTip);
                     }
                     this.btnSaveCls = cls;
diff --git a/apps/presentationeditor/main/app/view/Toolbar.js b/apps/presentationeditor/main/app/view/Toolbar.js
index f20a8aa58..0ad878eaf 100644
--- a/apps/presentationeditor/main/app/view/Toolbar.js
+++ b/apps/presentationeditor/main/app/view/Toolbar.js
@@ -1012,6 +1012,8 @@ define([
                     }
                 });
 
+                me.btnSave.$icon = $('.icon', me.btnSave.cmpEl);
+
                 var created = me.btnsInsertImage.concat(me.btnsInsertText, me.btnsInsertShape, me.btnsAddSlide);
                 this.lockToolbar(PE.enumLock.disableOnStart, true, {array: created});
 
@@ -1479,9 +1481,7 @@ define([
                 }
 
                 this._state.hasCollaborativeChanges = true;
-                var iconEl = $('.icon', this.btnSave.cmpEl);
-                iconEl.removeClass(this.btnSaveCls);
-                iconEl.addClass('btn-synch');
+                this.btnSave.$icon.removeClass(this.btnSaveCls).addClass('btn-synch');
                 if (this.showSynchTip) {
                     this.btnSave.updateHint('');
                     if (this.synchTooltip === undefined)
@@ -1514,12 +1514,10 @@ define([
 
             synchronizeChanges: function () {
                 if (this.btnSave.rendered) {
-                    var iconEl = $('.icon', this.btnSave.cmpEl),
-                        me = this;
+                    var me = this;
 
-                    if (iconEl.hasClass('btn-synch')) {
-                        iconEl.removeClass('btn-synch');
-                        iconEl.addClass(this.btnSaveCls);
+                    if ( me.btnSave.$icon.hasClass('btn-synch') ) {
+                        me.btnSave.$icon.removeClass('btn-synch').addClass(this.btnSaveCls);
                         if (this.synchTooltip)
                             this.synchTooltip.hide();
                         this.btnSave.updateHint(this.btnSaveTip);
@@ -1542,10 +1540,8 @@ define([
                 if (cls !== this.btnSaveCls && this.btnSave.rendered) {
                     this.btnSaveTip = ((length > 1) ? this.tipSaveCoauth : this.tipSave ) + Common.Utils.String.platformKey('Ctrl+S');
 
-                    var iconEl = $('.icon', this.btnSave.cmpEl);
-                    if (!iconEl.hasClass('btn-synch')) {
-                        iconEl.removeClass(this.btnSaveCls);
-                        iconEl.addClass(cls);
+                    if ( !this.btnSave.$icon.hasClass('btn-synch') ) {
+                        this.btnSave.$icon.removeClass(this.btnSaveCls).addClass(cls);
                         this.btnSave.updateHint(this.btnSaveTip);
                     }
                     this.btnSaveCls = cls;
diff --git a/apps/spreadsheeteditor/main/app/controller/Toolbar.js b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
index 4a28083c3..f21ff9169 100644
--- a/apps/spreadsheeteditor/main/app/controller/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
@@ -386,7 +386,7 @@ define([
         onSave: function(e) {
             if (this.api) {
                 var isModified = this.api.asc_isDocumentCanSave();
-                var isSyncButton = $('.icon', this.toolbar.btnSave.cmpEl).hasClass('btn-synch');
+                var isSyncButton = this.toolbar.btnSave.$icon.hasClass('btn-synch');
                 if (!isModified && !isSyncButton && !this.toolbar.mode.forcesave)
                     return;
 
diff --git a/apps/spreadsheeteditor/main/app/view/Toolbar.js b/apps/spreadsheeteditor/main/app/view/Toolbar.js
index f627aafb7..7b0f621d8 100644
--- a/apps/spreadsheeteditor/main/app/view/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/view/Toolbar.js
@@ -1388,6 +1388,7 @@ define([
             // replacePlacholder('#id-toolbar-short-placeholder-btn-valign',                this.btnVerticalAlign);
             // replacePlacholder('#id-toolbar-short-placeholder-btn-filter',                this.btnAutofilter);
 
+            this.btnSave.$icon = $('.icon', this.btnSave.cmpEl);
             return $host;
         },
 
@@ -1828,9 +1829,7 @@ define([
             }
 
             this._state.hasCollaborativeChanges = true;
-            var iconEl = $('.icon', this.btnSave.cmpEl);
-            iconEl.removeClass(this.btnSaveCls);
-            iconEl.addClass('btn-synch');
+            this.btnSave.$icon.removeClass(this.btnSaveCls).addClass('btn-synch');
 
             if (this.showSynchTip){
                 this.btnSave.updateHint('');
@@ -1864,12 +1863,10 @@ define([
 
         synchronizeChanges: function() {
             if (this.btnSave.rendered) {
-                var iconEl = $('.icon', this.btnSave.cmpEl),
-                    me = this;
+                var me = this;
 
-                if (iconEl.hasClass('btn-synch')) {
-                    iconEl.removeClass('btn-synch');
-                    iconEl.addClass(this.btnSaveCls);
+                if ( me.btnSave.$icon.hasClass('btn-synch') ) {
+                    me.btnSave.$icon.removeClass('btn-synch').addClass(this.btnSaveCls);
                     if (this.synchTooltip)
                         this.synchTooltip.hide();
                     this.btnSave.updateHint(this.btnSaveTip);
@@ -1892,10 +1889,8 @@ define([
             if (cls !== this.btnSaveCls && this.btnSave.rendered) {
                 this.btnSaveTip = ((length>1) ? this.tipSaveCoauth : this.tipSave )+ Common.Utils.String.platformKey('Ctrl+S');
 
-                var iconEl = $('.icon', this.btnSave.cmpEl);
-                if (!iconEl.hasClass('btn-synch')) {
-                    iconEl.removeClass(this.btnSaveCls);
-                    iconEl.addClass(cls);
+                if ( !this.btnSave.$icon.hasClass('btn-synch') ) {
+                    this.btnSave.$icon.removeClass(this.btnSaveCls).addClass(cls);
                     this.btnSave.updateHint(this.btnSaveTip);
                 }
                 this.btnSaveCls = cls;

From 6d0a353d7891faf7f7a5925a23b3131f6b23f896 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Mon, 26 Feb 2018 16:23:07 +0300
Subject: [PATCH 23/41] [Common] refactoring. defined $icon element for a
 button

---
 apps/common/main/lib/component/Button.js      |  1 +
 apps/documenteditor/main/app/view/Toolbar.js  |  2 -
 .../main/app/controller/Toolbar.js            | 46 ++++------
 .../main/app/view/Toolbar.js                  |  2 -
 .../main/app/controller/Toolbar.js            | 83 ++++++-------------
 .../main/app/view/Toolbar.js                  |  1 -
 6 files changed, 43 insertions(+), 92 deletions(-)

diff --git a/apps/common/main/lib/component/Button.js b/apps/common/main/lib/component/Button.js
index 2315c167a..71a4c74f4 100644
--- a/apps/common/main/lib/component/Button.js
+++ b/apps/common/main/lib/component/Button.js
@@ -350,6 +350,7 @@ define([
                         me.menu.render(me.cmpEl);
 
                     parentEl.html(me.cmpEl);
+                    me.$icon = me.$el.find('.icon');
                 }
             }
 
diff --git a/apps/documenteditor/main/app/view/Toolbar.js b/apps/documenteditor/main/app/view/Toolbar.js
index 93474165f..7dfe2dbf9 100644
--- a/apps/documenteditor/main/app/view/Toolbar.js
+++ b/apps/documenteditor/main/app/view/Toolbar.js
@@ -1323,8 +1323,6 @@ define([
                     Array.prototype.push.apply(me.paragraphControls, me.btnsPageBreak);
                 }.call(this);
 
-                this.btnSave.$icon = $('.icon', this.btnSave.cmpEl);
-                this.btnHorizontalAlign.$icon = $('.icon', this.btnHorizontalAlign.cmpEl);
                 return $host;
             },
 
diff --git a/apps/presentationeditor/main/app/controller/Toolbar.js b/apps/presentationeditor/main/app/controller/Toolbar.js
index 4099bc566..956aded7f 100644
--- a/apps/presentationeditor/main/app/controller/Toolbar.js
+++ b/apps/presentationeditor/main/app/controller/Toolbar.js
@@ -514,14 +514,9 @@ define([
                     btnHorizontalAlign.menu.clearAll();
                 }
 
-                if (btnHorizontalAlign.rendered) {
-                    var iconEl = $('.icon', btnHorizontalAlign.cmpEl);
-
-                    if (iconEl) {
-                        iconEl.removeClass(btnHorizontalAlign.options.icls);
-                        btnHorizontalAlign.options.icls = align;
-                        iconEl.addClass(btnHorizontalAlign.options.icls);
-                    }
+                if ( btnHorizontalAlign.rendered && btnHorizontalAlign.$icon ) {
+                    btnHorizontalAlign.$icon.removeClass(btnHorizontalAlign.options.icls).addClass(align);
+                    btnHorizontalAlign.options.icls = align;
                 }
             }
         },
@@ -547,14 +542,9 @@ define([
                     btnVerticalAlign.menu.clearAll();
                 }
 
-                if (btnVerticalAlign.rendered) {
-                    var iconEl = $('.icon', btnVerticalAlign.cmpEl);
-
-                    if (iconEl) {
-                        iconEl.removeClass(btnVerticalAlign.options.icls);
-                        btnVerticalAlign.options.icls = align;
-                        iconEl.addClass(btnVerticalAlign.options.icls);
-                    }
+                if ( btnVerticalAlign.rendered && btnVerticalAlign.$icon ) {
+                    btnVerticalAlign.$icon.removeClass(btnVerticalAlign.options.icls).addClass(align);
+                    btnVerticalAlign.options.icls = align;
                 }
             }
         },
@@ -912,7 +902,7 @@ define([
             var toolbar = this.toolbar;
             if (this.api && this.api.asc_isDocumentCanSave) {
                 var isModified = this.api.asc_isDocumentCanSave();
-                var isSyncButton = $('.icon', this.toolbar.btnSave.cmpEl).hasClass('btn-synch');
+                var isSyncButton = this.toolbar.btnSave.$icon.hasClass('btn-synch');
                 if (!isModified && !isSyncButton && !this.toolbar.mode.forcesave)
                     return;
 
@@ -1046,14 +1036,11 @@ define([
 
         onMenuHorizontalAlignSelect: function(menu, item) {
             this._state.pralign = undefined;
-            var btnHorizontalAlign = this.toolbar.btnHorizontalAlign,
-                iconEl = $('.icon', btnHorizontalAlign.cmpEl);
+            var btnHorizontalAlign = this.toolbar.btnHorizontalAlign;
 
-            if (iconEl) {
-                iconEl.removeClass(btnHorizontalAlign.options.icls);
-                btnHorizontalAlign.options.icls = !item.checked ? 'btn-align-left' : item.options.icls;
-                iconEl.addClass(btnHorizontalAlign.options.icls);
-            }
+            btnHorizontalAlign.$icon.removeClass(btnHorizontalAlign.options.icls);
+            btnHorizontalAlign.options.icls = !item.checked ? 'btn-align-left' : item.options.icls;
+            btnHorizontalAlign.$icon.addClass(btnHorizontalAlign.options.icls);
 
             if (this.api && item.checked)
                 this.api.put_PrAlign(item.value);
@@ -1063,14 +1050,11 @@ define([
         },
 
         onMenuVerticalAlignSelect: function(menu, item) {
-            var btnVerticalAlign = this.toolbar.btnVerticalAlign,
-                iconEl = $('.icon', btnVerticalAlign.cmpEl);
+            var btnVerticalAlign = this.toolbar.btnVerticalAlign;
 
-            if (iconEl) {
-                iconEl.removeClass(btnVerticalAlign.options.icls);
-                btnVerticalAlign.options.icls = !item.checked ? 'btn-align-middle' : item.options.icls;
-                iconEl.addClass(btnVerticalAlign.options.icls);
-            }
+            btnVerticalAlign.$icon.removeClass(btnVerticalAlign.options.icls);
+            btnVerticalAlign.options.icls = !item.checked ? 'btn-align-middle' : item.options.icls;
+            btnVerticalAlign.$icon.addClass(btnVerticalAlign.options.icls);
 
             this._state.vtextalign = undefined;
             if (this.api && item.checked)
diff --git a/apps/presentationeditor/main/app/view/Toolbar.js b/apps/presentationeditor/main/app/view/Toolbar.js
index 0ad878eaf..84023b454 100644
--- a/apps/presentationeditor/main/app/view/Toolbar.js
+++ b/apps/presentationeditor/main/app/view/Toolbar.js
@@ -1012,8 +1012,6 @@ define([
                     }
                 });
 
-                me.btnSave.$icon = $('.icon', me.btnSave.cmpEl);
-
                 var created = me.btnsInsertImage.concat(me.btnsInsertText, me.btnsInsertShape, me.btnsAddSlide);
                 this.lockToolbar(PE.enumLock.disableOnStart, true, {array: created});
 
diff --git a/apps/spreadsheeteditor/main/app/controller/Toolbar.js b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
index f21ff9169..6c6ed4809 100644
--- a/apps/spreadsheeteditor/main/app/controller/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
@@ -495,8 +495,7 @@ define([
         },
 
         onSubscriptMenu: function(menu, item) {
-            var btnSubscript = this.toolbar.btnSubscript,
-                iconEl = $('.icon', btnSubscript.cmpEl);
+            var btnSubscript = this.toolbar.btnSubscript;
 
             if (item.value == 'sub') {
                 this._state.subscript = undefined;
@@ -506,9 +505,8 @@ define([
                 this.api.asc_setCellSuperscript(item.checked);
             }
             if (item.checked) {
-                iconEl.removeClass(btnSubscript.options.icls);
+                btnSubscript.$icon.removeClass(btnSubscript.options.icls).addClass(item.options.icls);
                 btnSubscript.options.icls = item.options.icls;
-                iconEl.addClass(btnSubscript.options.icls);
             }
 
             Common.NotificationCenter.trigger('edit:complete', this.toolbar);
@@ -612,14 +610,9 @@ define([
                     bordersWidth = btnBorders.options.borderswidth,
                     bordersColor = btnBorders.options.borderscolor;
 
-                if (btnBorders.rendered) {
-                    var iconEl = $('.icon', btnBorders.cmpEl);
-
-                    if (iconEl) {
-                        iconEl.removeClass(btnBorders.options.icls);
-                        btnBorders.options.icls = item.options.icls;
-                        iconEl.addClass(btnBorders.options.icls);
-                    }
+                if ( btnBorders.rendered ) {
+                    btnBorders.$icon.removeClass(btnBorders.options.icls).addClass(item.options.icls);
+                    btnBorders.options.icls = item.options.icls;
                 }
 
                 btnBorders.options.borderId = item.options.borderId;
@@ -681,14 +674,11 @@ define([
         },
 
         onHorizontalAlignMenu: function(menu, item) {
-            var btnHorizontalAlign = this.toolbar.btnHorizontalAlign,
-                iconEl = $('.icon', btnHorizontalAlign.cmpEl);
+            var btnHorizontalAlign = this.toolbar.btnHorizontalAlign;
 
-            if (iconEl) {
-                iconEl.removeClass(btnHorizontalAlign.options.icls);
-                btnHorizontalAlign.options.icls = !item.checked ? 'btn-align-left' : item.options.icls;
-                iconEl.addClass(btnHorizontalAlign.options.icls);
-            }
+            btnHorizontalAlign.$icon.removeClass(btnHorizontalAlign.options.icls);
+            btnHorizontalAlign.options.icls = !item.checked ? 'btn-align-left' : item.options.icls;
+            btnHorizontalAlign.$icon.addClass(btnHorizontalAlign.options.icls);
 
             this._state.pralign = undefined;
             if (this.api)
@@ -701,14 +691,11 @@ define([
         },
 
         onVerticalAlignMenu: function(menu, item) {
-            var btnVerticalAlign = this.toolbar.btnVerticalAlign,
-                iconEl = $('.icon', btnVerticalAlign.cmpEl);
+            var btnVerticalAlign = this.toolbar.btnVerticalAlign;
 
-            if (iconEl) {
-                iconEl.removeClass(btnVerticalAlign.options.icls);
-                btnVerticalAlign.options.icls = !item.checked ? 'btn-valign-bottom' : item.options.icls;
-                iconEl.addClass(btnVerticalAlign.options.icls);
-            }
+            btnVerticalAlign.$icon.removeClass(btnVerticalAlign.options.icls);
+            btnVerticalAlign.options.icls = !item.checked ? 'btn-valign-bottom' : item.options.icls;
+            btnVerticalAlign.$icon.addClass(btnVerticalAlign.options.icls);
 
             this._state.valign = undefined;
             if (this.api)
@@ -1792,13 +1779,10 @@ define([
                         btnSubscript.menu.clearAll();
                     } else {
                         btnSubscript.menu.items[index].setChecked(true);
-                        if (btnSubscript.rendered) {
-                            var iconEl = $('.icon', btnSubscript.cmpEl);
-                            if (iconEl) {
-                                iconEl.removeClass(btnSubscript.options.icls);
-                                btnSubscript.options.icls = btnSubscript.menu.items[index].options.icls;
-                                iconEl.addClass(btnSubscript.options.icls);
-                            }
+                        if ( btnSubscript.rendered && btnSubscript.$icon ) {
+                            btnSubscript.$icon.removeClass(btnSubscript.options.icls);
+                            btnSubscript.options.icls = btnSubscript.menu.items[index].options.icls;
+                            btnSubscript.$icon.addClass(btnSubscript.options.icls);
                         }
                     }
 
@@ -1933,13 +1917,10 @@ define([
                         btnSubscript.menu.clearAll();
                     } else {
                         btnSubscript.menu.items[index].setChecked(true);
-                        if (btnSubscript.rendered) {
-                            var iconEl = $('.icon', btnSubscript.cmpEl);
-                            if (iconEl) {
-                                iconEl.removeClass(btnSubscript.options.icls);
-                                btnSubscript.options.icls = btnSubscript.menu.items[index].options.icls;
-                                iconEl.addClass(btnSubscript.options.icls);
-                            }
+                        if ( btnSubscript.rendered ) {
+                            btnSubscript.$icon.removeClass(btnSubscript.options.icls);
+                            btnSubscript.options.icls = btnSubscript.menu.items[index].options.icls;
+                            btnSubscript.$icon.addClass(btnSubscript.options.icls);
                         }
                     }
 
@@ -2068,14 +2049,9 @@ define([
                         }
 
                         var btnHorizontalAlign = this.toolbar.btnHorizontalAlign;
-                        if (btnHorizontalAlign.rendered) {
-                            var hIconEl = $('.icon', btnHorizontalAlign.cmpEl);
-
-                            if (hIconEl) {
-                                hIconEl.removeClass(btnHorizontalAlign.options.icls);
-                                btnHorizontalAlign.options.icls = align;
-                                hIconEl.addClass(btnHorizontalAlign.options.icls);
-                            }
+                        if ( btnHorizontalAlign.rendered ) {
+                            btnHorizontalAlign.$icon.removeClass(btnHorizontalAlign.options.icls).addClass(align);
+                            btnHorizontalAlign.options.icls = align;
                         }
                     }
 
@@ -2103,14 +2079,9 @@ define([
                             toolbar.btnVerticalAlign.menu.items[index].setChecked(true, false);
 
                             var btnVerticalAlign = this.toolbar.btnVerticalAlign;
-                            if (btnVerticalAlign.rendered) {
-                                var vIconEl = $('.icon', btnVerticalAlign.cmpEl);
-
-                                if (vIconEl) {
-                                    vIconEl.removeClass(btnVerticalAlign.options.icls);
-                                    btnVerticalAlign.options.icls = align;
-                                    vIconEl.addClass(btnVerticalAlign.options.icls);
-                                }
+                            if ( btnVerticalAlign.rendered ) {
+                                btnVerticalAlign.$icon.removeClass(btnVerticalAlign.options.icls).addClass(align);
+                                btnVerticalAlign.options.icls = align;
                             }
                         }
                     }
diff --git a/apps/spreadsheeteditor/main/app/view/Toolbar.js b/apps/spreadsheeteditor/main/app/view/Toolbar.js
index 7b0f621d8..537958d85 100644
--- a/apps/spreadsheeteditor/main/app/view/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/view/Toolbar.js
@@ -1388,7 +1388,6 @@ define([
             // replacePlacholder('#id-toolbar-short-placeholder-btn-valign',                this.btnVerticalAlign);
             // replacePlacholder('#id-toolbar-short-placeholder-btn-filter',                this.btnAutofilter);
 
-            this.btnSave.$icon = $('.icon', this.btnSave.cmpEl);
             return $host;
         },
 

From 09b99470511956058bbc3acb4fb3def3cf56e53e Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Mon, 26 Feb 2018 16:31:34 +0300
Subject: [PATCH 24/41] [DE] defined button to indicate coauth changes

---
 .../main/app/controller/Toolbar.js            |  2 +-
 apps/documenteditor/main/app/view/Toolbar.js  | 38 ++++++++++---------
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js
index 0bbb5b629..42eee2857 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -912,7 +912,7 @@ define([
             var toolbar = this.toolbar;
             if (this.api) {
                 var isModified = this.api.asc_isDocumentCanSave();
-                var isSyncButton = toolbar.btnSave.$icon.hasClass('btn-synch');
+                var isSyncButton = toolbar.btnCollabChanges.$icon.hasClass('btn-synch');
                 if (!isModified && !isSyncButton && !toolbar.mode.forcesave)
                     return;
 
diff --git a/apps/documenteditor/main/app/view/Toolbar.js b/apps/documenteditor/main/app/view/Toolbar.js
index 7dfe2dbf9..76dc2a073 100644
--- a/apps/documenteditor/main/app/view/Toolbar.js
+++ b/apps/documenteditor/main/app/view/Toolbar.js
@@ -124,6 +124,7 @@ define([
                     signals: ['disabled']
                 });
                 this.toolbarControls.push(this.btnSave);
+                this.btnCollabChanges = this.btnSave;
 
                 this.btnUndo = new Common.UI.Button({
                     id: 'id-toolbar-btn-undo',
@@ -2116,21 +2117,21 @@ define([
             /** coauthoring begin **/
             onCollaborativeChanges: function () {
                 if (this._state.hasCollaborativeChanges) return;
-                if (!this.btnSave.rendered || this._state.previewmode) {
+                if (!this.btnCollabChanges.rendered || this._state.previewmode) {
                     this.needShowSynchTip = true;
                     return;
                 }
 
                 this._state.hasCollaborativeChanges = true;
-                this.btnSave.$icon.removeClass(this.btnSaveCls).addClass('btn-synch');
+                this.btnCollabChanges.$icon.removeClass(this.btnSaveCls).addClass('btn-synch');
                 if (this.showSynchTip) {
-                    this.btnSave.updateHint('');
+                    this.btnCollabChanges.updateHint('');
                     if (this.synchTooltip === undefined)
                         this.createSynchTip();
 
                     this.synchTooltip.show();
                 } else {
-                    this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
+                    this.btnCollabChanges.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                 }
 
                 this.btnSave.setDisabled(false);
@@ -2139,29 +2140,30 @@ define([
 
             createSynchTip: function () {
                 this.synchTooltip = new Common.UI.SynchronizeTip({
-                    target: $('#id-toolbar-btn-save')
+                    target: this.btnCollabChanges.$el
                 });
                 this.synchTooltip.on('dontshowclick', function () {
                     this.showSynchTip = false;
                     this.synchTooltip.hide();
-                    this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
+                    this.btnCollabChanges.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                     Common.localStorage.setItem("de-hide-synch", 1);
                 }, this);
                 this.synchTooltip.on('closeclick', function () {
                     this.synchTooltip.hide();
-                    this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
+                    this.btnCollabChanges.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                 }, this);
             },
 
             synchronizeChanges: function () {
-                if (!this._state.previewmode && this.btnSave.rendered) {
+                if ( !this._state.previewmode && this.btnCollabChanges.rendered ) {
                     var me = this;
 
-                    if ( me.btnSave.$icon.hasClass('btn-synch') ) {
-                        me.btnSave.$icon.removeClass('btn-synch').addClass(me.btnSaveCls);
+                    if ( me.btnCollabChanges.$icon.hasClass('btn-synch') ) {
+                        me.btnCollabChanges.$icon.removeClass('btn-synch').addClass(me.btnSaveCls);
                         if (this.synchTooltip)
                             this.synchTooltip.hide();
-                        this.btnSave.updateHint(this.btnSaveTip);
+                        this.btnCollabChanges.updateHint(this.btnSaveTip);
+
                         this.btnSave.setDisabled(!me.mode.forcesave);
                         this._state.hasCollaborativeChanges = false;
                     }
@@ -2175,16 +2177,18 @@ define([
                         editusers.push(item);
                 });
 
+                var me = this;
                 var length = _.size(editusers);
                 var cls = (length > 1) ? 'btn-save-coauth' : 'btn-save';
-                if (cls !== this.btnSaveCls && this.btnSave.rendered) {
-                    this.btnSaveTip = ((length > 1) ? this.tipSaveCoauth : this.tipSave ) + Common.Utils.String.platformKey('Ctrl+S');
+                if ( cls !== me.btnSaveCls && me.btnCollabChanges.rendered ) {
+                    me.btnSaveTip = ((length > 1) ? me.tipSaveCoauth : me.tipSave ) + Common.Utils.String.platformKey('Ctrl+S');
+
+                    if ( !me.btnCollabChanges.$icon.hasClass('btn-synch') ) {
+                        me.btnCollabChanges.$icon.removeClass(me.btnSaveCls).addClass(cls);
+                        me.btnCollabChanges.updateHint(me.btnSaveTip);
 
-                    if ( !this.btnSave.$icon.hasClass('btn-synch') ) {
-                        this.btnSave.$icon.removeClass(this.btnSaveCls).addClass(cls);
-                        this.btnSave.updateHint(this.btnSaveTip);
                     }
-                    this.btnSaveCls = cls;
+                    me.btnSaveCls = cls;
                 }
             },
 

From 6cf3ee7fb99e3778429c82825c5a48a4dc78af55 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 28 Feb 2018 16:17:53 +0300
Subject: [PATCH 25/41] [SE PE] absract 'save' button

---
 .../main/app/controller/Toolbar.js            |  2 +-
 .../main/app/view/Toolbar.js                  | 31 ++++++++--------
 .../main/app/controller/Toolbar.js            |  2 +-
 .../main/app/view/Toolbar.js                  | 35 ++++++++++---------
 4 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/apps/presentationeditor/main/app/controller/Toolbar.js b/apps/presentationeditor/main/app/controller/Toolbar.js
index 956aded7f..15bc3e532 100644
--- a/apps/presentationeditor/main/app/controller/Toolbar.js
+++ b/apps/presentationeditor/main/app/controller/Toolbar.js
@@ -902,7 +902,7 @@ define([
             var toolbar = this.toolbar;
             if (this.api && this.api.asc_isDocumentCanSave) {
                 var isModified = this.api.asc_isDocumentCanSave();
-                var isSyncButton = this.toolbar.btnSave.$icon.hasClass('btn-synch');
+                var isSyncButton = this.toolbar.btnCollabChanges.$icon.hasClass('btn-synch');
                 if (!isModified && !isSyncButton && !this.toolbar.mode.forcesave)
                     return;
 
diff --git a/apps/presentationeditor/main/app/view/Toolbar.js b/apps/presentationeditor/main/app/view/Toolbar.js
index 84023b454..ae8c0d90c 100644
--- a/apps/presentationeditor/main/app/view/Toolbar.js
+++ b/apps/presentationeditor/main/app/view/Toolbar.js
@@ -173,6 +173,7 @@ define([
                     lock        : [_set.lostConnect],
                     signals     : ['disabled']
                 });
+                me.btnCollabChanges = me.btnSave;
 
                 me.btnUndo = new Common.UI.Button({
                     id          : 'id-toolbar-btn-undo',
@@ -1467,7 +1468,7 @@ define([
             /** coauthoring begin **/
             onCollaborativeChanges: function () {
                 if (this._state.hasCollaborativeChanges) return;
-                if (!this.btnSave.rendered) {
+                if (!this.btnCollabChanges.rendered) {
                     this.needShowSynchTip = true;
                     return;
                 }
@@ -1479,15 +1480,15 @@ define([
                 }
 
                 this._state.hasCollaborativeChanges = true;
-                this.btnSave.$icon.removeClass(this.btnSaveCls).addClass('btn-synch');
+                this.btnCollabChanges.$icon.removeClass(this.btnSaveCls).addClass('btn-synch');
                 if (this.showSynchTip) {
-                    this.btnSave.updateHint('');
+                    this.btnCollabChanges.updateHint('');
                     if (this.synchTooltip === undefined)
                         this.createSynchTip();
 
                     this.synchTooltip.show();
                 } else {
-                    this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
+                    this.btnCollabChanges.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                 }
 
                 this.btnSave.setDisabled(false);
@@ -1496,29 +1497,29 @@ define([
 
             createSynchTip: function () {
                 this.synchTooltip = new Common.UI.SynchronizeTip({
-                    target: $('#id-toolbar-btn-save')
+                    target: this.btnCollabChanges.$el
                 });
                 this.synchTooltip.on('dontshowclick', function () {
                     this.showSynchTip = false;
                     this.synchTooltip.hide();
-                    this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
+                    this.btnCollabChanges.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                     Common.localStorage.setItem("pe-hide-synch", 1);
                 }, this);
                 this.synchTooltip.on('closeclick', function () {
                     this.synchTooltip.hide();
-                    this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
+                    this.btnCollabChanges.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                 }, this);
             },
 
             synchronizeChanges: function () {
-                if (this.btnSave.rendered) {
+                if (this.btnCollabChanges.rendered) {
                     var me = this;
 
-                    if ( me.btnSave.$icon.hasClass('btn-synch') ) {
-                        me.btnSave.$icon.removeClass('btn-synch').addClass(this.btnSaveCls);
+                    if ( me.btnCollabChanges.$icon.hasClass('btn-synch') ) {
+                        me.btnCollabChanges.$icon.removeClass('btn-synch').addClass(this.btnSaveCls);
                         if (this.synchTooltip)
                             this.synchTooltip.hide();
-                        this.btnSave.updateHint(this.btnSaveTip);
+                        this.btnCollabChanges.updateHint(this.btnSaveTip);
                         this.btnSave.setDisabled(!me.mode.forcesave);
 
                         this._state.hasCollaborativeChanges = false;
@@ -1535,12 +1536,12 @@ define([
 
                 var length = _.size(editusers);
                 var cls = (length > 1) ? 'btn-save-coauth' : 'btn-save';
-                if (cls !== this.btnSaveCls && this.btnSave.rendered) {
+                if (cls !== this.btnSaveCls && this.btnCollabChanges.rendered) {
                     this.btnSaveTip = ((length > 1) ? this.tipSaveCoauth : this.tipSave ) + Common.Utils.String.platformKey('Ctrl+S');
 
-                    if ( !this.btnSave.$icon.hasClass('btn-synch') ) {
-                        this.btnSave.$icon.removeClass(this.btnSaveCls).addClass(cls);
-                        this.btnSave.updateHint(this.btnSaveTip);
+                    if ( !this.btnCollabChanges.$icon.hasClass('btn-synch') ) {
+                        this.btnCollabChanges.$icon.removeClass(this.btnSaveCls).addClass(cls);
+                        this.btnCollabChanges.updateHint(this.btnSaveTip);
                     }
                     this.btnSaveCls = cls;
                 }
diff --git a/apps/spreadsheeteditor/main/app/controller/Toolbar.js b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
index 6c6ed4809..87b9d0c06 100644
--- a/apps/spreadsheeteditor/main/app/controller/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
@@ -386,7 +386,7 @@ define([
         onSave: function(e) {
             if (this.api) {
                 var isModified = this.api.asc_isDocumentCanSave();
-                var isSyncButton = this.toolbar.btnSave.$icon.hasClass('btn-synch');
+                var isSyncButton = this.toolbar.btnCollabChanges.$icon.hasClass('btn-synch');
                 if (!isModified && !isSyncButton && !this.toolbar.mode.forcesave)
                     return;
 
diff --git a/apps/spreadsheeteditor/main/app/view/Toolbar.js b/apps/spreadsheeteditor/main/app/view/Toolbar.js
index 537958d85..ad33156ae 100644
--- a/apps/spreadsheeteditor/main/app/view/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/view/Toolbar.js
@@ -375,6 +375,7 @@ define([
                     iconCls     : 'no-mask ' + me.btnSaveCls,
                     signals     : ['disabled']
                 });
+                me.btnCollabChanges = me.btnSave;
 
                 me.btnIncFontSize = new Common.UI.Button({
                     id          : 'id-toolbar-btn-incfont',
@@ -1221,7 +1222,7 @@ define([
 
                 var hidetip = Common.localStorage.getItem("sse-hide-synch");
                 me.showSynchTip = !(hidetip && parseInt(hidetip) == 1);
-                me.needShowSynchTip = false;
+                // me.needShowSynchTip = false;
             }
 
             me.lockControls = [
@@ -1822,22 +1823,22 @@ define([
 
         onApiCollaborativeChanges: function() {
             if (this._state.hasCollaborativeChanges) return;
-            if (!this.btnSave.rendered) {
-                this.needShowSynchTip = true;
+            if (!this.btnCollabChanges.rendered) {
+                // this.needShowSynchTip = true;
                 return;
             }
 
             this._state.hasCollaborativeChanges = true;
-            this.btnSave.$icon.removeClass(this.btnSaveCls).addClass('btn-synch');
+            this.btnCollabChanges.$icon.removeClass(this.btnSaveCls).addClass('btn-synch');
 
             if (this.showSynchTip){
-                this.btnSave.updateHint('');
+                this.btnCollabChanges.updateHint('');
                 if (this.synchTooltip===undefined)
                     this.createSynchTip();
 
                 this.synchTooltip.show();
             } else {
-                this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
+                this.btnCollabChanges.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
             }
 
             this.btnSave.setDisabled(false);
@@ -1846,29 +1847,29 @@ define([
 
         createSynchTip: function () {
             this.synchTooltip = new Common.UI.SynchronizeTip({
-                target    : $('#id-toolbar-btn-save')
+                target: this.btnCollabChanges.$el
             });
             this.synchTooltip.on('dontshowclick', function() {
                 this.showSynchTip = false;
                 this.synchTooltip.hide();
-                this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
+                this.btnCollabChanges.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
                 Common.localStorage.setItem('sse-hide-synch', 1);
             }, this);
             this.synchTooltip.on('closeclick', function() {
                 this.synchTooltip.hide();
-                this.btnSave.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
+                this.btnCollabChanges.updateHint(this.tipSynchronize + Common.Utils.String.platformKey('Ctrl+S'));
             }, this);
         },
 
         synchronizeChanges: function() {
-            if (this.btnSave.rendered) {
+            if (this.btnCollabChanges.rendered) {
                 var me = this;
 
-                if ( me.btnSave.$icon.hasClass('btn-synch') ) {
-                    me.btnSave.$icon.removeClass('btn-synch').addClass(this.btnSaveCls);
+                if ( me.btnCollabChanges.$icon.hasClass('btn-synch') ) {
+                    me.btnCollabChanges.$icon.removeClass('btn-synch').addClass(this.btnSaveCls);
                     if (this.synchTooltip)
                         this.synchTooltip.hide();
-                    this.btnSave.updateHint(this.btnSaveTip);
+                    this.btnCollabChanges.updateHint(this.btnSaveTip);
                     this.btnSave.setDisabled(!me.mode.forcesave);
 
                     this._state.hasCollaborativeChanges = false;
@@ -1885,12 +1886,12 @@ define([
 
             var length = _.size(editusers);
             var cls = (length>1) ? 'btn-save-coauth' : 'btn-save';
-            if (cls !== this.btnSaveCls && this.btnSave.rendered) {
+            if (cls !== this.btnSaveCls && this.btnCollabChanges.rendered) {
                 this.btnSaveTip = ((length>1) ? this.tipSaveCoauth : this.tipSave )+ Common.Utils.String.platformKey('Ctrl+S');
 
-                if ( !this.btnSave.$icon.hasClass('btn-synch') ) {
-                    this.btnSave.$icon.removeClass(this.btnSaveCls).addClass(cls);
-                    this.btnSave.updateHint(this.btnSaveTip);
+                if ( !this.btnCollabChanges.$icon.hasClass('btn-synch') ) {
+                    this.btnCollabChanges.$icon.removeClass(this.btnSaveCls).addClass(cls);
+                    this.btnCollabChanges.updateHint(this.btnSaveTip);
                 }
                 this.btnSaveCls = cls;
             }

From 8a9c221eb3e430d900a870d83b3dd3417fef3b8f Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 28 Feb 2018 16:22:14 +0300
Subject: [PATCH 26/41] redefine 'save' button for desktop app

---
 apps/documenteditor/main/app/controller/Viewport.js     | 3 +++
 apps/presentationeditor/main/app/controller/Viewport.js | 4 +++-
 apps/spreadsheeteditor/main/app/controller/Viewport.js  | 5 +++++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/apps/documenteditor/main/app/controller/Viewport.js b/apps/documenteditor/main/app/controller/Viewport.js
index c1cc0ea62..b0118523e 100644
--- a/apps/documenteditor/main/app/controller/Viewport.js
+++ b/apps/documenteditor/main/app/controller/Viewport.js
@@ -163,6 +163,9 @@ define([
                 _intvars.set('toolbar-height-normal', _tabs_new_height + _intvars.get('toolbar-height-controls'));
 
                 $filemenu.css('top', _tabs_new_height + _intvars.get('document-title-height'));
+
+                toolbar = me.getApplication().getController('Toolbar').getView();
+                toolbar.btnCollabChanges = me.header.btnSave;
             }
         },
 
diff --git a/apps/presentationeditor/main/app/controller/Viewport.js b/apps/presentationeditor/main/app/controller/Viewport.js
index 6d80c3200..bd7495fea 100644
--- a/apps/presentationeditor/main/app/controller/Viewport.js
+++ b/apps/presentationeditor/main/app/controller/Viewport.js
@@ -100,7 +100,6 @@ define([
                     'save:disabled' : function (state) {
                         if ( me.header.btnSave )
                             me.header.btnSave.setDisabled(state);
-                        console.log('header save: ' + state);
                     }
                 },
                 // Events generated by main view
@@ -167,6 +166,9 @@ define([
                 _intvars.set('toolbar-height-normal', _tabs_new_height + _intvars.get('toolbar-height-controls'));
 
                 $filemenu.css('top', _tabs_new_height + _intvars.get('document-title-height'));
+
+                toolbar = me.getApplication().getController('Toolbar').getView('Toolbar');
+                toolbar.btnCollabChanges = me.header.btnSave;
             }
         },
 
diff --git a/apps/spreadsheeteditor/main/app/controller/Viewport.js b/apps/spreadsheeteditor/main/app/controller/Viewport.js
index 9998b0722..93ddc559a 100644
--- a/apps/spreadsheeteditor/main/app/controller/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/controller/Viewport.js
@@ -76,6 +76,11 @@ define([
                         var config = SSE.getController('Main').appOptions;
                         toolbar.setExtra('right', me.header.getPanel('right', config));
                         toolbar.setExtra('left', me.header.getPanel('left', config));
+
+                        if ( me.appConfig && me.appConfig.isDesktopApp &&
+                                me.appConfig.isEdit && toolbar.btnCollabChanges )
+                            toolbar.btnCollabChanges = me.header.btnSave;
+
                     },
                     'view:compact'  : function (toolbar, state) {
                         me.viewport.vlayout.getItem('toolbar').height = state ?

From 9dcf65d8dfe731d3bc99d1a2c465cd11e993d380 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 28 Feb 2018 16:24:48 +0300
Subject: [PATCH 27/41] [common] added coauth icons to header's 'save' button

---
 apps/common/main/lib/view/Header.js           | 13 +++++++++++++
 .../main/resources/img/header/buttons.svg     | 18 +++++++++++++++++-
 apps/common/main/resources/less/header.less   | 19 +++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js
index 38e2729e0..e8c86e103 100644
--- a/apps/common/main/lib/view/Header.js
+++ b/apps/common/main/lib/view/Header.js
@@ -496,6 +496,19 @@ define([
                     me.btnUndo = createTitleButton('svg-btn-undo', $('#slot-btn-dt-undo', $html), true);
                     me.btnRedo = createTitleButton('svg-btn-redo', $('#slot-btn-dt-redo', $html), true);
 
+                    if ( me.btnSave.$icon.is('svg') ) {
+                        me.btnSave.$icon.addClass('icon-save');
+                        var _create_use = function (extid, intid) {
+                            var _use = document.createElementNS('http://www.w3.org/2000/svg', 'use');
+                            _use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', extid);
+                            _use.setAttribute('id', intid);
+
+                            return $(_use);
+                        };
+
+                        _create_use('#svg-btn-save-coauth', 'coauth').appendTo(me.btnSave.$icon);
+                        _create_use('#svg-btn-save-sync', 'sync').appendTo(me.btnSave.$icon);
+                    }
                     return $html;
                 }
             },
diff --git a/apps/common/main/resources/img/header/buttons.svg b/apps/common/main/resources/img/header/buttons.svg
index f55f3ea4f..8bb39193b 100644
--- a/apps/common/main/resources/img/header/buttons.svg
+++ b/apps/common/main/resources/img/header/buttons.svg
@@ -35,9 +35,25 @@
     <symbol id="svg-btn-save" viewBox="0 0 20 20">
         <rect x="7" y="13" width="6" height="1"/>
 	    <rect x="7" y="11" width="6" height="1"/>
-	    <path fill="#FFFFFF" d="M13,4H5C4.447,4,4,4.447,4,5v10c0,0.553,0.447,1,1,1h10c0.553,0,1-0.447,1-1V7L13,4z M11,5v2h-1V5H11z
+	    <path d="M13,4H5C4.447,4,4,4.447,4,5v10c0,0.553,0.447,1,1,1h10c0.553,0,1-0.447,1-1V7L13,4z M11,5v2h-1V5H11z
 		 M15,15H5V5h2v3h5V5h0.5L15,7.5V15z"/>
     </symbol>
+    <symbol id="svg-btn-save-coauth" viewBox="0 0 20 20">
+        <path d="M14,9c-2.209,0-4,1.791-4,4c0,0.348,0.059,0.679,0.142,1h1.043C11.072,13.686,11,13.353,11,13
+            c0-1.654,1.346-3,3-3s3,1.346,3,3s-1.346,3-3,3v-1l-2,1.5l2,1.5v-1c2.209,0,4-1.791,4-4S16.209,9,14,9z"/>
+        <rect x="6" y="13" width="3" height="1"/>
+        <rect x="6" y="11" width="3" height="1"/>
+        <path d="M9,15H4V5h2v3h3h2V5h0.5L14,7.5V8h1V7l-3-3H4C3.447,4,3,4.447,3,5v10c0,0.553,0.447,1,1,1h5V15z M9,5h1v2H9 V5z"/>
+    </symbol>
+    <symbol id="svg-btn-save-sync" viewBox="0 0 20 20">
+        <path fill="#FFD112" d="M18,16c0.553,0,1-0.447,1-1v-5c0-0.553-0.447-1-1-1h-7c-0.553,0-1,0.447-1,1v5c0,0.553,0.447,1,1,1h1
+                l1.5,2l1.5-2H18z"/>
+        <rect x="12" y="11" fill="#444444" width="5" height="1"/>
+        <rect x="12" y="13" fill="#444444" width="5" height="1"/>
+        <rect x="6" y="13" width="3" height="1"/>
+        <rect x="6" y="11" width="3" height="1"/>
+        <path d="M9,15H4V5h2v3h3h2V5h0.5L14,7.5V8h1V7l-3-3H4C3.447,4,3,4.447,3,5v10c0,0.553,0.447,1,1,1h5V15z M9,5h1v2H9 V5z"/>
+    </symbol>
     <symbol id="svg-btn-undo" viewBox="0 0 20 20">
         <path d="M11.355,7.625c-1.965,0-3.864,0.777-5.151,2.033L4,7.625V14h6.407l-2.091-2.219
 		c0.845-1.277,2.313-2.215,3.99-2.215c2.461,0,5.405,1.78,5.694,4.119C17.601,10.291,14.966,7.625,11.355,7.625z"/>
diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less
index e53a67037..1e6988336 100644
--- a/apps/common/main/resources/less/header.less
+++ b/apps/common/main/resources/less/header.less
@@ -289,6 +289,25 @@
 
     svg.icon {
         fill: #fff;
+
+        &.icon-save {
+            &.btn-save-coauth, &.btn-synch {
+                use:first-child {
+                    display: none;
+                }
+            }
+
+            &:not(.btn-save-coauth) {
+                use#coauth {
+                    display: none;
+                }
+            }
+            &:not(.btn-synch) {
+                use#sync {
+                    display: none;
+                }
+            }
+        }
     }
 
     #title-doc-name {

From 19b0d197929e5356611b88262c5c545b63d9fb71 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 28 Feb 2018 16:31:59 +0300
Subject: [PATCH 28/41] [common] centered document title

---
 apps/common/main/lib/view/Header.js         | 1 +
 apps/common/main/resources/less/header.less | 8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js
index e8c86e103..bdf17cd8e 100644
--- a/apps/common/main/lib/view/Header.js
+++ b/apps/common/main/lib/view/Header.js
@@ -109,6 +109,7 @@ define([
                                     '<div class="btn-slot" id="slot-btn-dt-undo"></div>' +
                                     '<div class="btn-slot" id="slot-btn-dt-redo"></div>' +
                                 '</div>' +
+                                '<div class="lr-separator"></div>' +
                                 '<input type="text" id="title-doc-name" spellcheck="false" data-can-copy="false" style="pointer-events: none;">' +
                                 '<label id="title-user-name" style="pointer-events: none;"></label>' +
                             '</section>';
diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less
index 1e6988336..fe8398aee 100644
--- a/apps/common/main/resources/less/header.less
+++ b/apps/common/main/resources/less/header.less
@@ -282,6 +282,7 @@
     display: flex;
     height: 100%;
     color:#fff;
+    position: relative;
 
     .btn-slot {
         display: inline-block;
@@ -311,13 +312,14 @@
     }
 
     #title-doc-name {
-        flex-grow: 1;
+        position: absolute;
         white-space: nowrap;
         text-overflow: ellipsis;
         overflow: hidden;
         text-align: center;
         font-size: 12px;
         height: 100%;
+        width: 100%;
         background-color: transparent;
         border: 0 none;
         cursor: default;
@@ -333,4 +335,8 @@
         padding: 0 12px;
         line-height: @height-title;
    }
+
+    .lr-separator {
+        flex-grow: 1;
+    }
 }

From 794d08ea9cae7bb60db217403bf87a10daf796b1 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 28 Feb 2018 16:33:04 +0300
Subject: [PATCH 29/41] [common] changed synchronize tooltip markup

---
 .../main/resources/less/synchronize-tip.less  | 31 +++++++++++++------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/apps/common/main/resources/less/synchronize-tip.less b/apps/common/main/resources/less/synchronize-tip.less
index df5b141c9..b018a7aff 100644
--- a/apps/common/main/resources/less/synchronize-tip.less
+++ b/apps/common/main/resources/less/synchronize-tip.less
@@ -9,16 +9,19 @@
     }
 
     &.right {
-        margin: -32px 0 0 15px;
+        margin: 0 0 0 15px;
 
         .tip-arrow {
             left: -15px;
-            top: 20px;
-            width: 15px;
-            height: 30px;
+            top: 0;
+            width: 16px;
+            height: 15px;
+            .box-shadow(0 -5px 8px -5px rgba(0, 0, 0, 0.2));
+
             &:after {
-                top: 5px;
-                left: 8px;
+                top: -7px;
+                left: 6px;
+                width: 16px;
             }
         }
     }
@@ -42,13 +45,15 @@
         margin: 0 -32px 15px 0;
 
         .tip-arrow {
-            right: 15px;
+            right: 0;
             bottom: -15px;
-            width: 30px;
+            width: 15px;
             height: 15px;
+            .box-shadow(5px 0 8px -5px rgba(0, 0, 0, 0.2));
+
             &:after {
                 top: -8px;
-                left: 5px;
+                left: 8px;
             }
         }
     }
@@ -60,6 +65,14 @@
     background-color: #fcfed7;
     overflow: visible;
 
+    .right & {
+        border-top-left-radius: 0;
+    }
+
+    .top & {
+        border-bottom-right-radius: 0;
+    }
+
     .box-shadow(0 4px 15px -2px rgba(0, 0, 0, 0.5));
     font-size: 11px;
 }

From 321a92bf7f7e6b5e664d85459187aeab42d8e1f2 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Sun, 4 Mar 2018 23:23:26 +0300
Subject: [PATCH 30/41] [DE] refactoring

---
 apps/documenteditor/main/app/controller/Main.js         | 2 +-
 apps/presentationeditor/main/app/controller/LeftMenu.js | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js
index 937e55832..15d935a67 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -1512,7 +1512,7 @@ define([
                 var toolbarView = this.getApplication().getController('Toolbar').getView();
 
                 if (toolbarView && !toolbarView._state.previewmode) {
-                    var isSyncButton = $('.icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
+                    var isSyncButton = toolbarView.btnSave.$icon.hasClass('btn-synch'),
                         forcesave = this.appOptions.forcesave,
                         isDisabled = !isModified && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave;
                         toolbarView.btnSave.setDisabled(isDisabled);
diff --git a/apps/presentationeditor/main/app/controller/LeftMenu.js b/apps/presentationeditor/main/app/controller/LeftMenu.js
index 0682a1652..6b036422a 100644
--- a/apps/presentationeditor/main/app/controller/LeftMenu.js
+++ b/apps/presentationeditor/main/app/controller/LeftMenu.js
@@ -308,7 +308,6 @@ define([
 
         changeToolbarSaveState: function (state) {
             this.leftMenu.menuFile.getButton('save').setDisabled(state);
-            console.log('save: ' + state);
         },
 
         /** coauthoring begin **/

From 9f289a6392c4757bcf20589851d4f84812b69f7a Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Sun, 4 Mar 2018 23:25:00 +0300
Subject: [PATCH 31/41] [DE] button 'save' disabled in wrong way

---
 apps/documenteditor/main/app/controller/Toolbar.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js
index 42eee2857..b5dc426f7 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -231,7 +231,6 @@ define([
 
             toolbar.btnPrint.on('click',                                _.bind(this.onPrint, this));
             toolbar.btnSave.on('click',                                 _.bind(this.onSave, this));
-            toolbar.btnSave.on('disabled',                              _.bind(this.onBtnChangeState, this, 'save:disabled'));
             toolbar.btnUndo.on('click',                                 _.bind(this.onUndo, this));
             toolbar.btnUndo.on('disabled',                              _.bind(this.onBtnChangeState, this, 'undo:disabled'));
             toolbar.btnRedo.on('click',                                 _.bind(this.onRedo, this));
@@ -2762,6 +2761,8 @@ define([
                     me.toolbar.addTab(tab, $panel, 4);
 
                 if ( config.isDesktopApp ) {
+                    me.toolbar.btnSave.on('disabled', _.bind(me.onBtnChangeState, me, 'save:disabled'));
+
                     // hide 'print' and 'save' buttons group and next separator
                     me.toolbar.btnPrint.$el.parents('.group').hide().next().hide();
 

From 217e7afeaaf37667298b6c6c3ac31eb5b469a0f1 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Fri, 9 Mar 2018 00:48:47 +0300
Subject: [PATCH 32/41] [DE] unlocked version history for desktop app

---
 apps/api/documents/api.js                       | 1 -
 apps/documenteditor/main/app/controller/Main.js | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js
index 2d8544be1..631c20c73 100644
--- a/apps/api/documents/api.js
+++ b/apps/api/documents/api.js
@@ -363,7 +363,6 @@
                 if (result[1] == 'desktop') {
                     _config.editorConfig.targetApp = result[1];
                     // _config.editorConfig.canBackToFolder = false;
-                    _config.editorConfig.canUseHistory = false;
                     if (!_config.editorConfig.customization) _config.editorConfig.customization = {};
                     _config.editorConfig.customization.about = false;
                 }
diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js
index 15d935a67..6ab590526 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -1065,7 +1065,7 @@ define([
                                                  (!this.appOptions.isReviewOnly || this.appOptions.canLicense); // if isReviewOnly==true -> canLicense must be true
                 this.appOptions.isEdit         = this.appOptions.canLicense && this.appOptions.canEdit && this.editorConfig.mode !== 'view';
                 this.appOptions.canReview      = this.permissions.review === true && this.appOptions.canLicense && this.appOptions.isEdit;
-                this.appOptions.canUseHistory  = this.appOptions.canLicense && this.editorConfig.canUseHistory && this.appOptions.canCoAuthoring && !this.appOptions.isDesktopApp;
+                this.appOptions.canUseHistory  = this.appOptions.canLicense && this.editorConfig.canUseHistory && this.appOptions.canCoAuthoring;
                 this.appOptions.canHistoryClose  = this.editorConfig.canHistoryClose;
                 this.appOptions.canHistoryRestore= this.editorConfig.canHistoryRestore && !!this.permissions.changeHistory;
                 this.appOptions.canUseMailMerge= this.appOptions.canLicense && this.appOptions.canEdit && !this.appOptions.isOffline;

From b50749f5721fe5f092d77b840c301fdc62702554 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Fri, 9 Mar 2018 01:01:28 +0300
Subject: [PATCH 33/41] element with id=title inserted in some data views

---
 apps/documenteditor/main/app/template/Viewport.template     | 2 +-
 apps/documenteditor/main/app/view/Viewport.js               | 2 +-
 apps/presentationeditor/main/app/template/Viewport.template | 2 +-
 apps/presentationeditor/main/app/view/Viewport.js           | 2 +-
 apps/spreadsheeteditor/main/app/template/Viewport.template  | 2 +-
 apps/spreadsheeteditor/main/app/view/Viewport.js            | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/apps/documenteditor/main/app/template/Viewport.template b/apps/documenteditor/main/app/template/Viewport.template
index 7b9070236..40c1ea100 100644
--- a/apps/documenteditor/main/app/template/Viewport.template
+++ b/apps/documenteditor/main/app/template/Viewport.template
@@ -3,7 +3,7 @@
         <section class="layout-ct">
             <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
         </section>
-        <section id="title" class="layout-item"></section>
+        <section id="app-title" class="layout-item"></section>
         <div id="toolbar" class="layout-item"></div>
         <div class="layout-item middle">
             <div id="viewport-hbox-layout" class="layout-ct hbox">
diff --git a/apps/documenteditor/main/app/view/Viewport.js b/apps/documenteditor/main/app/view/Viewport.js
index fb1fd87d8..08de444b8 100644
--- a/apps/documenteditor/main/app/view/Viewport.js
+++ b/apps/documenteditor/main/app/view/Viewport.js
@@ -83,7 +83,7 @@ define([
             this.vlayout = new Common.UI.VBoxLayout({
                 box: $container,
                 items: [{
-                        el: $container.find('> .layout-item#title').hide(),
+                        el: $container.find('> .layout-item#app-title').hide(),
                         alias: 'title',
                         height: Common.Utils.InternalSettings.get('document-title-height')
                     }, {
diff --git a/apps/presentationeditor/main/app/template/Viewport.template b/apps/presentationeditor/main/app/template/Viewport.template
index 064d0a777..960edecea 100644
--- a/apps/presentationeditor/main/app/template/Viewport.template
+++ b/apps/presentationeditor/main/app/template/Viewport.template
@@ -4,7 +4,7 @@
         <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
     </section>
     <div id="viewport-vbox-layout" class="layout-ct vbox">
-        <section id="title" class="layout-item"></section>
+        <section id="app-title" class="layout-item"></section>
         <div id="toolbar" class="layout-item"></div>
         <div class="layout-item middle">
             <div id="viewport-hbox-layout" class="layout-ct hbox">
diff --git a/apps/presentationeditor/main/app/view/Viewport.js b/apps/presentationeditor/main/app/view/Viewport.js
index 926a4ef3a..421a73793 100644
--- a/apps/presentationeditor/main/app/view/Viewport.js
+++ b/apps/presentationeditor/main/app/view/Viewport.js
@@ -86,7 +86,7 @@ define([
             this.vlayout = new Common.UI.VBoxLayout({
                 box: $container,
                 items: [{
-                    el: $container.find('> .layout-item#title').hide(),
+                    el: $container.find('> .layout-item#app-title').hide(),
                     alias: 'title',
                     height: Common.Utils.InternalSettings.get('document-title-height')
                 }, {
diff --git a/apps/spreadsheeteditor/main/app/template/Viewport.template b/apps/spreadsheeteditor/main/app/template/Viewport.template
index 90a065c83..e9dd6ee38 100644
--- a/apps/spreadsheeteditor/main/app/template/Viewport.template
+++ b/apps/spreadsheeteditor/main/app/template/Viewport.template
@@ -3,7 +3,7 @@
         <section class="layout-ct">
             <div id="file-menu-panel" class="toolbar-fullview-panel" style="display:none;"></div>
         </section>
-        <section id="title" class="layout-item"></section>
+        <section id="app-title" class="layout-item"></section>
         <div id="toolbar" class="layout-item"></div>
         <div class="layout-item">
             <div id="viewport-hbox-layout" class="layout-ct hbox">
diff --git a/apps/spreadsheeteditor/main/app/view/Viewport.js b/apps/spreadsheeteditor/main/app/view/Viewport.js
index 416239c73..66f1e1ace 100644
--- a/apps/spreadsheeteditor/main/app/view/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/view/Viewport.js
@@ -86,7 +86,7 @@ define([
             this.vlayout = new Common.UI.VBoxLayout({
                 box: $container,
                 items: [{
-                    el: $container.find('> .layout-item#title').hide(),
+                    el: $container.find('> .layout-item#app-title').hide(),
                     alias: 'title',
                     height: Common.Utils.InternalSettings.get('document-title-height')
                 },{

From 0ee904ab39a2147edb554c1ad71176032bd0f061 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 14 Mar 2018 17:54:25 +0300
Subject: [PATCH 34/41] [ALL] removed event for desktop

---
 apps/common/main/lib/controller/Desktop.js     | 4 ----
 apps/documenteditor/main/index.html.deploy     | 4 ----
 apps/presentationeditor/main/index.html.deploy | 4 ----
 apps/spreadsheeteditor/main/index.html.deploy  | 4 ----
 4 files changed, 16 deletions(-)

diff --git a/apps/common/main/lib/controller/Desktop.js b/apps/common/main/lib/controller/Desktop.js
index a395d131a..add4de842 100644
--- a/apps/common/main/lib/controller/Desktop.js
+++ b/apps/common/main/lib/controller/Desktop.js
@@ -45,10 +45,6 @@ define([
         var config = {};
         var app = window.AscDesktopEditor;
 
-        // if ( app ) {
-            // app.execCommand('doc:onload', '');
-        // }
-
         return {
             init: function (opts) {
                 _.extend(config, opts);
diff --git a/apps/documenteditor/main/index.html.deploy b/apps/documenteditor/main/index.html.deploy
index c400cc771..9c673db2f 100644
--- a/apps/documenteditor/main/index.html.deploy
+++ b/apps/documenteditor/main/index.html.deploy
@@ -217,10 +217,6 @@
                     .replace(/>/g, '&gt;');
         }
 
-        if ( window.AscDesktopEditor ) {
-            window.AscDesktopEditor.execCommand('doc:onload', '');
-        }
-
         var params = getUrlParams(),
             lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
             customer = params["customer"] ? ('<div class="loader-page-text-customer">' + encodeUrlParam(params["customer"]) + '</div>') : '',
diff --git a/apps/presentationeditor/main/index.html.deploy b/apps/presentationeditor/main/index.html.deploy
index e53735d94..8ee29fc49 100644
--- a/apps/presentationeditor/main/index.html.deploy
+++ b/apps/presentationeditor/main/index.html.deploy
@@ -217,10 +217,6 @@
                     .replace(/>/g, '&gt;');
         }
 
-        if ( window.AscDesktopEditor ) {
-            window.AscDesktopEditor.execCommand('doc:onload', '');
-        }
-
         var params = getUrlParams(),
             lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
             customer = params["customer"] ? ('<div class="loader-page-text-customer">' + encodeUrlParam(params["customer"]) + '</div>') : '',
diff --git a/apps/spreadsheeteditor/main/index.html.deploy b/apps/spreadsheeteditor/main/index.html.deploy
index f1bcef03e..9f4009e4d 100644
--- a/apps/spreadsheeteditor/main/index.html.deploy
+++ b/apps/spreadsheeteditor/main/index.html.deploy
@@ -216,10 +216,6 @@
                     .replace(/>/g, '&gt;');
         }
 
-        if ( window.AscDesktopEditor ) {
-            window.AscDesktopEditor.execCommand('doc:onload', '');
-        }
-
         var params = getUrlParams(),
             lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
             customer = params["customer"] ? ('<div class="loader-page-text-customer">' + encodeUrlParam(params["customer"]) + '</div>') : '',

From 958355cf4a1d5123c80c39f3079932f92e5b1dae Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 14 Mar 2018 17:55:34 +0300
Subject: [PATCH 35/41] [ALL] notify desktop about event

---
 apps/api/documents/api.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js
index 631c20c73..aba6e716c 100644
--- a/apps/api/documents/api.js
+++ b/apps/api/documents/api.js
@@ -365,6 +365,8 @@
                     // _config.editorConfig.canBackToFolder = false;
                     if (!_config.editorConfig.customization) _config.editorConfig.customization = {};
                     _config.editorConfig.customization.about = false;
+
+                    if ( window.AscDesktopEditor ) window.AscDesktopEditor.execCommand('webapps:events', 'loading');
                 }
             }
         })();

From a2afa4b7fec2d78a6d3a0be57003d871cdfff9c4 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 21 Mar 2018 14:11:03 +0300
Subject: [PATCH 36/41] [Common] added 'settings' button

---
 apps/common/main/lib/view/Header.js           | 30 +++++++++++++++----
 .../main/resources/img/header/buttons.svg     |  9 ++++--
 apps/common/main/resources/less/header.less   | 19 +++++++++++-
 3 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js
index 8032fcdba..64d3d6ae6 100644
--- a/apps/common/main/lib/view/Header.js
+++ b/apps/common/main/lib/view/Header.js
@@ -95,6 +95,7 @@ define([
                             '</div>' +
                             '<div class="hedset">' +
                                 '<div class="btn-slot" id="slot-btn-back"></div>' +
+                                '<div class="btn-slot" id="slot-btn-options"></div>' +
                             '</div>' +
                         '</section>';
 
@@ -216,6 +217,8 @@ define([
             }
         }
 
+        function onAppShowed(config) {}
+
         function onAppReady(mode) {
             appConfig = mode;
 
@@ -318,6 +321,9 @@ define([
                     });
                 }
             }
+
+            if ( me.btnOptions )
+                me.btnOptions.updateHint(me.tipViewSettings);
         }
 
         function onDocNameKeyDown(e) {
@@ -393,9 +399,18 @@ define([
                     reset   : onResetUsers
                 });
 
+                me.btnOptions = new Common.UI.Button({
+                    cls: 'btn-header no-caret',
+                    iconCls: 'svgicon svg-btn-options',
+                    menu: true
+                });
+
                 Common.NotificationCenter.on('app:ready', function(mode) {
                     Common.Utils.asyncCall(onAppReady, me, mode);
                 });
+                Common.NotificationCenter.on('app:face', function(mode) {
+                    Common.Utils.asyncCall(onAppShowed, me, mode);
+                });
             },
 
             render: function (el, role) {
@@ -468,6 +483,8 @@ define([
 
                         if ( config.canEdit && config.canRequestEditRights )
                             this.btnEdit = createTitleButton('svg-btn-edit', $html.find('#slot-hbtn-edit'));
+                    } else {
+                        me.btnOptions.render($html.find('#slot-btn-options'));
                     }
 
                     $userList = $html.find('.cousers-list');
@@ -657,18 +674,19 @@ define([
                                 btn.keepState = {
                                     disabled: btn.isDisabled()
                                 };
+                                btn.setDisabled( true );
                             } else {
                                 btn.setDisabled( btn.keepState.disabled );
-                                delete me.btnUndo.keepState;
+                                delete btn.keepState;
                             }
                         }
                     }
 
-                    if ( alias == 'undo' ) {
-                        _lockButton(me.btnUndo);
-                    } else
-                    if ( alias == 'redo' ) {
-                        _lockButton(me.btnRedo);
+                    switch ( alias ) {
+                    case 'undo': _lockButton(me.btnUndo); break;
+                    case 'redo': _lockButton(me.btnRedo); break;
+                    case 'opts': _lockButton(me.btnOptions); break;
+                    default: break;
                     }
                 }
             },
diff --git a/apps/common/main/resources/img/header/buttons.svg b/apps/common/main/resources/img/header/buttons.svg
index 8bb39193b..637a73f15 100644
--- a/apps/common/main/resources/img/header/buttons.svg
+++ b/apps/common/main/resources/img/header/buttons.svg
@@ -59,7 +59,12 @@
 		c0.845-1.277,2.313-2.215,3.99-2.215c2.461,0,5.405,1.78,5.694,4.119C17.601,10.291,14.966,7.625,11.355,7.625z"/>
     </symbol>
     <symbol id="svg-btn-redo" viewBox="0 0 20 20">
-    	<path d="M10.645,7.625c1.965,0,3.863,0.777,5.15,2.033L18,7.625V14h-6.406l2.09-2.219
-		c-0.845-1.277-2.313-2.215-3.989-2.215c-2.461,0-5.405,1.78-5.694,4.119C4.399,10.291,7.034,7.625,10.645,7.625z"/>
+        <path d="M10.645,7.625c1.965,0,3.863,0.777,5.15,2.033L18,7.625V14h-6.406l2.09-2.219
+        c-0.845-1.277-2.313-2.215-3.989-2.215c-2.461,0-5.405,1.78-5.694,4.119C4.399,10.291,7.034,7.625,10.645,7.625z"/>
+    </symbol>
+    <symbol id="svg-btn-options" viewBox="0 0 20 20">
+        <rect x="4" y="6" width="12" height="1"/>
+        <rect x="4" y="9" width="12" height="1"/>
+        <rect x="4" y="12" width="12" height="1"/>
     </symbol>
 </svg>
diff --git a/apps/common/main/resources/less/header.less b/apps/common/main/resources/less/header.less
index fe8398aee..782457e60 100644
--- a/apps/common/main/resources/less/header.less
+++ b/apps/common/main/resources/less/header.less
@@ -62,6 +62,12 @@
         color: #fff;
     }
 
+    .dropdown-menu {
+        label {
+            color: @gray-deep;
+        }
+    }
+
     .btn-users,
     .btn-header {
         &:hover {
@@ -70,7 +76,7 @@
             }
         }
 
-        &:active {
+        &:active, &.active {
             &:not(.disabled) {
                 background-color: rgba(0,0,0,0.2);
             }
@@ -242,6 +248,11 @@
 .hedset {
     font-size: 0;
     display: flex;
+
+    .btn-group {
+        height: 100%;
+    }
+
 }
 
 .btn-header {
@@ -275,6 +286,12 @@
             background-color: rgba(0,0,0,0.2);
         }
     }
+
+    &.no-caret {
+        .inner-box-caret {
+            display: none;
+        }
+    }
 }
 
 #box-document-title {

From dbf06b62fe4fd0210a0266e9d689673a923e6ad6 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 21 Mar 2018 14:28:28 +0300
Subject: [PATCH 37/41] [ALL] added menu for 'options' button

---
 apps/common/main/lib/view/Header.js           |  18 +-
 .../main/app/controller/LeftMenu.js           |   1 +
 .../main/app/controller/Statusbar.js          |  10 +
 .../main/app/controller/Toolbar.js            |  78 +-------
 .../main/app/controller/Viewport.js           | 151 +++++++++++++-
 .../main/app/template/Toolbar.template        |  11 +-
 apps/documenteditor/main/app/view/Toolbar.js  | 104 +---------
 apps/documenteditor/main/locale/en.json       |  26 ++-
 .../main/app/controller/LeftMenu.js           |   1 +
 .../main/app/controller/Statusbar.js          |  10 +
 .../main/app/controller/Toolbar.js            |  91 +--------
 .../main/app/controller/Viewport.js           | 149 +++++++++++++-
 .../main/app/template/Toolbar.template        |  11 +-
 .../main/app/view/Toolbar.js                  | 105 +---------
 apps/presentationeditor/main/locale/en.json   |  26 ++-
 .../main/app/controller/CellEditor.js         |   7 +
 .../main/app/controller/LeftMenu.js           |   1 +
 .../main/app/controller/Toolbar.js            |  84 +-------
 .../main/app/controller/Viewport.js           | 187 +++++++++++++++++-
 .../main/app/template/Toolbar.template        |  11 +-
 .../main/app/view/Toolbar.js                  | 121 +-----------
 apps/spreadsheeteditor/main/locale/en.json    |  26 ++-
 22 files changed, 600 insertions(+), 629 deletions(-)

diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js
index 64d3d6ae6..405e63780 100644
--- a/apps/common/main/lib/view/Header.js
+++ b/apps/common/main/lib/view/Header.js
@@ -405,6 +405,8 @@ define([
                     menu: true
                 });
 
+                me.mnuZoom = {options: {value: 100}};
+
                 Common.NotificationCenter.on('app:ready', function(mode) {
                     Common.Utils.asyncCall(onAppReady, me, mode);
                 });
@@ -691,6 +693,14 @@ define([
                 }
             },
 
+            fakeMenuItem: function() {
+                return {
+                    conf: {checked: false},
+                    setChecked: function (val) { this.conf.checked = val; },
+                    isChecked: function () { return this.conf.checked; }
+                };
+            },
+
             textBack: 'Go to Documents',
             txtRename: 'Rename',
             textSaveBegin: 'Saving...',
@@ -706,7 +716,13 @@ define([
             tipGoEdit: 'Edit current file',
             tipSave: 'Save',
             tipUndo: 'Undo',
-            tipRedo: 'Redo'
+            tipRedo: 'Redo',
+            textCompactView: 'Hide Toolbar',
+            textHideStatusBar: 'Hide Status Bar',
+            textHideLines: 'Hide Rulers',
+            textZoom: 'Zoom',
+            textAdvSettings: 'Advanced Settings',
+            tipViewSettings: 'View Settings'
         }
     }(), Common.Views.Header || {}))
 });
diff --git a/apps/documenteditor/main/app/controller/LeftMenu.js b/apps/documenteditor/main/app/controller/LeftMenu.js
index a3a5d020a..2be1b2a1c 100644
--- a/apps/documenteditor/main/app/controller/LeftMenu.js
+++ b/apps/documenteditor/main/app/controller/LeftMenu.js
@@ -62,6 +62,7 @@ define([
                 },
                 'Common.Views.Header': {
                     'click:users': _.bind(this.clickStatusbarUsers, this),
+                    'file:settings': _.bind(this.clickToolbarSettings,this),
                     'history:show': function () {
                         if ( !this.leftMenu.panelHistory.isVisible() )
                             this.clickMenuFileItem('header', 'history');
diff --git a/apps/documenteditor/main/app/controller/Statusbar.js b/apps/documenteditor/main/app/controller/Statusbar.js
index d195a7620..35237e80c 100644
--- a/apps/documenteditor/main/app/controller/Statusbar.js
+++ b/apps/documenteditor/main/app/controller/Statusbar.js
@@ -55,6 +55,7 @@ define([
         ],
 
         initialize: function() {
+            var me = this;
             this.addListeners({
                 'Statusbar': {
                     'langchanged': this.onLangMenu,
@@ -62,6 +63,15 @@ define([
                         this.api.zoom(value);
                         Common.NotificationCenter.trigger('edit:complete', this.statusbar);
                     }.bind(this)
+                },
+                'Common.Views.Header': {
+                    'statusbar:hide': function (view, status) {
+                        me.statusbar.setVisible(!status);
+                        Common.localStorage.setBool('de-hidden-status', status);
+
+                        Common.NotificationCenter.trigger('layout:changed', 'status');
+                        Common.NotificationCenter.trigger('edit:complete', this.statusbar);
+                    }
                 }
             });
         },
diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js
index 349989085..87bbe2826 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -114,6 +114,7 @@ define([
                     'menu:show': this.onFileMenu.bind(this, 'show')
                 },
                 'Common.Views.Header': {
+                    'toolbar:setcompact': this.onChangeCompactView.bind(this),
                     'print': function (opts) {
                         var _main = this.getApplication().getController('Main');
                         _main.onPrint();
@@ -296,7 +297,6 @@ define([
             toolbar.btnPageMargins.menu.on('item:click',                _.bind(this.onPageMarginsSelect, this));
             toolbar.btnClearStyle.on('click',                           _.bind(this.onClearStyleClick, this));
             toolbar.btnCopyStyle.on('toggle',                           _.bind(this.onCopyStyleToggle, this));
-            toolbar.btnAdvSettings.on('click',                          _.bind(this.onAdvSettingsClick, this));
             toolbar.mnuPageSize.on('item:click',                        _.bind(this.onPageSizeClick, this));
             toolbar.mnuColorSchema.on('item:click',                     _.bind(this.onColorSchemaClick, this));
             toolbar.btnMailRecepients.on('click',                       _.bind(this.onSelectRecepientsClick, this));
@@ -308,13 +308,6 @@ define([
             toolbar.listStyles.on('click',                              _.bind(this.onListStyleSelect, this));
             toolbar.listStyles.on('contextmenu',                        _.bind(this.onListStyleContextMenu, this));
             toolbar.styleMenu.on('hide:before',                         _.bind(this.onListStyleBeforeHide, this));
-            toolbar.mnuitemHideStatusBar.on('toggle',                   _.bind(this.onHideStatusBar, this));
-            toolbar.mnuitemHideRulers.on('toggle',                      _.bind(this.onHideRulers, this));
-            toolbar.mnuitemCompactToolbar.on('toggle',                  _.bind(this.onChangeCompactView, this));
-            toolbar.btnFitPage.on('toggle',                             _.bind(this.onZoomToPageToggle, this));
-            toolbar.btnFitWidth.on('toggle',                            _.bind(this.onZoomToWidthToggle, this));
-            toolbar.mnuZoomIn.on('click',                               _.bind(this.onZoomInClick, this));
-            toolbar.mnuZoomOut.on('click',                              _.bind(this.onZoomOutClick, this));
             toolbar.btnInsertEquation.on('click',                       _.bind(this.onInsertEquationClick, this));
 
             $('#id-save-style-plus, #id-save-style-link', toolbar.$el).on('click', this.onMenuSaveStyle.bind(this));
@@ -379,7 +372,6 @@ define([
                 var me = this;
                 setTimeout(function () {
                     me.onChangeCompactView(null, !me.toolbar.isCompact());
-                    me.toolbar.mnuitemCompactToolbar.setChecked(me.toolbar.isCompact(), true);
                 }, 0);
             }
         },
@@ -845,12 +837,7 @@ define([
             this.toolbar.mnuInsertPageNum.setDisabled(false);
         },
 
-        onApiZoomChange: function(percent, type) {
-            this.toolbar.btnFitPage.setChecked(type == 2, true);
-            this.toolbar.btnFitWidth.setChecked(type == 1, true);
-            this.toolbar.mnuZoom.options.value = percent;
-            $('.menu-zoom .zoom', this.toolbar.el).html(percent + '%');
-        },
+        onApiZoomChange: function(percent, type) {},
 
         onApiStartHighlight: function(pressed) {
             this.toolbar.btnHighlightColor.toggle(pressed, true);
@@ -1415,11 +1402,6 @@ define([
             this.modeAlwaysSetStyle = state;
         },
 
-        onAdvSettingsClick: function(btn, e) {
-            this.toolbar.fireEvent('file:settings', this);
-            btn.cmpEl.blur();
-        },
-
         onPageSizeClick: function(menu, item, state) {
             if (this.api && state) {
                 this._state.pgsize = [0, 0];
@@ -1993,61 +1975,6 @@ define([
         //     Common.NotificationCenter.trigger('edit:complete', this.toolbar);
         // },
 
-        onHideStatusBar: function(item, checked) {
-            var headerView  = this.getApplication().getController('Statusbar').getView('Statusbar');
-            headerView  && headerView.setVisible(!checked);
-
-            Common.localStorage.setBool('de-hidden-status', checked);
-
-            Common.NotificationCenter.trigger('layout:changed', 'status');
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onHideRulers: function(item, checked) {
-            if (this.api) {
-                this.api.asc_SetViewRulers(!checked);
-            }
-
-            Common.localStorage.setBool('de-hidden-rulers', checked);
-
-            Common.NotificationCenter.trigger('layout:changed', 'rulers');
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onZoomToPageToggle: function(item, state) {
-            if (this.api) {
-                if (state)
-                    this.api.zoomFitToPage();
-                else
-                    this.api.zoomCustomMode();
-            }
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onZoomToWidthToggle: function(item, state) {
-            if (this.api) {
-                if (state)
-                    this.api.zoomFitToWidth();
-                else
-                    this.api.zoomCustomMode();
-            }
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onZoomInClick: function(btn) {
-            if (this.api)
-                this.api.zoomIn();
-
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onZoomOutClick: function(btn) {
-            if (this.api)
-                this.api.zoomOut();
-
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
         _clearBullets: function() {
             this.toolbar.btnMarkers.toggle(false, true);
             this.toolbar.btnNumbers.toggle(false, true);
@@ -2716,7 +2643,6 @@ define([
 
             disable = disable || (reviewmode ? toolbar_mask.length>0 : group_mask.length>0);
             toolbar.$el.find('.toolbar').toggleClass('masked', disable);
-            toolbar.btnHide.setDisabled(disable);
             if ( toolbar.synchTooltip )
                 toolbar.synchTooltip.hide();
 
diff --git a/apps/documenteditor/main/app/controller/Viewport.js b/apps/documenteditor/main/app/controller/Viewport.js
index 93bb5defd..0c889b7c0 100644
--- a/apps/documenteditor/main/app/controller/Viewport.js
+++ b/apps/documenteditor/main/app/controller/Viewport.js
@@ -79,6 +79,7 @@ define([
                         toolbar.setExtra('left', me.header.getPanel('left', config));
                     },
                     'view:compact'  : function (toolbar, state) {
+                        me.header.mnuitemCompactToolbar.setChecked(state, true);
                         me.viewport.vlayout.getItem('toolbar').height = state ?
                                 Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
                     },
@@ -105,6 +106,7 @@ define([
 
         setApi: function(api) {
             this.api = api;
+            this.api.asc_registerCallback('asc_onZoomChange', this.onApiZoomChange.bind(this));
         },
 
 
@@ -130,7 +132,11 @@ define([
             this.boxSdk = $('#editor_sdk');
             this.boxSdk.css('border-left', 'none');
 
+            this.header.mnuitemFitPage = this.header.fakeMenuItem();
+            this.header.mnuitemFitWidth = this.header.fakeMenuItem();
+
             Common.NotificationCenter.on('app:face', this.onAppShowed.bind(this));
+            Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this));
         },
 
         onAppShowed: function (config) {
@@ -169,6 +175,111 @@ define([
             }
         },
 
+        onAppReady: function (config) {
+            var me = this;
+            if ( me.header.btnOptions ) {
+                var compactview = !config.isEdit;
+                if ( config.isEdit ) {
+                    if ( Common.localStorage.itemExists("de-compact-toolbar") ) {
+                        compactview = Common.localStorage.getBool("de-compact-toolbar");
+                    } else
+                    if ( config.customization && config.customization.compactToolbar )
+                        compactview = true;
+                }
+
+                me.header.mnuitemCompactToolbar = new Common.UI.MenuItem({
+                    caption: me.header.textCompactView,
+                    checked: compactview,
+                    checkable: true,
+                    value: 'toolbar'
+                });
+
+                var mnuitemHideStatusBar = new Common.UI.MenuItem({
+                    caption: me.header.textHideStatusBar,
+                    checked: Common.localStorage.getBool("de-hidden-status"),
+                    checkable: true,
+                    value: 'statusbar'
+                });
+
+                if ( config.canBrandingExt && config.customization && config.customization.statusBar === false )
+                    mnuitemHideStatusBar.hide();
+
+                var mnuitemHideRulers = new Common.UI.MenuItem({
+                    caption: me.header.textHideLines,
+                    checked: Common.localStorage.getBool("de-hidden-rulers"),
+                    checkable: true,
+                    value: 'rulers'
+                });
+
+                me.header.mnuitemFitPage = new Common.UI.MenuItem({
+                    caption: me.textFitPage,
+                    checkable: true,
+                    checked: me.header.mnuitemFitPage.isChecked(),
+                    value: 'zoom:page'
+                });
+
+                me.header.mnuitemFitWidth = new Common.UI.MenuItem({
+                    caption: me.textFitWidth,
+                    checkable: true,
+                    checked: me.header.mnuitemFitWidth.isChecked(),
+                    value: 'zoom:width'
+                });
+
+                me.header.mnuZoom = new Common.UI.MenuItem({
+                    template: _.template([
+                        '<div id="hdr-menu-zoom" class="menu-zoom" style="height: 25px;" ',
+                            '<% if(!_.isUndefined(options.stopPropagation)) { %>',
+                                'data-stopPropagation="true"',
+                            '<% } %>', '>',
+                            '<label class="title">' + me.header.textZoom + '</label>',
+                            '<button id="hdr-menu-zoom-in" type="button" style="float:right; margin: 2px 5px 0 0;" class="btn small btn-toolbar"><i class="icon btn-zoomup">&nbsp;</i></button>',
+                            '<label class="zoom"><%= options.value %>%</label>',
+                            '<button id="hdr-menu-zoom-out" type="button" style="float:right; margin-top: 2px;" class="btn small btn-toolbar"><i class="icon btn-zoomdown">&nbsp;</i></button>',
+                        '</div>'
+                    ].join('')),
+                    stopPropagation: true,
+                    value: me.header.mnuZoom.options.value
+                });
+
+                me.header.btnOptions.setMenu(new Common.UI.Menu({
+                        cls: 'pull-right',
+                        style: 'min-width: 180px;',
+                        items: [
+                            me.header.mnuitemCompactToolbar,
+                            mnuitemHideStatusBar,
+                            mnuitemHideRulers,
+                            {caption:'--'},
+                            me.header.mnuitemFitPage,
+                            me.header.mnuitemFitWidth,
+                            me.header.mnuZoom,
+                            {caption:'--'},
+                            new Common.UI.MenuItem({
+                                caption: me.header.textAdvSettings,
+                                value: 'advanced'
+                            })
+                        ]
+                    })
+                );
+
+                var _on_btn_zoom = function (btn) {
+                    btn == 'up' ? me.api.zoomIn() : me.api.zoomOut();
+                    Common.NotificationCenter.trigger('edit:complete', me.header);
+                };
+
+                (new Common.UI.Button({
+                    el      : $('#hdr-menu-zoom-out', me.header.mnuZoom.$el),
+                    cls     : 'btn-toolbar'
+                })).on('click', _on_btn_zoom.bind(me, 'down'));
+
+                (new Common.UI.Button({
+                    el      : $('#hdr-menu-zoom-in', me.header.mnuZoom.$el),
+                    cls     : 'btn-toolbar'
+                })).on('click', _on_btn_zoom.bind(me, 'up'));
+
+                me.header.btnOptions.menu.on('item:click', me.onOptionsItemClick.bind(this));
+            }
+        },
+
         onLayoutChanged: function(area) {
             switch (area) {
             default:
@@ -217,6 +328,42 @@ define([
 
             me.header.lockHeaderBtns( 'undo', _need_disable );
             me.header.lockHeaderBtns( 'redo', _need_disable );
-        }
-    });
+            me.header.lockHeaderBtns( 'opts', _need_disable );
+        },
+
+        onApiZoomChange: function(percent, type) {
+            this.header.mnuitemFitPage.setChecked(type == 2, true);
+            this.header.mnuitemFitWidth.setChecked(type == 1, true);
+            this.header.mnuZoom.options.value = percent;
+
+            if ( this.header.mnuZoom.$el )
+                $('.menu-zoom label.zoom', this.header.mnuZoom.$el).html(percent + '%');
+        },
+
+        onOptionsItemClick: function (menu, item, e) {
+            var me = this;
+
+            switch ( item.value ) {
+            case 'toolbar': me.header.fireEvent('toolbar:setcompact', [menu, item.isChecked()]); break;
+            case 'statusbar': me.header.fireEvent('statusbar:hide', [item, item.isChecked()]); break;
+            case 'rulers':
+                me.api.asc_SetViewRulers(!item.isChecked());
+                Common.localStorage.setBool('de-hidden-rulers', item.isChecked());
+                Common.NotificationCenter.trigger('layout:changed', 'rulers');
+                Common.NotificationCenter.trigger('edit:complete', me.header);
+                break;
+            case 'zoom:page':
+                item.isChecked() ? me.api.zoomFitToPage() : me.api.zoomCustomMode();
+                Common.NotificationCenter.trigger('edit:complete', me.header);
+                break;
+            case 'zoom:width':
+                item.isChecked() ? me.api.zoomFitToWidth() : me.api.zoomCustomMode();
+                Common.NotificationCenter.trigger('edit:complete', me.header);
+                break;
+            case 'advanced': me.header.fireEvent('file:settings', me.header); break;
+            }
+        },
+
+        textFitPage: 'Fit to Page',
+        textFitWidth: 'Fit to Width'
 });
diff --git a/apps/documenteditor/main/app/template/Toolbar.template b/apps/documenteditor/main/app/template/Toolbar.template
index 1c6d10506..6e9d81d96 100644
--- a/apps/documenteditor/main/app/template/Toolbar.template
+++ b/apps/documenteditor/main/app/template/Toolbar.template
@@ -92,16 +92,7 @@
                         <span class="btn-slot" id="slot-btn-mailrecepients"></span>
                     </div>
                 </div>
-                <div class="group" id="slot-field-styles">
-                </div>
-                <div class="group no-mask">
-                    <div class="elset">
-                        <span class="btn-slot split" id="slot-btn-hidebars"></span>
-                    </div>
-                    <div class="elset">
-                        <span class="btn-slot" id="slot-btn-settings"></span>
-                    </div>
-                </div>
+                <div class="group" id="slot-field-styles"></div>
             </section>
             <section class="panel" data-tab="ins">
                 <div class="group">
diff --git a/apps/documenteditor/main/app/view/Toolbar.js b/apps/documenteditor/main/app/view/Toolbar.js
index 15a7c2f74..fc879aaf5 100644
--- a/apps/documenteditor/main/app/view/Toolbar.js
+++ b/apps/documenteditor/main/app/view/Toolbar.js
@@ -944,33 +944,6 @@ define([
                     iconCls: 'btn-mailrecepients'
                 });
 
-                this.btnHide = new Common.UI.Button({
-                    id: 'id-toolbar-btn-hidebars',
-                    cls: 'btn-toolbar',
-                    iconCls: 'btn-hidebars no-mask',
-                    menu: true
-                });
-                this.toolbarControls.push(this.btnHide);
-
-                this.btnFitPage = {
-                    conf: {checked: false},
-                    setChecked: function (val) {
-                        this.conf.checked = val;
-                    },
-                    isChecked: function () {
-                        return this.conf.checked;
-                    }
-                };
-                this.btnFitWidth = clone(this.btnFitPage);
-                this.mnuZoom = {options: {value: 100}};
-
-                this.btnAdvSettings = new Common.UI.Button({
-                    id: 'id-toolbar-btn-settings',
-                    cls: 'btn-toolbar',
-                    iconCls: 'btn-settings no-mask'
-                });
-                this.toolbarControls.push(this.btnAdvSettings);
-
                 me.btnImgAlign = new Common.UI.Button({
                     cls: 'btn-toolbar x-huge icon-top',
                     iconCls: 'btn-img-align',
@@ -1198,9 +1171,9 @@ define([
                     }
                 });
 
+                me.setTab('home');
                 if ( me.isCompactView )
-                    me.setFolded(true); else
-                    me.setTab('home');
+                    me.setFolded(true);
 
                 var top = Common.localStorage.getItem("de-pgmargins-top"),
                     left = Common.localStorage.getItem("de-pgmargins-left"),
@@ -1291,8 +1264,6 @@ define([
                 _injectComponent('#slot-btn-clearstyle', this.btnClearStyle);
                 _injectComponent('#slot-btn-copystyle', this.btnCopyStyle);
                 _injectComponent('#slot-btn-colorschemas', this.btnColorSchemas);
-                _injectComponent('#slot-btn-hidebars', this.btnHide);
-                _injectComponent('#slot-btn-settings', this.btnAdvSettings);
                 _injectComponent('#slot-btn-paracolor', this.btnParagraphColor);
                 _injectComponent('#slot-field-styles', this.listStyles);
                 _injectComponent('#slot-btn-halign', this.btnHorizontalAlign);
@@ -1539,67 +1510,14 @@ define([
                 this.btnCopyStyle.updateHint(this.tipCopyStyle + Common.Utils.String.platformKey('Ctrl+Shift+C'));
                 this.btnColorSchemas.updateHint(this.tipColorSchemas);
                 this.btnMailRecepients.updateHint(this.tipMailRecepients);
-                this.btnHide.updateHint(this.tipViewSettings);
-                this.btnAdvSettings.updateHint(this.tipAdvSettings);
 
                 // set menus
 
                 var me = this;
 
-                this.btnHide.setMenu(new Common.UI.Menu({
-                        cls: 'pull-right',
-                        style: 'min-width: 180px;',
-                        items: [
-                            this.mnuitemCompactToolbar = new Common.UI.MenuItem({
-                                caption: this.textCompactView,
-                                checked: me.isCompactView,
-                                checkable: true
-                            }),
-                            this.mnuitemHideStatusBar = new Common.UI.MenuItem({
-                                caption: this.textHideStatusBar,
-                                checked: Common.localStorage.getBool("de-hidden-status"),
-                                checkable: true
-                            }),
-                            this.mnuitemHideRulers = new Common.UI.MenuItem({
-                                caption: this.textHideLines,
-                                checked: Common.localStorage.getBool("de-hidden-rulers"),
-                                checkable: true
-                            }),
-                            {caption: '--'},
-                            this.btnFitPage = new Common.UI.MenuItem({
-                                caption: this.textFitPage,
-                                checkable: true,
-                                checked: this.btnFitPage.isChecked()
-                            }),
-                            this.btnFitWidth = new Common.UI.MenuItem({
-                                caption: this.textFitWidth,
-                                checkable: true,
-                                checked: this.btnFitWidth.isChecked()
-                            }),
-                            this.mnuZoom = new Common.UI.MenuItem({
-                                template: _.template([
-                                    '<div id="id-toolbar-menu-zoom" class="menu-zoom" style="height: 25px;" ',
-                                    '<% if(!_.isUndefined(options.stopPropagation)) { %>',
-                                    'data-stopPropagation="true"',
-                                    '<% } %>', '>',
-                                    '<label class="title">' + this.textZoom + '</label>',
-                                    '<button id="id-menu-zoom-in" type="button" style="float:right; margin: 2px 5px 0 0;" class="btn small btn-toolbar"><i class="icon btn-zoomup">&nbsp;</i></button>',
-                                    '<label class="zoom"><%= options.value %>%</label>',
-                                    '<button id="id-menu-zoom-out" type="button" style="float:right; margin-top: 2px;" class="btn small btn-toolbar"><i class="icon btn-zoomdown">&nbsp;</i></button>',
-                                    '</div>'
-                                ].join('')),
-                                stopPropagation: true,
-                                value: this.mnuZoom.options.value
-                            })
-                        ]
-                    })
-                );
                 // if (this.mode.isDesktopApp || this.mode.canBrandingExt && this.mode.customization && this.mode.customization.header === false)
                 //     this.mnuitemHideTitleBar.hide();
 
-                if (this.mode.canBrandingExt && this.mode.customization && this.mode.customization.statusBar===false)
-                    this.mnuitemHideStatusBar.hide();
-
                 this.btnMarkers.setMenu(
                     new Common.UI.Menu({
                         style: 'min-width: 139px',
@@ -1657,15 +1575,6 @@ define([
                 this.paragraphControls.push(this.mnuPageNumCurrentPos);
                 this.paragraphControls.push(this.mnuInsertPageCount);
 
-                this.mnuZoomOut = new Common.UI.Button({
-                    el: $('#id-menu-zoom-out'),
-                    cls: 'btn-toolbar'
-                });
-                this.mnuZoomIn = new Common.UI.Button({
-                    el: $('#id-menu-zoom-in'),
-                    cls: 'btn-toolbar'
-                });
-
                 // set dataviews
 
                 var _conf = this.mnuMarkersPicker.conf;
@@ -2305,15 +2214,6 @@ define([
             tipInsertText: 'Insert Text',
             tipInsertTextArt: 'Insert Text Art',
             tipHAligh: 'Horizontal Align',
-            tipViewSettings: 'View Settings',
-            tipAdvSettings: 'Advanced Settings',
-            textCompactView: 'Hide Toolbar',
-            textHideTitleBar: 'Hide Title Bar',
-            textHideStatusBar: 'Hide Status Bar',
-            textHideLines: 'Hide Rulers',
-            textFitPage: 'Fit to Page',
-            textFitWidth: 'Fit to Width',
-            textZoom: 'Zoom',
             mniEditDropCap: 'Drop Cap Settings',
             textNone: 'None',
             textInText: 'In Text',
diff --git a/apps/documenteditor/main/locale/en.json b/apps/documenteditor/main/locale/en.json
index c87840c5d..7f15075c5 100644
--- a/apps/documenteditor/main/locale/en.json
+++ b/apps/documenteditor/main/locale/en.json
@@ -153,6 +153,12 @@
   "Common.Views.Header.tipViewUsers": "View users and manage document access rights",
   "Common.Views.Header.txtAccessRights": "Change access rights",
   "Common.Views.Header.txtRename": "Rename",
+  "Common.Views.Header.textAdvSettings": "Advanced settings",
+  "Common.Views.Header.textCompactView": "Hide Toolbar",
+  "Common.Views.Header.textHideStatusBar": "Hide Status Bar",
+  "Common.Views.Header.textZoom": "Zoom",
+  "Common.Views.Header.tipViewSettings": "View settings",
+  "Common.Views.Header.textHideLines": "Hide Rulers",
   "Common.Views.History.textCloseHistory": "Close History",
   "Common.Views.History.textHide": "Collapse",
   "Common.Views.History.textHideAll": "Hide detailed changes",
@@ -779,6 +785,8 @@
   "DE.Controllers.Toolbar.txtSymbol_vdots": "Vertical ellipsis",
   "DE.Controllers.Toolbar.txtSymbol_xsi": "Xi",
   "DE.Controllers.Toolbar.txtSymbol_zeta": "Zeta",
+  "DE.Controllers.Viewport.textFitPage": "Fit to Page",
+  "DE.Controllers.Viewport.textFitWidth": "Fit to Width",
   "DE.Views.ChartSettings.textAdvanced": "Show advanced settings",
   "DE.Views.ChartSettings.textArea": "Area",
   "DE.Views.ChartSettings.textBar": "Bar",
@@ -1744,14 +1752,14 @@
   "DE.Views.Toolbar.textColumnsRight": "Right",
   "DE.Views.Toolbar.textColumnsThree": "Three",
   "DE.Views.Toolbar.textColumnsTwo": "Two",
-  "DE.Views.Toolbar.textCompactView": "Hide Toolbar",
+  "del_DE.Views.Toolbar.textCompactView": "Hide Toolbar",
   "DE.Views.Toolbar.textContPage": "Continuous Page",
   "DE.Views.Toolbar.textEvenPage": "Even Page",
-  "DE.Views.Toolbar.textFitPage": "Fit to Page",
-  "DE.Views.Toolbar.textFitWidth": "Fit to Width",
-  "DE.Views.Toolbar.textHideLines": "Hide Rulers",
-  "DE.Views.Toolbar.textHideStatusBar": "Hide Status Bar",
-  "DE.Views.Toolbar.textHideTitleBar": "Hide Title Bar",
+  "del_DE.Views.Toolbar.textFitPage": "Fit to Page",
+  "del_DE.Views.Toolbar.textFitWidth": "Fit to Width",
+  "del_DE.Views.Toolbar.textHideLines": "Hide Rulers",
+  "del_DE.Views.Toolbar.textHideStatusBar": "Hide Status Bar",
+  "del_DE.Views.Toolbar.textHideTitleBar": "Hide Title Bar",
   "DE.Views.Toolbar.textInMargin": "In Margin",
   "DE.Views.Toolbar.textInsColumnBreak": "Insert Column Break",
   "DE.Views.Toolbar.textInsertPageCount": "Insert number of pages",
@@ -1805,8 +1813,8 @@
   "DE.Views.Toolbar.textToCurrent": "To current position",
   "DE.Views.Toolbar.textTop": "Top: ",
   "DE.Views.Toolbar.textUnderline": "Underline",
-  "DE.Views.Toolbar.textZoom": "Zoom",
-  "DE.Views.Toolbar.tipAdvSettings": "Advanced settings",
+  "del_DE.Views.Toolbar.textZoom": "Zoom",
+  "del_DE.Views.Toolbar.tipAdvSettings": "Advanced settings",
   "DE.Views.Toolbar.tipAlignCenter": "Align center",
   "DE.Views.Toolbar.tipAlignJust": "Justified",
   "DE.Views.Toolbar.tipAlignLeft": "Align left",
@@ -1862,7 +1870,7 @@
   "DE.Views.Toolbar.tipShowHiddenChars": "Nonprinting characters",
   "DE.Views.Toolbar.tipSynchronize": "The document has been changed by another user. Please click to save your changes and reload the updates.",
   "DE.Views.Toolbar.tipUndo": "Undo",
-  "DE.Views.Toolbar.tipViewSettings": "View settings",
+  "del_DE.Views.Toolbar.tipViewSettings": "View settings",
   "DE.Views.Toolbar.txtScheme1": "Office",
   "DE.Views.Toolbar.txtScheme10": "Median",
   "DE.Views.Toolbar.txtScheme11": "Metro",
diff --git a/apps/presentationeditor/main/app/controller/LeftMenu.js b/apps/presentationeditor/main/app/controller/LeftMenu.js
index eaed9b725..ce96b2837 100644
--- a/apps/presentationeditor/main/app/controller/LeftMenu.js
+++ b/apps/presentationeditor/main/app/controller/LeftMenu.js
@@ -61,6 +61,7 @@ define([
                     'hide': _.bind(this.onHideChat, this)
                 },
                 'Common.Views.Header': {
+                    'file:settings': _.bind(this.clickToolbarSettings,this),
                     'click:users': _.bind(this.clickStatusbarUsers, this)
                 },
                 'Common.Views.Plugins': {
diff --git a/apps/presentationeditor/main/app/controller/Statusbar.js b/apps/presentationeditor/main/app/controller/Statusbar.js
index 00b0364c8..87ef91725 100644
--- a/apps/presentationeditor/main/app/controller/Statusbar.js
+++ b/apps/presentationeditor/main/app/controller/Statusbar.js
@@ -56,12 +56,22 @@ define([
         ],
 
         initialize: function() {
+            var me = this;
             this.addListeners({
                 'FileMenu': {
                     'settings:apply': _.bind(this.applySettings, this)
                 },
                 'Statusbar': {
                     'langchanged': this.onLangMenu
+                },
+                'Common.Views.Header': {
+                    'statusbar:hide': function (view, status) {
+                        me.statusbar.setVisible(!status);
+                        Common.localStorage.setBool('pe-hidden-status', status);
+
+                        Common.NotificationCenter.trigger('layout:changed', 'status');
+                        Common.NotificationCenter.trigger('edit:complete', this.statusbar);
+                    }
                 }
             });
             this._state = {
diff --git a/apps/presentationeditor/main/app/controller/Toolbar.js b/apps/presentationeditor/main/app/controller/Toolbar.js
index 51cb88ead..da523a4e6 100644
--- a/apps/presentationeditor/main/app/controller/Toolbar.js
+++ b/apps/presentationeditor/main/app/controller/Toolbar.js
@@ -129,6 +129,7 @@ define([
                     'menu:show': this.onFileMenu.bind(this, 'show')
                 },
                 'Common.Views.Header': {
+                    'toolbar:setcompact': this.onChangeCompactView.bind(this),
                     'print': function (opts) {
                         var _main = this.getApplication().getController('Main');
                         _main.onPrint();
@@ -293,18 +294,10 @@ define([
             toolbar.btnInsertTable.menu.on('item:click',                _.bind(this.onInsertTableClick, this));
             toolbar.btnClearStyle.on('click',                           _.bind(this.onClearStyleClick, this));
             toolbar.btnCopyStyle.on('toggle',                           _.bind(this.onCopyStyleToggle, this));
-            toolbar.btnAdvSettings.on('click',                          _.bind(this.onAdvSettingsClick, this));
             toolbar.btnColorSchemas.menu.on('item:click',               _.bind(this.onColorSchemaClick, this));
             toolbar.btnSlideSize.menu.on('item:click',                  _.bind(this.onSlideSize, this));
             toolbar.mnuInsertChartPicker.on('item:click',               _.bind(this.onSelectChart, this));
             toolbar.listTheme.on('click',                               _.bind(this.onListThemeSelect, this));
-            toolbar.mnuitemHideStatusBar.on('toggle',                   _.bind(this.onHideStatusBar, this));
-            toolbar.mnuitemHideRulers.on('toggle',                      _.bind(this.onHideRulers, this));
-            toolbar.mnuitemCompactToolbar.on('toggle',                  _.bind(this.onChangeCompactView, this));
-            toolbar.btnFitPage.on('toggle',                             _.bind(this.onZoomToPageToggle, this));
-            toolbar.btnFitWidth.on('toggle',                            _.bind(this.onZoomToWidthToggle, this));
-            toolbar.mnuZoomIn.on('click',                               _.bind(this.onZoomInClick, this));
-            toolbar.mnuZoomOut.on('click',                              _.bind(this.onZoomOutClick, this));
             toolbar.btnInsertEquation.on('click',                       _.bind(this.onInsertEquationClick, this));
         },
 
@@ -369,7 +362,6 @@ define([
                 var me = this;
                 Common.Utils.asyncCall(function () {
                     me.onChangeCompactView(null, !me.toolbar.isCompact());
-                    me.toolbar.mnuitemCompactToolbar.setChecked(me.toolbar.isCompact(), true);
                 });
             }
         },
@@ -775,18 +767,7 @@ define([
             this.editMode = false;
         },
 
-        onApiZoomChange: function(percent, type) {
-            if (this._state.zoom_type !== type) {
-                this.toolbar.btnFitPage.setChecked(type == 2, true);
-                this.toolbar.btnFitWidth.setChecked(type == 1, true);
-                this._state.zoom_type = type;
-            }
-            if (this._state.zoom_percent !== percent) {
-                $('.menu-zoom .zoom', this.toolbar.el).html(percent + '%');
-                this._state.zoom_percent = percent;
-            }
-            this.toolbar.mnuZoom.options.value = percent;
-        },
+        onApiZoomChange: function(percent, type) {},
 
         onApiInitEditorStyles: function(themes) {
             if (themes) {
@@ -1441,11 +1422,6 @@ define([
             this.modeAlwaysSetStyle = state;
         },
 
-        onAdvSettingsClick: function(btn, e) {
-            this.toolbar.fireEvent('file:settings', this);
-            btn.cmpEl.blur();
-        },
-
         onColorSchemaClick: function(menu, item) {
             if (this.api) {
                 this.api.ChangeColorScheme(item.value);
@@ -1559,69 +1535,6 @@ define([
             Common.NotificationCenter.trigger('edit:complete', this.toolbar);
         },
 
-        onHideStatusBar: function(item, checked) {
-            var headerView  = this.getApplication().getController('Statusbar').getView('Statusbar');
-            headerView  && headerView.setVisible(!checked);
-
-            Common.localStorage.setBool('pe-hidden-status', checked);
-
-            Common.NotificationCenter.trigger('layout:changed', 'status');
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onHideRulers: function(item, checked) {
-            if (this.api) {
-                this.api.asc_SetViewRulers(!checked);
-            }
-
-            Common.localStorage.setBool('pe-hidden-rulers', checked);
-
-            Common.NotificationCenter.trigger('layout:changed', 'rulers');
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onZoomToPageToggle: function(item, state) {
-            if (this.api) {
-                this._state.zoom_type = undefined;
-                this._state.zoom_percent = undefined;
-                if (state)
-                    this.api.zoomFitToPage();
-                else
-                    this.api.zoomCustomMode();
-            }
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onZoomToWidthToggle: function(item, state) {
-            if (this.api) {
-                this._state.zoom_type = undefined;
-                this._state.zoom_percent = undefined;
-                if (state)
-                    this.api.zoomFitToWidth();
-                else
-                    this.api.zoomCustomMode();
-            }
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onZoomInClick: function(btn) {
-            this._state.zoom_type = undefined;
-            this._state.zoom_percent = undefined;
-            if (this.api)
-                this.api.zoomIn();
-
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onZoomOutClick: function(btn) {
-            this._state.zoom_type = undefined;
-            this._state.zoom_percent = undefined;
-            if (this.api)
-                this.api.zoomOut();
-
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
         _clearBullets: function() {
             this.toolbar.btnMarkers.toggle(false, true);
             this.toolbar.btnNumbers.toggle(false, true);
diff --git a/apps/presentationeditor/main/app/controller/Viewport.js b/apps/presentationeditor/main/app/controller/Viewport.js
index 0ae30080e..6ae3dbbe9 100644
--- a/apps/presentationeditor/main/app/controller/Viewport.js
+++ b/apps/presentationeditor/main/app/controller/Viewport.js
@@ -112,6 +112,7 @@ define([
 
         setApi: function(api) {
             this.api = api;
+            this.api.asc_registerCallback('asc_onZoomChange', this.onApiZoomChange.bind(this));
         },
 
 
@@ -134,7 +135,11 @@ define([
                 Common.localStorage.setItem('pe-mainmenu-width',leftPanel.width());
             }, this);
 
+            this.header.mnuitemFitPage = this.header.fakeMenuItem();
+            this.header.mnuitemFitWidth = this.header.fakeMenuItem();
+
             Common.NotificationCenter.on('app:face', this.onAppShowed.bind(this));
+            Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this));
         },
 
         onAppShowed: function (config) {
@@ -172,6 +177,110 @@ define([
             }
         },
 
+        onAppReady: function (config) {
+            var me = this;
+            if ( me.header.btnOptions ) {
+                var compactview = !config.isEdit;
+                if ( config.isEdit ) {
+                    if ( Common.localStorage.itemExists("pe-compact-toolbar") ) {
+                        compactview = Common.localStorage.getBool("pe-compact-toolbar");
+                    } else
+                    if ( config.customization && config.customization.compactToolbar )
+                        compactview = true;
+                }
+
+                me.header.mnuitemCompactToolbar = new Common.UI.MenuItem({
+                    caption: me.header.textCompactView,
+                    checked: compactview,
+                    checkable: true,
+                    value: 'toolbar'
+                });
+
+                var mnuitemHideStatusBar = new Common.UI.MenuItem({
+                    caption: me.header.textHideStatusBar,
+                    checked: Common.localStorage.getBool("pe-hidden-status"),
+                    checkable: true,
+                    value: 'statusbar'
+                });
+
+                if ( config.canBrandingExt && config.customization && config.customization.statusBar === false )
+                    mnuitemHideStatusBar.hide();
+
+                var mnuitemHideRulers = new Common.UI.MenuItem({
+                    caption: me.header.textHideLines,
+                    checked: Common.localStorage.getBool("pe-hidden-rulers"),
+                    checkable: true,
+                    value: 'rulers'
+                });
+
+                me.header.mnuitemFitPage = new Common.UI.MenuItem({
+                    caption: me.textFitPage,
+                    checkable: true,
+                    checked: me.header.mnuitemFitPage.isChecked(),
+                    value: 'zoom:page'
+                });
+
+                me.header.mnuitemFitWidth = new Common.UI.MenuItem({
+                    caption: me.textFitWidth,
+                    checkable: true,
+                    checked: me.header.mnuitemFitWidth.isChecked(),
+                    value: 'zoom:width'
+                });
+
+                me.header.mnuZoom = new Common.UI.MenuItem({
+                    template: _.template([
+                        '<div id="hdr-menu-zoom" class="menu-zoom" style="height: 25px;" ',
+                            '<% if(!_.isUndefined(options.stopPropagation)) { %>',
+                                'data-stopPropagation="true"',
+                            '<% } %>', '>',
+                            '<label class="title">' + me.header.textZoom + '</label>',
+                            '<button id="hdr-menu-zoom-in" type="button" style="float:right; margin: 2px 5px 0 0;" class="btn small btn-toolbar"><i class="icon btn-zoomin">&nbsp;</i></button>',
+                            '<label class="zoom"><%= options.value %>%</label>',
+                            '<button id="hdr-menu-zoom-out" type="button" style="float:right; margin-top: 2px;" class="btn small btn-toolbar"><i class="icon btn-zoomout">&nbsp;</i></button>',
+                        '</div>'
+                    ].join('')),
+                    stopPropagation: true,
+                    value: me.header.mnuZoom.options.value
+                });
+
+                me.header.btnOptions.setMenu(new Common.UI.Menu({
+                        cls: 'pull-right',
+                        style: 'min-width: 180px;',
+                        items: [
+                            me.header.mnuitemCompactToolbar,
+                            mnuitemHideStatusBar,
+                            mnuitemHideRulers,
+                            {caption:'--'},
+                            me.header.mnuitemFitPage,
+                            me.header.mnuitemFitWidth,
+                            me.header.mnuZoom,
+                            {caption:'--'},
+                            new Common.UI.MenuItem({
+                                caption: me.header.textAdvSettings,
+                                value: 'advanced'
+                            })
+                        ]
+                    })
+                );
+
+                var _on_btn_zoom = function (btn) {
+                    btn == 'up' ? me.api.zoomIn() : me.api.zoomOut();
+                    Common.NotificationCenter.trigger('edit:complete', me.header);
+                };
+
+                (new Common.UI.Button({
+                    el      : $('#hdr-menu-zoom-out', me.header.mnuZoom.$el),
+                    cls     : 'btn-toolbar'
+                })).on('click', _on_btn_zoom.bind(me, 'down'));
+
+                (new Common.UI.Button({
+                    el      : $('#hdr-menu-zoom-in', me.header.mnuZoom.$el),
+                    cls     : 'btn-toolbar'
+                })).on('click', _on_btn_zoom.bind(me, 'up'));
+
+                me.header.btnOptions.menu.on('item:click', me.onOptionsItemClick.bind(this));
+            }
+        },
 
         onLayoutChanged: function(area) {
             switch (area) {
@@ -256,6 +365,42 @@ define([
 
             me.header.lockHeaderBtns( 'undo', _need_disable );
             me.header.lockHeaderBtns( 'redo', _need_disable );
-        }
-    });
+            me.header.lockHeaderBtns( 'opts', _need_disable );
+        },
+
+        onApiZoomChange: function(percent, type) {
+            this.header.mnuitemFitPage.setChecked(type == 2, true);
+            this.header.mnuitemFitWidth.setChecked(type == 1, true);
+            this.header.mnuZoom.options.value = percent;
+
+            if ( this.header.mnuZoom.$el )
+                $('.menu-zoom label.zoom', this.header.mnuZoom.$el).html(percent + '%');
+        },
+
+        onOptionsItemClick: function (menu, item, e) {
+            var me = this;
+
+            switch ( item.value ) {
+            case 'toolbar': me.header.fireEvent('toolbar:setcompact', [menu, item.isChecked()]); break;
+            case 'statusbar': me.header.fireEvent('statusbar:hide', [item, item.isChecked()]); break;
+            case 'rulers':
+                me.api.asc_SetViewRulers(!item.isChecked());
+                Common.localStorage.setBool('pe-hidden-rulers', item.isChecked());
+                Common.NotificationCenter.trigger('layout:changed', 'rulers');
+                Common.NotificationCenter.trigger('edit:complete', me.header);
+                break;
+            case 'zoom:page':
+                item.isChecked() ? me.api.zoomFitToPage() : me.api.zoomCustomMode();
+                Common.NotificationCenter.trigger('edit:complete', me.header);
+                break;
+            case 'zoom:width':
+                item.isChecked() ? me.api.zoomFitToWidth() : me.api.zoomCustomMode();
+                Common.NotificationCenter.trigger('edit:complete', me.header);
+                break;
+            case 'advanced': me.header.fireEvent('file:settings', me.header); break;
+            }
+        },
+
+        textFitPage: 'Fit to Page',
+        textFitWidth: 'Fit to Width'
 });
diff --git a/apps/presentationeditor/main/app/template/Toolbar.template b/apps/presentationeditor/main/app/template/Toolbar.template
index 7cae88f91..0cb5f81ec 100644
--- a/apps/presentationeditor/main/app/template/Toolbar.template
+++ b/apps/presentationeditor/main/app/template/Toolbar.template
@@ -110,16 +110,7 @@
                         <span class="btn-slot split" id="slot-btn-slidesize"></span>
                     </div>
                 </div>
-                <div class="group" id="slot-field-styles" style="width: 100%; min-width: 140px;">
-                </div>
-                <div class="group no-mask">
-                    <div class="elset">
-                        <span class="btn-slot split" id="slot-btn-hidebars"></span>
-                    </div>
-                    <div class="elset">
-                        <span class="btn-slot" id="slot-btn-settings"></span>
-                    </div>
-                </div>
+                <div class="group" id="slot-field-styles" style="width: 100%; min-width: 140px;"></div>
             </section>
             <section class="panel" data-tab="ins">
                 <div class="group">
diff --git a/apps/presentationeditor/main/app/view/Toolbar.js b/apps/presentationeditor/main/app/view/Toolbar.js
index bafa319e4..6a308131f 100644
--- a/apps/presentationeditor/main/app/view/Toolbar.js
+++ b/apps/presentationeditor/main/app/view/Toolbar.js
@@ -576,31 +576,6 @@ define([
                 });
                 me.slideOnlyControls.push(me.btnColorSchemas);
 
-                me.btnHide = new Common.UI.Button({
-                    id          : 'id-toolbar-btn-hidebars',
-                    cls         : 'btn-toolbar',
-                    iconCls     : 'btn-hidebars no-mask',
-                    lock        : [_set.menuFileOpen, _set.slideDeleted, _set.disableOnStart],
-                    menu        : true
-                });
-                me.slideOnlyControls.push(me.btnHide);
-
-                this.btnFitPage = {
-                    conf: {checked:false},
-                    setChecked: function(val) { this.conf.checked = val;},
-                    isChecked: function () { return this.conf.checked; }
-                };
-                this.btnFitWidth = clone(this.btnFitPage);
-                this.mnuZoom = {options: {value: 100}};
-
-                me.btnAdvSettings = new Common.UI.Button({
-                    id          : 'id-toolbar-btn-settings',
-                    cls         : 'btn-toolbar',
-                    iconCls     : 'btn-settings no-mask',
-                    lock        : [_set.slideDeleted, _set.disableOnStart]
-                });
-                me.slideOnlyControls.push(me.btnAdvSettings);
-
                 me.btnShapeAlign = new Common.UI.Button({
                     id          : 'id-toolbar-btn-shape-align',
                     cls         : 'btn-toolbar',
@@ -875,9 +850,9 @@ define([
                     }
                 });
 
+                me.setTab('home');
                 if ( me.isCompactView )
-                    me.setFolded(true); else
-                    me.setTab('home');
+                    me.setFolded(true);
 
                 return this;
             },
@@ -943,8 +918,6 @@ define([
                 _injectComponent('#slot-btn-colorschemas', this.btnColorSchemas);
                 _injectComponent('#slot-btn-slidesize', this.btnSlideSize);
                 _injectComponent('#slot-field-styles', this.listTheme);
-                _injectComponent('#slot-btn-hidebars', this.btnHide);
-                _injectComponent('#slot-btn-settings', this.btnAdvSettings);
 
                 function _injectBtns(opts) {
                     var array = createButtonSet();
@@ -1105,8 +1078,6 @@ define([
                 this.btnInsertHyperlink.updateHint(this.tipInsertHyperlink + Common.Utils.String.platformKey('Ctrl+K'));
                 this.btnInsertTextArt.updateHint(this.tipInsertTextArt);
                 this.btnColorSchemas.updateHint(this.tipColorSchemas);
-                this.btnHide.updateHint(this.tipViewSettings);
-                this.btnAdvSettings.updateHint(this.tipAdvSettings);
                 this.btnShapeAlign.updateHint(this.tipShapeAlign);
                 this.btnShapeArrange.updateHint(this.tipShapeArrange);
                 this.btnSlideSize.updateHint(this.tipSlideSize);
@@ -1115,66 +1086,6 @@ define([
 
                 var me = this;
 
-                this.btnHide.setMenu(
-                    new Common.UI.Menu({
-                        cls: 'pull-right',
-                        style: 'min-width: 180px;',
-                        items: [
-                            this.mnuitemCompactToolbar = new Common.UI.MenuItem({
-                                caption: this.textCompactView,
-                                checkable: true,
-                                checked: me.isCompactView
-                            }),
-                            this.mnuitemHideStatusBar = new Common.UI.MenuItem({
-                                caption: this.textHideStatusBar,
-                                checkable: true
-                            }),
-                            this.mnuitemHideRulers = new Common.UI.MenuItem({
-                                caption: this.textHideLines,
-                                checkable: true
-                            }),
-                            {caption: '--'},
-                            this.btnFitPage = new Common.UI.MenuItem({
-                                caption: this.textFitPage,
-                                checkable: true,
-                                checked: this.btnFitPage.isChecked()
-                            }),
-                            this.btnFitWidth = new Common.UI.MenuItem({
-                                caption: this.textFitWidth,
-                                checkable: true,
-                                checked: this.btnFitWidth.isChecked()
-                            }),
-                            this.mnuZoom = new Common.UI.MenuItem({
-                                template: _.template([
-                                    '<div id="id-toolbar-menu-zoom" class="menu-zoom" style="height: 25px;" ',
-                                    '<% if(!_.isUndefined(options.stopPropagation)) { %>',
-                                    'data-stopPropagation="true"',
-                                    '<% } %>',
-                                    '>',
-                                    '<label class="title">' + this.textZoom + '</label>',
-                                    '<button id="id-menu-zoom-in" type="button" style="float:right; margin: 2px 5px 0 0;" class="btn small btn-toolbar"><i class="icon btn-zoomin"></i></button>',
-                                    '<label class="zoom"><%= options.value %>%</label>',
-                                    '<button id="id-menu-zoom-out" type="button" style="float:right; margin-top: 2px;" class="btn small btn-toolbar"><i class="icon btn-zoomout"></i></button>',
-                                    '</div>'
-                                ].join('')),
-                                stopPropagation: true,
-                                value: this.mnuZoom.options.value
-                            })
-                        ]
-                    })
-                );
-                if (this.mode.canBrandingExt && this.mode.customization && this.mode.customization.statusBar === false)
-                    this.mnuitemHideStatusBar.hide();
-
-                this.mnuZoomOut = new Common.UI.Button({
-                    el: $('#id-menu-zoom-out'),
-                    cls: 'btn-toolbar'
-                });
-                this.mnuZoomIn = new Common.UI.Button({
-                    el: $('#id-menu-zoom-in'),
-                    cls: 'btn-toolbar'
-                });
-
                 this.btnMarkers.setMenu(
                     new Common.UI.Menu({
                         style: 'min-width: 139px',
@@ -1339,9 +1250,6 @@ define([
                         me.mnuChangeSlidePicker._needRecalcSlideLayout = true;
                 });
 
-                this.mnuitemHideStatusBar.setChecked(Common.localStorage.getBool('pe-hidden-status'), true);
-                this.mnuitemHideRulers.setChecked(Common.localStorage.getBool("pe-hidden-rulers", true), true);
-
 //            // Enable none paragraph components
                 this.lockToolbar(PE.enumLock.disableOnStart, false, {array: this.slideOnlyControls.concat(this.shapeControls)});
 
@@ -1747,15 +1655,6 @@ define([
             mniSlideWide: 'Widescreen (16:9)',
             mniSlideAdvanced: 'Advanced Settings',
             tipSlideSize: 'Select Slide Size',
-            tipViewSettings: 'View Settings',
-            tipAdvSettings: 'Advanced Settings',
-            textCompactView: 'Hide Toolbar',
-            textHideTitleBar: 'Hide Title Bar',
-            textHideStatusBar: 'Hide Status Bar',
-            textHideLines: 'Hide Rulers',
-            textFitPage: 'Fit to Slide',
-            textFitWidth: 'Fit to Width',
-            textZoom: 'Zoom',
             tipInsertChart: 'Insert Chart',
             textLine: 'Line',
             textColumn: 'Column',
diff --git a/apps/presentationeditor/main/locale/en.json b/apps/presentationeditor/main/locale/en.json
index a60255b37..eb8605858 100644
--- a/apps/presentationeditor/main/locale/en.json
+++ b/apps/presentationeditor/main/locale/en.json
@@ -92,6 +92,12 @@
   "Common.Views.Header.tipViewUsers": "View users and manage document access rights",
   "Common.Views.Header.txtAccessRights": "Change access rights",
   "Common.Views.Header.txtRename": "Rename",
+  "Common.Views.Header.textAdvSettings": "Advanced settings",
+  "Common.Views.Header.textCompactView": "Hide Toolbar",
+  "Common.Views.Header.textHideStatusBar": "Hide Status Bar",
+  "Common.Views.Header.textZoom": "Zoom",
+  "Common.Views.Header.tipViewSettings": "View settings",
+  "Common.Views.Header.textHideLines": "Hide Rulers",
   "Common.Views.ImageFromUrlDialog.cancelButtonText": "Cancel",
   "Common.Views.ImageFromUrlDialog.okButtonText": "OK",
   "Common.Views.ImageFromUrlDialog.textUrl": "Paste an image URL:",
@@ -700,6 +706,8 @@
   "PE.Controllers.Toolbar.txtSymbol_vdots": "Vertical ellipsis",
   "PE.Controllers.Toolbar.txtSymbol_xsi": "Xi",
   "PE.Controllers.Toolbar.txtSymbol_zeta": "Zeta",
+  "PE.Controllers.Viewport.textFitPage": "Fit to Slide",
+  "PE.Controllers.Viewport.textFitWidth": "Fit to Width",
   "PE.Views.ChartSettings.textAdvanced": "Show advanced settings",
   "PE.Views.ChartSettings.textArea": "Area",
   "PE.Views.ChartSettings.textBar": "Bar",
@@ -1405,12 +1413,12 @@
   "PE.Views.Toolbar.textCancel": "Cancel",
   "PE.Views.Toolbar.textCharts": "Charts",
   "PE.Views.Toolbar.textColumn": "Column",
-  "PE.Views.Toolbar.textCompactView": "Hide Toolbar",
-  "PE.Views.Toolbar.textFitPage": "Fit to Slide",
-  "PE.Views.Toolbar.textFitWidth": "Fit to Width",
-  "PE.Views.Toolbar.textHideLines": "Hide Rulers",
-  "PE.Views.Toolbar.textHideStatusBar": "Hide Status Bar",
-  "PE.Views.Toolbar.textHideTitleBar": "Hide Title Bar",
+  "del_PE.Views.Toolbar.textCompactView": "Hide Toolbar",
+  "del_PE.Views.Toolbar.textFitPage": "Fit to Slide",
+  "del_PE.Views.Toolbar.textFitWidth": "Fit to Width",
+  "del_PE.Views.Toolbar.textHideLines": "Hide Rulers",
+  "del_PE.Views.Toolbar.textHideStatusBar": "Hide Status Bar",
+  "del_PE.Views.Toolbar.textHideTitleBar": "Hide Title Bar",
   "PE.Views.Toolbar.textItalic": "Italic",
   "PE.Views.Toolbar.textLine": "Line",
   "PE.Views.Toolbar.textNewColor": "Custom Color",
@@ -1439,9 +1447,9 @@
   "PE.Views.Toolbar.textTabProtect": "Protection",
   "PE.Views.Toolbar.textTitleError": "Error",
   "PE.Views.Toolbar.textUnderline": "Underline",
-  "PE.Views.Toolbar.textZoom": "Zoom",
+  "del_PE.Views.Toolbar.textZoom": "Zoom",
   "PE.Views.Toolbar.tipAddSlide": "Add slide",
-  "PE.Views.Toolbar.tipAdvSettings": "Advanced settings",
+  "del_PE.Views.Toolbar.tipAdvSettings": "Advanced settings",
   "PE.Views.Toolbar.tipBack": "Back",
   "PE.Views.Toolbar.tipChangeChart": "Change chart type",
   "PE.Views.Toolbar.tipChangeSlide": "Change slide layout",
@@ -1454,7 +1462,7 @@
   "PE.Views.Toolbar.tipFontName": "Font",
   "PE.Views.Toolbar.tipFontSize": "Font size",
   "PE.Views.Toolbar.tipHAligh": "Horizontal align",
-  "PE.Views.Toolbar.tipHideBars": "Hide Title bar & Status bar",
+  "del_PE.Views.Toolbar.tipHideBars": "Hide Title bar & Status bar",
   "PE.Views.Toolbar.tipIncPrLeft": "Increase indent",
   "PE.Views.Toolbar.tipInsertChart": "Insert chart",
   "PE.Views.Toolbar.tipInsertEquation": "Insert equation",
diff --git a/apps/spreadsheeteditor/main/app/controller/CellEditor.js b/apps/spreadsheeteditor/main/app/controller/CellEditor.js
index ab413d942..7c9c69def 100644
--- a/apps/spreadsheeteditor/main/app/controller/CellEditor.js
+++ b/apps/spreadsheeteditor/main/app/controller/CellEditor.js
@@ -67,6 +67,13 @@ define([
                 'CellEditor': {},
                 'Viewport': {
                     'layout:resizedrag': _.bind(this.onLayoutResize, this)
+                },
+                'Common.Views.Header': {
+                    'formulabar:hide': function (state) {
+                        this.editor.setVisible(!state);
+                        Common.localStorage.setBool('sse-hidden-formula', state);
+                        Common.NotificationCenter.trigger('layout:changed', 'celleditor', state?'hidden':'showed');
+                    }.bind(this)
                 }
             });
         },
diff --git a/apps/spreadsheeteditor/main/app/controller/LeftMenu.js b/apps/spreadsheeteditor/main/app/controller/LeftMenu.js
index c472d4f92..c6fa3a093 100644
--- a/apps/spreadsheeteditor/main/app/controller/LeftMenu.js
+++ b/apps/spreadsheeteditor/main/app/controller/LeftMenu.js
@@ -55,6 +55,7 @@ define([
                     'hide':        _.bind(this.onHidePlugins, this)
                 },
                 'Common.Views.Header': {
+                    'file:settings': _.bind(this.clickToolbarSettings,this),
                     'click:users': _.bind(this.clickStatusbarUsers, this)
                 },
                 'LeftMenu': {
diff --git a/apps/spreadsheeteditor/main/app/controller/Toolbar.js b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
index 7e6a09000..59beebf6a 100644
--- a/apps/spreadsheeteditor/main/app/controller/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/controller/Toolbar.js
@@ -80,6 +80,7 @@ define([
                     'settings:apply': _.bind(this.applyFormulaSettings, this)
                 },
                 'Common.Views.Header': {
+                    'toolbar:setcompact': this.onChangeViewMode.bind(this),
                     'print': function (opts) {
                         var _main = this.getApplication().getController('Main');
                         _main.onPrint();
@@ -305,7 +306,6 @@ define([
                 toolbar.btnDecDecimal.on('click',                           _.bind(this.onDecrement, this));
                 toolbar.btnIncDecimal.on('click',                           _.bind(this.onIncrement, this));
                 toolbar.btnInsertFormula.on('click',                        _.bind(this.onInsertFormulaMenu, this));
-                toolbar.btnSettings.on('click',                             _.bind(this.onAdvSettingsClick, this));
                 toolbar.btnInsertFormula.menu.on('item:click',              _.bind(this.onInsertFormulaMenu, this));
                 toolbar.btnNamedRange.menu.on('item:click',                 _.bind(this.onNamedRangeMenu, this));
                 toolbar.btnNamedRange.menu.on('show:after',                 _.bind(this.onNamedRangeMenuOpen, this));
@@ -326,16 +326,12 @@ define([
                 toolbar.cmbFontSize.on('hide:after',                        _.bind(this.onHideMenus, this));
                 toolbar.cmbFontSize.on('combo:blur',                        _.bind(this.onComboBlur, this));
                 toolbar.cmbFontSize.on('combo:focusin',                     _.bind(this.onComboOpen, this, false));
-                if (toolbar.mnuZoomIn)  toolbar.mnuZoomIn.on('click',       _.bind(this.onZoomInClick, this));
-                if (toolbar.mnuZoomOut) toolbar.mnuZoomOut.on('click',      _.bind(this.onZoomOutClick, this));
-                if (toolbar.btnShowMode.rendered) toolbar.btnShowMode.menu.on('item:click', _.bind(this.onHideMenu, this));
                 toolbar.listStyles.on('click',                              _.bind(this.onListStyleSelect, this));
                 toolbar.cmbNumberFormat.on('selected',                      _.bind(this.onNumberFormatSelect, this));
                 toolbar.cmbNumberFormat.on('show:before',                   _.bind(this.onNumberFormatOpenBefore, this, true));
                 if (toolbar.cmbNumberFormat.cmpEl)
                     toolbar.cmbNumberFormat.cmpEl.on('click', '#id-toolbar-mnu-item-more-formats a', _.bind(this.onNumberFormatSelect, this));
                 toolbar.btnCurrencyStyle.menu.on('item:click',              _.bind(this.onNumberFormatMenu, this));
-                if (toolbar.mnuitemCompactToolbar) toolbar.mnuitemCompactToolbar.on('toggle', _.bind(this.onChangeViewMode, this));
                 $('#id-toolbar-menu-new-fontcolor').on('click',             _.bind(this.onNewTextColor, this));
                 $('#id-toolbar-menu-new-paracolor').on('click',             _.bind(this.onNewBackColor, this));
                 $('#id-toolbar-menu-new-bordercolor').on('click',           _.bind(this.onNewBorderColor, this));
@@ -1361,53 +1357,6 @@ define([
             }
         },
 
-        onAdvSettingsClick: function(btn, e) {
-            this.toolbar.fireEvent('file:settings', this);
-            btn.cmpEl.blur();
-        },
-
-        onZoomInClick: function(btn) {
-            if (this.api) {
-                var f = Math.floor(this.api.asc_getZoom() * 10)/10;
-                f += .1;
-                if (f > 0 && !(f > 2.)) {
-                    this.api.asc_setZoom(f);
-                }
-            }
-
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onZoomOutClick: function(btn) {
-            if (this.api) {
-                var f = Math.ceil(this.api.asc_getZoom() * 10)/10;
-                f -= .1;
-                if (!(f < .5)) {
-                    this.api.asc_setZoom(f);
-                }
-            }
-
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
-        onHideMenu: function(menu, item) {
-            var params = {},
-                option;
-
-            switch(item.value) {
-                case 'title':       params.title = item.checked;      option = 'sse-hidden-title';      break;
-                case 'formula':     params.formula = item.checked;    option = 'sse-hidden-formula';    break;
-                case 'headings':    params.headings = item.checked;   break;
-                case 'gridlines':   params.gridlines = item.checked;  break;
-                case 'freezepanes': params.freezepanes = item.checked;  break;
-            }
-
-            this.hideElements(params);
-            option && Common.localStorage.setBool(option, item.checked);
-
-            Common.NotificationCenter.trigger('edit:complete', this.toolbar);
-        },
-
         onListStyleSelect: function(combo, record) {
             this._state.prstyle = undefined;
             if (this.api) {
@@ -1513,7 +1462,6 @@ define([
             if ( from != 'file' ) {
                 Common.Utils.asyncCall(function () {
                     this.onChangeViewMode(null, !this.toolbar.isCompact());
-                    this.toolbar.mnuitemCompactToolbar.setChecked(this.toolbar.isCompact(), true);
                 }, this);
             }
         },
@@ -1711,26 +1659,9 @@ define([
             this.checkInsertAutoshape({action:'cancel'});
         },
 
-        onApiZoomChange: function(zf, type){
-            switch (type) {
-                case 1: // FitWidth
-                case 2: // FitPage
-                case 0:
-                default: {
-                    this.toolbar.mnuZoom.options.value = Math.floor((zf + .005) * 100);
-                    $('.menu-zoom .zoom', this.toolbar.el).html(Math.floor((zf + .005) * 100) + '%');
-                }
-            }
-        },
+        onApiZoomChange: function(zf, type){},
 
-        onApiSheetChanged: function() {
-            if ( this.api && !this.appConfig.isEditDiagram && !this.appConfig.isEditMailMerge ) {
-                var params  = this.api.asc_getSheetViewSettings();
-                this.toolbar.mnuitemHideHeadings.setChecked(!params.asc_getShowRowColHeaders());
-                this.toolbar.mnuitemHideGridlines.setChecked(!params.asc_getShowGridLines());
-                this.toolbar.mnuitemFreezePanes.setChecked(params.asc_getIsFreezePane());
-            }
-        },
+        onApiSheetChanged: function() {},
 
         onApiEditorSelectionChanged: function(fontobj) {
             if (!this.editMode) return;
@@ -2411,13 +2342,6 @@ define([
         },
 
         hideElements: function(opts) {
-            if (!_.isUndefined(opts.title)) {
-                var headerView  = this.getApplication().getController('Viewport').getView('Common.Views.Header');
-                headerView && headerView.setVisible(!opts.title);
-
-                Common.NotificationCenter.trigger('layout:changed', 'header');
-            }
-
             if (!_.isUndefined(opts.compact)) {
                 this.onChangeViewMode(opts.compact);
             }
@@ -2981,7 +2905,7 @@ define([
             var toolbar = this.toolbar;
             toolbar.$el.find('.toolbar').toggleClass('masked', disable);
 
-            this.toolbar.lockToolbar(SSE.enumLock.menuFileOpen, disable, {array: [toolbar.btnShowMode]});
+            this.toolbar.lockToolbar(SSE.enumLock.menuFileOpen, disable);
             if(disable) {
                 mask = $("<div class='toolbar-mask'>").appendTo(toolbar.$el.find('.toolbar'));
                 Common.util.Shortcuts.suspendEvents('command+l, ctrl+l, command+shift+l, ctrl+shift+l, command+k, ctrl+k, command+alt+h, ctrl+alt+h, command+1, ctrl+1');
diff --git a/apps/spreadsheeteditor/main/app/controller/Viewport.js b/apps/spreadsheeteditor/main/app/controller/Viewport.js
index a88a191c1..ce517338f 100644
--- a/apps/spreadsheeteditor/main/app/controller/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/controller/Viewport.js
@@ -71,6 +71,9 @@ define([
                     'menu:hide': me.onFileMenu.bind(me, 'hide'),
                     'menu:show': me.onFileMenu.bind(me, 'show')
                 },
+                'Statusbar': {
+                    'sheet:changed': me.onApiSheetChanged.bind(me)
+                },
                 'Toolbar': {
                     'render:before' : function (toolbar) {
                         var config = SSE.getController('Main').appOptions;
@@ -83,6 +86,7 @@ define([
 
                     },
                     'view:compact'  : function (toolbar, state) {
+                        me.header.mnuitemCompactToolbar.setChecked(state, true);
                         me.viewport.vlayout.getItem('toolbar').height = state ?
                             Common.Utils.InternalSettings.get('toolbar-height-compact') : Common.Utils.InternalSettings.get('toolbar-height-normal');
                     },
@@ -108,10 +112,16 @@ define([
             });
 
             Common.NotificationCenter.on('app:face', this.onAppShowed.bind(this));
+            Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this));
+            Common.NotificationCenter.on('cells:range', this.onCellsRange.bind(this));
         },
 
         setApi: function(api) {
             this.api = api;
+            this.api.asc_registerCallback('asc_onZoomChanged',              this.onApiZoomChange.bind(this));
+            this.api.asc_registerCallback('asc_onSheetsChanged',            this.onApiSheetChanged.bind(this));
+            this.api.asc_registerCallback('asc_onUpdateSheetViewSettings',  this.onApiSheetChanged.bind(this));
+            this.api.asc_registerCallback('asc_onEditCell',                 this.onApiEditCell.bind(this));
         },
 
         onAppShowed: function (config) {
@@ -149,6 +159,123 @@ define([
             }
         },
 
+        onAppReady: function (config) {
+            var me = this;
+            if ( me.header.btnOptions ) {
+                var compactview = !config.isEdit;
+                if ( config.isEdit && !config.isEditDiagram && !config.isEditMailMerge ) {
+                    if ( Common.localStorage.itemExists("sse-compact-toolbar") ) {
+                        compactview = Common.localStorage.getBool("sse-compact-toolbar");
+                    } else
+                    if ( config.customization && config.customization.compactToolbar )
+                        compactview = true;
+                }
+
+                me.header.mnuitemCompactToolbar = new Common.UI.MenuItem({
+                    caption     : me.header.textCompactView,
+                    checked     : compactview,
+                    checkable   : true,
+                    value       : 'toolbar'
+                });
+
+                var mnuitemHideFormulaBar = new Common.UI.MenuItem({
+                    caption     : me.textHideFBar,
+                    checked     : Common.localStorage.getBool('sse-hidden-formula'),
+                    checkable   : true,
+                    value       : 'formula'
+                });
+
+                me.header.mnuitemHideHeadings = new Common.UI.MenuItem({
+                    caption     : me.textHideHeadings,
+                    checkable   : true,
+                    checked     : me.header.mnuitemHideHeadings.isChecked(),
+                    value       : 'headings'
+                });
+
+                me.header.mnuitemHideGridlines = new Common.UI.MenuItem({
+                    caption     : me.textHideGridlines,
+                    checkable   : true,
+                    checked     : me.header.mnuitemHideGridlines.isChecked(),
+                    value       : 'gridlines'
+                });
+
+                me.header.mnuitemFreezePanes = new Common.UI.MenuItem({
+                    caption     : me.textFreezePanes,
+                    checkable   : true,
+                    checked     : me.header.mnuitemFreezePanes.isChecked(),
+                    value       : 'freezepanes'
+                });
+
+                me.header.mnuZoom = new Common.UI.MenuItem({
+                    template: _.template([
+                        '<div id="hdr-menu-zoom" class="menu-zoom" style="height: 25px;" ',
+                            '<% if(!_.isUndefined(options.stopPropagation)) { %>',
+                            'data-stopPropagation="true"',
+                            '<% } %>', '>',
+                            '<label class="title">' + me.header.textZoom + '</label>',
+                            '<button id="hdr-menu-zoom-in" type="button" style="float:right; margin: 2px 5px 0 0;" class="btn small btn-toolbar"><i class="icon btn-zoomin">&nbsp;</i></button>',
+                            '<label class="zoom"><%= options.value %>%</label>',
+                            '<button id="hdr-menu-zoom-out" type="button" style="float:right; margin-top: 2px;" class="btn small btn-toolbar"><i class="icon btn-zoomout">&nbsp;</i></button>',
+                        '</div>'
+                    ].join('')),
+                    stopPropagation: true,
+                    value: me.header.mnuZoom.options.value
+                });
+
+                var mnuitemAdvSettings = new Common.UI.MenuItem({
+                    caption: me.header.textAdvSettings,
+                    value: 'advanced'
+                });
+
+                me.header.btnOptions.setMenu(new Common.UI.Menu({
+                        cls: 'pull-right',
+                        style: 'min-width: 180px;',
+                        items: [
+                            me.header.mnuitemCompactToolbar,
+                            mnuitemHideFormulaBar,
+                            {caption:'--'},
+                            me.header.mnuitemHideHeadings,
+                            me.header.mnuitemHideGridlines,
+                            {caption:'--'},
+                            me.header.mnuitemFreezePanes,
+                            {caption:'--'},
+                            me.header.mnuZoom,
+                            {caption:'--'},
+                            mnuitemAdvSettings
+                        ]
+                    })
+                );
+
+                var _on_btn_zoom = function (btn) {
+                    if ( btn == 'up' ) {
+                        var _f = Math.floor(this.api.asc_getZoom() * 10)/10;
+                        _f += .1;
+                        if (_f > 0 && !(_f > 2.))
+                            this.api.asc_setZoom(_f);
+                    } else {
+                        _f = Math.ceil(this.api.asc_getZoom() * 10)/10;
+                        _f -= .1;
+                        if (!(_f < .5))
+                            this.api.asc_setZoom(_f);
+                    }
+
+                    Common.NotificationCenter.trigger('edit:complete', me.header);
+                };
+
+                (new Common.UI.Button({
+                    el      : $('#hdr-menu-zoom-out', me.header.mnuZoom.$el),
+                    cls     : 'btn-toolbar'
+                })).on('click', _on_btn_zoom.bind(me, 'down'));
+
+                (new Common.UI.Button({
+                    el      : $('#hdr-menu-zoom-in', me.header.mnuZoom.$el),
+                    cls     : 'btn-toolbar'
+                })).on('click', _on_btn_zoom.bind(me, 'up'));
+
+                me.header.btnOptions.menu.on('item:click', me.onOptionsItemClick.bind(this));
+            }
+        },
+
         // When our application is ready, lets get started
         onLaunch: function() {
             // Create and render main view
@@ -176,6 +303,10 @@ define([
             this.boxFormula = $('#cell-editing-box');
             this.boxSdk.css('border-left', 'none');
             this.boxFormula.css('border-left', 'none');
+
+            this.header.mnuitemHideHeadings = this.header.fakeMenuItem();
+            this.header.mnuitemHideGridlines = this.header.fakeMenuItem();
+            this.header.mnuitemFreezePanes = this.header.fakeMenuItem();
         },
 
         onLayoutChanged: function(area) {
@@ -228,6 +359,58 @@ define([
 
             me.header.lockHeaderBtns( 'undo', _need_disable );
             me.header.lockHeaderBtns( 'redo', _need_disable );
-        }
-    });
+            me.header.lockHeaderBtns( 'opts', _need_disable );
+        },
+
+        onApiZoomChange: function(zf, type){
+            switch (type) {
+                case 1: // FitWidth
+                case 2: // FitPage
+                case 0:
+                default: {
+                    this.header.mnuZoom.options.value = Math.floor((zf + .005) * 100);
+                    $('.menu-zoom .zoom', this.header.mnuZoom.$el).html(Math.floor((zf + .005) * 100) + '%');
+                }
+            }
+        },
+
+        onApiSheetChanged: function() {
+            var me = this;
+            var appConfig = me.viewport.mode;
+            if ( !!appConfig && !appConfig.isEditDiagram && !appConfig.isEditMailMerge ) {
+                var params  = me.api.asc_getSheetViewSettings();
+                me.header.mnuitemHideHeadings.setChecked(!params.asc_getShowRowColHeaders());
+                me.header.mnuitemHideGridlines.setChecked(!params.asc_getShowGridLines());
+                me.header.mnuitemFreezePanes.setChecked(params.asc_getIsFreezePane());
+            }
+        },
+
+        onApiEditCell: function(state) {
+            if ( state == Asc.c_oAscCellEditorState.editStart )
+                this.header.lockHeaderBtns('opts', true); else
+            if ( state == Asc.c_oAscCellEditorState.editEnd )
+                this.header.lockHeaderBtns('opts', false);
+        },
+
+        onCellsRange: function(status) {
+            this.onApiEditCell(status != Asc.c_oAscSelectionDialogType.None ? Asc.c_oAscCellEditorState.editStart : Asc.c_oAscCellEditorState.editEnd);
+        },
+
+        onOptionsItemClick: function (menu, item, e) {
+            var me = this;
+
+            switch ( item.value ) {
+            case 'toolbar': me.header.fireEvent('toolbar:setcompact', [menu, item.isChecked()]); break;
+            case 'formula': me.header.fireEvent('formulabar:hide', [item.isChecked()]); break;
+            case 'headings': me.api.asc_setDisplayHeadings(!item.isChecked()); break;
+            case 'gridlines': me.api.asc_setDisplayGridlines(!item.isChecked()); break;
+            case 'freezepanes': me.api.asc_freezePane(); break;
+            case 'advanced': me.header.fireEvent('file:settings', me.header); break;
+            }
+        },
+
+        textHideFBar: 'Hide Formula Bar',
+        textHideHeadings: 'Hide Headings',
+        textHideGridlines: 'Hide Gridlines',
+        textFreezePanes: 'Freeze Panes'
 });
diff --git a/apps/spreadsheeteditor/main/app/template/Toolbar.template b/apps/spreadsheeteditor/main/app/template/Toolbar.template
index 6fc9e087c..5bb2ae135 100644
--- a/apps/spreadsheeteditor/main/app/template/Toolbar.template
+++ b/apps/spreadsheeteditor/main/app/template/Toolbar.template
@@ -131,16 +131,7 @@
                         <span class="btn-slot split" id="slot-btn-table-tpl"></span>
                     </div>
                 </div>
-                <div class="group" id="slot-field-styles" style="width: 100%; min-width: 160px;">
-                </div>
-                <div class="group no-mask">
-                    <div class="elset">
-                        <span class="btn-slot split" id="slot-btn-hidebars"></span>
-                    </div>
-                    <div class="elset">
-                        <span class="btn-slot" id="slot-btn-settings"></span>
-                    </div>
-                </div>
+                <div class="group" id="slot-field-styles" style="width: 100%; min-width: 160px;"></div>
             </section>
             <section class="panel" data-tab="ins">
                 <div class="group">
diff --git a/apps/spreadsheeteditor/main/app/view/Toolbar.js b/apps/spreadsheeteditor/main/app/view/Toolbar.js
index ed56ec308..23f6cd580 100644
--- a/apps/spreadsheeteditor/main/app/view/Toolbar.js
+++ b/apps/spreadsheeteditor/main/app/view/Toolbar.js
@@ -1048,41 +1048,6 @@ define([
                     })
                 });
 
-                me.mnuZoomIn = dummyCmp();
-                me.mnuZoomOut = dummyCmp();
-
-                var clone = function(source) {
-                    var obj = {};
-                    for (var prop in source)
-                        obj[prop] = (typeof(source[prop])=='object') ? clone(source[prop]) : source[prop];
-                    return obj;
-                };
-
-                this.mnuitemHideHeadings = {
-                    conf: {checked:false},
-                    setChecked: function(val) { this.conf.checked = val;},
-                    isChecked: function () { return this.conf.checked; }
-                };
-                this.mnuitemHideGridlines = clone(this.mnuitemHideHeadings);
-                this.mnuitemFreezePanes = clone(this.mnuitemHideHeadings);
-                this.mnuZoom = {
-                    options: {value: 100}
-                };
-
-                me.btnShowMode = new Common.UI.Button({
-                    id          : 'id-toolbar-btn-showmode',
-                    cls         : 'btn-toolbar',
-                    iconCls     : 'btn-showmode no-mask',
-                    lock        : [_set.menuFileOpen, _set.editCell],
-                    menu        : true
-                });
-
-                me.btnSettings = new Common.UI.Button({
-                    id          : 'id-toolbar-btn-settings',
-                    cls         : 'btn-toolbar',
-                    iconCls     : 'btn-settings no-mask'
-                });
-
                 // Is unique for the short view
 
                 me.btnHorizontalAlign = new Common.UI.Button({
@@ -1235,7 +1200,7 @@ define([
                 me.btnTableTemplate, me.btnPercentStyle, me.btnCurrencyStyle, me.btnDecDecimal, me.btnAddCell, me.btnDeleteCell,
                 me.cmbNumberFormat, me.btnBorders, me.btnInsertImage, me.btnInsertHyperlink,
                 me.btnInsertChart, me.btnColorSchemas,
-                me.btnAutofilter, me.btnCopy, me.btnPaste, me.btnSettings, me.listStyles, me.btnPrint, me.btnShowMode,
+                me.btnAutofilter, me.btnCopy, me.btnPaste, me.listStyles, me.btnPrint,
                 me.btnSave, me.btnClearStyle, me.btnCopyStyle
             ];
 
@@ -1244,8 +1209,8 @@ define([
                 me.btnInsertImage, me.btnInsertText, me.btnInsertTextArt, me.btnInsertShape, me.btnInsertEquation, me.btnIncFontSize,
                 me.btnDecFontSize, me.btnBold, me.btnItalic, me.btnUnderline, me.btnStrikeout, me.btnSubscript, me.btnTextColor, me.btnBackColor,
                 me.btnInsertHyperlink, me.btnBorders, me.btnTextOrient, me.btnPercentStyle, me.btnCurrencyStyle, me.btnColorSchemas,
-                me.btnSettings, me.btnInsertFormula, me.btnNamedRange, me.btnDecDecimal, me.btnIncDecimal, me.cmbNumberFormat, me.btnWrap,
-                me.btnInsertChart, me.btnMerge, me.btnAddCell, me.btnDeleteCell, me.btnShowMode, me.btnPrint,
+                me.btnInsertFormula, me.btnNamedRange, me.btnDecDecimal, me.btnIncDecimal, me.cmbNumberFormat, me.btnWrap,
+                me.btnInsertChart, me.btnMerge, me.btnAddCell, me.btnDeleteCell, me.btnPrint,
                 me.btnAutofilter, me.btnSortUp, me.btnSortDown, me.btnTableTemplate, me.btnSetAutofilter, me.btnClearAutofilter,
                 me.btnSave, me.btnClearStyle, me.btnCopyStyle, me.btnCopy, me.btnPaste];
 
@@ -1294,9 +1259,9 @@ define([
                 }
             });
 
+            me.setTab('home');
             if ( me.isCompactView )
-                me.setFolded(true); else
-                me.setTab('home');
+                me.setFolded(true);
 
             return this;
         },
@@ -1379,8 +1344,6 @@ define([
             _injectComponent('#slot-btn-cell-ins',       this.btnAddCell);
             _injectComponent('#slot-btn-cell-del',       this.btnDeleteCell);
             _injectComponent('#slot-btn-colorschemas',   this.btnColorSchemas);
-            _injectComponent('#slot-btn-hidebars',       this.btnShowMode);
-            _injectComponent('#slot-btn-settings',       this.btnSettings);
             _injectComponent('#slot-btn-search',         this.btnSearch);
             _injectComponent('#slot-btn-inschart',       this.btnInsertChart);
             _injectComponent('#slot-field-styles',       this.listStyles);
@@ -1450,77 +1413,11 @@ define([
             _updateHint(this.btnAddCell, this.tipInsertOpt);
             _updateHint(this.btnDeleteCell, this.tipDeleteOpt);
             _updateHint(this.btnColorSchemas, this.tipColorSchemas);
-            _updateHint(this.btnShowMode, this.tipViewSettings);
-            _updateHint(this.btnSettings, this.tipAdvSettings);
             _updateHint(this.btnHorizontalAlign, this.tipHAligh);
             _updateHint(this.btnVerticalAlign, this.tipVAligh);
             _updateHint(this.btnAutofilter, this.tipAutofilter);
 
             // set menus
-            if ( this.btnShowMode && this.btnShowMode.rendered ) {
-                this.btnShowMode.setMenu(new Common.UI.Menu({
-                    items: [
-                        this.mnuitemCompactToolbar = new Common.UI.MenuItem({
-                            caption     : this.textCompactToolbar,
-                            checkable   : true,
-                            checked     : this.isCompactView,
-                            value       : 'compact'
-                        }),
-                        this.mnuitemHideFormulaBar = new Common.UI.MenuItem({
-                            caption     : this.textHideFBar,
-                            checkable   : true,
-                            checked     : Common.localStorage.getBool('sse-hidden-formula'),
-                            value       : 'formula'
-                        }),
-                        {caption: '--'},
-                        this.mnuitemHideHeadings = new Common.UI.MenuItem({
-                            caption     : this.textHideHeadings,
-                            checkable   : true,
-                            checked     : this.mnuitemHideHeadings.isChecked(),
-                            value       : 'headings'
-                        }),
-                        this.mnuitemHideGridlines = new Common.UI.MenuItem({
-                            caption     : this.textHideGridlines,
-                            checkable   : true,
-                            checked     : this.mnuitemHideGridlines.isChecked(),
-                            value       : 'gridlines'
-                        }),
-                        {caption: '--'},
-                        this.mnuitemFreezePanes = new Common.UI.MenuItem({
-                            caption     : this.textFreezePanes,
-                            checkable   : true,
-                            checked     : this.mnuitemFreezePanes.isChecked(),
-                            value       : 'freezepanes'
-                        }),
-                        {caption: '--'},
-                        this.mnuZoom = new Common.UI.MenuItem({
-                            template: _.template([
-                                '<div id="id-toolbar-menu-zoom" class="menu-zoom" style="height: 25px;" ',
-                                    '<% if(!_.isUndefined(options.stopPropagation)) { %>',
-                                        'data-stopPropagation="true"',
-                                    '<% } %>', '>',
-                                    '<label class="title">' + this.textZoom + '</label>',
-                                    '<button id="id-menu-zoom-in" type="button" style="float:right; margin: 2px 5px 0 0;" class="btn small btn-toolbar"><span class="icon btn-zoomin">&nbsp;</span></button>',
-                                    '<label class="zoom"><%= options.value %>%</label>',
-                                    '<button id="id-menu-zoom-out" type="button" style="float:right; margin-top: 2px;" class="btn small btn-toolbar"><span class="icon btn-zoomout">&nbsp;</span></button>',
-                                '</div>'
-                            ].join('')),
-                            stopPropagation: true,
-                            value: this.mnuZoom.options.value
-                        })
-                    ]
-                }));
-
-                this.mnuZoomOut = new Common.UI.Button({
-                    el  : $('#id-menu-zoom-out'),
-                    cls : 'btn-toolbar'
-                });
-                this.mnuZoomIn = new Common.UI.Button({
-                    el  : $('#id-menu-zoom-in'),
-                    cls : 'btn-toolbar'
-                });
-            }
-            
             if (this.btnBorders && this.btnBorders.rendered) {
                 this.btnBorders.setMenu( new Common.UI.Menu({
                     items: [
@@ -1991,8 +1888,6 @@ define([
         tipDigStylePercent: 'Percent Style',
 //        tipDigStyleCurrency:'Currency Style',
         tipDigStyleAccounting: 'Accounting Style',
-        tipViewSettings:    'View Settings',
-        tipAdvSettings:     'Advanced Settings',
         tipTextOrientation: 'Orientation',
         tipInsertOpt:       'Insert Cells',
         tipDeleteOpt:       'Delete Cells',
@@ -2035,12 +1930,6 @@ define([
         textDelLeft:        'Shift Cells Left',
         textDelUp:          'Shift Cells Up',
         textZoom:           'Zoom',
-        textCompactToolbar: 'Hide Toolbar',
-        textHideTBar:       'Hide Title Bar',
-        textHideFBar:       'Hide Formula Bar',
-        textHideHeadings:   'Hide Headings',
-        textHideGridlines:  'Hide Gridlines',
-        textFreezePanes:    'Freeze Panes',
         txtScheme1:         'Office',
         txtScheme2:         'Grayscale',
         txtScheme3:         'Apex',
diff --git a/apps/spreadsheeteditor/main/locale/en.json b/apps/spreadsheeteditor/main/locale/en.json
index 5835da0a8..dfdd89c35 100644
--- a/apps/spreadsheeteditor/main/locale/en.json
+++ b/apps/spreadsheeteditor/main/locale/en.json
@@ -86,6 +86,12 @@
   "Common.Views.Header.tipViewUsers": "View users and manage document access rights",
   "Common.Views.Header.txtAccessRights": "Change access rights",
   "Common.Views.Header.txtRename": "Rename",
+  "Common.Views.Header.textAdvSettings": "Advanced settings",
+  "Common.Views.Header.textCompactView": "Hide Toolbar",
+  "Common.Views.Header.textHideStatusBar": "Hide Status Bar",
+  "Common.Views.Header.textZoom": "Zoom",
+  "Common.Views.Header.tipViewSettings": "View settings",
+  "Common.Views.Header.textHideLines": "Hide Rulers",
   "Common.Views.ImageFromUrlDialog.cancelButtonText": "Cancel",
   "Common.Views.ImageFromUrlDialog.okButtonText": "OK",
   "Common.Views.ImageFromUrlDialog.textUrl": "Paste an image URL:",
@@ -835,6 +841,10 @@
   "SSE.Controllers.Toolbar.txtSymbol_zeta": "Zeta",
   "SSE.Controllers.Toolbar.warnLongOperation": "The operation you are about to perform might take rather much time to complete.<br>Are you sure you want to continue?",
   "SSE.Controllers.Toolbar.warnMergeLostData": "Only the data from the upper-left cell will remain in the merged cell. <br>Are you sure you want to continue?",
+  "SSE.Controllers.Viewport.textHideFBar": "Hide Formula Bar",
+  "SSE.Controllers.Viewport.textHideGridlines": "Hide Gridlines",
+  "SSE.Controllers.Viewport.textHideHeadings": "Hide Headings",
+  "SSE.Controllers.Viewport.textFreezePanes": "Freeze Panes",
   "SSE.Views.AutoFilterDialog.btnCustomFilter": "Custom Filter",
   "SSE.Views.AutoFilterDialog.cancelButtonText": "Cancel",
   "SSE.Views.AutoFilterDialog.okButtonText": "OK",
@@ -1790,7 +1800,7 @@
   "SSE.Views.Toolbar.textClockwise": "Angle Clockwise",
   "SSE.Views.Toolbar.textColumn": "Column",
   "SSE.Views.Toolbar.textColumnSpark": "Column",
-  "SSE.Views.Toolbar.textCompactToolbar": "Hide Toolbar",
+  "del_SSE.Views.Toolbar.textCompactToolbar": "Hide Toolbar",
   "SSE.Views.Toolbar.textCounterCw": "Angle Counterclockwise",
   "SSE.Views.Toolbar.textDelLeft": "Shift Cells Left",
   "SSE.Views.Toolbar.textDelUp": "Shift Cells Up",
@@ -1798,11 +1808,11 @@
   "SSE.Views.Toolbar.textDiagUpBorder": "Diagonal Up Border",
   "SSE.Views.Toolbar.textEntireCol": "Entire Column",
   "SSE.Views.Toolbar.textEntireRow": "Entire Row",
-  "SSE.Views.Toolbar.textFreezePanes": "Freeze Panes",
-  "SSE.Views.Toolbar.textHideFBar": "Hide Formula Bar",
-  "SSE.Views.Toolbar.textHideGridlines": "Hide Gridlines",
-  "SSE.Views.Toolbar.textHideHeadings": "Hide Headings",
-  "SSE.Views.Toolbar.textHideTBar": "Hide Title Bar",
+  "del_SSE.Views.Toolbar.textFreezePanes": "Freeze Panes",
+  "del_SSE.Views.Toolbar.textHideFBar": "Hide Formula Bar",
+  "del_SSE.Views.Toolbar.textHideGridlines": "Hide Gridlines",
+  "del_SSE.Views.Toolbar.textHideHeadings": "Hide Headings",
+  "del_SSE.Views.Toolbar.textHideTBar": "Hide Title Bar",
   "SSE.Views.Toolbar.textHorizontal": "Horizontal Text",
   "SSE.Views.Toolbar.textInsDown": "Shift Cells Down",
   "SSE.Views.Toolbar.textInsideBorders": "Inside Borders",
@@ -1839,7 +1849,7 @@
   "SSE.Views.Toolbar.textUnderline": "Underline",
   "SSE.Views.Toolbar.textWinLossSpark": "Win/Loss",
   "SSE.Views.Toolbar.textZoom": "Zoom",
-  "SSE.Views.Toolbar.tipAdvSettings": "Advanced settings",
+  "del_SSE.Views.Toolbar.tipAdvSettings": "Advanced settings",
   "SSE.Views.Toolbar.tipAlignBottom": "Align bottom",
   "SSE.Views.Toolbar.tipAlignCenter": "Align center",
   "SSE.Views.Toolbar.tipAlignJust": "Justified",
@@ -1890,7 +1900,7 @@
   "SSE.Views.Toolbar.tipTextOrientation": "Orientation",
   "SSE.Views.Toolbar.tipUndo": "Undo",
   "SSE.Views.Toolbar.tipVAligh": "Vertical Alignment",
-  "SSE.Views.Toolbar.tipViewSettings": "View settings",
+  "del_SSE.Views.Toolbar.tipViewSettings": "View settings",
   "SSE.Views.Toolbar.tipWrap": "Wrap text",
   "SSE.Views.Toolbar.txtAccounting": "Accounting",
   "SSE.Views.Toolbar.txtAdditional": "Additional",

From 456f4dcc2d8a3b73cc98a5f25c96ce0547e6ab80 Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 21 Mar 2018 14:28:52 +0300
Subject: [PATCH 38/41] refactoring

---
 apps/common/main/lib/component/DataView.js         | 7 ++++---
 apps/spreadsheeteditor/main/app/controller/Main.js | 5 +----
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/apps/common/main/lib/component/DataView.js b/apps/common/main/lib/component/DataView.js
index 64c0533c0..f57da14cf 100644
--- a/apps/common/main/lib/component/DataView.js
+++ b/apps/common/main/lib/component/DataView.js
@@ -140,9 +140,10 @@ define([
             el.html(this.template(this.model.toJSON()));
             el.addClass('item');
             el.toggleClass('selected', this.model.get('selected') && this.model.get('allowSelected'));
-            el.off('click').on('click', _.bind(this.onClick, this));
-            el.off('dblclick').on('dblclick', _.bind(this.onDblClick, this));
-            el.off('contextmenu').on('contextmenu', _.bind(this.onContextMenu, this));
+            el.off('click dblclick contextmenu');
+            el.on({ 'click': _.bind(this.onClick, this),
+                'dblclick': _.bind(this.onDblClick, this),
+                'contextmenu': _.bind(this.onContextMenu, this) });
             el.toggleClass('disabled', !!this.model.get('disabled'));
 
             if (!_.isUndefined(this.model.get('cls')))
diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js
index b85ff59f2..3134f6892 100644
--- a/apps/spreadsheeteditor/main/app/controller/Main.js
+++ b/apps/spreadsheeteditor/main/app/controller/Main.js
@@ -909,15 +909,12 @@ define([
             applyModeCommonElements: function() {
                 window.editor_elements_prepared = true;
 
-                var value = Common.localStorage.getItem("sse-hidden-title");
-                value = this.appOptions.isEdit && (value!==null && parseInt(value) == 1);
-
                 var app             = this.getApplication(),
                     viewport        = app.getController('Viewport').getView('Viewport'),
                     statusbarView   = app.getController('Statusbar').getView('Statusbar');
 
                 if (this.headerView) {
-                    this.headerView.setVisible(!this.appOptions.nativeApp && !value && !this.appOptions.isEditMailMerge &&
+                    this.headerView.setVisible(!this.appOptions.nativeApp && !this.appOptions.isEditMailMerge &&
                             !this.appOptions.isDesktopApp && !this.appOptions.isEditDiagram);
                 }
 

From ff8f958d0b6f777e4dab99912a79c811ef36397a Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 21 Mar 2018 14:29:43 +0300
Subject: [PATCH 39/41] [ALL] applied translation for Viewport controller

---
 apps/documenteditor/main/app/controller/Viewport.js     | 3 ++-
 apps/presentationeditor/main/app/controller/Viewport.js | 3 ++-
 apps/spreadsheeteditor/main/app/controller/Viewport.js  | 3 ++-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/apps/documenteditor/main/app/controller/Viewport.js b/apps/documenteditor/main/app/controller/Viewport.js
index 0c889b7c0..43b07abda 100644
--- a/apps/documenteditor/main/app/controller/Viewport.js
+++ b/apps/documenteditor/main/app/controller/Viewport.js
@@ -49,7 +49,7 @@ define([
 ], function (Viewport) {
     'use strict';
 
-    DE.Controllers.Viewport = Backbone.Controller.extend({
+    DE.Controllers.Viewport = Backbone.Controller.extend(_.assign({
         // Specifying a Viewport model
         models: [],
 
@@ -366,4 +366,5 @@ define([
 
         textFitPage: 'Fit to Page',
         textFitWidth: 'Fit to Width'
+    }, DE.Controllers.Viewport));
 });
diff --git a/apps/presentationeditor/main/app/controller/Viewport.js b/apps/presentationeditor/main/app/controller/Viewport.js
index 6ae3dbbe9..053110bc2 100644
--- a/apps/presentationeditor/main/app/controller/Viewport.js
+++ b/apps/presentationeditor/main/app/controller/Viewport.js
@@ -49,7 +49,7 @@ define([
 ], function (Viewport) {
     'use strict';
 
-    PE.Controllers.Viewport = Backbone.Controller.extend({
+    PE.Controllers.Viewport = Backbone.Controller.extend(_.assign({
         // Specifying a Viewport model
         models: [],
 
@@ -403,4 +403,5 @@ define([
 
         textFitPage: 'Fit to Page',
         textFitWidth: 'Fit to Width'
+    }, PE.Controllers.Viewport));
 });
diff --git a/apps/spreadsheeteditor/main/app/controller/Viewport.js b/apps/spreadsheeteditor/main/app/controller/Viewport.js
index ce517338f..fc3a06846 100644
--- a/apps/spreadsheeteditor/main/app/controller/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/controller/Viewport.js
@@ -48,7 +48,7 @@ define([
 ], function (Viewport) {
     'use strict';
 
-    SSE.Controllers.Viewport = Backbone.Controller.extend({
+    SSE.Controllers.Viewport = Backbone.Controller.extend(_.assign({
         // Specifying a Viewport model
         models: [],
 
@@ -413,4 +413,5 @@ define([
         textHideHeadings: 'Hide Headings',
         textHideGridlines: 'Hide Gridlines',
         textFreezePanes: 'Freeze Panes'
+    }, SSE.Controllers.Viewport));
 });

From 4bc206543c0385797f479dbb986c0b561159951f Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Tue, 27 Mar 2018 13:39:29 +0300
Subject: [PATCH 40/41] [SSE] fix bug 36623

---
 apps/spreadsheeteditor/main/app/controller/Viewport.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/apps/spreadsheeteditor/main/app/controller/Viewport.js b/apps/spreadsheeteditor/main/app/controller/Viewport.js
index fc3a06846..aacac3680 100644
--- a/apps/spreadsheeteditor/main/app/controller/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/controller/Viewport.js
@@ -142,7 +142,7 @@ define([
                 me.viewport.vlayout.getItem('toolbar').height = 41;
             }
 
-            if ( config.isDesktopApp && config.isEdit ) {
+            if ( config.isDesktopApp && config.isEdit && !config.isEditDiagram && !config.isEditMailMerge ) {
                 var $title = me.viewport.vlayout.getItem('title').el;
                 $title.html(me.header.getPanel('title', config)).show();
 

From 59b6193f2458bd813cc69c71eafb65c0d1c97e9b Mon Sep 17 00:00:00 2001
From: Maxim Kadushkin <maxim.kadushkin@onlyoffice.com>
Date: Wed, 28 Mar 2018 13:37:41 +0300
Subject: [PATCH 41/41] [DE] refactoring

---
 apps/common/main/lib/view/Header.js                    | 2 +-
 apps/documenteditor/main/app/collection/ShapeGroups.js | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/apps/common/main/lib/view/Header.js b/apps/common/main/lib/view/Header.js
index 405e63780..1bf226196 100644
--- a/apps/common/main/lib/view/Header.js
+++ b/apps/common/main/lib/view/Header.js
@@ -379,7 +379,7 @@ define([
 
             initialize: function (options) {
                 var me = this;
-                this.options = this.options ? _({}).extend(this.options, options) : options;
+                this.options = this.options ? _.extend(this.options, options) : options;
 
                 this.documentCaption = this.options.documentCaption;
                 this.branding = this.options.customization;
diff --git a/apps/documenteditor/main/app/collection/ShapeGroups.js b/apps/documenteditor/main/app/collection/ShapeGroups.js
index f453d8f93..40ae2e80f 100644
--- a/apps/documenteditor/main/app/collection/ShapeGroups.js
+++ b/apps/documenteditor/main/app/collection/ShapeGroups.js
@@ -46,6 +46,7 @@ define([
         var Common = {};
 
     Common.Collections = Common.Collections || {};
+    DE.Collections = DE.Collections || {};
 
     DE.Collections.ShapeGroups = Backbone.Collection.extend({
         model: DE.Models.ShapeGroup