summaryrefslogtreecommitdiffstats
path: root/src/gui/clientChatDialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/clientChatDialog.cpp')
-rw-r--r--src/gui/clientChatDialog.cpp298
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);
+}