~ubuntu-branches/ubuntu/edgy/psi/edgy

« back to all changes in this revision

Viewing changes to src/mainwin.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2002-04-19 02:28:44 UTC
  • Revision ID: james.westby@ubuntu.com-20020419022844-za7xgai5qyfd9xv6
Tags: upstream-0.8.5
ImportĀ upstreamĀ versionĀ 0.8.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
** mainwin.cpp - the main window.  holds contactlist and buttons.
 
3
** Copyright (C) 2001, 2002  Justin Karneges
 
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 program; 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"mainwin.h"
 
22
#include"userlist.h"
 
23
#include"common.h"
 
24
#include"showtextdlg.h"
 
25
 
 
26
#include<qmessagebox.h>
 
27
#include<qiconset.h>
 
28
#include<qtooltip.h>
 
29
#include<qstyle.h>
 
30
 
 
31
 
 
32
// deletes submenus in a popupmenu
 
33
void qpopupmenuclear(QPopupMenu *p)
 
34
{
 
35
        while(p->count()) {
 
36
                QMenuItem *item = p->findItem(p->idAt(0));
 
37
                QPopupMenu *popup = item->popup();
 
38
                p->removeItemAt(0);
 
39
 
 
40
                if(popup)
 
41
                        delete popup;
 
42
        }
 
43
}
 
44
 
 
45
 
 
46
//*******************************************************
 
47
//  MainWin
 
48
//*******************************************************
 
49
MainWin::MainWin(bool _onTop, QWidget *parent, const char *name)
 
50
:QWidget(parent, name, _onTop ? WStyle_StaysOnTop: 0)
 
51
{
 
52
        wmdock[0] = QImage("./image/psiwmdock1.png");
 
53
 
 
54
        setIcon(status2pix(STATUS_OFFLINE));
 
55
 
 
56
        onTop = _onTop;
 
57
        nextAmount = 0;
 
58
        localStatus = STATUS_OFFLINE;
 
59
        userlist = 0;
 
60
        tray = 0;
 
61
        trayMenu = 0;
 
62
        statusTip = "";
 
63
        infoString = "";
 
64
        localJid = "";
 
65
 
 
66
        trayTimer = 0;
 
67
        animStep = 0;
 
68
        v_isActive = FALSE;
 
69
 
 
70
        vb_main = new QVBoxLayout(this, 2);
 
71
        QHBoxLayout *hb_tools = new QHBoxLayout(vb_main);
 
72
 
 
73
        tb_offline = new MToolButton(this);
 
74
        tb_offline->setToggleButton(TRUE);
 
75
        tb_offline->setOn(TRUE);
 
76
        hb_tools->addWidget(tb_offline);
 
77
 
 
78
        tb_away = new MToolButton(this);
 
79
        tb_away->setToggleButton(TRUE);
 
80
        tb_away->setOn(TRUE);
 
81
        hb_tools->addWidget(tb_away);
 
82
 
 
83
        tb_agents = new MToolButton(this);
 
84
        tb_agents->setToggleButton(TRUE);
 
85
        tb_agents->setOn(TRUE);
 
86
        hb_tools->addWidget(tb_agents);
 
87
 
 
88
        setToolBarIcons();
 
89
 
 
90
        hb_tools->addStretch(1);
 
91
 
 
92
        QToolTip::add(tb_offline, tr("Show Offline Contacts"));
 
93
        QToolTip::add(tb_away, tr("Show Away/XA/DnD"));
 
94
        QToolTip::add(tb_agents, tr("Show Agents/Transports"));
 
95
 
 
96
        cvlist = new ContactView(this);
 
97
        //connect(cvlist, SIGNAL(totalAlerts(int)), this, SLOT(totalAlerts(int)));
 
98
        connect(tb_offline, SIGNAL(toggled(bool)), cvlist, SLOT(setShowOffline(bool)));
 
99
        connect(tb_away, SIGNAL(toggled(bool)), cvlist, SLOT(setShowAway(bool)));
 
100
        connect(tb_agents, SIGNAL(toggled(bool)), cvlist, SLOT(setShowAgents(bool)));
 
101
        connect(cvlist, SIGNAL(showOffline(bool)), tb_offline, SLOT(setPressed(bool)));
 
102
        connect(cvlist, SIGNAL(showAway(bool)), tb_away, SLOT(setPressed(bool)));
 
103
        connect(cvlist, SIGNAL(showAgents(bool)), tb_agents, SLOT(setPressed(bool)));
 
104
        vb_main->addWidget(cvlist);
 
105
 
 
106
        QHBoxLayout *hb1 = new QHBoxLayout(vb_main);
 
107
        lb_info = new MLabel(this);
 
108
        connect(lb_info, SIGNAL(clicked(int)), SLOT(statusClicked(int)));
 
109
        connect(lb_info, SIGNAL(doubleClicked()), SLOT(doRecvNextEvent()));
 
110
        lb_info->setMinimumWidth(48);
 
111
        lb_info->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
 
112
        lb_info->setFrameStyle(QFrame::Panel | QFrame::Sunken);
 
113
        hb1->addWidget(lb_info);
 
114
        lb_ssl = new QLabel(this);
 
115
        lb_ssl->setFrameStyle(QFrame::Panel | QFrame::Sunken);
 
116
        setUsingSSL(FALSE);
 
117
        hb1->addWidget(lb_ssl);
 
118
 
 
119
        hb_status = new QHBoxLayout(vb_main);
 
120
        pb_options = new QPushButton(this);
 
121
        pb_options->setPixmap(*pix_main);
 
122
        pb_options->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) );
 
