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

« back to all changes in this revision

Viewing changes to src/mainwin_p.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2005-01-10 17:41:43 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050110174143-ltocv5zapl6blf5d
Tags: 0.9.3-1
* New upstream release
* Cleaned up debian/rules (some things are done by upstream Makefiles now)
* Fixed some lintian warnings:
  - removed executable bit from some .png files
  - moved psi.desktop to /usr/share/applications
* Updated menu files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * mainwin_p.cpp - classes used privately by the main window.
 
3
 * Copyright (C) 2001-2003  Justin Karneges, Michail Pishchagin
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 *
 
19
 */
 
20
 
 
21
#include "common.h"
 
22
#include "mainwin_p.h"
 
23
 
 
24
#include <qapplication.h>
 
25
#include <qstyle.h>
 
26
#include <qtoolbar.h>
 
27
#include <qtimer.h>
 
28
#include <qsignalmapper.h>
 
29
#include <qobjectlist.h>
 
30
#include <qpixmapcache.h>
 
31
#include "psiaccount.h"
 
32
#include "iconwidget.h"
 
33
#include "alerticon.h"
 
34
 
 
35
//----------------------------------------------------------------------------
 
36
// PopupActionButton
 
37
//----------------------------------------------------------------------------
 
38
 
 
39
class PopupActionButton : public QPushButton
 
40
{
 
41
        Q_OBJECT
 
42
public:
 
43
        PopupActionButton(QWidget *parent = 0, const char *name = 0);
 
44
        ~PopupActionButton();
 
45
 
 
46
        void setIcon(Icon *, bool showText);
 
47
 
 
48
private slots:
 
49
        void pixmapUpdated(const QPixmap &);
 
50
 
 
51
private:
 
52
        void drawButtonLabel(QPainter *p);
 
53
        bool hasToolTip;
 
54
        Icon *icon;
 
55
        bool showText;
 
56
};
 
57
 
 
58
PopupActionButton::PopupActionButton(QWidget *parent, const char *name)
 
59
: QPushButton(parent, name)
 
60
{
 
61
        setWFlags(getWFlags() | WRepaintNoErase);
 
62
 
 
63
        hasToolTip = false;
 
64
        icon = 0;
 
65
}
 
66
 
 
67
PopupActionButton::~PopupActionButton()
 
68
{
 
69
        if (icon)
 
70
                icon->stop();
 
71
}
 
72
 
 
73
void PopupActionButton::setIcon(Icon *i, bool st)
 
74
{
 
75
        if ( icon ) {
 
76
                icon->stop();
 
77
                disconnect (icon, 0, this, 0);
 
78
                icon = 0;
 
79
        }
 
80
 
 
81
        icon = i;
 
82
        showText = st;
 
83
 
 
84
        if ( icon ) {
 
85
                pixmapUpdated(icon->pixmap());
 
86
 
 
87
                connect(icon, SIGNAL(pixmapChanged(const QPixmap &)), SLOT(pixmapUpdated(const QPixmap &)));
 
88
                icon->activated();
 
89
        }
 
90
}
 
91
 
 
92
void PopupActionButton::pixmapUpdated(const QPixmap &pix)
 
93
{
 
94
        if ( showText )
 
95
                setIconSet(pix);
 
96
        else
 
97
                setPixmap(pix);
 
98
}
 
99
 
 
100
void PopupActionButton::drawButtonLabel(QPainter *p)
 
