~ubuntu-branches/ubuntu/vivid/psi/vivid

« back to all changes in this revision

Viewing changes to src/psichatdlg.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-08-28 18:46:52 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080828184652-iiik12dl91nq7cdi
Tags: 0.12-2
Uploading to unstable (Closes: Bug#494352)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "psichatdlg.h"
 
2
 
 
3
#include <QLabel>
 
4
#include <QCursor>
 
5
#include <QLineEdit>
 
6
#include <QToolButton>
 
7
#include <QLayout>
 
8
#include <QSplitter>
 
9
#include <QToolBar>
 
10
#include <QPixmap>
 
11
#include <QColor>
 
12
#include <QCloseEvent>
 
13
#include <QHBoxLayout>
 
14
#include <QVBoxLayout>
 
15
#include <QContextMenuEvent>
 
16
#include <QResizeEvent>
 
17
#include <QMenu>
 
18
#include <QDragEnterEvent>
 
19
#include <QMessageBox>
 
20
 
 
21
#include "psicon.h"
 
22
#include "psiaccount.h"
 
23
#include "iconaction.h"
 
24
#include "stretchwidget.h"
 
25
#include "psiiconset.h"
 
26
#include "iconwidget.h"
 
27
#include "fancylabel.h"
 
28
#include "msgmle.h"
 
29
#include "iconselect.h"
 
30
#include "avatars.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"
 
38
#include "userlist.h"
 
39
#include "jidutil.h"
 
40
#include "textutil.h"
 
41
 
 
42
PsiChatDlg::PsiChatDlg(const Jid& jid, PsiAccount* pa, TabManager* tabManager)
 
43
                : ChatDlg(jid, pa, tabManager)
 
44
{
 
45
        connect(account()->psi(), SIGNAL(accountCountChanged()), this, SLOT(updateIdentityVisibility()));
 
46
}
 
47
 
 
48
void PsiChatDlg::initUi()
 
49
{
 
50
        ui_.setupUi(this);
 
51
        ui_.lb_ident->setAccount(account());
 
52
        ui_.lb_ident->setShowJid(false);
 
53
 
 
54
        PsiToolTip::install(ui_.lb_status);
 
55
        ui_.lb_status->setPsiIcon(IconsetFactory::iconPtr("status/noauth"));
 
56
 
 
57
        ui_.tb_emoticons->setIcon(IconsetFactory::icon("psi/smile").icon());
 
58
 
 
59
        connect(ui_.mle, SIGNAL(textEditCreated(QTextEdit*)), SLOT(chatEditCreated()));
 
60
        chatEditCreated();
 
61
 
 
62
#ifdef Q_WS_MAC
 
63
        connect(chatView(), SIGNAL(selectionChanged()), SLOT(logSelectionChanged()));
 
64
#endif
 
65
 
 
66
        initToolButtons();
 
67
        initToolBar();
 
68
        updateAvatar();
 
69
        
 
70
        PsiToolTip::install(ui_.avatar);
 
71
 
 
72
        UserListItem* u = account()->findFirstRelevant(jid());
 
73
        if (u && u->isSecure(jid().resource())) {
 
74
                setPGPEnabled(true);
 
75
        }
 
76
 
 
77
        connect(account()->avatarFactory(), SIGNAL(avatarChanged(const Jid&)), this, SLOT(updateAvatar(const Jid&)));
 
78
 
 
79
        pm_settings_ = new QMenu(this);
 
80
        connect(pm_settings_, SIGNAL(aboutToShow()), SLOT(buildMenu()));
 
81
        ui_.tb_actions->setMenu(pm_settings_);
 
82
 
 
83
        connect(account()->capsManager(), SIGNAL(capsChanged(const Jid&)), SLOT(capsChanged(const Jid&)));
 
84
 
 
85
        QList<int> list;
 
86
        list << 324;
 
87
        list << 96;
 
88
        ui_.splitter->setSizes(list);
 
89
 
 
90
        smallChat_ = PsiOptions::instance()->getOption("options.ui.chat.use-small-chats").toBool();
 
91
}
 
92
 
 
93
void PsiChatDlg::updateCountVisibility()
 
94
{
 
95
        if (PsiOptions::instance()->getOption("options.ui.message.show-character-count").toBool() && !smallChat_) {
 
96
                ui_.lb_count->show();
 
97
        }
 
98
        else {
 
99
                ui_.lb_count->hide();
 
100
        }
 
101
}
 
102
 
 
103
void PsiChatDlg::setLooks()
 
104
{
 
105
        ChatDlg::setLooks();
 
106
 
 
107
        ui_.splitter->optionsChanged();
 
108
        ui_.mle->optionsChanged();
 
109
 
 
110
        ui_.tb_pgp->hide();
 
111
        if (smallChat_) {
 
112
                ui_.lb_status->hide();
 
113
                ui_.le_jid->hide();
 
114
                ui_.tb_actions->hide();
 
115
                ui_.tb_emoticons->hide();
 
116
                ui_.toolbar->hide();
 
117
        }
 
118
        else {
 
119
                ui_.lb_status->show();
 
120
                ui_.le_jid->show();
 
121
                if (PsiOptions::instance()->getOption("options.ui.chat.central-toolbar").toBool()) {
 
122
                        ui_.toolbar->show();
 
123
                        ui_.tb_actions->hide();
 
124
                        ui_.tb_emoticons->hide();
 
125
                }
 
126
                else {
 
127
                        ui_.toolbar->hide();
 
128
                        ui_.tb_emoticons->setVisible(PsiOptions::instance()->getOption("options.ui.emoticons.use-emoticons").toBool());
 
129
                        ui_.tb_actions->show();
 
130
                }
 
131
        }
 
132
 
 
133
        updateIdentityVisibility();
 
134
        updateCountVisibility();
 
135
 
 
136
        // toolbuttons
 
137
        QIcon i;
 
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);
 
142
}
 
