1
#include "psichatdlg.h"
12
#include <QCloseEvent>
13
#include <QHBoxLayout>
14
#include <QVBoxLayout>
15
#include <QContextMenuEvent>
16
#include <QResizeEvent>
18
#include <QDragEnterEvent>
19
#include <QMessageBox>
22
#include "psiaccount.h"
23
#include "iconaction.h"
24
#include "stretchwidget.h"
25
#include "psiiconset.h"
26
#include "iconwidget.h"
27
#include "fancylabel.h"
29
#include "iconselect.h"
31
#include "psitooltip.h"
32
#include "psioptions.h"
33
#include "shortcutmanager.h"
34
#include "accountlabel.h"
35
#include "iconlabel.h"
36
#include "capsmanager.h"
37
#include "psicontactlist.h"
42
PsiChatDlg::PsiChatDlg(const Jid& jid, PsiAccount* pa, TabManager* tabManager)
43
: ChatDlg(jid, pa, tabManager)
45
connect(account()->psi(), SIGNAL(accountCountChanged()), this, SLOT(updateIdentityVisibility()));
48
void PsiChatDlg::initUi()
51
ui_.lb_ident->setAccount(account());
52
ui_.lb_ident->setShowJid(false);
54
PsiToolTip::install(ui_.lb_status);
55
ui_.lb_status->setPsiIcon(IconsetFactory::iconPtr("status/noauth"));
57
ui_.tb_emoticons->setIcon(IconsetFactory::icon("psi/smile").icon());
59
connect(ui_.mle, SIGNAL(textEditCreated(QTextEdit*)), SLOT(chatEditCreated()));
63
connect(chatView(), SIGNAL(selectionChanged()), SLOT(logSelectionChanged()));
70
PsiToolTip::install(ui_.avatar);
72
UserListItem* u = account()->findFirstRelevant(jid());
73
if (u && u->isSecure(jid().resource())) {
77
connect(account()->avatarFactory(), SIGNAL(avatarChanged(const Jid&)), this, SLOT(updateAvatar(const Jid&)));
79
pm_settings_ = new QMenu(this);
80
connect(pm_settings_, SIGNAL(aboutToShow()), SLOT(buildMenu()));
81
ui_.tb_actions->setMenu(pm_settings_);
83
connect(account()->capsManager(), SIGNAL(capsChanged(const Jid&)), SLOT(capsChanged(const Jid&)));
88
ui_.splitter->setSizes(list);
90
smallChat_ = PsiOptions::instance()->getOption("options.ui.chat.use-small-chats").toBool();
93
void PsiChatDlg::updateCountVisibility()
95
if (PsiOptions::instance()->getOption("options.ui.message.show-character-count").toBool() && !smallChat_) {
103
void PsiChatDlg::setLooks()
107
ui_.splitter->optionsChanged();
108
ui_.mle->optionsChanged();
112
ui_.lb_status->hide();
114
ui_.tb_actions->hide();
115
ui_.tb_emoticons->hide();
119
ui_.lb_status->show();
121
if (PsiOptions::instance()->getOption("options.ui.chat.central-toolbar").toBool()) {
123
ui_.tb_actions->hide();
124
ui_.tb_emoticons->hide();
128
ui_.tb_emoticons->setVisible(PsiOptions::instance()->getOption("options.ui.emoticons.use-emoticons").toBool());
129
ui_.tb_actions->show();
133
updateIdentityVisibility();
134
updateCountVisibility();
138
i.setPixmap(IconsetFactory::icon("psi/cryptoNo").impix(), QIcon::Automatic, QIcon::Normal, QIcon::Off);
139
i.setPixmap(IconsetFactory::icon("psi/cryptoYes").impix(), QIcon::Automatic, QIcon::Normal, QIcon::On);
140
act_pgp_->setPsiIcon(0);
141
act_pgp_->setIcon(i);
144
void PsiChatDlg::setShortcuts()
146
ChatDlg::setShortcuts();
148
act_clear_->setShortcuts(ShortcutManager::instance()->shortcuts("chat.clear"));
149
act_info_->setShortcuts(ShortcutManager::instance()->shortcuts("common.user-info"));
150
act_history_->setShortcuts(ShortcutManager::instance()->shortcuts("common.history"));
153
void PsiChatDlg::updateIdentityVisibility()
156
bool visible = account()->psi()->contactList()->enabledAccounts().count() > 1;
157
ui_.lb_ident->setVisible(visible);
160
ui_.lb_ident->setVisible(false);
164
void PsiChatDlg::initToolButtons()
166
act_clear_ = new IconAction(tr("Clear chat window"), "psi/clearChat", tr("Clear chat window"), 0, this);
167
connect(act_clear_, SIGNAL(activated()), SLOT(doClearButton()));
169
connect(account()->psi()->iconSelectPopup(), SIGNAL(textSelected(QString)), this, SLOT(addEmoticon(QString)));
170
act_icon_ = new IconAction(tr("Select icon"), "psi/smile", tr("Select icon"), 0, this);
171
act_icon_->setMenu(account()->psi()->iconSelectPopup());
172
ui_.tb_emoticons->setMenu(account()->psi()->iconSelectPopup());
174
act_voice_ = new IconAction(tr("Voice Call"), "psi/voice", tr("Voice Call"), 0, this);
175
connect(act_voice_, SIGNAL(activated()), SLOT(doVoice()));
176
act_voice_->setEnabled(false);
178
act_file_ = new IconAction(tr("Send file"), "psi/upload", tr("Send file"), 0, this);
179
connect(act_file_, SIGNAL(activated()), SLOT(doFile()));
181
act_pgp_ = new IconAction(tr("Toggle encryption"), "psi/cryptoNo", tr("Toggle encryption"), 0, this, 0, true);
182
ui_.tb_pgp->setDefaultAction(act_pgp_);
184
act_info_ = new IconAction(tr("User info"), "psi/vCard", tr("User info"), 0, this);
185
connect(act_info_, SIGNAL(activated()), SLOT(doInfo()));
187
act_history_ = new IconAction(tr("Message history"), "psi/history", tr("Message history"), 0, this);
188
connect(act_history_, SIGNAL(activated()), SLOT(doHistory()));
190
act_compact_ = new IconAction(tr("Toggle Compact/Full size"), "psi/compact", tr("Toggle Compact/Full size"), 0, this);
191
connect(act_compact_, SIGNAL(activated()), SLOT(toggleSmallChat()));
194
void PsiChatDlg::initToolBar()
196
ui_.toolbar->setWindowTitle(tr("Chat toolbar"));
197
ui_.toolbar->setIconSize(QSize(16, 16));
198
ui_.toolbar->addAction(act_clear_);
199
ui_.toolbar->addWidget(new StretchWidget(ui_.toolbar));
200
ui_.toolbar->addAction(act_icon_);
201
ui_.toolbar->addAction(act_file_);
202
if (PsiOptions::instance()->getOption("options.pgp.enable").toBool()) {
203
ui_.toolbar->addAction(act_pgp_);
205
ui_.toolbar->addAction(act_info_);
206
ui_.toolbar->addAction(act_history_);
207
if (account()->voiceCaller()) {
208
ui_.toolbar->addAction(act_voice_);
212
void PsiChatDlg::contextMenuEvent(QContextMenuEvent *)
214
pm_settings_->exec(QCursor::pos());
217
void PsiChatDlg::capsChanged()
219
ChatDlg::capsChanged();
221
QString resource = jid().resource();
222
UserListItem *ul = account()->findFirstRelevant(jid());
223
if (resource.isEmpty() && ul && !ul->userResourceList().isEmpty()) {
224
resource = (*(ul->userResourceList().priority())).name();
226
act_voice_->setEnabled(!account()->capsManager()->isEnabled() || (ul && ul->isAvailable() && account()->capsManager()->features(jid().withResource(resource)).canVoice()));
229
void PsiChatDlg::activated()
231
ChatDlg::activated();
233
updateCountVisibility();
236
void PsiChatDlg::setContactToolTip(QString text)
238
ui_.lb_status->setToolTip(text);
239
ui_.avatar->setToolTip(text);
242
void PsiChatDlg::contactUpdated(UserListItem* u, int status, const QString& statusString)
244
Q_UNUSED(statusString);
246
if (status == -1 || !u) {
247
ui_.lb_status->setPsiIcon(IconsetFactory::iconPtr("status/noauth"));
250
ui_.lb_status->setPsiIcon(PsiIconset::instance()->statusPtr(jid(), status));
254
setContactToolTip(u->makeTip(true, false));
257
setContactToolTip(QString());
263
if (jid().resource().isEmpty())
264
j = JIDUtil::toString(u->jid(), true);
266
j = JIDUtil::toString(u->jid().userHost(), false) + '/' + jid().resource();
268
if (!u->name().isEmpty())
269
name = u->name() + QString(" <%1>").arg(j);
273
ui_.le_jid->setText(name);
274
ui_.le_jid->setCursorPosition(0);
275
ui_.le_jid->setToolTip(name);
279
void PsiChatDlg::updateAvatar()
284
if (!PsiOptions::instance()->getOption("options.ui.chat.avatars.show").toBool()) {
289
UserListItem *ul = account()->findFirstRelevant(jid());
290
if (ul && !ul->userResourceList().isEmpty()) {
291
UserResourceList::Iterator it = ul->userResourceList().find(jid().resource());
292
if (it == ul->userResourceList().end())
293
it = ul->userResourceList().priority();
296
client = (*it).clientName();
298
//QPixmap p = account()->avatarFactory()->getAvatar(jid().withResource(res),client);
299
QPixmap p = account()->avatarFactory()->getAvatar(jid().withResource(res));
304
int size = PsiOptions::instance()->getOption("options.ui.chat.avatars.size").toInt();
305
ui_.avatar->setPixmap(p.scaled(QSize(size, size), Qt::KeepAspectRatio, Qt::SmoothTransformation));
310
void PsiChatDlg::optionsUpdate()
312
smallChat_ = PsiOptions::instance()->getOption("options.ui.chat.use-small-chats").toBool();
314
ChatDlg::optionsUpdate();
317
void PsiChatDlg::updatePGP()
319
if (account()->hasPGP()) {
320
act_pgp_->setEnabled(true);
323
act_pgp_->setChecked(false);
324
act_pgp_->setEnabled(false);
327
ui_.tb_pgp->setVisible(account()->hasPGP() &&
329
!PsiOptions::instance()->getOption("options.ui.chat.central-toolbar").toBool());
332
void PsiChatDlg::doClearButton()
334
int n = QMessageBox::information(this, tr("Warning"), tr("Are you sure you want to clear the chat window?\n(note: does not affect saved history)"), tr("&Yes"), tr("&No"));
339
void PsiChatDlg::setPGPEnabled(bool enabled)
341
act_pgp_->setChecked(enabled);
344
void PsiChatDlg::toggleSmallChat()
346
smallChat_ = !smallChat_;
350
void PsiChatDlg::buildMenu()
353
pm_settings_->clear();
354
pm_settings_->addAction(act_compact_);
355
pm_settings_->addAction(act_clear_);
356
pm_settings_->insertSeparator();
358
pm_settings_->addAction(act_icon_);
359
pm_settings_->addAction(act_file_);
360
if (account()->voiceCaller())
361
act_voice_->addTo(pm_settings_);
362
pm_settings_->addAction(act_pgp_);
363
pm_settings_->insertSeparator();
365
pm_settings_->addAction(act_info_);
366
pm_settings_->addAction(act_history_);
369
void PsiChatDlg::updateCounter()
371
ui_.lb_count->setNum(chatEdit()->text().length());
374
void PsiChatDlg::appendEmoteMessage(SpooledType spooled, const QDateTime& time, bool local, QString txt)
376
updateLastMsgTime(time);
377
QString color = colorString(local, spooled);
378
QString timestr = chatView()->formatTimeStamp(time);
380
chatView()->appendText(QString("<span style=\"color: %1\">").arg(color) + QString("[%1]").arg(timestr) + QString(" *%1 ").arg(whoNick(local)) + txt + "</span>");
383
void PsiChatDlg::appendNormalMessage(SpooledType spooled, const QDateTime& time, bool local, QString txt)
385
updateLastMsgTime(time);
386
QString color = colorString(local, spooled);
387
QString timestr = chatView()->formatTimeStamp(time);
389
if (PsiOptions::instance()->getOption("options.ui.chat.use-chat-says-style").toBool()) {
390
chatView()->appendText(QString("<p style=\"color: %1\">").arg(color) + QString("[%1] ").arg(timestr) + tr("%1 says:").arg(whoNick(local)) + "</p>" + txt);
393
chatView()->appendText(QString("<span style=\"color: %1\">").arg(color) + QString("[%1] <").arg(timestr) + whoNick(local) + QString("></span> ") + txt);
397
void PsiChatDlg::appendMessageFields(const Message& m)
399
if (!m.subject().isEmpty()) {
400
chatView()->appendText(QString("<b>") + tr("Subject:") + "</b> " + QString("%1").arg(Qt::escape(m.subject())));
402
if (!m.urlList().isEmpty()) {
403
UrlList urls = m.urlList();
404
chatView()->appendText(QString("<i>") + tr("-- Attached URL(s) --") + "</i>");
405
for (QList<Url>::ConstIterator it = urls.begin(); it != urls.end(); ++it) {
407
chatView()->appendText(QString("<b>") + tr("URL:") + "</b> " + QString("%1").arg(TextUtil::linkify(Qt::escape(u.url()))));
408
chatView()->appendText(QString("<b>") + tr("Desc:") + "</b> " + QString("%1").arg(u.desc()));
413
bool PsiChatDlg::isEncryptionEnabled() const
415
return act_pgp_->isChecked();
418
void PsiChatDlg::appendSysMsg(const QString &str)
420
QDateTime t = QDateTime::currentDateTime();
421
updateLastMsgTime(t);
422
QString timestr = chatView()->formatTimeStamp(t);
423
QString color = "#00A000";
425
chatView()->appendText(QString("<font color=\"%1\">[%2]").arg(color, timestr) + QString(" *** %1</font>").arg(str));
428
QString PsiChatDlg::colorString(bool local, ChatDlg::SpooledType spooled) const
430
if (spooled == ChatDlg::Spooled_OfflineStorage)
439
ChatView* PsiChatDlg::chatView() const
444
ChatEdit* PsiChatDlg::chatEdit() const
446
return ui_.mle->chatEdit();
449
void PsiChatDlg::chatEditCreated()
451
ChatDlg::chatEditCreated();
453
connect(chatEdit(), SIGNAL(textChanged()), this, SLOT(updateCounter()));
454
chatEdit()->installEventFilter(this);
457
void PsiChatDlg::updateLastMsgTime(QDateTime t)
459
bool doInsert = t.date() != lastMsgTime_.date();
462
QString color = "#00A000";
463
chatView()->appendText(QString("<font color=\"%1\">*** %2</font>").arg(color).arg(t.date().toString(Qt::ISODate)));