101
{
 
102
        // code by Justin Karneges :-)
 
103
        // crazy code ahead!  watch out for potholes and deer.
 
104
 
 
105
        // this gets us the width of the "text area" on the button.
 
106
        // adapted from qt/src/styles/qcommonstyle.cpp and qt/src/widgets/qpushbutton.cpp
 
107
        QRect r = style().subRect(QStyle::SR_PushButtonContents, this);
 
108
        if(isMenuButton())
 
109
                r.setWidth(r.width() - style().pixelMetric(QStyle::PM_MenuButtonIndicator, this));
 
110
        if(iconSet() && !iconSet()->isNull())
 
111
                r.setWidth(r.width() - (iconSet()->pixmap(QIconSet::Small, QIconSet::Normal, QIconSet::Off).width() + 4));
 
112
 
 
113
        // font metrics
 
114
        QFontMetrics fm(font());
 
115
 
 
116
        // w1 = width of button text, w2 = width of text area
 
117
        int w1 = fm.width(text());
 
118
        int w2 = r.width();
 
119
 
 
120
        // backup original text
 
121
        QString oldtext = text();
 
122
 
 
123
        // button text larger than what will fit?
 
124
        if(w1 > w2) {
 
125
                if( !hasToolTip ) {
 
126
                        QToolTip::add(this, text());
 
127
                        hasToolTip = TRUE;
 
128
                }
 
129
 
 
130
                // make a string that fits
 
131
                bool found = FALSE;
 
132
                QString newtext;
 
133
                int n;
 
134
                for(n = oldtext.length(); n > 0; --n) {
 
135
                        if(fm.width(oldtext, n) < w2) {
 
136
                                found = TRUE;
 
137
                                break;
 
138
                        }
 
139
                }
 
140
                if(found)
 
141
                        newtext = oldtext.mid(0, n);
 
142
                else
 
143
                        newtext = "";
 
144
 
 
145
                // set the new text that fits.  updates must be off, or we recurse.
 
146
                setUpdatesEnabled(FALSE);
 
147
                QButton::setText(newtext);
 
148
                setUpdatesEnabled(TRUE);
 
149
        }
 
150
        else {
 
151
                if( hasToolTip ) {
 
152
                        QToolTip::remove(this);
 
153
                        hasToolTip = FALSE;
 
154
                }
 
155
        }
 
156
 
 
157
        // draw!
 
158
        QPushButton::drawButtonLabel(p);
 
159
 
 
160
        // restore original button text now that we are done drawing.
 
161
        setUpdatesEnabled(FALSE);
 
162
        QButton::setText(oldtext);
 
163
        setUpdatesEnabled(TRUE);
 
164
}
 
165
 
 
166
//----------------------------------------------------------------------------
 
167
// PopupAction -- the IconButton with popup or QPopupMenu
 
168
//----------------------------------------------------------------------------
 
169
 
 
170
class PopupAction::Private : public QObject
 
171
{
 
172
public:
 
173
        QSizePolicy size;
 
174
        QPtrList<PopupActionButton> buttons;
 
175
        Icon *icon;
 
176
        bool showText;
 
177
 
 
178
        Private (QObject *parent)
 
179
        : QObject (parent)
 
180
        {
 
181
                icon = 0;
 
182
                showText = true;
 
183
        }
 
184
 
 
185
        ~Private()
 
186
        {
 
187
                buttons.clear();
 
188
                if (icon)
 
189
                        delete icon;
 
190
        }
 
191
};
 
192
 
 
193
PopupAction::PopupAction (const QString &label, QPopupMenu *_menu, QObject *parent, const char *name)
 
194
: IconAction (label, label, 0, parent, name)
 
195
{
 
196
        d = new Private (this);
 
197
        setPopup( _menu );
 
198
}
 
199
 
 
200
void PopupAction::setSizePolicy (const QSizePolicy &p)
 
201
{
 
202
        d->size = p;
 
203
}
 
204
 
 
205
void PopupAction::setAlert (const Icon *icon)
 
206
{
 
207
        setIcon(icon, d->showText, true);
 
208
}
 
209
 
 
210
void PopupAction::setIcon (const Icon *icon, bool showText, bool alert)
 
