[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    koffice
From:       Thomas Zander <zander () kde ! org>
Date:       2009-09-01 15:20:48
Message-ID: 1251818448.150558.7953.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 1018326 by zander:

Reimplement checking the document for bidi-ness, this time non-multi-threading.

BUG:186100

 M  +7 -1      kword/part/KWView.cpp  
 M  +0 -1      libs/kotext/KoText.h  
 M  +96 -5     libs/kotext/KoTextEditor.cpp  
 M  +7 -0      libs/kotext/KoTextEditor.h  
 M  +10 -87    plugins/textshape/TextTool.cpp  
 M  +2 -13     plugins/textshape/TextTool.h  


--- trunk/koffice/kword/part/KWView.cpp #1018325:1018326
@@ -43,6 +43,7 @@
 
 // koffice libs includes
 #include <KoCopyController.h>
+#include <KoTextDocument.h>
 #include <KoShapeCreateCommand.h>
 #include <KoImageSelectionWidget.h>
 #include <KoCanvasResourceProvider.h>
@@ -1010,7 +1011,12 @@
     if (! m_currentPage.isValid())
         return;
     KWPageSettingsDialog *dia = new KWPageSettingsDialog(this, m_document, \
                m_currentPage);
-    dia->showTextDirection(kwcanvas()->resourceProvider()->boolResource(KoText::BidiDocument));
 +    if (m_document->mainFrameSet()) {
+        KoTextDocument doc(m_document->mainFrameSet()->document());
+        KoTextEditor *editor = doc.textEditor();
+        if (editor)
+            dia->showTextDirection(editor->isBidiDocument());
+    }
     dia->show();
 }
 
--- trunk/koffice/libs/kotext/KoText.h #1018325:1018326
@@ -49,7 +49,6 @@
     ShowTabs,           ///< boolean that enables painting of tabs
     ShowEnters,         ///< boolean that enables painting of enters (linefeed \
                chars)
     ShowSpecialCharacters,  ///< boolean that enables painting of special characters \
                (nbsp etc)
-    BidiDocument = 493038196,
     CurrentTextDocument = 382490375, ///< set by the text plugin whenever the \
                document is changed
     CurrentTextPosition = 183523,   ///<  used by the text plugin whenever the \
                position is changed
     CurrentTextAnchor = 341899485,   ///<  used by the text plugin whenever the \
                anchor-position is changed
--- trunk/koffice/libs/kotext/KoTextEditor.cpp #1018325:1018326
@@ -1,5 +1,6 @@
 /* This file is part of the KDE project
  * Copyright (C) 2009 Pierre Stirnweiss <pstirnweiss@googlemail.com>
+ * Copyright (C) 2006-2009 Thomas Zander <zander@kde.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -39,6 +40,7 @@
 
 #include <KLocale>
 
+#include <QApplication>
 #include <QFontDatabase>
 #include <QTextBlock>
 #include <QTextBlockFormat>
@@ -47,11 +49,37 @@
 #include <QTextDocumentFragment>
 #include <QTextFormat>
 #include <QTextTable>
+#include <QTimer>
 #include <QString>
 #include <QUndoCommand>
 
 #include <kdebug.h>
 
+static bool isRightToLeft(const QString &text)
+{
+    int ltr = 0, rtl = 0;
+
+    QString::const_iterator iter = text.begin();
+    while (iter != text.end()) {
+        switch (QChar::direction((*iter).unicode())) {
+        case QChar::DirL:
+        case QChar::DirLRO:
+        case QChar::DirLRE:
+            ltr++;
+            break;
+        case QChar::DirR:
+        case QChar::DirAL:
+        case QChar::DirRLO:
+        case QChar::DirRLE:
+            rtl++;
+        default:
+            break;
+        }
+        ++iter;
+    }
+    return ltr < rtl;
+}
+
 /*Private*/
 
 class KoTextEditor::Private
@@ -65,7 +93,7 @@
         Custom
     };
 
-    explicit Private(QTextDocument *document);
+    explicit Private(KoTextEditor *qq, QTextDocument *document);
 
     ~Private() {}
 
@@ -74,22 +102,33 @@
 
     bool deleteInlineObjects(bool backwards = false);
     void deleteSelection();
+    void runDirectionUpdater();
 
+    KoTextEditor *q;
     QTextCursor caret;
     QTextDocument *document;
     QUndoCommand *headCommand;
     QString commandTitle;
     KoText::Direction direction;