143
 
 
144
void PsiChatDlg::setShortcuts()
 
145
{
 
146
        ChatDlg::setShortcuts();
 
147
 
 
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"));
 
151
}
 
152
 
 
153
void PsiChatDlg::updateIdentityVisibility()
 
154
{
 
155
        if (!smallChat_) {
 
156
                bool visible = account()->psi()->contactList()->enabledAccounts().count() > 1;
 
157
                ui_.lb_ident->setVisible(visible);
 
158
        }
 
159
        else {
 
160
                ui_.lb_ident->setVisible(false);
 
161
        }
 
162
}
 
163
 
 
164
void PsiChatDlg::initToolButtons()
 
165
{
 
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()));
 
168
 
 
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());
 
173
 
 
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);
 
177
 
 
178
        act_file_ = new IconAction(tr("Send file"), "psi/upload", tr("Send file"), 0, this);
 
179
        connect(act_file_, SIGNAL(activated()), SLOT(doFile()));
 
180
 
 
181
        act_pgp_ = new IconAction(tr("Toggle encryption"), "psi/cryptoNo", tr("Toggle encryption"), 0, this, 0, true);
 
182
        ui_.tb_pgp->setDefaultAction(act_pgp_);
 
183
 
 
184
        act_info_ = new IconAction(tr("User info"), "psi/vCard", tr("User info"), 0, this);
 
185
        connect(act_info_, SIGNAL(activated()), SLOT(doInfo()));
 
186
 
 
187
        act_history_ = new IconAction(tr("Message history"), "psi/history", tr("Message history"), 0, this);
 
188
        connect(act_history_, SIGNAL(activated()), SLOT(doHistory()));
 
189
 
 
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()));
 
192
}
 
193
 
 
194
void PsiChatDlg::initToolBar()
 
195
{
 
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_);
 
204
        }
 
205
        ui_.toolbar->addAction(act_info_);
 
206
        ui_.toolbar->addAction(act_history_);
 
207
        if (account()->voiceCaller()) {
 
208
                ui_.toolbar->addAction(act_voice_);
 
209
        }
 
210
}
 
211
 
 
212
void PsiChatDlg::contextMenuEvent(QContextMenuEvent *)
 
213
{
 
214
        pm_settings_->exec(QCursor::pos());
 
215
}
 
216
 
 
217
void PsiChatDlg::capsChanged()
 
218
{
 
219
        ChatDlg::capsChanged();
 
220
 
 
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();
 
225
        }
 
226
        act_voice_->setEnabled(!account()->capsManager()->isEnabled() || (ul && ul->isAvailable() && account()->capsManager()->features(jid().withResource(resource)).canVoice()));
 
227
}
 