211
{
 
212
        Icon *oldIcon = 0;
 
213
        if ( d->icon ) {
 
214
                oldIcon = d->icon;
 
215
                d->icon = 0;
 
216
        }
 
217
 
 
218
        d->showText = showText;
 
219
 
 
220
        if ( icon ) {
 
221
                if ( !alert )
 
222
                        d->icon = new Icon(*icon);
 
223
                else
 
224
                        d->icon = new AlertIcon(icon);
 
225
 
 
226
                IconAction::setIconSet(*icon);
 
227
        }
 
228
        else {
 
229
                d->icon = 0;
 
230
                IconAction::setIconSet(QIconSet());
 
231
        }
 
232
 
 
233
        for ( QPtrListIterator<PopupActionButton> it(d->buttons); it.current(); ++it ) {
 
234
                PopupActionButton *btn = it.current();
 
235
                btn->setIcon (d->icon, showText);
 
236
        }
 
237
 
 
238
        if ( oldIcon ) {
 
239
                delete oldIcon;
 
240
        }
 
241
}
 
242
 
 
243
void PopupAction::setText (const QString &text)
 
244
{
 
245
        IconAction::setText (text);
 
246
        for ( QPtrListIterator<PopupActionButton> it(d->buttons); it.current(); ++it ) {
 
247
                PopupActionButton *btn = it.current();
 
248
                btn->setText (text);
 
249
        }
 
250
}
 
251
 
 
252
bool PopupAction::addTo (QWidget *w)
 
253
{
 
254
        if ( w->inherits("QPopupMenu") ) {
 
255
                QPopupMenu *m = (QPopupMenu*)w;
 
256
#ifndef Q_WS_MAC
 
257
                m->insertItem (iconSet(), menuText(), popup());
 
258
#else
 
259
                m->insertItem (QIconSet(), menuText(), popup());
 
260
#endif
 
261
        }
 
262
        else if ( w->inherits("QToolBar") ) {
 
263
                QCString bname = name() + QCString("_action_button");
 
264
                PopupActionButton *btn = new PopupActionButton ( (QToolBar*)w, bname );
 
265
                d->buttons.append ( btn );
 
266
                btn->setPopup ( popup() );
 
267
                btn->setText ( text() );
 
268
                btn->setIcon ( d->icon, d->showText );
 
269
                btn->setSizePolicy ( d->size );
 
270
                btn->setEnabled ( isEnabled() );
 
271
 
 
272
                connect( btn, SIGNAL( destroyed() ), SLOT( objectDestroyed() ) );
 
273
        }
 
274
        else
 
275
                return false;
 
276
 
 
277
        return true;
 
278
}
 
279
 
 
280
void PopupAction::objectDestroyed ()
 
281
{
 
282
        const QObject *obj = sender();
 
283
        d->buttons.removeRef( (PopupActionButton *) obj );
 
284
}
 
285
 
 
286
void PopupAction::setEnabled (bool e)
 
287
{
 
288
        IconAction::setEnabled (e);
 
289
        for ( QPtrListIterator<PopupActionButton> it(d->buttons); it.current(); ++it ) {
 
290
                PopupActionButton *btn = it.current();
 
291
                btn->setEnabled (e);
 
292
        }
 
293
}
 
294
 
 
295
IconAction *PopupAction::copy() const
 
296
{
 
297
        PopupAction *act = new PopupAction(text(), popup(), 0, name());
 
298
 
 
299
        *act = *this;
 
300
 
 
301
        return act;
 
302
}
 
303
 
 
304
PopupAction &PopupAction::operator=( const PopupAction &from )
 
305
{
 
306
        *( (IconAction *)this ) = from;
 
307
 
 
308
        d->size = from.d->size;
 
309
        setIcon( from.d->icon );
 
310
        d->showText = from.d->showText;
 
311
 
 
312
        return *this;
 
313
}
 
314
 
 
315
//----------------------------------------------------------------------------
 
316
// MLabel -- a clickable label
 
317
//----------------------------------------------------------------------------
 
318
 
 
319
MLabel::MLabel(QWidget *parent, const char *name)
 
320
:QLabel(parent, name)
 
321
{
 
322
        setMinimumWidth(48);
 
323
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
 
324
        setFrameStyle(QFrame::Panel | QFrame::Sunken);
 
325
}
 
326
 
 
327
void MLabel::mouseReleaseEvent(QMouseEvent *e)
 
328
{
 
329
        emit clicked(e->button());
 
330
        e->ignore();
 
331
}
 
