File indexing completed on 2024-05-05 05:21:14

0001 /*******************************************************************
0002  KNotes -- Notes for the KDE project
0003 
0004  SPDX-FileCopyrightText: 1997-2013 The KNotes Developers
0005 
0006  SPDX-License-Identifier: GPL-2.0-or-later
0007 *******************************************************************/
0008 
0009 #include "knoteedit.h"
0010 #include "editor/noteeditorutils.h"
0011 #include "notes/knote.h"
0012 
0013 #include <TextUtils/ConvertText>
0014 
0015 #include <PimCommon/KActionMenuChangeCase>
0016 
0017 #include <KActionCollection>
0018 #include <KFontAction>
0019 #include <KFontSizeAction>
0020 #include <KLocalizedString>
0021 #include <KToggleAction>
0022 
0023 #include <QActionGroup>
0024 #include <QColorDialog>
0025 #include <QIcon>
0026 #include <QMenu>
0027 
0028 static const short ICON_SIZE = 10;
0029 
0030 KNoteEdit::KNoteEdit(KActionCollection *actions, QWidget *parent)
0031     : KTextEdit(parent)
0032     , m_note(nullptr)
0033     , m_actions(actions)
0034 {
0035     setAcceptDrops(true);
0036     setWordWrapMode(QTextOption::WordWrap);
0037     setLineWrapMode(WidgetWidth);
0038     if (acceptRichText()) {
0039         setAutoFormatting(AutoAll);
0040     } else {
0041         setAutoFormatting(AutoNone);
0042     }
0043 
0044     // create the actions modifying the text format
0045     m_textBold = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-text-bold")), i18n("Bold"), this);
0046     actions->addAction(QStringLiteral("format_bold"), m_textBold);
0047     actions->setDefaultShortcut(m_textBold, QKeySequence(Qt::CTRL | Qt::Key_B));
0048     m_textItalic = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-text-italic")), i18n("Italic"), this);
0049     actions->addAction(QStringLiteral("format_italic"), m_textItalic);
0050     actions->setDefaultShortcut(m_textItalic, QKeySequence(Qt::CTRL | Qt::Key_I));
0051     m_textUnderline = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-text-underline")), i18n("Underline"), this);
0052     actions->addAction(QStringLiteral("format_underline"), m_textUnderline);
0053     actions->setDefaultShortcut(m_textUnderline, QKeySequence(Qt::CTRL | Qt::Key_U));
0054     m_textStrikeOut = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-text-strikethrough")), i18n("Strike Out"), this);
0055     actions->addAction(QStringLiteral("format_strikeout"), m_textStrikeOut);
0056     actions->setDefaultShortcut(m_textStrikeOut, QKeySequence(Qt::CTRL | Qt::Key_S));
0057 
0058     connect(m_textBold, &KToggleAction::toggled, this, &KNoteEdit::textBold);
0059     connect(m_textItalic, &KToggleAction::toggled, this, &KNoteEdit::setFontItalic);
0060     connect(m_textUnderline, &KToggleAction::toggled, this, &KNoteEdit::setFontUnderline);
0061     connect(m_textStrikeOut, &KToggleAction::toggled, this, &KNoteEdit::textStrikeOut);
0062 
0063     m_textAlignLeft = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-justify-left")), i18n("Align Left"), this);
0064     actions->addAction(QStringLiteral("format_alignleft"), m_textAlignLeft);
0065     connect(m_textAlignLeft, &KToggleAction::triggered, this, &KNoteEdit::textAlignLeft);
0066     actions->setDefaultShortcut(m_textAlignLeft, QKeySequence(Qt::ALT | Qt::Key_L));
0067     m_textAlignLeft->setChecked(true); // just a dummy, will be updated later
0068     m_textAlignCenter = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-justify-center")), i18n("Align Center"), this);
0069     actions->addAction(QStringLiteral("format_aligncenter"), m_textAlignCenter);
0070     connect(m_textAlignCenter, &KToggleAction::triggered, this, &KNoteEdit::textAlignCenter);
0071     actions->setDefaultShortcut(m_textAlignCenter, QKeySequence(Qt::ALT | Qt::Key_C));
0072     m_textAlignRight = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-justify-right")), i18n("Align Right"), this);
0073     actions->addAction(QStringLiteral("format_alignright"), m_textAlignRight);
0074     connect(m_textAlignRight, &KToggleAction::triggered, this, &KNoteEdit::textAlignRight);
0075     actions->setDefaultShortcut(m_textAlignRight, QKeySequence(Qt::ALT | Qt::Key_R));
0076     m_textAlignBlock = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-justify-fill")), i18n("Align Block"), this);
0077     actions->addAction(QStringLiteral("format_alignblock"), m_textAlignBlock);
0078     connect(m_textAlignBlock, &KToggleAction::triggered, this, &KNoteEdit::textAlignBlock);
0079     actions->setDefaultShortcut(m_textAlignBlock, QKeySequence(Qt::ALT | Qt::Key_B));
0080 
0081     auto group = new QActionGroup(this);
0082     group->addAction(m_textAlignLeft);
0083     group->addAction(m_textAlignCenter);
0084     group->addAction(m_textAlignRight);
0085     group->addAction(m_textAlignBlock);
0086 
0087     m_textList = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-list-ordered")), i18n("List"), this);
0088     actions->addAction(QStringLiteral("format_list"), m_textList);
0089     connect(m_textList, &KToggleAction::triggered, this, &KNoteEdit::textList);
0090 
0091     m_textSuper = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-text-superscript")), i18n("Superscript"), this);
0092     actions->addAction(QStringLiteral("format_super"), m_textSuper);
0093     connect(m_textSuper, &KToggleAction::triggered, this, &KNoteEdit::textSuperScript);
0094     m_textSub = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-text-subscript")), i18n("Subscript"), this);
0095     actions->addAction(QStringLiteral("format_sub"), m_textSub);
0096     connect(m_textSub, &KToggleAction::triggered, this, &KNoteEdit::textSubScript);
0097 
0098     m_textIncreaseIndent = new QAction(QIcon::fromTheme(QStringLiteral("format-indent-more")), i18n("Increase Indent"), this);
0099     actions->addAction(QStringLiteral("format_increaseindent"), m_textIncreaseIndent);
0100     actions->setDefaultShortcut(m_textIncreaseIndent, QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_I));
0101     connect(m_textIncreaseIndent, &QAction::triggered, this, &KNoteEdit::textIncreaseIndent);
0102 
0103     m_textDecreaseIndent = new QAction(QIcon::fromTheme(QStringLiteral("format-indent-less")), i18n("Decrease Indent"), this);
0104     actions->addAction(QStringLiteral("format_decreaseindent"), m_textDecreaseIndent);
0105     actions->setDefaultShortcut(m_textDecreaseIndent, QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_D));
0106     connect(m_textDecreaseIndent, &QAction::triggered, this, &KNoteEdit::textDecreaseIndent);
0107 
0108     group = new QActionGroup(this);
0109     group->addAction(m_textIncreaseIndent);
0110     group->addAction(m_textDecreaseIndent);
0111 
0112     QPixmap pix(ICON_SIZE, ICON_SIZE);
0113     pix.fill(Qt::black); // just a dummy, gets updated before widget is shown
0114     m_textColor = new QAction(i18n("Text Color..."), this);
0115     actions->addAction(QStringLiteral("format_color"), m_textColor);
0116     m_textColor->setIcon(pix);
0117     connect(m_textColor, &QAction::triggered, this, &KNoteEdit::slotTextColor);
0118 
0119     auto act = new QAction(QIcon::fromTheme(QStringLiteral("format-fill-color")), i18n("Text Background Color..."), this);
0120     actions->addAction(QStringLiteral("text_background_color"), act);
0121     connect(act, &QAction::triggered, this, &KNoteEdit::slotTextBackgroundColor);
0122 
0123     m_textFont = new KFontAction(i18n("Text Font"), this);
0124     actions->addAction(QStringLiteral("format_font"), m_textFont);
0125     connect(m_textFont, &KFontAction::textTriggered, this, &KNoteEdit::setFontFamily);
0126     m_textSize = new KFontSizeAction(i18n("Text Size"), this);
0127     actions->addAction(QStringLiteral("format_size"), m_textSize);
0128     connect(m_textSize, &KFontSizeAction::fontSizeChanged, this, &KNoteEdit::setTextFontSize);
0129 
0130     mChangeCaseActionMenu = new PimCommon::KActionMenuChangeCase(this);
0131     mChangeCaseActionMenu->appendInActionCollection(actions);
0132     connect(mChangeCaseActionMenu, &PimCommon::KActionMenuChangeCase::upperCase, this, &KNoteEdit::slotUpperCase);
0133     connect(mChangeCaseActionMenu, &PimCommon::KActionMenuChangeCase::lowerCase, this, &KNoteEdit::slotLowerCase);
0134     connect(mChangeCaseActionMenu, &PimCommon::KActionMenuChangeCase::sentenceCase, this, &KNoteEdit::slotSentenceCase);
0135     connect(mChangeCaseActionMenu, &PimCommon::KActionMenuChangeCase::reverseCase, this, &KNoteEdit::slotReverseCase);
0136 
0137     auto action = new QAction(QIcon::fromTheme(QStringLiteral("knotes_date")), i18n("Insert Date"), this);
0138     actions->addAction(QStringLiteral("insert_date"), action);
0139     connect(action, &QAction::triggered, this, &KNoteEdit::slotInsertDate);
0140 
0141     action = new QAction(QIcon::fromTheme(QStringLiteral("checkmark")), i18n("Insert Checkmark"), this);
0142     actions->addAction(QStringLiteral("insert_checkmark"), action);
0143     connect(action, &QAction::triggered, this, &KNoteEdit::slotInsertCheckMark);
0144 
0145     // QTextEdit connections
0146     connect(this, &KNoteEdit::currentCharFormatChanged, this, &KNoteEdit::slotCurrentCharFormatChanged);
0147     connect(this, &KNoteEdit::cursorPositionChanged, this, &KNoteEdit::slotCursorPositionChanged);
0148     slotCurrentCharFormatChanged(currentCharFormat());
0149     slotCursorPositionChanged();
0150 }
0151 
0152 KNoteEdit::~KNoteEdit() = default;
0153 
0154 void KNoteEdit::setColor(const QColor &fg, const QColor &bg)
0155 {
0156     mDefaultBackgroundColor = bg;
0157     mDefaultForegroundColor = fg;
0158 
0159     QPalette p = palette();
0160 
0161     // better: from light(150) to light(100) to light(75)
0162     // QLinearGradient g( width()/2, 0, width()/2, height() );
0163     // g.setColorAt( 0, bg );
0164     // g.setColorAt( 1, bg.darker(150) );
0165 
0166     p.setColor(QPalette::Window, bg);
0167     // p.setBrush( QPalette::Window,     g );
0168     p.setColor(QPalette::Base, bg);
0169     // p.setBrush( QPalette::Base,       g );
0170 
0171     p.setColor(QPalette::WindowText, fg);
0172     p.setColor(QPalette::Text, fg);
0173 
0174     p.setColor(QPalette::Button, bg.darker(116));
0175     p.setColor(QPalette::ButtonText, fg);
0176 
0177     // p.setColor( QPalette::Highlight,  bg );
0178     // p.setColor( QPalette::HighlightedText, fg );
0179 
0180     // order: Light, Midlight, Button, Mid, Dark, Shadow
0181 
0182     // the shadow
0183     p.setColor(QPalette::Light, bg.lighter(180));
0184     p.setColor(QPalette::Midlight, bg.lighter(150));
0185     p.setColor(QPalette::Mid, bg.lighter(150));
0186     p.setColor(QPalette::Dark, bg.darker(108));
0187     p.setColor(QPalette::Shadow, bg.darker(116));
0188 
0189     setPalette(p);
0190 
0191     setTextColor(fg);
0192 }
0193 
0194 void KNoteEdit::setNote(KNote *_note)
0195 {
0196     m_note = _note;
0197 }
0198 
0199 void KNoteEdit::slotReverseCase()
0200 {
0201     QTextCursor cursor = textCursor();
0202     TextUtils::ConvertText::reverseCase(cursor);
0203 }
0204 
0205 void KNoteEdit::slotSentenceCase()
0206 {
0207     QTextCursor cursor = textCursor();
0208     TextUtils::ConvertText::sentenceCase(cursor);
0209 }
0210 
0211 void KNoteEdit::slotUpperCase()
0212 {
0213     QTextCursor cursor = textCursor();
0214     TextUtils::ConvertText::upperCase(cursor);
0215 }
0216 
0217 void KNoteEdit::slotLowerCase()
0218 {
0219     QTextCursor cursor = textCursor();
0220     TextUtils::ConvertText::lowerCase(cursor);
0221 }
0222 
0223 QMenu *KNoteEdit::mousePopupMenu()
0224 {
0225     QMenu *popup = KTextEdit::mousePopupMenu();
0226     if (popup) {
0227         QTextCursor cursor = textCursor();
0228         if (!isReadOnly()) {
0229             if (cursor.hasSelection()) {
0230                 popup->addSeparator();
0231                 popup->addAction(mChangeCaseActionMenu);
0232             }
0233             popup->addSeparator();
0234             QAction *act = m_actions->action(QStringLiteral("insert_date"));
0235             popup->addAction(act);
0236             popup->addSeparator();
0237             act = m_actions->action(QStringLiteral("insert_checkmark"));
0238             popup->addAction(act);
0239         }
0240     }
0241     return popup;
0242 }
0243 
0244 void KNoteEdit::setText(const QString &text)
0245 {
0246     if (acceptRichText() && Qt::mightBeRichText(text)) {
0247         setHtml(text);
0248     } else {
0249         setPlainText(text);
0250     }
0251 }
0252 
0253 QString KNoteEdit::text() const
0254 {
0255     if (acceptRichText()) {
0256         return toHtml();
0257     } else {
0258         return toPlainText();
0259     }
0260 }
0261 
0262 void KNoteEdit::setTextFont(const QFont &font)
0263 {
0264     setCurrentFont(font);
0265 
0266     // make this font default so that if user deletes note content
0267     // font is remembered
0268     document()->setDefaultFont(font);
0269 }
0270 
0271 void KNoteEdit::setTextFontSize(int size)
0272 {
0273     setFontPointSize(size);
0274 }
0275 
0276 void KNoteEdit::setTabStop(int tabs)
0277 {
0278     QFontMetrics fm(font());
0279     setTabStopDistance(fm.boundingRect(QLatin1Char('x')).width() * tabs);
0280 }
0281 
0282 void KNoteEdit::setAutoIndentMode(bool newmode)
0283 {
0284     m_autoIndentMode = newmode;
0285 }
0286 
0287 /** public slots **/
0288 
0289 void KNoteEdit::setRichText(bool f)
0290 {
0291     if (f == acceptRichText()) {
0292         return;
0293     }
0294 
0295     setAcceptRichText(f);
0296 
0297     if (f) {
0298         setAutoFormatting(AutoAll);
0299     } else {
0300         setAutoFormatting(AutoNone);
0301     }
0302 
0303     const QString t = toPlainText();
0304     if (f) {
0305         // if the note contains html source try to render it
0306         if (Qt::mightBeRichText(t)) {
0307             setHtml(t);
0308         } else {
0309             setPlainText(t);
0310         }
0311 
0312         enableRichTextActions(true);
0313     } else {
0314         setPlainText(t);
0315         enableRichTextActions(false);
0316     }
0317 }
0318 
0319 void KNoteEdit::textBold(bool b)
0320 {
0321     if (!acceptRichText()) {
0322         return;
0323     }
0324 
0325     QTextCharFormat f;
0326     f.setFontWeight(b ? QFont::Bold : QFont::Normal);
0327     mergeCurrentCharFormat(f);
0328 }
0329 
0330 void KNoteEdit::textStrikeOut(bool s)
0331 {
0332     if (!acceptRichText()) {
0333         return;
0334     }
0335 
0336     QTextCharFormat f;
0337     f.setFontStrikeOut(s);
0338     mergeCurrentCharFormat(f);
0339 }
0340 
0341 void KNoteEdit::slotTextColor()
0342 {
0343     if (!acceptRichText()) {
0344         return;
0345     }
0346 
0347     if (m_note) {
0348         m_note->setBlockSave(true);
0349     }
0350     QColor c = QColorDialog::getColor(textColor(), this);
0351     if (c.isValid()) {
0352         setTextColor(c);
0353     }
0354     if (m_note) {
0355         m_note->setBlockSave(false);
0356     }
0357 }
0358 
0359 void KNoteEdit::slotTextBackgroundColor()
0360 {
0361     if (!acceptRichText()) {
0362         return;
0363     }
0364 
0365     if (m_note) {
0366         m_note->setBlockSave(true);
0367     }
0368     const QColor c = QColorDialog::getColor(textBackgroundColor(), this);
0369     if (c.isValid()) {
0370         setTextBackgroundColor(c);
0371     }
0372     if (m_note) {
0373         m_note->setBlockSave(false);
0374     }
0375 }
0376 
0377 void KNoteEdit::textAlignLeft()
0378 {
0379     if (!acceptRichText()) {
0380         return;
0381     }
0382     setAlignment(Qt::AlignLeft);
0383     m_textAlignLeft->setChecked(true);
0384 }
0385 
0386 void KNoteEdit::textAlignCenter()
0387 {
0388     if (!acceptRichText()) {
0389         return;
0390     }
0391     setAlignment(Qt::AlignCenter);
0392     m_textAlignCenter->setChecked(true);
0393 }
0394 
0395 void KNoteEdit::textAlignRight()
0396 {
0397     if (!acceptRichText()) {
0398         return;
0399     }
0400     setAlignment(Qt::AlignRight);
0401     m_textAlignRight->setChecked(true);
0402 }
0403 
0404 void KNoteEdit::textAlignBlock()
0405 {
0406     if (!acceptRichText()) {
0407         return;
0408     }
0409     setAlignment(Qt::AlignJustify);
0410     m_textAlignBlock->setChecked(true);
0411 }
0412 
0413 void KNoteEdit::textList()
0414 {
0415     if (!acceptRichText()) {
0416         return;
0417     }
0418     QTextCursor c = textCursor();
0419     c.beginEditBlock();
0420 
0421     if (m_textList->isChecked()) {
0422         QTextListFormat lf;
0423         QTextBlockFormat bf = c.blockFormat();
0424 
0425         lf.setIndent(bf.indent() + 1);
0426         bf.setIndent(0);
0427 
0428         lf.setStyle(QTextListFormat::ListDisc);
0429 
0430         c.setBlockFormat(bf);
0431         c.createList(lf);
0432     } else {
0433         QTextBlockFormat bf;
0434         bf.setObjectIndex(-1);
0435         c.setBlockFormat(bf);
0436     }
0437 
0438     c.endEditBlock();
0439 }
0440 
0441 void KNoteEdit::textSuperScript()
0442 {
0443     if (!acceptRichText()) {
0444         return;
0445     }
0446     QTextCharFormat f;
0447     if (m_textSuper->isChecked()) {
0448         if (m_textSub->isChecked()) {
0449             m_textSub->setChecked(false);
0450         }
0451         f.setVerticalAlignment(QTextCharFormat::AlignSuperScript);
0452     } else {
0453         f.setVerticalAlignment(QTextCharFormat::AlignNormal);
0454     }
0455     mergeCurrentCharFormat(f);
0456 }
0457 
0458 void KNoteEdit::textSubScript()
0459 {
0460     if (!acceptRichText()) {
0461         return;
0462     }
0463     QTextCharFormat f;
0464     if (m_textSub->isChecked()) {
0465         if (m_textSuper->isChecked()) {
0466             m_textSuper->setChecked(false);
0467         }
0468         f.setVerticalAlignment(QTextCharFormat::AlignSubScript);
0469     } else {
0470         f.setVerticalAlignment(QTextCharFormat::AlignNormal);
0471     }
0472     mergeCurrentCharFormat(f);
0473 }
0474 
0475 void KNoteEdit::textIncreaseIndent()
0476 {
0477     if (!acceptRichText()) {
0478         return;
0479     }
0480     QTextBlockFormat f = textCursor().blockFormat();
0481     f.setIndent(f.indent() + 1);
0482     textCursor().setBlockFormat(f);
0483 }
0484 
0485 void KNoteEdit::textDecreaseIndent()
0486 {
0487     if (!acceptRichText()) {
0488         return;
0489     }
0490     QTextBlockFormat f = textCursor().blockFormat();
0491     short int curIndent = f.indent();
0492 
0493     if (curIndent > 0) {
0494         f.setIndent(curIndent - 1);
0495     }
0496     textCursor().setBlockFormat(f);
0497 }
0498 
0499 /** protected methods **/
0500 
0501 void KNoteEdit::keyPressEvent(QKeyEvent *e)
0502 {
0503     KTextEdit::keyPressEvent(e);
0504 
0505     if (m_autoIndentMode && ((e->key() == Qt::Key_Return) || (e->key() == Qt::Key_Enter))) {
0506         autoIndent();
0507     }
0508 }
0509 
0510 void KNoteEdit::focusInEvent(QFocusEvent *e)
0511 {
0512     KTextEdit::focusInEvent(e);
0513 
0514     setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0515     setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0516 }
0517 
0518 void KNoteEdit::focusOutEvent(QFocusEvent *e)
0519 {
0520     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0521     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0522 
0523     KTextEdit::focusOutEvent(e);
0524 }
0525 
0526 /** private slots **/
0527 
0528 void KNoteEdit::slotCurrentCharFormatChanged(const QTextCharFormat &f)
0529 {
0530     if (!acceptRichText()) {
0531         return;
0532     }
0533 
0534     // font changes
0535     const QStringList families = f.fontFamilies().toStringList();
0536     const auto fontFamily = families.isEmpty() ? QString() : families.constFirst();
0537     m_textFont->setFont(fontFamily);
0538     m_textSize->setFontSize((f.fontPointSize() > 0) ? (int)f.fontPointSize() : 10);
0539 
0540     m_textBold->setChecked(f.font().bold());
0541     m_textItalic->setChecked(f.fontItalic());
0542     m_textUnderline->setChecked(f.fontUnderline());
0543     m_textStrikeOut->setChecked(f.fontStrikeOut());
0544 
0545     // color changes
0546     QPixmap pix(ICON_SIZE, ICON_SIZE);
0547     pix.fill(f.foreground().color());
0548     m_textColor->QAction::setIcon(pix);
0549 
0550     // vertical alignment changes
0551     QTextCharFormat::VerticalAlignment va = f.verticalAlignment();
0552     if (va == QTextCharFormat::AlignNormal) {
0553         m_textSuper->setChecked(false);
0554         m_textSub->setChecked(false);
0555     } else if (va == QTextCharFormat::AlignSuperScript) {
0556         m_textSuper->setChecked(true);
0557     } else if (va == QTextCharFormat::AlignSubScript) {
0558         m_textSub->setChecked(true);
0559     }
0560 }
0561 
0562 void KNoteEdit::slotCursorPositionChanged()
0563 {
0564     if (!acceptRichText()) {
0565         return;
0566     }
0567     // alignment changes
0568     const Qt::Alignment a = alignment();
0569     if (a & Qt::AlignLeft) {
0570         m_textAlignLeft->setChecked(true);
0571     } else if (a & Qt::AlignHCenter) {
0572         m_textAlignCenter->setChecked(true);
0573     } else if (a & Qt::AlignRight) {
0574         m_textAlignRight->setChecked(true);
0575     } else if (a & Qt::AlignJustify) {
0576         m_textAlignBlock->setChecked(true);
0577     }
0578 }
0579 
0580 /** private methods **/
0581 
0582 void KNoteEdit::autoIndent()
0583 {
0584     QTextCursor c = textCursor();
0585     QTextBlock b = c.block();
0586 
0587     QString string;
0588     while ((b.previous().length() > 0) && string.trimmed().isEmpty()) {
0589         b = b.previous();
0590         string = b.text();
0591     }
0592 
0593     if (string.trimmed().isEmpty()) {
0594         return;
0595     }
0596 
0597     // This routine returns the whitespace before the first non white space
0598     // character in string.
0599     // It is assumed that string contains at least one non whitespace character
0600     // ie \n \r \t \v \f and space
0601     QString indentString;
0602 
0603     const int len = string.length();
0604     int i = 0;
0605     while (i < len && string.at(i).isSpace()) {
0606         indentString += string.at(i++);
0607     }
0608 
0609     if (!indentString.isEmpty()) {
0610         c.insertText(indentString);
0611     }
0612 }
0613 
0614 void KNoteEdit::enableRichTextActions(bool enabled)
0615 {
0616     m_textColor->setEnabled(enabled);
0617     m_textFont->setEnabled(enabled);
0618     m_textSize->setEnabled(enabled);
0619 
0620     m_textBold->setEnabled(enabled);
0621     m_textItalic->setEnabled(enabled);
0622     m_textUnderline->setEnabled(enabled);
0623     m_textStrikeOut->setEnabled(enabled);
0624 
0625     m_textAlignLeft->setEnabled(enabled);
0626     m_textAlignCenter->setEnabled(enabled);
0627     m_textAlignRight->setEnabled(enabled);
0628     m_textAlignBlock->setEnabled(enabled);
0629 
0630     m_textList->setEnabled(enabled);
0631     m_textSuper->setEnabled(enabled);
0632     m_textSub->setEnabled(enabled);
0633 
0634     m_textIncreaseIndent->setEnabled(enabled);
0635     m_textDecreaseIndent->setEnabled(enabled);
0636 }
0637 
0638 void KNoteEdit::slotInsertDate()
0639 {
0640     NoteShared::NoteEditorUtils noteEditorUtils;
0641     noteEditorUtils.insertDate(this);
0642 }
0643 
0644 void KNoteEdit::slotInsertCheckMark()
0645 {
0646     QTextCursor cursor = textCursor();
0647     NoteShared::NoteEditorUtils noteEditorUtils;
0648     noteEditorUtils.addCheckmark(cursor);
0649 }
0650 
0651 void KNoteEdit::setCursorPositionFromStart(int pos)
0652 {
0653     if (pos > 0) {
0654         QTextCursor cursor = textCursor();
0655         // Fix html pos cursor
0656         cursor.setPosition(qMin(pos, cursor.document()->characterCount() - 1));
0657         setTextCursor(cursor);
0658         ensureCursorVisible();
0659     }
0660 }
0661 
0662 int KNoteEdit::cursorPositionFromStart() const
0663 {
0664     return textCursor().position();
0665 }
0666 
0667 #include "moc_knoteedit.cpp"