228
 
 
229
void PsiChatDlg::activated()
 
230
{
 
231
        ChatDlg::activated();
 
232
 
 
233
        updateCountVisibility();
 
234
}
 
235
 
 
236
void PsiChatDlg::setContactToolTip(QString text)
 
237
{
 
238
        ui_.lb_status->setToolTip(text);
 
239
        ui_.avatar->setToolTip(text);
 
240
}
 
241
 
 
242
void PsiChatDlg::contactUpdated(UserListItem* u, int status, const QString& statusString)
 
243
{
 
244
        Q_UNUSED(statusString);
 
245
 
 
246
        if (status == -1 || !u) {
 
247
                ui_.lb_status->setPsiIcon(IconsetFactory::iconPtr("status/noauth"));
 
248
        }
 
249
        else {
 
250
                ui_.lb_status->setPsiIcon(PsiIconset::instance()->statusPtr(jid(), status));
 
251
        }
 
252
 
 
253
        if (u) {
 
254
                setContactToolTip(u->makeTip(true, false));
 
255
        }
 
256
        else {
 
257
                setContactToolTip(QString());
 
258
        }
 
259
 
 
260
        if (u) {
 
261
                QString name;
 
262
                QString j;
 
263
                if (jid().resource().isEmpty())
 
264
                        j = JIDUtil::toString(u->jid(), true);
 
265
                else
 
266
                        j = JIDUtil::toString(u->jid().userHost(), false) + '/' + jid().resource();
 
267
 
 
268
                if (!u->name().isEmpty())
 
269
                        name = u->name() + QString(" <%1>").arg(j);
 
270
                else
 
271
                        name = j;
 
272
 
 
273
                ui_.le_jid->setText(name);
 
274
                ui_.le_jid->setCursorPosition(0);
 
275
                ui_.le_jid->setToolTip(name);
 
276
        }
 
277
}
 
278
 
 
279
void PsiChatDlg::updateAvatar()
 
280
{
 
281
        QString res;
 
282
        QString client;
 
283
 
 
284
        if (!PsiOptions::instance()->getOption("options.ui.chat.avatars.show").toBool()) {
 
285
                ui_.avatar->hide();
 
286
                return;
 
287
        }
 
288
 
 
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();
 
294
 
 
295
                res = (*it).name();
 
296
                client = (*it).clientName();
 
297
        }
 
298
        //QPixmap p = account()->avatarFactory()->getAvatar(jid().withResource(res),client);
 
299
        QPixmap p = account()->avatarFactory()->getAvatar(jid().withResource(res));
 
300
        if (p.isNull()) {
 
301
                ui_.avatar->hide();
 
302
        }
 
303
        else {
 
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));
 
306
                ui_.avatar->show();
 
307
        }
 
308
}
 
309
 
 
310
void PsiChatDlg::optionsUpdate()
 
311
{
 
312
        smallChat_ = PsiOptions::instance()->getOption("options.ui.chat.use-small-chats").toBool();
 
313
 
 
314
        ChatDlg::optionsUpdate();
 
315
}
 
316
 
 
317
void PsiChatDlg::updatePGP()
 
318
{
 
319
        if (account()->hasPGP()) {
 
320
                act_pgp_->setEnabled(true);
 
321
        }
 
322
        else {
 
323
                act_pgp_->setChecked(false);
 
324
                act_pgp_->setEnabled(false);
 
325
        }
 
326
 
 
327
        ui_.tb_pgp->setVisible(account()->hasPGP() &&
 
328
                               !smallChat_ &&
 
329
                               !PsiOptions::instance()->getOption("options.ui.chat.central-toolbar").toBool());
 
330
}
 
331
 
 
332
void PsiChatDlg::doClearButton()
 
333
{
 
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"));
 
335
        if (n == 0)
 
336
                doClear();
 
337
}
 
338
 
 
339
void PsiChatDlg::setPGPEnabled(bool enabled)
 
340
{
 
341
        act_pgp_->setChecked(enabled);
 
342
}
 
343
 
 
344
void PsiChatDlg::toggleSmallChat()
 
345
{
 
346
        smallChat_ = !smallChat_;
 
347
        setLooks();
 
348
}
 
349
 
 
350
void PsiChatDlg::buildMenu()
 
