[calligra] /: Make paragraph and character dialogs actually work, and use the new visitor

Elvis Stansvik elvstone at gmail.com
Sat Mar 10 09:52:04 GMT 2012


2012/3/9 C. Boemann <cbo at boemann.dk>:
> Could someone please review and take it for a spin so i can backport it

Works fine here. Tested on single and multiple paragraphs and
undo/redo. Please backport.

Side note: At the moment it's impossible to e.g. directly format e.g.
the underlining of a paragraph while still having the font family
taken from the style. Is this just a fact of life or a bug that should
be fixed? It should be possible right? E.g. test the following:

- Insert a para (style Default)
- Make it underlined in Paragraph Settings
- Change font in style Default to monospace
- Nothing happens

Anyways, great work and sorry for dropping the ball on this one.

Elvis

>
>
> ----------  Forwarded Message  ----------
>
> Subject: [calligra] /: Make paragraph and character dialogs actually work, and
> use the new visitor
> Date: Friday 09 March 2012
> From: "C. Boemann" <cbo at boemann.dk>
> To: kde-commits at kde.org
>
> Git commit f829eea91c2fe479a496730af08dff897a99bea7 by C. Boemann.
> Committed on 09/03/2012 at 19:41.
> Pushed by boemann into branch 'master'.
>
> Make paragraph and character dialogs actually work, and use the new visitor
> so it doesn't apply to protected blocks.
> Undo also seems to work.
>
> M  +4    -0    libs/kotext/KoTextEditor.h
> M  +112  -3    libs/kotext/KoTextEditor_format.cpp
> M  +4    -6    plugins/textshape/TextTool.cpp
> M  +3    -3    plugins/textshape/dialogs/CharacterGeneral.cpp
> M  +1    -1    plugins/textshape/dialogs/CharacterGeneral.h
> M  +12   -40   plugins/textshape/dialogs/FontDia.cpp
> M  +3    -10   plugins/textshape/dialogs/FontDia.h
> M  +12   -9    plugins/textshape/dialogs/ParagraphSettingsDialog.cpp
> M  +3    -9    plugins/textshape/dialogs/ParagraphSettingsDialog.h
>
> http://commits.kde.org/calligra/f829eea91c2fe479a496730af08dff897a99bea7
>
> diff --git a/libs/kotext/KoTextEditor.h b/libs/kotext/KoTextEditor.h
> index c98a427..1f81cf5 100644
> --- a/libs/kotext/KoTextEditor.h
> +++ b/libs/kotext/KoTextEditor.h
> @@ -206,6 +206,10 @@ public slots:
>
>     void setStyle(KoCharacterStyle *style);
>
> +    void mergeAutoStyle(QTextCharFormat deltaCharFormat);
> +
> +    void mergeAutoStyle(QTextCharFormat deltaCharFormat, QTextBlockFormat
> deltaBlockFormat);
> +
>     /**
>      * Insert an inlineObject (such as a variable) at the current cursor
> position. Possibly replacing the selection.
>      * @param inliner the object to insert.
> diff --git a/libs/kotext/KoTextEditor_format.cpp
> b/libs/kotext/KoTextEditor_format.cpp
> index f969ef2..f862719 100644
> --- a/libs/kotext/KoTextEditor_format.cpp
> +++ b/libs/kotext/KoTextEditor_format.cpp
> @@ -407,7 +407,6 @@ public:
>     virtual void visitFragmentSelection(QTextCursor fragmentSelection)
>     {
>         QTextCharFormat format = m_newFormat;
> -        fragmentSelection.charFormat();
>
>         QVariant v;
>         v =
> fragmentSelection.charFormat().property(KoCharacterStyle::InlineInstanceId);
> @@ -438,7 +437,7 @@ public:
>  void KoTextEditor::setStyle(KoCharacterStyle *style)
>  {
>     Q_ASSERT(style);
> -    d->updateState(KoTextEditor::Private::Format, i18n("Set Character
> Style"));
> +    d->updateState(KoTextEditor::Private::Custom, i18n("Set Character
> Style"));
>
>     SetCharacterStyleVisitor visitor(this, style);
>
> @@ -478,7 +477,7 @@ public:
>
>  void KoTextEditor::setStyle(KoParagraphStyle *style)
>  {
> -    d->updateState(KoTextEditor::Private::Format, i18n("Set Paragraph
> Style"));
> +    d->updateState(KoTextEditor::Private::Custom, i18n("Set Paragraph
> Style"));
>
>     KoStyleManager *styleManager = KoTextDocument(d-
>>document).styleManager();
>     SetParagraphStyleVisitor visitor(this, styleManager, style);
> @@ -489,6 +488,116 @@ void KoTextEditor::setStyle(KoParagraphStyle *style)
>     emit textFormatChanged();
>  }
>
> +class MergeAutoCharacterStyleVisitor : public KoTextVisitor
> +{
> +public:
> +    MergeAutoCharacterStyleVisitor(KoTextEditor *editor, QTextCharFormat
> deltaCharFormat)
> +        : KoTextVisitor(editor)
> +        , m_deltaCharFormat(deltaCharFormat)
> +    {
> +    }
> +
> +    virtual void visitBlock(QTextBlock block, const QTextCursor &caret)
> +    {
> +        KoTextVisitor::visitBlock(block, caret);
> +
> +        QList<QTextCharFormat>::Iterator it = m_formats.begin();
> +        foreach(QTextCursor cursor, m_cursors) {
> +            QTextFormat prevFormat(cursor.charFormat());
> +            cursor.setCharFormat(*it);
> +            editor()->registerTrackedChange(cursor,
> KoGenChange::FormatChange, i18n("Formatting"), *it, prevFormat, false);
> +            ++it;
> +        }
> +    }
> +
> +    virtual void visitFragmentSelection(QTextCursor fragmentSelection)
> +    {
> +        QTextCharFormat format = fragmentSelection.charFormat();
> +        format.merge(m_deltaCharFormat);
> +
> +        m_formats.append(format);
> +        m_cursors.append(fragmentSelection);
> +    }
> +
> +    QTextCharFormat m_deltaCharFormat;
> +    QList<QTextCharFormat> m_formats;
> +    QList<QTextCursor> m_cursors;
> +};
> +
> +void KoTextEditor::mergeAutoStyle(QTextCharFormat deltaCharFormat)
> +{
> +    d->updateState(KoTextEditor::Private::Custom, "Formatting");
> +
> +    MergeAutoCharacterStyleVisitor visitor(this, deltaCharFormat);
> +
> +    recursivelyVisitSelection(d->document->rootFrame()->begin(), visitor);
> +
> +    d->updateState(KoTextEditor::Private::NoOp);
> +    emit textFormatChanged();
> +}
> +
> +class MergeAutoParagraphStyleVisitor : public KoTextVisitor
> +{
> +public:
> +    MergeAutoParagraphStyleVisitor(KoTextEditor *editor, QTextCharFormat
> deltaCharFormat, QTextBlockFormat deltaBlockFormat)
> +        : KoTextVisitor(editor)
> +        , m_deltaCharFormat(deltaCharFormat)
> +        , m_deltaBlockFormat(deltaBlockFormat)
> +    {
> +    }
> +
> +    virtual void visitBlock(QTextBlock block, const QTextCursor &caret)
> +    {
> +        for (QTextBlock::iterator it = block.begin(); it != block.end();
> ++it) {
> +            QTextCursor fragmentSelection(caret);
> +            fragmentSelection.setPosition(it.fragment().position());
> +            fragmentSelection.setPosition(it.fragment().position() +
> it.fragment().length(), QTextCursor::KeepAnchor);
> +
> +            if (fragmentSelection.anchor() >= fragmentSelection.position()) {
> +                continue;
> +            }
> +
> +            visitFragmentSelection(fragmentSelection);
> +        }
> +
> +        QList<QTextCharFormat>::Iterator it = m_formats.begin();
> +        foreach(QTextCursor cursor, m_cursors) {
> +            QTextFormat prevFormat(cursor.charFormat());
> +            cursor.setCharFormat(*it);
> +            editor()->registerTrackedChange(cursor,
> KoGenChange::FormatChange, i18n("Formatting"), *it, prevFormat, false);
> +            ++it;
> +        }
> +        QTextCursor cursor(caret);
> +        cursor.mergeBlockFormat(m_deltaBlockFormat);
> +        cursor.mergeBlockCharFormat(m_deltaCharFormat);
> +    }
> +
> +    virtual void visitFragmentSelection(QTextCursor fragmentSelection)
> +    {
> +        QTextCharFormat format = fragmentSelection.charFormat();
> +        format.merge(m_deltaCharFormat);
> +
> +        m_formats.append(format);
> +        m_cursors.append(fragmentSelection);
> +    }
> +
> +    QTextCharFormat m_deltaCharFormat;
> +    QTextBlockFormat m_deltaBlockFormat;
> +    QList<QTextCharFormat> m_formats;
> +    QList<QTextCursor> m_cursors;
> +};
> +
> +void KoTextEditor::mergeAutoStyle(QTextCharFormat deltaCharFormat,
> QTextBlockFormat deltaBlockFormat)
> +{
> +    d->updateState(KoTextEditor::Private::Custom, "Formatting");
> +
> +    MergeAutoParagraphStyleVisitor visitor(this, deltaCharFormat,
> deltaBlockFormat);
> +
> +    recursivelyVisitSelection(d->document->rootFrame()->begin(), visitor);
> +
> +    d->updateState(KoTextEditor::Private::NoOp);
> +    emit textFormatChanged();
> +}
>
>  QTextCharFormat KoTextEditor::blockCharFormat() const
>  {
> diff --git a/plugins/textshape/TextTool.cpp b/plugins/textshape/TextTool.cpp
> index 2efab17..7e098a8 100644
> --- a/plugins/textshape/TextTool.cpp
> +++ b/plugins/textshape/TextTool.cpp
> @@ -1848,13 +1848,12 @@ void TextTool::splitTableCells()
>
>  void TextTool::formatParagraph()
>  {
> -    ParagraphSettingsDialog *dia = new ParagraphSettingsDialog(this,
> m_textEditor.data()->cursor());//TODO  check this with KoTextEditor
> +    ParagraphSettingsDialog *dia = new ParagraphSettingsDialog(this,
> m_textEditor.data());
>     dia->setUnit(canvas()->unit());
> -    connect(dia, SIGNAL(startMacro(const QString&)), this,
> SLOT(startMacro(const QString&)));//TODO
> -    connect(dia, SIGNAL(stopMacro()), this, SLOT(stopMacro()));
>
>     dia->exec();
>     delete dia;
> +    returnFocusToCanvas();
>  }
>
>  void TextTool::testSlot(bool on)
> @@ -1997,11 +1996,10 @@ void TextTool::insertString(const QString& string)
>
>  void TextTool::selectFont()
>  {
> -    FontDia *fontDlg = new FontDia(m_textEditor.data()->cursor());//TODO
> check this with KoTextEditor
> -    connect(fontDlg, SIGNAL(startMacro(const QString &)), this,
> SLOT(startMacro(const QString &)));
> -    connect(fontDlg, SIGNAL(stopMacro()), this, SLOT(stopMacro()));
> +    FontDia *fontDlg = new FontDia(m_textEditor.data());
>     fontDlg->exec();
>     delete fontDlg;
> +    returnFocusToCanvas();
>  }
>
>  void TextTool::shapeAddedToCanvas()
> diff --git a/plugins/textshape/dialogs/CharacterGeneral.cpp
> b/plugins/textshape/dialogs/CharacterGeneral.cpp
> index c2315c1..5366b2e 100644
> --- a/plugins/textshape/dialogs/CharacterGeneral.cpp
> +++ b/plugins/textshape/dialogs/CharacterGeneral.cpp
> @@ -29,14 +29,14 @@
>
>  #include "kdebug.h"
>
> -CharacterGeneral::CharacterGeneral(QWidget *parent, bool uniqueFormat)
> +CharacterGeneral::CharacterGeneral(QWidget *parent)
>         : QWidget(parent),
>         m_blockSignals(false),
>         m_style(0)
>  {
>     widget.setupUi(this);
>
> -    m_characterHighlighting = new CharacterHighlighting(uniqueFormat, this);
> +    m_characterHighlighting = new CharacterHighlighting(true, this);
>     connect(m_characterHighlighting,
> SIGNAL(underlineChanged(KoCharacterStyle::LineType,
> KoCharacterStyle::LineStyle, QColor)), this,
> SLOT(slotUnderlineChanged(KoCharacterStyle::LineType,
> KoCharacterStyle::LineStyle, QColor)));
>     connect(m_characterHighlighting,
> SIGNAL(strikethroughChanged(KoCharacterStyle::LineType,
> KoCharacterStyle::LineStyle, QColor)), this,
> SLOT(slotStrikethroughChanged(KoCharacterStyle::LineType,
> KoCharacterStyle::LineStyle, QColor)));
>     connect(m_characterHighlighting,
> SIGNAL(capitalizationChanged(QFont::Capitalization)), this,
> SLOT(slotCapitalizationChanged(QFont::Capitalization)));
> @@ -44,7 +44,7 @@ CharacterGeneral::CharacterGeneral(QWidget *parent, bool
> uniqueFormat)
>     connect(m_characterHighlighting, SIGNAL(backgroundColorChanged(QColor)),
> this, SLOT(slotBackgroundColorChanged(QColor)));
>     connect(m_characterHighlighting, SIGNAL(textColorChanged(QColor)), this,
> SLOT(slotTextColorChanged(QColor)));
>
> -    m_languageTab = new LanguageTab(uniqueFormat, this);
> +    m_languageTab = new LanguageTab(true, this);
>
>     widget.tabs->addTab(m_characterHighlighting, i18n("Font"));
>
> diff --git a/plugins/textshape/dialogs/CharacterGeneral.h
> b/plugins/textshape/dialogs/CharacterGeneral.h
> index 8946bc3..cd025a6 100644
> --- a/plugins/textshape/dialogs/CharacterGeneral.h
> +++ b/plugins/textshape/dialogs/CharacterGeneral.h
> @@ -33,7 +33,7 @@ class CharacterGeneral : public QWidget
>  {
>     Q_OBJECT
>  public:
> -    explicit CharacterGeneral(QWidget *parent = 0, bool uniqueFormat = true);
> +    explicit CharacterGeneral(QWidget *parent = 0);
>
>     void setStyle(KoCharacterStyle *style);
>     void hideStyleName(bool hide);
> diff --git a/plugins/textshape/dialogs/FontDia.cpp
> b/plugins/textshape/dialogs/FontDia.cpp
> index 80f1aec..599a295 100644
> --- a/plugins/textshape/dialogs/FontDia.cpp
> +++ b/plugins/textshape/dialogs/FontDia.cpp
> @@ -28,6 +28,8 @@
>
>  #include "FormattingPreview.h"
>
> +#include <KoTextEditor.h>
> +
>  #include <klocale.h>
>  #include <kvbox.h>
>  #include <kfontdialog.h>
> @@ -37,50 +39,18 @@
>  #include <QTextDocument>
>  #include <QTextCursor>
>
> -FontDia::FontDia(QTextCursor* cursor, QWidget* parent)
> -        : KDialog(parent),
> -        m_cursor(cursor)
> +FontDia::FontDia(KoTextEditor *editor, QWidget* parent)
> +        : KDialog(parent)
> +        , m_editor(editor)
>  {
> -    //First find out if we have more than one charFormat in our selection. If
> so, m_initialFormat/m_style will get initialised with the charFormat at the
> cursor's position. The tabs will get informed of this.
> -
> -    if (m_cursor->hasSelection()) {
> -        int begin = qMin(m_cursor->anchor(), m_cursor->position());
> -        int end = qMax(m_cursor->anchor(), m_cursor->position());
> -        QTextBlock block = m_cursor->block().document()->findBlock(begin);
> -        m_uniqueFormat = true;
> -        QTextCursor caret(*m_cursor);
> -        caret.setPosition(begin+1);
> -        m_initialFormat = caret.charFormat();
> -        while (block.isValid() && block.position() < end) {
> -            QTextBlock::iterator iter = block.begin();
> -            while (! iter.atEnd()) {
> -                QTextFragment fragment = iter.fragment();
> -                if (fragment.position() >= end)
> -                    break;
> -                if (fragment.position() + fragment.length() <= begin) {
> -                    ++iter;
> -                    continue;
> -                }
> -                if (!(m_uniqueFormat = (fragment.charFormat() ==
> m_initialFormat)))
> -                    break;
> -                ++iter;
> -            }
> -            if (!m_uniqueFormat)
> -                break;
> -            block = block.next();
> -        }
> -    }
> -    else {
> -        m_initialFormat = cursor->charFormat();
> -        m_uniqueFormat = true;
> -    }
> +    m_initialFormat = m_editor->charFormat();
>
>     setCaption(i18n("Select Font"));
>     setModal(true);
>     setButtons(Ok | Cancel | Reset | Apply);
>     setDefaultButton(Ok);
>
> -    m_characterGeneral = new CharacterGeneral(this, m_uniqueFormat);
> +    m_characterGeneral = new CharacterGeneral(this);
>     m_characterGeneral->hideStyleName(true);
>     setMainWidget(m_characterGeneral);
>
> @@ -98,11 +68,13 @@ void FontDia::initTabs()
>
>  void FontDia::slotApply()
>  {
> -    emit startMacro(i18n("Font"));
> +    m_editor->beginEditBlock(i18n("Font"));
>     KoCharacterStyle chosenStyle;
>     m_characterGeneral->save(&chosenStyle);
> -    chosenStyle.applyStyle(m_cursor);
> -    emit stopMacro();
> +    QTextCharFormat cformat;
> +    chosenStyle.applyStyle(cformat);
> +    m_editor->mergeAutoStyle(cformat);
> +    m_editor->endEditBlock();
>  }
>
>  void FontDia::slotOk()
> diff --git a/plugins/textshape/dialogs/FontDia.h
> b/plugins/textshape/dialogs/FontDia.h
> index 7f8e6e0..9ae9567 100644
> --- a/plugins/textshape/dialogs/FontDia.h
> +++ b/plugins/textshape/dialogs/FontDia.h
> @@ -26,8 +26,7 @@
>  #include <kdialog.h>
>  #include <KoCharacterStyle.h>
>
> -#include <QTextCursor>
> -
> +class KoTextEditor;
>
>  class CharacterGeneral;
>
> @@ -35,13 +34,7 @@ class FontDia : public KDialog
>  {
>     Q_OBJECT
>  public:
> -    explicit FontDia(QTextCursor *cursor, QWidget* parent = 0);
> -
> -signals:
> -    /// emitted when a series of commands is started that together need to
> become 1 undo action.
> -    void startMacro(const QString &name);
> -    /// emitted when a series of commands has ended that together should be 1
> undo action.
> -    void stopMacro();
> +    explicit FontDia(KoTextEditor *cursor, QWidget* parent = 0);
>
>  protected slots:
>     void slotReset();
> @@ -53,7 +46,7 @@ private:
>
>     CharacterGeneral *m_characterGeneral;
>
> -    QTextCursor* m_cursor;
> +    KoTextEditor *m_editor;
>     QTextCharFormat m_initialFormat;
>
>     bool m_uniqueFormat;
> diff --git a/plugins/textshape/dialogs/ParagraphSettingsDialog.cpp
> b/plugins/textshape/dialogs/ParagraphSettingsDialog.cpp
> index 85ca90b..befcaca 100644
> --- a/plugins/textshape/dialogs/ParagraphSettingsDialog.cpp
> +++ b/plugins/textshape/dialogs/ParagraphSettingsDialog.cpp
> @@ -30,10 +30,10 @@
>  #include <QTextBlock>
>  #include <QTimer>
>
> -ParagraphSettingsDialog::ParagraphSettingsDialog(TextTool *tool, QTextCursor
> *cursor, QWidget* parent)
> +ParagraphSettingsDialog::ParagraphSettingsDialog(TextTool *tool, KoTextEditor
> *editor, QWidget* parent)
>         : KDialog(parent),
>         m_tool(tool),
> -        m_cursor(cursor)
> +        m_editor(editor)
>  {
>     setCaption(i18n("Paragraph Format"));
>     setModal(true);
> @@ -55,8 +55,8 @@ ParagraphSettingsDialog::~ParagraphSettingsDialog()
>
>  void ParagraphSettingsDialog::initTabs()
>  {
> -    KoParagraphStyle *style = KoParagraphStyle::fromBlock(m_cursor->block());
> -    m_paragraphGeneral->setStyle(style, KoList::level(m_cursor->block()));
> +    KoParagraphStyle *style = KoParagraphStyle::fromBlock(m_editor->block());
> +    m_paragraphGeneral->setStyle(style, KoList::level(m_editor->block()));
>  }
>
>  void ParagraphSettingsDialog::slotOk()
> @@ -67,23 +67,26 @@ void ParagraphSettingsDialog::slotOk()
>
>  void ParagraphSettingsDialog::slotApply()
>  {
> -    emit startMacro(i18n("Paragraph Settings"));
> +    m_editor->beginEditBlock(i18n("Paragraph Settings"));
>     KoParagraphStyle chosenStyle;
>     m_paragraphGeneral->save(&chosenStyle);
> +    QTextCharFormat cformat;
>     QTextBlockFormat format;
> +    chosenStyle.KoCharacterStyle::applyStyle(cformat);
>     chosenStyle.applyStyle(format);
> -    m_cursor->mergeBlockFormat(format);
> +
> +    m_editor->mergeAutoStyle(cformat, format);
>     if (chosenStyle.listStyle()) {
>         KoTextEditor::ChangeListFlags flags(KoTextEditor::AutoListStyle |
> KoTextEditor::DontUnsetIfSame);
>         m_tool->textEditor()->setListProperties(chosenStyle.listStyle()-
>>levelProperties(chosenStyle.listStyle()->listLevels().first()),
>                                                 flags);
>     } else {
> -        QTextList *list = m_cursor->block().textList();
> +        QTextList *list = m_editor->block().textList();
>         if (list) { // then remove it.
> -            list->remove(m_cursor->block());
> +            list->remove(m_editor->block());
>         }
>     }
> -    emit stopMacro();
> +    m_editor->endEditBlock();
>  }
>
>  void ParagraphSettingsDialog::setUnit(const KoUnit &unit)
> diff --git a/plugins/textshape/dialogs/ParagraphSettingsDialog.h
> b/plugins/textshape/dialogs/ParagraphSettingsDialog.h
> index 7224692..c54d8e0 100644
> --- a/plugins/textshape/dialogs/ParagraphSettingsDialog.h
> +++ b/plugins/textshape/dialogs/ParagraphSettingsDialog.h
> @@ -20,9 +20,9 @@
>  #define PARAGRAPHSETTINGSDIALOG_H
>
>  #include <KoUnit.h>
> +#include <KoTextEditor.h>
>
>  #include <KDialog>
> -#include <QTextCursor>
>
>  class TextTool;
>  class ParagraphGeneral;
> @@ -32,17 +32,11 @@ class ParagraphSettingsDialog : public KDialog
>  {
>     Q_OBJECT
>  public:
> -    explicit ParagraphSettingsDialog(TextTool *tool, QTextCursor *cursor,
> QWidget* parent = 0);
> +    explicit ParagraphSettingsDialog(TextTool *tool, KoTextEditor *editor,
> QWidget* parent = 0);
>     ~ParagraphSettingsDialog();
>
>     void setUnit(const KoUnit &unit);
>
> -signals:
> -    /// emitted when a series of commands is started that together need to
> become 1 undo action.
> -    void startMacro(const QString &name);
> -    /// emitted when a series of commands has ended that together should be 1
> undo action.
> -    void stopMacro();
> -
>  protected slots:
>     void slotApply();
>     void slotOk();
> @@ -52,7 +46,7 @@ private:
>
>     ParagraphGeneral *m_paragraphGeneral;
>     TextTool *m_tool;
> -    QTextCursor *m_cursor;
> +    KoTextEditor *m_editor;
>     bool m_uniqueFormat;
>  };
>
>
> -------------------------------------------------------
> _______________________________________________
> calligra-devel mailing list
> calligra-devel at kde.org
> https://mail.kde.org/mailman/listinfo/calligra-devel



More information about the calligra-devel mailing list