332
 
 
333
void MLabel::mouseDoubleClickEvent(QMouseEvent *e)
 
334
{
 
335
        if(e->button() == LeftButton)
 
336
                emit doubleClicked();
 
337
 
 
338
        e->ignore();
 
339
}
 
340
 
 
341
//----------------------------------------------------------------------------
 
342
// MTray
 
343
//----------------------------------------------------------------------------
 
344
 
 
345
class MTray::Private
 
346
{
 
347
public:
 
348
        Private() {
 
349
                icon    = 0;
 
350
                ti      = 0;
 
351
        }
 
352
 
 
353
        ~Private() {
 
354
                if ( icon )
 
355
                        delete icon;
 
356
 
 
357
                delete ti;
 
358
        }
 
359
 
 
360
        TrayIcon *ti;
 
361
        Icon *icon;
 
362
 
 
363
        QPixmap makeIcon();
 
364
        QRgb pixelBlend(QRgb p1, QRgb p2);
 
365
};
 
366
 
 
367
MTray::MTray(const QString &tip, QPopupMenu *popup, QObject *parent)
 
368
:QObject(parent)
 
369
{
 
370
        d = new Private;
 
371
 
 
372
        d->ti = new TrayIcon(d->makeIcon(), tip, popup);
 
373
        d->ti->setWMDock(option.isWMDock);
 
374
        connect(d->ti, SIGNAL(clicked(const QPoint &, int)), SIGNAL(clicked(const QPoint &, int)));
 
375
        connect(d->ti, SIGNAL(doubleClicked(const QPoint &)), SIGNAL(doubleClicked(const QPoint &)));
 
376
        connect(d->ti, SIGNAL(closed()), SIGNAL(closed()));
 
377
        connect(qApp, SIGNAL(newTrayOwner()), d->ti, SLOT(newTrayOwner()));
 
378
        connect(qApp, SIGNAL(trayOwnerDied()), d->ti, SLOT(hide()));
 
379
        d->ti->show();
 
380
}
 
381
 
 
382
MTray::~MTray()
 
383
{
 
384
        delete d;
 
385
}
 
386
 
 
387
void MTray::setToolTip(const QString &str)
 
388
{
 
389
        d->ti->setToolTip(str);
 
390
}
 
391
 
 
392
void MTray::setIcon(const Icon *icon, bool alert)
 
393
{
 
394
        if ( d->icon ) {
 
395
                disconnect(d->icon, 0, this, 0 );
 
396
                d->icon->stop();
 
397
 
 
398
                delete d->icon;
 
399
                d->icon = 0;
 
400
        }
 
401
 
 
402
        if ( icon ) {
 
403
                if ( !alert )
 
404
                        d->icon = new Icon(*icon);
 
405
                else
 
406
                        d->icon = new AlertIcon(icon);
 
407
 
 
408
                connect(d->icon, SIGNAL(pixmapChanged(const QPixmap &)), SLOT(animate()));
 
409
                d->icon->activated();
 
410
        }
 
411
        else
 
412
                d->icon = new Icon();
 
413
 
 
414
        animate();
 
415
}
 
416
 
 
417
void MTray::setAlert(const Icon *icon)
 
418
{
 
419
        setIcon(icon, true);
 
420
}
 
421
 
 
422
bool MTray::isAnimating() const
 
423
{
 
424
        return d->icon->isAnimated();
 
425
}
 
426
 
 
427
bool MTray::isWMDock()
 
428
{
 
429
        return d->ti->isWMDock();
 
430
}
 
431
 
 
432
void MTray::show()
 
433
{
 
434
        d->ti->show();
 
435
}
 
436
 
 
437
void MTray::hide()
 
438
{
 
439
        d->ti->hide();
 
440
}
 
441
 
 
442
 
 
443
// a function to blend 2 pixels taking their alpha channels
 
444
// into consideration
 
445
// p1 is in the 1st layer, p2 is in the 2nd layer (over p1)
 
446
QRgb MTray::Private::pixelBlend(QRgb p1, QRgb p2)
 
