Merge pull request #1017 from ONLYOFFICE/feature/encoding-options

Feature/encoding options
This commit is contained in:
maxkadushkin 2021-07-27 13:33:36 +03:00 committed by GitHub
commit 3cc784cdc6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 606 additions and 234 deletions

View file

@ -295,9 +295,7 @@
"textTopAndBottom": "Top and Bottom", "textTopAndBottom": "Top and Bottom",
"textTotalRow": "Total Row", "textTotalRow": "Total Row",
"textType": "Type", "textType": "Type",
"textWrap": "Wrap", "textWrap": "Wrap"
"textBullets": "Bullets",
"textNumbers": "Numbers"
}, },
"Error": { "Error": {
"convertationTimeoutText": "Conversion timeout exceeded.", "convertationTimeoutText": "Conversion timeout exceeded.",
@ -566,7 +564,11 @@
"txtScheme6": "Concourse", "txtScheme6": "Concourse",
"txtScheme7": "Equity", "txtScheme7": "Equity",
"txtScheme8": "Flow", "txtScheme8": "Flow",
"txtScheme9": "Foundry" "txtScheme9": "Foundry",
"textChooseTxtOptions": "Choose TXT Options",
"txtDownloadTxt": "Download TXT",
"textChooseEncoding": "Choose Encoding",
"txtOk": "Ok"
}, },
"Toolbar": { "Toolbar": {
"dlgLeaveMsgText": "You have unsaved changes. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.", "dlgLeaveMsgText": "You have unsaved changes. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.",

View file

@ -0,0 +1,89 @@
import React, { Component } from 'react';
import { Device } from '../../../../common/mobile/utils/device';
import { f7 } from "framework7-react";
import { Encoding } from "../view/Encoding";
class EncodingController extends Component {
constructor(props) {
super(props);
this.onSaveFormat = this.onSaveFormat.bind(this);
this.closeModal = this.closeModal.bind(this);
this.state = {
isOpen: false
};
Common.Notifications.on('engineCreated', api => {
api.asc_registerCallback('asc_onAdvancedOptions', (type, advOptions, mode, formatOptions) => {
this.initEncoding(type, advOptions, mode, formatOptions);
});
});
Common.Notifications.on('openEncoding', (type, advOptions, mode, formatOptions) => {
this.initEncoding(type, advOptions, mode, formatOptions);
});
}
initEncoding(type, advOptions, mode, formatOptions) {
if(type === Asc.c_oAscAdvancedOptionsID.TXT) {
Common.Notifications.trigger('preloader:close');
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256, true);
this.mode = mode;
this.advOptions = advOptions;
this.formatOptions = formatOptions;
this.pages = [];
this.pagesName = [];
const recommendedSettings = this.advOptions.asc_getRecommendedSettings();
this.initPages();
this.valueEncoding = recommendedSettings.asc_getCodePage();
this.setState({
isOpen: true
});
}
}
initPages() {
for (let page of this.advOptions.asc_getCodePages()) {
this.pages.push(page.asc_getCodePage());
this.pagesName.push(page.asc_getCodePageName());
}
}
closeModal() {
f7.sheet.close('.encoding-popup', true);
this.setState({isOpen: false});
}
onSaveFormat(valueEncoding) {
const api = Common.EditorApi.get();
this.closeModal();
if(this.mode === 2) {
this.formatOptions && this.formatOptions.asc_setAdvancedOptions(new Asc.asc_CTextOptions(valueEncoding));
api.asc_DownloadAs(this.formatOptions);
} else {
api.asc_setAdvancedOptions(Asc.c_oAscAdvancedOptionsID.TXT, new Asc.asc_CTextOptions(valueEncoding));
}
}
render() {
return (
this.state.isOpen &&
<Encoding
closeModal={this.closeModal}
mode={this.mode}
onSaveFormat={this.onSaveFormat}
pages={this.pages}
pagesName={this.pagesName}
valueEncoding={this.valueEncoding}
/>
);
}
}
export default EncodingController;

View file

@ -16,7 +16,7 @@ import EditorUIController from '../lib/patch';
import ErrorController from "./Error"; import ErrorController from "./Error";
import LongActionsController from "./LongActions"; import LongActionsController from "./LongActions";
import PluginsController from '../../../../common/mobile/lib/controller/Plugins.jsx'; import PluginsController from '../../../../common/mobile/lib/controller/Plugins.jsx';
import EncodingController from "./Encoding";
@inject( @inject(
"storeAppOptions", "storeAppOptions",
"storeDocumentSettings", "storeDocumentSettings",
@ -614,11 +614,14 @@ class MainController extends Component {
}); });
// Downloaded Advanced Options // Downloaded Advanced Options
this.api.asc_registerCallback('asc_onAdvancedOptions', (type, advOptions, mode, formatOptions) => { this.api.asc_registerCallback('asc_onAdvancedOptions', (type, advOptions, mode, formatOptions) => {
const {t} = this.props; const {t} = this.props;
const _t = t("Settings", { returnObjects: true }); const _t = t("Settings", { returnObjects: true });
onAdvancedOptions(type, advOptions, mode, formatOptions, _t, this._isDocReady, this.props.storeAppOptions.canRequestClose, this.isDRM); if(type == Asc.c_oAscAdvancedOptionsID.DRM) {
if(type == Asc.c_oAscAdvancedOptionsID.DRM) this.isDRM = true; onAdvancedOptions(type, _t, this._isDocReady, this.props.storeAppOptions.canRequestClose, this.isDRM);
this.isDRM = true;
}
}); });
} }
@ -824,6 +827,7 @@ class MainController extends Component {
{EditorUIController.getEditCommentControllers && EditorUIController.getEditCommentControllers()} {EditorUIController.getEditCommentControllers && EditorUIController.getEditCommentControllers()}
<ViewCommentsController /> <ViewCommentsController />
<PluginsController /> <PluginsController />
<EncodingController />
</Fragment> </Fragment>
) )
} }