123
        hb_status->addWidget(pb_options);
 
124
 
 
125
        pb_status = new MPushButton(this);
 
126
        pb_status->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
 
127
        decorateButton(STATUS_OFFLINE);
 
128
        hb_status->addWidget(pb_status);
 
129
 
 
130
        statusMenu = new QPopupMenu(this);
 
131
        optionsMenu = new QPopupMenu(this);
 
132
        buildStatusMenu();
 
133
        buildOptionsMenu();
 
134
        connect(statusMenu, SIGNAL(aboutToShow()), SLOT(buildStatusMenu()));
 
135
        connect(statusMenu, SIGNAL(activated(int)), SLOT(activatedStatusMenu(int)));
 
136
        connect(optionsMenu, SIGNAL(aboutToShow()), SLOT(buildOptionsMenu()));
 
137
        connect(optionsMenu, SIGNAL(activated(int)), SLOT(activatedOptionsMenu(int)));
 
138
 
 
139
        pb_options->setPopup(optionsMenu);
 
140
        pb_status->setPopup(statusMenu);
 
141
 
 
142
#ifdef Q_WS_MAC
 
143
        vb_main->addSpacing(16);
 
144
#endif
 
145
 
 
146
        updateCaption();
 
147
}
 
148
 
 
149
MainWin::~MainWin()
 
150
{
 
151
        if(tray) {
 
152
                delete tray;
 
153
                tray = 0;
 
154
                delete trayMenu;
 
155
                trayMenu = 0;
 
156
        }
 
157
}
 
158
 
 
159
void MainWin::setAlwaysOnTop(bool _onTop)
 
160
{
 
161
        if(_onTop == onTop)
 
162
                return;
 
163
 
 
164
        onTop = _onTop;
 
165
        QPoint p = pos();
 
166
        reparent(parentWidget(), onTop ? WStyle_StaysOnTop: 0, p, FALSE);
 
167
        move(p);
 
168
        show();
 
169
}
 
170
 
 
171
void MainWin::setUseDock(bool use)
 
172
{
 
173
        if(use == FALSE) {
 
174
                if(tray) {
 
175
                        traySetAnim(0);
 
176
                        delete tray;
 
177
                        tray = 0;
 
178
                        delete trayMenu;
 
179
                        trayMenu = 0;
 
180
                }
 
181
                return;
 
182
        }
 
183
 
 
184
        if(tray)
 
185
                return;
 
186
 
 
187
        trayMenu = new QPopupMenu;
 
188
        connect(trayMenu, SIGNAL(aboutToShow()), SLOT(buildTrayMenu()));
 
189
 
 
190
        tray = new TrayIcon(makeTrayIcon(status2qim(localStatus)), "Psi", trayMenu);
 
191
        connect(tray, SIGNAL(clicked(const QPoint &, int)), SLOT(trayClicked(const QPoint &, int)));
 
192
        connect(tray, SIGNAL(doubleClicked(const QPoint &)), SLOT(trayDoubleClicked()));
 
193
        connect(tray, SIGNAL(closed()), SIGNAL(closeProgram()));
 
194
        tray->show();
 
195
 
 
196
        updateReadNext(nextType, nextAmount);
 
197
}
 
198
 
 
199
void MainWin::setInfo(const QString &str)
 
200
{
 
201
        infoString = str;
 
202
 
 
203
        if(nextAmount == 0)
 
204
                lb_info->setText(QString("<nobr>") + infoString + "</nobr>");
 
205
}
 
206
 
 
207
void MainWin::setUsingSSL(bool use)
 
208
{
 
209
        usingSSL = use;
 
210
        lb_ssl->setPixmap(usingSSL ? *pix_ssl_yes : *pix_ssl_no);
 
211
        QToolTip::add(lb_ssl, usingSSL ? tr("Connection is encrypted") : tr("Connection is not encrypted"));
 
212
}
 
213
 
 
214
void MainWin::buildStatusMenu()
 
