From f41d0bd35468b83767f5ac0a495fc877755a9ab3 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 3 Nov 2020 23:30:05 +0300 Subject: [PATCH] [DE mobile] Add edit table settings (Add/remove column, add/remove row, remove table, wrap, table options) --- apps/documenteditor/mobile/locale/en.json | 9 +- .../mobile/src/components/edit/Edit.jsx | 21 +- .../mobile/src/components/edit/EditTable.jsx | 182 ++++++++++++++++++ .../components/edit/controller/EditTable.jsx | 174 +++++++++++++++++ .../mobile/src/controller/Main.jsx | 8 +- .../mobile/src/store/focusObjects.js | 22 +++ .../mobile/src/store/mainStore.js | 4 +- .../mobile/src/store/tableSettings.js | 46 +++++ 8 files changed, 460 insertions(+), 6 deletions(-) create mode 100644 apps/documenteditor/mobile/src/components/edit/EditTable.jsx create mode 100644 apps/documenteditor/mobile/src/components/edit/controller/EditTable.jsx create mode 100644 apps/documenteditor/mobile/src/store/tableSettings.js diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index feea3fe5b..4faf57fde 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -95,6 +95,13 @@ "textReplaceImage": "Replace Image", "textEmptyImgUrl": "You need to specify image URL.", "textNotUrl": "This field should be a URL in the format \"http://www.example.com\"", - "notcriticalErrorTitle": "Warning" + "notcriticalErrorTitle": "Warning", + "textRemoveTable": "Remove Table", + "textTableOptions": "Table Options", + "textOptions": "Options", + "textRepeatAsHeaderRow": "Repeat as Header Row", + "textResizeToFitContent": "Resize to Fit Content", + "textCellMargins": "Cell Margins", + "textFlow": "Flow" } } \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/components/edit/Edit.jsx b/apps/documenteditor/mobile/src/components/edit/Edit.jsx index 4935ac0d6..30ae170c8 100644 --- a/apps/documenteditor/mobile/src/components/edit/Edit.jsx +++ b/apps/documenteditor/mobile/src/components/edit/Edit.jsx @@ -9,11 +9,13 @@ import EditTextController from "./controller/EditText"; import EditParagraphController from "./controller/EditParagraph"; import EditShapeController from "./controller/EditShape"; import EditImageController from "./controller/EditImage"; +import EditTableController from "./controller/EditTable"; import {PageAdditionalFormatting, PageBullets, PageFonts, PageLineSpacing, PageNumbers} from "./EditText"; import {PageAdvancedSettings} from "./EditParagraph"; import {PageWrap, PageReorder, PageReplace} from "./EditShape"; import {PageImageReorder, PageImageReplace, PageImageWrap, PageLinkSettings} from "./EditImage"; +import {PageTableOptions, PageTableWrap, PageTableStyle} from "./EditTable"; const routes = [ //Edit text @@ -71,6 +73,19 @@ const routes = [ { path: '/edit-image-link/', component: PageLinkSettings, + }, + //Edit table + { + path: '/edit-table-options/', + component: PageTableOptions, + }, + { + path: '/edit-table-wrap/', + component: PageTableWrap, + }, + { + path: '/edit-table-style/', + component: PageTableStyle, } ]; @@ -152,14 +167,14 @@ const EditTabs = props => { component: }) } - /*if (settings.indexOf('table') > -1) { + if (settings.indexOf('table') > -1) { editors.push({ caption: _t.textTable, id: 'edit-table', - component: + component: }) } - if (settings.indexOf('header') > -1) { + /*if (settings.indexOf('header') > -1) { editors.push({ caption: headerType==2 ? _t.textFooter : _t.textHeader, id: 'edit-header', diff --git a/apps/documenteditor/mobile/src/components/edit/EditTable.jsx b/apps/documenteditor/mobile/src/components/edit/EditTable.jsx new file mode 100644 index 000000000..bb7499958 --- /dev/null +++ b/apps/documenteditor/mobile/src/components/edit/EditTable.jsx @@ -0,0 +1,182 @@ +import React, {Fragment, useState} from 'react'; +import {observer, inject} from "mobx-react"; +import {Page, Navbar, List, ListItem, ListButton, Row, BlockTitle, Range, Toggle} from 'framework7-react'; +import { useTranslation } from 'react-i18next'; + +const PageTableOptions = props => { + const { t } = useTranslation(); + const _t = t('Edit', {returnObjects: true}); + const metricText = Common.Utils.Metric.getCurrentMetricName(); + const storeFocusObjects = props.storeFocusObjects; + const tableObject = storeFocusObjects.tableObject; + const storeTableSettings = props.storeTableSettings; + const distance = Common.Utils.Metric.fnRecalcFromMM(storeTableSettings.getCellMargins(tableObject)); + const [stateDistance, setDistance] = useState(distance); + const isRepeat = storeTableSettings.getRepeatOption(tableObject); + const isResize = storeTableSettings.getResizeOption(tableObject); + return ( + + + + + {props.onOptionRepeat(!isRepeat)}}/> + + + {props.onOptionResize(!isResize)}}/> + + + {_t.textCellMargins} + + +
+ {setDistance(value)}} + onRangeChanged={(value) => {props.onCellMargins(value)}} + > +
+
+ {stateDistance + ' ' + metricText} +
+
+
+
+ ) +}; + +const PageWrap = props => { + const c_tableWrap = { + TABLE_WRAP_NONE: 0, + TABLE_WRAP_PARALLEL: 1 + }; + const c_tableAlign = { + TABLE_ALIGN_LEFT: 0, + TABLE_ALIGN_CENTER: 1, + TABLE_ALIGN_RIGHT: 2 + }; + const { t } = useTranslation(); + const _t = t('Edit', {returnObjects: true}); + const storeTableSettings = props.storeTableSettings; + const tableObject = props.storeFocusObjects.tableObject; + const wrapType = storeTableSettings.getWrapType(tableObject); + const align = storeTableSettings.getAlign(tableObject); + const moveText = storeTableSettings.getMoveText(tableObject); + const distance = Common.Utils.Metric.fnRecalcFromMM(storeTableSettings.getWrapDistance(tableObject)); + const metricText = Common.Utils.Metric.getCurrentMetricName(); + const [stateDistance, setDistance] = useState(distance); + return ( + + + + {props.onWrapType(c_tableWrap.TABLE_WRAP_NONE)}}> + {props.onWrapType(c_tableWrap.TABLE_WRAP_PARALLEL)}}> + + + + {props.onWrapMoveText(!moveText)}}/> + + + { + wrapType === 'inline' && + + {_t.textAlign} + + + + { + props.onWrapAlign(c_tableAlign.TABLE_ALIGN_LEFT) + }}>left + { + props.onWrapAlign(c_tableAlign.TABLE_ALIGN_CENTER) + }}>center + { + props.onWrapAlign(c_tableAlign.TABLE_ALIGN_RIGHT) + }}>right + + + + + } + { + (wrapType === 'flow') && + + {_t.textDistanceFromText} + + +
+ {setDistance(value)}} + onRangeChanged={(value) => {props.onWrapDistance(value)}} + > +
+
+ {stateDistance + ' ' + metricText} +
+
+
+
+ } +
+ ) +}; + +const PageStyle = props => { + const { t } = useTranslation(); + const _t = t('Edit', {returnObjects: true}); + return ( + + + ) +}; + +const EditTable = props => { + const { t } = useTranslation(); + const _t = t('Edit', {returnObjects: true}); + return ( + + + + + {props.onAddColumnLeft()}}>col-left + {props.onAddColumnRight()}}>col-right + {props.onAddRowAbove()}}>row-above + {props.onAddRowBelow()}}>row-below + + + + + {props.onRemoveColumn()}}>remove-column + {props.onRemoveRow()}}>remove-row + + + {props.onRemoveTable()}}> + + + + + + + + ) +}; + +const EditTableContainer = inject("storeFocusObjects")(observer(EditTable)); +const PageTableOptionsContainer = inject("storeFocusObjects","storeTableSettings")(observer(PageTableOptions)); +const PageWrapContainer = inject("storeFocusObjects","storeTableSettings")(observer(PageWrap)); +const PageStyleContainer = inject("storeFocusObjects","storeTableSettings")(observer(PageStyle)); + +export {EditTableContainer as EditTable, + PageTableOptionsContainer as PageTableOptions, + PageWrapContainer as PageTableWrap, + PageStyleContainer as PageTableStyle} \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/components/edit/controller/EditTable.jsx b/apps/documenteditor/mobile/src/components/edit/controller/EditTable.jsx new file mode 100644 index 000000000..6087e8e91 --- /dev/null +++ b/apps/documenteditor/mobile/src/components/edit/controller/EditTable.jsx @@ -0,0 +1,174 @@ +import React, {Component} from 'react'; +import { f7 } from 'framework7-react'; +import {Device} from '../../../../../../common/mobile/utils/device'; +import {observer, inject} from "mobx-react"; + +import { EditTable } from '../EditTable'; + +class EditTableController extends Component { + constructor (props) { + super(props); + this.closeIfNeed = this.closeIfNeed.bind(this); + this.onRemoveTable = this.onRemoveTable.bind(this); + this.onAddColumnLeft = this.onAddColumnLeft.bind(this); + this.onAddColumnRight = this.onAddColumnRight.bind(this); + this.onAddRowAbove = this.onAddRowAbove.bind(this); + this.onAddRowBelow = this.onAddRowBelow.bind(this); + this.onRemoveColumn = this.onRemoveColumn.bind(this); + this.onRemoveRow = this.onRemoveRow.bind(this); + this.onWrapMoveText = this.onWrapMoveText.bind(this); + } + closeIfNeed () { + if (!this.props.storeFocusObjects.isTableInStack) { + if ( Device.phone ) { + f7.sheet.close('#edit-sheet', true); + } else { + f7.popover.close('#edit-popover'); + } + } + } + onRemoveTable () { + const api = Common.EditorApi.get(); + if (api) { + api.remTable(); + this.closeIfNeed(); + } + } + onAddColumnLeft () { + const api = Common.EditorApi.get(); + if (api) { + api.addColumnLeft(); + this.closeIfNeed(); + } + } + onAddColumnRight () { + const api = Common.EditorApi.get(); + if (api) { + api.addColumnRight(); + this.closeIfNeed(); + } + } + onAddRowAbove () { + const api = Common.EditorApi.get(); + if (api) { + api.addRowAbove(); + this.closeIfNeed(); + } + } + onAddRowBelow () { + const api = Common.EditorApi.get(); + if (api) { + api.addRowBelow(); + this.closeIfNeed(); + } + } + onRemoveColumn () { + const api = Common.EditorApi.get(); + if (api) { + api.remColumn(); + this.closeIfNeed(); + } + } + onRemoveRow () { + const api = Common.EditorApi.get(); + if (api) { + api.remRow(); + this.closeIfNeed(); + } + } + onCellMargins (value) { + const api = Common.EditorApi.get(); + if (api) { + const properties = new Asc.CTableProp(); + const margins = new Asc.CMargins(); + const val = Common.Utils.Metric.fnRecalcToMM(value); + margins.put_Top(val); + margins.put_Right(val); + margins.put_Bottom(val); + margins.put_Left(val); + margins.put_Flag(2); + properties.put_CellMargins(margins); + api.tblApply(properties); + } + } + onOptionRepeat (value) { + const api = Common.EditorApi.get(); + if (api) { + const properties = new Asc.CTableProp(); + properties.put_RowsInHeader(value); + api.tblApply(properties); + } + } + onOptionResize (value) { + const api = Common.EditorApi.get(); + if (api) { + const properties = new Asc.CTableProp(); + properties.put_TableLayout(value ? Asc.c_oAscTableLayout.AutoFit : Asc.c_oAscTableLayout.Fixed); + api.tblApply(properties); + } + } + onWrapType (value) { + const api = Common.EditorApi.get(); + if (api) { + const properties = new Asc.CTableProp(); + properties.put_TableWrap(value); + api.tblApply(properties); + } + } + onWrapAlign (type) { + const api = Common.EditorApi.get(); + if (api) { + const properties = new Asc.CTableProp(); + properties.put_TableAlignment(type); + api.tblApply(properties); + } + } + onWrapMoveText (value) { + const api = Common.EditorApi.get(); + if (api) { + const properties = new Asc.CTableProp(); + const position = new Asc.CTablePositionV(); + position.put_UseAlign(false); + position.put_RelativeFrom(value ? Asc.c_oAscVAnchor.Text : Asc.c_oAscVAnchor.Page); + const tableObject = this.props.storeFocusObjects.tableObject; + position.put_Value(tableObject.get_Value_Y(value ? Asc.c_oAscVAnchor.Text : Asc.c_oAscVAnchor.Page)); + properties.put_PositionV(position); + api.tblApply(properties); + } + } + onWrapDistance (value) { + const api = Common.EditorApi.get(); + if (api) { + const properties = new Asc.CTableProp(); + const paddings = new Asc.asc_CPaddings(); + const distance = Common.Utils.Metric.fnRecalcToMM(parseInt(value)); + paddings.put_Top(distance); + paddings.put_Right(distance); + paddings.put_Bottom(distance); + paddings.put_Left(distance); + properties.put_TablePaddings(paddings); + api.tblApply(properties); + } + } + render () { + return ( + + ) + } +} + +export default inject("storeFocusObjects")(observer(EditTableController)); \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 151a95232..6a20a6af3 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -3,7 +3,7 @@ import React, {Component} from 'react' import {inject} from "mobx-react"; import CollaborationController from '../../../../common/mobile/lib/controller/Collaboration.jsx' -@inject("storeDocumentSettings", "storeFocusObjects", "storeTextSettings", "storeParagraphSettings") +@inject("storeDocumentSettings", "storeFocusObjects", "storeTextSettings", "storeParagraphSettings", "storeTableSettings") class MainController extends Component { constructor(props) { super(props) @@ -229,6 +229,12 @@ class MainController extends Component { storeParagraphSettings.changeParaStyleName(name); }); + //table settings + const storeTableSettings = this.props.storeTableSettings; + this.api.asc_registerCallback('asc_onInitTableTemplates', (templates) => { + storeTableSettings.initTableTemplates(templates); + }); + } render() { diff --git a/apps/documenteditor/mobile/src/store/focusObjects.js b/apps/documenteditor/mobile/src/store/focusObjects.js index 70dd0c389..ef4d1e4a3 100644 --- a/apps/documenteditor/mobile/src/store/focusObjects.js +++ b/apps/documenteditor/mobile/src/store/focusObjects.js @@ -90,4 +90,26 @@ export class storeFocusObjects { return undefined; } } + @computed get tableObject() { + let tables = []; + for (let object of this._focusObjects) { + if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Table) { + tables.push(object); + } + } + if (tables.length > 0) { + let object = tables[tables.length - 1]; // get top table + return object.get_ObjectValue(); + } else { + return undefined; + } + } + @computed get isTableInStack() { + for (let object of this._focusObjects) { + if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Table) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/store/mainStore.js b/apps/documenteditor/mobile/src/store/mainStore.js index 1f9638895..c37d4301b 100644 --- a/apps/documenteditor/mobile/src/store/mainStore.js +++ b/apps/documenteditor/mobile/src/store/mainStore.js @@ -6,6 +6,7 @@ import {storeTextSettings} from "./textSettings"; import {storeParagraphSettings} from "./paragraphSettings"; import {storeShapeSettings} from "./shapeSettings"; import {storeImageSettings} from "./imageSettings"; +import {storeTableSettings} from "./tableSettings"; export const stores = { storeFocusObjects: new storeFocusObjects(), @@ -14,6 +15,7 @@ export const stores = { storeTextSettings: new storeTextSettings(), storeParagraphSettings: new storeParagraphSettings(), storeShapeSettings: new storeShapeSettings(), - storeImageSettings: new storeImageSettings() + storeImageSettings: new storeImageSettings(), + storeTableSettings: new storeTableSettings() }; diff --git a/apps/documenteditor/mobile/src/store/tableSettings.js b/apps/documenteditor/mobile/src/store/tableSettings.js new file mode 100644 index 000000000..1c17c35be --- /dev/null +++ b/apps/documenteditor/mobile/src/store/tableSettings.js @@ -0,0 +1,46 @@ +import {action, observable, computed} from 'mobx'; + +export class storeTableSettings { + @observable _templates = []; + @action initTableTemplates (templates) { + this._templates = templates; + } + @computed get styles () { + let styles = []; + for (let template of templates) { + styles.push({ + imageUrl : template.asc_getImage(), + templateId : template.asc_getId() + }); + } + return styles; + } + getTableLook (tableObject) { + return tableObject.get_TableLook() + } + getCellMargins (tableObject) { + const margins = tableObject.get_CellMargins(); + return margins.get_Left(); + } + getRepeatOption (tableObject) { + if (tableObject.get_RowsInHeader() === null) { + return null; + } + return !!tableObject.get_RowsInHeader(); + } + getResizeOption (tableObject) { + return tableObject.get_TableLayout()==Asc.c_oAscTableLayout.AutoFit; + } + getWrapType (tableObject) { + return tableObject.get_TableWrap() === 0 ? 'inline' : 'flow'; + } + getAlign (tableObject) { + return tableObject.get_TableAlignment(); + } + getMoveText (tableObject) { + return (tableObject.get_PositionV() && tableObject.get_PositionV().get_RelativeFrom() === Asc.c_oAscVAnchor.Text); + } + getWrapDistance (tableObject) { + return tableObject.get_TablePaddings().get_Top(); + } +} \ No newline at end of file