diff --git a/apps/presentationeditor/mobile/locale/en.json b/apps/presentationeditor/mobile/locale/en.json
index bcf17b851..a4aaae940 100644
--- a/apps/presentationeditor/mobile/locale/en.json
+++ b/apps/presentationeditor/mobile/locale/en.json
@@ -21,9 +21,110 @@
"Slide subtitle": "Slide subtitle",
"Table": "Table",
"Slide title": "Slide title"
- }
+ },
+ "closeButtonText": "Close File",
+ "advDRMOptions": "Protected File",
+ "advDRMPassword": "Password",
+
+ "leavePageText": "You have unsaved changes in this document. Click 'Stay on this Page' to await the autosave of the document. Click 'Leave this Page' to discard all the unsaved changes.",
+ "titleLicenseExp": "License expired",
+ "warnLicenseExp": "Your license has expired. Please update your license and refresh the page.",
+ "errorServerVersion": "The editor version has been updated. The page will be reloaded to apply the changes.",
+ "titleServerVersion": "Editor updated",
+ "notcriticalErrorTitle": "Warning",
+ "errorOpensource": "Using the free Community version you can open documents for viewing only. To access mobile web editors, a commercial license is required.",
+ "warnLicenseLimitedNoAccess": "License expired. You have no access to document editing functionality. Please contact your administrator.",
+ "warnLicenseLimitedRenewed": "License needs to be renewed. You have a limited access to document editing functionality.
Please contact your administrator to get full access",
+ "warnLicenseExceeded": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only. Contact your administrator to learn more.",
+ "warnLicenseUsersExceeded": "You've reached the user limit for %1 editors. Contact your administrator to learn more.",
+ "warnNoLicense": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only. Contact %1 sales team for personal upgrade terms.",
+ "warnNoLicenseUsers": "You've reached the user limit for %1 editors. Contact %1 sales team for personal upgrade terms.",
+ "textBuyNow": "Visit website",
+ "textContactUs": "Contact sales",
+ "textNoLicenseTitle": "License limit reached",
+ "textPaidFeature": "Paid feature",
+ "textCustomLoader": "Please note that according to the terms of the license you are not entitled to change the loader. Please contact our Sales Department to get a quote.",
+ "textClose": "Close",
+
+ "errorProcessSaveResult": "Saving is failed.",
+ "criticalErrorTitle": "Error",
+ "warnProcessRightsChange": "You have been denied the right to edit the file.",
+ "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please contact your Document Server administrator.",
+
+ "errorUpdateVersion": "The file version has been changed. The page will be reloaded.",
+ "titleUpdateVersion": "Version changed",
+ "textHasMacros": "The file contains automatic macros.
Do you want to run macros?",
+ "textRemember": "Remember my choice",
+ "textYes": "Yes",
+ "textNo": "No"
}
},
+ "Error": {
+ "criticalErrorTitle": "Error",
+ "unknownErrorText": "Unknown error.",
+ "convertationTimeoutText": "Convertation timeout exceeded.",
+ "openErrorText": "An error has occurred while opening the file",
+ "saveErrorText": "An error has occurred while saving the file",
+ "downloadErrorText": "Download failed.",
+ "uploadImageSizeMessage": "Maximium image size limit exceeded.",
+ "uploadImageExtMessage": "Unknown image format.",
+ "uploadImageFileCountMessage": "No images uploaded.",
+ "splitMaxRowsErrorText": "The number of rows must be less than %1",
+ "splitMaxColsErrorText": "The number of columns must be less than %1",
+ "splitDividerErrorText": "The number of rows must be a divisor of %1",
+ "errorKeyEncrypt": "Unknown key descriptor",
+ "errorKeyExpire": "Key descriptor expired",
+ "errorUsersExceed": "Count of users was exceed",
+ "errorViewerDisconnect": "Connection is lost. You can still view the document,
but will not be able to download until the connection is restored and page is reloaded.",
+ "errorFilePassProtect": "The file is password protected and could not be opened.",
+ "errorStockChart": "Incorrect row order. To build a stock chart place the data on the sheet in the following order:
opening price, max price, min price, closing price.",
+ "errorDataRange": "Incorrect data range.",
+ "errorDatabaseConnection": "External error.
Database connection error. Please, contact support.",
+ "errorUserDrop": "The file cannot be accessed right now.",
+ "errorConnectToServer": " The document could not be saved. Please check connection settings or contact your administrator.
When you click the 'OK' button, you will be prompted to download the document.",
+ "errorBadImageUrl": "Image url is incorrect",
+ "errorSessionAbsolute": "The document editing session has expired. Please reload the page.",
+ "errorSessionIdle": "The document has not been edited for quite a long time. Please reload the page.",
+ "errorSessionToken": "The connection to the server has been interrupted. Please reload the page.",
+ "errorDataEncrypted": "Encrypted changes have been received, they cannot be deciphered.",
+ "errorAccessDeny": "You are trying to perform an action you do not have rights for.
Please contact your Document Server administrator.",
+ "errorEditingDownloadas": "An error occurred during the work with the document.
Use the 'Download' option to save the file backup copy to your computer hard drive.",
+ "errorFileSizeExceed": "The file size exceeds the limitation set for your server.
Please contact your Document Server administrator for details.",
+ "errorUpdateVersionOnDisconnect": "Internet connection has been restored, and the file version has been changed.
Before you can continue working, you need to download the file or copy its content to make sure nothing is lost, and then reload this page.",
+ "errorDefaultMessage": "Error code: %1",
+ "criticalErrorExtText": "Press 'OK' to back to document list.",
+ "notcriticalErrorTitle": "Warning",
+ "scriptLoadError": "The connection is too slow, some of the components could not be loaded. Please reload the page."
+ },
+ "LongActions": {
+ "openTitleText": "Opening Document",
+ "openTextText": "Opening document...",
+ "saveTitleText": "Saving Document",
+ "saveTextText": "Saving document...",
+ "loadFontsTitleText": "Loading Data",
+ "loadFontsTextText": "Loading data...",
+ "loadImagesTitleText": "Loading Images",
+ "loadImagesTextText": "Loading images...",
+ "loadFontTitleText": "Loading Data",
+ "loadFontTextText": "Loading data...",
+ "loadImageTitleText": "Loading Image",
+ "loadImageTextText": "Loading image...",
+ "downloadTitleText": "Downloading Document",
+ "downloadTextText": "Downloading document...",
+ "printTitleText": "Printing Document",
+ "printTextText": "Printing document...",
+ "uploadImageTitleText": "Uploading Image",
+ "uploadImageTextText": "Uploading image...",
+ "applyChangesTitleText": "Loading Data",
+ "applyChangesTextText": "Loading data...",
+ "savePreparingText": "Preparing to save",
+ "savePreparingTitle": "Preparing to save. Please wait...",
+ "waitText": "Please, wait...",
+ "txtEditingMode": "Set editing mode...",
+ "loadingDocumentTitleText": "Loading document",
+ "loadingDocumentTextText": "Loading document...",
+ "textLoadingDocument": "Loading document"
+ },
"ContextMenu": {
"menuViewComment": "View Comment",
"menuAddComment": "Add Comment",
diff --git a/apps/presentationeditor/mobile/src/controller/Error.jsx b/apps/presentationeditor/mobile/src/controller/Error.jsx
new file mode 100644
index 000000000..a8cd9213e
--- /dev/null
+++ b/apps/presentationeditor/mobile/src/controller/Error.jsx
@@ -0,0 +1,222 @@
+import React, { useEffect } from 'react';
+import { inject } from 'mobx-react';
+import { f7 } from 'framework7-react';
+import { useTranslation } from 'react-i18next';
+
+const ErrorController = inject('storeAppOptions')(({storeAppOptions, LoadingDocument}) => {
+ const {t} = useTranslation();
+ const _t = t("Error", { returnObjects: true });
+
+ useEffect(() => {
+ Common.Notifications.on('engineCreated', (api) => {
+ api.asc_registerCallback('asc_onError', onError);
+ });
+ return () => {
+ const api = Common.EditorApi.get();
+ api.asc_unregisterCallback('asc_onError', onError);
+ }
+ });
+
+ const onError = (id, level, errData) => {
+ if (id === -82) return; // format error
+
+ if (id === Asc.c_oAscError.ID.LoadingScriptError) {
+ f7.notification.create({
+ title: _t.criticalErrorTitle,
+ text: _t.scriptLoadError,
+ closeButton: true
+ }).open();
+ return;
+ }
+
+ Common.Notifications.trigger('preloader:close');
+ Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument);
+
+ const api = Common.EditorApi.get();
+
+ const config = {
+ closable: false
+ };
+
+ switch (id)
+ {
+ case Asc.c_oAscError.ID.Unknown:
+ config.msg = _t.unknownErrorText;
+ break;
+
+ case Asc.c_oAscError.ID.ConvertationTimeout:
+ config.msg = _t.convertationTimeoutText;
+ break;
+
+ case Asc.c_oAscError.ID.ConvertationOpenError:
+ config.msg = _t.openErrorText;
+ break;
+
+ case Asc.c_oAscError.ID.ConvertationSaveError:
+ config.msg = _t.saveErrorText;
+ break;
+
+ case Asc.c_oAscError.ID.DownloadError:
+ config.msg = _t.downloadErrorText;
+ break;
+
+ case Asc.c_oAscError.ID.UplImageSize:
+ config.msg = _t.uploadImageSizeMessage;
+ break;
+
+ case Asc.c_oAscError.ID.UplImageExt:
+ config.msg = _t.uploadImageExtMessage;
+ break;
+
+ case Asc.c_oAscError.ID.UplImageFileCount:
+ config.msg = _t.uploadImageFileCountMessage;
+ break;
+
+ case Asc.c_oAscError.ID.SplitCellMaxRows:
+ config.msg = _t.splitMaxRowsErrorText.replace('%1', errData.get_Value());
+ break;
+
+ case Asc.c_oAscError.ID.SplitCellMaxCols:
+ config.msg = _t.splitMaxColsErrorText.replace('%1', errData.get_Value());
+ break;
+
+ case Asc.c_oAscError.ID.SplitCellRowsDivider:
+ config.msg = _t.splitDividerErrorText.replace('%1', errData.get_Value());
+ break;
+
+ case Asc.c_oAscError.ID.VKeyEncrypt:
+ config.msg = _t.errorKeyEncrypt;
+ break;
+
+ case Asc.c_oAscError.ID.KeyExpire:
+ config.msg = _t.errorKeyExpire;
+ break;
+
+ case Asc.c_oAscError.ID.UserCountExceed:
+ config.msg = _t.errorUsersExceed;
+ break;
+
+ case Asc.c_oAscError.ID.CoAuthoringDisconnect:
+ config.msg = _t.errorViewerDisconnect;
+ break;
+
+ case Asc.c_oAscError.ID.ConvertationPassword:
+ config.msg = _t.errorFilePassProtect;
+ break;
+
+ case Asc.c_oAscError.ID.StockChartError:
+ config.msg = _t.errorStockChart;
+ break;
+
+ case Asc.c_oAscError.ID.DataRangeError:
+ config.msg = _t.errorDataRange;
+ break;
+
+ case Asc.c_oAscError.ID.Database:
+ config.msg = _t.errorDatabaseConnection;
+ break;
+
+ case Asc.c_oAscError.ID.UserDrop:
+ const lostEditingRights = storeAppOptions.lostEditingRights;
+ if (lostEditingRights) {
+ storeAppOptions.changeEditingRights(false);
+ return;
+ }
+ storeAppOptions.changeEditingRights(true);
+ config.msg = _t.errorUserDrop;
+ break;
+
+ case Asc.c_oAscError.ID.Warning:
+ config.msg = _t.errorConnectToServer;
+ break;
+
+ case Asc.c_oAscError.ID.UplImageUrl:
+ config.msg = _t.errorBadImageUrl;
+ break;
+
+ case Asc.c_oAscError.ID.SessionAbsolute:
+ config.msg = _t.errorSessionAbsolute;
+ break;
+
+ case Asc.c_oAscError.ID.SessionIdle:
+ config.msg = _t.errorSessionIdle;
+ break;
+
+ case Asc.c_oAscError.ID.SessionToken:
+ config.msg = _t.errorSessionToken;
+ break;
+
+ case Asc.c_oAscError.ID.DataEncrypted:
+ config.msg = _t.errorDataEncrypted;
+ break;
+
+ case Asc.c_oAscError.ID.AccessDeny:
+ config.msg = _t.errorAccessDeny;
+ break;
+
+ case Asc.c_oAscError.ID.EditingError:
+ config.msg = _t.errorEditingDownloadas;
+ break;
+
+ case Asc.c_oAscError.ID.ConvertationOpenLimitError:
+ config.msg = _t.errorFileSizeExceed;
+ break;
+
+ case Asc.c_oAscError.ID.UpdateVersion:
+ config.msg = _t.errorUpdateVersionOnDisconnect;
+ break;
+
+ default:
+ config.msg = _t.errorDefaultMessage.replace('%1', id);
+ break;
+ }
+
+ if (level === Asc.c_oAscError.Level.Critical) {
+
+ // report only critical errors
+ Common.Gateway.reportError(id, config.msg);
+
+ config.title = _t.criticalErrorTitle;
+
+ if (storeAppOptions.canBackToFolder && !storeAppOptions.isDesktopApp) {
+ config.msg += '' + _t.criticalErrorExtText;
+ config.callback = function() {
+ Common.Notifications.trigger('goback', true);
+ }
+ }
+ if (id === Asc.c_oAscError.ID.DataEncrypted) {
+ api.asc_coAuthoringDisconnect();
+ Common.Notifications.trigger('api:disconnect');
+ }
+ }
+ else {
+ Common.Gateway.reportWarning(id, config.msg);
+
+ config.title = _t.notcriticalErrorTitle;
+ config.callback = (btn) => {
+ if (id === Asc.c_oAscError.ID.Warning && btn === 'ok' && (storeAppOptions.canDownload || storeAppOptions.canDownloadOrigin)) {
+ api.asc_DownloadOrigin();
+ }
+ storeAppOptions.changeEditingRights(false);
+ };
+ }
+
+ f7.dialog.create({
+ cssClass: 'error-dialog',
+ title : config.title,
+ text : config.msg,
+ buttons: [
+ {
+ text: 'OK',
+ onClick: config.callback
+ }
+ ]
+ }).open();
+
+ Common.component.Analytics.trackEvent('Internal Error', id.toString());
+ };
+
+ return null
+});
+
+export default ErrorController;
\ No newline at end of file
diff --git a/apps/presentationeditor/mobile/src/controller/LongActions.jsx b/apps/presentationeditor/mobile/src/controller/LongActions.jsx
new file mode 100644
index 000000000..0828925ab
--- /dev/null
+++ b/apps/presentationeditor/mobile/src/controller/LongActions.jsx
@@ -0,0 +1,192 @@
+import React, { Component } from 'react';
+import { inject } from 'mobx-react';
+import { f7 } from 'framework7-react';
+import { withTranslation } from 'react-i18next';
+import IrregularStack from "../../../../common/mobile/utils/IrregularStack";
+
+class LongActions extends Component {
+ constructor(props) {
+ super(props);
+
+ this.stackLongActions = new IrregularStack({
+ strongCompare : function(obj1, obj2){return obj1.id === obj2.id && obj1.type === obj2.type;},
+ weakCompare : function(obj1, obj2){return obj1.type === obj2.type;}
+ });
+
+ this.onLongActionBegin = this.onLongActionBegin.bind(this);
+ this.onLongActionEnd = this.onLongActionEnd.bind(this);
+ this.onOpenDocument = this.onOpenDocument.bind(this);
+ this.closePreloader = this.closePreloader.bind(this);
+ }
+
+ closePreloader() {
+ if (this.loadMask && this.loadMask.el) {
+ f7.dialog.close(this.loadMask.el);
+ }
+ }
+
+ componentDidMount() {
+ Common.Notifications.on('engineCreated', (api) => {
+ api.asc_registerCallback('asc_onStartAction', this.onLongActionBegin);
+ api.asc_registerCallback('asc_onEndAction', this.onLongActionEnd);
+ api.asc_registerCallback('asc_onOpenDocumentProgress', this.onOpenDocument);
+ });
+ Common.Notifications.on('preloader:endAction', this.onLongActionEnd);
+ Common.Notifications.on('preloader:beginAction', this.onLongActionBegin);
+ Common.Notifications.on('preloader:close', this.closePreloader);
+ }
+
+ componentWillUnmount() {
+ const api = Common.EditorApi.get();
+ api.asc_unregisterCallback('asc_onStartAction', this.onLongActionBegin);
+ api.asc_unregisterCallback('asc_onEndAction', this.onLongActionEnd);
+ api.asc_unregisterCallback('asc_onOpenDocumentProgress', this.onOpenDocument);
+
+ Common.Notifications.off('preloader:endAction', this.onLongActionEnd);
+ Common.Notifications.off('preloader:beginAction', this.onLongActionBegin);
+ Common.Notifications.off('preloader:close', this.closePreloader);
+ }
+
+ onLongActionBegin (type, id) {
+ const action = {id: id, type: type};
+ this.stackLongActions.push(action);
+ this.setLongActionView(action);
+ }
+
+ onLongActionEnd (type, id) {
+ let action = {id: id, type: type};
+ this.stackLongActions.pop(action);
+
+ //this.updateWindowTitle(true);
+
+ action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.Information});
+
+ if (action) {
+ this.setLongActionView(action)
+ }
+
+ action = this.stackLongActions.get({type: Asc.c_oAscAsyncActionType.BlockInteraction});
+
+ if (action) {
+ this.setLongActionView(action)
+ } else {
+ this.loadMask && this.loadMask.el && this.loadMask.el.classList.contains('modal-in') && f7.dialog.close(this.loadMask.el);
+ }
+ }
+
+ setLongActionView (action) {
+ const { t } = this.props;
+ const _t = t("LongActions", { returnObjects: true });
+ let title = '';
+ let text = '';
+ switch (action.id) {
+ case Asc.c_oAscAsyncAction['Open']:
+ title = _t.openTitleText;
+ text = _t.openTextText;
+ break;
+
+ case Asc.c_oAscAsyncAction['Save']:
+ title = _t.saveTitleText;
+ text = _t.saveTextText;
+ break;
+
+ case Asc.c_oAscAsyncAction['LoadDocumentFonts']:
+ title = _t.loadFontsTitleText;
+ text = _t.loadFontsTextText;
+ break;
+
+ case Asc.c_oAscAsyncAction['LoadDocumentImages']:
+ title = _t.loadImagesTitleText;
+ text = _t.loadImagesTextText;
+ break;
+
+ case Asc.c_oAscAsyncAction['LoadFont']:
+ title = _t.loadFontTitleText;
+ text = _t.loadFontTextText;
+ break;
+
+ case Asc.c_oAscAsyncAction['LoadImage']:
+ title = _t.loadImageTitleText;
+ text = _t.loadImageTextText;
+ break;
+
+ case Asc.c_oAscAsyncAction['DownloadAs']:
+ title = _t.downloadTitleText;
+ text = _t.downloadTextText;
+ break;
+
+ case Asc.c_oAscAsyncAction['Print']:
+ title = _t.printTitleText;
+ text = _t.printTextText;
+ break;
+
+ case Asc.c_oAscAsyncAction['UploadImage']:
+ title = _t.uploadImageTitleText;
+ text = _t.uploadImageTextText;
+ break;
+
+ case Asc.c_oAscAsyncAction['ApplyChanges']:
+ title = _t.applyChangesTitleText;
+ text = _t.applyChangesTextText;
+ break;
+
+ case Asc.c_oAscAsyncAction['PrepareToSave']:
+ title = _t.savePreparingText;
+ text = _t.savePreparingTitle;
+ break;
+
+ case Asc.c_oAscAsyncAction['Waiting']:
+ title = _t.waitText;
+ text = _t.waitText;
+ break;
+
+ case ApplyEditRights:
+ title = _t.txtEditingMode;
+ text = _t.txtEditingMode;
+ break;
+
+ case LoadingDocument:
+ title = _t.loadingDocumentTitleText;
+ text = _t.loadingDocumentTextText;
+ break;
+ default:
+ if (typeof action.id == 'string'){
+ title = action.id;
+ text = action.id;
+ }
+ break;
+ }
+
+ if (action.type === Asc.c_oAscAsyncActionType['BlockInteraction']) {
+ if (action.id === Asc.c_oAscAsyncAction['ApplyChanges']) {
+ return;
+ }
+
+ if (this.loadMask && this.loadMask.el && this.loadMask.el.classList.contains('modal-in')) {
+ this.loadMask.el.getElementsByClassName('dialog-title')[0].innerHTML = title;
+ } else {
+ this.loadMask = f7.dialog.preloader(title);
+ }
+ }
+
+ }
+
+ onOpenDocument (progress) {
+ if (this.loadMask && this.loadMask.el) {
+ const $title = this.loadMask.el.getElementsByClassName('dialog-title')[0];
+ const proc = (progress.asc_getCurrentFont() + progress.asc_getCurrentImage())/(progress.asc_getFontsCount() + progress.asc_getImagesCount());
+
+ const { t } = this.props;
+ const _t = t("LongActions", { returnObjects: true });
+ $title.innerHTML = `${_t.textLoadingDocument}: ${Math.min(Math.round(proc * 100), 100)}%`;
+ }
+ }
+
+ render() {
+ return null;
+ }
+}
+
+const LongActionsController = withTranslation()(LongActions);
+
+export default LongActionsController;
\ No newline at end of file
diff --git a/apps/presentationeditor/mobile/src/controller/Main.jsx b/apps/presentationeditor/mobile/src/controller/Main.jsx
index 8c5e89e0b..aa626e48e 100644
--- a/apps/presentationeditor/mobile/src/controller/Main.jsx
+++ b/apps/presentationeditor/mobile/src/controller/Main.jsx
@@ -7,19 +7,44 @@ import CollaborationController from '../../../../common/mobile/lib/controller/co
import EditorUIController from '../lib/patch';
import {
CommentsController,
- AddCommentController,
- EditCommentController,
ViewCommentsController
} from "../../../../common/mobile/lib/controller/collaboration/Comments";
+import ErrorController from "./Error";
+import LongActionsController from "./LongActions";
+import {LocalStorage} from "../../../../common/mobile/utils/LocalStorage";
+import About from '../../../../common/mobile/lib/view/About';
-@inject("storeFocusObjects", "storeAppOptions", "storePresentationInfo", "storePresentationSettings", "storeSlideSettings", "storeTextSettings", "storeTableSettings", "storeChartSettings", "storeLinkSettings")
+@inject(
+ "storeFocusObjects",
+ "storeAppOptions",
+ "storePresentationInfo",
+ "storePresentationSettings",
+ "storeSlideSettings",
+ "storeTextSettings",
+ "storeTableSettings",
+ "storeChartSettings",
+ "storeLinkSettings",
+ "storeApplicationSettings"
+ )
class MainController extends Component {
- constructor(props) {
+ constructor (props) {
super(props)
window.editorType = 'pe';
+
+ this.LoadingDocument = -256;
+
+ this._state = {
+ licenseType: false,
+ isDocModified: false
+ };
+
+ this.defaultTitleText = __APP_TITLE_TEXT__;
+
+ const { t } = this.props;
+ this._t = t('Controller.Main', {returnObjects:true});
}
- initSdk() {
+ initSdk () {
const script = document.createElement("script");
script.src = "../../../../sdkjs/develop/sdkjs/slide/scripts.js";
script.async = true;
@@ -54,7 +79,15 @@ class MainController extends Component {
this.props.storeAppOptions.setConfigOptions(this.editorConfig);
this.editorConfig.lang && this.api.asc_setLocale(this.editorConfig.lang);
- // console.log(this.editorConfig);
+
+ let value = LocalStorage.getItem("pe-mobile-macros-mode");
+ if (value === null) {
+ value = this.editorConfig.customization ? this.editorConfig.customization.macrosMode : 'warn';
+ value = (value === 'enable') ? 1 : (value === 'disable' ? 2 : 0);
+ } else {
+ value = parseInt(value);
+ }
+ this.props.storeApplicationSettings.changeMacrosSettings(value);
};
const loadDocument = data => {
@@ -85,15 +118,15 @@ class MainController extends Component {
docInfo.put_Permissions(_permissions);
docInfo.put_EncryptedInfo(this.editorConfig.encryptionKeys);
- // var enable = !this.editorConfig.customization || (this.editorConfig.customization.macros!==false);
- // docInfo.asc_putIsEnabledMacroses(!!enable);
- // enable = !this.editorConfig.customization || (this.editorConfig.customization.plugins!==false);
- // docInfo.asc_putIsEnabledPlugins(!!enable);
+ let enable = !this.editorConfig.customization || (this.editorConfig.customization.macros !== false);
+ docInfo.asc_putIsEnabledMacroses(!!enable);
+ enable = !this.editorConfig.customization || (this.editorConfig.customization.plugins !== false);
+ docInfo.asc_putIsEnabledPlugins(!!enable);
}
this.api.asc_registerCallback('asc_onGetEditorPermissions', onEditorPermissions);
- // this.api.asc_registerCallback('asc_onLicenseChanged', _.bind(this.onLicenseChanged, this));
- // this.api.asc_registerCallback('asc_onRunAutostartMacroses', _.bind(this.onRunAutostartMacroses, this));
+ this.api.asc_registerCallback('asc_onLicenseChanged', this.onLicenseChanged.bind(this));
+ this.api.asc_registerCallback('asc_onRunAutostartMacroses', this.onRunAutostartMacroses.bind(this));
this.api.asc_setDocInfo(docInfo);
this.api.asc_getEditorPermissions(this.editorConfig.licenseUrl, this.editorConfig.customerId);
@@ -111,16 +144,16 @@ class MainController extends Component {
};
const onEditorPermissions = params => {
- let me = this;
const licType = params.asc_getLicenseType();
- me.appOptions.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit);
+ this.appOptions.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit);
- this.props.storeAppOptions.setPermissionOptions(this.document, licType, params, this.permissions);
+ const storeAppOptions = this.props.storeAppOptions;
+ storeAppOptions.setPermissionOptions(this.document, licType, params, this.permissions);
+ this.applyMode(storeAppOptions);
- // me.api.asc_setViewMode(!me.appOptions.isEdit);
- me.api.asc_setViewMode(false);
- me.api.asc_LoadDocument();
+ this.api.asc_LoadDocument();
+ this.api.Resize();
};
const _process_array = (array, fn) => {
@@ -144,24 +177,36 @@ class MainController extends Component {
'translate': t('Controller.Main.SDK', {returnObjects:true})
});
+ Common.Notifications.trigger('engineCreated', this.api);
Common.EditorApi = {get: () => this.api};
this.appOptions = {};
this.bindEvents();
- let value = null /*Common.localStorage.getItem("pe-settings-fontrender")*/;
+ let value = LocalStorage.getItem("pe-settings-fontrender");
if (value===null) value = window.devicePixelRatio > 1 ? '1' : '3';
this.api.SetFontRenderingMode(parseInt(value));
this.api.SetDrawingFreeze(true);
this.api.SetThemesPath("../../../../sdkjs/slide/themes/");
- // Common.Utils.Metric.setCurrentMetric(1); //pt
+ Common.Utils.Metric.setCurrentMetric(1); //pt
Common.Gateway.on('init', loadConfig);
- // Common.Gateway.on('showmessage', _.bind(me.onExternalMessage, me));
+ Common.Gateway.on('showmessage', this.onExternalMessage.bind(this));
Common.Gateway.on('opendocument', loadDocument);
Common.Gateway.appReady();
- Common.Notifications.trigger('engineCreated', this.api);
+ Common.Gateway.on('internalcommand', function(data) {
+ if (data.command === 'hardBack') {
+ if ($$('.modal-in').length > 0) {
+ if ( !($$('.error-dialog.modal-in').length > 0) ) {
+ f7.dialog.close();
+ }
+ Common.Gateway.internalMessage('hardBack', false);
+ } else
+ Common.Gateway.internalMessage('hardBack', true);
+ }
+ });
+ Common.Gateway.internalMessage('listenHardBack');
}, error => {
console.log('promise failed ' + error);
});
@@ -174,11 +219,76 @@ class MainController extends Component {
document.body.appendChild(script);
}
- bindEvents() {
-
- // me.api.asc_registerCallback('asc_onError', _.bind(me.onError, me));
- this.api.asc_registerCallback('asc_onDocumentContentReady', this._onDocumentContentReady.bind(this));
- this.api.asc_registerCallback('asc_onOpenDocumentProgress', this._onOpenDocumentProgress.bind(this));
+ applyMode(appOptions) {
+ this.api.asc_enableKeyEvents(appOptions.isEdit);
+ this.api.asc_setViewMode(!appOptions.isEdit && !appOptions.isRestrictedEdit);
+ (appOptions.isRestrictedEdit && appOptions.canComments) && this.api.asc_setRestriction(Asc.c_oAscRestrictionType.OnlyComments);
+
+ let value = LocalStorage.getItem('pe-mobile-settings-unit');
+ value = (value !== null) ?
+ parseInt(value) :
+ (appOptions.customization && appOptions.customization.unit ? Common.Utils.Metric.c_MetricUnits[appOptions.customization.unit.toLocaleLowerCase()] : Common.Utils.Metric.getDefaultMetric());
+ (value === undefined) && (value = Common.Utils.Metric.getDefaultMetric());
+ Common.Utils.Metric.setCurrentMetric(value);
+ this.api.asc_SetDocumentUnits((value === Common.Utils.Metric.c_MetricUnits.inch) ?
+ Asc.c_oAscDocumentUnits.Inch :
+ ((value === Common.Utils.Metric.c_MetricUnits.pt) ? Asc.c_oAscDocumentUnits.Point : Asc.c_oAscDocumentUnits.Millimeter));
+
+ this.api.asc_registerCallback('asc_onDocumentModifiedChanged', this.onDocumentModifiedChanged.bind(this));
+ this.api.asc_registerCallback('asc_onDocumentCanSaveChanged', this.onDocumentCanSaveChanged.bind(this));
+
+ //if (me.stackLongActions.exist({id: ApplyEditRights, type: Asc.c_oAscAsyncActionType['BlockInteraction']})) {
+ // me.onLongActionEnd(Asc.c_oAscAsyncActionType['BlockInteraction'], ApplyEditRights);
+ //} else if (!this._isDocReady) {
+ // me.hidePreloader();
+ // me.onLongActionBegin(Asc.c_oAscAsyncActionType['BlockInteraction'], LoadingDocument);
+ //}
+
+ // Message on window close
+ window.onbeforeunload = this.onBeforeUnload.bind(this);
+ window.onunload = this.onUnload.bind(this);
+ }
+
+ onDocumentModifiedChanged () {
+ const isModified = this.api.asc_isDocumentCanSave();
+ if (this._state.isDocModified !== isModified) {
+ this._isDocReady && Common.Gateway.setDocumentModified(this.api.isDocumentModified());
+ }
+
+ this.updateWindowTitle();
+ }
+
+ onDocumentCanSaveChanged (isCanSave) {
+ //
+ }
+
+ onBeforeUnload () {
+ LocalStorage.save();
+
+ if (this.api.isDocumentModified()) {
+ this.api.asc_stopSaving();
+ this.continueSavingTimer = window.setTimeout(() => {
+ this.api.asc_continueSaving();
+ }, 500);
+
+ return this._t.leavePageText;
+ }
+ }
+
+ onUnload () {
+ if (this.continueSavingTimer)
+ clearTimeout(this.continueSavingTimer);
+ }
+
+ bindEvents () {
+ this.api.asc_registerCallback('asc_onDocumentContentReady', this.onDocumentContentReady.bind(this));
+ this.api.asc_registerCallback('asc_onDocumentUpdateVersion', this.onUpdateVersion.bind(this));
+ this.api.asc_registerCallback('asc_onServerVersion', this.onServerVersion.bind(this));
+ this.api.asc_registerCallback('asc_onAdvancedOptions', this.onAdvancedOptions.bind(this));
+ this.api.asc_registerCallback('asc_onDocumentName', this.onDocumentName.bind(this));
+ this.api.asc_registerCallback('asc_onPrintUrl', this.onPrintUrl.bind(this));
+ this.api.asc_registerCallback('asc_onPrint', this.onPrint.bind(this));
+ this.api.asc_registerCallback('asc_onMeta', this.onMeta.bind(this));
EditorUIController.initThemeColors && EditorUIController.initThemeColors();
@@ -266,12 +376,48 @@ class MainController extends Component {
EditorUIController.updateChartStyles && EditorUIController.updateChartStyles(this.props.storeChartSettings, this.props.storeFocusObjects);
}
- _onDocumentContentReady() {
+ onDocumentContentReady () {
+ if (this._isDocReady)
+ return;
+
+ this._isDocReady = true;
+
+ const appOptions = this.props.storeAppOptions;
+ const appSettings = this.props.storeApplicationSettings;
+
this.api.SetDrawingFreeze(false);
+ Common.Notifications.trigger('preloader:close');
+ Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument);
+
+ let value = LocalStorage.getItem("pe-settings-zoom");
+ const zf = (value!==null) ? parseInt(value) : (appOptions.customization && appOptions.customization.zoom ? parseInt(appOptions.customization.zoom) : -1);
+ (zf === -1) ? this.api.zoomFitToPage() : ((zf === -2) ? this.api.zoomFitToWidth() : this.api.zoom(zf>0 ? zf : 100));
+
+ value = LocalStorage.getBool("pe-mobile-spellcheck", !(appOptions.customization && appOptions.customization.spellcheck===false));
+ appSettings.changeSpellCheck(value);
+ this.api.asc_setSpellCheck(value);
+
+ this.updateWindowTitle(true);
+
+ this.api.SetTextBoxInputMode(LocalStorage.getBool("pe-settings-inputmode"));
+
+ if (appOptions.isEdit && this.needToUpdateVersion) {
+ Common.Notifications.trigger('api:disconnect');
+ }
+
+ Common.Gateway.on('processsaveresult', this.onProcessSaveResult.bind(this));
+ Common.Gateway.on('processrightschange', this.onProcessRightsChange.bind(this));
+ Common.Gateway.on('downloadas', this.onDownloadAs.bind(this));
+ Common.Gateway.on('requestclose', this.onRequestClose.bind(this));
+
+ Common.Gateway.sendInfo({
+ mode: appOptions.isEdit ? 'edit' : 'view'
+ });
+
this.api.Resize();
this.api.zoomFitToPage();
- // me.api.asc_GetDefaultTableStyles && _.defer(function () {me.api.asc_GetDefaultTableStyles()});
+ this.api.asc_GetDefaultTableStyles && setTimeout(() => {this.api.asc_GetDefaultTableStyles()}, 1);
this.applyLicense();
@@ -281,23 +427,354 @@ class MainController extends Component {
Common.Notifications.trigger('document:ready');
}
- _onOpenDocumentProgress(progress) {
- // if (this.loadMask) {
- // var $title = $$(this.loadMask).find('.modal-title'),
- // const proc = (progress.asc_getCurrentFont() + progress.asc_getCurrentImage())/(progress.asc_getFontsCount() + progress.asc_getImagesCount());
-
- // $title.text(this.textLoadingDocument + ': ' + Math.min(Math.round(proc * 100), 100) + '%');
- // }
+ onLicenseChanged (params) {
+ const appOptions = this.props.storeAppOptions;
+ const licType = params.asc_getLicenseType();
+ if (licType !== undefined && appOptions.canEdit && appOptions.config.mode !== 'view' &&
+ (licType === Asc.c_oLicenseResult.Connections || licType === Asc.c_oLicenseResult.UsersCount || licType === Asc.c_oLicenseResult.ConnectionsOS || licType === Asc.c_oLicenseResult.UsersCountOS
+ || licType === Asc.c_oLicenseResult.SuccessLimit && (appOptions.trialMode & Asc.c_oLicenseMode.Limited) !== 0))
+ this._state.licenseType = licType;
+ if (this._isDocReady && this._state.licenseType)
+ this.applyLicense();
}
- applyLicense() {
- /* TO DO */
- Common.Notifications.trigger('toolbar:activatecontrols');
+ applyLicense () {
+ const _t = this._t;
+ const warnNoLicense = _t.warnNoLicense.replace(/%1/g, __COMPANY_NAME__);
+ const warnNoLicenseUsers = _t.warnNoLicenseUsers.replace(/%1/g, __COMPANY_NAME__);
+ const textNoLicenseTitle = _t.textNoLicenseTitle.replace(/%1/g, __COMPANY_NAME__);
+ const warnLicenseExceeded = _t.warnLicenseExceeded.replace(/%1/g, __COMPANY_NAME__);
+ const warnLicenseUsersExceeded = _t.warnLicenseUsersExceeded.replace(/%1/g, __COMPANY_NAME__);
+
+ const appOptions = this.props.storeAppOptions;
+ if (appOptions.config.mode !== 'view' && !EditorUIController.isSupportEditFeature()) {
+ let value = LocalStorage.getItem("pe-opensource-warning");
+ value = (value !== null) ? parseInt(value) : 0;
+ const now = (new Date).getTime();
+ if (now - value > 86400000) {
+ LocalStorage.setItem("pe-opensource-warning", now);
+ f7.dialog.create({
+ title: _t.notcriticalErrorTitle,
+ text : _t.errorOpensource,
+ buttons: [{text: 'OK'}]
+ }).open();
+ }
+ Common.Notifications.trigger('toolbar:activatecontrols');
+ return;
+ }
+
+ if (this._state.licenseType) {
+ let license = this._state.licenseType;
+ let buttons = [{text: 'OK'}];
+ if ((appOptions.trialMode & Asc.c_oLicenseMode.Limited) !== 0 &&
+ (license === Asc.c_oLicenseResult.SuccessLimit ||
+ license === Asc.c_oLicenseResult.ExpiredLimited ||
+ appOptions.permissionsLicense === Asc.c_oLicenseResult.SuccessLimit)
+ ) {
+ license = (license === Asc.c_oLicenseResult.ExpiredLimited) ? _t.warnLicenseLimitedNoAccess : _t.warnLicenseLimitedRenewed;
+ } else if (license === Asc.c_oLicenseResult.Connections || license === Asc.c_oLicenseResult.UsersCount) {
+ license = (license===Asc.c_oLicenseResult.Connections) ? warnLicenseExceeded : warnLicenseUsersExceeded;
+ } else {
+ license = (license === Asc.c_oLicenseResult.ConnectionsOS) ? warnNoLicense : warnNoLicenseUsers;
+ buttons = [{
+ text: _t.textBuyNow,
+ bold: true,
+ onClick: function() {
+ window.open(`${__PUBLISHER_URL__}`, "_blank");
+ }
+ },
+ {
+ text: _t.textContactUs,
+ onClick: function() {
+ window.open(`mailto:${__SALES_EMAIL__}`, "_blank");
+ }
+ }];
+ }
+ if (this._state.licenseType === Asc.c_oLicenseResult.SuccessLimit) {
+ Common.Notifications.trigger('toolbar:activatecontrols');
+ } else {
+ Common.Notifications.trigger('toolbar:activatecontrols');
+ Common.Notifications.trigger('toolbar:deactivateeditcontrols');
+ Common.Notifications.trigger('api:disconnect');
+ }
+
+ let value = LocalStorage.getItem("pe-license-warning");
+ value = (value !== null) ? parseInt(value) : 0;
+ const now = (new Date).getTime();
+
+ if (now - value > 86400000) {
+ LocalStorage.setItem("pe-license-warning", now);
+ f7.dialog.create({
+ title: textNoLicenseTitle,
+ text : license,
+ buttons: buttons
+ }).open();
+ }
+ } else {
+ if (!appOptions.isDesktopApp && !appOptions.canBrandingExt &&
+ appOptions.config && appOptions.config.customization && (appOptions.config.customization.loaderName || appOptions.config.customization.loaderLogo)) {
+ f7.dialog.create({
+ title: _t.textPaidFeature,
+ text : _t.textCustomLoader,
+ buttons: [{
+ text: _t.textContactUs,
+ bold: true,
+ onClick: () => {
+ window.open(`mailto:${__SALES_EMAIL__}`, "_blank");
+ }
+ },
+ { text: _t.textClose }]
+ }).open();
+ }
+ Common.Notifications.trigger('toolbar:activatecontrols');
+ }
}
- render() {
+ onUpdateVersion (callback) {
+ const _t = this._t;
+
+ this.needToUpdateVersion = true;
+ Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument);
+
+ f7.dialog.alert(
+ _t.errorUpdateVersion,
+ _t.titleUpdateVersion,
+ () => {
+ Common.Gateway.updateVersion();
+ if (callback) {
+ callback.call(this);
+ }
+ Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument);
+ });
+ }
+
+ onServerVersion (buildVersion) {
+ if (this.changeServerVersion) return true;
+ const _t = this._t;
+
+ if (About.appVersion() !== buildVersion && !window.compareVersions) {
+ this.changeServerVersion = true;
+ f7.dialog.alert(
+ _t.errorServerVersion,
+ _t.titleServerVersion,
+ () => {
+ setTimeout(() => {Common.Gateway.updateVersion()}, 0);
+ });
+ return true;
+ }
+ return false;
+ }
+
+ onAdvancedOptions (type, advOptions) {
+ if ($$('.dlg-adv-options.modal-in').length > 0) return;
+
+ const _t = this._t;
+
+ if (type == Asc.c_oAscAdvancedOptionsID.DRM) {
+ Common.Notifications.trigger('preloader:close');
+ Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument);
+
+ const buttons = [{
+ text: 'OK',
+ bold: true,
+ close: false,
+ onClick: () => {
+ const password = document.getElementById('modal-password').value;
+ this.api.asc_setAdvancedOptions(type, new Asc.asc_CDRMAdvancedOptions(password));
+
+ if (!this._isDocReady) {
+ Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], this.LoadingDocument);
+ }
+ }
+ }];
+ if (this.props.storeAppOptions.canRequestClose)
+ buttons.push({
+ text: _t.closeButtonText,
+ onClick: () => {
+ Common.Gateway.requestClose();
+ }
+ });
+
+ f7.dialog.create({
+ title: _t.advDRMOptions,
+ text: (typeof advOptions === 'string' ? advOptions : _t.txtProtected),
+ content:
+ `