[SCM] ktp-text-ui packaging branch, master, updated. debian/15.12.1-1-1918-gdf4b0ec

Maximiliano Curia maxy at moszumanska.debian.org
Sat May 28 00:23:02 UTC 2016


Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/ktp-text-ui.git;a=commitdiff;h=a75ac95

The following commit has been merged in the master branch:
commit a75ac9592499aab85bdf1be34fb81a913413d709
Author: Dan Vrátil <dvratil at redhat.com>
Date:   Mon Dec 17 10:55:01 2012 +0100

    Nick completion in MUC
    
    Add Konversation-like nick completion on Tab keypress
    
    BUG: 291709
    REVIEW: 107773
---
 lib/channel-contact-model.cpp |  10 +++
 lib/channel-contact-model.h   |   9 +--
 lib/chat-text-edit.cpp        | 153 +++++++++++++++++++++++++++++++++++++++++-
 lib/chat-text-edit.h          |  12 ++++
 lib/chat-widget.cpp           |   5 ++
 5 files changed, 182 insertions(+), 7 deletions(-)

diff --git a/lib/channel-contact-model.cpp b/lib/channel-contact-model.cpp
index 619e9ad..49a1799 100644
--- a/lib/channel-contact-model.cpp
+++ b/lib/channel-contact-model.cpp
@@ -47,6 +47,16 @@ void ChannelContactModel::setTextChannel(const Tp::TextChannelPtr &channel)
                                      Tp::Contacts,Tp::Channel::GroupMemberChangeDetails)));
 }
 
+bool ChannelContactModel::containsNick(const QString& nick)
+{
+    Q_FOREACH(const Tp::ContactPtr &contact, m_contacts) {
+        if (contact->alias() == nick) {
+            return true;
+        }
+    }
+
+    return false;
+}
 
 int ChannelContactModel::rowCount(const QModelIndex &parent) const
 {
diff --git a/lib/channel-contact-model.h b/lib/channel-contact-model.h
index 55840ea..d2f6f6f 100644
--- a/lib/channel-contact-model.h
+++ b/lib/channel-contact-model.h
@@ -44,15 +44,16 @@ public:
 
     void setTextChannel(const Tp::TextChannelPtr &channel);
 
+    bool containsNick(const QString &nick);
+
+    int rowCount(const QModelIndex &parent = QModelIndex()) const;
+    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
 Q_SIGNALS:
     void contactPresenceChanged(const Tp::ContactPtr &contact, const KTp::Presence &presence);
     void contactAliasChanged(const Tp::ContactPtr &contact, const QString &alias);
     void contactBlockStatusChanged(const Tp::ContactPtr &contact, bool blocked);
 
-protected:
-    int rowCount(const QModelIndex &parent) const;
-    QVariant data(const QModelIndex &index, int role) const;
-
 private Q_SLOTS:
     void onGroupMembersChanged(const Tp::Contacts &groupMembersAdded,
                              const Tp::Contacts &groupLocalPendingMembersAdded,
diff --git a/lib/chat-text-edit.cpp b/lib/chat-text-edit.cpp
index 9babc73..19fdb38 100644
--- a/lib/chat-text-edit.cpp
+++ b/lib/chat-text-edit.cpp
@@ -18,6 +18,7 @@
  ***************************************************************************/
 
 #include "chat-text-edit.h"
+#include "channel-contact-model.h"
 
 #include <QtGui/QMenu>
 #include <QtGui/QContextMenuEvent>
@@ -30,7 +31,11 @@
 #define MAXHISTORY 100
 
 ChatTextEdit::ChatTextEdit(QWidget *parent) :
-        KTextEdit(parent)
+        KTextEdit(parent),
+        m_contactModel(0),
+        m_oldCursorPos(0),
+        m_completionPosition(0),
+        m_continuousCompletion(false)
 {
     setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);    // no need for horizontal scrollbar with this
     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -49,6 +54,11 @@ ChatTextEdit::ChatTextEdit(QWidget *parent) :
     connect(this, SIGNAL(textChanged()), SLOT(recalculateSize()));
 }
 
+void ChatTextEdit::setContactModel(ChannelContactModel* model)
+{
+    m_contactModel = model;
+}
+
 void ChatTextEdit::setFontBold(bool isBold)
 {
     if (isBold) {
@@ -83,6 +93,8 @@ void ChatTextEdit::keyPressEvent(QKeyEvent *e)
 	if (!toPlainText().isEmpty()) {
 	    addHistory(toPlainText());
 	}
+	m_continuousCompletion = false;
+
         Q_EMIT returnKeyPressed();
         return;
     }
@@ -108,11 +120,19 @@ void ChatTextEdit::keyPressEvent(QKeyEvent *e)
         return;
     }
 
-    if (e->key() == Qt::Key_Tab && e->modifiers() & Qt::ControlModifier) {
-        QWidget::keyPressEvent(e);
+    if (e->key() == Qt::Key_Tab) {
+        if (e->modifiers() & Qt::ControlModifier) {
+            QWidget::keyPressEvent(e);
+        } else if (e->modifiers() == 0) {
+            completeNick();
+        }
         return;
     }
 
+    if(!e->text().isEmpty() || ((e->key() >= Qt::Key_Home) && (e->key() <= Qt::Key_Down))) {
+        m_continuousCompletion = false;
+    }
+
     KTextEdit::keyPressEvent(e);
 }
 
@@ -193,3 +213,130 @@ void ChatTextEdit::addHistory(const QString &text)
 
     m_historyPos = 0;
 }
