123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- /**
- * Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com>
- *
- * @licstart
- * This file is part of WebODF.
- *
- * WebODF is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Affero General Public License (GNU AGPL)
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * WebODF is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with WebODF. If not, see <http://www.gnu.org/licenses/>.
- * @licend
- *
- * @source: http://www.webodf.org/
- * @source: https://github.com/kogmbh/WebODF/
- */
- /*global define,require,dojo,dijit */
- define("webodf/editor/widgets/paragraphStylesDialog", [], function () {
- "use strict";
- return function ParagraphStylesDialog(callback) {
- var self = this,
- editorSession,
- dialog,
- stylePicker, alignmentPane, fontEffectsPane;
- function makeWidget(callback) {
- require([
- "dijit/Dialog",
- "dijit/TooltipDialog",
- "dijit/popup",
- "dijit/layout/LayoutContainer",
- "dijit/layout/TabContainer",
- "dijit/layout/ContentPane",
- "dijit/form/Button",
- "dijit/form/DropDownButton"], function (Dialog, TooltipDialog, popup, LayoutContainer, TabContainer, ContentPane, Button, DropDownButton) {
- var i,
- tr = runtime.tr,
- mainLayoutContainer,
- tabContainer,
- topBar,
- actionBar,
- okButton,
- cancelButton,
- cloneButton,
- deleteButton,
- cloneTooltip,
- cloneDropDown,
- /**
- * Mapping of the properties from edit pane properties to the attributes of style:text-properties
- * @const@type{Array.<!{propertyName:string,attributeName:string,unit:string}>}
- */
- textPropertyMapping = [
- {
- propertyName: 'fontSize',
- attributeName: 'fo:font-size',
- unit: 'pt'
- }, {
- propertyName: 'fontName',
- attributeName: 'style:font-name'
- }, {
- propertyName: 'color',
- attributeName: 'fo:color'
- }, {
- propertyName: 'backgroundColor',
- attributeName: 'fo:background-color'
- }, {
- propertyName: 'fontWeight',
- attributeName: 'fo:font-weight'
- }, {
- propertyName: 'fontStyle',
- attributeName: 'fo:font-style'
- }, {
- propertyName: 'underline',
- attributeName: 'style:text-underline-style'
- }, {
- propertyName: 'strikethrough',
- attributeName: 'style:text-line-through-style'
- }],
- /**
- * Mapping of the properties from edit pane properties to the attributes of style:paragraph-properties
- * @const@type{Array.<!{propertyName:string,attributeName:string,unit:string}>}
- */
- paragraphPropertyMapping = [
- {
- propertyName: 'topMargin',
- attributeName: 'fo:margin-top',
- unit: 'mm'
- }, {
- propertyName: 'bottomMargin',
- attributeName: 'fo:margin-bottom',
- unit: 'mm'
- }, {
- propertyName: 'leftMargin',
- attributeName: 'fo:margin-left',
- unit: 'mm'
- }, {
- propertyName: 'rightMargin',
- attributeName: 'fo:margin-right',
- unit: 'mm'
- }, {
- propertyName: 'textAlign',
- attributeName: 'fo:text-align'
- }],
- originalFontEffectsPaneValue,
- originalAlignmentPaneValue;
- /**
- * Sets attributes of a node by the properties of the object properties,
- * based on the mapping defined in propertyMapping.
- * @param {!Object} properties
- * @param {!Array.<!{propertyName:string,attributeName:string,unit:string}>} propertyMapping
- * @return {!Object}
- */
- function mappedProperties(properties, propertyMapping) {
- var i, m, value,
- result = {};
- for (i = 0; i < propertyMapping.length; i += 1) {
- m = propertyMapping[i];
- value = properties[m.propertyName];
- // Set a value as the attribute of a node, if that value is defined.
- // If there is a unit specified, it is suffixed to the value.
- if (value !== undefined) {
- result[m.attributeName] = (m.unit !== undefined) ? value + m.unit : value;
- }
- }
- return result;
- }
- /**
- * Returns an flat object containing only the key-value mappings
- * from the 'new' flat object which are different from the 'old' object's.
- * @param {!Object} oldProperties
- * @param {!Object} newProperties
- * @return {!Object}
- */
- function updatedProperties(oldProperties, newProperties) {
- var properties = {};
- Object.keys(newProperties).forEach(function (key) {
- if (newProperties[key] !== oldProperties[key]) {
- properties[key] = newProperties[key];
- }
- });
- return properties;
- }
- function accept() {
- editorSession.updateParagraphStyle(stylePicker.value(), {
- "style:paragraph-properties": mappedProperties(
- updatedProperties(originalAlignmentPaneValue, alignmentPane.value()),
- paragraphPropertyMapping
- ),
- "style:text-properties": mappedProperties(
- updatedProperties(originalFontEffectsPaneValue, fontEffectsPane.value()),
- textPropertyMapping
- )
- });
- dialog.hide();
- }
- function cancel() {
- dialog.hide();
- }
- function setStyle(value) {
- if (value !== stylePicker.value()) {
- stylePicker.setValue(value);
- }
- alignmentPane.setStyle(value);
- fontEffectsPane.setStyle(value);
- originalAlignmentPaneValue = alignmentPane.value();
- originalFontEffectsPaneValue = fontEffectsPane.value();
- // If it is a default (nameless) style or is used, make it undeletable.
- if (value === "" || editorSession.isStyleUsed(editorSession.getParagraphStyleElement(value))) {
- deleteButton.domNode.style.display = 'none';
- } else {
- deleteButton.domNode.style.display = 'block';
- }
- }
- /**
- * Creates and enqueues a paragraph-style cloning operation.
- * Remembers the id of the created style in newStyleName, so the
- * style picker can be set to it, once the operation has been applied.
- * @param {!string} styleName id of the style to clone
- * @param {!string} newStyleDisplayName display name of the new style
- */
- function cloneStyle(styleName, newStyleDisplayName) {
- var newStyleName = editorSession.cloneParagraphStyle(styleName, newStyleDisplayName);
- setStyle(newStyleName);
- }
- function deleteStyle(styleName) {
- editorSession.deleteStyle(styleName);
- }
- // Dialog
- dialog = new Dialog({
- title: tr("Paragraph Styles")
- });
- mainLayoutContainer = new LayoutContainer({
- style: "height: 520px; width: 450px;"
- });
- topBar = new ContentPane({
- region: "top",
- style: "margin: 0; padding: 0"
- });
- mainLayoutContainer.addChild(topBar);
- cloneTooltip = new TooltipDialog({
- content:
- '<h2 style="margin: 0;">'+tr("Clone this Style")+'</h2><br/>' +
- '<label for="name">'+tr("New Name:")+'</label> <input data-dojo-type="dijit/form/TextBox" id="name" name="name"><br/><br/>',
- style: "width: 300px;"
- });
- cloneButton = new Button({
- label: tr("Create"),
- onClick: function () {
- cloneStyle(stylePicker.value(), cloneTooltip.get('value').name);
- cloneTooltip.reset();
- popup.close(cloneTooltip);
- }
- });
- cloneTooltip.addChild(cloneButton);
- cloneDropDown = new DropDownButton({
- label: tr("Clone"),
- showLabel: false,
- iconClass: 'dijitEditorIcon dijitEditorIconCopy',
- dropDown: cloneTooltip,
- style: "float: right; margin-bottom: 5px;"
- });
- topBar.addChild(cloneDropDown, 1);
- deleteButton = new Button({
- label: tr("Delete"),
- showLabel: false,
- iconClass: 'dijitEditorIcon dijitEditorIconDelete',
- style: "float: right; margin-bottom: 5px;",
- onClick: function () {
- deleteStyle(stylePicker.value());
- }
- });
- topBar.addChild(deleteButton, 2);
- // Tab Container
- tabContainer = new TabContainer({
- region: "center"
- });
- mainLayoutContainer.addChild(tabContainer);
- actionBar = dojo.create("div", {
- "class": "dijitDialogPaneActionBar"
- });
- okButton = new dijit.form.Button({
- label: tr("OK"),
- onClick: accept
- }).placeAt(actionBar);
- cancelButton = new dijit.form.Button({
- label: tr("Cancel"),
- onClick: cancel
- }).placeAt(actionBar);
- dialog.domNode.appendChild(actionBar);
- require([
- "webodf/editor/widgets/paragraphStyles",
- "webodf/editor/widgets/dialogWidgets/alignmentPane",
- "webodf/editor/widgets/dialogWidgets/fontEffectsPane"
- ], function (ParagraphStyles, AlignmentPane, FontEffectsPane) {
- var p, a, f;
- p = new ParagraphStyles(function (paragraphStyles) {
- stylePicker = paragraphStyles;
- stylePicker.widget().startup();
- stylePicker.widget().domNode.style.float = "left";
- stylePicker.widget().domNode.style.width = "350px";
- stylePicker.widget().domNode.style.marginTop = "5px";
- topBar.addChild(stylePicker.widget(), 0);
- stylePicker.onRemove = function (name) {
- // The style picker automatically falls back
- // to the first entry if the currently selected
- // entry is deleted. So it is safe to simply
- // open the new auto-selected entry after removal.
- setStyle(stylePicker.value());
- };
- stylePicker.onChange = setStyle;
- stylePicker.setEditorSession(editorSession);
- });
- a = new AlignmentPane(function (pane) {
- alignmentPane = pane;
- alignmentPane.widget().startup();
- tabContainer.addChild(alignmentPane.widget());
- alignmentPane.setEditorSession(editorSession);
- });
- f = new FontEffectsPane(function (pane) {
- fontEffectsPane = pane;
- fontEffectsPane.widget().startup();
- tabContainer.addChild(fontEffectsPane.widget());
- fontEffectsPane.setEditorSession(editorSession);
- });
- dialog.onShow = function () {
- var currentStyle = editorSession.getCurrentParagraphStyle();
- setStyle(currentStyle);
- };
- dialog.onHide = self.onToolDone;
- });
- dialog.addChild(mainLayoutContainer);
- mainLayoutContainer.startup();
- return callback(dialog);
- });
- }
- this.setEditorSession = function(session) {
- editorSession = session;
- if (stylePicker) {
- stylePicker.setEditorSession(session);
- }
- if (alignmentPane) {
- alignmentPane.setEditorSession(session);
- }
- if (fontEffectsPane) {
- fontEffectsPane.setEditorSession(session);
- }
- if (!editorSession && dialog) { // TODO: check show state
- dialog.hide();
- }
- };
- this.onToolDone = function () {};
- // init
- makeWidget(function (dialog) {
- return callback(dialog);
- });
- };
- });
|