[Konversation-devel] [Bug 200833] chat view is left-to-right, even for RTL discussions

Peter Simonsson peter.simonsson at gmail.com
Tue Sep 15 18:47:49 CEST 2009


https://bugs.kde.org/show_bug.cgi?id=200833


Peter Simonsson <peter.simonsson at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |peter.simonsson at gmail.com




--- Comment #1 from Peter Simonsson <peter simonsson gmail com>  2009-09-15 18:47:44 ---
SVN commit 1023945 by psn:

Resurrect RTL text support in ircview.


 M  +1 -0      ChangeLog
 M  +1 -1      src/commit.h
 M  +154 -17   src/viewer/ircview.cpp
 M  +2 -3      src/viewer/ircview.h


--- trunk/extragear/network/konversation/ChangeLog #1023944:1023945
@@ -54,6 +54,7 @@
 * The initial width of the nickname lists in channel tabs is now more sen-
  sible.
 * Added back the ability to drag links out of the chat view.
+* Resurrected the RTL text support in the chat view.


 Changes from 1.2-alpha5 to 1.2-alpha6:
--- trunk/extragear/network/konversation/src/commit.h #1023944:1023945
@@ -1,4 +1,4 @@
 // This COMMIT number is added to version string to be used as "patch level"
 #ifndef COMMIT
-#define COMMIT 3434
+#define COMMIT 3435
 #endif
--- trunk/extragear/network/konversation/src/viewer/ircview.cpp
#1023944:1023945
@@ -36,6 +36,7 @@
 #include <QColor>
 #include <QMouseEvent>
 #include <QScrollBar>
+#include <QTextBlock>

 #include <KUrl>
 #include <KBookmarkManager>
@@ -280,12 +281,24 @@
    QString nickLine = createNickLine(nick, channelColor);

    QString line;
-    line = "<font color=\"" + channelColor + "\">%1" + nickLine + "
%3</font>";
+    bool rtl = (basicDirection(message) == QChar::DirR);
+
+    if(rtl)
+    {
+        line = RLE;
+        line += LRE;
+        line += "<font color=\"" + channelColor + "\">" + nickLine +" %1" +
PDF + RLM + " %3</font>";
+    }
+    else
+    {
+        line = "<font color=\"" + channelColor + "\">%1" + nickLine + "
%3</font>";
+    }
+
    line = line.arg(timeStamp(), nick, filter(message, channelColor, nick,
true));

    emit textToLog(QString("<%1>\t%2").arg(nick).arg(message));

-    doAppend(line);
+    doAppend(line, rtl);
 }

 void IRCView::appendRaw(const QString& message, bool suppressTimestamps, bool
self)
@@ -299,7 +312,7 @@
    else
        line = QString(timeStamp() + " <font color=\"" + channelColor.name() +
"\">" + message + "</font>");

-    doAppend(line, self);
+    doAppend(line, false, self);
 }

 void IRCView::appendLog(const QString & message)
@@ -309,7 +322,7 @@

    QString line("<font color=\"" + channelColor.name() + "\">" + message +
"</font>");

-    doRawAppend(line);
+    doRawAppend(line, !QApplication::isLeftToRight());
 }

 void IRCView::appendQuery(const QString& nick, const QString& message, bool
inChannel)
@@ -321,12 +334,24 @@
    QString nickLine = createNickLine(nick, queryColor, true, inChannel);

    QString line;
-    line = "<font color=\"" + queryColor + "\">%1 " + nickLine + " %3</font>";
+    bool rtl = (basicDirection(message) == QChar::DirR);
+
+    if(rtl)
+    {
+        line = RLE;
+        line += LRE;
+        line += "<font color=\"" + queryColor + "\">" + nickLine + " %1" + PDF
+ RLM + " %3</font>";
+    }
+    else
+    {
+        line = "<font color=\"" + queryColor + "\">%1 " + nickLine + "
%3</font>";
+    }
+
    line = line.arg(timeStamp(), nick, filter(message, queryColor, nick,
true));

    emit textToLog(QString("<%1>\t%2").arg(nick).arg(message));

-    doAppend(line);
+    doAppend(line, rtl);
 }

 void IRCView::appendChannelAction(const QString& nick, const QString& message)