351
{
 
352
        // Dialog menu
 
353
        pm_settings_->clear();
 
354
        pm_settings_->addAction(act_compact_);
 
355
        pm_settings_->addAction(act_clear_);
 
356
        pm_settings_->insertSeparator();
 
357
 
 
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();
 
364
 
 
365
        pm_settings_->addAction(act_info_);
 
366
        pm_settings_->addAction(act_history_);
 
367
}
 
368
 
 
369
void PsiChatDlg::updateCounter()
 
370
{
 
371
        ui_.lb_count->setNum(chatEdit()->text().length());
 
372
}
 
373
 
 
374
void PsiChatDlg::appendEmoteMessage(SpooledType spooled, const QDateTime& time, bool local, QString txt)
 
375
{
 
376
        updateLastMsgTime(time);
 
377
        QString color = colorString(local, spooled);
 
378
        QString timestr = chatView()->formatTimeStamp(time);
 
379
 
 
380
        chatView()->appendText(QString("<span style=\"color: %1\">").arg(color) + QString("[%1]").arg(timestr) + QString(" *%1 ").arg(whoNick(local)) + txt + "</span>");
 
381
}
 
382
 
 
383
void PsiChatDlg::appendNormalMessage(SpooledType spooled, const QDateTime& time, bool local, QString txt)
 
384
{
 
385
        updateLastMsgTime(time);
 
386
        QString color = colorString(local, spooled);
 
387
        QString timestr = chatView()->formatTimeStamp(time);
 
388
 
 
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);
 
391
        }
 
392
        else {
 
393
                chatView()->appendText(QString("<span style=\"color: %1\">").arg(color) + QString("[%1] &lt;").arg(timestr) + whoNick(local) + QString("&gt;</span> ") + txt);
 
394
        }
 
395
}
 
396
 
 
397
void PsiChatDlg::appendMessageFields(const Message& m)
 
398
{
 
399
        if (!m.subject().isEmpty()) {
 
400
                chatView()->appendText(QString("<b>") + tr("Subject:") + "</b> " + QString("%1").arg(Qt::escape(m.subject())));
 
401
        }
 
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) {
 
406
                        const Url &u = *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()));
 
409
                }
 
410
        }
 
411
}
 
412
 
 
413
bool PsiChatDlg::isEncryptionEnabled() const
 
414
{
 
415
        return act_pgp_->isChecked();
 
416
}
 
417
 
 
418
void PsiChatDlg::appendSysMsg(const QString &str)
 
419
{
 
420
        QDateTime t = QDateTime::currentDateTime();
 
421
        updateLastMsgTime(t);
 
422
        QString timestr = chatView()->formatTimeStamp(t);
 
423
        QString color = "#00A000";
 
424
 
 
425
        chatView()->appendText(QString("<font color=\"%1\">[%2]").arg(color, timestr) + QString(" *** %1</font>").arg(str));
 
426
}
 
427
 
 
428
QString PsiChatDlg::colorString(bool local, ChatDlg::SpooledType spooled) const
 
429
{
 
430
        if (spooled == ChatDlg::Spooled_OfflineStorage)
 
431
                return "#008000";
 
432
 
 
433
        if (local)
 
434
                return "#FF0000";
 
435
 
 
436
        return "#0000FF";
 
437
}
 
438
 
 
439
ChatView* PsiChatDlg::chatView() const
 
440
{
 
441
        return ui_.log;
 
442
}
 
443
 
 
444
ChatEdit* PsiChatDlg::chatEdit() const
 
445
{
 
446
        return ui_.mle->chatEdit();
 
447
}
 
448
 
 
449
void PsiChatDlg::chatEditCreated()
 
450
{
 
451
        ChatDlg::chatEditCreated();
 
452
 
 
453
        connect(chatEdit(), SIGNAL(textChanged()), this, SLOT(updateCounter()));
 
454
        chatEdit()->installEventFilter(this);
 
455
}
 
456
 
 
457
void PsiChatDlg::updateLastMsgTime(QDateTime t)
 
458
{
 
459
        bool doInsert = t.date() != lastMsgTime_.date();
 
460
        lastMsgTime_ = t;
 
461
        if (doInsert) {
 
462
                QString color = "#00A000";
 
463
                chatView()->appendText(QString("<font color=\"%1\">*** %2</font>").arg(color).arg(t.date().toString(Qt::ISODate)));
 
464
        }
 
465
}