diff --git a/apps/api/documents/api.js b/apps/api/documents/api.js
index 7853efe00..8408248e3 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 840009f9c..b45770c4e 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -253,12 +253,15 @@ define([
this.appOptions.canBack = this.editorConfig.nativeApp !== true && this.appOptions.canBackToFolder === true;
this.appOptions.canPlugins = false;
this.plugins = this.editorConfig.plugins;
+ this.appOptions.forcesave = (typeof (this.editorConfig.customization) == 'object') && this.editorConfig.customization.forcesave;
this.getApplication()
.getController('Viewport')
.getView('Common.Views.Header')
.setCanBack(this.appOptions.canBackToFolder === true);
+ this.api.asc_setIsForceSaveOnUserSave(this.appOptions.forcesave);
+
if (this.editorConfig.lang)
this.api.asc_setLocale(this.editorConfig.lang);
@@ -542,10 +545,11 @@ define([
application.getController('DocumentHolder').getView('DocumentHolder').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);
}
},
@@ -570,16 +574,19 @@ define([
if (action) {
this.setLongActionView(action)
} else {
- if (this._state.fastCoauth && this._state.usersCount>1 && id==Asc.c_oAscAsyncAction['Save']) {
- var me = this;
- if (me._state.timerSave===undefined)
- me._state.timerSave = setInterval(function(){
- if ((new Date()) - me._state.isSaving>500) {
- clearInterval(me._state.timerSave);
- me.getApplication().getController('Statusbar').setStatusCaption('');
- me._state.timerSave = undefined;
- }
- }, 500);
+ if (id==Asc.c_oAscAsyncAction['Save']) {
+ if (this._state.fastCoauth && this._state.usersCount>1) {
+ var me = this;
+ if (me._state.timerSave===undefined)
+ me._state.timerSave = setInterval(function(){
+ if ((new Date()) - me._state.isSaving>500) {
+ clearInterval(me._state.timerSave);
+ me.getApplication().getController('Statusbar').setStatusCaption(me.textChangesSaved, false, 3000);
+ me._state.timerSave = undefined;
+ }
+ }, 500);
+ } else
+ this.getApplication().getController('Statusbar').setStatusCaption(this.textChangesSaved, false, 3000);
} else
this.getApplication().getController('Statusbar').setStatusCaption('');
}
@@ -599,7 +606,7 @@ define([
},
setLongActionView: function(action) {
- var title = '', text = '';
+ var title = '', text = '', force = false;
switch (action.id) {
case Asc.c_oAscAsyncAction['Open']:
@@ -609,6 +616,7 @@ define([
case Asc.c_oAscAsyncAction['Save']:
this._state.isSaving = new Date();
+ force = true;
title = this.saveTitleText;
text = this.saveTextText;
break;
@@ -694,7 +702,7 @@ define([
this.loadMask.show();
}
else {
- this.getApplication().getController('Statusbar').setStatusCaption(text);
+ this.getApplication().getController('Statusbar').setStatusCaption(text, force);
}
},
@@ -1399,9 +1407,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;
}
@@ -1423,9 +1433,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 **/
@@ -1440,9 +1451,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);
}
},
@@ -1552,7 +1564,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 **/
@@ -2127,7 +2139,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 ac5233d75..9712cf9e0 100644
--- a/apps/documenteditor/main/app/controller/Statusbar.js
+++ b/apps/documenteditor/main/app/controller/Statusbar.js
@@ -149,9 +149,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 f10305bc2..ca0e903d1 100644
--- a/apps/documenteditor/main/app/controller/Toolbar.js
+++ b/apps/documenteditor/main/app/controller/Toolbar.js
@@ -854,13 +854,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/Toolbar.js b/apps/documenteditor/main/app/view/Toolbar.js
index 474884217..dd4325f5b 100644
--- a/apps/documenteditor/main/app/view/Toolbar.js
+++ b/apps/documenteditor/main/app/view/Toolbar.js
@@ -1740,7 +1740,7 @@ define([
if (this.synchTooltip)
this.synchTooltip.hide();
this.btnSave.updateHint(this.btnSaveTip);
- this.btnSave.setDisabled(true);
+ this.btnSave.setDisabled(!this.mode.forcesave);
this._state.hasCollaborativeChanges = false;
}
}
diff --git a/apps/documenteditor/main/locale/en.json b/apps/documenteditor/main/locale/en.json
index 1660ba6ec..b4c98a50e 100644
--- a/apps/documenteditor/main/locale/en.json
+++ b/apps/documenteditor/main/locale/en.json
@@ -300,6 +300,7 @@
"DE.Controllers.Main.warnProcessRightsChange": "You have been denied the right to edit the file.",
"DE.Controllers.Main.titleServerVersion": "Editor updated",
"DE.Controllers.Main.errorServerVersion": "The editor version has been updated. The page will be reloaded to apply the changes.",
+ "DE.Controllers.Main.textChangesSaved": "All changes saved",
"DE.Controllers.Statusbar.textHasChanges": "New changes have been tracked",
"DE.Controllers.Statusbar.textTrackChanges": "The document is opened with the Track Changes mode enabled",
"DE.Controllers.Statusbar.zoomText": "Zoom {0}%",
diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js
index 0d6b83d26..43a61ccc4 100644
--- a/apps/presentationeditor/main/app/controller/Main.js
+++ b/apps/presentationeditor/main/app/controller/Main.js
@@ -384,16 +384,19 @@ define([
if (action) {
this.setLongActionView(action)
} else {
- if (this._state.fastCoauth && this._state.usersCount>1 && id==Asc.c_oAscAsyncAction['Save']) {
- var me = this;
- if (me._state.timerSave===undefined)
- me._state.timerSave = setInterval(function(){
- if ((new Date()) - me._state.isSaving>500) {
- clearInterval(me._state.timerSave);
- me.getApplication().getController('Statusbar').setStatusCaption('');
- me._state.timerSave = undefined;
- }
- }, 500);
+ if (id==Asc.c_oAscAsyncAction['Save']) {
+ if (this._state.fastCoauth && this._state.usersCount>1) {
+ var me = this;
+ if (me._state.timerSave===undefined)
+ me._state.timerSave = setInterval(function(){
+ if ((new Date()) - me._state.isSaving>500) {
+ clearInterval(me._state.timerSave);
+ me.getApplication().getController('Statusbar').setStatusCaption(me.textChangesSaved, false, 3000);
+ me._state.timerSave = undefined;
+ }
+ }, 500);
+ } else
+ this.getApplication().getController('Statusbar').setStatusCaption(this.textChangesSaved, false, 3000);
} else
this.getApplication().getController('Statusbar').setStatusCaption('');
}
@@ -411,7 +414,7 @@ define([
},
setLongActionView: function(action) {
- var title = '', text = '';
+ var title = '', text = '', force = false;
switch (action.id) {
case Asc.c_oAscAsyncAction['Open']:
@@ -421,6 +424,7 @@ define([
case Asc.c_oAscAsyncAction['Save']:
this._state.isSaving = new Date();
+ force = true;
title = this.saveTitleText;
text = this.saveTextText;
break;
@@ -496,7 +500,7 @@ define([
this.loadMask.show();
}
else {
- this.getApplication().getController('Statusbar').setStatusCaption(text);
+ this.getApplication().getController('Statusbar').setStatusCaption(text, force);
}
},
@@ -1157,9 +1161,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;
}
@@ -1302,7 +1308,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 **/
@@ -1917,7 +1923,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'
}
})(), PE.Controllers.Main || {}))
});
diff --git a/apps/presentationeditor/main/app/controller/Statusbar.js b/apps/presentationeditor/main/app/controller/Statusbar.js
index 7f0fc3cb2..ae5e6480a 100644
--- a/apps/presentationeditor/main/app/controller/Statusbar.js
+++ b/apps/presentationeditor/main/app/controller/Statusbar.js
@@ -177,9 +177,16 @@ define([
}
},
- 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/presentationeditor/main/locale/en.json b/apps/presentationeditor/main/locale/en.json
index 8a6464467..4c012d14b 100644
--- a/apps/presentationeditor/main/locale/en.json
+++ b/apps/presentationeditor/main/locale/en.json
@@ -247,6 +247,7 @@
"PE.Controllers.Main.warnProcessRightsChange": "You have been denied the right to edit the file.",
"PE.Controllers.Main.titleServerVersion": "Editor updated",
"PE.Controllers.Main.errorServerVersion": "The editor version has been updated. The page will be reloaded to apply the changes.",
+ "PE.Controllers.Main.textChangesSaved": "All changes saved",
"PE.Controllers.Statusbar.zoomText": "Zoom {0}%",
"PE.Controllers.Toolbar.confirmAddFontName": "The font you are going to save is not available on the current device.
The text style will be displayed using one of the system fonts, the saved font will be used when it is available.
Do you want to continue?",
"PE.Controllers.Toolbar.textAccent": "Accents",