@@ -348,12 +373,24 @@
    QString nickLine = createNickLine(nick, actionColor, false);

    QString line;
-    line = "<font color=\"" + actionColor + "\">%1 * " + nickLine + "
%3</font>";
+    bool rtl = (basicDirection(message) == QChar::DirR);
+
+    if(rtl)
+    {
+        line = RLE;
+        line += LRE;
+        line += "<font color=\"" + actionColor + "\">" + nickLine + " * %1" +
PDF + " %3</font>";
+    }
+    else
+    {
+        line = "<font color=\"" + actionColor + "\">%1 * " + nickLine + "
%3</font>";
+    }
+
    line = line.arg(timeStamp(), nick, filter(message, actionColor, nick,
true));

    emit textToLog(QString("\t * %1 %2").arg(nick).arg(message));

-    doAppend(line);
+    doAppend(line, rtl);
 }

 void IRCView::appendServerMessage(const QString& type, const QString& message,
bool parseURL)
@@ -370,7 +407,19 @@
    }

    QString line;
-    line = "<font color=\"" + serverColor + "\"" + fixed + ">%1
<b>[</b>%2<b>]</b> %3</font>";
+    bool rtl = (basicDirection(message) == QChar::DirR);
+
+    if(rtl)
+    {
+        line = RLE;
+        line += LRE;
+        line += "<font color=\"" + serverColor + "\"" + fixed +
"><b>[</b>%2<b>]</b> %1" + PDF + " %3</font>";
+    }
+    else
+    {
+        line = "<font color=\"" + serverColor + "\"" + fixed + ">%1
<b>[</b>%2<b>]</b> %3</font>";
+    }
+
    if(type != i18n("Notify"))
        line = line.arg(timeStamp(), type, filter(message, serverColor, 0 ,
true, parseURL));
    else
@@ -378,7 +427,7 @@

    emit textToLog(QString("%1\t%2").arg(type).arg(message));

-    doAppend(line);
+    doAppend(line, rtl);
 }

 void IRCView::appendCommandMessage(const QString& type,const QString& message,
bool important, bool parseURL, bool self)
@@ -403,13 +452,24 @@
    prefix=Qt::escape(prefix);

    QString line;
-    line = "<font color=\"" + commandColor + "\">%1 %2 %3</font>";
+    bool rtl = (basicDirection(message) == QChar::DirR);

+    if(rtl)
+    {
+        line = RLE;
+        line += LRE;
+        line += "<font color=\"" + commandColor + "\">%2 %1" + PDF + "
%3</font>";
+    }
+    else
+    {
+        line = "<font color=\"" + commandColor + "\">%1 %2 %3</font>";
+    }
+
    line = line.arg(timeStamp(), prefix, filter(message, commandColor, 0, true,
parseURL, self));

    emit textToLog(QString("%1\t%2").arg(type).arg(message));

-    doAppend(line, self);
+    doAppend(line, rtl, self);
 }

 void IRCView::appendBacklogMessage(const QString& firstColumn,const QString&
rawMessage)
@@ -433,14 +493,25 @@
    nick.replace('>',"&gt;");

    QString line;
+    bool rtl = (basicDirection(message) == QChar::DirR);

-    line = "<font color=\"" + backlogColor + "\">%1 %2 %3</font>";
+    if(rtl)
+    {
+        line = RLE;
+        line += LRE;
+        line += "<font color=\"" + backlogColor + "\">%2 %1" + PDF + "
%3</font>";
+    }
+    else
+    {
+        line = "<font color=\"" + backlogColor + "\">%1 %2 %3</font>";
+    }
+
    line = line.arg(time, nick, filter(message, backlogColor, NULL, false,
false));

-    doAppend(line);
+    doAppend(line, rtl);
 }

-void IRCView::doAppend(const QString& newLine, bool self)
+void IRCView::doAppend(const QString& newLine, bool rtl, bool self)
 {
    if (!self && m_chatWin)
        m_chatWin->activateTabNotification(m_tabNotification);
@@ -454,7 +525,7 @@
        //setMaximumBlockCount(atBottom ? scrollMax : maximumBlockCount() + 1);
    }

