Mercurial > hg > octave-avbm
changeset 13603:3a1ba08ad392
Further development of IRC backend.
author | Jacob Dawid <jacob.dawid@googlemail.com> |
---|---|
date | Mon, 15 Aug 2011 13:10:38 +0200 |
parents | cfd231a4286a |
children | 269ef479ecbf |
files | gui/src/IRCWidget.cpp gui/src/IRCWidget.h gui/src/qirc/IRCClientImpl.cpp gui/src/qirc/IRCClientImpl.h gui/src/qirc/IRCClientInterface.h |
diffstat | 5 files changed, 178 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/gui/src/IRCWidget.cpp +++ b/gui/src/IRCWidget.cpp @@ -24,8 +24,109 @@ #include <QLabel> #include <QSettings> #include <QInputDialog> +#include <QKeyEvent> +#include <QScrollBar> #include "IRCClientImpl.h" +ChatMessageTextEdit::ChatMessageTextEdit (QWidget *parent) + : QTextEdit (parent), m_completer (0) +{ + setMaximumHeight (50); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); +} + +ChatMessageTextEdit::~ChatMessageTextEdit () +{ +} + +void +ChatMessageTextEdit::setCompleter (QCompleter *completer) +{ + if (m_completer) + QObject::disconnect (m_completer, 0, this, 0); + + m_completer = completer; + + if (!m_completer) + return; + + m_completer->setWidget (this); + m_completer->setCompletionMode (QCompleter::InlineCompletion); + m_completer->setCaseSensitivity (Qt::CaseInsensitive); + QObject::connect (m_completer, SIGNAL (activated (QString)), + this, SLOT (insertCompletion (QString))); +} + +QCompleter * +ChatMessageTextEdit::completer () const +{ + return m_completer; +} + +void +ChatMessageTextEdit::insertCompletion(const QString& completion) +{ + + if (m_completer->widget() != this) + return; + QTextCursor tc = textCursor(); + int extra = completion.length() - m_completer->completionPrefix().length(); + tc.movePosition(QTextCursor::Left); + tc.movePosition(QTextCursor::EndOfWord); + tc.insertText(completion.right(extra)); + setTextCursor(tc); +} + +QString +ChatMessageTextEdit::textUnderCursor () const +{ + QTextCursor tc = textCursor (); + tc.select (QTextCursor::WordUnderCursor); + return tc.selectedText (); +} + +void +ChatMessageTextEdit::focusInEvent (QFocusEvent *e) +{ + if (m_completer) + m_completer->setWidget (this); + QTextEdit::focusInEvent (e); +} + +void +ChatMessageTextEdit::keyPressEvent (QKeyEvent *keyPressEvent) +{ + if (m_completer) { + switch (keyPressEvent->key ()) { + case Qt::Key_Enter: + case Qt::Key_Return: + if (! (keyPressEvent->modifiers () & Qt::ShiftModifier)) + { + emit sendMessage (toPlainText ()); + setText (""); + } + else + { + QTextEdit::keyPressEvent (keyPressEvent); + } + break; + case Qt::Key_Escape: + case Qt::Key_Tab: + case Qt::Key_Backtab: + keyPressEvent->ignore (); + return; + default: + QTextEdit::keyPressEvent(keyPressEvent); + break; + } + + QString completionPrefix = textUnderCursor (); + if (completionPrefix != m_completer->completionPrefix ()) + m_completer->setCompletionPrefix(completionPrefix); + m_completer->complete (); + } +} + IRCWidget::IRCWidget (QWidget * parent): QWidget (parent) { @@ -54,21 +155,21 @@ m_nickButton = new QPushButton (bottomWidget); m_nickButton->setStatusTip (tr ((char *) "Click here to change your nick.")); m_nickButton->setText (m_initialNick); - m_inputLine = new QLineEdit (bottomWidget); - m_inputLine->setStatusTip (tr ((char *) "Enter your message here.")); + m_chatMessageTextEdit = new ChatMessageTextEdit (bottomWidget); + m_chatMessageTextEdit->setStatusTip (tr ((char *) "Enter your message here.")); bottomLayout->addWidget (m_nickButton); bottomLayout->addWidget (new QLabel (":", this)); - bottomLayout->addWidget (m_inputLine); + bottomLayout->addWidget (m_chatMessageTextEdit); bottomLayout->setMargin (0); bottomWidget->setLayout (bottomLayout); m_nickButton->setEnabled (false); - m_inputLine->setEnabled (false); + m_chatMessageTextEdit->setEnabled (false); //m_chatWindow->setFocusProxy (m_inputLine); - this->setFocusProxy (m_inputLine); - m_nickButton->setFocusProxy (m_inputLine); + this->setFocusProxy (m_chatMessageTextEdit); + m_nickButton->setFocusProxy (m_chatMessageTextEdit); QFont font; font.setFamily ("Courier"); @@ -96,9 +197,12 @@ connect (m_ircClientInterface, SIGNAL (userNicknameChanged (QString)), this, SLOT (handleUserNicknameChanged (QString))); - connect (m_nickButton, SIGNAL (clicked ()), this, SLOT (nickPopup ())); - connect (m_inputLine, SIGNAL (returnPressed ()), this, - SLOT (sendInputLine ())); + connect (m_nickButton, SIGNAL (clicked ()), this, SLOT (showChangeUserNickPopup ())); + connect (m_chatMessageTextEdit, SIGNAL (sendMessage (QString)), + this, SLOT (sendMessage (QString))); + + m_chatMessageTextEdit->setCompleter + (new QCompleter (m_ircClientInterface->ircChannelProxy ("#octave")->userListModel (), this)); if (connectOnStartup) connectToServer (); @@ -178,7 +282,7 @@ } void -IRCWidget::nickPopup () +IRCWidget::showChangeUserNickPopup () { bool ok; QString newNick = @@ -238,13 +342,6 @@ } void -IRCWidget::sendInputLine () -{ - sendMessage (m_inputLine->text ()); - m_inputLine->setText (""); -} - -void IRCWidget::handleLoggedIn (const QString &nick) { m_chatWindow-> @@ -252,9 +349,9 @@ ("<i><font color=\"#00AA00\"><b>Successfully logged in as %1.</b></font></i>"). arg (nick)); m_nickButton->setEnabled (true); - m_inputLine->setEnabled (true); + m_chatMessageTextEdit->setEnabled (true); m_chatWindow->setEnabled (true); - m_inputLine->setFocus (); + m_chatMessageTextEdit->setFocus (); if (m_autoIdentification) @@ -268,27 +365,18 @@ IRCWidget::handleNickChange (const QString &oldNick, const QString &newNick) { m_chatWindow->append (QString ("%1 is now known as %2.").arg (oldNick).arg (newNick)); - m_nickList.removeAll (QString (oldNick)); - m_nickList.append (QString (newNick)); - updateNickCompleter (); } void IRCWidget::handleUserJoined (const QString &nick, const QString &channel) { - m_chatWindow->append (QString ("<i>%1 has joined %2.</i>").arg (nick). - arg (channel)); - m_nickList.append (QString (nick)); - updateNickCompleter (); + m_chatWindow->append (QString ("<i>%1 has joined %2.</i>").arg (nick).arg (channel)); } void IRCWidget::handleUserQuit (const QString &nick, const QString &reason) { - m_chatWindow->append (QString ("<i>%1 has quit.(%2).</i>").arg (nick). - arg (reason)); - m_nickList.removeAll (QString (nick)); - updateNickCompleter (); + m_chatWindow->append (QString ("<i>%1 has quit.(%2).</i>").arg (nick).arg (reason)); } void @@ -298,11 +386,3 @@ QSettings *settings = ResourceManager::instance ()->settings (); settings->setValue ("IRCNick", nick); } - -void -IRCWidget::updateNickCompleter () -{ - QCompleter *completer = new QCompleter (m_nickList, this); - completer->setCompletionMode (QCompleter::InlineCompletion); - m_inputLine->setCompleter (completer); -}
--- a/gui/src/IRCWidget.h +++ b/gui/src/IRCWidget.h @@ -26,7 +26,34 @@ #include <QCompleter> #include "IRCClientInterface.h" -class IRCWidget:public QWidget +class ChatMessageTextEdit : public QTextEdit +{ + Q_OBJECT +public: + explicit ChatMessageTextEdit(QWidget *parent = 0); + ~ChatMessageTextEdit(); + + void setCompleter(QCompleter *m_completer); + QCompleter *completer() const; + +signals: + void sendMessage (const QString& message); + +protected: + void keyPressEvent(QKeyEvent *e); + void focusInEvent(QFocusEvent *e); + +private slots: + void insertCompletion(const QString &completion); + +private: + QString textUnderCursor() const; + +private: + QCompleter *m_completer; +}; + +class IRCWidget : public QWidget { Q_OBJECT public: explicit IRCWidget (QWidget * parent); @@ -47,23 +74,20 @@ void handleUserQuit (const QString& nick, const QString& reason); void handleUserNicknameChanged (const QString& nick); - void nickPopup (); + void showChangeUserNickPopup (); void sendMessage (QString); - void sendInputLine (); - void updateNickCompleter (); private: IRCClientInterface *m_ircClientInterface; IRCChannelProxyInterface *m_octaveChannel; QTextEdit *m_chatWindow; QPushButton *m_nickButton; - QLineEdit *m_inputLine; + ChatMessageTextEdit *m_chatMessageTextEdit; QString m_initialNick; bool m_autoIdentification; QString m_nickServPassword; QString m_settingsFile; - QStringList m_nickList; }; #endif // IRCWIDGET_H
--- a/gui/src/qirc/IRCClientImpl.cpp +++ b/gui/src/qirc/IRCClientImpl.cpp @@ -20,6 +20,9 @@ IRCServerMessage::IRCServerMessage (const QString& serverMessage) { + if (serverMessage.isEmpty ()) + return; + int position = 0; QString buffer; @@ -31,50 +34,55 @@ // a prefix. A prefix has the format: // :nick!user@host // followed by a space character. - if (serverMessage.startsWith(":")) + if (serverMessage.startsWith (":")) { position++; - while ((serverMessage.at (position) != '!') && !serverMessage.at (position).isSpace ()) + while ((position < serverMessage.size ()) + &&(serverMessage.at (position) != '!') + && !serverMessage.at (position).isSpace ()) { buffer.append (serverMessage.at (position)); position++; } - m_nick = buffer, buffer.clear(), position++; + m_nick = buffer, buffer.clear (), position++; // If it belongs to the prefix, it must be concatenanted neatlessly without // any spaces. if (!serverMessage.at (position - 1).isSpace ()) { - while (serverMessage.at (position) != '@') + while ((position < serverMessage.size ()) + && serverMessage.at (position) != '@') { buffer.append (serverMessage.at (position)); position++; } - m_user = buffer, buffer.clear(), position++; + m_user = buffer, buffer.clear (), position++; } // If it belongs to the prefix, it must be concatenanted neatlessly without // any spaces. if (!serverMessage.at (position - 1).isSpace ()) { - while (serverMessage.at (position) != ' ') + while ((position < serverMessage.size ()) + && serverMessage.at (position) != ' ') { buffer.append (serverMessage.at (position)); position++; } - m_host = buffer, buffer.clear(), position++; + m_host = buffer, buffer.clear (), position++; } } // The next part is the command. The command can either be numeric // or a written command. - while (!serverMessage.at (position).isSpace ()) + while ((position < serverMessage.size ()) + && !serverMessage.at (position).isSpace ()) { buffer.append (serverMessage.at (position)); position++; } - m_command = buffer.toUpper(), buffer.clear(), position++; - m_codeNumber = m_command.toInt(&m_isNumeric); + m_command = buffer.toUpper (), buffer.clear (), position++; + m_codeNumber = m_command.toInt (&m_isNumeric); // Next: a list of parameters. If any of these parameters // starts with a colon, we have to read everything that follows @@ -158,6 +166,13 @@ } void +IRCChannelProxy::setNickList (const QStringList &nickList) +{ + m_userList = nickList; + m_userListModel.setStringList (nickList); +} + +void IRCChannelProxy::sendMessage (const QString& message) { QStringList arguments; @@ -330,7 +345,6 @@ void IRCClientImpl::handleIncomingLine (const QString &line) { - //emit debugMessage (QString (">>>recv: \"%1\"").arg (line)); if (m_connected && !line.isEmpty()) { IRCServerMessage ircServerMessage(line); @@ -372,8 +386,9 @@ case IRCReply::Topic: break; case IRCReply::NameReply: - emit debugMessage (QString ("LINKME: (NameReply) \'%1\'").arg (ircServerMessage.parameter(2))); - //m_nickList = event->getParam (3).split (QRegExp ("\\s+"), QString::SkipEmptyParts); + QString channel = ircServerMessage.parameter (2); + QString nickList = ircServerMessage.parameter (3); + ircChannelProxy (channel)->setNickList (nickList.split (QRegExp ("\\s+"), QString::SkipEmptyParts)); break; } } @@ -454,7 +469,6 @@ void IRCClientImpl::sendLine (const QString &line) { - //emit debugMessage (QString (">>>send: \"%1\"").arg (line)); if (m_connected) m_tcpSocket.write ((line + "\r\n").toStdString ().c_str ()); }
--- a/gui/src/qirc/IRCClientImpl.h +++ b/gui/src/qirc/IRCClientImpl.h @@ -262,6 +262,7 @@ QStringListModel *userListModel (); QString channelName (); + void setNickList (const QStringList &nickList); void sendMessage (const QString& message); void sendJoinRequest (); void leave (const QString &reason);
--- a/gui/src/qirc/IRCClientInterface.h +++ b/gui/src/qirc/IRCClientInterface.h @@ -36,6 +36,7 @@ virtual QTextDocument *conversationModel () = 0; virtual QStringListModel *userListModel () = 0; virtual QString channelName () = 0; + virtual void setNickList (const QStringList& nickList) = 0; virtual void sendMessage (const QString& message) = 0; virtual void sendJoinRequest () = 0; virtual void leave (const QString& reason) = 0;