215
{
 
216
        statusMenu->clear();
 
217
 
 
218
        statusMenu->insertItem(QIconSet(status2pix(STATUS_ONLINE)),  status2txt(STATUS_ONLINE),      STATUS_ONLINE);
 
219
        statusMenu->insertItem(QIconSet(status2pix(STATUS_AWAY)),    status2txt(STATUS_AWAY),        STATUS_AWAY);
 
220
        statusMenu->insertItem(QIconSet(status2pix(STATUS_XA)),      status2txt(STATUS_XA),          STATUS_XA);
 
221
        statusMenu->insertItem(QIconSet(status2pix(STATUS_DND)),     status2txt(STATUS_DND),         STATUS_DND);
 
222
        statusMenu->insertSeparator();
 
223
        statusMenu->insertItem(QIconSet(status2pix(STATUS_OFFLINE)), status2txt(STATUS_OFFLINE),     STATUS_OFFLINE);
 
224
}
 
225
 
 
226
void MainWin::activatedStatusMenu(int id)
 
227
{
 
228
        statusChanged(id);
 
229
}
 
230
 
 
231
void MainWin::buildOptionsMenu()
 
232
{
 
233
        // clear the menu and submenus
 
234
        qpopupmenuclear(optionsMenu);
 
235
 
 
236
        QPopupMenu *helpMenu = new QPopupMenu(optionsMenu);
 
237
        helpMenu->insertItem(tr("&ReadMe"), 13);
 
238
        helpMenu->insertItem(tr("&Hints"), 14);
 
239
        helpMenu->insertItem(tr("&License"), 11);
 
240
        helpMenu->insertItem(tr("&Warning"), 12);
 
241
        helpMenu->insertSeparator();
 
242
        helpMenu->insertItem(tr("&About"), 7);
 
243
        helpMenu->insertItem(tr("About &Qt"), 8);
 
244
        helpMenu->setItemEnabled(14, FALSE);
 
245
        connect(helpMenu, SIGNAL(activated(int)), SLOT(activatedOptionsMenu(int)));
 
246
 
 
247
        // options menu
 
248
        optionsMenu->insertItem(QIconSet(*pix_add),   tr("&Add a contact"),     0);
 
249
        optionsMenu->insertItem(QIconSet(*pix_send),  tr("New &blank message"), 1);
 
250
        optionsMenu->insertItem(QIconSet(transport2icon("", STATUS_ONLINE)), tr("Manage &services"), 15);
 
251
        optionsMenu->insertItem(tr("File sharing"), 4);
 
252
        optionsMenu->setItemEnabled(4, FALSE);
 
253
        optionsMenu->insertItem(QIconSet(*pix_account), tr("Account Setup"), 16);
 
254
        optionsMenu->insertItem(QIconSet(*pix_info), tr("Personal &info"), 6);
 
255
        optionsMenu->insertItem(tr("&Options"),             9);
 
256
        optionsMenu->insertItem(tr("&Log window"),          10);
 
257
        optionsMenu->insertItem(QIconSet(*pix_changeacc), tr("&Change profile"),3);
 
258
        optionsMenu->insertItem(tr("Play &sounds"), 2);
 
259
        optionsMenu->setItemChecked(2, useSound);
 
260
        optionsMenu->insertSeparator();
 
261
        optionsMenu->insertItem(tr("&Help"), helpMenu);
 
262
        optionsMenu->insertItem(tr("&Quit"),                 5);
 
263
}
 
264
 
 
265
void MainWin::activatedOptionsMenu(int id)
 
