1
/****************************************************************************
2
** chatdlg.cpp - a single window chat dialog
3
** Copyright (C) 2001, 2002 Justin Karneges
5
** This program is free software; you can redistribute it and/or
6
** modify it under the terms of the GNU General Public License
7
** as published by the Free Software Foundation; either version 2
8
** of the License, or (at your option) any later version.
10
** This program is distributed in the hope that it will be useful,
11
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
** GNU General Public License for more details.
15
** You should have received a copy of the GNU General Public License
16
** along with this program; if not, write to the Free Software
17
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
19
****************************************************************************/
2
* chatdlg.cpp - dialog for handling chats
3
* Copyright (C) 2001, 2002 Justin Karneges
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
21
#include"chatdlg.h"
26
#include<qtoolbutton.h>
23
28
#include<qsplitter.h>
25
31
#include<qdatetime.h>
32
#include<qlcdnumber.h>
34
#include"psiaccount.h"
37
#include"iconwidget.h"
38
#include"fancylabel.h"
40
#include"iconselect.h"
30
44
#include<windows.h>
34
ChatDlg::ChatDlg(UserListItem *item, const QString &_whoami, int _localStatus, QWidget *parent)
35
:QWidget(parent, "chatwindow"), UniqueWindow(TRUE, "ChatDlg", this, cleanJid(item->jid))
37
//setWFlags(getWFlags() | WDestructiveClose);
38
resize(option.sizeChatDlg);
40
// save everything locally
43
v_status = item->state;
46
localStatus = _localStatus;
52
setIcon(anim_chat->base());
54
QVBoxLayout *vb1 = new QVBoxLayout(this, 4);
55
QSplitter *sp = new QSplitter(Vertical, this);
59
lo_single = new QWidget(sp);
60
QVBoxLayout *lo_single_vb = new QVBoxLayout(lo_single, 4);
61
QHBoxLayout *lo_single_hb = new QHBoxLayout(lo_single_vb);
62
lb_statusIcon = new QLabel(lo_single);
63
lo_single_hb->addWidget(lb_statusIcon);
65
le_nick = new QLineEdit(lo_single);
66
le_nick->setReadOnly(TRUE);
67
le_nick->setFixedWidth(120);
68
lo_single_hb->addWidget(le_nick);
70
lo_single_hb->addSpacing(16);
72
QLabel *lo_single_jid = new QLabel(tr("Jabber ID"), lo_single);
73
lo_single_hb->addWidget(lo_single_jid);
74
le_jid = new QLineEdit(lo_single);
75
le_jid->setReadOnly(TRUE);
76
le_jid->setText(v_jid);
77
le_jid->setCursorPosition(0);
78
QToolTip::add(le_jid, v_jid);
79
lo_single_hb->addWidget(le_jid);
81
t = new MsgMle(lo_single);
82
connect(t, SIGNAL(linkClicked(const QString &)), SIGNAL(aOpenURL(const QString &)));
84
t->setUndoRedoEnabled(FALSE);
85
lo_single_vb->addWidget(t);
88
QWidget *w = new QWidget(sp);
90
QVBoxLayout *vb2 = new QVBoxLayout(w, 4);
91
QHBoxLayout *hb1 = new QHBoxLayout(vb2);
93
QToolButton *tb_clear = new QToolButton(w);
94
tb_clear->setIconSet(QIconSet(*pix_chatclear));
95
connect(tb_clear, SIGNAL(clicked()), SLOT(doClearButton()));
96
QToolTip::add(tb_clear, tr("Clear chat window"));
97
hb1->addWidget(tb_clear);
101
tb_info = new QToolButton(w);
102
tb_info->setIconSet(QIconSet(*pix_info));
103
connect(tb_info, SIGNAL(clicked()), SLOT(doInfo()));
104
QToolTip::add(tb_info, tr("User info"));
105
hb1->addWidget(tb_info);
107
tb_history = new QToolButton(w);
108
tb_history->setIconSet(QIconSet(*pix_history));
109
connect(tb_history, SIGNAL(clicked()), SLOT(doHistory()));
110
QToolTip::add(tb_history, tr("Message history"));
111
hb1->addWidget(tb_history);
47
//----------------------------------------------------------------------------
49
//----------------------------------------------------------------------------
50
class ChatDlg::Private : public QObject
71
QLCDNumber *lcd_count;
72
IconToolButton *tb_send, *tb_clear, *tb_history, *tb_info, *tb_pgp, *tb_icon, *tb_file;
73
QPopupMenu *pm_settings;
76
bool keepOpen, warnSend;
85
bool lastWasEncrypted;
89
void addEmoticon(const Icon *icon) {
90
if ( !dlg->isActiveWindow() )
95
QDict<QString> itext = icon->text();
96
QDictIterator<QString> it ( itext );
97
for ( ; it.current(); ++it) {
98
if ( it.current() && !it.current()->isEmpty() ) {
99
text = *(it.current()) + " ";
104
if ( !text.isEmpty() )
108
void addEmoticon(QString text) {
109
if ( !dlg->isActiveWindow() )
112
mle->insert( text + " " );
115
void updateCounter() {
116
lcd_count->display((int)mle->text().length());
120
ChatDlg::ChatDlg(const Jid &jid, PsiAccount *pa)
123
d = new Private(this);
134
d->lastWasEncrypted = false;
136
QVBoxLayout *vb1 = new QVBoxLayout(this, 4);
137
QSplitter *sp = new QSplitter(Vertical, this);
140
QWidget *sp_top = new QWidget(sp);
142
QVBoxLayout *vb2 = new QVBoxLayout(sp_top, 4);
143
d->lb_ident = d->pa->accountLabel(sp_top, true);
144
d->lb_ident->setSizePolicy(QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ));
113
147
QHBoxLayout *hb2 = new QHBoxLayout(vb2);
114
mle = new ChatMle(w);
115
mle->setMinimumHeight(48);
117
//hb2->addStretch(1);
119
/*(tb_send = new QToolButton(w);
120
QPalette mypal = tb_send->palette();
121
mypal.setColor(QColorGroup::Button, palette().color(QPalette::Normal, QColorGroup::Background));
122
tb_send->setPalette(mypal);
124
QIconSet is(*pix_chatsend1, QIconSet::Large);
125
//is.setPixmap(*pix_chatsend1, QIconSet::Large, QIconSet::Normal);
126
is.setPixmap(*pix_chatsend2, QIconSet::Large, QIconSet::Active);
127
tb_send->setIconSet(is);
128
tb_send->setAutoRaise(TRUE);
129
tb_send->setUsesBigPixmap(TRUE);
130
//tb_send->setFixedSize(56,56);
131
connect(tb_send, SIGNAL(clicked()), SLOT(doSend()));
132
hb2->addWidget(tb_send);*/
148
d->lb_status = new IconLabel(sp_top);
149
d->lb_status->setIcon(IconsetFactory::iconPtr("status/noauth"));
150
hb2->addWidget(d->lb_status);
151
d->le_jid = new QLineEdit(sp_top);
152
d->le_jid->setReadOnly(true);
153
d->lcd_count = new QLCDNumber(sp_top);
154
d->le_jid->setFocusPolicy(QWidget::NoFocus);
155
QToolTip::add(d->lcd_count, tr("Message length"));
156
d->lcd_count->setFixedWidth(50);
157
hb2->addWidget(d->le_jid);
158
hb2->addWidget(d->lcd_count);
159
hb2->addWidget(d->lb_ident);
162
d->log = new ChatView(sp_top);
163
vb2->addWidget(d->log);
165
QWidget *sp_bottom = new QWidget(sp);
167
QVBoxLayout *vb3 = new QVBoxLayout(sp_bottom, 4);
168
QHBoxLayout *hb3 = new QHBoxLayout(vb3);
169
d->tb_clear = new IconToolButton(sp_bottom);
170
connect(d->tb_clear, SIGNAL(clicked()), SLOT(doClearButton()));
171
QToolTip::add(d->tb_clear, tr("Clear chat window"));
172
hb3->addWidget(d->tb_clear);
176
//connect(pa->psi()->iconSelectPopup(), SIGNAL(iconSelected(const Icon *)), d, SLOT(addEmoticon(const Icon *)));
177
connect(pa->psi()->iconSelectPopup(), SIGNAL(textSelected(QString)), d, SLOT(addEmoticon(QString)));
178
d->tb_icon = new IconToolButton(sp_bottom);
179
d->tb_icon->setPopup(pa->psi()->iconSelectPopup());
180
d->tb_icon->setPopupDelay (1);
181
QToolTip::add(d->tb_icon, tr("Select icon"));
182
hb3->addWidget(d->tb_icon);
184
d->tb_file = new IconToolButton(sp_bottom);
185
connect(d->tb_file, SIGNAL(clicked()), SLOT(doFile()));
186
QToolTip::add(d->tb_file, tr("Send file"));
187
hb3->addWidget(d->tb_file);
189
d->tb_pgp = new IconToolButton(sp_bottom);
190
d->tb_pgp->setToggleButton(true);
191
QToolTip::add(d->tb_pgp, tr("Toggle encryption"));
192
hb3->addWidget(d->tb_pgp);
194
d->tb_info = new IconToolButton(sp_bottom);
195
connect(d->tb_info, SIGNAL(clicked()), SLOT(doInfo()));
196
QToolTip::add(d->tb_info, tr("User info"));
197
hb3->addWidget(d->tb_info);
199
d->tb_history = new IconToolButton(sp_bottom);
200
connect(d->tb_history, SIGNAL(clicked()), SLOT(doHistory()));
201
QToolTip::add(d->tb_history, tr("Message history"));
202
hb3->addWidget(d->tb_history);
204
d->mle = new ChatEdit(sp_bottom);
205
vb3->addWidget(d->mle);
206
connect(d->mle, SIGNAL(textChanged()), d, SLOT(updateCounter()));
208
d->pm_settings=new QPopupMenu(this);
210
connect(d->pm_settings, SIGNAL(aboutToShow()), SLOT(buildMenu()));
136
211
QValueList<int> list;
141
214
sp->setSizes(list);
145
mle->setTextFormat(PlainText);
146
t->setTextFormat(RichText);
149
//if(localStatus == STATUS_OFFLINE)
150
// tb_send->setEnabled(FALSE);
217
d->pa->dialogRegister(this, d->jid);
219
updateContact(d->jid, true);
221
d->smallChat=option.smallChats;
154
QString msg = expandEntities(jidnick(v_jid, v_nick)) + " is " + status2txt(v_status);
155
if(!item->statusString.isEmpty()) {
156
msg += QString(" [%1]").arg(item->statusString);
226
connect(d->pa, SIGNAL(pgpKeyChanged()), SLOT(updatePGP()));
227
connect(d->pa, SIGNAL(encryptedMessageSent(int, bool)), SLOT(encryptedMessageSent(int, bool)));
229
d->le_jid->setFocusPolicy(QWidget::NoFocus);
230
d->log->setFocusPolicy(QWidget::NoFocus);
233
resize(option.sizeChatDlg);
235
UserListItem *u = d->pa->findFirstRelavent(d->jid);
236
if(u && u->isSecure(d->jid.resource()))
237
d->tb_pgp->setOn(true);
161
240
ChatDlg::~ChatDlg()
165
QSize ChatDlg::defaultSize()
167
return QSize(380, 420);
170
void ChatDlg::resizeEvent(QResizeEvent *e)
173
option.sizeChatDlg = e->size();
242
d->pa->dialogUnregister(this);
244
//QMimeSourceFactory *m = d->log->mimeSourceFactory();
245
//d->log->setMimeSourceFactory(QMimeSourceFactory::defaultFactory());
251
void ChatDlg::contextMenuEvent(QContextMenuEvent *)
253
d->pm_settings->exec(QCursor::pos());
176
256
void ChatDlg::keyPressEvent(QKeyEvent *e)
178
if(e->key() == Key_Escape)
180
else if(e->key() == Key_Return || (e->key() == Key_S && (e->state() & AltButton)))
258
if(e->key() == Key_Escape)
261
else if(e->key() == Key_W && e->state() & ControlButton)
264
else if(e->key() == Key_Return || e->key() == Key_Enter || (e->key() == Key_S && (e->state() & AltButton)))
182
else if(e->key() == Key_H && (e->state() & ControlButton))
266
else if(e->key() == Key_H && (e->state() & ControlButton))
184
268
else if(e->key() == Key_PageUp && (e->state() & ShiftButton))
185
t->setContentsPos(t->contentsX(), t->contentsY() - t->visibleHeight()/2);
269
d->log->setContentsPos(d->log->contentsX(), d->log->contentsY() - d->log->visibleHeight()/2);
186
270
else if(e->key() == Key_PageDown && (e->state() & ShiftButton))
187
t->setContentsPos(t->contentsX(), t->contentsY() + t->visibleHeight()/2);
271
d->log->setContentsPos(d->log->contentsX(), d->log->contentsY() + d->log->visibleHeight()/2);
276
void ChatDlg::resizeEvent(QResizeEvent *e)
279
option.sizeChatDlg = e->size();
192
282
void ChatDlg::closeEvent(QCloseEvent *e)
284
// really lame way of checking if we are encrypting
285
if(!d->mle->isEnabled())
195
289
int n = QMessageBox::information(this, tr("Warning"), tr("A new chat message was just received.\nDo you still want to close the window?"), tr("&Yes"), tr("&No"));
223
324
// if we're bringing it to the front, get rid of the '*' if necessary
224
325
if(isActiveWindow()) {
235
/* static */ ChatDlg *ChatDlg::find(const QString &xjid)
237
return (ChatDlg *)UniqueWindowBank::find("ChatDlg", cleanJid(xjid));
240
void ChatDlg::localUpdate(const JabRosterEntry &e)
242
localStatus = e.localStatus();
245
//if(localStatus == STATUS_OFFLINE)
246
// tb_send->setEnabled(FALSE);
248
// tb_send->setEnabled(TRUE);
251
void ChatDlg::updateContact(UserListItem *item)
253
if(jidcmp(item->jid, v_jid)) {
254
int oldstate = v_status;
258
v_status = item->state;
260
QString nick = jidnick(item->jid, item->nick);
262
if(nick != le_nick->text()) {
263
le_nick->setText(nick);
264
le_nick->setCursorPosition(0);
265
QToolTip::add(le_nick, nick);
267
if(nick != caption()) {
272
lb_statusIcon->setPixmap(jidIsAgent(v_jid) ? transport2icon(v_jid, v_status) : status2pix(v_status));
274
if(oldstate != v_status && !isHidden()) {
275
QString msg = expandEntities(jidnick(v_jid, v_nick)) + " is " + status2txt(v_status);
276
if(!item->statusString.isEmpty()) {
277
msg += QString(" [%1]").arg(item->statusString);
284
void ChatDlg::incomingMessage(const Message &msg)
286
//if(!jidcmp(msg.from, v_jid))
292
void ChatDlg::doSend()
294
if(mle->text().isEmpty())
297
if(mle->text() == "/clear") {
303
if(localStatus == STATUS_OFFLINE)
306
//if(!tb_send->isEnabled())
311
msg.type = MESSAGE_CHAT;
312
if(option.outgoingAs == 1)
313
msg.type = MESSAGE_NORM;
314
msg.text = mle->text();
315
msg.timeStamp = QDateTime::currentDateTime();
316
msg.originLocal = TRUE;
325
void ChatDlg::appendMessage(const Message &msg)
329
if(msg.originLocal) {
334
who = jidnick(v_jid, v_nick);
341
QDateTime time = msg.timeStamp;
342
timestr.sprintf("%02d:%02d:%02d", time.time().hour(), time.time().minute(), time.time().second());
344
int y = t->contentsHeight() - t->visibleHeight();
347
bool atBottom = (t->contentsY() < y - 32) ? FALSE: TRUE;
349
//t->setUpdatesEnabled(FALSE);
350
if(msg.text.left(4) == "/me ") {
351
QString txt = plain2rich(msg.text.mid(4));
352
t->append(QString("<font color=\"%1\">").arg(color) + QString("[%1]").arg(timestr) + QString(" *%1 ").arg(expandEntities(who)) + txt + "</font><br>\n");
355
QString txt = linkify(plain2rich(msg.text));
356
t->append(QString("<font color=\"%1\">").arg(color) + QString("[%1] <").arg(timestr) + expandEntities(who) + QString("></font> ") + txt + "<br>\n");
359
if(!(!msg.originLocal && !atBottom)) {
360
// scroll after some event loop processing
361
//QTimer::singleShot(0, this, SLOT(deferredScroll()));
364
//if(msg.originLocal)
367
// if we're not active, notify the user by changing the title
368
if(!isActiveWindow()) {
374
if(!msg.originLocal) {
376
QTimer::singleShot(1000, this, SLOT(setKeepOpenFalse()));
380
void ChatDlg::doHistory()
385
void ChatDlg::doAuth()
389
void ChatDlg::doAdd()
393
void ChatDlg::doInfo()
328
messagesRead(d->jid);
333
if(option.showCounter && !d->smallChat)
334
d->lcd_count->show();
336
d->lcd_count->hide();
342
const Jid & ChatDlg::jid() const
347
void ChatDlg::setJid(const Jid &jid)
349
if(!jid.compare(d->jid)) {
350
d->pa->dialogUnregister(this);
352
d->pa->dialogRegister(this, d->jid);
353
updateContact(d->jid, false);
357
QSize ChatDlg::defaultSize()
359
return QSize(380, 420);
362
void ChatDlg::updateContact(const Jid &jid, bool fromPresence)
364
// if groupchat, only update if the resource matches
365
if(d->pa->findGCContact(jid) && !d->jid.compare(jid))
368
if(d->jid.compare(jid, false)) {
369
QString rname = d->jid.resource();
370
QPtrList<UserListItem> ul = d->pa->findRelavent(jid);
373
QString statusString, key;
376
if(rname.isEmpty()) {
378
if(!u->isAvailable())
379
status = STATUS_OFFLINE;
381
const UserResource &r = *u->userResourceList().priority();
382
status = makeSTATUS(r.status());
383
statusString = r.status().status();
384
key = r.publicKeyID();
389
UserResourceList::ConstIterator rit = u->userResourceList().find(rname);
390
if(rit != u->userResourceList().end()) {
391
status = makeSTATUS((*rit).status());
392
statusString = (*rit).status().status();
393
key = (*rit).publicKeyID();
396
status = STATUS_OFFLINE;
397
statusString = u->lastUnavailableStatus().status();
403
bool statusChanged = false;
404
if(d->status != status || d->statusString != statusString) {
405
statusChanged = true;
407
d->statusString = statusString;
410
//if(statusChanged) {
411
if(status == -1 || !u)
412
d->lb_status->setIcon(IconsetFactory::iconPtr("status/noauth"));
414
d->lb_status->setIcon(is->statusPtr(jid, status));
418
QToolTip::add(d->lb_status, u->makeTip(true, false));
420
QToolTip::remove(d->lb_status);
428
j = u->jid().userHost() + '/' + rname;
430
if(!u->name().isEmpty())
431
name = u->name() + QString(" <%1>").arg(j);
435
d->le_jid->setText(name);
436
d->le_jid->setCursorPosition(0);
437
QToolTip::add(d->le_jid, name);
439
d->dispNick = jidnick(u->jid().full(), u->name());
445
if(fromPresence && statusChanged) {
446
QString msg = tr("%1 is %2").arg(expandEntities(d->dispNick)).arg(status2txt(d->status));
447
if(!statusString.isEmpty()) {
448
QString ss = linkify(plain2rich(statusString));
449
if(option.useEmoticons)
450
ss = emoticonify(ss);
452
msg += QString(" [%1]").arg(ss);
398
460
void ChatDlg::setLooks()
546
662
void ChatDlg::flashAnimate()
549
FlashWindow(winId(), TRUE);
551
//if(flashCount == 10)
665
FlashWindow(winId(), true);
667
if(d->flashCount == 5)
668
d->flashTimer->stop();
672
void ChatDlg::doSend()
674
if(!d->mle->isEnabled())
677
if(d->mle->text().isEmpty())
680
if(d->mle->text() == "/clear") {
686
if(!d->pa->loggedIn())
691
int n = QMessageBox::information(this, tr("Warning"), tr(
692
"<p>Encryption was recently disabled by the remote contact. "
693
"Are you sure you want to send this message without encryption?</p>"
694
), tr("&Yes"), tr("&No"));
701
m.setBody(d->mle->text());
702
m.setTimeStamp(QDateTime::currentDateTime());
703
if(d->tb_pgp->isOn())
704
m.setWasEncrypted(true);
707
if(d->tb_pgp->isOn()) {
708
d->mle->setEnabled(false);
709
d->transid = d->pa->sendMessageEncrypted(m);
710
if(d->transid == -1) {
711
d->mle->setEnabled(true);
722
void ChatDlg::doneSend()
724
appendMessage(d->m, true);
728
void ChatDlg::encryptedMessageSent(int x, bool b)
738
QMessageBox::information(this, tr("Error"), tr("There was an error trying to send the message encrypted.\nCheck your OpenPGP application/settings."));
739
d->mle->setEnabled(true);
743
void ChatDlg::incomingMessage(const Message &m)
748
void ChatDlg::appendSysMsg(const QString &str)
751
QDateTime time = QDateTime::currentDateTime();
752
//timestr.sprintf("%02d:%02d:%02d", time.time().hour(), time.time().minute(), time.time().second());
753
timestr = time.time().toString(LocalDate);
755
int y = d->log->contentsHeight() - d->log->visibleHeight();
758
bool atBottom = (d->log->contentsY() < y - 32) ? false: true;
760
d->log->append(QString("<font color=\"#00A000\">[%1]").arg(timestr) + QString(" *** %1</font>").arg(str));
765
void ChatDlg::appendMessage(const Message &m, bool local)
780
// figure out the encryption state
781
bool encChanged = false;
782
bool encEnabled = false;
783
if(d->lastWasEncrypted != m.wasEncrypted())
785
d->lastWasEncrypted = m.wasEncrypted();
786
encEnabled = d->lastWasEncrypted;
790
appendSysMsg(QString("<icon name=\"psi/cryptoYes\"> ") + tr("Encryption Enabled"));
792
d->tb_pgp->setOn(true);
795
appendSysMsg(QString("<icon name=\"psi/cryptoNo\"> ") + tr("Encryption Disabled"));
797
d->tb_pgp->setOn(false);
801
QTimer::singleShot(3000, this, SLOT(setWarnSendFalse()));
807
QDateTime time = m.timeStamp();
808
//timestr.sprintf("%02d:%02d:%02d", time.time().hour(), time.time().minute(), time.time().second());
809
timestr = time.time().toString(LocalDate);
811
int y = d->log->contentsHeight() - d->log->visibleHeight();
814
bool atBottom = (d->log->contentsY() < y - 32) ? false: true;
817
if(m.body().left(4) == "/me ")
822
txt = plain2rich(m.body().mid(4));
824
txt = plain2rich(m.body());
828
if(option.useEmoticons)
829
txt = emoticonify(txt);
831
who = expandEntities(who);
834
d->log->append(QString("<font color=\"%1\">").arg(color) + QString("[%1]").arg(timestr) + QString(" *%1 ").arg(who) + txt + "</font>");
838
d->log->append(QString("<font color=\"%1\">").arg(color) + QString("[%1] ").arg(timestr) + tr("%1 says:").arg(who) + "</font><br>" + txt);
840
d->log->append(QString("<font color=\"%1\">").arg(color) + QString("[%1] <").arg(timestr) + who + QString("></font> ") + txt);
842
if(!m.subject().isEmpty()) {
843
d->log->append(QString("<b>") + tr("Subject:") + "</b> " + QString("%1").arg(expandEntities(m.subject())));
845
if(!m.urlList().isEmpty()) {
846
UrlList urls = m.urlList();
847
d->log->append(QString("<i>") + tr("-- Attached URL(s) --") + "</i>");
848
for(QValueList<Url>::ConstIterator it = urls.begin(); it != urls.end(); ++it) {
850
d->log->append(QString("<b>") + tr("URL:") + "</b> " + QString("%1").arg( linkify(expandEntities(u.url())) ));
851
d->log->append(QString("<b>") + tr("Desc:") + "</b> " + QString("%1").arg(u.desc()));
855
if(local || atBottom)
858
// if we're not active, notify the user by changing the title
859
if(!isActiveWindow()) {
863
if(option.raiseChatWindow)
864
bringToFront(this, false);
867
// messagesRead(d->jid);
872
QTimer::singleShot(1000, this, SLOT(setKeepOpenFalse()));
876
void ChatDlg::deferredScroll()
878
QTimer::singleShot(250, this, SLOT(slotScroll()));
881
void ChatDlg::slotScroll()
883
d->log->scrollToBottom();
886
void ChatDlg::toggleSmallChat()
895
void ChatDlg::toggleEncryption()
897
d->tb_pgp->setOn(1-d->tb_pgp->isOn());
900
void ChatDlg::buildMenu()
902
d->pm_settings->clear();
903
d->pm_settings->insertItem("Toggle Compact/Full Size", this, SLOT(toggleSmallChat()));
904
d->pm_settings->insertItem(IconsetFactory::iconPtr("psi/clearChat")->pixmap(),"Clear Chat", this, SLOT(doClearButton()));
905
d->pm_settings->insertSeparator();
906
if (d->tb_pgp->isEnabled()) {
907
if (d->tb_pgp->isOn())
908
d->pm_settings->insertItem(IconsetFactory::icon("psi/cryptoYes").pixmap(),"Toggle Encryption", this, SLOT(toggleEncryption()));
910
d->pm_settings->insertItem(IconsetFactory::icon("psi/cryptoNo").pixmap(),"Toggle Encryption", this, SLOT(toggleEncryption()));
912
d->pm_settings->insertSeparator();
913
d->pm_settings->insertItem(IconsetFactory::iconPtr("psi/vCard")->pixmap(),"View User Profile", this, SLOT(doInfo()));
914
d->pm_settings->insertItem(IconsetFactory::iconPtr("psi/history")->pixmap(),"View History", this, SLOT(doHistory()));
916
#include "chatdlg.moc"