+
+// Nick completion - based on code from Konversation by Eike Hein
+void ChatTextEdit::completeNick()
+{
+    if (!m_contactModel) {
+        return;
+    }
+
+    int pos, oldPos;
+    QTextCursor cursor = textCursor();
+    bool continousCompletion = m_continuousCompletion;
+
+    pos = cursor.position();
+    oldPos = m_oldCursorPos;
+
+    QString line = toPlainText();
+    QString newLine;
+
+    // Check if completion position is out of range
+    if (m_completionPosition >= m_contactModel->rowCount()) {
+        m_completionPosition = 0;
+    }
+
+    if (continousCompletion) {
+        line.remove(oldPos, pos - oldPos);
+        pos = oldPos;
+    }
+
+    // If the cursor is at beginning of line, insert last completion if the nick is still around
+    if (pos == 0 && !m_lastCompletion.isEmpty() && m_contactModel->containsNick(m_lastCompletion)) {
+        newLine = m_lastCompletion;
+        // New cursor position is behind nickname
+        pos = newLine.length();
+        // Add rest of the line
+        newLine += line;
+    } else {
+        // remember old cursor position in input field
+        m_oldCursorPos = pos;
+        // remember old cursor position locally
+        oldPos = pos;
+        // step back to last space or start of line
+        while (pos && line[pos - 1] != QLatin1Char(' ')) {
+            pos--;
+        }
+
+        // copy search pattern (lowercase)
+        QString pattern = line.mid(pos, oldPos - pos);
+        // copy line to newLine-buffer
+        newLine = line;
+
+        // did we find any pattern?
+        if (!pattern.isEmpty()) {
+            bool complete = false;
+            QString foundNick;
+
+            if (m_contactModel->rowCount() > 0) {
+                if (!continousCompletion) {
+                    int listPosition = 0;
+
+                    for (int i = 0; i < m_contactModel->rowCount(); ++i) {
+                        QModelIndex index = m_contactModel->index(i, 0);
+                        if (index.data().toString().startsWith(pattern, Qt::CaseInsensitive)) {
+                            m_completionPosition = listPosition;
+
+                            ++listPosition;
+                        }
+                    }
+                }
+
+                // remember old nick completion position
+                int oldCompletionPosition = m_completionPosition;
+                complete = true;
+
+                do {
+                    QModelIndex index = m_contactModel->index(m_completionPosition, 0);
+                    QString lookNick = index.data(Qt::DisplayRole).toString();
+                    if (lookNick.startsWith(pattern, Qt::CaseInsensitive)) {
+                        foundNick = lookNick;
+                    }
+
+                    // increment search position
+                    m_completionPosition++;
+
+                    // wrap around
+                    if(m_completionPosition == m_contactModel->rowCount()) {
+                        m_completionPosition = 0;
+                    }
+
+                // the search ends when we either find a suitable nick or we end up at the
+                // first search position
+                } while ((m_completionPosition != oldCompletionPosition) && foundNick.isEmpty());
+            }
+
+            // did we find a suitable nick?
+            if (!foundNick.isEmpty()) {
+                m_continuousCompletion = true;
+
+                // remove pattern from line
+                newLine.remove(pos, pattern.length());
+
+                // did we find the nick in the middle of the line?
+                if ((pos > 0) && complete) {
+                    m_lastCompletion = foundNick;
+                    newLine.insert(pos, foundNick);
+                    pos = pos + foundNick.length();
+                } else if ((pos == 0) && complete) {
+                    // no, it was at the beginning
+                    m_lastCompletion = foundNick;
+                    newLine.insert(pos, foundNick + QLatin1String(", "));
+                    pos = pos + foundNick.length() + 2; /* 2 = strlen(", ") */
+                } else {
+                    // the nick wasn't complete
+                    newLine.insert(pos, foundNick);
+                    pos = pos + foundNick.length();
+                }
+            } else {
+                // no pattern found, so restore old cursor position
+                pos = oldPos;
+            }
+        }
+    }
+
+    // Set new text and cursor position
+    setText(newLine);
+    cursor.setPosition(pos);
+    setTextCursor(cursor);
+}
diff --git a/lib/chat-text-edit.h b/lib/chat-text-edit.h
index a8b0e79..4279ce5 100644
--- a/lib/chat-text-edit.h
+++ b/lib/chat-text-edit.h
@@ -22,12 +22,15 @@
 
 #include <KTextEdit>
 