266
{
 
267
        QString dstr; dstr.sprintf("mainwin: id=%d\n", id);
 
268
        pdb(DEBUG_MAINWIN, dstr);
 
269
 
 
270
        if(id == 0)
 
271
                addUser();
 
272
        else if(id == 1)
 
273
                blankMessage();
 
274
        else if(id == 2) {
 
275
                if(useSound)
 
276
                        useSound = FALSE;
 
277
                else
 
278
                        useSound = TRUE;
 
279
        }
 
280
        else if(id == 3)
 
281
                changeProfile();
 
282
        else if(id == 4)
 
283
                doFileSharing();
 
284
        else if(id == 5) {
 
285
                tryCloseProgram();
 
286
        }
 
287
        else if(id == 6)
 
288
                accountInfo();
 
289
        else if(id == 7) {
 
290
                QString content = QString("<h3>%1 v%2</h3>\n").arg(PROG_NAME).arg(PROG_VERSION);
 
291
                content += "<br>\n";
 
292
                content += "Copyright (C) 2001,2002<br>\n";
 
293
                content += "By Justin Karneges<br>\n";
 
294
                content += "infiniti@affinix.com<br>\n";
 
295
                content += "http://psi.affinix.com/<br>\n";
 
296
                content += "<br>\n";
 
297
                content += "Psi is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions.  See Help->License for details.<br>\n";
 
298
                content += "<br>\n";
 
299
                content += "A capable Jabber client written in C++ using the Qt GUI Toolkit.<br>\n";
 
300
                content += "<br>\n";
 
301
//#ifdef Q_WS_MAC
 
302
                content += "Mac port contributed by Bill Myers.<br>\n";
 
303
//#endif
 
304
                content += "Graphics by Jason Kim, Justin Karneges, Hideaki Omuro, and other contributers.<br>\n";
 
305
 
 
306
                AboutDlg *w = new AboutDlg(*pix_icon_48, content, this);
 
307
                w->setCaption(tr("About"));
 
308
                //w->setIcon(*pix_online);
 
309
                w->exec();
 
310
                delete w;
 
311
                //QMessageBox::about(this, CAP("About"), content);
 
312
        }
 
313
        else if(id == 8) {
 
314
                QMessageBox::aboutQt(this);
 
315
        }
 
316
        else if(id == 9) {
 
317
                doOptions();
 
318
        }
 
319
        else if(id == 10)
 
320
                debug_window->show();
 
321
        else if(id == 11) {
 
322
                ShowTextDlg *w = new ShowTextDlg(g.pathBase + "/COPYING");
 
323
                w->setCaption(CAP(tr("License")));
 
324
                w->show();
 
325
        }
 
326
        else if(id == 12) {
 
327
                unfinishedSoftware();
 
328
        }
 
329
        else if(id == 13) {
 
330
                // readme
 
331
#ifdef Q_WS_WIN
 
332
                ShowTextDlg *w = new ShowTextDlg(g.pathBase + "/readme.txt");
 
333
#else
 
334
                ShowTextDlg *w = new ShowTextDlg(g.pathBase + "/README");
 
335
#endif
 
336
                w->setCaption(CAP(tr("ReadMe")));
 
337
                w->show();
 
338
        }
 
339
        else if(id == 14) {
 
340
                // hints
 
341
        }
 
342
        else if(id == 15) {
 
343
                doManageServices();
 
344
 
 
345
                return;
 
346
        }
 
347
        else if(id == 16) {
 
348
                doManageAccounts();
 
349
        }
 
350
}
 
351
 
 
352
void MainWin::buildTrayMenu()
 
353
{
 
354
        if(!trayMenu)
 
355
                return;
 
356
        trayMenu->clear();
 
357
 
 
358
        if(nextAmount > 0) {
 
359
                trayMenu->insertItem(tr("Receive next event"), this, SLOT(doRecvNextEvent()));
 
360
                trayMenu->insertSeparator();
 
361
        }
 
362
 
 
363
        if(isHidden())
 
364
                trayMenu->insertItem(tr("Un&hide"), this, SLOT(trayShow()));
 
365
        else
 
366
                trayMenu->insertItem(tr("&Hide"), this, SLOT(trayHide()));
 
367
        trayMenu->insertItem(tr("&Status"), statusMenu);
 
368
        trayMenu->insertSeparator();
 
369
        trayMenu->insertItem(tr("&Quit"), this, SLOT(tryCloseProgram()));
 
370
}
 
371
 
 
372
void MainWin::decorateButton(int status)
 
373
{
 
374
        setIcon(status2pix(status));
 
375
        if(tray && !v_isActive)
 
376
                tray->setIcon(makeTrayIcon(status2qim(status)));
 
377
 
 
378
        QIconSet icon;
 
379
        icon.setPixmap(status2pix(status), QIconSet::Small);
 
380
 
 
381
        pb_status->setIconSet(icon);
 
382
        pb_status->setText(status2txt(status));
 
383
}
 
384
 
 
385
bool MainWin::askQuit()
 
386
{
 
387
        if(localStatus != STATUS_OFFLINE) {
 
388
                int n = QMessageBox::information(0, tr("Warning"), tr("You are currently logged in.  Are you sure you want to close Psi?"), tr("&Yes"), tr("&No"));
 
389
                if(n != 0)
 
390
                        return FALSE;
 
391
        }
 
392
 
 
393
        return TRUE;
 
394
}
 
395
 
 
396
void MainWin::tryCloseProgram()
 
397
{
 
398
        if(askQuit())
 
399
                closeProgram();
 
400
}
 
401
 
 
402
void MainWin::closeEvent(QCloseEvent *e)
 
403
{
 
404
        if(tray) {
 
405
                hide();
 
406
                return;
 
407
        }
 
408
 
 
409
        if(!askQuit())
 
410
                return;
 
411
 
 
412
        closeProgram();
 
413
        e->accept();
 
414
}
 
415
 
 
416
void MainWin::updateCaption()
 
417
{
 
418
        QString str = "";
 
419
 
 
420
        if(nextAmount > 0)
 
421
                str += "* ";
 
422
 
 
423
        if(localJid.isEmpty())
 
424
                str += PROG_NAME;
 
425
        else
 
426
                str += localJid;
 
427
 
 
428
        if(str == caption())
 
429
                return;
 
430
 
 
431
        setCaption(str);
 
432
}
 