447
{
 
448
        int a2 = qAlpha(p2);
 
449
        if (a2 == 255) return p2; // don't calculate anything if p2 is completely opaque
 
450
        int a1 = qAlpha(p1);
 
451
        double prop1 = double(a1*(255-a2))/double(255*255);
 
452
        double prop2 = double(a2)/255.0;
 
453
        int r = int( qRed(p1)*prop1 + qRed(p2)*prop2 );
 
454
        int g = int( qGreen(p1)*prop1 + qGreen(p2)*prop2 );
 
455
        int b = int( qBlue(p1)*prop1 + qBlue(p2)*prop2 );
 
456
        return qRgba(r, g, b, (a1>a2) ? a1:a2);
 
457
}
 
458
 
 
459
 
 
460
QPixmap MTray::Private::makeIcon()
 
461
{
 
462
        if ( !icon )
 
463
                return QPixmap();
 
464
 
 
465
#ifdef Q_WS_X11
 
466
        // on X11, the KDE dock is 22x22.  let's make our icon "seem" bigger.
 
467
        QImage real(22,22,32);
 
468
        QImage in = icon->image();
 
469
        in.detach();
 
470
        real.setAlphaBuffer(true);
 
471
 
 
472
        // make sure it is no bigger than 16x16
 
473
        if(in.width() > 16 || in.height() > 16)
 
474
                in = in.smoothScale(16,16);
 
475
 
 
476
        int xo = (real.width() - in.width()) / 2;
 
477
        int yo = (real.height() - in.height()) / 2;
 
478
 
 
479
        int n, n2;
 
480
 
 
481
        // clear the output and make it transparent
 
482
        // deprecates real.fill(0)
 
483
        for(n2 = 0; n2 < real.height(); ++n2)
 
484
                for(n = 0; n < real.width(); ++n)
 
485
                        real.setPixel(n, n2, qRgba(0,0,0,0));
 
486
 
 
487
        // draw a dropshadow
 
488
        for(n2 = 0; n2 < in.height(); ++n2) {
 
489
                for(n = 0; n < in.width(); ++n) {
 
490
                        if(int a = qAlpha(in.pixel(n,n2))) {
 
491
                                int x = n + xo + 2;
 
492
                                int y = n2 + yo + 2;
 
493
                                real.setPixel(x, y, qRgba(0x80,0x80,0x80,a));
 
494
                        }
 
495
                }
 
496
        }
 
497
 
 
498
        // draw the image
 
499
        for(n2 = 0; n2 < in.height(); ++n2) {
 
500
                for(n = 0; n < in.width(); ++n) {
 
501
                        if(qAlpha(in.pixel(n,n2))) {
 
502
                                QRgb pold = real.pixel(n + xo , n2 + yo);
 
503
                                QRgb pnew = in.pixel(n , n2);
 
504
                                real.setPixel(n + xo, n2 + yo, pixelBlend(pold, pnew));
 
505
                        }
 
506
                }
 
507
        }
 
508
 
 
509
        QPixmap pixmap;
 
510
        pixmap.convertFromImage(real);
 
511
        return pixmap;
 
512
#else
 
513
        return icon->pixmap();
 
514
#endif
 
515
}
 
516
 
 
517
void MTray::animate()
 
518
{
 
519
#ifdef Q_WS_X11
 
520
        if ( !d->icon )
 
521
                return;
 
522
 
 
523
        QString cachedName = "PsiTray/" + option.defaultRosterIconset + "/" + d->icon->name() + "/" + QString::number( d->icon->framenumber() );
 
524
 
 
525
        QPixmap p;
 
526
        if ( !QPixmapCache::find(cachedName, p) ) {
 
527
                p = d->makeIcon();
 
528
                QPixmapCache::insert( cachedName, p );
 
529
        }
 
530
 
 
531
        d->ti->setIcon(p);
 
532
#else
 
533
        d->ti->setIcon( d->makeIcon() );
 
534
#endif
 
535
}
 
536
 
 
537
//----------------------------------------------------------------------------
 
538
// MAction
 
539
//----------------------------------------------------------------------------
 