View file

@ -13,7 +13,7 @@ class DownloadController extends Component {
closeModal() { closeModal() {
if (Device.phone) { if (Device.phone) {
f7.sheet.close('.settings-popup', true); f7.sheet.close('.settings-popup', false);
} else { } else {
f7.popover.close('#settings-popover'); f7.popover.close('#settings-popover');
} }
@ -25,17 +25,18 @@ class DownloadController extends Component {
const _t = t("Settings", { returnObjects: true }); const _t = t("Settings", { returnObjects: true });
if(format) { if(format) {
this.closeModal();
if (format == Asc.c_oAscFileType.TXT || format == Asc.c_oAscFileType.RTF) { if (format == Asc.c_oAscFileType.TXT || format == Asc.c_oAscFileType.RTF) {
f7.dialog.confirm( f7.dialog.confirm(
(format === Asc.c_oAscFileType.TXT) ? _t.textDownloadTxt : _t.textDownloadRtf, (format === Asc.c_oAscFileType.TXT) ? _t.textDownloadTxt : _t.textDownloadRtf,
_t.notcriticalErrorTitle, _t.notcriticalErrorTitle,
() => { () => {
if (format == Asc.c_oAscFileType.TXT) { if (format === Asc.c_oAscFileType.TXT) {
const isDocReady = this.props.storeAppOptions.isDocReady; const advOptions = api.asc_getAdvancedOptions();
onAdvancedOptions(Asc.c_oAscAdvancedOptionsID.TXT, api.asc_getAdvancedOptions(), 2, new Asc.asc_CDownloadOptions(format), _t, isDocReady); this.closeModal();
Common.Notifications.trigger('openEncoding', Asc.c_oAscAdvancedOptionsID.TXT, advOptions, 2, new Asc.asc_CDownloadOptions(format));
} }
else { else {
this.closeModal();
setTimeout(() => { setTimeout(() => {
api.asc_DownloadAs(new Asc.asc_CDownloadOptions(format)); api.asc_DownloadAs(new Asc.asc_CDownloadOptions(format));
}, 400); }, 400);
@ -44,6 +45,7 @@ class DownloadController extends Component {
); );
} }
else { else {
this.closeModal();
setTimeout(() => { setTimeout(() => {
api.asc_DownloadAs(new Asc.asc_CDownloadOptions(format)); api.asc_DownloadAs(new Asc.asc_CDownloadOptions(format));
}, 400); }, 400);
@ -60,110 +62,51 @@ class DownloadController extends Component {
const DownloadWithTranslation = inject("storeAppOptions")(observer(withTranslation()(DownloadController))); const DownloadWithTranslation = inject("storeAppOptions")(observer(withTranslation()(DownloadController)));
const onAdvancedOptions = (type, advOptions, mode, formatOptions, _t, isDocReady, canRequestClose, isDRM) => { const onAdvancedOptions = (type, _t, isDocReady, canRequestClose, isDRM) => {
if ($$('.dlg-adv-options.modal-in').length > 0) return; if ($$('.dlg-adv-options.modal-in').length > 0) return;
const api = Common.EditorApi.get(); const api = Common.EditorApi.get();
if (type == Asc.c_oAscAdvancedOptionsID.TXT) {
let picker;
const pages = [];
const pagesName = [];
for (let page of advOptions.asc_getCodePages()) {
pages.push(page.asc_getCodePage());
pagesName.push(page.asc_getCodePageName());
}
Common.Notifications.trigger('preloader:close');
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256, true);
const buttons = [];
if (mode === 2) {
buttons.push({
text: _t.textCancel
});
}
buttons.push({
text: 'OK',
bold: true,
onClick: function() {
const encoding = picker.value;
if (mode==2) {
formatOptions && formatOptions.asc_setAdvancedOptions(new Asc.asc_CTextOptions(encoding));
api.asc_DownloadAs(formatOptions);
} else {
api.asc_setAdvancedOptions(type, new Asc.asc_CTextOptions(encoding));
}
if (!isDocReady) {
Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256);
}
}
});
const dialog = f7.dialog.create({
title: _t.advTxtOptions,
text: '',
content:
'<div class="content-block">' +
'<div class="row">' +
'<div class="col-100">' + _t.textEncoding + '</div>' +
'</div>' +
'<div id="txt-encoding"></div>' +
'</div>',
buttons: buttons,
cssClass: 'dlg-adv-options'
}).open();
dialog.on('opened', () => {
picker = f7.picker.create({
containerEl: document.getElementById('txt-encoding'),
cols: [
{
values: pages,
displayValues: pagesName
}
],
toolbar: false,
rotateEffect: true,
value: [advOptions.asc_getRecommendedSettings().asc_getCodePage()],
});
});
} else if (type == Asc.c_oAscAdvancedOptionsID.DRM) {
Common.Notifications.trigger('preloader:close');
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256, true);
const buttons = [{
text: 'OK',
bold: true,
onClick: function () {
const password = document.getElementById('modal-password').value;
api.asc_setAdvancedOptions(type, new Asc.asc_CDRMAdvancedOptions(password));
if (!isDocReady) {
Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256);
}
}
}];
if(isDRM) { Common.Notifications.trigger('preloader:close');
f7.dialog.create({ Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256, true);
text: _t.txtIncorrectPwd,
buttons : [{
text: 'OK',
bold: true,
}]
}).open();
}
if (canRequestClose) const buttons = [{
buttons.push({ text: 'OK',
text: _t.closeButtonText, bold: true,
onClick: function () { onClick: function () {
Common.Gateway.requestClose(); const password = document.getElementById('modal-password').value;
} api.asc_setAdvancedOptions(type, new Asc.asc_CDRMAdvancedOptions(password));
}); if (!isDocReady) {
Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256);
}
}
}];
if(isDRM) {
f7.dialog.create({ f7.dialog.create({
title: _t.advDRMOptions, text: _t.txtIncorrectPwd,
text: _t.textOpenFile, buttons : [{
content: Device.ios ? text: 'OK',
'<div class="input-field"><input type="password" class="modal-text-input" name="modal-password" placeholder="' + _t.advDRMPassword + '" id="modal-password"></div>' : '<div class="input-field"><div class="inputs-list list inline-labels"><ul><li><div class="item-content item-input"><div class="item-inner"><div class="item-input-wrap"><input type="password" name="modal-password" id="modal-password" placeholder=' + _t.advDRMPassword + '></div></div></div></li></ul></div></div>', bold: true,
buttons: buttons, }]
cssClass: 'dlg-adv-options'
}).open(); }).open();
} }
if (canRequestClose)
buttons.push({
text: _t.closeButtonText,
onClick: function () {
Common.Gateway.requestClose();
}
});
f7.dialog.create({
title: _t.advDRMOptions,
text: _t.textOpenFile,
content: Device.ios ?
'<div class="input-field"><input type="password" class="modal-text-input" name="modal-password" placeholder="' + _t.advDRMPassword + '" id="modal-password"></div>' : '<div class="input-field"><div class="inputs-list list inline-labels"><ul><li><div class="item-content item-input"><div class="item-inner"><div class="item-input-wrap"><input type="password" name="modal-password" id="modal-password" placeholder=' + _t.advDRMPassword + '></div></div></div></li></ul></div></div>',
buttons: buttons,
cssClass: 'dlg-adv-options'
}).open();
}; };

View file

@ -0,0 +1,118 @@
import React, {Component, useEffect, useState} from 'react';
import { f7, Page, Navbar, List, ListItem, BlockTitle, ListButton, Popover, Popup, View, Link } from "framework7-react";
import { useTranslation } from "react-i18next";
import { Device } from '../../../../common/mobile/utils/device';
const PageEncoding = props => {
const { t } = useTranslation();
const _t = t("Settings", { returnObjects: true });
const pagesName = props.pagesName;
const pages = props.pages;
const [stateEncoding, setStateEncoding] = useState(props.valueEncoding);
const nameEncoding = pagesName[pages.indexOf(stateEncoding)];
const mode = props.mode;
const changeStateEncoding = value => {
setStateEncoding(value);
}
return (
<View style={props.style} routes={routes}>
<Page>
<Navbar title={_t.textChooseTxtOptions} />
<BlockTitle>{_t.textEncoding}</BlockTitle>
<List>
<ListItem title={nameEncoding} link="/encoding-list/" routeProps={{
stateEncoding,
pages: props.pages,
pagesName: props.pagesName,
changeStateEncoding
}}></ListItem>
</List>
<List className="buttons-list">
{mode === 2 ?
<ListButton className='button-fill button-raised' title={_t.textCancel} onClick={() => props.closeModal()}></ListButton>
: null}
<ListButton className='button-fill button-raised' title={mode === 2 ?_t.textDownload : _t.txtOk} onClick={() => props.onSaveFormat(stateEncoding)}></ListButton>
</List>
</Page>
</View>
)
};
const PageEncodingList = props => {
const { t } = useTranslation();
const _t = t("Settings", { returnObjects: true });
const [currentEncoding, changeCurrentEncoding] = useState(props.stateEncoding);
const pages = props.pages;
const pagesName = props.pagesName;
return (
<Page>
<Navbar title={_t.txtDownloadTxt} backLink={_t.textBack} />
<BlockTitle>{_t.textChooseEncoding}</BlockTitle>
<List>
{pagesName.map((name, index) => {
return (
<ListItem radio checked={currentEncoding === pages[index]} title={name} key={index} value={pages[index]} onChange={() => {
changeCurrentEncoding(pages[index]);
props.changeStateEncoding(pages[index]);
f7.views.current.router.back();
}}></ListItem>
)
})}
</List>
</Page>
)
};
class EncodingView extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Popup className="encoding-popup" closeByBackdropClick={false}>
<PageEncoding
onSaveFormat={this.props.onSaveFormat}
closeModal={this.props.closeModal}
mode={this.props.mode}
pages={this.props.pages}
pagesName={this.props.pagesName}
valueEncoding={this.props.valueEncoding}
/>
</Popup>
)
}
}
const routes = [
{
path: '/encoding-list/',
component: PageEncodingList
}
];
const Encoding = props => {
useEffect(() => {
f7.popup.open('.encoding-popup');
return () => {
}
});
return (
<EncodingView
closeModal={props.closeModal}
onSaveFormat={props.onSaveFormat}
mode={props.mode}
pages={props.pages}
pagesName={props.pagesName}
valueEncoding={props.valueEncoding}
/>
)
};
export {Encoding, PageEncodingList}

View file

@ -629,7 +629,17 @@
"txtScheme9": "Foundry", "txtScheme9": "Foundry",
"txtSpace": "Space", "txtSpace": "Space",
"txtTab": "Tab", "txtTab": "Tab",
"warnDownloadAs": "If you continue saving in this format all features except the text will be lost.<br>Are you sure you want to continue?" "warnDownloadAs": "If you continue saving in this format all features except the text will be lost.<br>Are you sure you want to continue?",
"textChooseCsvOptions": "Choose CSV Options",
"txtDownloadCsv": "Download CSV",
"textDelimeter": "Delimeter",
"textEncoding": "Encoding",
"textChooseEncoding": "Choose Encoding",
"textChooseDelimeter": "Choose Delimeter",
"txtComma": "Comma",
"txtSemicolon": "Semicolon",
"txtColon": "Colon",
"txtOk": "Ok"
} }
} }
} }

