| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102 |
- /**
- * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved.
- *
- * This file is part of the QCAD project.
- *
- * QCAD is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * QCAD 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with QCAD.
- */
- include("scripts/library.js");
- include("scripts/map.js");
- include("scripts/WidgetFactory.js");
- include("CharacterMapDialog.js");
- /**
- * \class SymbolMenuData
- * \brief Helper class for symbol popup menu.
- * \ingroup ecma_draw_text
- */
- function SymbolMenuData(textWidget, data) {
- this.textWidget = textWidget;
- this.data = data;
- }
- SymbolMenuData.prototype.triggered = function() {
- var cursor = this.textWidget.textCursor();
- cursor.insertText(this.data);
- };
- /**
- * \class TextDialog
- * \brief Text creation or editing dialog.
- * \ingroup ecma_draw_text
- */
- function TextDialog(mode) {
- if (isNull(mode)) {
- mode = TextDialog.Mode.Text;
- }
- this.mode = mode;
- this.dialog = undefined;
- this.textEdit = undefined;
- this.sourceEdit = undefined;
- this.actionTextBold = undefined;
- this.actionTextItalic = undefined;
- this.actionTextUnderline = undefined;
- this.actionSubscript = undefined;
- this.actionSuperscript = undefined;
- this.actionTextColor = undefined;
- //this.actionZoomIn = undefined;
- //this.actionZoomOut = undefined;
-
- this.actionTextSymbol = undefined;
- this.actionUndo = undefined;
- this.actionRedo = undefined;
- this.actionCut = undefined;
- this.actionCopy = undefined;
- this.actionPaste = undefined;
- this.comboFont = undefined;
- this.comboSize = undefined;
- // display text in text edit with this factor, compared to drawing unit:
- this.fontHeightFactor = 10.0;
- this.mainFont = undefined;
- this.initialColor = new RColor();
- }
- TextDialog.prototype = {};
- TextDialog.Mode = {
- Text : 0,
- Attribute : 1,
- AttributeDefinition : 2
- };
- TextDialog.prototype.setMode = function(mode) {
- this.mode = mode;
- };
- TextDialog.prototype.getTextDocument = function() {
- if (RSettings.getQtVersion() >= 0x050000) {
- return this.textEdit.document;
- }
- else {
- return this.textEdit.document();
- }
- };
- TextDialog.prototype.getSourceDocument = function() {
- return this.sourceEdit.document();
- };
- TextDialog.prototype.show = function(textDataIn) {
- if (!isNull(textDataIn)) {
- if (isOfType(textDataIn, RAttributeData)) {
- this.mode = TextDialog.Mode.Attribute;
- }
- else if (isOfType(textDataIn, RAttributeDefinitionData)) {
- this.mode = TextDialog.Mode.AttributeDefinition;
- }
- else {
- this.mode = TextDialog.Mode.Text;
- }
- }
- this.dialog = WidgetFactory.createDialog(TextDialog.basePath, "TextDialog.ui", EAction.getMainWindow());
- // initialize dialog controls:
- this.textEdit = this.dialog.findChild("Text");
- this.sourceEdit = this.dialog.findChild("Source");
- this.tabWidget = this.dialog.findChild("TabWidget");
- // main font combo box:
- var comboMainFont = this.dialog.findChild("MainFont");
- var comboFont = this.dialog.findChild("Font");
- initFontComboBox(comboMainFont);
- initFontComboBox(comboFont);
- comboMainFont.currentFontChanged.connect(this, this.mainFontChanged);
- // main font height:
- var editMainHeight = this.dialog.findChild("MainHeight");
- editMainHeight.valueChanged.connect(this, this.mainFontChanged);
- // main font bold:
- var checkMainBold = this.dialog.findChild("MainBold");
- checkMainBold.toggled.connect(this, this.mainFontChanged);
- // main font italic:
- var checkMainItalic = this.dialog.findChild("MainItalic");
- checkMainItalic.toggled.connect(this, this.mainFontChanged);
- // default line spacing:
- //var checkBoxDefaultLineSpacing = this.dialog.findChild("DefaultLineSpacing");
- //checkBoxDefaultLineSpacing.toggled.connect(this, this.useDefaultLineSpacing);
- // line spacing:
- var editLineSpacingFactor = this.dialog.findChild("LineSpacingFactor");
- // angle:
- var editAngle = this.dialog.findChild("Angle");
- /*
- var buttonNew = this.dialog.findChild("New");
- buttonNew.clicked.connect(this.textEdit, "clear");
- var buttonOpen = this.dialog.findChild("Open");
- var buttonSaveAs = this.dialog.findChild("SaveAs");
- */
- this.setupEditActions();
- this.setupTextActions();
- // update status buttons bold / italic / underline:
- this.textEdit.currentCharFormatChanged.connect(this, this.currentCharFormatChanged);
- this.textEdit.cursorPositionChanged.connect(this, this.cursorPositionChanged);
- var td = this.getTextDocument();
- td.undoAvailable.connect(this.actionUndo, this.actionUndo.setEnabled);
- td.redoAvailable.connect(this.actionRedo, this.actionRedo.setEnabled);
- this.actionUndo.setEnabled(td.isUndoAvailable());
- this.actionRedo.setEnabled(td.isRedoAvailable());
- this.actionUndo.triggered.connect(this.textEdit, this.textEdit.undo);
- this.actionRedo.triggered.connect(this.textEdit, this.textEdit.redo);
- this.actionCut.setEnabled(false);
- this.actionCopy.setEnabled(false);
- this.actionCut.triggered.connect(this.textEdit, this.textEdit.cut);
- this.actionCopy.triggered.connect(this.textEdit, this.textEdit.copy);
- this.actionPaste.triggered.connect(this.textEdit, this.textEdit.paste);
- this.textEdit.copyAvailable.connect(this.actionCut, this.actionCut.setEnabled);
- this.textEdit.copyAvailable.connect(this.actionCopy, this.actionCopy.setEnabled);
- var cbSimpleText = this.dialog.findChild("SimpleText");
- cbSimpleText.toggled.connect(this, this.simpleTextToggled);
- var buttonTopLeft = this.dialog.findChild("AlignTopLeft");
- var buttonTopCenter = this.dialog.findChild("AlignTopCenter");
- var buttonTopRight = this.dialog.findChild("AlignTopRight");
- var buttonMiddleLeft = this.dialog.findChild("AlignMiddleLeft");
- var buttonMiddleCenter = this.dialog.findChild("AlignMiddleCenter");
- var buttonMiddleRight = this.dialog.findChild("AlignMiddleRight");
- var buttonBaseLeft = this.dialog.findChild("AlignBaseLeft");
- var buttonBaseCenter = this.dialog.findChild("AlignBaseCenter");
- var buttonBaseRight = this.dialog.findChild("AlignBaseRight");
- var buttonBottomLeft = this.dialog.findChild("AlignBottomLeft");
- var buttonBottomCenter = this.dialog.findChild("AlignBottomCenter");
- var buttonBottomRight = this.dialog.findChild("AlignBottomRight");
- getClipboard().dataChanged.connect(this, this.clipboardDataChanged);
- // change dialog into attribute / attribute definition dialog:
- if (this.mode === TextDialog.Mode.AttributeDefinition ||
- this.mode === TextDialog.Mode.Attribute) {
- this.dialog.findChild("Separator").visible = false;
- this.dialog.findChild("LineSpacingFactorLabel").visible = false;
- editLineSpacingFactor.visible = false;
- cbSimpleText.visible = false;
- this.tabWidget.removeTab(1);
- this.tabWidget.removeTab(0);
- this.dialog.resize(0,0);
- if (this.mode === TextDialog.Mode.AttributeDefinition) {
- this.dialog.windowTitle = entityTypeToString(RS.EntityAttributeDefinition, false);
- }
- else if (this.mode === TextDialog.Mode.Attribute) {
- this.dialog.windowTitle = entityTypeToString(RS.EntityAttribute, false);
- }
- }
- else {
- this.tabWidget.removeTab(2);
- }
- // sync rich text / source:
- this.tabWidget["currentChanged(int)"].connect(this, this.tabChanged);
- if (this.mode === TextDialog.Mode.AttributeDefinition) {
- this.dialog.findChild("ValueLabel").text = qsTr("Default value:");
- }
- // initialize dialog from given text data (textDataIn):
- if (!isNull(textDataIn)) {
- cbSimpleText.checked = textDataIn.isSimple();
- this.initialColor = textDataIn.getColor();
- activateFont(comboMainFont, textDataIn.getFontName());
- checkMainBold.checked = textDataIn.isBold();
- checkMainItalic.checked = textDataIn.isItalic();
- editMainHeight.setValue(textDataIn.getTextHeight());
- this.sourceEdit.setPlainText(textDataIn.getEscapedText());
- this.updateRichText(true);
- //qDebug("this.sourceEdit:", this.sourceEdit.plainText);
- if (textDataIn.getVAlign()==RS.VAlignTop) {
- if (textDataIn.getHAlign()==RS.HAlignLeft || textDataIn.getHAlign()==RS.HAlignFit || textDataIn.getHAlign()==RS.HAlignAlign) {
- buttonTopLeft.checked = true;
- }
- else if (textDataIn.getHAlign()==RS.HAlignCenter) {
- buttonTopCenter.checked = true;
- }
- else if (textDataIn.getHAlign()==RS.HAlignRight) {
- buttonTopRight.checked = true;
- }
- }
- else if (textDataIn.getVAlign()==RS.VAlignMiddle) {
- if (textDataIn.getHAlign()==RS.HAlignLeft || textDataIn.getHAlign()==RS.HAlignFit || textDataIn.getHAlign()==RS.HAlignAlign) {
- buttonMiddleLeft.checked = true;
- }
- else if (textDataIn.getHAlign()==RS.HAlignCenter || textDataIn.getHAlign()==RS.HAlignMid) {
- buttonMiddleCenter.checked = true;
- }
- else if (textDataIn.getHAlign()==RS.HAlignRight) {
- buttonMiddleRight.checked = true;
- }
- }
- else if (textDataIn.getVAlign()==RS.VAlignBase) {
- if (textDataIn.getHAlign()==RS.HAlignLeft || textDataIn.getHAlign()==RS.HAlignFit || textDataIn.getHAlign()==RS.HAlignAlign) {
- buttonBaseLeft.checked = true;
- }
- else if (textDataIn.getHAlign()==RS.HAlignCenter) {
- buttonBaseCenter.checked = true;
- }
- else if (textDataIn.getHAlign()==RS.HAlignRight) {
- buttonBaseRight.checked = true;
- }
- }
- else if (textDataIn.getVAlign()==RS.VAlignBottom) {
- if (textDataIn.getHAlign()==RS.HAlignLeft || textDataIn.getHAlign()==RS.HAlignFit || textDataIn.getHAlign()==RS.HAlignAlign) {
- buttonBottomLeft.checked = true;
- }
- else if (textDataIn.getHAlign()==RS.HAlignCenter) {
- buttonBottomCenter.checked = true;
- }
- else if (textDataIn.getHAlign()==RS.HAlignRight) {
- buttonBottomRight.checked = true;
- }
- }
- editLineSpacingFactor.setValue(textDataIn.getLineSpacingFactor());
- editAngle.setValue(textDataIn.getAngle());
- // init values specific to attributes / attribute definitions:
- if (this.mode === TextDialog.Mode.Attribute ||
- this.mode === TextDialog.Mode.AttributeDefinition) {
- this.dialog.findChild("AttributeTag").text = textDataIn.getTag();
- this.dialog.findChild("AttributeValue").text = textDataIn.getText();
- if (this.mode === TextDialog.Mode.AttributeDefinition) {
- this.dialog.findChild("AttributePrompt").text = textDataIn.getPrompt();
- }
- else {
- this.dialog.findChild("AttributePrompt").visible = false;
- this.dialog.findChild("PromptLabel").visible = false;
- this.dialog.findChild("AttributeTag").enabled = false;
- this.dialog.findChild("AttributeValue").selectAll();
- }
- }
- }
- else {
- WidgetFactory.restoreState(this.dialog);
- cbSimpleText.checked = RSettings.getBoolValue("TextDialog/SimpleText", false);
- // restore widgets that are not supported by WidgetFactory:
- var mainFontName = RSettings.getStringValue("TextDialog/MainFont", "Arial");
- var mainFontIndex = comboMainFont.findText(mainFontName);
- if (mainFontIndex>0) {
- comboMainFont.currentIndex = mainFontIndex;
- }
- this.sourceEdit.setPlainText(RSettings.getStringValue("TextDialog/Source", ""));
- this.updateRichText(true);
- var vAlignment = RSettings.getIntValue("TextDialog/VAlignment", RS.VAlignTop);
- var hAlignment = RSettings.getIntValue("TextDialog/HAlignment", RS.HAlignLeft);
- if (vAlignment==RS.VAlignTop) {
- if (hAlignment==RS.HAlignLeft || hAlignment==RS.HAlignFit || hAlignment==RS.HAlignAlign) {
- buttonTopLeft.checked = true;
- }
- else if (hAlignment==RS.HAlignCenter) {
- buttonTopCenter.checked = true;
- }
- else if (hAlignment==RS.HAlignRight) {
- buttonTopRight.checked = true;
- }
- }
- else if (vAlignment==RS.VAlignMiddle) {
- if (hAlignment==RS.HAlignLeft || hAlignment==RS.HAlignFit || hAlignment==RS.HAlignAlign) {
- buttonMiddleLeft.checked = true;
- }
- else if (hAlignment==RS.HAlignCenter) {
- buttonMiddleCenter.checked = true;
- }
- else if (hAlignment==RS.HAlignRight) {
- buttonMiddleRight.checked = true;
- }
- }
- else if (vAlignment==RS.VAlignBase) {
- if (hAlignment==RS.HAlignLeft || hAlignment==RS.HAlignFit || hAlignment==RS.HAlignAlign) {
- buttonBaseLeft.checked = true;
- }
- else if (hAlignment==RS.HAlignCenter) {
- buttonBaseCenter.checked = true;
- }
- else if (hAlignment==RS.HAlignRight) {
- buttonBaseRight.checked = true;
- }
- }
- else if (vAlignment==RS.VAlignBottom) {
- if (hAlignment==RS.HAlignLeft || hAlignment==RS.HAlignFit || hAlignment==RS.HAlignAlign) {
- buttonBottomLeft.checked = true;
- }
- else if (hAlignment==RS.HAlignCenter) {
- buttonBottomCenter.checked = true;
- }
- else if (hAlignment==RS.HAlignRight) {
- buttonBottomRight.checked = true;
- }
- }
- var di = EAction.getDocumentInterface();
- if (!isNull(di)) {
- // initial text color is current color (e.g. ByLayer, red, ..):
- this.initialColor = di.getCurrentColor();
- }
- else {
- // initial color is invalid (no document, never reached):
- this.initialColor = new RColor();
- debugger;
- }
- }
- this.mainFontChanged();
- this.colorChanged(this.textEdit.textColor());
- this.colorChanged(this.initialColor);
- if (cbSimpleText.checked) {
- this.sourceEdit.setFocus(Qt.OtherFocusReason);
- this.sourceEdit.selectAll();
- }
- else {
- this.textEdit.setFocus(Qt.OtherFocusReason);
- this.textEdit.selectAll();
- }
- this.currentCharFormatChanged(this.textEdit.currentCharFormat());
- //this.colorChanged();
- // exec text dialog:
- var res = this.dialog.exec();
- if (this.tabWidget.currentIndex===0) {
- this.updateSource(true);
- }
- if (RSettings.getQtVersion() >= 0x060000) {
- // disconnect clipboard from changed event handler:
- getClipboard().dataChanged.disconnect(this, this.clipboardDataChanged);
- }
- // analyze dialog input:
- var textDataOut;
- if (isNull(textDataIn)) {
- if (this.mode === TextDialog.Mode.Attribute) {
- textDataOut = new RAttributeData();
- }
- else if (this.mode === TextDialog.Mode.AttributeDefinition) {
- textDataOut = new RAttributeDefinitionData();
- }
- else {
- textDataOut = new RTextData();
- }
- }
- else {
- textDataOut = textDataIn;
- }
- textDataOut.setFontName(comboMainFont.currentFont.family());
- textDataOut.setBold(checkMainBold.checked);
- textDataOut.setItalic(checkMainItalic.checked);
- textDataOut.setTextHeight(editMainHeight.getValue());
- if (buttonTopLeft.checked || buttonTopCenter.checked || buttonTopRight.checked) {
- textDataOut.setVAlign(RS.VAlignTop);
- }
- else if (buttonMiddleLeft.checked || buttonMiddleCenter.checked || buttonMiddleRight.checked) {
- textDataOut.setVAlign(RS.VAlignMiddle);
- }
- else if (buttonBaseLeft.checked || buttonBaseCenter.checked || buttonBaseRight.checked) {
- textDataOut.setVAlign(RS.VAlignBase);
- }
- else if (buttonBottomLeft.checked || buttonBottomCenter.checked || buttonBottomRight.checked) {
- textDataOut.setVAlign(RS.VAlignBottom);
- }
- if (buttonTopLeft.checked || buttonMiddleLeft.checked || buttonBaseLeft.checked || buttonBottomLeft.checked) {
- textDataOut.setHAlign(RS.HAlignLeft);
- }
- else if (buttonTopCenter.checked || buttonMiddleCenter.checked || buttonBaseCenter.checked || buttonBottomCenter.checked) {
- textDataOut.setHAlign(RS.HAlignCenter);
- }
- else if (buttonTopRight.checked || buttonMiddleRight.checked || buttonBaseRight.checked || buttonBottomRight.checked) {
- textDataOut.setHAlign(RS.HAlignRight);
- }
- //textDataOut.setDrawingDirection();
- //textDataOut.setLineSpacingStyle();
- textDataOut.setLineSpacingFactor(editLineSpacingFactor.getValue());
- textDataOut.setAngle(editAngle.getValue());
- // init values specific to attributes / attribute definitions:
- if (this.mode === TextDialog.Mode.Attribute ||
- this.mode === TextDialog.Mode.AttributeDefinition) {
- textDataOut.setSimple(true);
- textDataOut.setTag(this.dialog.findChild("AttributeTag").text);
- if (this.mode === TextDialog.Mode.AttributeDefinition) {
- textDataOut.setPrompt(this.dialog.findChild("AttributePrompt").text);
- }
- textDataOut.setText(this.dialog.findChild("AttributeValue").text);
- }
- else {
- textDataOut.setSimple(cbSimpleText.checked);
- textDataOut.setText(this.sourceEdit.toPlainText());
- }
- WidgetFactory.saveState(this.dialog);
- // save state of unsupported widgets:
- RSettings.setValue("TextDialog/VAlignment", textDataOut.getVAlign());
- RSettings.setValue("TextDialog/HAlignment", textDataOut.getHAlign());
- RSettings.setValue("TextDialog/MainFont", textDataOut.getFontName());
- destr(this.dialog);
- EAction.activateMainWindow();
- if (res) {
- return textDataOut;
- }
- else {
- return undefined;
- }
- };
- TextDialog.basePath = includeBasePath;
- TextDialog.prototype.setupEditActions = function() {
- var a;
- a = this.actionUndo = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Undo.svg")), qsTr("&Undo"), this.dialog);
- a.shortcut = QKeySequence.Undo;
- this.dialog.findChild("Undo").setDefaultAction(a);
- a = this.actionRedo = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Redo.svg")), qsTr("&Redo"), this.dialog);
- a.shortcut = QKeySequence.Redo;
- this.dialog.findChild("Redo").setDefaultAction(a);
- a = this.actionCut = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Cut.svg")), qsTr("Cu&t"), this.dialog);
- a.shortcut = QKeySequence.Cut;
- this.dialog.findChild("Cut").setDefaultAction(a);
- a = this.actionCopy = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Copy.svg")), qsTr("&Copy"), this.dialog);
- a.shortcut = QKeySequence.Copy;
- this.dialog.findChild("Copy").setDefaultAction(a);
- a = this.actionPaste = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Paste.svg")), qsTr("&Paste"), this.dialog);
- a.shortcut = QKeySequence.Paste;
- this.dialog.findChild("Paste").setDefaultAction(a);
- this.actionPaste.setEnabled(!getClipboard().text().isEmpty());
- };
- TextDialog.prototype.setupTextActions = function() {
- this.actionTextBold = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Bold.svg")), qsTr("&Bold"), this.dialog);
- this.actionTextBold.shortcut = new QKeySequence("Ctrl+B");
- var bold = new QFont();
- bold.setBold(true);
- this.actionTextBold.font = bold;
- this.actionTextBold.triggered.connect(this, this.textBold);
- this.actionTextBold.checkable = true;
- this.dialog.findChild("Bold").setDefaultAction(this.actionTextBold);
- this.actionTextItalic = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Italic.svg")), qsTr("&Italic"), this.dialog);
- this.actionTextItalic.shortcut = new QKeySequence("Ctrl+I");
- var italic = new QFont();
- italic.setItalic(true);
- this.actionTextItalic.font = italic;
- this.actionTextItalic.triggered.connect(this, this.textItalic);
- this.actionTextItalic.checkable = true;
- this.dialog.findChild("Italic").setDefaultAction(this.actionTextItalic);
- this.actionTextUnderline = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Underline.svg")), qsTr("&Underline"), this.dialog);
- this.actionTextUnderline.shortcut = new QKeySequence("Ctrl+U");
- var underline = new QFont();
- underline.setUnderline(true);
- this.actionTextUnderline.font = underline;
- this.actionTextUnderline.triggered.connect(this, this.textUnderline);
- this.actionTextUnderline.checkable = true;
- this.dialog.findChild("Underline").setDefaultAction(this.actionTextUnderline);
- this.actionSubscript = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Subscript.svg")), qsTr("&Subscript"), this.dialog);
- this.actionSubscript.shortcut = new QKeySequence("Shift+Ctrl+B");
- this.actionSubscript.triggered.connect(this, this.textSubscript);
- this.actionSubscript.checkable = true;
- this.dialog.findChild("Subscript").setDefaultAction(this.actionSubscript);
- this.actionSuperscript = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Superscript.svg")), qsTr("&Superscript"), this.dialog);
- this.actionSuperscript.shortcut = new QKeySequence("Shift+Ctrl+P");
- this.actionSuperscript.triggered.connect(this, this.textSuperscript);
- this.actionSuperscript.checkable = true;
- this.dialog.findChild("Superscript").setDefaultAction(this.actionSuperscript);
- // this.actionZoomIn = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/ZoomIn.svg")), qsTr("Zoom &In"), this.dialog);
- // this.actionZoomIn.shortcut = new QKeySequence(Qt.ControlModifier | Qt.Key_Plus);
- // this.actionZoomIn.triggered.connect(this.textEdit, "zoomIn");
- // this.dialog.findChild("ZoomIn").setDefaultAction(this.actionZoomIn);
- // this.actionZoomOut = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/ZoomOut.svg")), qsTr("Zoom &Out"), this.dialog);
- // this.actionZoomOut.shortcut = new QKeySequence(Qt.ControlModifier | Qt.Key_Minus);
- // this.actionZoomOut.triggered.connect(this.textEdit, "zoomOut");
- // this.dialog.findChild("ZoomOut").setDefaultAction(this.actionZoomOut);
- var pix = new QPixmap(16, 16);
- pix.fill(new QColor(Qt.black));
- this.actionTextColor = new QAction(new QIcon(pix), qsTr("&Color..."), this.dialog);
- this.actionTextColor.triggered.connect(this, this.textColor);
- this.dialog.findChild("Color").setDefaultAction(this.actionTextColor);
- this.actionTextSymbol = new QAction(new QIcon(autoIconPath(TextDialog.basePath + "/Symbol.svg")), qsTr("&Special Characters..."), this.dialog);
- this.actionTextSymbol.triggered.connect(this, this.textSymbol);
- this.dialog.findChild("Symbol").setDefaultAction(this.actionTextSymbol);
-
- this.comboFont = this.dialog.findChild("Font");
- if (RSettings.getQtVersion() >= 0x060000) {
- this.comboFont.textActivated.connect(this, this.textFamily);
- }
- else {
- this.comboFont["activated(QString)"].connect(this, this.textFamily);
- }
- this.comboSize = this.dialog.findChild("Height");
- this.comboSize.editable = true;
- if (RSettings.getQtVersion() >= 0x060000) {
- this.comboSize.textActivated.connect(this, this.textSize);
- }
- else {
- this.comboSize["activated(QString)"].connect(this, this.textSize);
- }
- this.comboSize.setEditText("1.0");
- this.comboSize.editTextChanged.connect(this, this.textSize);
- };
- /**
- * \return Main font to use with main height set in in drawing units
- * as points. E.g. a font with point size 15.0 means the font height
- * is really 15 drawing units.
- */
- TextDialog.prototype.getMainFont = function() {
- // get main font with main height:
- var comboMainFont = this.dialog.findChild("MainFont");
- var font = comboMainFont.currentFont;
- var editMainHeight = this.dialog.findChild("MainHeight");
- var h = editMainHeight.getValue();
- if (isNumber(h) && h>0.0) {
- font.setPointSizeF(h);
- }
- var checkMainBold = this.dialog.findChild("MainBold");
- font.setBold(checkMainBold.checked);
- var checkMainItalic = this.dialog.findChild("MainItalic");
- font.setItalic(checkMainItalic.checked);
- return font;
- };
- /**
- * Called when user changes the main font (initial font for text).
- */
- TextDialog.prototype.mainFontChanged = function() {
- var font = this.getMainFont();
- if (font.pointSizeF()>RS.PointTolerance) {
- this.fontHeightFactor = RSettings.getDoubleValue("Text/PreviewFontSize", 14.0) / font.pointSizeF();
- }
- else {
- this.fontHeightFactor = 10.0;
- }
- if (this.tabWidget.currentIndex===1) {
- this.updateRichText(true);
- }
- var document = this.getTextDocument();
- var html = document.toHtml();
- // qDebug("\n\nmainFontChanged: html before fix: ", html, "\n\n");
- html = this.fixHtml(html);
- // qDebug("\n\nmainFontChanged: html after fix: ", html, "\n\n");
- var previousMainFont = this.mainFont;
- this.mainFont = font;
- font.setPointSizeF(font.pointSizeF() * this.fontHeightFactor);
- this.textEdit.font = font;
- document.defaultFont = font;
- //qDebug("\n\nHTML after setting default font: \n", html, "\n\n");
- // replace all fonts that matched the previous main font with new
- // main font. this is _most likely_ what the user expects:
- if (!isNull(previousMainFont)) {
- html.replace("font-family:'%1';".arg(previousMainFont.family()),
- "font-family:'%1';".arg(font.family()));
- }
- // qDebug("\n\nmainFontChanged: html after font replace: ", html, "\n\n");
- this.textEdit.setHtml(html);
- // qDebug("\n\nnew html: ", this.getTextDocument().toHtml(), "\n\n");
- this.updateSource(true);
- };
- TextDialog.prototype.fixHtml = function(html) {
- var font = this.getMainFont();
- //html = html.replace(/>[ ]*</, "><");
- var htmlNbsp = "";
- var cdata = false;
- for (var i=0; i<html.length; i++) {
- if (html[i]==='<') {
- cdata = false;
- }
- else if (html[i]==='>') {
- cdata = true;
- }
- // create nbsp from all spaces. QTextEdit will simplify white space
- // to one single space otherwise.
- else if (cdata && (html[i]===' ' || html[i]==='\u00A0')) {
- htmlNbsp += ' ';
- continue;
- }
- htmlNbsp += html[i];
- }
- // change font in HTML directly. changing default font of document
- // keeps content formatting by adding font style with previous
- // default font to all content:
- var dom = new QDomDocument();
- if (RSettings.getQtVersion()>=0x060500) {
- dom.setContent(htmlNbsp);
- }
- else {
- dom.setContent(htmlNbsp, false);
- }
- var docElem = dom.documentElement();
- //qDebug("initial font color: ", this.initialColor);
- var n = docElem.firstChild();
- while (!n.isNull()) {
- var e = n.toElement();
- if(!e.isNull()) {
- if (e.tagName().toLowerCase()==="body") {
- var qcol = this.initialColor.toCompat();
- var bodyStyle = ("font-family:'%1';" +
- "font-size:%2pt;" +
- "font-weight:%3;" +
- "font-style:%4;" +
- "color:%5;")
- .arg(font.family())
- .arg(font.pointSizeF() * this.fontHeightFactor)
- .arg(font.weight()<=QFont.Normal ? "normal" : "bold")
- .arg(font.italic() ? "italic" : "normal")
- .arg(qcol.name());
- // brighter background of text area in macOS dark mode:
- if (RSettings.hasDarkGuiBackground() && RS.getSystemId()==="osx") {
- bodyStyle += "background-color:#dddddd;";
- }
- e.setAttribute("style", bodyStyle);
- }
- }
- n = n.nextSibling();
- }
- return dom.toString(-1);
- };
- TextDialog.prototype.simpleTextToggled = function(enable) {
- if (this.mode!==TextDialog.Mode.Text) {
- return;
- }
- var editLineSpacingFactor = this.dialog.findChild("LineSpacingFactor");
- if (enable) {
- this.tabWidget.setTabEnabled(0, false);
- this.tabWidget.currentIndex = 1;
- editLineSpacingFactor.enabled = false;
- }
- else {
- this.tabWidget.setTabEnabled(0, true);
- this.tabWidget.currentIndex = 0;
- editLineSpacingFactor.enabled = true;
- }
- };
- TextDialog.prototype.mergeFormatOnWordOrSelection = function(format) {
- var cursor = this.textEdit.textCursor();
- if (!cursor.hasSelection()) {
- cursor.select(QTextCursor.WordUnderCursor);
- }
- cursor.mergeCharFormat(format);
- this.textEdit.mergeCurrentCharFormat(format);
- };
- /**
- * Called when user clicks bold button.
- */
- TextDialog.prototype.textBold = function() {
- var fmt = new QTextCharFormat();
- fmt.setFontWeight(this.actionTextBold.checked ? QFont.Bold : QFont.Normal);
- this.mergeFormatOnWordOrSelection(fmt);
- };
- /**
- * Called when user clicks italic button.
- */
- TextDialog.prototype.textItalic = function() {
- var fmt = new QTextCharFormat();
- fmt.setFontItalic(this.actionTextItalic.checked);
- this.mergeFormatOnWordOrSelection(fmt);
- };
- /**
- * Called when user clicks underline button.
- */
- TextDialog.prototype.textUnderline = function() {
- var fmt = new QTextCharFormat();
- fmt.setFontUnderline(this.actionTextUnderline.checked);
- this.mergeFormatOnWordOrSelection(fmt);
- };
- /**
- * Called when user clicks subscript button.
- */
- TextDialog.prototype.textSubscript = function() {
- var fmt = new QTextCharFormat();
- fmt.setVerticalAlignment(this.actionSubscript.checked ? QTextCharFormat.AlignSubScript : QTextCharFormat.AlignNormal);
- this.mergeFormatOnWordOrSelection(fmt);
- };
- /**
- * Called when user clicks superscript button.
- */
- TextDialog.prototype.textSuperscript = function() {
- var fmt = new QTextCharFormat();
- fmt.setVerticalAlignment(this.actionSuperscript.checked ? QTextCharFormat.AlignSuperScript : QTextCharFormat.AlignNormal);
- this.mergeFormatOnWordOrSelection(fmt);
- };
- /**
- * Called when user changes font.
- */
- TextDialog.prototype.textFamily = function(f) {
- var fmt = new QTextCharFormat();
- // Qt 5.13, 5.14, 5.15 bug: appends the font as fall-back instead of setting the font:
- //fmt.setFontFamily(f);
- fmt.setFontFamilies([f]);
- this.mergeFormatOnWordOrSelection(fmt);
- };
- /**
- * Called when user changes font size.
- */
- TextDialog.prototype.textSize = function(p) {
- var pointSize = parseFloat(p);
- if (pointSize > 0) {
- var fmt = new QTextCharFormat();
- fmt.setFontPointSize(pointSize * this.fontHeightFactor);
- this.mergeFormatOnWordOrSelection(fmt);
- }
- };
- /**
- * Called when user changes font color.
- */
- TextDialog.prototype.textColor = function() {
- var colorNameList = RColor.getNameList(false);
- var colorList = RColor.getColorList(false);
- if (colorNameList.length!==colorList.length) {
- qWarning("Not same number of colors as color names. Aborting...");
- return;
- }
- var menu = new QMenu(this.dialog);
- for (var i=0; i < colorNameList.length; ++i) {
- var label = colorNameList[i];
- var color = colorList[i];
- if (label==="---") {
- menu.addSeparator();
- }
- else {
- var action = menu.addAction(RColor.getIcon(color, new QSize(16,16)), label);
- action.setProperty("color", color);
- action.iconVisibleInMenu = true;
- }
- }
- var chosenAction = menu.exec(QCursor.pos());
- if (isNull(chosenAction)) {
- return;
- }
- var chosenColor = chosenAction.property("color");
- if (chosenColor.isValid()) {
- if (chosenColor.isByLayer()) {
- chosenColor = RColor.CompatByLayer;
- }
- else if (chosenColor.isByBlock()) {
- chosenColor = RColor.CompatByBlock;
- }
- else {
- chosenColor = new QColor(chosenColor.red(), chosenColor.green(), chosenColor.blue(), chosenColor.alpha());
- }
- }
- else {
- // custom color: show color dialog:
- chosenColor = QColorDialog.getColor(this.textEdit.textColor(), this.dialog);
- if (!chosenColor.isValid()) {
- // color dialog canceled:
- return;
- }
- }
- var fmt = new QTextCharFormat();
- fmt.setForeground(new QBrush(chosenColor));
- this.mergeFormatOnWordOrSelection(fmt);
- this.colorChanged(chosenColor);
- };
- /**
- * Called when user is about to insert a symbol (special character).
- */
- TextDialog.prototype.textSymbol = function() {
- var action;
-
- var menu = new QMenu(this.dialog);
-
- // common special characters
- var textWidget = this.dialog.findChild("Text");
- var charsMap = this.getSpecialCharsMap();
- var keys = charsMap.getKeys();
- for (var i = 0; i < keys.length; ++i) {
- var str = charsMap.get(keys[i])[0];
- var character = charsMap.get(keys[i])[1];
- action = menu.addAction(str + "\t" + character);
- var menuData = new SymbolMenuData(textWidget, character);
- action.triggered.connect(menuData, menuData.triggered);
- }
- // other characters
- menu.addSeparator();
- action = menu.addAction(qsTr("Others..."));
- action.triggered.connect(this, function(){
- var dlg = new CharacterMapDialog(this);
- dlg.show();
- });
-
- menu.exec(QCursor.pos());
- };
- /**
- * Character format under cursor changed. Update relevant controls.
- */
- TextDialog.prototype.currentCharFormatChanged = function(format) {
- this.fontChanged(format.font());
- this.colorChanged(format.foreground().color());
- this.actionSubscript.setChecked(format.verticalAlignment()==QTextCharFormat.AlignSubScript);
- this.actionSuperscript.setChecked(format.verticalAlignment()==QTextCharFormat.AlignSuperScript);
- };
- /**
- * Called when user changes the current font or the font under the cursor changed.
- */
- TextDialog.prototype.fontChanged = function(font) {
- activateFont(this.comboFont, font.family());
- this.comboSize.blockSignals(true);
- this.comboSize.setEditText("%1".arg(font.pointSizeF() / this.fontHeightFactor));
- this.comboSize.blockSignals(false);
- this.actionTextBold.setChecked(font.bold());
- this.actionTextItalic.setChecked(font.italic());
- this.actionTextUnderline.setChecked(font.underline());
- };
- /**
- * Called when user changes the current color or the color under the cursor changed.
- */
- TextDialog.prototype.colorChanged = function(c) {
- if (!RSettings.hasDarkGuiBackground()) {
- // make sure that very bright text is readable:
- if (c.lightness()>240) {
- var p = this.textEdit.palette;
- p.setColor(QPalette.Active, QPalette.Base, new QColor(Qt.lightGray));
- this.textEdit.palette = p;
- }
- }
- var pix = new QPixmap(16, 16);
- pix.fill(c);
- this.actionTextColor.icon = new QIcon(pix);
- };
- TextDialog.prototype.cursorPositionChanged = function() {
- //alignmentChanged(textEdit->alignment());
- };
- /**
- * Called to switch to default line spacing (factor 1.0).
- */
- /*
- TextDialog.prototype.useDefaultLineSpacing = function(checked) {
- var editLineSpacingFactor = this.dialog.findChild("LineSpacingFactor");
- if (checked) {
- editLineSpacingFactor.text = "1.0";
- }
- editLineSpacingFactor.enabled = !checked;
- };
- */
- /**
- * Called when clipboard text becomes available / unavailable.
- */
- TextDialog.prototype.clipboardDataChanged = function() {
- if (isDeleted(this.actionPaste)) {
- return;
- }
- this.actionPaste.setEnabled(!getClipboard().text().isEmpty());
- };
- TextDialog.prototype.tabChanged = function(index) {
- switch (index) {
- case 0:
- this.updateRichText(false);
- break;
- case 1:
- this.updateSource(false);
- break;
- }
- };
- /**
- * Updates the source based on the rich text edit.
- */
- TextDialog.prototype.updateSource = function(force) {
- if (this.getTextDocument().modified || force===true) {
- var html = this.textEdit.html;
- html = this.fixHtml(html);
- var textDocument = new QTextDocument();
- textDocument.setHtml(html);
- textDocument.defaultFont = this.getTextDocument().defaultFont;
- var cbSimpleText = this.dialog.findChild("SimpleText");
- var source = RTextBasedData.toEscapedText(textDocument, this.initialColor, this.fontHeightFactor, cbSimpleText.checked);
- //qDebug("source: \n\n", source, "\n\n");
- this.sourceEdit.setPlainText(source);
- this.getTextDocument().modified = false;
- }
- };
- /**
- * Updates the rich text edit based on the source.
- */
- TextDialog.prototype.updateRichText = function(force) {
- if (this.getSourceDocument().modified || force===true) {
- var source = this.getSourceDocument().toPlainText();
- source = source.replace("\n", "\\P");
- var richText = RTextBasedData.toRichText(source, this.getMainFont(), this.fontHeightFactor);
- //richText = richText.replace("<html>", "<html xmlns='http://www.w3.org/1999/xhtml' xml:space='preserve'>");
- //qDebug("richText: \n\n", richText, "\n\n");
- // TODO: preserve tabs (img with arrow?)
- this.textEdit.setHtml(richText);
- //qDebug("HTML from text edit: \n\n", this.textEdit.html, "\n\n");
- this.getSourceDocument().modified = false;
- }
- };
- //TextDialog.prototype.activateFont = function(fontComboBox, fontName) {
- // var index = fontComboBox.findText(fontName, Qt.MatchFixedString);
- // fontComboBox.setCurrentIndex(index);
- //};
- TextDialog.prototype.getSpecialCharsMap = function() {
- if (isNull(TextDialog.specialChars)) {
- TextDialog.specialChars = new Map();
- TextDialog.specialChars.put("degree", [ qsTr("Degree"), "\u00B0" ]);
- TextDialog.specialChars.put("plus_minus", [ qsTr("Plus-Minus"), "\u00B1" ]);
- //TextDialog.specialChars.put("diameter", [ qsTr("Diameter"), "\u2300" ]);
- TextDialog.specialChars.put("diameter", [ qsTr("Diameter"), "\u00F8" ]);
- TextDialog.specialChars.put("allmost_equal", [ qsTr("Almost equal"), "\u2248" ]);
- TextDialog.specialChars.put("multiplication", [ qsTr("Multiplication"), "\u00D7" ]);
- TextDialog.specialChars.put("division", [ qsTr("Division"), "\u00F7" ]);
- TextDialog.specialChars.put("delta", [ qsTr("Delta"), "\u0394" ]);
- TextDialog.specialChars.put("pi", [ qsTr("Pi"), "\u03C0" ]);
- TextDialog.specialChars.put("identity", [ qsTr("Identity"), "\u2261" ]);
- TextDialog.specialChars.put("not_equal", [ qsTr("Not equal"), "\u2260" ]);
- TextDialog.specialChars.put("ohm", [ qsTr("Ohm"), "\u2126" ]);
- TextDialog.specialChars.put("omega", [ qsTr("Omega"), "\u03A9" ]);
- TextDialog.specialChars.put("squared", [ qsTr("Squared"), "\u00B2" ]);
- TextDialog.specialChars.put("cubed", [ qsTr("Cubed"), "\u00B3" ]);
- TextDialog.specialChars.put("nbsp", [ qsTr("No-break space"), " " ]);
- }
- return TextDialog.specialChars;
- };
|