Mercurial > hg > octave-lyh
diff gui/src/IRCWidget.cpp @ 13501:86d6c3b90ad7
Added new gui files.
author | Jacob Dawid <jacob.dawid@googlemail.com> |
---|---|
date | Sun, 17 Jul 2011 17:45:05 +0200 |
parents | |
children | 13e3d60aff2d |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/gui/src/IRCWidget.cpp @@ -0,0 +1,243 @@ +/* Quint - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid + * jacob.dawid@googlemail.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "IRCWidget.h" +#include <QMessageBox> +#include <QHBoxLayout> +#include <QVBoxLayout> +#include <QLabel> +#include <QSettings> +#include <QInputDialog> + +IRCWidget::IRCWidget(QWidget *parent, QString settingsFile) : + QWidget(parent) +{ + m_settingsFile = settingsFile; + m_alternatingColor = false; + QSettings settings(m_settingsFile, QSettings::IniFormat); + bool connectOnStartup = settings.value("connectOnStartup").toBool(); + m_autoIdentification = settings.value("autoIdentification").toBool(); + m_nickServPassword = settings.value("nickServPassword").toString(); + + m_initialNick = settings.value("IRCNick").toString(); + + if(m_initialNick.isEmpty()) + m_initialNick = "OctaveGUI-User"; + + QVBoxLayout *layout = new QVBoxLayout(); + + m_chatWindow = new QTextEdit(this); + m_chatWindow->setReadOnly(true); + m_chatWindow->setEnabled(false); + QWidget* bottomWidget = new QWidget(this); + + layout->addWidget(m_chatWindow); + layout->addWidget(bottomWidget); + setLayout(layout); + + QHBoxLayout *bottomLayout = new QHBoxLayout(); + 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.")); + bottomLayout->addWidget(m_nickButton); + bottomLayout->addWidget(new QLabel(":", this)); + bottomLayout->addWidget(m_inputLine); + bottomLayout->setMargin(0); + bottomWidget->setLayout(bottomLayout); + m_nickButton->setEnabled(false); + m_inputLine->setEnabled(false); + + m_chatWindow->setFocusProxy(m_inputLine); + m_nickButton->setFocusProxy(m_inputLine); + + QFont font; + font.setFamily("Courier"); + font.setPointSize(11); + m_chatWindow->setFont(font); + m_ircClient = new IRCClient(); + + connect(m_nickButton, SIGNAL(clicked()), this, SLOT(nickPopup())); + connect(m_inputLine, SIGNAL(returnPressed()), this, SLOT(sendInputLine())); + + connect(m_ircClient, SIGNAL(nickInUseChanged()), this, SLOT(handleNickInUseChanged())); + connect(m_ircClient, SIGNAL(connectionStatus(const char*)), this, SLOT(showStatusMessage(const char*))); + connect(m_ircClient, SIGNAL(error(const char*)), this, SLOT(showStatusMessage(const char*))); + connect(m_ircClient, SIGNAL(completedLogin(const char*)), this, SLOT(loginSuccessful(const char*))); + connect(m_ircClient, SIGNAL(completedLogin(const char*)), this, SLOT(joinOctaveChannel(const char*))); + connect(m_ircClient, SIGNAL(topic(const char*,const char*,const char*)), this, SLOT(showTopic(const char*,const char*,const char*))); + connect(m_ircClient, SIGNAL(join(const char*,const char*)), this, SLOT(showJoin(const char*, const char*))); + connect(m_ircClient, SIGNAL(quit(const char*,const char*)), this, SLOT(showQuit(const char*,const char*))); + connect(m_ircClient, SIGNAL(privateMessage(const char*,const char*,const char*)), this, SLOT(showPrivateMessage(const char*,const char*,const char*))); + connect(m_ircClient, SIGNAL(notice(const char*,const char*,const char*)), this, SLOT(showNotice(const char*,const char*,const char*))); + connect(m_ircClient, SIGNAL(nick(const char*,const char*)), this, SLOT(showNickChange(const char*, const char*))); + connect(m_ircClient, SIGNAL(replyCode(IRCEvent*)), this, SLOT(handleReplyCode(IRCEvent*))); + + if(connectOnStartup) + connectToServer(); +} + +void IRCWidget::connectToServer() { + m_ircClient->connectToServer("irc.freenode.net", 6667, + m_initialNick.toStdString().c_str(), + m_initialNick.toStdString().c_str(), + "Unknown", "Unknown", 0, 0); +} + +void IRCWidget::showStatusMessage(const char *message) { + m_chatWindow->append(QString("<i>%1</i>").arg(message)); +} + +void IRCWidget::joinOctaveChannel(const char*) { + m_ircClient->joinChannel("#octave"); +} + +void IRCWidget::loginSuccessful(const char *nick) { + m_chatWindow->append(QString("<i><font color=\"#00AA00\"><b>Successfully logged in as %1.</b></font></i>").arg(nick)); + m_nickButton->setEnabled(true); + m_inputLine->setEnabled(true); + m_chatWindow->setEnabled(true); + m_inputLine->setFocus(); + + if(m_autoIdentification) + m_ircClient->sendCommand(2, COMMAND_PRIVMSG, + "NickServ", + QString("identify %1").arg(m_nickServPassword).toStdString().c_str()); +} + +void IRCWidget::showPrivateMessage(const char *nick, const char *destination, const char *message) { + Q_UNUSED(destination); + QString msg(message); + if(msg.contains(m_ircClient->nickInUse())) { + msg = QString("<font color=\"#990000\"><b>%1:</b> %2</font>").arg(nick).arg(msg); + } else { + msg = QString("<font color=\"%3\"><b>%1:</b> %2</font>").arg(nick).arg(msg).arg(getAlternatingColor()); + } + m_chatWindow->append(msg); +} + +void IRCWidget::showNotice(const char *nick, const char *destination, const char *message) { + Q_UNUSED(nick); + Q_UNUSED(destination); + m_chatWindow->append(QString("<font color=\"#007700\">%1</font>").arg(message)); +} + +void IRCWidget::showTopic(const char *nick, const char *channel, const char *message) { + m_chatWindow->append(QString("Topic for %2 was set by %1: %3").arg(nick).arg(channel).arg(message)); +} + +void IRCWidget::showNickChange(const char *oldNick, const char *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)); +} + +void IRCWidget::nickPopup() { + bool ok; + QString newNick = QInputDialog::getText(this, QString("Nickname"), QString("Type in your nickname:"), + QLineEdit::Normal, m_ircClient->nickInUse(), &ok); + if(ok) { + m_ircClient->sendNickChange(newNick); + } +} + +void IRCWidget::showJoin(const char *nick, const char *channel) { + m_chatWindow->append(QString("<i>%1 has joined %2.</i>").arg(nick).arg(channel)); +} + +void IRCWidget::showQuit(const char *nick, const char *reason) { + m_chatWindow->append(QString("<i>%1 has quit.(%2).</i>").arg(nick).arg(reason)); +} + +void IRCWidget::sendMessage(QString message) { + // Do not send empty messages. + if(message.isEmpty()) + return; + + // Remove trailing spaces. + while(message.at(0).isSpace()) message.remove(0, 1); + if(message.startsWith("/")) { + QStringList line = message.split(QRegExp("\\s+"), QString::SkipEmptyParts); + if(line.at(0) == "/join") { + m_ircClient->joinChannel(line.at(1)); + } else if(line.at(0) == "/nick") { + m_ircClient->sendNickChange(line.at(1)); + } else if(line.at(0) == "/msg") { + QString recipient = line.at(1); + // Since we splitted the message before, we have to glue it together again. + QString pmsg = ""; + for(int i=2; i < line.length(); i++) { + pmsg += line.at(i); + pmsg += " "; + } + m_ircClient->sendCommand(2, COMMAND_PRIVMSG, + recipient.toStdString().c_str(), + pmsg.toStdString().c_str()); + } + } else { + m_ircClient->sendPublicMessage(message); + m_chatWindow->append(QString("<b>%1:</b> %2").arg(m_ircClient->nickInUse()).arg(message)); + } +} + +void IRCWidget::sendInputLine() { + sendMessage(m_inputLine->text()); + m_inputLine->setText(""); +} + +void IRCWidget::handleNickInUseChanged() { + m_nickButton->setText(m_ircClient->nickInUse()); + QSettings settings(m_settingsFile, QSettings::IniFormat); + settings.setValue("IRCNick", m_ircClient->nickInUse()); +} + +void IRCWidget::handleReplyCode(IRCEvent *event) { + QSettings settings(m_settingsFile, QSettings::IniFormat); + + switch(event->getNumeric()) { + case RPL_MOTDSTART: + case RPL_MOTD: + case ERR_NOMOTD: + case RPL_ENDOFMOTD: + if(settings.value("showMessageOfTheDay").toBool()) + m_chatWindow->append(QString("<font color=\"#777777\">%1</font>").arg(event->getParam(1))); + break; + case RPL_NOTOPIC: + case RPL_TOPIC: + if(settings.value("showTopic").toBool()) + m_chatWindow->append(QString("<font color=\"#000088\"><b>%1</b></font>").arg(event->getParam(2))); + break; + case RPL_NAMREPLY: + m_chatWindow->append(QString("<font color=\"#000088\">Users online: %1</font>").arg(event->getParam(3))); + m_nickList = event->getParam(3).split(QRegExp("\\s+"), QString::SkipEmptyParts); + updateNickCompleter(); + break; + case ERR_NICKNAMEINUSE: + case ERR_NICKCOLLISION: + m_chatWindow->append(QString("<font color=\"#AA0000\">Nickname in use.</font>")); + break; + }; +} + + +void IRCWidget::updateNickCompleter() { + QCompleter *completer = new QCompleter(m_nickList, this); + completer->setCompletionMode(QCompleter::InlineCompletion); + m_inputLine->setCompleter(completer); +}