View file

@ -0,0 +1,99 @@
import React, { Component } from 'react';
import { Device } from '../../../../common/mobile/utils/device';
import { f7 } from "framework7-react";
import { Encoding } from "../view/Encoding";
import { withTranslation } from 'react-i18next';
class EncodingController extends Component {
constructor(props) {
super(props);
const { t } = this.props;
const _t = t("View.Settings", { returnObjects: true });
this.valuesDelimeter = [4, 2, 3, 1, 5];
this.namesDelimeter = [_t.txtComma, _t.txtSemicolon, _t.txtColon, _t.txtTab, _t.txtSpace];
this.onSaveFormat = this.onSaveFormat.bind(this);
this.closeModal = this.closeModal.bind(this);
this.state = {
isOpen: false
};
Common.Notifications.on('engineCreated', api => {
api.asc_registerCallback('asc_onAdvancedOptions', (type, advOptions, mode, formatOptions) => {
this.initEncoding(type, advOptions, mode, formatOptions);
});
});
Common.Notifications.on('openEncoding', (type, advOptions, mode, formatOptions) => {
this.initEncoding(type, advOptions, mode, formatOptions);
});
}
initEncoding(type, advOptions, mode, formatOptions) {
if(type === Asc.c_oAscAdvancedOptionsID.CSV) {
Common.Notifications.trigger('preloader:close');
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256, true);
this.mode = mode;
this.advOptions = advOptions;
this.formatOptions = formatOptions;
this.pages = [];
this.pagesName = [];
const recommendedSettings = this.advOptions.asc_getRecommendedSettings();
this.initPages();
this.valueEncoding = recommendedSettings.asc_getCodePage();
this.valueDelimeter = recommendedSettings && recommendedSettings.asc_getDelimiter() ? recommendedSettings.asc_getDelimiter() : 4;
this.setState({
isOpen: true
});
}
}
initPages() {
for (let page of this.advOptions.asc_getCodePages()) {
this.pages.push(page.asc_getCodePage());
this.pagesName.push(page.asc_getCodePageName());
}
}
closeModal() {
f7.sheet.close('.encoding-popup', true);
this.setState({isOpen: false});
}
onSaveFormat(valueEncoding, valueDelimeter) {
const api = Common.EditorApi.get();
this.closeModal();
if(this.mode === 2) {
this.formatOptions && this.formatOptions.asc_setAdvancedOptions(new Asc.asc_CTextOptions(valueEncoding, valueDelimeter));
api.asc_DownloadAs(this.formatOptions);
} else {
api.asc_setAdvancedOptions(Asc.c_oAscAdvancedOptionsID.CSV, new Asc.asc_CTextOptions(valueEncoding, valueDelimeter));
}
}
render() {
return (
this.state.isOpen &&
<Encoding
closeModal={this.closeModal}
mode={this.mode}
onSaveFormat={this.onSaveFormat}
pages={this.pages}
pagesName={this.pagesName}
namesDelimeter={this.namesDelimeter}
valueEncoding={this.valueEncoding}
valueDelimeter={this.valueDelimeter}
valuesDelimeter={this.valuesDelimeter}
/>
);
}
}
export default withTranslation()(EncodingController);

