File indexing completed on 2024-05-05 09:59:05
0001 /* 0002 ** Copyright (C) 2013 Jiří Procházka (Hobrasoft) 0003 ** Contact: http://www.hobrasoft.cz/ 0004 ** 0005 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). 0006 ** Contact: http://www.qt-project.org/legal 0007 ** 0008 ** $QT_BEGIN_LICENSE:LGPL$ 0009 ** GNU Lesser General Public License Usage 0010 ** This file is under the terms of the GNU Lesser General Public License 0011 ** version 2.1 as published by the Free Software Foundation and appearing 0012 ** in the file LICENSE.LGPL included in the packaging of this file. 0013 ** Please review the following information to ensure the 0014 ** GNU Lesser General Public License version 2.1 requirements 0015 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 0016 ** 0017 ** In addition, as a special exception, Digia gives you certain additional 0018 ** rights. These rights are described in the Digia Qt LGPL Exception 0019 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 0020 ** 0021 ** $QT_END_LICENSE$ 0022 */ 0023 0024 #include "mrichtextedit.h" 0025 #include <QApplication> 0026 #include <QBuffer> 0027 #include <QClipboard> 0028 #include <QColorDialog> 0029 #include <QDialog> 0030 #include <QFileDialog> 0031 #include <QFontDatabase> 0032 #include <QImageReader> 0033 #include <QInputDialog> 0034 #include <QMenu> 0035 #include <QMimeData> 0036 #include <QPlainTextEdit> 0037 #include <QRegularExpression> 0038 #include <QSettings> 0039 #include <QTextList> 0040 #include <QUrl> 0041 #include <QtDebug> 0042 0043 #include "ui_mrichtextedit.h" 0044 0045 MRichTextEdit::MRichTextEdit(QWidget* parent) : QWidget(parent), m_ui(new Ui::MRichTextEdit) 0046 { 0047 m_ui->setupUi(this); 0048 m_lastBlockList= nullptr; 0049 m_ui->f_textedit->setTabStopDistance(40); 0050 0051 connect(m_ui->f_textedit, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, 0052 SLOT(slotCurrentCharFormatChanged(QTextCharFormat))); 0053 connect(m_ui->f_textedit, SIGNAL(cursorPositionChanged()), this, SLOT(slotCursorPositionChanged())); 0054 0055 m_fontsize_h1= 18; 0056 m_fontsize_h2= 16; 0057 m_fontsize_h3= 14; 0058 m_fontsize_h4= 12; 0059 0060 fontChanged(m_ui->f_textedit->font()); 0061 bgColorChanged(m_ui->f_textedit->textColor()); 0062 0063 // paragraph formatting 0064 0065 m_paragraphItems << tr("Standard") << tr("Heading 1") << tr("Heading 2") << tr("Heading 3") << tr("Heading 4") 0066 << tr("Monospace"); 0067 m_ui->f_paragraph->addItems(m_paragraphItems); 0068 0069 connect(m_ui->f_paragraph, SIGNAL(activated(int)), this, SLOT(textStyle(int))); 0070 0071 // undo & redo 0072 0073 m_ui->f_undo->setShortcut(QKeySequence::Undo); 0074 m_ui->f_redo->setShortcut(QKeySequence::Redo); 0075 0076 connect(m_ui->f_textedit->document(), SIGNAL(undoAvailable(bool)), m_ui->f_undo, SLOT(setEnabled(bool))); 0077 connect(m_ui->f_textedit->document(), SIGNAL(redoAvailable(bool)), m_ui->f_redo, SLOT(setEnabled(bool))); 0078 0079 m_ui->f_undo->setEnabled(m_ui->f_textedit->document()->isUndoAvailable()); 0080 m_ui->f_redo->setEnabled(m_ui->f_textedit->document()->isRedoAvailable()); 0081 0082 connect(m_ui->f_undo, SIGNAL(clicked()), m_ui->f_textedit, SLOT(undo())); 0083 connect(m_ui->f_redo, SIGNAL(clicked()), m_ui->f_textedit, SLOT(redo())); 0084 0085 // cut, copy & paste 0086 0087 m_ui->f_cut->setShortcut(QKeySequence::Cut); 0088 m_ui->f_copy->setShortcut(QKeySequence::Copy); 0089 m_ui->f_paste->setShortcut(QKeySequence::Paste); 0090 0091 m_ui->f_cut->setEnabled(false); 0092 m_ui->f_copy->setEnabled(false); 0093 0094 connect(m_ui->f_cut, SIGNAL(clicked()), m_ui->f_textedit, SLOT(cut())); 0095 connect(m_ui->f_copy, SIGNAL(clicked()), m_ui->f_textedit, SLOT(copy())); 0096 connect(m_ui->f_paste, SIGNAL(clicked()), m_ui->f_textedit, SLOT(paste())); 0097 0098 connect(m_ui->f_textedit, SIGNAL(copyAvailable(bool)), m_ui->f_cut, SLOT(setEnabled(bool))); 0099 connect(m_ui->f_textedit, SIGNAL(copyAvailable(bool)), m_ui->f_copy, SLOT(setEnabled(bool))); 0100 0101 #ifndef QT_NO_CLIPBOARD 0102 connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slotClipboardDataChanged())); 0103 #endif 0104 0105 // link 0106 0107 m_ui->f_link->setShortcut(Qt::CTRL + Qt::Key_L); 0108 0109 connect(m_ui->f_link, SIGNAL(clicked(bool)), this, SLOT(textLink(bool))); 0110 0111 // bold, italic & underline 0112 0113 m_ui->f_bold->setShortcut(Qt::CTRL + Qt::Key_B); 0114 m_ui->f_italic->setShortcut(Qt::CTRL + Qt::Key_I); 0115 m_ui->f_underline->setShortcut(Qt::CTRL + Qt::Key_U); 0116 0117 connect(m_ui->f_bold, SIGNAL(clicked()), this, SLOT(textBold())); 0118 connect(m_ui->f_italic, SIGNAL(clicked()), this, SLOT(textItalic())); 0119 connect(m_ui->f_underline, SIGNAL(clicked()), this, SLOT(textUnderline())); 0120 connect(m_ui->f_strikeout, SIGNAL(clicked()), this, SLOT(textStrikeout())); 0121 0122 QAction* removeFormat= new QAction(tr("Remove character formatting"), this); 0123 removeFormat->setShortcut(QKeySequence("CTRL+M")); 0124 connect(removeFormat, SIGNAL(triggered()), this, SLOT(textRemoveFormat())); 0125 m_ui->f_textedit->addAction(removeFormat); 0126 0127 QAction* removeAllFormat= new QAction(tr("Remove all formatting"), this); 0128 connect(removeAllFormat, SIGNAL(triggered()), this, SLOT(textRemoveAllFormat())); 0129 m_ui->f_textedit->addAction(removeAllFormat); 0130 0131 QAction* textsource= new QAction(tr("Edit document source"), this); 0132 textsource->setShortcut(QKeySequence("CTRL+O")); 0133 connect(textsource, SIGNAL(triggered()), this, SLOT(textSource())); 0134 m_ui->f_textedit->addAction(textsource); 0135 0136 QMenu* menu= new QMenu(this); 0137 menu->addAction(removeAllFormat); 0138 menu->addAction(removeFormat); 0139 menu->addAction(textsource); 0140 m_ui->f_menu->setMenu(menu); 0141 m_ui->f_menu->setPopupMode(QToolButton::InstantPopup); 0142 0143 // lists 0144 0145 m_ui->f_list_bullet->setShortcut(Qt::CTRL + Qt::Key_Minus); 0146 m_ui->f_list_ordered->setShortcut(Qt::CTRL + Qt::Key_Equal); 0147 0148 connect(m_ui->f_list_bullet, SIGNAL(clicked(bool)), this, SLOT(listBullet(bool))); 0149 connect(m_ui->f_list_ordered, SIGNAL(clicked(bool)), this, SLOT(listOrdered(bool))); 0150 0151 // indentation 0152 0153 m_ui->f_indent_dec->setShortcut(Qt::CTRL + Qt::Key_Comma); 0154 m_ui->f_indent_inc->setShortcut(Qt::CTRL + Qt::Key_Period); 0155 0156 connect(m_ui->f_indent_inc, SIGNAL(clicked()), this, SLOT(increaseIndentation())); 0157 connect(m_ui->f_indent_dec, SIGNAL(clicked()), this, SLOT(decreaseIndentation())); 0158 0159 // font size 0160 0161 QFontDatabase db; 0162 for(int& size : db.standardSizes()) 0163 m_ui->f_fontsize->addItem(QString::number(size)); 0164 0165 connect(m_ui->f_fontsize, SIGNAL(activated(QString)), this, SLOT(textSize(QString))); 0166 m_ui->f_fontsize->setCurrentIndex(m_ui->f_fontsize->findText(QString::number(QApplication::font().pointSize()))); 0167 0168 // text foreground color 0169 0170 QPixmap pix(16, 16); 0171 pix.fill(QApplication::palette().windowText().color()); 0172 m_ui->f_fgcolor->setIcon(pix); 0173 0174 connect(m_ui->f_fgcolor, SIGNAL(clicked()), this, SLOT(textFgColor())); 0175 0176 // text background color 0177 0178 pix.fill(QApplication::palette().window().color()); 0179 m_ui->f_bgcolor->setIcon(pix); 0180 0181 connect(m_ui->f_bgcolor, SIGNAL(clicked()), this, SLOT(textBgColor())); 0182 0183 // images 0184 connect(m_ui->f_image, SIGNAL(clicked()), this, SLOT(insertImage())); 0185 } 0186 0187 MRichTextEdit::~MRichTextEdit() = default; 0188 0189 QString MRichTextEdit::toPlainText() const { return m_ui->f_textedit->toPlainText(); } 0190 0191 void MRichTextEdit::textSource() 0192 { 0193 QDialog* dialog= new QDialog(this); 0194 QPlainTextEdit* pte= new QPlainTextEdit(dialog); 0195 pte->setPlainText(m_ui->f_textedit->toHtml()); 0196 QGridLayout* gl= new QGridLayout(dialog); 0197 gl->addWidget(pte, 0, 0, 1, 1); 0198 dialog->setWindowTitle(tr("Document source")); 0199 dialog->setMinimumWidth(400); 0200 dialog->setMinimumHeight(600); 0201 dialog->exec(); 0202 0203 m_ui->f_textedit->setHtml(pte->toPlainText()); 0204 0205 delete dialog; 0206 } 0207 0208 void MRichTextEdit::textRemoveFormat() 0209 { 0210 QTextCharFormat fmt; 0211 fmt.setFontWeight(QFont::Normal); 0212 fmt.setFontUnderline(false); 0213 fmt.setFontStrikeOut(false); 0214 fmt.setFontItalic(false); 0215 fmt.setFontPointSize(9); 0216 // fmt.setFontFamily ("Helvetica"); 0217 // fmt.setFontStyleHint (QFont::SansSerif); 0218 // fmt.setFontFixedPitch (true); 0219 0220 m_ui->f_bold->setChecked(false); 0221 m_ui->f_underline->setChecked(false); 0222 m_ui->f_italic->setChecked(false); 0223 m_ui->f_strikeout->setChecked(false); 0224 m_ui->f_fontsize->setCurrentIndex(m_ui->f_fontsize->findText("9")); 0225 0226 // QTextBlockFormat bfmt = cursor.blockFormat(); 0227 // bfmt->setIndent(0); 0228 0229 fmt.clearBackground(); 0230 0231 mergeFormatOnWordOrSelection(fmt); 0232 } 0233 0234 void MRichTextEdit::textRemoveAllFormat() 0235 { 0236 m_ui->f_bold->setChecked(false); 0237 m_ui->f_underline->setChecked(false); 0238 m_ui->f_italic->setChecked(false); 0239 m_ui->f_strikeout->setChecked(false); 0240 m_ui->f_fontsize->setCurrentIndex(m_ui->f_fontsize->findText("9")); 0241 QString text= m_ui->f_textedit->toPlainText(); 0242 m_ui->f_textedit->setPlainText(text); 0243 } 0244 0245 void MRichTextEdit::textBold() 0246 { 0247 QTextCharFormat fmt; 0248 fmt.setFontWeight(m_ui->f_bold->isChecked() ? QFont::Bold : QFont::Normal); 0249 mergeFormatOnWordOrSelection(fmt); 0250 } 0251 0252 void MRichTextEdit::focusInEvent(QFocusEvent*) 0253 { 0254 m_ui->f_textedit->setFocus(Qt::TabFocusReason); 0255 } 0256 0257 void MRichTextEdit::textUnderline() 0258 { 0259 QTextCharFormat fmt; 0260 fmt.setFontUnderline(m_ui->f_underline->isChecked()); 0261 mergeFormatOnWordOrSelection(fmt); 0262 } 0263 0264 void MRichTextEdit::textItalic() 0265 { 0266 QTextCharFormat fmt; 0267 fmt.setFontItalic(m_ui->f_italic->isChecked()); 0268 mergeFormatOnWordOrSelection(fmt); 0269 } 0270 0271 void MRichTextEdit::textStrikeout() 0272 { 0273 QTextCharFormat fmt; 0274 fmt.setFontStrikeOut(m_ui->f_strikeout->isChecked()); 0275 mergeFormatOnWordOrSelection(fmt); 0276 } 0277 0278 void MRichTextEdit::textSize(const QString& p) 0279 { 0280 qreal pointSize= p.toFloat(); 0281 if(p.toFloat() > 0) 0282 { 0283 QTextCharFormat fmt; 0284 fmt.setFontPointSize(pointSize); 0285 mergeFormatOnWordOrSelection(fmt); 0286 } 0287 } 0288 0289 void MRichTextEdit::textLink(bool checked) 0290 { 0291 bool unlink= false; 0292 QTextCharFormat fmt; 0293 if(checked) 0294 { 0295 QString url= m_ui->f_textedit->currentCharFormat().anchorHref(); 0296 bool ok; 0297 QString newUrl= QInputDialog::getText(this, tr("Create a link"), tr("Link URL:"), QLineEdit::Normal, url, &ok); 0298 if(ok) 0299 { 0300 fmt.setAnchor(true); 0301 fmt.setAnchorHref(newUrl); 0302 fmt.setForeground(QApplication::palette().color(QPalette::Link)); 0303 fmt.setFontUnderline(true); 0304 } 0305 else 0306 { 0307 unlink= true; 0308 } 0309 } 0310 else 0311 { 0312 unlink= true; 0313 } 0314 if(unlink) 0315 { 0316 fmt.setAnchor(false); 0317 fmt.setForeground(QApplication::palette().color(QPalette::Text)); 0318 fmt.setFontUnderline(false); 0319 } 0320 mergeFormatOnWordOrSelection(fmt); 0321 } 0322 0323 void MRichTextEdit::textStyle(int index) 0324 { 0325 QTextCursor cursor= m_ui->f_textedit->textCursor(); 0326 cursor.beginEditBlock(); 0327 0328 // standard 0329 if(!cursor.hasSelection()) 0330 { 0331 cursor.select(QTextCursor::BlockUnderCursor); 0332 } 0333 QTextCharFormat fmt; 0334 cursor.setCharFormat(fmt); 0335 m_ui->f_textedit->setCurrentCharFormat(fmt); 0336 0337 if(index == ParagraphHeading1 || index == ParagraphHeading2 || index == ParagraphHeading3 0338 || index == ParagraphHeading4) 0339 { 0340 if(index == ParagraphHeading1) 0341 { 0342 fmt.setFontPointSize(m_fontsize_h1); 0343 } 0344 if(index == ParagraphHeading2) 0345 { 0346 fmt.setFontPointSize(m_fontsize_h2); 0347 } 0348 if(index == ParagraphHeading3) 0349 { 0350 fmt.setFontPointSize(m_fontsize_h3); 0351 } 0352 if(index == ParagraphHeading4) 0353 { 0354 fmt.setFontPointSize(m_fontsize_h4); 0355 } 0356 if(index == ParagraphHeading2 || index == ParagraphHeading4) 0357 { 0358 fmt.setFontItalic(true); 0359 } 0360 0361 fmt.setFontWeight(QFont::Bold); 0362 } 0363 if(index == ParagraphMonospace) 0364 { 0365 fmt= cursor.charFormat(); 0366 fmt.setFontFamily("Monospace"); 0367 fmt.setFontStyleHint(QFont::Monospace); 0368 fmt.setFontFixedPitch(true); 0369 } 0370 cursor.setCharFormat(fmt); 0371 m_ui->f_textedit->setCurrentCharFormat(fmt); 0372 0373 cursor.endEditBlock(); 0374 } 0375 0376 void MRichTextEdit::textFgColor() 0377 { 0378 QColor col= QColorDialog::getColor(m_ui->f_textedit->textColor(), this); 0379 QTextCursor cursor= m_ui->f_textedit->textCursor(); 0380 if(!cursor.hasSelection()) 0381 { 0382 cursor.select(QTextCursor::WordUnderCursor); 0383 } 0384 QTextCharFormat fmt= cursor.charFormat(); 0385 if(col.isValid()) 0386 { 0387 fmt.setForeground(col); 0388 } 0389 else 0390 { 0391 fmt.clearForeground(); 0392 } 0393 cursor.setCharFormat(fmt); 0394 m_ui->f_textedit->setCurrentCharFormat(fmt); 0395 fgColorChanged(col); 0396 } 0397 0398 void MRichTextEdit::textBgColor() 0399 { 0400 QColor col= QColorDialog::getColor(m_ui->f_textedit->textBackgroundColor(), this); 0401 QTextCursor cursor= m_ui->f_textedit->textCursor(); 0402 if(!cursor.hasSelection()) 0403 { 0404 cursor.select(QTextCursor::WordUnderCursor); 0405 } 0406 QTextCharFormat fmt= cursor.charFormat(); 0407 if(col.isValid()) 0408 { 0409 fmt.setBackground(col); 0410 } 0411 else 0412 { 0413 fmt.clearBackground(); 0414 } 0415 cursor.setCharFormat(fmt); 0416 m_ui->f_textedit->setCurrentCharFormat(fmt); 0417 bgColorChanged(col); 0418 } 0419 0420 void MRichTextEdit::listBullet(bool checked) 0421 { 0422 if(checked) 0423 { 0424 m_ui->f_list_ordered->setChecked(false); 0425 } 0426 list(checked, QTextListFormat::ListDisc); 0427 } 0428 0429 void MRichTextEdit::listOrdered(bool checked) 0430 { 0431 if(checked) 0432 { 0433 m_ui->f_list_bullet->setChecked(false); 0434 } 0435 list(checked, QTextListFormat::ListDecimal); 0436 } 0437 0438 void MRichTextEdit::list(bool checked, QTextListFormat::Style style) 0439 { 0440 QTextCursor cursor= m_ui->f_textedit->textCursor(); 0441 cursor.beginEditBlock(); 0442 if(!checked) 0443 { 0444 QTextBlockFormat obfmt= cursor.blockFormat(); 0445 QTextBlockFormat bfmt; 0446 bfmt.setIndent(obfmt.indent()); 0447 cursor.setBlockFormat(bfmt); 0448 } 0449 else 0450 { 0451 QTextListFormat listFmt; 0452 if(cursor.currentList()) 0453 { 0454 listFmt= cursor.currentList()->format(); 0455 } 0456 listFmt.setStyle(style); 0457 cursor.createList(listFmt); 0458 } 0459 cursor.endEditBlock(); 0460 } 0461 0462 void MRichTextEdit::mergeFormatOnWordOrSelection(const QTextCharFormat& format) 0463 { 0464 QTextCursor cursor= m_ui->f_textedit->textCursor(); 0465 if(!cursor.hasSelection()) 0466 { 0467 cursor.select(QTextCursor::WordUnderCursor); 0468 } 0469 cursor.mergeCharFormat(format); 0470 m_ui->f_textedit->mergeCurrentCharFormat(format); 0471 m_ui->f_textedit->setFocus(Qt::TabFocusReason); 0472 } 0473 0474 void MRichTextEdit::slotCursorPositionChanged() 0475 { 0476 QTextList* l= m_ui->f_textedit->textCursor().currentList(); 0477 if(m_lastBlockList 0478 && (l == m_lastBlockList 0479 || (l != nullptr && m_lastBlockList != nullptr && l->format().style() == m_lastBlockList->format().style()))) 0480 { 0481 return; 0482 } 0483 m_lastBlockList= l; 0484 if(l) 0485 { 0486 QTextListFormat lfmt= l->format(); 0487 if(lfmt.style() == QTextListFormat::ListDisc) 0488 { 0489 m_ui->f_list_bullet->setChecked(true); 0490 m_ui->f_list_ordered->setChecked(false); 0491 } 0492 else if(lfmt.style() == QTextListFormat::ListDecimal) 0493 { 0494 m_ui->f_list_bullet->setChecked(false); 0495 m_ui->f_list_ordered->setChecked(true); 0496 } 0497 else 0498 { 0499 m_ui->f_list_bullet->setChecked(false); 0500 m_ui->f_list_ordered->setChecked(false); 0501 } 0502 } 0503 else 0504 { 0505 m_ui->f_list_bullet->setChecked(false); 0506 m_ui->f_list_ordered->setChecked(false); 0507 } 0508 } 0509 0510 void MRichTextEdit::fontChanged(const QFont& f) 0511 { 0512 m_ui->f_fontsize->setCurrentIndex(m_ui->f_fontsize->findText(QString::number(f.pointSize()))); 0513 m_ui->f_bold->setChecked(f.bold()); 0514 m_ui->f_italic->setChecked(f.italic()); 0515 m_ui->f_underline->setChecked(f.underline()); 0516 m_ui->f_strikeout->setChecked(f.strikeOut()); 0517 if(f.pointSize() == m_fontsize_h1) 0518 { 0519 m_ui->f_paragraph->setCurrentIndex(ParagraphHeading1); 0520 } 0521 else if(f.pointSize() == m_fontsize_h2) 0522 { 0523 m_ui->f_paragraph->setCurrentIndex(ParagraphHeading2); 0524 } 0525 else if(f.pointSize() == m_fontsize_h3) 0526 { 0527 m_ui->f_paragraph->setCurrentIndex(ParagraphHeading3); 0528 } 0529 else if(f.pointSize() == m_fontsize_h4) 0530 { 0531 m_ui->f_paragraph->setCurrentIndex(ParagraphHeading4); 0532 } 0533 else 0534 { 0535 if(f.fixedPitch() && f.family() == "Monospace") 0536 { 0537 m_ui->f_paragraph->setCurrentIndex(ParagraphMonospace); 0538 } 0539 else 0540 { 0541 m_ui->f_paragraph->setCurrentIndex(ParagraphStandard); 0542 } 0543 } 0544 if(m_ui->f_textedit->textCursor().currentList()) 0545 { 0546 QTextListFormat lfmt= m_ui->f_textedit->textCursor().currentList()->format(); 0547 if(lfmt.style() == QTextListFormat::ListDisc) 0548 { 0549 m_ui->f_list_bullet->setChecked(true); 0550 m_ui->f_list_ordered->setChecked(false); 0551 } 0552 else if(lfmt.style() == QTextListFormat::ListDecimal) 0553 { 0554 m_ui->f_list_bullet->setChecked(false); 0555 m_ui->f_list_ordered->setChecked(true); 0556 } 0557 else 0558 { 0559 m_ui->f_list_bullet->setChecked(false); 0560 m_ui->f_list_ordered->setChecked(false); 0561 } 0562 } 0563 else 0564 { 0565 m_ui->f_list_bullet->setChecked(false); 0566 m_ui->f_list_ordered->setChecked(false); 0567 } 0568 } 0569 0570 void MRichTextEdit::fgColorChanged(const QColor& c) 0571 { 0572 QPixmap pix(16, 16); 0573 if(c.isValid()) 0574 { 0575 pix.fill(c); 0576 } 0577 else 0578 { 0579 pix.fill(QApplication::palette().windowText().color()); 0580 } 0581 m_ui->f_fgcolor->setIcon(pix); 0582 } 0583 0584 void MRichTextEdit::bgColorChanged(const QColor& c) 0585 { 0586 QPixmap pix(16, 16); 0587 if(c.isValid()) 0588 { 0589 pix.fill(c); 0590 } 0591 else 0592 { 0593 pix.fill(QApplication::palette().window().color()); 0594 } 0595 m_ui->f_bgcolor->setIcon(pix); 0596 } 0597 0598 void MRichTextEdit::slotCurrentCharFormatChanged(const QTextCharFormat& format) 0599 { 0600 fontChanged(format.font()); 0601 bgColorChanged((format.background().isOpaque()) ? format.background().color() : QColor()); 0602 fgColorChanged((format.foreground().isOpaque()) ? format.foreground().color() : QColor()); 0603 m_ui->f_link->setChecked(format.isAnchor()); 0604 } 0605 0606 void MRichTextEdit::slotClipboardDataChanged() 0607 { 0608 #ifndef QT_NO_CLIPBOARD 0609 if(const QMimeData* md= QApplication::clipboard()->mimeData()) 0610 m_ui->f_paste->setEnabled(md->hasText()); 0611 #endif 0612 } 0613 0614 QString MRichTextEdit::toHtml() const 0615 { 0616 QString s= m_ui->f_textedit->toHtml(); 0617 // convert emails to links 0618 s= s.replace(QRegularExpression("(<[^a][^>]+>(?:<span[^>]+>)?|\\s)([a-zA-Z\\d]+@[a-zA-Z\\d]+\\.[a-zA-Z]+)"), 0619 "\\1<a href=\"mailto:\\2\">\\2</a>"); 0620 // convert links 0621 s= s.replace(QRegularExpression("(<[^a][^>]+>(?:<span[^>]+>)?|\\s)((?:https?|ftp|file)://[^\\s'\"<>]+)"), 0622 "\\1<a href=\"\\2\">\\2</a>"); 0623 // see also: Utils::linkify() 0624 return s; 0625 } 0626 0627 QTextDocument *MRichTextEdit::document() { return m_ui->f_textedit->document(); } 0628 0629 QTextCursor MRichTextEdit::textCursor() const { return m_ui->f_textedit->textCursor(); } 0630 0631 void MRichTextEdit::setTextCursor(const QTextCursor &cursor) { m_ui->f_textedit->setTextCursor(cursor); } 0632 0633 void MRichTextEdit::increaseIndentation() 0634 { 0635 indent(+1); 0636 } 0637 0638 void MRichTextEdit::decreaseIndentation() 0639 { 0640 indent(-1); 0641 } 0642 0643 void MRichTextEdit::indent(int delta) 0644 { 0645 QTextCursor cursor= m_ui->f_textedit->textCursor(); 0646 cursor.beginEditBlock(); 0647 QTextBlockFormat bfmt= cursor.blockFormat(); 0648 int ind= bfmt.indent(); 0649 if(ind + delta >= 0) 0650 { 0651 bfmt.setIndent(ind + delta); 0652 } 0653 cursor.setBlockFormat(bfmt); 0654 cursor.endEditBlock(); 0655 } 0656 0657 void MRichTextEdit::setText(const QString& text) 0658 { 0659 if(text.isEmpty()) 0660 { 0661 setPlainText(text); 0662 return; 0663 } 0664 if(text[0] == '<') 0665 { 0666 setHtml(text); 0667 } 0668 else 0669 { 0670 setPlainText(text); 0671 } 0672 } 0673 0674 void MRichTextEdit::setPlainText(const QString &text) { m_ui->f_textedit->setPlainText(text); } 0675 0676 void MRichTextEdit::setHtml(const QString &text) { m_ui->f_textedit->setHtml(text); } 0677 0678 void MRichTextEdit::insertImage() 0679 { 0680 QSettings s; 0681 QString attdir= s.value("general/filedialog-path").toString(); 0682 QString file= QFileDialog::getOpenFileName(this, tr("Select an image"), attdir, 0683 tr("JPEG (*.jpg);; GIF (*.gif);; PNG (*.png);; BMP (*.bmp);; All (*)")); 0684 QImage image= QImageReader(file).read(); 0685 0686 m_ui->f_textedit->dropImage(image, QFileInfo(file).suffix().toUpper().toLocal8Bit().data()); 0687 }