2
** Copyright (C) 2013 Jiří Procházka (Hobrasoft)
3
** Contact: http://www.hobrasoft.cz/
5
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
6
** Contact: http://www.qt-project.org/legal
8
** $QT_BEGIN_LICENSE:LGPL$
9
** GNU Lesser General Public License Usage
10
** This file is under the terms of the GNU Lesser General Public License
11
** version 2.1 as published by the Free Software Foundation and appearing
12
** in the file LICENSE.LGPL included in the packaging of this file.
13
** Please review the following information to ensure the
14
** GNU Lesser General Public License version 2.1 requirements
15
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
** In addition, as a special exception, Digia gives you certain additional
18
** rights. These rights are described in the Digia Qt LGPL Exception
19
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
24
/********************************
25
* includes changes by wandererfan@gmail.com
26
* for FreeCAD project https://www.freecad.org/
27
********************************/
29
#include "PreCompiled.h"
34
# include <QApplication>
37
# include <QColorDialog>
39
# include <QFileDialog>
40
# include <QFontDatabase>
41
# include <QImageReader>
42
# include <QInputDialog>
45
# include <QPlainTextEdit>
46
# include <QRegularExpression>
51
#include <App/Application.h>
52
#include <Base/Console.h>
53
#include <Base/Tools.h>
54
#include <Gui/FileDialog.h>
55
#include <Mod/TechDraw/App/Preferences.h>
57
#include "mrichtextedit.h"
58
#include "PreferencesGui.h"
61
using namespace TechDrawGui;
62
using namespace TechDraw;
64
MRichTextEdit::MRichTextEdit(QWidget *parent, QString textIn) : QWidget(parent) {
66
m_lastBlockList = nullptr;
67
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
68
f_textedit->setTabStopWidth(40);
70
f_textedit->setTabStopDistance(40);
72
// setDefFontSize(getDefFontSizeNum());
73
setDefFontSize(TechDrawGui::PreferencesGui::labelFontSizePX());
74
m_defFont = getDefFont().family();
75
f_textedit->setFont(getDefFont());
77
connect(f_save, &QToolButton::clicked,
78
this, &MRichTextEdit::onSave);
79
connect(f_exit, &QToolButton::clicked,
80
this, &MRichTextEdit::onExit);
82
connect(f_textedit, &MTextEdit::currentCharFormatChanged,
83
this, &MRichTextEdit::slotCurrentCharFormatChanged);
84
connect(f_textedit, &MTextEdit::cursorPositionChanged,
85
this, &MRichTextEdit::slotCursorPositionChanged);
86
connect(f_textedit, &MTextEdit::selectionChanged,
87
this, &MRichTextEdit::onSelectionChanged);
90
m_fontsize_h1 = m_defFontSize + 8;
91
m_fontsize_h2 = m_defFontSize + 6;
92
m_fontsize_h3 = m_defFontSize + 4;
93
m_fontsize_h4 = m_defFontSize + 2;
95
//TODO: should check for existing text and set font to match
96
fontChanged(getDefFont());
97
bgColorChanged(f_textedit->textColor());
99
// paragraph formatting
100
m_paragraphItems << tr("Standard")
106
<< QString::fromUtf8(" ");
107
f_paragraph->addItems(m_paragraphItems);
109
connect(f_paragraph, qOverload<int>(&QComboBox::activated),
110
this, &MRichTextEdit::textStyle);
114
f_undo->setShortcut(QKeySequence::Undo);
115
f_redo->setShortcut(QKeySequence::Redo);
117
connect(f_textedit->document(), &QTextDocument::undoAvailable,
118
f_undo, &QToolButton::setEnabled);
119
connect(f_textedit->document(), &QTextDocument::redoAvailable,
120
f_redo, &QToolButton::setEnabled);
122
f_undo->setEnabled(f_textedit->document()->isUndoAvailable());
123
f_redo->setEnabled(f_textedit->document()->isRedoAvailable());
125
connect(f_undo, &QToolButton::clicked, f_textedit, &MTextEdit::undo);
126
connect(f_redo, &QToolButton::clicked, f_textedit, &MTextEdit::redo);
130
f_cut->setShortcut(QKeySequence::Cut);
131
f_copy->setShortcut(QKeySequence::Copy);
132
f_paste->setShortcut(QKeySequence::Paste);
134
f_cut->setEnabled(false);
135
f_copy->setEnabled(false);
137
connect(f_cut, &QToolButton::clicked, f_textedit, &MTextEdit::cut);
138
connect(f_copy, &QToolButton::clicked, f_textedit, &MTextEdit::copy);
139
connect(f_paste, &QToolButton::clicked, f_textedit, &MTextEdit::paste);
141
connect(f_textedit, &MTextEdit::copyAvailable, f_cut, &QToolButton::setEnabled);
142
connect(f_textedit, &MTextEdit::copyAvailable, f_copy, &QToolButton::setEnabled);
144
#ifndef QT_NO_CLIPBOARD
145
connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &MRichTextEdit::slotClipboardDataChanged);
150
f_link->setShortcut(QKeySequence(QString::fromUtf8("CTRL+L")));
152
connect(f_link, &QToolButton::clicked, this, &MRichTextEdit::textLink);
154
// bold, italic & underline
156
f_bold->setShortcut(QKeySequence(QString::fromUtf8("CTRL+B")));
157
f_italic->setShortcut(QKeySequence(QString::fromUtf8("CTRL+I")));
158
f_underline->setShortcut(QKeySequence(QString::fromUtf8("CTRL+U")));
160
connect(f_bold, &QToolButton::clicked, this, &MRichTextEdit::textBold);
161
connect(f_italic, &QToolButton::clicked, this, &MRichTextEdit::textItalic);
162
connect(f_underline, &QToolButton::clicked, this, &MRichTextEdit::textUnderline);
163
connect(f_strikeout, &QToolButton::clicked, this, &MRichTextEdit::textStrikeout);
165
QAction *removeFormat = new QAction(tr("Remove character formatting"), this);
166
removeFormat->setShortcut(QKeySequence(QString::fromUtf8("CTRL+M")));
167
connect(removeFormat, &QAction::triggered, this, &MRichTextEdit::textRemoveFormat);
168
f_textedit->addAction(removeFormat);
170
QAction *removeAllFormat = new QAction(tr("Remove all formatting"), this);
171
connect(removeAllFormat, &QAction::triggered, this, &MRichTextEdit::textRemoveAllFormat);
172
f_textedit->addAction(removeAllFormat);
174
QAction *textsource = new QAction(tr("Edit document source"), this);
175
textsource->setShortcut(QKeySequence(QString::fromUtf8("CTRL+O")));
176
connect(textsource, &QAction::triggered, this, &MRichTextEdit::textSource);
177
f_textedit->addAction(textsource);
179
QMenu *menu = new QMenu(this);
180
menu->addAction(removeAllFormat);
181
menu->addAction(removeFormat);
182
menu->addAction(textsource);
183
f_menu->setMenu(menu);
184
f_menu->setPopupMode(QToolButton::InstantPopup);
188
f_list_bullet->setShortcut(QKeySequence(QString::fromUtf8("CTRL+-")));
189
f_list_ordered->setShortcut(QKeySequence(QString::fromUtf8("CTRL+=")));
191
connect(f_list_bullet, &QToolButton::clicked, this, &MRichTextEdit::listBullet);
192
connect(f_list_ordered, &QToolButton::clicked, this, &MRichTextEdit::listOrdered);
196
f_indent_dec->setShortcut(QKeySequence(QString::fromUtf8("CTRL+, ")));
197
f_indent_inc->setShortcut(QKeySequence(QString::fromUtf8("CTRL+.")));
199
connect(f_indent_inc, &QToolButton::clicked, this, &MRichTextEdit::increaseIndentation);
200
connect(f_indent_dec, &QToolButton::clicked, this, &MRichTextEdit::decreaseIndentation);
204
const auto sizes = QFontDatabase::standardSizes();
205
for(int size: sizes) {
206
f_fontsize->addItem(QString::number(size));
208
//TODO: void QComboBox::setEditText(const QString &text) to " " when multiple select
209
#if QT_VERSION < QT_VERSION_CHECK(5,15,0)
210
connect(f_fontsize, qOverload<const QString&>(&QComboBox::currentIndexChanged),
211
this, &MRichTextEdit::textSize);
213
connect(f_fontsize, qOverload<int>(&QComboBox::currentIndexChanged), this, [=](int index) {
214
textSize(f_fontsize->itemText(index));
218
// text foreground color
220
connect(f_fgcolor, &QToolButton::clicked, this, &MRichTextEdit::textFgColor);
222
// text background color
224
connect(f_bgcolor, &QToolButton::clicked, this, &MRichTextEdit::textBgColor);
227
connect(f_image, &QToolButton::clicked, this, &MRichTextEdit::insertImage);
229
//set initial font size when editing existing text
230
if (!textIn.isEmpty()) {
231
//insert existing text with cursor at beginning
232
QTextCursor cursor = f_textedit->textCursor();
233
cursor.movePosition(QTextCursor::Start);
234
cursor.insertHtml(textIn);
235
cursor.movePosition(QTextCursor::Start);
236
f_textedit->setTextCursor(cursor);
238
//set current font size to match inserted text at cursor pos
239
QTextCharFormat fmt = cursor.charFormat();
240
double currSize = fmt.fontPointSize();
241
int intSize = round(currSize);
242
QString qsSize = QString::number(intSize);
244
int fSize = f_fontsize->findText(qsSize);
245
f_fontsize ->setCurrentIndex(fSize);
247
QTextCursor cursor = f_textedit->textCursor();
248
cursor.movePosition(QTextCursor::Start);
249
f_textedit->setTextCursor(cursor);
251
QTextCharFormat fmt = cursor.charFormat();
252
fmt.setFontPointSize(getDefFontSizeNum());
254
addFontSize(getDefFontSize());
256
f_fontsize->setCurrentIndex(f_fontsize->findText(getDefFontSize()));
262
void MRichTextEdit::textSource() {
263
QDialog *dialog = new QDialog(this);
264
QPlainTextEdit *pte = new QPlainTextEdit(dialog);
265
pte->setPlainText( f_textedit->toHtml() );
266
QGridLayout *gl = new QGridLayout(dialog);
267
gl->addWidget(pte, 0,0, 1,1);
268
dialog->setWindowTitle(tr("Document source"));
269
dialog->setMinimumWidth (400);
270
dialog->setMinimumHeight(600);
273
f_textedit->setHtml(pte->toPlainText());
279
void MRichTextEdit::textRemoveFormat() {
281
fmt.setFontWeight(QFont::Normal);
282
fmt.setFontUnderline (false);
283
fmt.setFontStrikeOut (false);
284
fmt.setFontItalic (false);
285
fmt.setFontPointSize (m_defFontSize);
286
// fmt.setFontFamily ("Helvetica");
287
// fmt.setFontStyleHint (QFont::SansSerif);
288
// fmt.setFontFixedPitch (true);
290
f_bold ->setChecked(false);
291
f_underline ->setChecked(false);
292
f_italic ->setChecked(false);
293
f_strikeout ->setChecked(false);
294
f_fontsize ->setCurrentIndex(f_fontsize->findText(getDefFontSize()));
296
// QTextBlockFormat bfmt = cursor.blockFormat();
297
// bfmt->setIndent(0);
299
fmt.clearBackground();
301
mergeFormatOnWordOrSelection(fmt);
305
void MRichTextEdit::textRemoveAllFormat() {
306
f_bold ->setChecked(false);
307
f_underline ->setChecked(false);
308
f_italic ->setChecked(false);
309
f_strikeout ->setChecked(false);
310
f_fontsize ->setCurrentIndex(f_fontsize->findText(getDefFontSize()));
311
QString text = f_textedit->toPlainText();
312
f_textedit->setPlainText(text);
316
void MRichTextEdit::textBold() {
318
fmt.setFontWeight(f_bold->isChecked() ? QFont::Bold : QFont::Normal);
319
mergeFormatOnWordOrSelection(fmt);
323
void MRichTextEdit::focusInEvent(QFocusEvent *) {
324
f_textedit->setFocus(Qt::TabFocusReason);
327
void MRichTextEdit::keyPressEvent(QKeyEvent *event) {
328
if (event->key() == Qt::Key_Return && event->modifiers() == Qt::ControlModifier) {
333
QWidget::keyPressEvent(event);
337
void MRichTextEdit::textUnderline() {
339
fmt.setFontUnderline(f_underline->isChecked());
340
mergeFormatOnWordOrSelection(fmt);
343
void MRichTextEdit::textItalic() {
345
fmt.setFontItalic(f_italic->isChecked());
346
mergeFormatOnWordOrSelection(fmt);
349
void MRichTextEdit::textStrikeout() {
351
fmt.setFontStrikeOut(f_strikeout->isChecked());
352
mergeFormatOnWordOrSelection(fmt);
355
void MRichTextEdit::textSize(const QString &pointsAsString) {
356
// qDebug() << "MRTE::textSize(" << p << ")";
357
qreal pointSize = pointsAsString.toFloat();
358
if (pointsAsString.toFloat() > 0) {
360
fmt.setFontPointSize(pointSize);
361
mergeFormatOnWordOrSelection(fmt);
365
void MRichTextEdit::textLink(bool checked) {
369
QString url = f_textedit->currentCharFormat().anchorHref();
371
QString newUrl = QInputDialog::getText(this, tr("Create a link"),
372
tr("Link URL:"), QLineEdit::Normal,
375
Qt::MSWindowsFixedSizeDialogHint);
378
fmt.setAnchorHref(newUrl);
379
fmt.setForeground(QApplication::palette().color(QPalette::Link));
380
fmt.setFontUnderline(true);
388
fmt.setAnchor(false);
389
fmt.setForeground(QApplication::palette().color(QPalette::Text));
390
fmt.setFontUnderline(false);
392
mergeFormatOnWordOrSelection(fmt);
395
void MRichTextEdit::textStyle(int index) {
396
//TODO: would prefer select font vs paragraph style.
397
QTextCursor cursor = f_textedit->textCursor();
398
cursor.beginEditBlock();
401
if (!cursor.hasSelection()) {
402
cursor.select(QTextCursor::BlockUnderCursor);
405
cursor.setCharFormat(fmt);
406
f_textedit->setCurrentCharFormat(fmt);
408
if (index == ParagraphHeading1
409
|| index == ParagraphHeading2
410
|| index == ParagraphHeading3
411
|| index == ParagraphHeading4 ) {
412
if (index == ParagraphHeading1) {
413
fmt.setFontPointSize(m_fontsize_h1);
415
if (index == ParagraphHeading2) {
416
fmt.setFontPointSize(m_fontsize_h2);
418
if (index == ParagraphHeading3) {
419
fmt.setFontPointSize(m_fontsize_h3);
421
if (index == ParagraphHeading4) {
422
fmt.setFontPointSize(m_fontsize_h4);
424
if (index == ParagraphHeading2 || index == ParagraphHeading4) {
425
fmt.setFontItalic(true);
428
fmt.setFontWeight(QFont::Bold);
430
if (index == ParagraphMonospace) {
431
fmt = cursor.charFormat();
432
#if QT_VERSION < QT_VERSION_CHECK(5,13,0)
433
fmt.setFontFamily(QString::fromUtf8("Monospace"));
435
fmt.setFontFamilies(QStringList() << QString::fromUtf8("Monospace"));
437
fmt.setFontStyleHint(QFont::Monospace);
438
fmt.setFontFixedPitch(true);
440
cursor.setCharFormat(fmt);
441
f_textedit->setCurrentCharFormat(fmt);
443
cursor.endEditBlock();
446
void MRichTextEdit::textFgColor() {
448
if (Gui::DialogOptions::dontUseNativeColorDialog()){
449
col = QColorDialog::getColor(f_textedit->textColor(), this, QLatin1String(""), QColorDialog::DontUseNativeDialog);
451
col = QColorDialog::getColor(f_textedit->textColor(), this);
453
QTextCursor cursor = f_textedit->textCursor();
454
if (!cursor.hasSelection()) {
455
cursor.select(QTextCursor::WordUnderCursor);
457
QTextCharFormat fmt = cursor.charFormat();
459
fmt.setForeground(col);
461
fmt.clearForeground();
463
cursor.setCharFormat(fmt);
464
f_textedit->setCurrentCharFormat(fmt);
468
void MRichTextEdit::textBgColor() {
470
if (Gui::DialogOptions::dontUseNativeColorDialog()){
471
col = QColorDialog::getColor(f_textedit->textBackgroundColor(), this, QLatin1String(""), QColorDialog::DontUseNativeDialog);
473
col = QColorDialog::getColor(f_textedit->textBackgroundColor(), this);
475
QTextCursor cursor = f_textedit->textCursor();
476
if (!cursor.hasSelection()) {
477
cursor.select(QTextCursor::WordUnderCursor);
479
QTextCharFormat fmt = cursor.charFormat();
481
fmt.setBackground(col);
483
fmt.clearBackground();
485
cursor.setCharFormat(fmt);
486
f_textedit->setCurrentCharFormat(fmt);
490
void MRichTextEdit::listBullet(bool checked) {
492
f_list_ordered->setChecked(false);
494
list(checked, QTextListFormat::ListDisc);
497
void MRichTextEdit::listOrdered(bool checked) {
499
f_list_bullet->setChecked(false);
501
list(checked, QTextListFormat::ListDecimal);
504
void MRichTextEdit::list(bool checked, QTextListFormat::Style style) {
505
QTextCursor cursor = f_textedit->textCursor();
506
cursor.beginEditBlock();
508
QTextBlockFormat obfmt = cursor.blockFormat();
509
QTextBlockFormat bfmt;
510
bfmt.setIndent(obfmt.indent());
511
cursor.setBlockFormat(bfmt);
513
QTextListFormat listFmt;
514
if (cursor.currentList()) {
515
listFmt = cursor.currentList()->format();
517
listFmt.setStyle(style);
518
cursor.createList(listFmt);
520
cursor.endEditBlock();
523
void MRichTextEdit::mergeFormatOnWordOrSelection(const QTextCharFormat &format) {
524
QTextCursor cursor = f_textedit->textCursor();
525
if (!cursor.hasSelection()) {
526
cursor.select(QTextCursor::WordUnderCursor);
528
cursor.mergeCharFormat(format);
529
f_textedit->mergeCurrentCharFormat(format);
530
f_textedit->setFocus(Qt::TabFocusReason);
533
void MRichTextEdit::slotCursorPositionChanged() {
534
// qDebug() << "MRTE::slotCursorPositionChanged()";
535
//why do we change text style when selecting text?
536
QTextCursor cursor = f_textedit->textCursor();
537
if (cursor.hasSelection()) { //let selection logic handle this
540
//set font size widget to match curr char size
541
QTextCharFormat fmt = cursor.charFormat();
542
double currSize = fmt.fontPointSize();
543
int fSize = f_fontsize->findText(QString::number(currSize));
544
f_fontsize ->setCurrentIndex(fSize);
546
QTextList *l = f_textedit->textCursor().currentList();
548
if (m_lastBlockList &&
549
(l == m_lastBlockList ||
550
(l && m_lastBlockList && l->format().style() == m_lastBlockList->format().style()) ) ) {
555
QTextListFormat lfmt = l->format();
556
if (lfmt.style() == QTextListFormat::ListDisc) {
557
f_list_bullet->setChecked(true);
558
f_list_ordered->setChecked(false);
559
} else if (lfmt.style() == QTextListFormat::ListDecimal) {
560
f_list_bullet->setChecked(false);
561
f_list_ordered->setChecked(true);
563
f_list_bullet->setChecked(false);
564
f_list_ordered->setChecked(false);
567
f_list_bullet->setChecked(false);
568
f_list_ordered->setChecked(false);
572
void MRichTextEdit::fontChanged(const QFont &font) {
573
// qDebug() << "MRTE::fontChanged()";
574
//TODO: change this to real font selector
575
f_fontsize->setCurrentIndex(f_fontsize->findText(QString::number(font.pointSize())));
576
f_bold->setChecked(font.bold());
577
f_italic->setChecked(font.italic());
578
f_underline->setChecked(font.underline());
579
f_strikeout->setChecked(font.strikeOut());
580
if (font.pointSize() == m_fontsize_h1) {
581
f_paragraph->setCurrentIndex(ParagraphHeading1);
582
} else if (font.pointSize() == m_fontsize_h2) {
583
f_paragraph->setCurrentIndex(ParagraphHeading2);
584
} else if (font.pointSize() == m_fontsize_h3) {
585
f_paragraph->setCurrentIndex(ParagraphHeading3);
586
} else if (font.pointSize() == m_fontsize_h4) {
587
f_paragraph->setCurrentIndex(ParagraphHeading4);
589
if (font.fixedPitch() && font.family() == QString::fromUtf8("Monospace")) {
590
f_paragraph->setCurrentIndex(ParagraphMonospace);
592
f_paragraph->setCurrentIndex(ParagraphStandard);
595
if (f_textedit->textCursor().currentList()) {
596
QTextListFormat lfmt = f_textedit->textCursor().currentList()->format();
597
if (lfmt.style() == QTextListFormat::ListDisc) {
598
f_list_bullet->setChecked(true);
599
f_list_ordered->setChecked(false);
600
} else if (lfmt.style() == QTextListFormat::ListDecimal) {
601
f_list_bullet->setChecked(false);
602
f_list_ordered->setChecked(true);
604
f_list_bullet->setChecked(false);
605
f_list_ordered->setChecked(false);
608
f_list_bullet->setChecked(false);
609
f_list_ordered->setChecked(false);
613
void MRichTextEdit::fgColorChanged(const QColor &color) {
614
QSize iconSize(16, 16);
615
QIcon fgIcon = f_fgcolor->icon();
616
QPixmap fgPix = fgIcon.pixmap(iconSize, QIcon::Mode::Normal, QIcon::State::On);
617
QPixmap filler(iconSize);
618
if (color.isValid() ) {
620
filler.setMask(fgPix.createMaskFromColor(Qt::transparent, Qt::MaskInColor) );
621
f_fgcolor->setIcon(filler);
625
void MRichTextEdit::bgColorChanged(const QColor &color) {
626
QSize iconSize(16, 16);
627
QIcon bgIcon = f_bgcolor->icon();
628
QPixmap bgPix = bgIcon.pixmap(iconSize, QIcon::Mode::Normal, QIcon::State::On);
629
QPixmap filler(iconSize);
630
if (color.isValid() ) {
632
filler.setMask(bgPix.createMaskFromColor(Qt::transparent, Qt::MaskOutColor) );
633
f_bgcolor->setIcon(filler);
637
void MRichTextEdit::slotCurrentCharFormatChanged(const QTextCharFormat &format) {
638
// qDebug() << "MRTE::slotCurrentCharFormatChanged()";
640
//again, why do we do all this just because the cursor moved?
641
//can it be this simple???
642
// fontChanged(format.font());
643
// bgColorChanged((format.background().isOpaque()) ? format.background().color() : QColor());
644
// fgColorChanged((format.foreground().isOpaque()) ? format.foreground().color() : QColor());
645
// f_link->setChecked(format.isAnchor());
648
void MRichTextEdit::slotClipboardDataChanged() {
649
#ifndef QT_NO_CLIPBOARD
650
if (const QMimeData *md = QApplication::clipboard()->mimeData())
651
f_paste->setEnabled(md->hasText());
655
QString MRichTextEdit::toHtml() const {
656
QString s = f_textedit->toHtml();
657
// convert emails to links
658
s = s.replace(QRegularExpression(
659
QString::fromUtf8("(<[^a][^>]+>(?:<span[^>]+>)?|\\s)([a-zA-Z\\d]+@[a-zA-Z\\d]+\\.[a-zA-Z]+)")),
660
QString::fromUtf8("\\1<a href=\"mailto:\\2\">\\2</a>"));
662
s = s.replace(QRegularExpression(
663
QString::fromUtf8("(<[^a][^>]+>(?:<span[^>]+>)?|\\s)((?:https?|ftp|file)://[^\\s'\"<>]+)")),
664
QString::fromUtf8( "\\1<a href=\"\\2\">\\2</a>"));
665
// see also: Utils::linkify()
669
void MRichTextEdit::increaseIndentation() {
673
void MRichTextEdit::decreaseIndentation() {
677
void MRichTextEdit::indent(int delta) {
678
QTextCursor cursor = f_textedit->textCursor();
679
cursor.beginEditBlock();
680
QTextBlockFormat bfmt = cursor.blockFormat();
681
int ind = bfmt.indent();
682
if (ind + delta >= 0) {
683
bfmt.setIndent(ind + delta);
685
cursor.setBlockFormat(bfmt);
686
cursor.endEditBlock();
689
void MRichTextEdit::setText(const QString& text) {
690
if (text.isEmpty()) {
694
if (text[0] == QChar::fromLatin1('<')) {
701
void MRichTextEdit::insertImage() {
703
QString attdir = s.value(QString::fromUtf8("general/filedialog-path")).toString();
704
QString file = QFileDialog::getOpenFileName(this,
705
tr("Select an image"),
707
tr("JPEG (*.jpg);; GIF (*.gif);; PNG (*.png);; BMP (*.bmp);; All (*)"));
708
QImage image = QImageReader(file).read();
710
f_textedit->dropImage(image,
711
QFileInfo(file).suffix().toUpper());
714
void MRichTextEdit::onSave()
716
QString result = toHtml();
717
Q_EMIT saveText(result);
720
void MRichTextEdit::onExit()
722
Q_EMIT editorFinished();
725
void MRichTextEdit::onSelectionChanged()
727
// qDebug() << "MRTE::onSelectionChanged()";
728
if (hasMultipleSizes()) {
729
f_fontsize->setEditText(QString());
730
f_fontsize->setCurrentIndex(-1);
732
QTextCursor cursor = f_textedit->textCursor();
733
QTextCharFormat fmt = cursor.charFormat();
734
double currSize = fmt.fontPointSize();
735
int fSize = f_fontsize->findText(QString::number(currSize));
736
f_fontsize ->setCurrentIndex(fSize);
740
//does selection have multiple sizes?
741
bool MRichTextEdit::hasMultipleSizes()
743
// qDebug() << "MRTE::hasMultipleSizes()";
744
QTextCursor cursor = f_textedit->textCursor();
745
if (cursor.hasSelection()) {
746
int begin = cursor.selectionStart();
747
int end = cursor.selectionEnd();
749
std::vector<QString> foundSizes;
750
std::map<QString, int> countMap;
751
for (currPos = begin; currPos < end; currPos++) {
752
cursor.setPosition(currPos);
753
QTextCharFormat fmt = cursor.charFormat();
754
double currSize = fmt.fontPointSize();
755
QString asQS = QString::number(currSize, 'f', 2);
756
foundSizes.push_back(asQS);
757
auto ret = countMap.insert(std::pair<QString, int>(asQS, 1));
758
if (!ret.second) { //already have this size
759
ret.first->second++; //bump count
762
if (countMap.size() > 1) {
769
void MRichTextEdit::setDefFontSize(int fontSize)
771
// Base::Console().Message("MRTE::setDefFontSize(%d)\n", fs);
772
m_defFontSize = fontSize;
773
m_fontsize_h1 = fontSize + 8;
774
m_fontsize_h2 = fontSize + 6;
775
m_fontsize_h3 = fontSize + 4;
776
m_fontsize_h4 = fontSize + 2;
778
QString newSize = QString::number(fontSize);
779
f_fontsize->findText(newSize);
780
int idx = f_fontsize->findText(newSize);
782
f_fontsize->setCurrentIndex(idx);
784
f_fontsize->setCurrentIndex(0);
789
int MRichTextEdit::getDefFontSizeNum()
791
// Base::Console().Message("MRTE::getDefFontSizeNum()\n");
792
double fontSize = TechDraw::Preferences::dimFontSizeMM();
794
//this conversion is only approximate. the factor changes for different fonts.
795
// double mmToPts = 2.83; //theoretical value
796
double mmToPts = 2.00; //practical value. seems to be reasonable for common fonts.
798
return round(fontSize * mmToPts);
801
QString MRichTextEdit::getDefFontSize()
803
// Base::Console().Message("MRTE::getDefFontSize()\n");
804
return QString::number(getDefFontSizeNum());
808
void MRichTextEdit::setDefFont(QString fontName)
810
m_defFont = fontName;
813
QFont MRichTextEdit::getDefFont()
815
QString family = Base::Tools::fromStdString(Preferences::labelFont());
818
result.setFamily(family);
822
// add a new fontSize to the list
823
// this seems like massive overkill for integer point<->mm conversion factor
824
// if the conversion factor is float, will generate non-standard sizes
825
void MRichTextEdit::addFontSize(QString fontSize)
827
// Base::Console().Message("MRTE::addFontSize(%s)\n", qPrintable(fs));
829
int fsVal = fontSize.toInt();
830
int size = f_fontsize->count();
832
for (int i = 0; i < size; i++) {
833
QString item = f_fontsize->itemText(i);
834
int itemVal = item.toInt();
839
if (itemVal < fsVal) {
841
} else if (itemVal == fsVal) { // already in list
844
} else { //item > fs, add both
850
if (!added) { //bigger than all choices, add to end of list
854
f_fontsize->addItems(newList);
857
#include <Mod/TechDraw/Gui/moc_mrichtextedit.cpp>