diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js
index ad2263ec66..a0a9917949 100644
--- a/apps/api/documents/api.js
+++ b/apps/api/documents/api.js
@@ -105,15 +105,16 @@
url: 'http://...',
text: 'Go to London'
},
- chat: false,
- comments: false,
+ chat: true,
+ comments: true,
zoom: 100,
compactToolbar: false,
leftMenu: true,
rightMenu: true,
toolbar: true,
header: true,
- autosave: true
+ autosave: true,
+ forcesave: false
},
plugins: {
autoStartGuid: 'asc.{FFE1F462-1EA2-4391-990D-4CC84940B754}',
diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js
index 70734511fc..de2841c5e8 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -541,10 +541,13 @@ define([
application.getController('DocumentHolder').getView().focus();
if (this.api) {
- var cansave = this.api.asc_isDocumentCanSave();
+ var cansave = this.api.asc_isDocumentCanSave(),
+ forcesave = this.appOptions.forcesave;
var isSyncButton = $('.btn-icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch');
if (toolbarView.btnSave.isDisabled() !== (!cansave && !isSyncButton || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1))
toolbarView.btnSave.setDisabled(!cansave && !isSyncButton || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1);
+ if (toolbarView.btnSave.isDisabled() !== (!cansave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave))
+ toolbarView.btnSave.setDisabled(!cansave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave);
}
},
@@ -569,29 +572,23 @@ define([
if (action) {
this.setLongActionView(action)
} else {
- if ( id==Asc.c_oAscAsyncAction.Save ) {
- var me = this;
- if ( me._state.fastCoauth && me._state.usersCount > 1 ) {
- if ( !me._state.timerSave &&
- Date.now() - me._state.isSaving < 500 )
- {
- me._state.timerSave = setTimeout(function () {
- me.getApplication().getController('Viewport').getView('Common.Views.Header').setSaveStatus('end');
- delete me._state.timerSave;
- }, 500);
- }
- } else {
- me.getApplication().getController('Viewport').getView('Common.Views.Header').setSaveStatus('end');
- }
- } else {
+ if (id==Asc.c_oAscAsyncAction['Save'] || id==Asc.c_oAscAsyncAction['ForceSaveButton']) {
+ if (this._state.fastCoauth && this._state.usersCount>1) {
+ var me = this;
+ me._state.timerSave = setTimeout(function () {
+ me.getApplication().getController('Viewport').getView('Common.Views.Header').setSaveStatus('end');
+ delete me._state.timerSave;
+ }, 500);
+ } else
+ this.getApplication().getController('Viewport').getView('Common.Views.Header').setSaveStatus('end');
+ } else
this.getApplication().getController('Statusbar').setStatusCaption('');
- }
}
action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.BlockInteraction});
action ? this.setLongActionView(action) : this.loadMask && this.loadMask.hide();
- if (id==Asc.c_oAscAsyncAction['Save'] && (!this._state.fastCoauth || this._state.usersCount<2))
+ if ((id==Asc.c_oAscAsyncAction['Save'] || id==Asc.c_oAscAsyncAction['ForceSaveButton']) && (!this._state.fastCoauth || this._state.usersCount<2))
this.synchronizeChanges();
if ( type == Asc.c_oAscAsyncActionType.BlockInteraction &&
@@ -603,7 +600,7 @@ define([
},
setLongActionView: function(action) {
- var title = '', text = '';
+ var title = '', text = '', force = false;
switch (action.id) {
case Asc.c_oAscAsyncAction['Open']:
@@ -612,7 +609,9 @@ define([
break;
case Asc.c_oAscAsyncAction['Save']:
- this._state.isSaving = Date.now();
+ case Asc.c_oAscAsyncAction['ForceSaveButton']:
+ clearTimeout(this._state.timerSave);
+ force = true;
// title = this.saveTitleText;
// text = this.saveTextText;
break;
@@ -697,7 +696,7 @@ define([
if (!this.isShowOpenDialog)
this.loadMask.show();
} else
- if ( action.id == Asc.c_oAscAsyncAction.Save ) {
+ if ( action.id == Asc.c_oAscAsyncAction.Save || action.id == Asc.c_oAscAsyncAction['ForceSaveButton']) {
this.getApplication().getController('Viewport').getView('Common.Views.Header').setSaveStatus('begin');
} else {
this.getApplication().getController('Statusbar').setStatusCaption(text);
@@ -894,6 +893,12 @@ define([
me.api.asc_setAutoSaveGap(value);
+ if (me.appOptions.canForcesave) {// use asc_setIsForceSaveOnUserSave only when customization->forcesave = true
+ value = Common.localStorage.getItem("de-settings-forcesave");
+ me.appOptions.forcesave = (value===null) ? me.appOptions.canForcesave : (parseInt(value)==1);
+ me.api.asc_setIsForceSaveOnUserSave(me.appOptions.forcesave);
+ }
+
if (me.needToUpdateVersion)
Common.NotificationCenter.trigger('api:disconnect');
var timer_sl = setInterval(function(){
@@ -1017,6 +1022,8 @@ define([
this.appOptions.canPrint = (this.permissions.print !== false);
this.appOptions.canRename = !!this.permissions.rename;
this.appOptions.buildVersion = params.asc_getBuildVersion();
+ this.appOptions.canForcesave = this.appOptions.isEdit && !this.appOptions.isOffline && (typeof (this.editorConfig.customization) == 'object' && !!this.editorConfig.customization.forcesave);
+ this.appOptions.forcesave = this.appOptions.canForcesave;
if ( this.appOptions.isLightVersion ) {
this.appOptions.canUseHistory =
@@ -1418,9 +1425,11 @@ define([
if (window.document.title != title)
window.document.title = title;
- if (!this._state.fastCoauth || this._state.usersCount<2 )
+ if (!this._state.fastCoauth || this._state.usersCount<2 ) {
Common.Gateway.setDocumentModified(isModified);
- else if ( this._state.startModifyDocument!==undefined && this._state.startModifyDocument === isModified){
+ if (isModified)
+ this.getApplication().getController('Statusbar').setStatusCaption('', true);
+ } else if ( this._state.startModifyDocument!==undefined && this._state.startModifyDocument === isModified){
Common.Gateway.setDocumentModified(isModified);
this._state.startModifyDocument = (this._state.startModifyDocument) ? !this._state.startModifyDocument : undefined;
}
@@ -1445,9 +1454,10 @@ define([
var toolbarView = this.getApplication().getController('Toolbar').getView('Toolbar');
if (toolbarView) {
- var isSyncButton = $('.btn-icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch');
- if (toolbarView.btnSave.isDisabled() !== (!isModified && !isSyncButton || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1))
- toolbarView.btnSave.setDisabled(!isModified && !isSyncButton || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1);
+ var isSyncButton = $('.btn-icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
+ forcesave = this.appOptions.forcesave;
+ if (toolbarView.btnSave.isDisabled() !== (!isModified && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave))
+ toolbarView.btnSave.setDisabled(!isModified && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave);
}
/** coauthoring begin **/
@@ -1462,9 +1472,10 @@ define([
toolbarView = toolbarController.getView('Toolbar');
if (toolbarView && this.api) {
- var isSyncButton = $('.btn-icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch');
- if (toolbarView.btnSave.isDisabled() !== (!isCanSave && !isSyncButton || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1))
- toolbarView.btnSave.setDisabled(!isCanSave && !isSyncButton || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1);
+ var isSyncButton = $('.btn-icon', toolbarView.btnSave.cmpEl).hasClass('btn-synch'),
+ forcesave = this.appOptions.forcesave;
+ if (toolbarView.btnSave.isDisabled() !== (!isCanSave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave))
+ toolbarView.btnSave.setDisabled(!isCanSave && !isSyncButton && !forcesave || this._state.isDisconnected || this._state.fastCoauth && this._state.usersCount>1 && !forcesave);
}
},
@@ -1578,7 +1589,7 @@ define([
if (this._state.hasCollaborativeChanges) return;
this._state.hasCollaborativeChanges = true;
if (this.appOptions.isEdit)
- this.getApplication().getController('Statusbar').setStatusCaption(this.txtNeedSynchronize);
+ this.getApplication().getController('Statusbar').setStatusCaption(this.txtNeedSynchronize, true);
},
/** coauthoring end **/
@@ -1830,6 +1841,11 @@ define([
if (this._state.fastCoauth && !oldval)
this.synchronizeChanges();
}
+ if (this.appOptions.canForcesave) {
+ value = Common.localStorage.getItem("de-settings-forcesave");
+ this.appOptions.forcesave = (value===null) ? this.appOptions.canForcesave : (parseInt(value)==1);
+ this.api.asc_setIsForceSaveOnUserSave(this.appOptions.forcesave);
+ }
},
onDocumentName: function(name) {
@@ -2129,7 +2145,8 @@ define([
errorSessionToken: 'The connection to the server has been interrupted. Please reload the page.',
errorAccessDeny: 'You are trying to perform an action you do not have rights for.
Please contact your Document Server administrator.',
titleServerVersion: 'Editor updated',
- errorServerVersion: 'The editor version has been updated. The page will be reloaded to apply the changes.'
+ errorServerVersion: 'The editor version has been updated. The page will be reloaded to apply the changes.',
+ textChangesSaved: 'All changes saved'
}
})(), DE.Controllers.Main || {}))
});
\ No newline at end of file
diff --git a/apps/documenteditor/main/app/controller/Statusbar.js b/apps/documenteditor/main/app/controller/Statusbar.js
index 154b953be8..e7ba727693 100644
--- a/apps/documenteditor/main/app/controller/Statusbar.js
+++ b/apps/documenteditor/main/app/controller/Statusbar.js
@@ -216,9 +216,16 @@ define([
this.statusbar.reloadLanguages(langs);
},
- setStatusCaption: function(text) {
- if (text.length)
- this.statusbar.showStatusMessage(text); else
+ setStatusCaption: function(text, force, delay) {
+ if (this.timerCaption && ( ((new Date()) < this.timerCaption) || text.length==0 ) && !force )
+ return;
+
+ this.timerCaption = undefined;
+ if (text.length) {
+ this.statusbar.showStatusMessage(text);
+ if (delay>0)
+ this.timerCaption = (new Date()).getTime() + delay;
+ } else
this.statusbar.clearStatusMessage();
},
diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js
index 90be43926e..ead77a5b94 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -850,13 +850,13 @@ define([
if (this.api) {
var isModified = this.api.asc_isDocumentCanSave();
var isSyncButton = $('.btn-icon', this.toolbar.btnSave.cmpEl).hasClass('btn-synch');
- if (!isModified && !isSyncButton)
+ if (!isModified && !isSyncButton && !this.toolbar.mode.forcesave)
return;
this.api.asc_Save();
}
- this.toolbar.btnSave.setDisabled(true);
+ this.toolbar.btnSave.setDisabled(!this.toolbar.mode.forcesave);
Common.NotificationCenter.trigger('edit:complete', this.toolbar);
diff --git a/apps/documenteditor/main/app/view/FileMenuPanels.js b/apps/documenteditor/main/app/view/FileMenuPanels.js
index 2cfc3d83f5..a71cfe262d 100644
--- a/apps/documenteditor/main/app/view/FileMenuPanels.js
+++ b/apps/documenteditor/main/app/view/FileMenuPanels.js
@@ -132,6 +132,10 @@ define([
'