540
 
 
541
class MAction::Private : public QObject
 
542
{
 
543
public:
 
544
        int id;
 
545
        PsiCon *psi;
 
546
        QSignalMapper *sm;
 
547
 
 
548
        Private (int _id, PsiCon *_psi, QObject *parent)
 
549
        : QObject (parent)
 
550
        {
 
551
                id = _id;
 
552
                psi = _psi;
 
553
                sm = new QSignalMapper(this, "MAction::Private::SignalMapper");
 
554
        }
 
555
 
 
556
        QPopupMenu *subMenu(QWidget *p)
 
557
        {
 
558
                QPopupMenu *pm = new QPopupMenu (p);
 
559
                uint i = 0;
 
560
                for ( PsiAccountListIt it(psi->accountList(TRUE)); it.current(); ++it, i++ )
 
561
                {
 
562
                        PsiAccount *acc = it.current();
 
563
                        pm->insertItem( acc->name(), parent(), SLOT(itemActivated(int)), 0, id*1000 + i );
 
564
                        pm->setItemParameter ( id*1000 + i, i );
 
565
                }
 
566
                return pm;
 
567
        }
 
568
};
 
569
 
 
570
MAction::MAction(Icon i, const QString &s, int id, PsiCon *psi, QObject *parent)
 
571
: IconAction(s, s, 0, parent)
 
572
{
 
573
        init (i, id, psi);
 
574
}
 
575
 
 
576
MAction::MAction(const QString &s, int id, PsiCon *psi, QObject *parent)
 
577
: IconAction(s, s, 0, parent)
 
578
{
 
579
        init (Icon(), id, psi);
 
580
}
 
581
 
 
582
void MAction::init(Icon i, int id, PsiCon *psi)
 
583
{
 
584
        d = new Private(id, psi, this);
 
585
        setIcon (&i);
 
586
        connect(psi, SIGNAL(accountCountChanged()), SLOT(numAccountsChanged()));
 
587
        setEnabled ( !d->psi->accountList(TRUE).isEmpty() );
 
588
        connect (d->sm, SIGNAL(mapped(int)), SLOT(itemActivated(int)));
 
589
}
 
590
 
 
591
bool MAction::addTo(QWidget *w)
 
592
{
 
593
        if ( w->inherits("QPopupMenu") )
 
594
        {
 
595
                QPopupMenu *menu = (QPopupMenu*)w;
 
596
        QIconSet iconset;
 
597
#ifndef Q_WS_MAC
 
598
                iconset = iconSet();
 
599
#endif
 
600
                if ( d->psi->accountList(TRUE).count() < 2 ) {
 
601
                        menu->insertItem ( iconset, menuText(), this, SLOT(itemActivated(int)), 0, d->id*1000 + 0 );
 
602
                        menu->setItemEnabled (d->id*1000 + 0, isEnabled());
 
603
                        menu->setItemParameter ( d->id*1000 + 0, 0 );
 
604
                }
 
605
                else
 
606
                        menu->insertItem(iconset, menuText(), d->subMenu(w));
 
607
        }
 
608
        else
 
609
                return IconAction::addTo(w);
 
610
 
 
611
        return true;
 
612
}
 
613
 
 
614
void MAction::addingToolButton(IconToolButton *btn)
 
615
{
 
616
        connect (btn, SIGNAL(clicked()), d->sm, SLOT(map()));
 
617
        d->sm->setMapping (btn, 0);
 
618
 
 
619
        if ( d->psi->accountList(TRUE).count() >= 2 )
 
620
                btn->setPopup ( d->subMenu(btn) );
 
621
        else
 
622
                btn->setPopup (0);
 
623
}
 
624
 
 
625
void MAction::itemActivated(int n)
 
626
{
 
627
        PsiAccountList list = (PsiAccountList)d->psi->accountList(TRUE);
 
628
 
 
629
        if (n >= (int)list.count()) // just in case
 
630
                return;
 
631
 
 
632
        emit activated((PsiAccount *)list.at(n), d->id);
 
633
}
 