433
 
 
434
void MainWin::localUpdate(const JabRosterEntry &e)
 
435
{
 
436
        localJid = e.jid;
 
437
 
 
438
        if(e.isAvailable())
 
439
                localStatus = e.local()->status;
 
440
        else
 
441
                localStatus = STATUS_OFFLINE;
 
442
 
 
443
        if(!localJid.isEmpty()) {
 
444
                statusTip = makeToolTip(e);
 
445
                QToolTip::add(lb_info, statusTip);
 
446
        }
 
447
        else {
 
448
                QToolTip::remove(lb_info);
 
449
        }
 
450
 
 
451
        if(tray)
 
452
                tray->setToolTip(status2txt(localStatus));
 
453
 
 
454
        updateCaption();
 
455
}
 
456
 
 
457
QString MainWin::makeToolTip(const JabRosterEntry &e)
 
458
{
 
459
        QString statusString = "";
 
460
        if(e.isAvailable())
 
461
                statusString = e.local()->statusString;
 
462
 
 
463
        QString jid = e.jid;
 
464
        QString nick = e.nick;
 
465
 
 
466
        QString str = QString("<qt>");
 
467
        str += QString("<nobr>%1: %2</nobr>").arg(jidnick(jid,nick)).arg(status2txt(localStatus));
 
468
        if(!nick.isEmpty())
 
469
                str += QString("<br>[%1]").arg(jid);
 
470
 
 
471
        if(e.isAvailable()) {
 
472
                JabResource *pr = e.res.priority();
 
473
                JabResource *r, *l;
 
474
 
 
475
                // current resource
 
476
                QString curres = "";
 
477
                l = e.res.local();
 
478
                if(l == pr)
 
479
                        curres += "*";
 
480
                curres += l->name;
 
481
                str += QString("<br><nobr>") + QString(tr("Resource: %1")).arg(curres) + "</nobr>";
 
482
 
 
483
                // other resources
 
484
                QString resources;
 
485
                int n = 0;
 
486
                QPtrListIterator<JabResource> it(e.res);
 
487
                for(; (r = it.current()); ++it) {
 
488
                        // skip the local resource
 
489
                        if(l == r)
 
490
                                continue;
 
491
 
 
492
                        if(n > 0)
 
493
                                resources += ", ";
 
494
 
 
495
                        // priority?
 
496
                        if(r == pr)
 
497
                                resources += "*";
 
498
                        resources += r->name;
 
499
                        ++n;
 
500
                }
 
501
                if(!resources.isEmpty())
 
502
                        str += QString("<br><nobr>") + QString(tr("Other(s): %1")).arg(resources) + "</nobr>";
 
503
        }
 
504
 
 
505
        if(!statusString.isEmpty()) {
 
506
                QString head = tr("Status Message");
 
507
                str += QString("<br><u>%1</u><br>%2").arg(head).arg(plain2rich(statusString));
 
508
        }
 
509
        str += "</qt>";
 
510
 
 
511
        return str;
 
512
}
 
513
 
 
514
void MainWin::setToolBarIcons()
 
515
{
 
516
        tb_offline->setIconSet(QIconSet(*pix_offline));
 
517
        tb_away->setIconSet(QIconSet(status2pix(STATUS_AWAY)));
 
518
        tb_agents->setIconSet(QIconSet(transport2icon("", STATUS_ONLINE)));
 
519
}
 
520
 
 
521
void MainWin::optionsUpdate()
 
522
{
 
523
        decorateButton(localStatus);
 
524
        setToolBarIcons();
 
525
 
 
526
        // if the tray animation is active, reset it
 
527
        if(tray && v_isActive) {
 
528
                traySetAnim(messagetype2anim(nextType));
 
529
        }
 
530
}
 
531
 
 
532
QPixmap MainWin::makeTrayIcon(const QImage &_in)
 