+    bool isBidiDocument;
 
     State editorState;
+
+    QTimer updateRtlTimer;
+    QList<int> dirtyBlocks;
 };
 
-KoTextEditor::Private::Private(QTextDocument *document)
-    : document (document),
-    headCommand(0)
+KoTextEditor::Private::Private(KoTextEditor *qq, QTextDocument *document)
+    : q(qq),
+    document (document),
+    headCommand(0),
+    isBidiDocument(false)
 {
     caret = QTextCursor(document);
     editorState = NoOp;
+    updateRtlTimer.setSingleShot(true);
+    updateRtlTimer.setInterval(250);
+    QObject::connect(&updateRtlTimer, SIGNAL(timeout()), q, \
SLOT(runDirectionUpdater()));  }
 
 void KoTextEditor::Private::documentCommandAdded()
@@ -234,6 +273,45 @@
     }
 }
 
+void KoTextEditor::Private::runDirectionUpdater()
+{
+    while (! dirtyBlocks.isEmpty()) {
+        const int blockNumber = dirtyBlocks.first();
+        dirtyBlocks.removeAll(blockNumber);
+        QTextBlock block = document->findBlockByNumber(blockNumber);
+        if (block.isValid()) {
+            KoText::Direction newDirection = KoText::AutoDirection;
+            QTextBlockFormat format = block.blockFormat();
+            KoText::Direction dir =
+                static_cast<KoText::Direction>(format.intProperty(KoParagraphStyle::TextProgressionDirection));
 +
+            if (dir == KoText::AutoDirection || dir == \
KoText::PerhapsLeftRightTopBottom || +                    dir == \
KoText::PerhapsRightLeftTopBottom) { +                bool rtl = \
isRightToLeft(block.text()); +                if (rtl && (dir != \
KoText::AutoDirection || QApplication::isLeftToRight())) +                    \
newDirection = KoText::PerhapsRightLeftTopBottom; +                else if (!rtl && \
(dir != KoText::AutoDirection || QApplication::isRightToLeft())) // remove previously \
set one if needed. +                    newDirection = \
KoText::PerhapsLeftRightTopBottom; +
+                QTextCursor cursor(block);
+                if (format.property(KoParagraphStyle::TextProgressionDirection).toInt() \
!= newDirection) { +                    \
format.setProperty(KoParagraphStyle::TextProgressionDirection, newDirection); +       \
cursor.setBlockFormat(format); // note that setting this causes a re-layout. +        \
} +                if (!isBidiDocument) {
+                    if ((QApplication::isLeftToRight() && (newDirection == \
KoText::RightLeftTopBottom +                                    || newDirection == \
KoText::PerhapsRightLeftTopBottom)) +                            || \
(QApplication::isRightToLeft() && (newDirection == KoText::LeftRightTopBottom +       \
|| newDirection == KoText::PerhapsLeftRightTopBottom))) { +                        \
isBidiDocument = true; +                        emit q->isBidiUpdated();
+                    }
+                }
+            }
+        }
+    }
+}
+
 /*KoTextEditor*/
 
 //TODO factor out the changeTracking charFormat setting from all individual slots to \
a public slot, which will be available for external commands (TextShape) @@ -357,7 \
+435,7 @@  
 KoTextEditor::KoTextEditor(QTextDocument *document)
     : KoToolSelection(document),
-    d (new Private(document))
+    d (new Private(this, document))
 {
     connect (d->document, SIGNAL (undoCommandAdded()), this, SLOT \
(documentCommandAdded()));  }
@@ -981,7 +1059,15 @@
         QTextCharFormat format = d->caret.charFormat();
         registerTrackedChange(d->caret, KoGenChange::insertChange, i18n("Key \
Press"), format, format, false);  }
+    int blockNumber = d->caret.blockNumber();
     d->caret.insertText(text);
+
+    while (blockNumber <= d->caret.blockNumber()) {
+        d->dirtyBlocks << blockNumber;
+        ++blockNumber;
+    }
+    d->updateRtlTimer.stop();
+    d->updateRtlTimer.start();
 }
 
 void KoTextEditor::insertText(const QString &text, const QTextCharFormat &format)
@@ -1138,4 +1224,9 @@
     return d->caret.visualNavigation();
 }
 
