1 /*
2  * iconwidget.cpp - misc. Iconset- and PsiIcon-aware widgets
3  * Copyright (C) 2003-2006  Michail Pishchagin
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  */
20 
21 #include "iconwidget.h"
22 #include "iconsetdisplay.h"
23 #include "iconsetselect.h"
24 #include "icontoolbutton.h"
25 #include "iconbutton.h"
26 
27 #include <QApplication>
28 #include <QPainter>
29 #include <QBrush>
30 
31 #ifndef WIDGET_PLUGIN
32 #	include "iconset.h"
33 #	include <QStyle>
34 #	include <QBitmap>
35 #	include <QMap>
36 #       include "pixmaputil.h"
37 #else
38 #	include <QImage>
39 
40 static const char *cancel_xpm[] = {
41 "22 22 60 1",
42 " 	c None",
43 ".	c #E84300",
44 "+	c #E63F00",
45 "@	c #D11E00",
46 "#	c #D11B00",
47 "$	c #F69D50",
48 "%	c #F59A4D",
49 "&	c #E23800",
50 "*	c #EE5F1F",
51 "=	c #ED5A1D",
52 "-	c #CD1700",
53 ";	c #FECBA2",
54 ">	c #FEC69A",
55 ",	c #F39045",
56 "'	c #DE3200",
57 ")	c #FE7B3C",
58 "!	c #FE7234",
59 "~	c #EC4C15",
60 "{	c #CC1100",
61 "]	c #FEC091",
62 "^	c #FEBA89",
63 "/	c #F2873D",
64 "(	c #DA2C00",
65 "_	c #FE692C",
66 ":	c #EB4712",
67 "<	c #CA0F00",
68 "[	c #FEB480",
69 "}	c #FEAE78",
70 "|	c #F07D35",
71 "1	c #D62600",
72 "2	c #FEA870",
73 "3	c #FEA166",
74 "4	c #EF722D",
75 "5	c #D32100",
76 "6	c #FE9B5F",
77 "7	c #FE9356",
78 "8	c #F16C2A",
79 "9	c #F16525",
80 "0	c #FE8B4D",
81 "a	c #FE8445",
82 "b	c #EE4B15",
83 "c	c #FE6025",
84 "d	c #EE4310",
85 "e	c #C90E00",
86 "f	c #FE561D",
87 "g	c #FE4B16",
88 "h	c #EA2F08",
89 "i	c #C70900",
90 "j	c #FE4010",
91 "k	c #FE350B",
92 "l	c #EA1D03",
93 "m	c #C60700",
94 "n	c #FE2906",
95 "o	c #FE1A02",
96 "p	c #E90900",
97 "q	c #C50300",
98 "r	c #FE0A00",
99 "s	c #FE0000",
100 "t	c #E90000",
101 "u	c #C40000",
102 "                      ",
103 "                      ",
104 "    .+          @#    ",
105 "   .$%&        @*=-   ",
106 "  .$;>,'      @*)!~{  ",
107 "  +%>]^/(    @*)!_:<  ",
108 "   &,^[}|1  @*)!_:<   ",
109 "    '/}2345@*)!_:<    ",
110 "     (|36789)!_:<     ",
111 "      1470a)!_:<      ",
112 "       58a)!_b<       ",
113 "       @9)!_cde       ",
114 "      @*)!_cfghi      ",
115 "     @*)!_bdgjklm     ",
116 "    @*)!_:<ehknopq    ",
117 "   @*)!_:<  ilorstu   ",
118 "  @*)!_:<    mpssstu  ",
119 "  #=!_:<      qtsstu  ",
120 "   -~:<        uttu   ",
121 "    {<          uu    ",
122 "                      ",
123 "                      "};
124 #endif
125 
126 //----------------------------------------------------------------------------
127 // RealIconWidgetItem
128 //----------------------------------------------------------------------------
129 
130 class RealIconWidgetItem : public IconWidgetItem
131 {
132 	Q_OBJECT
133 public:
RealIconWidgetItem(QListWidget * parent=0)134 	RealIconWidgetItem(QListWidget *parent = 0)
135 	: IconWidgetItem(parent) {}
136 
137 	virtual void paint(QPainter *painter) const = 0;
138 	virtual int height() const = 0;
139 	virtual int width() const = 0;
140 	virtual QPoint textPosition(QPainter *painter) const = 0;
141 
142 	static const int TextPositionRole = Qt::UserRole + 1;
143 
data(int role) const144 	QVariant data(int role) const
145 	{
146 		if (role == Qt::SizeHintRole)
147 			return QVariant(QSize(width(), height()));
148 		else if (role == Qt::DecorationRole) {
149 #ifndef WIDGET_PLUGIN
150 			QPixmap pix = PixmapUtil::createTransparentPixmap(width(), height());
151 #else
152 			QPixmap pix(width(), height()); // junk inside
153 #endif
154 			QPainter p(&pix);
155 			paint(&p);
156 			p.end();
157 			return QVariant(pix);
158 		}
159 		else if (role == TextPositionRole) {
160 			QPixmap pix(width(), height());
161 			QPainter p(&pix);
162 			QPoint pos = textPosition(&p);
163 			p.end();
164 			return QVariant(pos);
165 		}
166 		return QListWidgetItem::data(role);
167 	}
168 
169 public slots:
update()170 	void update()
171 	{
172 		setData(Qt::UserRole, data(Qt::UserRole).toInt() + 1);
173 	}
174 };
175 
176 //----------------------------------------------------------------------------
177 // IconWidgetDelegate
178 //----------------------------------------------------------------------------
179 
180 class IconWidgetDelegate : public QAbstractItemDelegate
181 {
182 public:
IconWidgetDelegate(QObject * parent)183 	IconWidgetDelegate(QObject *parent)
184 	: QAbstractItemDelegate(parent) {}
185 
sizeHint(const QStyleOptionViewItem &,const QModelIndex & index) const186 	QSize sizeHint(const QStyleOptionViewItem &/*option*/, const QModelIndex &index) const
187 	{
188 		return index.model()->data(index, Qt::SizeHintRole).toSize();
189 	}
190 
paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const191 	void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
192 	{
193 		const QAbstractItemModel *model = index.model();
194 
195 		QPalette::ColorGroup cg = option.state & QStyle::State_Enabled
196 			? QPalette::Normal : QPalette::Disabled;
197 
198 		// draw the background color
199 		if (option.showDecorationSelected && (option.state & QStyle::State_Selected)) {
200 			painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight));
201 			painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
202 		}
203 		else {
204 			painter->setPen(option.palette.color(cg, QPalette::Text));
205 			QVariant value = model->data(index, Qt::BackgroundRole);
206 			if (value.isValid() && qvariant_cast<QColor>(value).isValid())
207 				painter->fillRect(option.rect, qvariant_cast<QColor>(value));
208 		}
209 
210 		painter->drawPixmap(option.rect.topLeft(), model->data(index, Qt::DecorationRole).value<QPixmap>());
211 
212 		QVariant textPosition = model->data(index, RealIconWidgetItem::TextPositionRole);
213 		if (textPosition.isValid() && !qvariant_cast<QPoint>(textPosition).isNull())
214 			painter->drawText(option.rect.topLeft() + qvariant_cast<QPoint>(textPosition), model->data(index, Qt::DisplayRole).value<QString>());
215 
216 		if (option.state & QStyle::State_HasFocus) {
217 			QStyleOptionFocusRect o;
218 			o.QStyleOption::operator=(option);
219 			QRect r = option.rect;
220 			QPoint margin(1, 1);
221 			o.rect = QRect(r.topLeft() + margin, r.bottomRight() - margin);
222 			o.state |= QStyle::State_KeyboardFocusChange;
223 			o.backgroundColor = option.palette.color(cg, (option.state & QStyle::State_Selected)
224 				? QPalette::Highlight : QPalette::Background);
225 			QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter);
226 		}
227 	}
228 };
229 
230 //----------------------------------------------------------------------------
231 // IconsetSelect
232 //----------------------------------------------------------------------------
233 
234 class IconsetSelectItem : public RealIconWidgetItem
235 {
236 	Q_OBJECT
237 private:
238 	static const int margin;
239 	static const int displayNumIcons;
240 #ifndef WIDGET_PLUGIN
241 	Iconset iss;
242 	QMap<PsiIcon*, QRect> iconRects;
243 #endif
244 	int w, h;
245 	mutable int fullW, fullH;
246 
247 public:
IconsetSelectItem(QListWidget * parent,const Iconset & _iconset)248 	IconsetSelectItem(QListWidget *parent, const Iconset &_iconset)
249 	: RealIconWidgetItem(parent)
250 	{
251 		Q_UNUSED(fullW)
252 		Q_UNUSED(fullH)
253 #ifndef WIDGET_PLUGIN
254 		iss = _iconset;
255 		setText( iss.name() );
256 
257 		w = margin;
258 		h = 2*margin;
259 
260 		int count;
261 
262 		QListIterator<PsiIcon *> it = iss.iterator();
263 		count = 0;
264 		while ( it.hasNext() ) {
265 			if ( count++ >= displayNumIcons )
266 				break; // display only first displayNumIcons icons
267 
268 			PsiIcon *icon = it.next();
269 			QPixmap pix = icon->pixmap();
270 
271 			iconRects[icon] = QRect( w, margin, pix.width(), pix.height() );
272 
273 			w += pix.width() + margin;
274 			h = qMax( h, pix.height() + 2*margin );
275 
276 			connect(icon, SIGNAL(pixmapChanged()), SLOT(update()));
277 			icon->activated(false); // start animation
278 		}
279 
280 		QMutableMapIterator<PsiIcon*, QRect> it2(iconRects);
281 		while (it2.hasNext()) {
282 			it2.next();
283 			QRect r = it2.value();
284 			it2.setValue(QRect(r.x(), (h - r.height()) / 2, r.width(), r.height()));
285 		}
286 #else
287 		Q_UNUSED( _iconset );
288 #endif
289 	}
290 
~IconsetSelectItem()291 	~IconsetSelectItem()
292 	{
293 #ifndef WIDGET_PLUGIN
294 		QMap<PsiIcon*, QRect>::Iterator it;
295 		for (it = iconRects.begin(); it != iconRects.end(); it++)
296 			it.key()->stop();
297 #endif
298 	}
299 
iconset() const300 	const Iconset *iconset() const
301 	{
302 #ifndef WIDGET_PLUGIN
303 		return &iss;
304 #else
305 		return 0;
306 #endif
307 	}
308 
height() const309 	int height() const
310 	{
311 		int hh = listWidget()->fontMetrics().lineSpacing() + h;
312 		return qMax( hh, QApplication::globalStrut().height() );
313 	}
314 
width() const315 	int width() const
316 	{
317 		int ww = qMax(listWidget()->fontMetrics().width( text() ) + 6 + 15, w + 10);
318 		return qMax( ww, QApplication::globalStrut().width() );
319 	}
320 
321 
paint(QPainter * painter) const322 	void paint(QPainter *painter) const
323 	{
324 #ifndef WIDGET_PLUGIN
325 		QFontMetrics fm = painter->fontMetrics();
326 
327 		QMap<PsiIcon*, QRect>::ConstIterator it;
328 		for (it = iconRects.begin(); it != iconRects.end(); it++) {
329 			PsiIcon *icon = it.key();
330 			QRect r = it.value();
331 			painter->drawPixmap(QPoint(10 + r.left(), fm.lineSpacing() + 2 + r.top()), icon->pixmap());
332 		}
333 #else
334 		Q_UNUSED(painter);
335 #endif
336 	}
textPosition(QPainter * painter) const337 	QPoint textPosition(QPainter *painter) const
338 	{
339 		QFontMetrics fm = painter->fontMetrics();
340 		return QPoint(3, fm.ascent() + (fm.leading()+1)/2 + 1);
341 	}
342 };
343 const int IconsetSelectItem::margin = 3;
344 const int IconsetSelectItem::displayNumIcons = 10;
345 
IconsetSelect(QWidget * parent)346 IconsetSelect::IconsetSelect(QWidget *parent)
347 : QListWidget(parent)
348 {
349 	setItemDelegate(new IconWidgetDelegate(this));
350 }
351 
~IconsetSelect()352 IconsetSelect::~IconsetSelect()
353 {
354 }
355 
insert(const Iconset & iconset)356 void IconsetSelect::insert(const Iconset &iconset)
357 {
358 #ifndef WIDGET_PLUGIN
359 	new IconsetSelectItem(this, iconset);
360 #else
361 	Q_UNUSED(iconset);
362 #endif
363 }
364 
moveItemUp()365 void IconsetSelect::moveItemUp()
366 {
367 	if ( currentRow() < 1 )
368 		return;
369 
370 	QListWidgetItem *i = currentItem();
371 	if ( !i )
372 		return;
373 	int prevRow = row(i) - 1;
374 	i = takeItem(row(i));
375 	insertItem(prevRow, i);
376 	setItemSelected(i, true);
377 	setCurrentItem(i);
378 }
379 
moveItemDown()380 void IconsetSelect::moveItemDown()
381 {
382 	if ( !currentItem() || currentRow() > (int)count() - 2 )
383 		return;
384 
385 	QListWidgetItem *i = currentItem();
386 	if ( !i )
387 		return;
388 	int nextRow = row(i) + 1;
389 	i = takeItem(row(i));
390 	insertItem(nextRow, i);
391 	setCurrentItem(i);
392 }
393 
iconset() const394 const Iconset *IconsetSelect::iconset() const
395 {
396 	IconsetSelectItem *i = (IconsetSelectItem *)currentItem();
397 	if ( !i ) {
398 		QList<QListWidgetItem *> items = selectedItems();
399 		i = !items.isEmpty() ? (IconsetSelectItem *)items.first() : 0;
400 	}
401 	if ( i )
402 		return i->iconset();
403 	return 0;
404 }
405 
lastItem() const406 QListWidgetItem *IconsetSelect::lastItem() const
407 {
408 	return item(count() - 1);
409 }
410 
viewOptions() const411 QStyleOptionViewItem IconsetSelect::viewOptions() const
412 {
413 	QStyleOptionViewItem o = QListWidget::viewOptions();
414 	o.showDecorationSelected = true;
415 	return o;
416 }
417 
418 //----------------------------------------------------------------------------
419 // IconsetDisplay
420 //----------------------------------------------------------------------------
421 
422 class IconsetDisplayItem : public RealIconWidgetItem
423 {
424 	Q_OBJECT
425 private:
426 	static const int margin;
427 	PsiIcon icon;
428 	int w, h;
429 
430 public:
IconsetDisplayItem(QListWidget * parent,PsiIcon * i,int iconW)431 	IconsetDisplayItem(QListWidget *parent, PsiIcon *i, int iconW)
432 	: RealIconWidgetItem(parent)
433 	{
434 #ifndef WIDGET_PLUGIN
435 		icon = *i;
436 		w = iconW;
437 
438 		connect(&icon, SIGNAL(pixmapChanged()), SLOT(update()));
439 		icon.activated(false);
440 
441 		h = icon.pixmap().height();
442 
443 		QStringList str;
444 		foreach(PsiIcon::IconText t, icon.text())
445 			str += t.text;
446 
447 		if ( !str.isEmpty() )
448 			setText(str.join(", "));
449 		else
450 			setText(tr("Name: '%1'").arg(icon.name()));
451 #else
452 		Q_UNUSED( i );
453 		Q_UNUSED( iconW );
454 #endif
455 	}
456 
~IconsetDisplayItem()457 	~IconsetDisplayItem()
458 	{
459 #ifndef WIDGET_PLUGIN
460 		icon.stop();
461 #endif
462 	}
463 
height() const464 	int height() const
465 	{
466 		int hh = qMax(h + 2*margin, listWidget()->fontMetrics().lineSpacing() + 2);
467 		return qMax( hh, QApplication::globalStrut().height() );
468 	}
469 
width() const470 	int width() const
471 	{
472 		int ww = listWidget()->fontMetrics().width(text()) + w + 3*margin + 15;
473 		return qMax( ww, QApplication::globalStrut().width() );
474 	}
475 
paint(QPainter * painter) const476 	void paint(QPainter *painter) const
477 	{
478 #ifndef WIDGET_PLUGIN
479 		painter->drawPixmap(QPoint((2*margin+w - icon.pixmap().width())/2, margin), icon.pixmap());
480 #else
481 		Q_UNUSED(painter);
482 #endif
483 	}
textPosition(QPainter * painter) const484 	QPoint textPosition(QPainter *painter) const
485 	{
486 		QFontMetrics fm = painter->fontMetrics();
487 		return QPoint(w + 2*margin, fm.ascent() + (fm.leading()+1)/2 + 1);
488 	}
489 
490 };
491 const int IconsetDisplayItem::margin = 3;
492 
IconsetDisplay(QWidget * parent)493 IconsetDisplay::IconsetDisplay(QWidget *parent)
494 : QListWidget(parent)
495 {
496 	setItemDelegate(new IconWidgetDelegate(this));
497 }
498 
~IconsetDisplay()499 IconsetDisplay::~IconsetDisplay()
500 {
501 }
502 
setIconset(const Iconset & iconset)503 void IconsetDisplay::setIconset(const Iconset &iconset)
504 {
505 #ifndef WIDGET_PLUGIN
506 	int w = 0;
507 	QListIterator<PsiIcon *> it = iconset.iterator();
508 	while ( it.hasNext() ) {
509 		w = qMax(w, it.next()->pixmap().width());
510 	}
511 
512 	it = iconset.iterator();
513 	while ( it.hasNext() ) {
514 		new IconsetDisplayItem(this, it.next(), w);
515 	}
516 #else
517 	Q_UNUSED(iconset);
518 #endif
519 }
520 
521 //----------------------------------------------------------------------------
522 // IconButton
523 //----------------------------------------------------------------------------
524 
525 class IconButton::Private : public QObject
526 {
527 	Q_OBJECT
528 public:
529 	PsiIcon *icon;
530 	IconButton *button;
531 	bool textVisible;
532 	bool activate, forced;
533 #ifdef WIDGET_PLUGIN
534 	QString iconName;
535 #endif
536 
537 public:
Private(IconButton * b)538 	Private(IconButton *b)
539 	{
540 		icon = 0;
541 		button = b;
542 		textVisible = true;
543 		forced = false;
544 	}
545 
~Private()546 	~Private()
547 	{
548 		iconStop();
549 	}
550 
setIcon(PsiIcon * i)551 	void setIcon(PsiIcon *i)
552 	{
553 #ifndef WIDGET_PLUGIN
554 		iconStop();
555 		if ( i )
556 			icon = i->copy();
557 		iconStart();
558 #else
559 		Q_UNUSED(i);
560 #endif
561 	}
562 
iconStart()563 	void iconStart()
564 	{
565 #ifndef WIDGET_PLUGIN
566 		if ( icon ) {
567 			connect(icon, SIGNAL(pixmapChanged()), SLOT(iconUpdated()));
568 			if ( activate )
569 				icon->activated(true); // FIXME: should icon play sound when it's activated on button?
570 		}
571 
572 		updateIcon();
573 #endif
574 	}
575 
iconStop()576 	void iconStop()
577 	{
578 #ifndef WIDGET_PLUGIN
579 		if ( icon ) {
580 			disconnect(icon, 0, this, 0 );
581 			if ( activate )
582 				icon->stop();
583 
584 			delete icon;
585 			icon = 0;
586 		}
587 #endif
588 	}
589 
update()590 	void update()
591 	{
592 		iconUpdated();
593 	}
594 
updateIcon()595 	void updateIcon()
596 	{
597 		iconUpdated();
598 	}
599 
600 public slots:
iconUpdated()601 	void iconUpdated()
602 	{
603 		button->setUpdatesEnabled(false);
604 #ifndef WIDGET_PLUGIN
605 		button->setIcon(icon ? icon->pixmap() : QPixmap());
606 #else
607 		QPixmap pix;
608 		if (!iconName.isEmpty()) {
609 			QPixmap pix((const char **)cancel_xpm);
610 			pix = QPixmap(pix);
611 		}
612 		button->setIcon(pix);
613 #endif
614 		button->setUpdatesEnabled(true);
615 		button->update();
616 	}
617 };
618 
IconButton(QWidget * parent)619 IconButton::IconButton(QWidget *parent)
620 : QPushButton(parent)
621 {
622 	d = new Private(this);
623 }
624 
~IconButton()625 IconButton::~IconButton()
626 {
627 	delete d;
628 }
629 
setIcon(const QPixmap & p)630 void IconButton::setIcon(const QPixmap &p)
631 {
632 	QPushButton::setIcon(p);
633 }
634 
forceSetPsiIcon(const PsiIcon * i,bool activate)635 void IconButton::forceSetPsiIcon(const PsiIcon *i, bool activate)
636 {
637 	d->activate = activate;
638 	d->setIcon((PsiIcon *)i);
639 	d->forced = true;
640 }
641 
setPsiIcon(const PsiIcon * i,bool activate)642 void IconButton::setPsiIcon(const PsiIcon *i, bool activate)
643 {
644 #ifndef HAVE_X11
645 	if ( !text().isEmpty() )
646 		return;
647 #endif
648 
649 	forceSetPsiIcon(i, activate);
650 	d->forced = false;
651 }
652 
setPsiIcon(const QString & name)653 void IconButton::setPsiIcon(const QString &name)
654 {
655 #ifndef WIDGET_PLUGIN
656 	setPsiIcon( IconsetFactory::iconPtr(name) );
657 #else
658 	d->iconName = name;
659 	d->iconUpdated();
660 #endif
661 }
662 
psiIconName() const663 QString IconButton::psiIconName() const
664 {
665 #ifndef WIDGET_PLUGIN
666 	if ( d->icon )
667 		return d->icon->name();
668     return QString();
669 #else
670 	return d->iconName;
671 #endif
672 }
673 
setText(const QString & text)674 void IconButton::setText(const QString &text)
675 {
676 #ifndef HAVE_X11
677 	if ( !d->forced )
678 		setPsiIcon(0);
679 #endif
680 
681 	QPushButton::setText( text );
682 	d->updateIcon();
683 }
684 
textVisible() const685 bool IconButton::textVisible() const
686 {
687 	return d->textVisible;
688 }
689 
setTextVisible(bool v)690 void IconButton::setTextVisible(bool v)
691 {
692 	d->textVisible = v;
693 	d->updateIcon();
694 }
695 
696 //----------------------------------------------------------------------------
697 // IconToolButton
698 //----------------------------------------------------------------------------
699 
700 class IconToolButton::Private : public QObject
701 {
702 	Q_OBJECT
703 public:
704 	PsiIcon *icon;
705 	IconToolButton *button;
706 	bool activate;
707 #ifdef WIDGET_PLUGIN
708 	QString iconName;
709 #endif
710 
711 public:
Private(IconToolButton * b)712 	Private(IconToolButton *b)
713 	{
714 		icon = 0;
715 		button = b;
716 	}
717 
~Private()718 	~Private()
719 	{
720 		iconStop();
721 	}
722 
setIcon(const PsiIcon * i)723 	void setIcon(const PsiIcon *i)
724 	{
725 #ifndef WIDGET_PLUGIN
726 		iconStop();
727 		if ( i )
728 			icon = new PsiIcon(*i);
729 		iconStart();
730 #else
731 		Q_UNUSED(i);
732 #endif
733 	}
734 
iconStart()735 	void iconStart()
736 	{
737 #ifndef WIDGET_PLUGIN
738 		if ( icon ) {
739 			connect(icon, SIGNAL(pixmapChanged()), SLOT(iconUpdated()));
740 			if ( activate )
741 				icon->activated(true); // FIXME: should icon play sound when it's activated on button?
742 		}
743 		iconUpdated();
744 #endif
745 	}
746 
iconStop()747 	void iconStop()
748 	{
749 #ifndef WIDGET_PLUGIN
750 		if ( icon ) {
751 			disconnect(icon, 0, this, 0 );
752 			if ( activate )
753 				icon->stop();
754 
755 			delete icon;
756 			icon = 0;
757 		}
758 #endif
759 	}
760 
update()761 	void update()
762 	{
763 		iconUpdated();
764 	}
765 
766 private slots:
iconUpdated()767 	void iconUpdated()
768 	{
769 		button->setUpdatesEnabled(false);
770 #ifndef WIDGET_PLUGIN
771 		QPixmap pix = icon ? icon->pixmap() : QPixmap();
772 		if (pix.isNull())
773 			button->QToolButton::setIcon(QIcon());
774 		else
775 			button->QToolButton::setIcon(pix);
776 		button->setIcon(icon ? icon->pixmap() : QPixmap());
777 #else
778 		button->setIcon(QPixmap());
779 #endif
780 		button->setUpdatesEnabled(true);
781 		button->update();
782 	}
783 };
784 
IconToolButton(QWidget * parent)785 IconToolButton::IconToolButton(QWidget *parent)
786 : QToolButton(parent)
787 {
788 	d = new Private(this);
789 }
790 
~IconToolButton()791 IconToolButton::~IconToolButton()
792 {
793 	delete d;
794 }
795 
setIcon(const QIcon & p)796 void IconToolButton::setIcon(const QIcon &p)
797 {
798 	QToolButton::setIcon(p);
799 }
800 
setPsiIcon(const PsiIcon * i,bool activate)801 void IconToolButton::setPsiIcon(const PsiIcon *i, bool activate)
802 {
803 	d->activate = activate;
804 	d->setIcon ((PsiIcon *)i);
805 }
806 
setPsiIcon(const QString & name)807 void IconToolButton::setPsiIcon(const QString &name)
808 {
809 #ifndef WIDGET_PLUGIN
810 	setPsiIcon( IconsetFactory::iconPtr(name) );
811 #else
812 	d->iconName = name;
813 #endif
814 }
815 
psiIconName() const816 QString IconToolButton::psiIconName() const
817 {
818 #ifndef WIDGET_PLUGIN
819 	if ( d->icon )
820 		return d->icon->name();
821     return QString();
822 #else
823 	return d->iconName;
824 #endif
825 }
826 
paintEvent(QPaintEvent * event)827 void IconToolButton::paintEvent(QPaintEvent* event)
828 {
829 	setToolButtonStyle(icon().isNull() ?
830 	                   Qt::ToolButtonTextOnly :
831 	                   Qt::ToolButtonIconOnly);
832 	QToolButton::paintEvent(event);
833 }
834 
835 #include "iconwidget.moc"
836