533
{
 
534
#ifdef Q_WS_X11
 
535
        /*if(1) {
 
536
                QImage real = wmdock[0];
 
537
                real.detach();
 
538
                QImage in = _in;
 
539
                in.detach();
 
540
 
 
541
                // make sure it is no bigger than 16x16
 
542
                if(in.width() > 16 || in.height() > 16)
 
543
                        in = in.smoothScale(16,16);
 
544
 
 
545
                int xo = 40;
 
546
                int yo = 40;
 
547
 
 
548
                int n, n2;
 
549
 
 
550
                // draw a border
 
551
                for(n = 0; n < 22; ++n) {
 
552
                        real.setPixel(n + xo, yo, qRgb(0x80,0x80,0x80));
 
553
                        real.setPixel(n + xo, yo + 21, qRgb(0x00,0x00,0x00));
 
554
                        real.setPixel(xo, yo + n, qRgb(0x80,0x80,0x80));
 
555
                        real.setPixel(xo + 21, yo + n, qRgb(0x00,0x00,0x00));
 
556
                }
 
557
 
 
558
                xo += 3;
 
559
                yo += 3;
 
560
 
 
561
                // draw a dropshadow
 
562
                for(n2 = 0; n2 < in.height(); ++n2) {
 
563
                        for(n = 0; n < in.width(); ++n) {
 
564
                                if(qAlpha(_in.pixel(n,n2))) {
 
565
                                        real.setPixel(n + xo + 2, n2 + yo + 2, qRgb(0x80,0x80,0x80));
 
566
                                }
 
567
                        }
 
568
                }
 
569
                for(n2 = 0; n2 < in.height(); ++n2) {
 
570
                        for(n = 0; n < in.width(); ++n) {
 
571
                                if(qAlpha(_in.pixel(n,n2))) {
 
572
                                        real.setPixel(n + xo, n2 + yo, _in.pixel(n,n2));
 
573
                                }
 
574
                        }
 
575
                }
 
576
 
 
577
                QPixmap icon;
 
578
                icon.convertFromImage(real);
 
579
                return icon;
 
580
        }
 
581
        else {*/
 
582
                // on X11, the KDE dock is 22x22.  let's make our icon "seem" bigger.
 
583
                QImage real(22,22,32);
 
584
                //QImage in = _in.convertToImage();
 
585
                QImage in = _in;
 
586
                in.detach();
 
587
                real.fill(0);
 
588
                real.setAlphaBuffer(TRUE);
 
589
 
 
590
                // make sure it is no bigger than 16x16
 
591
                if(in.width() > 16 || in.height() > 16)
 
592
                        in = in.smoothScale(16,16);
 
593
 
 
594
                int xo = (real.width() - in.width()) / 2;
 
595
                int yo = (real.height() - in.height()) / 2;
 
596
 
 
597
                int n, n2;
 
598
 
 
599
                // draw a border
 
600
                for(n = 0; n < 22; ++n) {
 
601
                        real.setPixel(n,  0, qRgb(0x80,0x80,0x80));
 
602
                        real.setPixel(n, 21, qRgb(0x00,0x00,0x00));
 
603
                        real.setPixel( 0, n, qRgb(0x80,0x80,0x80));
 
604
                        real.setPixel(21, n, qRgb(0x00,0x00,0x00));
 
605
                }
 
606
 
 
607
                // draw a dropshadow
 
608
                for(n2 = 0; n2 < in.height(); ++n2) {
 
609
                        for(n = 0; n < in.width(); ++n) {
 
610
                                if(qAlpha(in.pixel(n,n2))) {
 
611
                                        int x = n + xo + 2;
 
612
                                        int y = n2 + yo + 2;
 
613
                                        real.setPixel(x, y, qRgba(0x80,0x80,0x80,0xff));
 
614
                                }
 
615
                        }
 
616
                }
 
617
                // draw the image
 
618
                for(n2 = 0; n2 < in.height(); ++n2) {
 
619
                        for(n = 0; n < in.width(); ++n) {
 
620
                                if(qAlpha(in.pixel(n,n2))) {
 
621
                                        QRgb c = in.pixel(n, n2);
 
622
                                        real.setPixel(n + xo, n2 + yo, qRgba(qRed(c), qGreen(c), qBlue(c), 0xff));
 
623
                                }
 
624
                        }
 
625
                }
 
626
                // create the alpha layer
 
627
                /*for(n2 = real.height()-2; n2 >= 0; --n2) {
 
628
                        for(n = 0; n < real.width(); ++n) {
 
629
                                uint c = real.pixel(n, n2);
 
630
                                if(c > 0) {
 
631
                                        QRgb old = real.pixel(n, n2);
 
632
                                        real.setPixel(n, n2, qRgba(qRed(old), qGreen(old), qBlue(old), 0xff));
 
633
                                }
 
634
                        }
 
635
                }*/
 
636
 
 
637
                QPixmap icon;
 
638
                icon.convertFromImage(real);
 
639
                return icon;
 
640
        //}
 
641
#else
 
642
        QPixmap icon;
 
643
        icon.convertFromImage(_in);
 
644
        return icon;
 
645
#endif
 
646
}
 
647
 
 
648
void MainWin::trayClicked(const QPoint &, int button)
 
649
{
 
650
        if(option.dockDCstyle)
 
651
                return;
 
652
 
 
653
        if(button == MidButton) {
 
654
                doRecvNextEvent();
 
655
                return;
 
656
        }
 
657
 
 
658
        if(isHidden())
 
659
                trayShow();
 
660
        else
 
661
                trayHide();
 
662
}
 
663
 
 
664
void MainWin::trayDoubleClicked()
 