634
 
 
635
void MAction::numAccountsChanged()
 
636
{
 
637
        setEnabled ( !d->psi->accountList(TRUE).isEmpty() );
 
638
 
 
639
        QPtrList<IconToolButton> btns = buttonList();
 
640
        for ( QPtrListIterator<IconToolButton> it(btns); it.current(); ++it ) {
 
641
                QToolButton *btn = it.current();
 
642
 
 
643
                if ( btn->popup() )
 
644
                        delete btn->popup();
 
645
                btn->setPopup (0);
 
646
 
 
647
                if ( d->psi->accountList(TRUE).count() >= 2 )
 
648
                        btn->setPopup ( d->subMenu(btn) );
 
649
        }
 
650
}
 
651
 
 
652
IconAction *MAction::copy() const
 
653
{
 
654
        MAction *act = new MAction(text(), d->id, d->psi, 0);
 
655
 
 
656
        *act = *this;
 
657
 
 
658
        return act;
 
659
}
 
660
 
 
661
MAction &MAction::operator=( const MAction &from )
 
662
{
 
663
        *( (IconAction *)this ) = from;
 
664
 
 
665
        return *this;
 
666
}
 
667
 
 
668
//----------------------------------------------------------------------------
 
669
// SpacerAction
 
670
//----------------------------------------------------------------------------
 
671
 
 
672
class SpacerAction::Private
 
673
{
 
674
public:
 
675
        Private() { }
 
676
 
 
677
        class StretchWidget : public QWidget
 
678
        {
 
679
        public:
 
680
                StretchWidget(QWidget *parent)
 
681
                : QWidget(parent)
 
682
                {
 
683
                        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
 
684
                }
 
685
        };
 
686
};
 
687
 
 
688
SpacerAction::SpacerAction(QObject *parent, const char *name)
 
689
: IconAction(parent, name)
 
690
{
 
691
        d = new Private;
 
692
        setText(tr("<Spacer>"));
 
693
        setMenuText(tr("<Spacer>"));
 
694
        setWhatsThis (tr("Spacer provides spacing to separate actions"));
 
695
}
 
696
 
 
697
SpacerAction::~SpacerAction()
 
698
{
 
699
        delete d;
 
700
}
 
701
 
 
702
bool SpacerAction::addTo(QWidget *w)
 
703
{
 
704
        if ( w->inherits("QToolBar") ) {
 
705
                new Private::StretchWidget(w);
 
706
                return true;
 
707
        }
 
708
 
 
709
        return false;
 
710
}
 
711
 
 
712
IconAction *SpacerAction::copy() const
 
713
{
 
714
        return new SpacerAction( 0 );
 
715
}
 
716
 
 
717
//----------------------------------------------------------------------------
 
718
// SeparatorAction
 
719
//----------------------------------------------------------------------------
 
720
 
 
721
class SeparatorAction::Private
 
722
{
 
723
public:
 
724
        Private() { }
 
725
 
 
726
        QAction *separator;
 
727
};
 
728
 
 
729
SeparatorAction::SeparatorAction( QObject *parent, const char *name )
 
730
        : IconAction( tr("<Separator>"), tr("<Separator>"), 0, parent, name )
 
731
{
 
732
        d = new Private();
 
733
        d->separator = new QAction(this, "qt_separator_action");
 
734
 
 
735
        setWhatsThis (tr("Separator"));
 
736
}
 
737
 
 
738
SeparatorAction::~SeparatorAction()
 
739
{
 
740
        delete d;
 
741
}
 
742
 
 
743
bool SeparatorAction::addTo (QWidget *w)
 
744
{
 
745
        return d->separator->addTo( w );
 
746
}
 
747
 
 
748
IconAction *SeparatorAction::copy() const
 
749
{
 
750
        return new SeparatorAction( 0 );
 
751
}
 
752
 
 
753
//----------------------------------------------------------------------------
 
754
// EventNotifierAction
 
755
//----------------------------------------------------------------------------
 
756
 
 
757
class EventNotifierAction::Private
 
