source: trunk/src/gui/widgets/qtoolbox.cpp@ 500

Last change on this file since 500 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 21.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qtoolbox.h"
43
44#ifndef QT_NO_TOOLBOX
45
46#include <qapplication.h>
47#include <qeventloop.h>
48#include <qlayout.h>
49#include <qlist.h>
50#include <qpainter.h>
51#include <qscrollarea.h>
52#include <qstyle.h>
53#include <qstyleoption.h>
54#include <qtooltip.h>
55#include <qabstractbutton.h>
56
57#include "qframe_p.h"
58
59QT_BEGIN_NAMESPACE
60
61class QToolBoxButton : public QAbstractButton
62{
63 Q_OBJECT
64public:
65 QToolBoxButton(QWidget *parent)
66 : QAbstractButton(parent), selected(false), indexInPage(-1)
67 {
68 setBackgroundRole(QPalette::Window);
69 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
70 setFocusPolicy(Qt::NoFocus);
71 }
72
73 inline void setSelected(bool b) { selected = b; update(); }
74 inline void setIndex(int newIndex) { indexInPage = newIndex; }
75
76 QSize sizeHint() const;
77 QSize minimumSizeHint() const;
78
79protected:
80 void initStyleOption(QStyleOptionToolBox *opt) const;
81 void paintEvent(QPaintEvent *);
82
83private:
84 bool selected;
85 int indexInPage;
86};
87
88
89class QToolBoxPrivate : public QFramePrivate
90{
91 Q_DECLARE_PUBLIC(QToolBox)
92public:
93 struct Page
94 {
95 QToolBoxButton *button;
96 QScrollArea *sv;
97 QWidget *widget;
98
99 inline void setText(const QString &text) { button->setText(text); }
100 inline void setIcon(const QIcon &is) { button->setIcon(is); }
101#ifndef QT_NO_TOOLTIP
102 inline void setToolTip(const QString &tip) { button->setToolTip(tip); }
103 inline QString toolTip() const { return button->toolTip(); }
104#endif
105 inline QString text() const { return button->text(); }
106 inline QIcon icon() const { return button->icon(); }
107
108 inline bool operator==(const Page& other) const
109 {
110 return widget == other.widget;
111 }
112 };
113 typedef QList<Page> PageList;
114
115 inline QToolBoxPrivate()
116 : currentPage(0)
117 {
118 }
119 void _q_buttonClicked();
120 void _q_widgetDestroyed(QObject*);
121
122 Page *page(QWidget *widget) const;
123 const Page *page(int index) const;
124 Page *page(int index);
125
126 void updateTabs();
127 void relayout();
128
129 PageList pageList;
130 QVBoxLayout *layout;
131 Page *currentPage;
132};
133
134QToolBoxPrivate::Page *QToolBoxPrivate::page(QWidget *widget) const
135{
136 if (!widget)
137 return 0;
138
139 for (PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i)
140 if ((*i).widget == widget)
141 return (Page*) &(*i);
142 return 0;
143}
144
145QToolBoxPrivate::Page *QToolBoxPrivate::page(int index)
146{
147 if (index >= 0 && index < pageList.size())
148 return &pageList[index];
149 return 0;
150}
151
152const QToolBoxPrivate::Page *QToolBoxPrivate::page(int index) const
153{
154 if (index >= 0 && index < pageList.size())
155 return &pageList.at(index);
156 return 0;
157}
158
159void QToolBoxPrivate::updateTabs()
160{
161 QToolBoxButton *lastButton = currentPage ? currentPage->button : 0;
162 bool after = false;
163 int index = 0;
164 for (index = 0; index < pageList.count(); ++index) {
165 const Page &page = pageList.at(index);
166 QToolBoxButton *tB = page.button;
167 // update indexes, since the updates are delayed, the indexes will be correct
168 // when we actually paint.
169 tB->setIndex(index);
170 QWidget *tW = page.widget;
171 if (after) {
172 QPalette p = tB->palette();
173 p.setColor(tB->backgroundRole(), tW->palette().color(tW->backgroundRole()));
174 tB->setPalette(p);
175 tB->update();
176 } else if (tB->backgroundRole() != QPalette::Window) {
177 tB->setBackgroundRole(QPalette::Window);
178 tB->update();
179 }
180 after = tB == lastButton;
181 }
182}
183
184QSize QToolBoxButton::sizeHint() const
185{
186 QSize iconSize(8, 8);
187 if (!icon().isNull()) {
188 int icone = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, parentWidget() /* QToolBox */);
189 iconSize += QSize(icone + 2, icone);
190 }
191 QSize textSize = fontMetrics().size(Qt::TextShowMnemonic, text()) + QSize(0, 8);
192
193 QSize total(iconSize.width() + textSize.width(), qMax(iconSize.height(), textSize.height()));
194 return total.expandedTo(QApplication::globalStrut());
195}
196
197QSize QToolBoxButton::minimumSizeHint() const
198{
199 if (icon().isNull())
200 return QSize();
201 int icone = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, parentWidget() /* QToolBox */);
202 return QSize(icone + 8, icone + 8);
203}
204
205void QToolBoxButton::initStyleOption(QStyleOptionToolBox *option) const
206{
207 if (!option)
208 return;
209 option->initFrom(this);
210 if (selected)
211 option->state |= QStyle::State_Selected;
212 if (isDown())
213 option->state |= QStyle::State_Sunken;
214 option->text = text();
215 option->icon = icon();
216
217 if (QStyleOptionToolBoxV2 *optionV2 = qstyleoption_cast<QStyleOptionToolBoxV2 *>(option)) {
218 QToolBox *toolBox = static_cast<QToolBox *>(parentWidget()); // I know I'm in a tool box.
219 int widgetCount = toolBox->count();
220 int currIndex = toolBox->currentIndex();
221 if (widgetCount == 1) {
222 optionV2->position = QStyleOptionToolBoxV2::OnlyOneTab;
223 } else if (indexInPage == 0) {
224 optionV2->position = QStyleOptionToolBoxV2::Beginning;
225 } else if (indexInPage == widgetCount - 1) {
226 optionV2->position = QStyleOptionToolBoxV2::End;
227 } else {
228 optionV2->position = QStyleOptionToolBoxV2::Middle;
229 }
230 if (currIndex == indexInPage - 1) {
231 optionV2->selectedPosition = QStyleOptionToolBoxV2::PreviousIsSelected;
232 } else if (currIndex == indexInPage + 1) {
233 optionV2->selectedPosition = QStyleOptionToolBoxV2::NextIsSelected;
234 } else {
235 optionV2->selectedPosition = QStyleOptionToolBoxV2::NotAdjacent;
236 }
237 }
238}
239
240void QToolBoxButton::paintEvent(QPaintEvent *)
241{
242 QPainter paint(this);
243 QString text = QAbstractButton::text();
244 QPainter *p = &paint;
245 QStyleOptionToolBoxV2 opt;
246 initStyleOption(&opt);
247 style()->drawControl(QStyle::CE_ToolBoxTab, &opt, p, parentWidget());
248}
249
250/*!
251 \class QToolBox
252
253 \brief The QToolBox class provides a column of tabbed widget items.
254
255 \mainclass
256 \ingroup basicwidgets
257
258 A toolbox is a widget that displays a column of tabs one above the
259 other, with the current item displayed below the current tab.
260 Every tab has an index position within the column of tabs. A tab's