665
{
 
666
        if(!option.dockDCstyle)
 
667
                return;
 
668
 
 
669
        if(nextAmount > 0) {
 
670
                doRecvNextEvent();
 
671
                return;
 
672
        }
 
673
 
 
674
        trayShow();
 
675
}
 
676
 
 
677
void MainWin::trayShow()
 
678
{
 
679
        show();
 
680
        bringToFront(this);
 
681
}
 
682
 
 
683
void MainWin::trayHide()
 
684
{
 
685
        hide();
 
686
}
 
687
 
 
688
void MainWin::updateReadNext(int type, int amount)
 
689
{
 
690
        nextType = type;
 
691
        nextAmount = amount;
 
692
 
 
693
        if(nextAmount == 0)
 
694
                lb_info->setText(QString("<nobr>") + infoString + "</nobr>");
 
695
        else
 
696
                lb_info->setText(QString("<nobr><b>") + tr("%1 event(s) received").arg(nextAmount) + "</b></nobr>");
 
697
 
 
698
        if(tray) {
 
699
                if(nextAmount == 0)
 
700
                        traySetAnim(0);
 
701
                else
 
702
                        traySetAnim(messagetype2anim(nextType));
 
703
        }
 
704
 
 
705
#ifdef Q_WS_MAC
 
706
        if(nextAmount == 0)
 
707
                stopDockTileBounce();
 
708
        else
 
709
                bounceDockTile();
 
710
#endif
 
711
 
 
712
        updateCaption();
 
713
}
 
714
 
 
715
void MainWin::traySetAnim(Anim *_anim)
 
716
{
 
717
        if(_anim) {
 
718
                anim = _anim;
 
719
                animStep = 0;
 
720
                if(option.alertStyle == 0)
 
721
                        tray->setIcon(makeTrayIcon(anim->qim_base()));
 
722
                if(!v_isActive) {
 
723
                        v_isActive = TRUE;
 
724
 
 
725
                        trayTimer = new QTimer(this);
 
726
                        connect(trayTimer, SIGNAL(timeout()), SLOT(trayAnimate()));
 
727
                        trayTimer->start(120);
 
728
                }
 
729
        }
 
730
        else {
 
731
                anim = 0;
 
732
                if(v_isActive) {
 
733
                        v_isActive = FALSE;
 
734
                        delete trayTimer;
 
735
 
 
736
                        // change back to normal icon
 
737
                        tray->setIcon(makeTrayIcon(status2qim(localStatus)));
 
738
                }
 
739
        }
 
740
}
 
741
 
 
742
void MainWin::trayAnimate()
 
743
{
 
744
        if(anim->isAnim() && option.alertStyle == 2) {
 
745
                tray->setIcon(makeTrayIcon(anim->qim_frame(animStep)));
 
746
 
 
747
                ++animStep;
 
748
                if(animStep >= anim->numFrames()-1)
 
749
                        animStep = 0;
 
750
        }
 
751
        else if(option.alertStyle != 0) {
 
752
                if(animStep == 0)
 
753
                        tray->setIcon(makeTrayIcon(anim->qim_base()));
 
754
                else if(animStep == 4) {
 
755
                        QImage blank(16,16,32);
 
756
                        blank.fill(0);
 
757
                        blank.setAlphaBuffer(TRUE);
 
758
                        tray->setIcon(makeTrayIcon(blank));
 
759
                }
 
760
 
 
761
                ++animStep;
 
762
                if(animStep == 8)
 
763
                        animStep = 0;
 
764
        }
 
765
}
 
766
 
 
767
void MainWin::doRecvNextEvent()
 
768
{
 
769
        recvNextEvent();
 
770
}
 
771
 
 
772
void MainWin::statusClicked(int x)
 
773
{
 
774
        if(x == MidButton)
 
775
                recvNextEvent();
 
776
}
 
777
 
 
778
 
 
779
//*******************************************************
 
780
//  MPushButton
 
781
//*******************************************************
 
782
MPushButton::MPushButton(QWidget *parent, const char *name)
 
783
:QPushButton(parent, name)
 
784
{
 
785
        setMinimumWidth(48);
 
786
        setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
 
787
 
 
788
        hasTip = FALSE;
 
789
}
 
790
 
 
791
void MPushButton::setText(const QString &_text)
 
792
{
 
793
        if(hasTip) {
 
794
                QToolTip::remove(this);
 
795
                hasTip = FALSE;
 
796
        }
 
797
 
 
798
        QPushButton::setText(_text);
 
799
}
 
800
 
 
801
void MPushButton::drawButtonLabel(QPainter *p)
 
