diff --git a/apps/spreadsheeteditor/main/app.js b/apps/spreadsheeteditor/main/app.js
index 2057534be..2adb3fef1 100644
--- a/apps/spreadsheeteditor/main/app.js
+++ b/apps/spreadsheeteditor/main/app.js
@@ -160,6 +160,7 @@ require([
'DataTab',
'ViewTab',
'Common.Controllers.Fonts',
+ 'Common.Controllers.History',
'Common.Controllers.Chat',
'Common.Controllers.Comments',
'Common.Controllers.Plugins'
@@ -196,6 +197,7 @@ require([
'common/main/lib/util/utils',
'common/main/lib/util/LocalStorage',
'common/main/lib/controller/Fonts',
+ 'common/main/lib/controller/History',
'common/main/lib/controller/Comments',
'common/main/lib/controller/Chat',
'common/main/lib/controller/Plugins'
diff --git a/apps/spreadsheeteditor/main/app/controller/LeftMenu.js b/apps/spreadsheeteditor/main/app/controller/LeftMenu.js
index 2127bd08e..88096da1d 100644
--- a/apps/spreadsheeteditor/main/app/controller/LeftMenu.js
+++ b/apps/spreadsheeteditor/main/app/controller/LeftMenu.js
@@ -56,7 +56,11 @@ define([
'hide': _.bind(this.onHidePlugins, this)
},
'Common.Views.Header': {
- 'file:settings': _.bind(this.clickToolbarSettings,this)
+ 'file:settings': _.bind(this.clickToolbarSettings,this),
+ 'history:show': function () {
+ if ( !this.leftMenu.panelHistory.isVisible() )
+ this.clickMenuFileItem('header', 'history');
+ }.bind(this)
},
'LeftMenu': {
'file:show': _.bind(this.fileShowHide, this, true),
@@ -98,6 +102,10 @@ define([
}
});
Common.NotificationCenter.on('app:comment:add', _.bind(this.onAppAddComment, this));
+ Common.NotificationCenter.on('collaboration:history', _.bind(function () {
+ if ( !this.leftMenu.panelHistory.isVisible() )
+ this.clickMenuFileItem(null, 'history');
+ }, this));
},
onLaunch: function() {
@@ -169,6 +177,8 @@ define([
if (!this.mode.isEditMailMerge && !this.mode.isEditDiagram)
this.api.asc_registerCallback('asc_onEditCell', _.bind(this.onApiEditCell, this));
this.leftMenu.getMenu('file').setApi(api);
+ if (this.mode.canUseHistory)
+ this.getApplication().getController('Common.Controllers.History').setApi(this.api).setMode(this.mode);
return this;
},
@@ -224,6 +234,8 @@ define([
this.leftMenu.btnSpellcheck.show();
this.leftMenu.setOptionsPanel('spellcheck', this.getApplication().getController('Spellcheck').getView('Spellcheck'));
}
+ if (this.mode.canUseHistory)
+ this.leftMenu.setOptionsPanel('history', this.getApplication().getController('Common.Controllers.History').getView('Common.Views.History'));
(this.mode.trialMode || this.mode.isBeta) && this.leftMenu.setDeveloperMode(this.mode.trialMode, this.mode.isBeta, this.mode.buildVersion);
/** coauthoring end **/
@@ -272,10 +284,35 @@ define([
}
})).show();
break;
+ case 'history':
+ if (!this.leftMenu.panelHistory.isVisible()) {
+ if (this.api.asc_isDocumentModified()) {
+ var me = this;
+ this.api.asc_stopSaving();
+ Common.UI.warning({
+ closable: false,
+ width: 500,
+ title: this.notcriticalErrorTitle,
+ msg: this.leavePageText,
+ buttons: ['ok', 'cancel'],
+ primary: 'ok',
+ callback: function(btn) {
+ if (btn == 'ok') {
+ me.api.asc_undoAllChanges();
+ me.api.asc_continueSaving();
+ me.showHistory();
+ } else
+ me.api.asc_continueSaving();
+ }
+ });
+ } else
+ this.showHistory();
+ }
+ break;
default: close_menu = false;
}
- if (close_menu) {
+ if (close_menu && menu) {
menu.hide();
}
},
@@ -954,6 +991,17 @@ define([
}
},
+ showHistory: function() {
+ if (!this.mode.wopi) {
+ var maincontroller = this.getApplication().getController('Main');
+ if (!maincontroller.loadMask)
+ maincontroller.loadMask = new Common.UI.LoadMask({owner: $('#viewport')});
+ maincontroller.loadMask.setTitle(this.textLoadHistory);
+ maincontroller.loadMask.show();
+ }
+ Common.Gateway.requestHistory();
+ },
+
textNoTextFound : 'Text not found',
newDocumentTitle : 'Unnamed document',
textItemEntireCell : 'Entire cell contents',
@@ -971,6 +1019,8 @@ define([
textWithin: 'Within',
textSearch: 'Search',
textLookin: 'Look in',
- txtUntitled: 'Untitled'
+ txtUntitled: 'Untitled',
+ textLoadHistory : 'Loading version history...',
+ leavePageText: 'All unsaved changes in this document will be lost.
Click \'Cancel\' then \'Save\' to save them. Click \'OK\' to discard all the unsaved changes.'
}, SSE.Controllers.LeftMenu || {}));
});
\ No newline at end of file
diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js
index 28f486644..555ccc576 100644
--- a/apps/spreadsheeteditor/main/app/controller/Main.js
+++ b/apps/spreadsheeteditor/main/app/controller/Main.js
@@ -90,7 +90,8 @@ define([
'TableTemplates',
'ConditionalFormatIcons',
'ConditionalFormatIconsPresets',
- 'Common.Collections.TextArt'
+ 'Common.Collections.TextArt',
+ 'Common.Collections.HistoryUsers'
],
views: [],
@@ -939,6 +940,7 @@ define([
Common.Gateway.on('downloadas', _.bind(me.onDownloadAs, me));
Common.Gateway.on('setfavorite', _.bind(me.onSetFavorite, me));
Common.Gateway.on('requestclose', _.bind(me.onRequestClose, me));
+ Common.Gateway.on('refreshhistory',_.bind(me.onRefreshHistory, me));
Common.Gateway.sendInfo({mode:me.appOptions.isEdit?'edit':'view'});
$(document).on('contextmenu', _.bind(me.onContextMenu, me));
@@ -1142,6 +1144,14 @@ define([
this.getApplication().getController('Common.Controllers.Plugins').setMode(this.appOptions);
}
+ this.appOptions.canUseHistory = this.appOptions.canLicense && this.editorConfig.canUseHistory && this.appOptions.canCoAuthoring && !this.appOptions.isOffline;
+ this.appOptions.canHistoryClose = this.editorConfig.canHistoryClose;
+ this.appOptions.canHistoryRestore= this.editorConfig.canHistoryRestore;
+
+ if ( this.appOptions.isLightVersion ) {
+ this.appOptions.canUseHistory = false;
+ }
+
this.loadCoAuthSettings();
this.applyModeCommonElements();
this.applyModeEditorElements();
@@ -2549,6 +2559,157 @@ define([
this._renameDialog.show(Common.Utils.innerWidth() - this._renameDialog.options.width - 15, 30);
},
+ onRefreshHistory: function(opts) {
+ if (!this.appOptions.canUseHistory) return;
+
+ this.loadMask && this.loadMask.hide();
+ if (opts.data.error || !opts.data.history) {
+ var historyStore = this.getApplication().getCollection('Common.Collections.HistoryVersions');
+ if (historyStore && historyStore.size()>0) {
+ historyStore.each(function(item){
+ item.set('canRestore', false);
+ });
+ }
+ Common.UI.alert({
+ title: this.notcriticalErrorTitle,
+ msg: (opts.data.error) ? opts.data.error : this.txtErrorLoadHistory,
+ iconCls: 'warn',
+ buttons: ['ok'],
+ callback: _.bind(function(btn){
+ this.onEditComplete();
+ }, this)
+ });
+ } else {
+ this.api.asc_coAuthoringDisconnect();
+ this.headerView.setCanRename(false);
+ this.headerView.getButton('users') && this.headerView.getButton('users').hide();
+ this.getApplication().getController('LeftMenu').getView('LeftMenu').showHistory();
+ this.disableEditing(true);
+ this._renameDialog && this._renameDialog.close();
+ var versions = opts.data.history,
+ historyStore = this.getApplication().getCollection('Common.Collections.HistoryVersions'),
+ currentVersion = null;
+ if (historyStore) {
+ var arrVersions = [], ver, version, group = -1, prev_ver = -1, arrColors = [], docIdPrev = '',
+ usersStore = this.getApplication().getCollection('Common.Collections.HistoryUsers'), user = null, usersCnt = 0;
+
+ for (ver=versions.length-1; ver>=0; ver--) {
+ version = versions[ver];
+ if (version.versionGroup===undefined || version.versionGroup===null)
+ version.versionGroup = version.version;
+ if (version) {
+ if (!version.user) version.user = {};
+ docIdPrev = (ver>0 && versions[ver-1]) ? versions[ver-1].key : version.key + '0';
+ user = usersStore.findUser(version.user.id);
+ if (!user) {
+ user = new Common.Models.User({
+ id : version.user.id,
+ username : version.user.name,
+ colorval : Asc.c_oAscArrUserColors[usersCnt],
+ color : this.generateUserColor(Asc.c_oAscArrUserColors[usersCnt++])
+ });
+ usersStore.add(user);
+ }
+
+ arrVersions.push(new Common.Models.HistoryVersion({
+ version: version.versionGroup,
+ revision: version.version,
+ userid : version.user.id,
+ username : version.user.name,
+ usercolor: user.get('color'),
+ created: version.created,
+ docId: version.key,
+ markedAsVersion: (group!==version.versionGroup),
+ selected: (opts.data.currentVersion == version.version),
+ canRestore: this.appOptions.canHistoryRestore && (ver < versions.length-1),
+ isExpanded: true,
+ serverVersion: version.serverVersion
+ }));
+ if (opts.data.currentVersion == version.version) {
+ currentVersion = arrVersions[arrVersions.length-1];
+ }
+ group = version.versionGroup;
+ if (prev_ver!==version.version) {
+ prev_ver = version.version;
+ arrColors.reverse();
+ for (i=0; i0) {
+ arrVersions[arrVersions.length-1].set('docIdPrev', docIdPrev);
+ if (!_.isEmpty(version.serverVersion) && version.serverVersion == this.appOptions.buildVersion) {
+ arrVersions[arrVersions.length-1].set('changeid', changes.length-1);
+ arrVersions[arrVersions.length-1].set('hasChanges', changes.length>1);
+ for (i=changes.length-2; i>=0; i--) {
+ change = changes[i];
+
+ user = usersStore.findUser(change.user.id);
+ if (!user) {
+ user = new Common.Models.User({
+ id : change.user.id,
+ username : change.user.name,
+ colorval : Asc.c_oAscArrUserColors[usersCnt],
+ color : this.generateUserColor(Asc.c_oAscArrUserColors[usersCnt++])
+ });
+ usersStore.add(user);
+ }
+
+ arrVersions.push(new Common.Models.HistoryVersion({
+ version: version.versionGroup,
+ revision: version.version,
+ changeid: i,
+ userid : change.user.id,
+ username : change.user.name,
+ usercolor: user.get('color'),
+ created: change.created,
+ docId: version.key,
+ docIdPrev: docIdPrev,
+ selected: false,
+ canRestore: this.appOptions.canHistoryRestore && this.appOptions.canDownload,
+ isRevision: false,
+ isVisible: true,
+ serverVersion: version.serverVersion
+ }));
+ arrColors.push(user.get('colorval'));
+ }
+ }
+ } else if (ver==0 && versions.length==1) {
+ arrVersions[arrVersions.length-1].set('docId', version.key + '1');
+ }
+ }
+ }
+ if (arrColors.length>0) {
+ arrColors.reverse();
+ for (i=0; i0) {
+ currentVersion = historyStore.at(0);
+ currentVersion.set('selected', true);
+ }
+ // if (currentVersion)
+ // this.getApplication().getController('Common.Controllers.History').onSelectRevision(null, null, currentVersion);
+ }
+ }
+ },
+
+ DisableVersionHistory: function() {
+ this.editorConfig.canUseHistory = false;
+ this.appOptions.canUseHistory = false;
+ },
+
+ generateUserColor: function(color) {
+ return"#"+("000000"+color.toString(16)).substr(-6);
+ },
+
onGrabFocus: function() {
this.getApplication().getController('DocumentHolder').getView().focus();
},
@@ -2953,7 +3114,8 @@ define([
errorPivotWithoutUnderlying: 'The Pivot Table report was saved without the underlying data.
Use the \'Refresh\' button to update the report.',
txtQuarter: 'Qtr',
txtOr: '%1 or %2',
- confirmReplaceFormulaInTable: 'Formulas in the header row will be removed and converted to static text.
Do you want to continue?'
+ confirmReplaceFormulaInTable: 'Formulas in the header row will be removed and converted to static text.
Do you want to continue?',
+ txtErrorLoadHistory: 'Loading history failed'
}
})(), SSE.Controllers.Main || {}))
});
diff --git a/apps/spreadsheeteditor/main/app/controller/Viewport.js b/apps/spreadsheeteditor/main/app/controller/Viewport.js
index 525c719ab..fc3e15791 100644
--- a/apps/spreadsheeteditor/main/app/controller/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/controller/Viewport.js
@@ -356,10 +356,11 @@ define([
this.api.asc_Resize();
}, this);
- var leftPanel = $('#left-menu');
+ var leftPanel = $('#left-menu'),
+ histPanel = $('#left-panel-history');
this.viewport.hlayout.on('layout:resizedrag', function() {
this.api.asc_Resize();
- Common.localStorage.setItem('sse-mainmenu-width',leftPanel.width());
+ Common.localStorage.setItem('sse-mainmenu-width',histPanel.is(':visible') ? (histPanel.width()+SCALE_MIN) : leftPanel.width());
}, this);
this.boxSdk = $('#editor_sdk');
@@ -380,6 +381,14 @@ define([
case 'rightmenu':
this.viewport.hlayout.doLayout();
break;
+ case 'history':
+ var panel = this.viewport.hlayout.items[1];
+ if (panel.resize.el) {
+ this.boxSdk.css('border-left', '');
+ panel.resize.el.show();
+ }
+ this.viewport.hlayout.doLayout();
+ break;
case 'leftmenu':
var panel = this.viewport.hlayout.items[0];
if (panel.resize.el) {
diff --git a/apps/spreadsheeteditor/main/app/template/FileMenu.template b/apps/spreadsheeteditor/main/app/template/FileMenu.template
index a2c9eb462..8bb022a44 100644
--- a/apps/spreadsheeteditor/main/app/template/FileMenu.template
+++ b/apps/spreadsheeteditor/main/app/template/FileMenu.template
@@ -16,6 +16,7 @@
+
diff --git a/apps/spreadsheeteditor/main/app/template/Viewport.template b/apps/spreadsheeteditor/main/app/template/Viewport.template
index e9dd6ee38..1628f2610 100644
--- a/apps/spreadsheeteditor/main/app/template/Viewport.template
+++ b/apps/spreadsheeteditor/main/app/template/Viewport.template
@@ -16,6 +16,7 @@
+
diff --git a/apps/spreadsheeteditor/main/app/view/FileMenu.js b/apps/spreadsheeteditor/main/app/view/FileMenu.js
index 3b6256650..0be1c83df 100644
--- a/apps/spreadsheeteditor/main/app/view/FileMenu.js
+++ b/apps/spreadsheeteditor/main/app/view/FileMenu.js
@@ -178,6 +178,13 @@ define([
canFocused: false
});
+ this.miHistory = new Common.UI.MenuItem({
+ el : $markup.elementById('#fm-btn-history'),
+ action : 'history',
+ caption : this.btnHistoryCaption,
+ canFocused: false
+ });
+
this.items = [];
this.items.push(
new Common.UI.MenuItem({
@@ -203,6 +210,7 @@ define([
canFocused: false
}),
this.miAccess,
+ this.miHistory,
this.miSettings,
this.miHelp,
new Common.UI.MenuItem({
@@ -327,6 +335,8 @@ define([
this.panels['help'].setLangConfig(this.mode.lang);
}
+ this.miHistory[this.mode.canUseHistory&&!this.mode.isDisconnected?'show':'hide']();
+
if ( this.mode.disableEditing != undefined ) {
this.panels['opts'].SetDisabled(this.mode.disableEditing);
delete this.mode.disableEditing;
@@ -456,6 +466,7 @@ define([
btnRenameCaption : 'Rename...',
btnCloseMenuCaption : 'Close Menu',
btnProtectCaption: 'Protect',
- btnSaveCopyAsCaption : 'Save Copy as...'
+ btnSaveCopyAsCaption : 'Save Copy as...',
+ btnHistoryCaption : 'Versions History'
}, SSE.Views.FileMenu || {}));
});
diff --git a/apps/spreadsheeteditor/main/app/view/LeftMenu.js b/apps/spreadsheeteditor/main/app/view/LeftMenu.js
index 8cca99aab..8b261c325 100644
--- a/apps/spreadsheeteditor/main/app/view/LeftMenu.js
+++ b/apps/spreadsheeteditor/main/app/view/LeftMenu.js
@@ -40,6 +40,7 @@ define([
/** coauthoring begin **/
'common/main/lib/view/Comments',
'common/main/lib/view/Chat',
+ 'common/main/lib/view/History',
/** coauthoring end **/
'common/main/lib/view/SearchDialog',
'common/main/lib/view/Plugins',
@@ -244,6 +245,8 @@ define([
} else
if (name == 'spellcheck' && !this.panelSpellcheck) {
this.panelSpellcheck = panel.render('#left-panel-spellcheck');
+ } else if (name == 'history') {
+ this.panelHistory = panel.render('#left-panel-history');
}
},
@@ -423,6 +426,14 @@ define([
this.limitHint && this.limitHint.css('top', top);
},
+ showHistory: function() {
+ this._state.pluginIsRunning = false;
+ this._state.historyIsRunning = true;
+ this.panelHistory.show();
+ this.panelHistory.$el.width((parseInt(Common.localStorage.getItem('sse-mainmenu-width')) || MENU_SCALE_PART) - SCALE_MIN);
+ Common.NotificationCenter.trigger('layout:changed', 'history');
+ },
+
/** coauthoring begin **/
tipComments : 'Comments',
tipChat : 'Chat',
diff --git a/apps/spreadsheeteditor/main/app/view/Viewport.js b/apps/spreadsheeteditor/main/app/view/Viewport.js
index d866e501a..baa0d58c9 100644
--- a/apps/spreadsheeteditor/main/app/view/Viewport.js
+++ b/apps/spreadsheeteditor/main/app/view/Viewport.js
@@ -117,6 +117,15 @@ define([
max: 600,
offset: 4
}
+ }, { // history versions
+ el: items[3],
+ rely: true,
+ resize: {
+ hidden: true,
+ autohide: false,
+ min: 300,
+ max: 600
+ }
}, {
el: items[1],
stretch: true
diff --git a/apps/spreadsheeteditor/main/app_dev.js b/apps/spreadsheeteditor/main/app_dev.js
index 86e790254..a5a63c7e5 100644
--- a/apps/spreadsheeteditor/main/app_dev.js
+++ b/apps/spreadsheeteditor/main/app_dev.js
@@ -150,6 +150,7 @@ require([
'DataTab',
'ViewTab',
'Common.Controllers.Fonts',
+ 'Common.Controllers.History',
'Common.Controllers.Chat',
'Common.Controllers.Comments',
'Common.Controllers.Plugins'
@@ -186,6 +187,7 @@ require([
'common/main/lib/util/utils',
'common/main/lib/util/LocalStorage',
'common/main/lib/controller/Fonts',
+ 'common/main/lib/controller/History',
'common/main/lib/controller/Comments',
'common/main/lib/controller/Chat',
'common/main/lib/controller/Plugins'
diff --git a/apps/spreadsheeteditor/main/resources/less/app.less b/apps/spreadsheeteditor/main/resources/less/app.less
index a92f42255..3573f82e4 100644
--- a/apps/spreadsheeteditor/main/resources/less/app.less
+++ b/apps/spreadsheeteditor/main/resources/less/app.less
@@ -120,6 +120,7 @@
@import "../../../../common/main/resources/less/language-dialog.less";
@import "../../../../common/main/resources/less/winxp_fix.less";
@import "../../../../common/main/resources/less/symboltable.less";
+@import "../../../../common/main/resources/less/history.less";
// App
// --------------------------------------------------
diff --git a/apps/spreadsheeteditor/main/resources/less/layout.less b/apps/spreadsheeteditor/main/resources/less/layout.less
index 54b5f4216..73e06aa0c 100644
--- a/apps/spreadsheeteditor/main/resources/less/layout.less
+++ b/apps/spreadsheeteditor/main/resources/less/layout.less
@@ -71,4 +71,11 @@ label {
.tooltip-inner {
max-width: none;
}
+}
+
+#left-panel-history {
+ left: 40px;
+ width: 300px;
+ height: 100%;
+ display: none;
}
\ No newline at end of file
diff --git a/apps/spreadsheeteditor/main/resources/less/leftmenu.less b/apps/spreadsheeteditor/main/resources/less/leftmenu.less
index 778e54c5d..1d6fb4a66 100644
--- a/apps/spreadsheeteditor/main/resources/less/leftmenu.less
+++ b/apps/spreadsheeteditor/main/resources/less/leftmenu.less
@@ -14,6 +14,12 @@
}
}
+.left-panel {
+ #left-panel-history {
+ height: 100%;
+ }
+}
+
.left-menu-full-ct {
width: 100%;
height: 100%;