-    doRawAppend(newLine);
+    doRawAppend(newLine, rtl);

    //appendHtml(line);

@@ -478,7 +549,7 @@
        emit clearStatusBarTempText();
 }

-void IRCView::doRawAppend(const QString& newLine)
+void IRCView::doRawAppend(const QString& newLine, bool rtl)
 {
    QString line(newLine);

@@ -499,6 +570,11 @@

    KTextBrowser::append(line);

+    QTextCursor formatCursor(document()->lastBlock());
+    QTextBlockFormat format = formatCursor.blockFormat();
+    format.setAlignment(rtl ? Qt::AlignRight : Qt::AlignLeft);
+    formatCursor.setBlockFormat(format);
+
    if (checkSelection && selectionLength < (cursor.selectionEnd() -
cursor.selectionStart()))
    {
        cursor.setPosition(cursor.selectionStart());
@@ -1244,6 +1320,67 @@
    emit popupCommand(action->data().toInt());
 }

+// for more information about these RTFM
+//    http://www.unicode.org/reports/tr9/
+//    http://www.w3.org/TR/unicode-xml/
+QChar IRCView::LRM = (ushort)0x200e; // Right-to-Left Mark
+QChar IRCView::RLM = (ushort)0x200f; // Left-to-Right Mark
+QChar IRCView::LRE = (ushort)0x202a; // Left-to-Right Embedding
+QChar IRCView::RLE = (ushort)0x202b; // Right-to-Left Embedding
+QChar IRCView::RLO = (ushort)0x202e; // Right-to-Left Override
+QChar IRCView::LRO = (ushort)0x202d; // Left-to-Right Override
+QChar IRCView::PDF = (ushort)0x202c; // Previously Defined Format
+
+QChar::Direction IRCView::basicDirection(const QString& string)
+{
+    // The following code decides between LTR or RTL direction for
+    // a line based on the amount of each type of characters pre-
+    // sent. It does so by counting, but stops when one of the two
+    // counters becomes higher than half of the string length to
+    // avoid unnecessary work.
+
+    unsigned int pos = 0;
+    unsigned int rtl_chars = 0;
+    unsigned int ltr_chars = 0;
+    unsigned int str_len = string.length();
+    unsigned int str_half_len = str_len/2;
+
+    for(pos=0; pos < str_len; pos++)
+    {
+        if (!(string[pos].isNumber() || string[pos].isSymbol() ||
+            string[pos].isSpace()  || string[pos].isPunct()  ||
+            string[pos].isMark()))
+        {
+            switch(string[pos].direction())
+            {
+                case QChar::DirL:
+                case QChar::DirLRO:
+                case QChar::DirLRE:
+                    ltr_chars++;
+                    break;
+                case QChar::DirR:
+                case QChar::DirAL:
+                case QChar::DirRLO:
+                case QChar::DirRLE:
+                    rtl_chars++;
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        if (ltr_chars > str_half_len)
+            return QChar::DirL;
+        else if (rtl_chars > str_half_len)
+            return QChar::DirR;
+    }
+
+    if (rtl_chars > ltr_chars)
+        return QChar::DirR;
+    else
+        return QChar::DirL;
+}
+
 // **WARNING** the selectionChange signal comes BEFORE the selection has
actually been changed, hook cursorPositionChanged too

 //void IRCView::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const
QPointF &pos)
--- trunk/extragear/network/konversation/src/viewer/ircview.h #1023944:1023945
@@ -112,18 +112,17 @@
        void appendBacklogMessage(const QString& firstColumn, const QString&
message);

    protected:
-        void doAppend(const QString& line, bool self=false);
+        void doAppend(const QString& line, bool rtl, bool self=false);
        /**
         * Appends a newLine without any scrollback or notification checks
         * @param newLine
         */
-        void doRawAppend(const QString& newLine);
+        void doRawAppend(const QString& newLine, bool rtl);
        void appendLine(const QString& color);
        void appendRememberLine();

        void updateNickMenuEntries(const QString& nickname);

-
    public slots:
        /// Emits the doSeach signal.
        void findText();

-- 
Configure bugmail: https://bugs.kde.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.


More information about the Konversation-devel mailing list