802
{
 
803
        // crazy code ahead!  watch out for potholes and deer.
 
804
 
 
805
        // this gets us the width of the "text area" on the button.
 
806
        // adapted from qt/src/styles/qcommonstyle.cpp and qt/src/widgets/qpushbutton.cpp
 
807
        QRect r = style().subRect(QStyle::SR_PushButtonContents, this);
 
808
        if(isMenuButton())
 
809
                r.setWidth(r.width() - style().pixelMetric(QStyle::PM_MenuButtonIndicator, this));
 
810
        if(iconSet() && !iconSet()->isNull())
 
811
                r.setWidth(r.width() - (iconSet()->pixmap(QIconSet::Small, QIconSet::Normal, QIconSet::Off).width() + 4));
 
812
 
 
813
        // font metrics
 
814
        QFontMetrics fm(font());
 
815
 
 
816
        // w1 = width of button text, w2 = width of text area
 
817
        int w1 = fm.width(text());
 
818
        int w2 = r.width();
 
819
 
 
820
        // backup original text
 
821
        QString oldtext = text();
 
822
 
 
823
        // button text larger than what will fit?
 
824
        if(w1 > w2) {
 
825
                if(!hasTip) {
 
826
                        QToolTip::add(this, text());
 
827
                        hasTip = TRUE;
 
828
                }
 
829
 
 
830
                // make a string that fits
 
831
                bool found = FALSE;
 
832
                QString newtext;
 
833
                int n;
 
834
                for(n = oldtext.length(); n > 0; --n) {
 
835
                        if(fm.width(oldtext, n) < w2) {
 
836
                                found = TRUE;
 
837
                                break;
 
838
                        }
 
839
                }
 
840
                if(found)
 
841
                        newtext = oldtext.mid(0, n);
 
842
                else
 
843
                        newtext = "";
 
844
 
 
845
                // set the new text that fits.  updates must be off, or we recurse.
 
846
                setUpdatesEnabled(FALSE);
 
847
                QButton::setText(newtext);
 
848
                setUpdatesEnabled(TRUE);
 
849
        }
 
850
        else {
 
851
                if(hasTip) {
 
852
                        QToolTip::remove(this);
 
853
                        hasTip = FALSE;
 
854
                }
 
855
        }
 
856
 
 
857
        // draw!
 
858
        QPushButton::drawButtonLabel(p);
 
859
 
 
860
        // restore original button text now that we are done drawing.
 
861
        setUpdatesEnabled(FALSE);
 
862
        QButton::setText(oldtext);
 
863
        setUpdatesEnabled(TRUE);
 
864
}
 
865
 
 
866
 
 
867
//*******************************************************
 
868
//  MToolButton
 
869
//*******************************************************
 
870
MToolButton::MToolButton(QWidget *parent, const char *name)
 
871
:QToolButton(parent, name)
 
872
{
 
873
}
 
874
 
 
875
void MToolButton::setPressed(bool x)
 
876
{
 
877
        setOn(x);
 
878
}
 
879
 
 
880
 
 
881
//*******************************************************
 
882
//  MLabel
 
883
//*******************************************************
 
884
MLabel::MLabel(QWidget *parent, const char *name)
 
885
:QLabel(parent, name)
 
886
{
 
887
}
 
888
 
 
889
void MLabel::mouseReleaseEvent(QMouseEvent *e)
 
890
{
 
891
        clicked(e->button());
 
892
        e->ignore();
 
893
}
 
894
 
 
895
void MLabel::mouseDoubleClickEvent(QMouseEvent *e)
 
896
{
 
897
        if(e->button() == LeftButton)
 
898
                doubleClicked();
 
899
 
 
900
        e->ignore();
 
901
}
 
902
 
 
903
 
 
904
//*******************************************************
 
905
//  AboutDlg
 
906
//*******************************************************
 
907
AboutDlg::AboutDlg(const QPixmap &icon, const QString &content, QWidget *par)
 
908
:QDialog(par, 0, TRUE)
 
909
{
 
910
        QLabel *l;
 
911
        QVBoxLayout *vb = new QVBoxLayout(this, 8);
 
912
        QHBoxLayout *hb = new QHBoxLayout(vb);
 
913
        QVBoxLayout *col;
 
914
 
 
915
        col = new QVBoxLayout(hb);
 
916
        l = new QLabel(this);
 
917
        l->setPixmap(icon);
 
918
        col->addWidget(l);
 
919
        col->addStretch(1);
 
920
 
 
921
        col = new QVBoxLayout(hb);
 
922
        l = new QLabel(this);
 
923
        l->setText(content);
 
924
        col->addWidget(l);
 
925
        col->addStretch(1);
 
926
 
 
927
        hb = new QHBoxLayout(vb);
 
928
        hb->addStretch(1);
 
929
        QPushButton *pb_ok = new QPushButton("&OK", this);
 
930
        connect(pb_ok, SIGNAL(clicked()), SLOT(close()));
 
931
        hb->addWidget(pb_ok);
 
932
        hb->addStretch(1);
 
933
}
 
934