+class ChannelContactModel;
 class ChatTextEdit : public KTextEdit
 {
     Q_OBJECT
 public:
     explicit ChatTextEdit(QWidget *parent = 0);
 
+    void setContactModel(ChannelContactModel *model);
+
     // reimplemented
     QSize minimumSizeHint() const;
     QSize sizeHint() const;
@@ -43,6 +46,8 @@ protected:
     void getHistory(bool up);
     void addHistory(const QString &text);
 
+    void completeNick();
+
 private Q_SLOTS:
     void recalculateSize();
     void updateScrollBar();
@@ -57,6 +62,13 @@ public Q_SLOTS:
 private:
     QStringList m_history;
     int m_historyPos;
+
+    /* Nick completion */
+    ChannelContactModel *m_contactModel;
+    QString m_lastCompletion;
+    int m_oldCursorPos;
+    int m_completionPosition;
+    bool m_continuousCompletion;
 };
 
 #endif // CHATTEXTEDIT_H
diff --git a/lib/chat-widget.cpp b/lib/chat-widget.cpp
index d5608df..8f63e14 100644
--- a/lib/chat-widget.cpp
+++ b/lib/chat-widget.cpp
@@ -114,6 +114,11 @@ ChatWidget::ChatWidget(const Tp::TextChannelPtr & channel, const Tp::AccountPtr
     d->contactModel = new ChannelContactModel(d->channel, this);
     setupContactModelSignals();
 
+    /* Enable nick completion only in group chats */
+    if (d->isGroupChat) {
+        d->ui.sendMessageBox->setContactModel(d->contactModel);
+    }
+
     d->ui.contactsView->setModel(d->contactModel);
 
     d->yourName = channel->groupSelfContact()->alias();

-- 
ktp-text-ui packaging



More information about the pkg-kde-commits mailing list