View file

@ -18,6 +18,7 @@ import ErrorController from "./Error";
import app from "../page/app"; import app from "../page/app";
import About from "../../../../common/mobile/lib/view/About"; import About from "../../../../common/mobile/lib/view/About";
import PluginsController from '../../../../common/mobile/lib/controller/Plugins.jsx'; import PluginsController from '../../../../common/mobile/lib/controller/Plugins.jsx';
import EncodingController from "./Encoding";
@inject( @inject(
"storeAppOptions", "storeAppOptions",
@ -28,7 +29,7 @@ import PluginsController from '../../../../common/mobile/lib/controller/Plugins.
"storeSpreadsheetSettings", "storeSpreadsheetSettings",
"storeSpreadsheetInfo", "storeSpreadsheetInfo",
"storeApplicationSettings" "storeApplicationSettings"
) )
class MainController extends Component { class MainController extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -355,8 +356,10 @@ class MainController extends Component {
this.api.asc_registerCallback('asc_onAdvancedOptions', (type, advOptions, mode, formatOptions) => { this.api.asc_registerCallback('asc_onAdvancedOptions', (type, advOptions, mode, formatOptions) => {
const {t} = this.props; const {t} = this.props;
const _t = t("View.Settings", { returnObjects: true }); const _t = t("View.Settings", { returnObjects: true });
onAdvancedOptions(type, advOptions, mode, formatOptions, _t, this._isDocReady, this.props.storeAppOptions.canRequestClose,this.isDRM); if(type == Asc.c_oAscAdvancedOptionsID.DRM) {
if(type == Asc.c_oAscAdvancedOptionsID.DRM) this.isDRM = true; onAdvancedOptions(type, _t, this._isDocReady, this.props.storeAppOptions.canRequestClose, this.isDRM);
this.isDRM = true;
}
}); });
} }
@ -805,6 +808,7 @@ class MainController extends Component {
<EditCommentController /> <EditCommentController />
<ViewCommentsController /> <ViewCommentsController />
<PluginsController /> <PluginsController />
<EncodingController />
</Fragment> </Fragment>
) )
} }

