1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the widgets module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
33
#include <qapplication.h>
34
#include <qeventloop.h>
38
#include <qscrollarea.h>
40
#include <qstyleoption.h>
42
#include <qabstractbutton.h>
46
class QToolBoxButton : public QAbstractButton
50
QToolBoxButton(QWidget *parent)
51
: QAbstractButton(parent), selected(false)
53
setBackgroundRole(QPalette::Background);
54
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
55
setFocusPolicy(Qt::NoFocus);
58
inline void setSelected(bool b) { selected = b; update(); }
60
QSize sizeHint() const;
61
QSize minimumSizeHint() const;
64
void paintEvent(QPaintEvent *);
70
#include "qtoolbox.moc"
73
class QToolBoxPrivate : public QFramePrivate
75
Q_DECLARE_PUBLIC(QToolBox)
79
QToolBoxButton *button;
83
inline void setText(const QString &text) { button->setText(text); }
84
inline void setIcon(const QIcon &is) { button->setIcon(is); }
85
inline void setToolTip(const QString &tip) { button->setToolTip(tip); }
86
inline QString text() const { return button->text(); }
87
inline QIcon icon() const { return button->icon(); }
88
inline QString toolTip() const { return button->toolTip(); }
90
inline bool operator==(const Page& other) const
92
return widget == other.widget;
95
typedef QList<Page> PageList;
97
inline QToolBoxPrivate()
101
void buttonClicked();
102
void widgetDestroyed(QObject*);
104
Page *page(QWidget *widget) const;
105
const Page *page(int index) const;
106
Page *page(int index);
116
QToolBoxPrivate::Page *QToolBoxPrivate::page(QWidget *widget) const
121
for (PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i)
122
if ((*i).widget == widget)
123
return (Page*) &(*i);
127
QToolBoxPrivate::Page *QToolBoxPrivate::page(int index)
129
if (index >= 0 && index < pageList.size())
130
return &pageList[index];
134
const QToolBoxPrivate::Page *QToolBoxPrivate::page(int index) const
136
if (index >= 0 && index < pageList.size())
137
return &pageList.at(index);
141
void QToolBoxPrivate::updateTabs()
143
QToolBoxButton *lastButton = currentPage ? currentPage->button : 0;
145
for (PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i) {
146
QToolBoxButton *tB = (*i).button;
147
QWidget *tW = (*i).widget;
149
QPalette p = tB->palette();
150
p.setColor(tB->backgroundRole(), tW->palette().color(tW->backgroundRole()));
153
} else if (tB->backgroundRole() != QPalette::Background) {
154
tB->setBackgroundRole(QPalette::Background);
157
after = (*i).button == lastButton;
161
QSize QToolBoxButton::sizeHint() const
163
QSize iconSize(8, 8);
164
if (!icon().isNull()) {
165
int icone = style()->pixelMetric(QStyle::PM_SmallIconSize);
166
iconSize += QSize(icone + 2, icone);
168
QSize textSize = fontMetrics().size(Qt::TextShowMnemonic, text()) + QSize(0, 8);
170
QSize total(iconSize.width() + textSize.width(), qMax(iconSize.height(), textSize.height()));
171
return total.expandedTo(QApplication::globalStrut());
174
QSize QToolBoxButton::minimumSizeHint() const
178
int icone = style()->pixelMetric(QStyle::PM_SmallIconSize);
179
return QSize(icone + 8, icone + 8);
182
void QToolBoxButton::paintEvent(QPaintEvent *)
184
QPainter paint(this);
185
QString text = QAbstractButton::text();
186
QPainter *p = &paint;
187
const QPalette &pal = palette();
188
QStyleOptionToolBox opt;
191
opt.state |= QStyle::State_Selected;
193
opt.state |= QStyle::State_Sunken;
196
style()->drawControl(QStyle::CE_ToolBoxTab, &opt, p, parentWidget());
198
QPixmap pm = icon().pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize), isEnabled() ? QIcon::Normal : QIcon::Disabled);
200
QRect cr = style()->subElementRect(QStyle::SE_ToolBoxTabContents, &opt, this);
205
tr.adjust(4, 0, -8, 0);
207
int iw = pm.width() + 4;
209
ir = QRect(cr.left() + 4, cr.top(), iw + 2, ih);
210
tr = QRect(ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height());
213
if (selected && style()->styleHint(QStyle::SH_ToolBox_SelectedPageTitleBold, &opt, this)) {
220
if (p->fontMetrics().width(text) < tr.width()) {
224
int ew = p->fontMetrics().width("...");
226
while (p->fontMetrics().width(txt) + ew +
227
p->fontMetrics().width(text[i]) < tr.width())
233
p->drawPixmap(ir.left(), (height() - ih) / 2, pm);
235
int alignment = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic;
236
if (!style()->styleHint(QStyle::SH_UnderlineShortcut, 0, this))
237
alignment |= Qt::TextHideMnemonic;
238
style()->drawItemText(p, tr, alignment, pal, isEnabled(), txt, foregroundRole());
240
if (!txt.isEmpty() && hasFocus()) {
241
QStyleOptionFocusRect opt;
244
opt.state = QStyle::State_None;
245
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, this);
252
\brief The QToolBox class provides a column of tabbed widget items.
257
A toolbox is a widget that displays a column of tabs one above the
258
other, with the current item displayed below the current tab.
259
Every tab has an index position within the column of tabs. A tab's
262
Each item has an itemText(), an optional itemIcon(), an optional
263
itemToolTip(), and a widget(). The item's attributes can be
264
changed with setItemText(), setItemIcon(), and
265
setItemToolTip(). Each item can be enabled or disabled
266
individually with setItemEnabled().
268
Items are added using addItem(), or inserted at particular
269
positions using insertItem(). The total number of items is given
270
by count(). Items can be deleted with delete, or removed from the
271
toolbox with removeItem(). Combining removeItem() and insertItem()
272
allows you to move items to different positions.
274
The index of the current item widget is returned by currentIndex(),
275
and set with setCurrentIndex(). The index of a particular item can
276
be found using indexOf(), and the item at a given index is returned
279
The currentChanged() signal is emitted when the current item is
286
\fn void QToolBox::currentChanged(int index)
288
This signal is emitted when the current item is changed. The new
289
current item's index is passed in \a index, or -1 if there is no
295
Constructs a toolbox called \a name with parent \a parent and flags \a f.
297
QToolBox::QToolBox(QWidget *parent, const char *name, Qt::WFlags f)
298
: QFrame(*new QToolBoxPrivate, parent, f)
302
d->layout = new QVBoxLayout(this);
303
d->layout->setMargin(0);
304
setBackgroundRole(QPalette::Button);
309
Constructs a new toolbox with the given \a parent and the flags, \a f.
311
QToolBox::QToolBox(QWidget *parent, Qt::WFlags f)
312
: QFrame(*new QToolBoxPrivate, parent, f)
315
d->layout = new QVBoxLayout(this);
316
d->layout->setMargin(0);
317
setBackgroundRole(QPalette::Button);
321
Destroys the toolbox.
324
QToolBox::~QToolBox()
329
\fn int QToolBox::addItem(QWidget *w, const QString &text)
332
Adds the widget \a w in a new tab at bottom of the toolbox. The
333
new tab's text is set to \a text. Returns the new tab's index.
337
\fn int QToolBox::addItem(QWidget *widget, const QIcon &iconSet,const QString &text)
338
Adds the \a widget in a new tab at bottom of the toolbox. The
339
new tab's text is set to \a text, and the \a iconSet is
340
displayed to the left of the \a text. Returns the new tab's index.
344
\fn int QToolBox::insertItem(int index, QWidget *widget, const QString &text)
347
Inserts the \a widget at position \a index, or at the bottom
348
of the toolbox if \a index is out of range. The new item's text is
349
set to \a text. Returns the new item's index.
353
Inserts the \a widget at position \a index, or at the bottom
354
of the toolbox if \a index is out of range. The new item's text
355
is set to \a text, and the \a icon is displayed to the left of
356
the \a text. Returns the new item's index.
359
int QToolBox::insertItem(int index, QWidget *widget, const QIcon &icon, const QString &text)
365
connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(widgetDestroyed(QObject*)));
367
QToolBoxPrivate::Page c;
369
c.button = new QToolBoxButton(this);
370
connect(c.button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
372
c.sv = new QScrollArea(this);
373
c.sv->setWidget(widget);
374
c.sv->setWidgetResizable(true);
376
c.sv->setFrameStyle(QFrame::NoFrame);
381
if (index < 0 || index >= (int)d->pageList.count()) {
382
index = d->pageList.count();
383
d->pageList.append(c);
384
d->layout->addWidget(c.button);
385
d->layout->addWidget(c.sv);
387
setCurrentIndex(index);
389
d->pageList.insert(index, c);
391
if (d->currentPage) {
392
QWidget *current = d->currentPage->widget;
393
int oldindex = indexOf(current);
394
if (index <= oldindex) {
395
d->currentPage = 0; // trigger change
396
setCurrentIndex(oldindex);
408
void QToolBoxPrivate::buttonClicked()
411
QToolBoxButton *tb = ::qobject_cast<QToolBoxButton*>(q->sender());
413
for (QToolBoxPrivate::PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i)
414
if ((*i).button == tb) {
419
q->setCurrentIndex(q->indexOf(item));
423
\property QToolBox::count
424
\brief The number of items contained in the toolbox.
427
int QToolBox::count() const
430
return d->pageList.count();
433
void QToolBox::setCurrentIndex(int index)
436
QToolBoxPrivate::Page *c = d->page(index);
437
if (!c || d->currentPage == c)
440
c->button->setSelected(true);
441
if (d->currentPage) {
442
d->currentPage->sv->hide();
443
d->currentPage->button->setSelected(false);
446
d->currentPage->sv->show();
448
emit currentChanged(index);
451
void QToolBoxPrivate::relayout()
455
layout = new QVBoxLayout(q);
456
for (QToolBoxPrivate::PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i) {
457
layout->addWidget((*i).button);
458
layout->addWidget((*i).sv);
462
void QToolBoxPrivate::widgetDestroyed(QObject *object)
465
// no verification - vtbl corrupted already
466
QWidget *p = (QWidget*)object;
468
QToolBoxPrivate::Page *c = page(p);
472
layout->removeWidget(c->sv);
473
layout->removeWidget(c->button);
474
c->sv->deleteLater(); // page might still be a child of sv
477
bool removeCurrent = c == currentPage;
478
pageList.removeAll(*c);
480
if (!pageList.count()) {
482
emit q->currentChanged(-1);
483
} else if (removeCurrent) {
485
q->setCurrentIndex(0);
490
Removes the item at position \a index from the toolbox. Note that
491
the widget is \e not deleted.
494
void QToolBox::removeItem(int index)
497
if (QWidget *w = widget(index)) {
498
disconnect(w, SIGNAL(destroyed(QObject*)), this, SLOT(widgetDestroyed(QObject*)));
500
// destroy internal data
501
d->widgetDestroyed(w);
508
\property QToolBox::currentIndex
509
\brief The index of the current item, or -1 if the toolbox is empty.
511
\sa indexOf(), widget()
515
int QToolBox::currentIndex() const
518
return d->currentPage ? indexOf(d->currentPage->widget) : -1;
522
Returns a pointer to the current widget, or 0 if there is no such item.
524
\sa currentIndex(), setCurrentWidget()
527
QWidget * QToolBox::currentWidget() const
530
return d->currentPage ? d->currentPage->widget : 0;
534
Makes\a widget the current widget. The \a widget must be an item in this tool box.
536
\sa addItem(), setCurrentIndex(), currentWidget()
538
void QToolBox::setCurrentWidget(QWidget *widget)
540
Q_ASSERT_X(indexOf(widget) >= 0, "QToolBox::setCurrentWidget", "widget not contained in tool box");
541
setCurrentIndex(indexOf(widget));
545
Returns the widget at position \a index, or 0 if there is no such
549
QWidget *QToolBox::widget(int index) const
552
if (index < 0 || index >= (int) d->pageList.size())
554
return d->pageList.at(index).widget;
558
Returns the index of \a widget, or -1 if the item does not
562
int QToolBox::indexOf(QWidget *widget) const
565
QToolBoxPrivate::Page *c = d->page(widget);
566
return c ? d->pageList.indexOf(*c) : -1;
570
If \a enabled is true then the item at position \a index is enabled; otherwise
571
the item at position \a index is disabled.
574
void QToolBox::setItemEnabled(int index, bool enabled)
577
QToolBoxPrivate::Page *c = d->page(index);
581
c->button->setEnabled(enabled);
582
if (!enabled && c == d->currentPage) {
583
int curIndexUp = index;
584
int curIndexDown = curIndexUp;
585
const int count = d->pageList.count();
586
while (curIndexUp > 0 || curIndexDown < count-1) {
587
if (curIndexDown < count-1) {
588
if (d->page(++curIndexDown)->button->isEnabled()) {
589
index = curIndexDown;
593
if (curIndexUp > 0) {
594
if (d->page(--curIndexUp)->button->isEnabled()) {
600
setCurrentIndex(index);
606
Sets the text of the item at position \a index to \a text.
609
void QToolBox::setItemText(int index, const QString &text)
612
QToolBoxPrivate::Page *c = d->page(index);
618
Sets the icon of the item at position \a index to \a icon.
621
void QToolBox::setItemIcon(int index, const QIcon &icon)
624
QToolBoxPrivate::Page *c = d->page(index);
630
Sets the tooltip of the item at position \a index to \a toolTip.
633
void QToolBox::setItemToolTip(int index, const QString &toolTip)
636
QToolBoxPrivate::Page *c = d->page(index);
638
c->setToolTip(toolTip);
642
Returns true if the item at position \a index is enabled; otherwise returns false.
645
bool QToolBox::isItemEnabled(int index) const
648
const QToolBoxPrivate::Page *c = d->page(index);
649
return c && c->button->isEnabled();
653
Returns the text of the item at position \a index, or an empty string if
654
\a index is out of range.
657
QString QToolBox::itemText(int index) const
660
const QToolBoxPrivate::Page *c = d->page(index);
661
return (c ? c->text() : QString());
665
Returns the icon of the item at position \a index, or a null
666
icon if \a index is out of range.
669
QIcon QToolBox::itemIcon(int index) const
672
const QToolBoxPrivate::Page *c = d->page(index);
673
return (c ? c->icon() : QIcon());
677
Returns the tooltip of the item at position \a index, or an
678
empty string if \a index is out of range.
681
QString QToolBox::itemToolTip(int index) const
684
const QToolBoxPrivate::Page *c = d->page(index);
685
return (c ? c->toolTip() : QString());
689
void QToolBox::showEvent(QShowEvent *e)
691
QWidget::showEvent(e);
695
void QToolBox::changeEvent(QEvent *ev)
698
if(ev->type() == QEvent::StyleChange)
700
QFrame::changeEvent(ev);
704
This virtual handler is called after a new item was added or
705
inserted at position \a index.
709
void QToolBox::itemInserted(int index)
715
This virtual handler is called after an item was removed from
720
void QToolBox::itemRemoved(int index)
726
\fn void QToolBox::setItemLabel(int index, const QString &text)
728
Use setItemText() instead.
732
\fn QString QToolBox::itemLabel(int index) const
734
Use itemText() instead.
738
\fn QWidget *QToolBox::currentItem() const
740
Use widget(currentIndex()) instead.
744
\fn void QToolBox::setCurrentItem(QWidget *widget)
746
Use setCurrentIndex(indexOf(widget)) instead.
750
\fn void QToolBox::setItemIconSet(int index, const QIcon &icon)
752
Use setItemIcon() instead.
756
\fn QIcon QToolBox::itemIconSet(int index) const
758
Use itemIcon() instead.
762
\fn int QToolBox::removeItem(QWidget *widget)
764
Use toolbox->removeItem(toolbox->indexOf(widget)) instead.
768
\fn QWidget *QToolBox::item(int index) const
770
Use widget() instead.
774
#include "moc_qtoolbox.cpp"
776
#endif //QT_NO_TOOLBOX