~ubuntu-branches/ubuntu/jaunty/psi/jaunty

« back to all changes in this revision

Viewing changes to src/psipopup.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-04-14 18:57:30 UTC
  • mfrom: (2.1.9 hardy)
  • Revision ID: james.westby@ubuntu.com-20080414185730-528re3zp0m2hdlhi
Tags: 0.11-8
* added CONFIG -= link_prl to .pro files and removed dependencies
  which are made unnecessary by this change
* Fix segfault when closing last chat tab with qt4.4
  (This is from upstream svn, rev. 1101) (Closes: Bug#476122)

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include "userlist.h"
26
26
#include "alerticon.h"
27
27
#include "psievent.h"
28
 
#include "im.h"
29
28
#include "psicon.h"
 
29
#include "textutil.h"
30
30
#include "psiaccount.h"
 
31
#include "psiiconset.h"
 
32
#include "iconlabel.h"
 
33
#include "psioptions.h"
31
34
 
32
35
#include <qapplication.h>
33
36
#include <qlayout.h>
34
 
 
35
 
//----------------------------------------------------------------------------
36
 
// PsiPopupList
37
 
//----------------------------------------------------------------------------
38
 
 
39
 
class PsiPopupList : public QObject, public QPtrList<PsiPopup>
40
 
{
41
 
        Q_OBJECT
42
 
private:
43
 
        int numPopups;
44
 
 
45
 
public:
46
 
        PsiPopupList()
47
 
        : QObject(qApp)
48
 
        {
49
 
                setAutoDelete(true);
50
 
        }
51
 
 
52
 
        PsiPopup *last()
53
 
        {
54
 
                if ( !count() )
55
 
                        return 0;
56
 
                return QPtrList<PsiPopup>::first();
57
 
        }
58
 
 
59
 
        void prepend(const PsiPopup *d)
60
 
        {
61
 
                if ( isEmpty() )
62
 
                        emit started();
63
 
 
64
 
                connect(d, SIGNAL(destroyed(QObject *)), SLOT(popupDestroyed(QObject *)));
65
 
                QPtrList<PsiPopup>::prepend(d);
66
 
        }
67
 
 
68
 
signals:
69
 
        void started();
70
 
        void finished();
71
 
 
72
 
private slots:
73
 
        void popupDestroyed(QObject *p)
74
 
        {
75
 
                setAutoDelete(false);
76
 
                remove((PsiPopup *)p);
77
 
                setAutoDelete(true);
78
 
 
79
 
                if ( isEmpty() )
80
 
                        emit finished();
81
 
        }
82
 
};
83
 
 
84
 
static PsiPopupList *psiPopupList = 0;
 
37
//Added by qt3to4:
 
38
#include <QLabel>
 
39
#include <QVBoxLayout>
 
40
#include <QHBoxLayout>
 
41
#include <Q3PtrList>
 
42
#include <QBoxLayout>
 
43
#include <QList>
 
44
#include <QTextDocument>
 
45
 
 
46
/**
 
47
 * Limits number of popups that could be displayed 
 
48
 * simultaneously on screen. Old popups momentally
 
49
 * disappear when new ones appear.
 
50
 */
 
51
static int MaxPopups = 5;
 
52
 
 
53
/**
 
54
 * Holds a list of Psi Popups.
 
55
 */
 
56
static QList<PsiPopup *> *psiPopupList = 0;
85
57
 
86
58
//----------------------------------------------------------------------------
87
59
// PsiPopup::Private
94
66
        Private(PsiPopup *p);
95
67
        ~Private();
96
68
 
97
 
        void init(const Icon *titleIcon, QString titleText, PsiAccount *_acc, PopupType type);
 
69
        void init(const PsiIcon *titleIcon, QString titleText, PsiAccount *_acc, PopupType type);
98
70
        QString clipText(QString);
99
 
        QBoxLayout *createContactInfo(const Icon *icon, QString text);
 
71
        QBoxLayout *createContactInfo(const PsiIcon *icon, QString text);
100
72
 
101
73
private slots:
102
74
        void popupDestroyed();
113
85
        Jid jid;
114
86
        Status status;
115
87
        PsiEvent *event;
116
 
        Icon *titleIcon;
 
88
        PsiIcon *titleIcon;
117
89
        bool display;
118
90
};
119
91
 
128
100
 