+bool KoTextEditor::isBidiDocument() const
+{
+    return d->isBidiDocument;
+}
+
 #include "KoTextEditor.moc"
--- trunk/koffice/libs/kotext/KoTextEditor.h #1018325:1018326
@@ -1,5 +1,6 @@
 /* This file is part of the KDE project
 * Copyright (C) 2009 Pierre Stirnweiss <pstirnweiss@googlemail.com>
+* Copyright (C) 2009 Thomas Zander <zander@kde.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
@@ -234,8 +235,14 @@
 
     bool visualNavigation() const;
 
+    bool isBidiDocument() const;
+
+signals:
+    void isBidiUpdated();
+
 private:
     Q_PRIVATE_SLOT(d, void documentCommandAdded())
+    Q_PRIVATE_SLOT(d, void runDirectionUpdater())
 
     class Private;
     Private* const d;
--- trunk/koffice/plugins/textshape/TextTool.cpp #1018325:1018326
@@ -110,31 +110,6 @@
     return false;
 }
 
-static bool isRightToLeft(const QString &text)
-{
-    int ltr = 0, rtl = 0;
-
-    QString::const_iterator iter = text.begin();
-    while (iter != text.end()) {
-        switch (QChar::direction((*iter).unicode())) {
-        case QChar::DirL:
-        case QChar::DirLRO:
-        case QChar::DirLRE:
-            ltr++;
-            break;
-        case QChar::DirR:
-        case QChar::DirAL:
-        case QChar::DirRLO:
-        case QChar::DirRLE:
-            rtl++;
-        default:
-            break;
-        }
-        ++iter;
-    }
-    return ltr < rtl;
-}
-
 TextTool::TextTool(KoCanvasBase *canvas)
         : KoTool(canvas),
         m_textShape(0),
@@ -429,13 +404,6 @@
     action->setWhatsThis(i18n("Insert one or more symbols or characters not found on \
                the keyboard."));
     connect(action, SIGNAL(triggered()), this, SLOT(insertSpecialCharacter()));
 
-    m_updateParagDirection.action = new KoAction(this);
-    m_updateParagDirection.action->setExecutePolicy(KoExecutePolicy::onlyLastPolicy);
                
-    connect(m_updateParagDirection.action, SIGNAL(triggered(const QVariant &)),
-            this, SLOT(updateParagraphDirection(const QVariant&)), \
                Qt::DirectConnection);
-    connect(m_updateParagDirection.action, SIGNAL(updateUi(const QVariant &)),
-            this, SLOT(updateParagraphDirectionUi()));
-
 #ifndef NDEBUG
     action = new KAction("Paragraph Debug", this); // do NOT add i18n!
     action->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_P);
@@ -712,7 +680,10 @@
         return;
     connect(m_textShapeData, SIGNAL(destroyed (QObject*)), this, \
SLOT(shapeDataRemoved()));  if (docChanged) {
+        if (m_textEditor)
+            disconnect(m_textEditor, SIGNAL(isBidiUpdated()), this, \
                SLOT(isBidiUpdated()));
         m_textEditor = KoTextDocument(m_textShapeData->document()).textEditor();
+        connect(m_textEditor, SIGNAL(isBidiUpdated()), this, SLOT(isBidiUpdated()));
 
         if (m_textShape->demoText()) {
             m_textShapeData->document()->setUndoRedoEnabled(false); // removes undo \
history @@ -990,7 +961,6 @@
             ensureCursorVisible();
         } else if (event->key() == Qt::Key_Tab || !(event->text().length() == 1 && \
!event->text().at(0).isPrint())) { // insert the text  \
                m_textEditor->insertText(event->text());
-            m_updateParagDirection.action->execute(m_textEditor->position());
             ensureCursorVisible();
         }
     }
@@ -1746,63 +1716,11 @@
 
 bool TextTool::isBidiDocument() const
 {
-    if (m_canvas->resourceProvider())
-        return m_canvas->resourceProvider()->boolResource(KoText::BidiDocument);
+    if (m_textEditor)
+        return m_textEditor->isBidiDocument();
     return false;
 }
 
-void TextTool::updateParagraphDirection(const QVariant &variant)
-{
-    int position = variant.toInt();
-    KoTextShapeData *data = m_textShapeData;
-    if (data == 0) // tool is deactivated already
-        return;
-    m_updateParagDirection.block = data->document()->findBlock(position);
-    m_updateParagDirection.direction = KoText::AutoDirection;
-    if (! m_updateParagDirection.block.isValid())
-        return;
-    QTextBlockFormat format = m_updateParagDirection.block.blockFormat();
-
-    KoText::Direction dir =
-        static_cast<KoText::Direction>(format.intProperty(KoParagraphStyle::TextProgressionDirection));
                
-
-    if (dir == KoText::AutoDirection || dir == KoText::PerhapsLeftRightTopBottom ||
-            dir == KoText::PerhapsRightLeftTopBottom) {
-        bool rtl = isRightToLeft(m_updateParagDirection.block.text());
-        if (rtl && (dir != KoText::AutoDirection || QApplication::isLeftToRight()))
-            m_updateParagDirection.direction = KoText::PerhapsRightLeftTopBottom;
-        else if (!rtl && (dir != KoText::AutoDirection || \
                QApplication::isRightToLeft())) // remove previously set one if \
                needed.
-            m_updateParagDirection.direction = KoText::PerhapsLeftRightTopBottom;
-    } else
-        m_updateParagDirection.block = QTextBlock();
-}
-//TODO
-void TextTool::updateParagraphDirectionUi()
-{
-    if (! m_updateParagDirection.block.isValid())
-        return;
-    QTextCursor cursor(m_updateParagDirection.block);
-    QTextBlockFormat format = cursor.blockFormat();
-    if (format.property(KoParagraphStyle::TextProgressionDirection).toInt() != \
                m_updateParagDirection.direction) {
-        format.setProperty(KoParagraphStyle::TextProgressionDirection, \
                m_updateParagDirection.direction);
-        cursor.setBlockFormat(format); // note that setting this causes a re-layout.
-    }
-
-    if (m_canvas->resourceProvider() && ! isBidiDocument()) {
-        if ((QApplication::isLeftToRight() &&
-                (m_updateParagDirection.direction == KoText::RightLeftTopBottom ||
-                 m_updateParagDirection.direction == \
                KoText::PerhapsRightLeftTopBottom)) ||
-                (QApplication::isRightToLeft() &&
-                 (m_updateParagDirection.direction == KoText::LeftRightTopBottom ||
-                  m_updateParagDirection.direction == \
                KoText::PerhapsLeftRightTopBottom))) {
-            m_canvas->resourceProvider()->setResource(KoText::BidiDocument, true);
-
-            emit blockChanged(m_textEditor->block()); // make sure that the dialogs \
                follow this change
-        }
-    }
-    updateActions();
-}
-
 void TextTool::resourceChanged(int key, const QVariant &var)
 {
     if (m_allowResourceProviderUpdates == false)
@@ -1821,6 +1739,11 @@
     repaintSelection();
 }
 
+void TextTool::isBidiUpdated()
+{
+    emit blockChanged(m_textEditor->block()); // make sure that the dialogs follow \
this change +}
+
 void TextTool::insertSpecialCharacter()
 {
     if (m_specialCharacterDocker == 0) {
--- trunk/koffice/plugins/textshape/TextTool.h #1018325:1018326
@@ -126,6 +126,8 @@
     /// reimplemented from KoTool
     virtual void resourceChanged(int key, const QVariant &res);
 
+    void isBidiUpdated();
+
 signals:
     /// emitted every time a different styleManager is set.
     void styleManagerChanged(KoStyleManager *manager);
@@ -213,11 +215,6 @@
     /// insert string
     void insertString(const QString &string);
 
-    /// method that will be called in an alternative thread for updating the \
                paragraph direction at a character pos
-    void updateParagraphDirection(const QVariant &variant);
-    /// method that will be called in the UI thread directly after the one above
-    void updateParagraphDirectionUi();
-
     /// returns the focus to canvas when styles are selected in the optionDocker
     void returnFocusToCanvas();
 
@@ -303,14 +300,6 @@
 
     bool m_currentCommandHasChildren;
 
-    // update Parag direction will be multi-threaded.
-    struct UpdatePageDirection {
-        KoAction *action;
-        QTextBlock block;
-        KoText::Direction direction;
-    };
-    UpdatePageDirection m_updateParagDirection;
-
     /// structure that allows us to remember the text position and selection of \
previously edited documents.  struct TextSelection {
         QTextDocument *document; // be warned that this may end up being a dangling \
pointer, so don't use.


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic