diff options
Diffstat (limited to 'src/gui/clientChatDialog.cpp')
| -rw-r--r-- | src/gui/clientChatDialog.cpp | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/src/gui/clientChatDialog.cpp b/src/gui/clientChatDialog.cpp new file mode 100644 index 0000000..7c32790 --- /dev/null +++ b/src/gui/clientChatDialog.cpp @@ -0,0 +1,298 @@ +/* + # Copyright (c) 2009, 2010 - OpenSLX Project, Computer Center University of + # Freiburg + # + # This program is free software distributed under the GPL version 2. + # See http://openslx.org/COPYING + # + # If you have any feedback please consult http://openslx.org/feedback and + # send your suggestions, praise, or complaints to feedback@openslx.org + # + # General information about OpenSLX can be found at http://openslx.org/ + # ----------------------------------------------------------------------------- + # clientChatDialog.cpp + # - graphical chat interface + # ----------------------------------------------------------------------------- + */ + +#include "clientChatDialog.h" + +ClientChatDialog::ClientChatDialog(QWidget *parent) : + QDialog(parent) +{ + _trayIcon = NULL; + _nickname = ""; + + setupUi(this); + setAcceptDrops(true); + connect(pushButton, SIGNAL(clicked()), this, SLOT(send())); + + // connect to D-Bus and get interface + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject("/chat", this); + dbus.registerService("org.openslx.pvsgui"); + _ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this); + connect(_ifaceDBus, SIGNAL(chat_receive(QString, QString, QString)), this, + SLOT(receive(QString, QString, QString))); + + // add first tab for public messages + tabWidget->clear(); + QTextEdit *t = new QTextEdit(); + t->setReadOnly(true); + tabWidget->addTab(t, "@all"); + _hash = new QHash<QString, QTextEdit*> (); + _hash->insert(tabWidget->tabText(0), t); + + // already connected? + QDBusPendingReply<QString> reply = _ifaceDBus->isConnected(); + reply.waitForFinished(); + if (reply.isValid() && reply.value() != "") + { + // get available nicknames if already connected + QDBusPendingReply<QStringList> reply1 = _ifaceDBus->chat_getNicknames(); + reply1.waitForFinished(); + QStringList nicknames = reply1.value(); + if (reply1.isValid() && !nicknames.isEmpty()) + listWidget->addItems(nicknames); + + connected(); + } + else + disconnected(); + + // setup menu + _menu = new QMenu(); + _sendFileAction = new QAction(tr("&Send File..."), this); + _menu->addAction(_sendFileAction); + + connect(listWidget, SIGNAL(doubleClicked(QModelIndex)), this, + SLOT(addTab(QModelIndex))); + connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, + SLOT(removeTab(int))); + connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(removeIcon(int))); + connect(listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, + SLOT(showMenu(QPoint))); + connect(_sendFileAction, SIGNAL(triggered()), this, + SLOT(sendFile())); + + connect(_ifaceDBus, SIGNAL(chat_client_add(QString)), this, + SLOT(addClient(QString))); + connect(_ifaceDBus, SIGNAL(chat_client_remove(QString)), this, + SLOT(removeClient(QString))); + connect(_ifaceDBus, SIGNAL(disconnected()), listWidget, + SLOT(clear())); + connect(_ifaceDBus, SIGNAL(connected(QString)), this, + SLOT(connected())); + connect(_ifaceDBus, SIGNAL(disconnected()), this, + SLOT(disconnected())); + + lineEdit->setFocus(); +} + +ClientChatDialog::~ClientChatDialog() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// Public + +void ClientChatDialog::setTrayIcon(QSystemTrayIcon *trayIcon) +{ + _trayIcon = trayIcon; + // FIXME: messageClicked() is always emitted, not only on chat msg + //connect(_trayIcon, SIGNAL(messageClicked()), this, SLOT(open())); +} + +//////////////////////////////////////////////////////////////////////////////// +// Protected + +void ClientChatDialog::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasUrls()) + event->accept(); +} + +void ClientChatDialog::dropEvent(QDropEvent *event) +{ + event->accept(); + sendFile(event->mimeData()->urls().first().toLocalFile()); +} + +//////////////////////////////////////////////////////////////////////////////// +// Private + +void ClientChatDialog::send() +{ + QString msg = lineEdit->text(); + if (msg != "") + { + QString nick_to = tabWidget->tabText(tabWidget->currentIndex()); + _ifaceDBus->chat_send(nick_to, _nickname, msg); + lineEdit->clear(); + lineEdit->setFocus(); + + qDebug("[%s] S %s -> %s : %s", metaObject()->className(), + qPrintable(_nickname), qPrintable(nick_to), qPrintable(msg)); + } +} + +void ClientChatDialog::receive(QString nick_from, QString nick_to, QString msg) +{ + qDebug("[%s] R %s <- %s : %s", metaObject()->className(), + qPrintable(nick_to), qPrintable(nick_from), qPrintable(msg)); + + if (nick_to == tabWidget->tabText(0) || nick_from == _nickname) + printMsg(nick_from, msg, getTab(nick_to)); // public message or own msg + else + printMsg(nick_from, msg, getTab(nick_from)); // private message +} + +void ClientChatDialog::addTab(QModelIndex i) +{ + QString text = i.data().toString(); + if (_hash->contains(text)) + tabWidget->setCurrentWidget(_hash->value(text)); + else + { + QTextEdit *t = new QTextEdit(); + t->setReadOnly(true); + tabWidget->setCurrentIndex(tabWidget->addTab(t, text)); + _hash->insert(text, t); + } + lineEdit->setFocus(); +} + +void ClientChatDialog::removeTab(int i) +{ + if (i != 0) + { + _hash->remove(tabWidget->tabText(i)); + tabWidget->removeTab(i); + lineEdit->setFocus(); + } +} + +void ClientChatDialog::addClient(QString nick) +{ + listWidget->addItem(nick); + printEvent("-> " + nick + tr(" has joined the chat.")); +} + +void ClientChatDialog::removeClient(QString nick) +{ + delete listWidget->findItems(nick, Qt::MatchExactly).first(); + printEvent("<- " + nick + tr(" has left the chat.")); +} + +void ClientChatDialog::removeIcon(int i) +{ + tabWidget->setTabIcon(i, QIcon()); +} + +void ClientChatDialog::showMenu(QPoint p) +{ + _menu->popup(listWidget->mapToGlobal(p)); +} + +void ClientChatDialog::sendFile() +{ + ClientFileSendDialog *d = new ClientFileSendDialog(this); + d->open(listWidget->currentItem()->text()); +} + +void ClientChatDialog::sendFile(QString filename) +{ + if (tabWidget->currentIndex() == 0 || filename == "") + return; + + // ask user + QString nick = tabWidget->tabText(tabWidget->currentIndex()); + QMessageBox::StandardButton result = QMessageBox::question(0, + tr("PVS File Transfer"), + tr("Send file '") + filename + tr("' to ") + nick + "?", + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok); + + if (result != QMessageBox::Ok) + return; + + ClientFileSendDialog *d = new ClientFileSendDialog(this); + d->open(nick, filename); +} + +void ClientChatDialog::connected() +{ + // get current users name from backend + QDBusPendingReply<QString> reply = _ifaceDBus->chat_getNickname(); + reply.waitForFinished(); + if (reply.isValid()) + { + _nickname = reply.value(); + pushButton->setEnabled(true); + printEvent("!!! " + tr("Connected.")); + } + + qDebug("[%s] Nickname: '%s'", metaObject()->className(), + qPrintable(_nickname)); +} + +void ClientChatDialog::disconnected() +{ + pushButton->setEnabled(false); + printEvent("!!! " + tr("Disconnected.")); +} + +QTextEdit* ClientChatDialog::getTab(QString text) +{ + if (!_hash->contains(text)) + { + QTextEdit *t = new QTextEdit(); + t->setReadOnly(true); + tabWidget->addTab(t, text); + _hash->insert(text, t); + } + lineEdit->setFocus(); + return _hash->value(text); +} + +void ClientChatDialog::printMsg(QString nick_from, QString msg, QTextEdit *t) +{ + // move cursor at the end + t->moveCursor(QTextCursor::End); + + // print time + t->setTextColor(QColor(0, 100, 0)); + t->append("[" + QTime::currentTime().toString("hh:mm") + "] "); + + // print nickname + t->setTextColor(QColor(0, 0, 255)); + t->insertPlainText("<" + nick_from + "> "); + + // print message + t->setTextColor(QColor(0, 0, 0)); + t->insertPlainText(msg); + + // show icon if not current tab + if (tabWidget->currentIndex() != tabWidget->indexOf(t)) + tabWidget->setTabIcon(tabWidget->indexOf(t), QIcon(":chat_msg16.svg")); + + // show balloon message if supported and chat-dialog is not visible + if (!isVisible() && _trayIcon && QSystemTrayIcon::supportsMessages()) + _trayIcon->showMessage(tr("Message from <") + nick_from + ">", msg, + QSystemTrayIcon::Information, 20000); +} + +void ClientChatDialog::printEvent(QString msg) +{ + QTextEdit *t = _hash->value(tabWidget->tabText(0)); + + // move cursor at the end + t->moveCursor(QTextCursor::End); + + t->setTextColor(QColor(150, 150, 150)); + + // print time + t->append("[" + QTime::currentTime().toString("hh:mm") + "] "); + + // print message + t->insertPlainText(msg); +} |