129
101
PsiPopup::Private::~Private()
130
102
{
 
103
        if ( psiPopupList )
 
104
                psiPopupList->removeAll(psiPopup);
 
105
 
131
106
        if ( popup )
132
107
                delete popup;
133
108
        if ( titleIcon )
135
110
        popup = 0;
136
111
}
137
112
 
138
 
void PsiPopup::Private::init(const Icon *_titleIcon, QString titleText, PsiAccount *acc, PopupType type)
 
113
void PsiPopup::Private::init(const PsiIcon *_titleIcon, QString titleText, PsiAccount *acc, PopupType type)
139
114
{
140
115
        psi = acc->psi();
141
116
        account = acc;
142
117
        display = true;
143
118
 
 
119
        if ( !option.ppIsOn )
 
120
                return;
 
121
 
144
122
        if ( !psiPopupList )
145
 
                psiPopupList = new PsiPopupList();
146
 
 
147
 
        FancyPopup *last = 0;
148
 
        if ( psiPopupList->last() )
149
 
                last = psiPopupList->last()->popup();
 
123
                psiPopupList = new QList<PsiPopup *>();
 
124
 
 
125
        if ( psiPopupList->count() >= MaxPopups && MaxPopups > 0 )
 
126
                delete psiPopupList->first();
 
127
 
 
128
        FancyPopup *lastPopup = 0;
 
129
        if ( psiPopupList->count() && psiPopupList->last() )
 
130
                lastPopup = psiPopupList->last()->popup();
150
131
 
151
132
        if ( type != AlertNone )
152
133
                titleIcon = new AlertIcon(_titleIcon);
153
134
        else
154
 
                titleIcon = new Icon(*_titleIcon);
 
135
                titleIcon = new PsiIcon(*_titleIcon);
155
136
 
156
137
        FancyPopup::setHideTimeout( option.ppHideTime );
157
138
        FancyPopup::setBorderColor( option.ppBorderColor );
158
139
 
159
 
        popup = new FancyPopup(titleText, titleIcon, last, false);
 
140
        popup = new FancyPopup(titleText, titleIcon, lastPopup, false);
160
141
        connect(popup, SIGNAL(clicked(int)), SLOT(popupClicked(int)));
161
142
        connect(popup, SIGNAL(destroyed()), SLOT(popupDestroyed()));
162
143
 
174
155
 
175
156
void PsiPopup::Private::popupClicked(int button)
176
157
{
177
 
        if ( button == (int)LeftButton ) {
 
158
        if ( button == (int)Qt::LeftButton ) {
178
159
                if ( event )
179
160
                        psi->processEvent( event );
180
161
                else if ( account ) {
184
165
                        account->actionDefault( j );
185
166
                }
186
167
        }
187
 
 
188
 
        if ( popup )
189
 
                popup->hide();
190
168
}
191
169
 
192
170
void PsiPopup::Private::eventDestroyed()
193
171
{
194
 
        if ( (popupType == AlertMessage || popupType == AlertHeadline) && !option.popupMsgs )
195
 
                delete popup;
196
 
        if ( popupType == AlertChat && !option.popupChats /*&& option.alertOpenChats*/ )
197
 
                delete popup;
198
 
        if ( popupType == AlertHeadline && !option.popupHeadlines)
199
 
                delete popup;
200
 
        if ( popupType == AlertFile && !option.popupFiles)
201
 
                delete popup;
202
 
 
 
172
        popup->deleteLater();
203
173
        event = 0;
204
174
}
205
175
 
223
193
        return text;
224
194
}
225
195
 
226
 
QBoxLayout *PsiPopup::Private::createContactInfo(const Icon *icon, QString text)
 
196
QBoxLayout *PsiPopup::Private::createContactInfo(const PsiIcon *icon, QString text)
227
197
{
228
 
        QHBoxLayout *dataBox = new QHBoxLayout(0);
 
198
        QHBoxLayout *dataBox = new QHBoxLayout();
229
199
 
230
200
        if ( icon ) {
231
201
                IconLabel *iconLabel = new IconLabel(popup);
232
202
                iconLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
233
 
                iconLabel->setIcon(icon);
 
203
                iconLabel->setPsiIcon(icon);
234
204
                dataBox->addWidget(iconLabel);
235
205
 
236
206
                dataBox->addSpacing(5);
237
207
        }
238
208
 
239
 
        IconLabel *textLabel = new IconLabel(popup);
 
209
        QLabel *textLabel = new QLabel(popup);
240
210
        QFont font;
241
211
        font.fromString( option.font[fPopup] );
242
212
        textLabel->setFont(font);
243
213
 
 
214
        textLabel->setWordWrap(false);
244
215
        textLabel->setText(QString("<qt>%1</qt>").arg(clipText(text)));
245
216
        textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
246
217
        dataBox->addWidget(textLabel);
252
223
// PsiPopup
253
224
//----------------------------------------------------------------------------
254
225
 
255
 
PsiPopup::PsiPopup(const Icon *titleIcon, QString titleText, PsiAccount *acc)
 
226
PsiPopup::PsiPopup(const PsiIcon *titleIcon, QString titleText, PsiAccount *acc)
256
227
{
257
228
        d = new Private(this);
258
229
        d->init(titleIcon, titleText, acc, AlertNone);
268
239
        d = new Private(this);
269
240
 
270
241
        d->popupType = type;
271
 
        Icon *icon = 0;
 
242
        PsiIcon *icon = 0;
272
243
        QString text = "Psi: ";
273
244
        bool doAlertIcon = false;
274
245
 
275
246
        switch(type) {
276
247
        case AlertOnline:
277
248
                text += PsiPopup::tr("Contact online");
278
 
                icon = (Icon *)IconsetFactory::iconPtr("status/online");
 
249
                icon = (PsiIcon *)IconsetFactory::iconPtr("status/online");
279
250
                break;
280
251
        case AlertOffline:
281
252
                text += PsiPopup::tr("Contact offline");
282
 
                icon = (Icon *)IconsetFactory::iconPtr("status/offline");
 
253
                icon = (PsiIcon *)IconsetFactory::iconPtr("status/offline");
283
254
                break;
284
255
        case AlertStatusChange:
285
256
                text += PsiPopup::tr("Status change");
286
 
                icon = (Icon *)IconsetFactory::iconPtr("status/online");
 
257
                icon = (PsiIcon *)IconsetFactory::iconPtr("status/online");
287
258
                break;
288
259
        case AlertMessage:
289
260
                text += PsiPopup::tr("Incoming message");
290
 
                icon = (Icon *)IconsetFactory::iconPtr("psi/message");
 
261
                icon = (PsiIcon *)IconsetFactory::iconPtr("psi/message");
291
262
                doAlertIcon = true;
292
263
                break;
293
264
        case AlertChat:
294
265
                text += PsiPopup::tr("Incoming chat message");
295
 
                icon= (Icon *)IconsetFactory::iconPtr("psi/chat");
 
266
                icon= (PsiIcon *)IconsetFactory::iconPtr("psi/chat");
296
267
                doAlertIcon = true;
297
268
                break;
298
269
        case AlertHeadline:
299
270
                text += PsiPopup::tr("Headline");
300
 
                icon= (Icon *)IconsetFactory::iconPtr("psi/headline");
 
271
                icon= (PsiIcon *)IconsetFactory::iconPtr("psi/headline");
301
272
                doAlertIcon = true;
302
273
                break;
303
274
        case AlertFile:
304
275
                text += PsiPopup::tr("Incoming file");
305
 
                icon= (Icon *)IconsetFactory::iconPtr("psi/file");
 
276
                icon= (PsiIcon *)IconsetFactory::iconPtr("psi/file");
306
277
                doAlertIcon = true;
307
278
                break;
308
279
        default:
312
283
        d->init(icon, text, acc, doAlertIcon ? type : AlertNone);
313
284
}
314
285
 
315
 
void PsiPopup::setData(const Icon *icon, QString text)
 
286
void PsiPopup::setData(const PsiIcon *icon, QString text)
316
287
{
317
288
        if ( !d->popup ) {
318
289
                deleteLater();
343
314
        if ( event )
344
315
                connect(event, SIGNAL(destroyed()), d, SLOT(eventDestroyed()));
345
316
 
346
 
        Icon *icon = is->statusPtr(j, r.status());
 
317
        PsiIcon *icon = PsiIconset::instance()->statusPtr(j, r.status());
347
318
        QString text;
348
319
 
349
320
        QString jid = j.full();
359
330
 
360
331
        QString name;
361
332
        if ( u && !u->name().isEmpty() ) {
 
333
                name = u->name();
 
334
        }
 
335
        else if (event && event->type() == PsiEvent::Auth) {
 
336
                name = ((AuthEvent*) event)->nick();
 
337
        }
 
338
        else if (event && event->type() == PsiEvent::Message) {
 
339
                name = ((MessageEvent*) event)->nick();
 
340
        }
 
341
                
 
342
        if (!name.isEmpty()) {
362
343
                if ( !option.ppJidClip )
363
 
                        name = "<nobr>" + u->name() + "</nobr>";
 
344
                        name = "<nobr>" + Qt::escape(name) + "</nobr>";
364
345
                else
365
 
                        name = "<nobr>" + u->name() + " &lt;" + jid + "&gt;" + "</nobr>";
 
346
                        name = "<nobr>" + Qt::escape(name) + " &lt;" + Qt::escape(jid) + "&gt;" + "</nobr>";
366
347
        }
367
 
        else
368
 
                name = "<nobr>&lt;" + jid + "&gt;</nobr>";
 
348
        else 
 
349
                name = "<nobr>&lt;" + Qt::escape(jid) + "&gt;</nobr>";
369
350
 
370
 
        QString statusString = plain2rich(status);
 
351
        QString statusString = TextUtil::plain2rich(status);
371
352
        if ( option.useEmoticons )
372
 
                statusString = emoticonify(statusString);
 
353
                statusString = TextUtil::emoticonify(statusString);
 
354
        if( PsiOptions::instance()->getOption("options.ui.chat.legacy-formatting").toBool() )
 
355
                statusString = TextUtil::legacyFormat(statusString);
373
356
 
374
357
        if ( !statusString.isEmpty() )
375
358
                statusString = "<br>" + statusString;
377
360
        QString contactText = "<font size=\"+1\">" + name + "</font>" + statusString;
378
361
 
379
362
        // hack for duplicate "Contact Online"/"Status Change" popups
380
 
        PsiPopup *pp = psiPopupList->first();
381
 
        while ( pp ) {
 
363
        foreach (PsiPopup *pp, *psiPopupList) {
382
364
                if ( d->jid.full() == pp->d->jid.full() && d->status.show() == pp->d->status.show() && d->status.status() == d->status.status() ) {
383
365
                        if ( d->popupType == AlertStatusChange && pp->d->popupType == AlertOnline ) {
384
366
                                d->display = false;
386
368
                                break;
387
369
                        }
388
370
                }
389
 
 
390
 
                pp = psiPopupList->next();
391
371
        }
392
372
 
393
373
        // show popup
403
383
                QString message;
404
384
                if ( !jmessage->subject().isEmpty() )
405
385
                        message += "<font color=\"red\"><b>" + tr("Subject:") + " " + jmessage->subject() + "</b></font><br>";
406
 
                message += plain2rich( jmessage->body() );
 
386
                message += TextUtil::plain2rich( jmessage->body() );
407
387
 
408
388
                QLabel *messageLabel = new QLabel(d->popup);
409
389
                QFont font = messageLabel->font();
410
390
                font.setPointSize(option.smallFontSize);
411
391
                messageLabel->setFont(font);
412
392
 
413
 
                messageLabel->setTextFormat(RichText);
414
 
                messageLabel->setText( d->clipText(linkify( message )) );
 
393
                messageLabel->setWordWrap(true);
 
394
                messageLabel->setTextFormat(Qt::RichText);
 
395
                messageLabel->setText( d->clipText(TextUtil::linkify( message )) );
415
396
                messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
416
397
                vbox->addWidget(messageLabel);
417
398
 
428
409
 
429
410
void PsiPopup::show()
430
411
{
431
 
        if ( !d->popup || !option.ppIsOn ) {
 
412
        if ( !d->popup ) {
432
413
                deleteLater();
433
414
                return;
434
415
        }
435
416
 
436
417
        if ( !d->id.isEmpty() /*&& option.ppNoDupes*/ ) {
437
 
                PsiPopup *pp = psiPopupList->first();
438
 
                while ( pp ) {
 
418
                foreach (PsiPopup *pp, *psiPopupList) {
439
419
                        if ( d->id == pp->id() && pp->popup() ) {
440
420
                                pp->popup()->restartHideTimer();
441
421
 
442
422
                                d->display = false;
443
423
                                break;
444
424
                        }
445
 
 
446
 
                        pp = psiPopupList->next();
447
425
                }
448
426
        }
449
427
 
450
428
        if ( d->display ) {
451
 
                psiPopupList->prepend( this );
 
429
                psiPopupList->append( this );
452
430
                d->popup->show();
453
431
        }
454
432
        else {