758
{
 
759
public:
 
760
        Private() { }
 
761
 
 
762
        QPtrList<MLabel> labels;
 
763
        bool hide;
 
764
};
 
765
 
 
766
EventNotifierAction::EventNotifierAction(QObject *parent, const char *name)
 
767
: IconAction(parent, name)
 
768
{
 
769
        d = new Private;
 
770
        setMenuText(tr("<Event notifier>"));
 
771
        d->hide = true;
 
772
}
 
773
 
 
774
EventNotifierAction::~EventNotifierAction()
 
775
{
 
776
        delete d;
 
777
}
 
778
 
 
779
bool EventNotifierAction::addTo(QWidget *w)
 
780
{
 
781
        if ( w->inherits("QToolBar") ) {
 
782
                MLabel *label = new MLabel(w, "EventNotifierAction::MLabel");
 
783
                label->setText(text());
 
784
                d->labels.append(label);
 
785
                connect(label, SIGNAL(destroyed()), SLOT(objectDestroyed()));
 
786
                connect(label, SIGNAL(doubleClicked()), SIGNAL(activated()));
 
787
                connect(label, SIGNAL(clicked(int)), SIGNAL(clicked(int)));
 
788
 
 
789
                if ( d->hide )
 
790
                        hide();
 
791
 
 
792
                return true;
 
793
        }
 
794
 
 
795
        return false;
 
796
}
 
797
 
 
798
void EventNotifierAction::setText(const QString &t)
 
799
{
 
800
        IconAction::setText("<nobr>" + t + "</nobr>");
 
801
 
 
802
        QPtrListIterator<MLabel> it ( d->labels );
 
803
        for ( ; it.current(); ++it) {
 
804
                MLabel *label = it.current();
 
805
                label->setText(text());
 
806
        }
 
807
}
 
808
 
 
809
void EventNotifierAction::objectDestroyed()
 
810
{
 
811
        MLabel *label = (MLabel *)sender();
 
812
        d->labels.removeRef(label);
 
813
}
 
814
 
 
815
void EventNotifierAction::hide()
 
816
{
 
817
        d->hide = true;
 
818
 
 
819
        QPtrListIterator<MLabel> it ( d->labels );
 
820
        for ( ; it.current(); ++it) {
 
821
                MLabel *label = it.current();
 
822
                label->hide();
 
823
                QToolBar *toolBar = (QToolBar *)label->parent();
 
824
 
 
825
                QObjectList *l = toolBar->queryList( "QWidget" );
 
826
                int found = 0;
 
827
 
 
828
                QObjectListIt it( *l );
 
829
                QObject *obj;
 
830
                for ( ; (obj = it.current()); ++it) {
 
831
                        if ( QCString(obj->name()).left(3) != "qt_" ) // misc internal Qt objects
 
832
                                found++;
 
833
                }
 
834
                delete l;
 
835
 
 
836
                if ( found == 1 ) // only MLabel is on ToolBar
 
837
                        toolBar->hide();
 
838
        }
 
839
}
 
840
 
 
841
void EventNotifierAction::show()
 
842
{
 
843
        d->hide = false;
 
844
 
 
845
        QPtrListIterator<MLabel> it ( d->labels );
 
846
        for ( ; it.current(); ++it) {
 
847
                MLabel *label = it.current();
 
848
                QToolBar *toolBar = (QToolBar *)label->parent();
 
849
                toolBar->show();
 
850
                label->show();
 
851
        }
 
852
}
 
853
 
 
854
IconAction *EventNotifierAction::copy() const
 
855
{
 
856
        EventNotifierAction *act = new EventNotifierAction( 0 );
 
857
 
 
858
        *act = *this;
 
859
 
 
860
        return act;
 
861
}
 
862
 
 
863
EventNotifierAction &EventNotifierAction::operator=( const EventNotifierAction &from )
 
864
{
 
865
        *( (IconAction *)this ) = from;
 
866
 
 
867
        d->hide = from.d->hide;
 
868
 
 
869
        return *this;
 
870
}
 
871
 
 
872
#include "mainwin_p.moc"