View file

@ -3,6 +3,7 @@ import Download from "../../view/settings/Download";
import { Device } from '../../../../../common/mobile/utils/device'; import { Device } from '../../../../../common/mobile/utils/device';
import { withTranslation, useTranslation } from 'react-i18next'; import { withTranslation, useTranslation } from 'react-i18next';
import { f7 } from 'framework7-react'; import { f7 } from 'framework7-react';
import { observer, inject } from "mobx-react";
class DownloadController extends Component { class DownloadController extends Component {
constructor(props) { constructor(props) {
@ -10,6 +11,14 @@ class DownloadController extends Component {
this.onSaveFormat = this.onSaveFormat.bind(this); this.onSaveFormat = this.onSaveFormat.bind(this);
} }
closeModal() {
if (Device.phone) {
f7.sheet.close('.settings-popup', false);
} else {
f7.popover.close('#settings-popover');
}
}
onSaveFormat(format) { onSaveFormat(format) {
const api = Common.EditorApi.get(); const api = Common.EditorApi.get();
const { t } = this.props; const { t } = this.props;
@ -20,11 +29,14 @@ class DownloadController extends Component {
f7.dialog.confirm( f7.dialog.confirm(
_t.warnDownloadAs, _t.warnDownloadAs,
_t.notcriticalErrorTitle, _t.notcriticalErrorTitle,
function () { () => {
onAdvancedOptions(Asc.c_oAscAdvancedOptionsID.CSV, api.asc_getAdvancedOptions(), 2, new Asc.asc_CDownloadOptions(format), _t, true); const advOptions = api.asc_getAdvancedOptions();
this.closeModal();
Common.Notifications.trigger('openEncoding', Asc.c_oAscAdvancedOptionsID.CSV, advOptions, 2, new Asc.asc_CDownloadOptions(format));
} }
) )
} else { } else {
this.closeModal();
api.asc_DownloadAs(new Asc.asc_CDownloadOptions(format)); api.asc_DownloadAs(new Asc.asc_CDownloadOptions(format));
} }
} }
@ -37,132 +49,51 @@ class DownloadController extends Component {
} }
} }
const DownloadWithTranslation = withTranslation()(DownloadController); const DownloadWithTranslation = inject("storeAppOptions")(observer(withTranslation()(DownloadController)));
const onAdvancedOptions = (type, advOptions, mode, formatOptions, _t, isDocReady, canRequestClose, isDRM) => { const onAdvancedOptions = (type, _t, isDocReady, canRequestClose, isDRM) => {
const api = Common.EditorApi.get(); const api = Common.EditorApi.get();
if (type == Asc.c_oAscAdvancedOptionsID.CSV) { Common.Notifications.trigger('preloader:close');
let picker; Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256, true);
const pages = []; const buttons = [{
const pagesName = []; text: 'OK',
bold: true,
for (let page of advOptions.asc_getCodePages()) { onClick: function () {
pages.push(page.asc_getCodePage()); const password = document.getElementById('modal-password').value;
pagesName.push(page.asc_getCodePageName()); api.asc_setAdvancedOptions(type, new Asc.asc_CDRMAdvancedOptions(password));
} if (!isDocReady) {
Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256);
Common.Notifications.trigger('preloader:close');
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256, true);
const buttons = [];
if (mode === 2) {
buttons.push({
text: _t.textCancel
});
}
buttons.push({
text: 'OK',
bold: true,
onClick: function() {
let encoding = picker.cols[0].value,
delimiter = picker.cols[1].value;
if (mode == 2) {
formatOptions && formatOptions.asc_setAdvancedOptions(new Asc.asc_CTextOptions(encoding, delimiter));
api.asc_DownloadAs(formatOptions);
} else {
api.asc_setAdvancedOptions(type, new Asc.asc_CTextOptions(encoding, delimiter));
}
if (!isDocReady) {
Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256);
}
} }
});
const dialog = f7.dialog.create({
title: _t.advCSVOptions,
text: '',
content:
'<div class="content-block small-picker" style="padding: 0; margin: 20px 0 0;">' +
'<div class="row">' +
'<div class="col-50" style="text-align: left;">' + _t.txtEncoding + '</div>' +
'<div class="col-50" style="text-align: right;">' + _t.txtDelimiter + '</div>' +
'</div>' +
'<div id="txt-encoding" class="small"></div>' +
'</div>',
buttons: buttons,
cssClass: 'dlg-adv-options'
}).open();
const recommendedSettings = advOptions.asc_getRecommendedSettings();
dialog.on('opened', () => {
picker = f7.picker.create({
containerEl: document.getElementById('txt-encoding'),
cols: [{
textAlign: 'left',
values: pages,
displayValues: pagesName
},{
textAlign: 'right',
width: 120,
values: [4, 2, 3, 1, 5],
displayValues: [',', ';', ':', _t.txtTab, _t.txtSpace]
}],
toolbar: false,
rotateEffect: true,
value: [
recommendedSettings && recommendedSettings.asc_getCodePage(),
(recommendedSettings && recommendedSettings.asc_getDelimiter()) ? recommendedSettings.asc_getDelimiter() : 4
],
});
});
} else if (type == Asc.c_oAscAdvancedOptionsID.DRM) {
Common.Notifications.trigger('preloader:close');
Common.Notifications.trigger('preloader:endAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256, true);
const buttons = [{
text: 'OK',
bold: true,
onClick: function () {
const password = document.getElementById('modal-password').value;
api.asc_setAdvancedOptions(type, new Asc.asc_CDRMAdvancedOptions(password));
if (!isDocReady) {
Common.Notifications.trigger('preloader:beginAction', Asc.c_oAscAsyncActionType['BlockInteraction'], -256);
}
}
}];
if(isDRM) {
f7.dialog.create({
text: _t.txtIncorrectPwd,
buttons : [{
text: 'OK',
bold: true,
}]
}).open();
} }
}];
if (canRequestClose) if(isDRM) {
buttons.push({
text: _t.closeButtonText,
onClick: function () {
Common.Gateway.requestClose();
}
});
f7.dialog.create({ f7.dialog.create({
title: _t.advDRMOptions, text: _t.txtIncorrectPwd,
text: _t.textOpenFile, buttons : [{
content: Device.ios ? text: 'OK',
'<div class="input-field"><input type="password" class="modal-text-input" name="modal-password" placeholder="' + _t.advDRMPassword + '" id="modal-password"></div>' : '<div class="input-field"><div class="inputs-list list inline-labels"><ul><li><div class="item-content item-input"><div class="item-inner"><div class="item-input-wrap"><input type="password" name="modal-password" id="modal-password" placeholder=' + _t.advDRMPassword + '></div></div></div></li></ul></div></div>', bold: true,
buttons: buttons }]
}).open(); }).open();
} }
if (canRequestClose)
buttons.push({
text: _t.closeButtonText,
onClick: function () {
Common.Gateway.requestClose();
}
});
f7.dialog.create({
title: _t.advDRMOptions,
text: _t.textOpenFile,
content: Device.ios ?
'<div class="input-field"><input type="password" class="modal-text-input" name="modal-password" placeholder="' + _t.advDRMPassword + '" id="modal-password"></div>' : '<div class="input-field"><div class="inputs-list list inline-labels"><ul><li><div class="item-content item-input"><div class="item-inner"><div class="item-input-wrap"><input type="password" name="modal-password" id="modal-password" placeholder=' + _t.advDRMPassword + '></div></div></div></li></ul></div></div>',
buttons: buttons
}).open();
}; };
export { export {

View file

@ -25,7 +25,7 @@ class MainPage extends Component {
addOptionsVisible: false, addOptionsVisible: false,
addShowOptions: null, addShowOptions: null,
settingsVisible: false, settingsVisible: false,
collaborationVisible: false, collaborationVisible: false
}; };
} }
@ -67,13 +67,14 @@ class MainPage extends Component {
f7.navbar.show('.main-navbar'); f7.navbar.show('.main-navbar');
} }
})(); })();
}; };
render() { render() {
const appOptions = this.props.storeAppOptions; const appOptions = this.props.storeAppOptions;
const config = appOptions.config; const config = appOptions.config;
const showLogo = !(appOptions.canBrandingExt && (config.customization && (config.customization.loaderName || config.customization.loaderLogo))); const showLogo = !(appOptions.canBrandingExt && (config.customization && (config.customization.loaderName || config.customization.loaderLogo)));
const showPlaceholder = !appOptions.isDocReady && (!config.customization || !(config.customization.loaderName || config.customization.loaderLogo)); const showPlaceholder = !appOptions.isDocReady && (!config.customization || !(config.customization.loaderName || config.customization.loaderLogo));
return ( return (
<Page name="home" className={`editor${ showLogo ? ' page-with-logo' : ''}`}> <Page name="home" className={`editor${ showLogo ? ' page-with-logo' : ''}`}>
{/* Top Navbar */} {/* Top Navbar */}

View file

@ -0,0 +1,171 @@
import React, {Component, useEffect, useState} from 'react';
import { f7, Page, Navbar, List, ListItem, BlockTitle, ListButton, Popover, Popup, View, Link } from "framework7-react";
import { useTranslation } from "react-i18next";
import { Device } from '../../../../common/mobile/utils/device';
const PageEncoding = props => {
const { t } = useTranslation();
const _t = t("View.Settings", { returnObjects: true });
const pagesName = props.pagesName;
const pages = props.pages;
const valuesDelimeter = props.valuesDelimeter;
const namesDelimeter = props.namesDelimeter;
const [stateEncoding, setStateEncoding] = useState(props.valueEncoding);
const [stateDelimeter, setStateDelimeter] = useState(props.valueDelimeter);
const nameEncoding = pagesName[pages.indexOf(stateEncoding)];
const nameDelimeter = namesDelimeter[valuesDelimeter.indexOf(stateDelimeter)];
const mode = props.mode;
const changeStateEncoding = value => {
setStateEncoding(value);
}
const changeStateDelimeter = value => {
setStateDelimeter(value);
}
return (
<View style={props.style} routes={routes}>
<Page>
<Navbar title={_t.textChooseCsvOptions} />
<BlockTitle>{_t.textDelimeter}</BlockTitle>
<List>
<ListItem title={nameDelimeter} link="/delimeter-list/" routeProps={{
stateDelimeter,
namesDelimeter: props.namesDelimeter,
valuesDelimeter: props.valuesDelimeter,
changeStateDelimeter
}}></ListItem>
</List>
<BlockTitle>{_t.textEncoding}</BlockTitle>
<List>
<ListItem title={nameEncoding} link="/encoding-list/" routeProps={{
stateEncoding,
pages: props.pages,
pagesName: props.pagesName,
changeStateEncoding
}}></ListItem>
</List>
<List className="buttons-list">
{mode === 2 ?
<ListButton className='button-fill button-raised' title={_t.textCancel} onClick={() => props.closeModal()}></ListButton>
: null}
<ListButton className='button-fill button-raised' title={mode === 2 ?_t.textDownload : _t.txtOk} onClick={() => props.onSaveFormat(stateEncoding, stateDelimeter)}></ListButton>
</List>
</Page>
</View>
)
};
const PageEncodingList = props => {
const { t } = useTranslation();
const _t = t("View.Settings", { returnObjects: true });
const [currentEncoding, changeCurrentEncoding] = useState(props.stateEncoding);
const pages = props.pages;
const pagesName = props.pagesName;
return (
<Page>
<Navbar title={_t.txtDownloadCsv} backLink={_t.textBack} />
<BlockTitle>{_t.textChooseEncoding}</BlockTitle>
<List>
{pagesName.map((name, index) => {
return (
<ListItem radio checked={currentEncoding === pages[index]} title={name} key={index} value={pages[index]} onChange={() => {
changeCurrentEncoding(pages[index]);
props.changeStateEncoding(pages[index]);
f7.views.current.router.back();
}}></ListItem>
)
})}
</List>
</Page>
)
};
const PageDelimeterList = props => {
const { t } = useTranslation();
const _t = t("View.Settings", { returnObjects: true });
const [currentDelimeter, changeCurrentDelimeter] = useState(props.stateDelimeter);
const namesDelimeter = props.namesDelimeter;
const valuesDelimeter = props.valuesDelimeter;
return (
<Page>
<Navbar title={_t.txtDownloadCsv} backLink={_t.textBack} />
<BlockTitle>{_t.textChooseDelimeter}</BlockTitle>
<List>
{namesDelimeter.map((name, index) => {
return (
<ListItem radio checked={currentDelimeter === valuesDelimeter[index]} title={name} key={index} value={valuesDelimeter[index]} onChange={() => {
changeCurrentDelimeter(valuesDelimeter[index]);
props.changeStateDelimeter(valuesDelimeter[index]);
f7.views.current.router.back();
}}></ListItem>
)
})}
</List>
</Page>
)
};
class EncodingView extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Popup className="encoding-popup" closeByBackdropClick={false}>
<PageEncoding
onSaveFormat={this.props.onSaveFormat}
closeModal={this.props.closeModal}
mode={this.props.mode}
pages={this.props.pages}
pagesName={this.props.pagesName}
namesDelimeter={this.props.namesDelimeter}
valueEncoding={this.props.valueEncoding}
valueDelimeter={this.props.valueDelimeter}
valuesDelimeter={this.props.valuesDelimeter}
/>
</Popup>
)
}
}
const routes = [
{
path: '/encoding-list/',
component: PageEncodingList
},
{
path: '/delimeter-list/',
component: PageDelimeterList
}
];
const Encoding = props => {
useEffect(() => {
f7.popup.open('.encoding-popup');
return () => {
}
});
return (
<EncodingView
closeModal={props.closeModal}
onSaveFormat={props.onSaveFormat}
mode={props.mode}
pages={props.pages}
pagesName={props.pagesName}
namesDelimeter={props.namesDelimeter}
valueEncoding={props.valueEncoding}
valueDelimeter={props.valueDelimeter}
valuesDelimeter={props.valuesDelimeter}
/>
)
};
export {Encoding, PageEncodingList, PageDelimeterList}

View file

@ -146,7 +146,7 @@ const SettingsList = inject("storeAppOptions")(observer(props => {
<ListItem title={_t.textApplicationSettings} link="#" onClick={onoptionclick.bind(this, '/application-settings/')}> <ListItem title={_t.textApplicationSettings} link="#" onClick={onoptionclick.bind(this, '/application-settings/')}>
<Icon slot="media" icon="icon-app-settings"></Icon> <Icon slot="media" icon="icon-app-settings"></Icon>
</ListItem> </ListItem>
<ListItem title={_t.textDownload} link="#" onClick={onoptionclick.bind(this, "/download/")}> <ListItem title={_t.textDownload} link="#" onClick={onoptionclick.bind(this, '/download/')}>
<Icon slot="media" icon="icon-download"></Icon> <Icon slot="media" icon="icon-download"></Icon>
</ListItem> </ListItem>
<ListItem title={_t.textPrint} onClick={onPrint}> <ListItem title={_t.textPrint} onClick={onPrint}>