summaryrefslogtreecommitdiffstats
path: root/Swift
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2010-06-05 12:30:16 (GMT)
committerKevin Smith <git@kismith.co.uk>2010-06-05 12:30:16 (GMT)
commit087267cdfedeab2ae55776f7b7246c47f1d39d6d (patch)
tree47c5a3bedd1fa7eb61587a7bd17934f0927dbb9f /Swift
parent7bca08eb2829982865f1649483f9aa01b3413b1c (diff)
downloadswift-contrib-087267cdfedeab2ae55776f7b7246c47f1d39d6d.zip
swift-contrib-087267cdfedeab2ae55776f7b7246c47f1d39d6d.tar.bz2
Tab completion in MUCs.
Resolves: #440
Diffstat (limited to 'Swift')
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp16
-rw-r--r--Swift/Controllers/Chat/MUCController.h2
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h2
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.h1
-rw-r--r--Swift/QtUI/QtChatWindow.cpp31
-rw-r--r--Swift/QtUI/QtChatWindow.h3
-rw-r--r--Swift/QtUI/QtTextEdit.cpp1
7 files changed, 55 insertions, 1 deletions
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 14fe180..65603d7 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -10,6 +10,7 @@
#include "Swiften/Network/Timer.h"
#include "Swiften/Network/TimerFactory.h"
+#include "SwifTools/TabComplete.h"
#include "Swiften/Base/foreach.h"
#include "Swift/Controllers/UIInterfaces/ChatWindow.h"
#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
@@ -49,7 +50,9 @@ MUCController::MUCController (
events_ = uiEventStream;
roster_ = new Roster(true);
+ completer_ = new TabComplete();
chatWindow_->setRosterModel(roster_);
+ chatWindow_->setTabComplete(completer_);
chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this));
muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1));
muc_->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1));
@@ -79,6 +82,8 @@ MUCController::~MUCController() {
if (loginCheckTimer_) {
loginCheckTimer_->stop();
}
+ chatWindow_->setTabComplete(NULL);
+ delete completer_;
}
void MUCController::handleJoinTimeoutTick() {
@@ -139,6 +144,9 @@ void MUCController::handleWindowClosed() {
}
void MUCController::handleOccupantJoined(const MUCOccupant& occupant) {
+ if (nick_ != occupant.getNick()) {
+ completer_->addWord(occupant.getNick());
+ }
receivedActivity();
JID jid(nickToJID(occupant.getNick()));
JID realJID;
@@ -175,7 +183,12 @@ JID MUCController::nickToJID(const String& nick) {
return JID(toJID_.getNode(), toJID_.getDomain(), nick);
}
-void MUCController::preHandleIncomingMessage(boost::shared_ptr<Message>) {
+void MUCController::preHandleIncomingMessage(boost::shared_ptr<Message> message) {
+ String nick = message->getFrom().getResource();
+ if (nick != nick_) {
+ completer_->removeWord(nick);
+ completer_->addWord(nick);
+ }
/*Buggy implementations never send the status code, so use an incoming message as a hint that joining's done (e.g. the old ejabberd on psi-im.org).*/
receivedActivity();
joined_ = true;
@@ -206,6 +219,7 @@ String MUCController::roleToGroupName(MUCOccupant::Role role) {
}
void MUCController::handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType, const String& reason) {
+ completer_->removeWord(occupant.getNick());
String partMessage = occupant.getNick() + " has left the room";
if (!reason.isEmpty()) {
partMessage += " (" + reason + ")";
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index f409309..a3c72e7 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -28,6 +28,7 @@ namespace Swift {
class AvatarManager;
class UIEventStream;
class TimerFactory;
+ class TabComplete;
class MUCController : public ChatControllerBase {
public:
@@ -60,6 +61,7 @@ namespace Swift {
UIEventStream* events_;
String nick_;
Roster* roster_;
+ TabComplete* completer_;
bool parting_;
bool joined_;
boost::bsignals::scoped_connection avatarChangedConnection_;
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index 7beb074..7e97f0c 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -20,6 +20,7 @@ namespace Swift {
class AvatarManager;
class TreeWidget;
class Roster;
+ class TabComplete;
class ChatWindow {
public:
@@ -44,6 +45,7 @@ namespace Swift {
virtual SecurityLabel getSelectedSecurityLabel() = 0;
virtual void setInputEnabled(bool enabled) = 0;
virtual void setRosterModel(Roster* model) = 0;
+ virtual void setTabComplete(TabComplete* completer) = 0;
boost::signal<void ()> onClosed;
boost::signal<void ()> onAllMessagesRead;
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index 1ce87ff..78705ce 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -31,6 +31,7 @@ namespace Swift {
virtual SecurityLabel getSelectedSecurityLabel() {return SecurityLabel();};
virtual void setInputEnabled(bool /*enabled*/) {};
virtual void setRosterModel(Roster* /*roster*/) {};
+ virtual void setTabComplete(TabComplete* complete) {};
boost::signal<void ()> onClosed;
boost::signal<void ()> onAllMessagesRead;
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index cb4c437..6f49082 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -14,6 +14,8 @@
#include "SystemMessageSnippet.h"
#include "QtTextEdit.h"
+#include "SwifTools/TabComplete.h"
+
#include <QApplication>
#include <QBoxLayout>
#include <QCloseEvent>
@@ -80,6 +82,10 @@ QtChatWindow::~QtChatWindow() {
}
+void QtChatWindow::setTabComplete(TabComplete* completer) {
+ completer_ = completer;
+}
+
void QtChatWindow::handleKeyPressEvent(QKeyEvent* event) {
int key = event->key();
Qt::KeyboardModifiers modifiers = event->modifiers();
@@ -95,11 +101,36 @@ void QtChatWindow::handleKeyPressEvent(QKeyEvent* event) {
|| (key == Qt::Key_Right && modifiers == (Qt::ControlModifier & Qt::ShiftModifier))
) {
emit requestNextTab();
+ } else if (key == Qt::Key_Tab) {
+ tabComplete();
} else {
messageLog_->handleKeyPressEvent(event);
}
}
+void QtChatWindow::tabComplete() {
+ if (!completer_) {
+ return;
+ }
+// QTextDocument* document = input_->document();
+ QTextCursor cursor = input_->textCursor();
+ cursor.select(QTextCursor::WordUnderCursor);
+ QString root = cursor.selectedText();
+ bool firstWord = cursor.selectionStart() == 0;
+ QString suggestion = P2QSTRING(completer_->completeWord(Q2PSTRING(root)));
+ if (root == suggestion) {
+ return;
+ }
+ cursor.beginEditBlock();
+ cursor.removeSelectedText();
+ cursor.insertText(suggestion);
+ if (firstWord) {
+ // cursor.insertText(":");
+ }
+ //cursor.insertText(" ");
+ cursor.endEditBlock();
+}
+
void QtChatWindow::setRosterModel(Roster* roster) {
treeWidget_->setRosterModel(roster);
}
diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h
index 9d3e3a7..ff2f1cb 100644
--- a/Swift/QtUI/QtChatWindow.h
+++ b/Swift/QtUI/QtChatWindow.h
@@ -45,6 +45,7 @@ namespace Swift {
QtTabbable::AlertType getWidgetAlertState();
void setContactChatState(ChatState::ChatStateType state);
void setRosterModel(Roster* roster);
+ void setTabComplete(TabComplete* completer);
protected slots:
void qAppFocusChanged(QWidget* old, QWidget* now);
@@ -59,6 +60,7 @@ namespace Swift {
private:
void updateTitleWithUnreadCount();
+ void tabComplete();
void addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const QString& style);
int unreadCount_;
@@ -68,6 +70,7 @@ namespace Swift {
QtTextEdit* input_;
QComboBox *labelsWidget_;
QtTreeWidget *treeWidget_;
+ TabComplete* completer_;
std::vector<SecurityLabel> availableLabels_;
bool previousMessageWasSelf_;
bool previousMessageWasSystem_;
diff --git a/Swift/QtUI/QtTextEdit.cpp b/Swift/QtUI/QtTextEdit.cpp
index 451a18c..89fc68f 100644
--- a/Swift/QtUI/QtTextEdit.cpp
+++ b/Swift/QtUI/QtTextEdit.cpp
@@ -29,6 +29,7 @@ void QtTextEdit::keyPressEvent(QKeyEvent* event) {
|| (key == Qt::Key_PageDown && modifiers == Qt::ControlModifier)
|| (key == Qt::Key_Left && modifiers == (Qt::ControlModifier | Qt::ShiftModifier))
|| (key == Qt::Key_Right && modifiers == (Qt::ControlModifier | Qt::ShiftModifier))
+ || (key == Qt::Key_Tab)
) {
emit unhandledKeyPressEvent(event);
} else {