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 Qt3Support 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 "q3toolbar.h"
|
---|
43 | #ifndef QT_NO_TOOLBAR
|
---|
44 |
|
---|
45 | #include "q3mainwindow.h"
|
---|
46 | #include "qapplication.h"
|
---|
47 | #include "q3combobox.h"
|
---|
48 | #include "qcursor.h"
|
---|
49 | #include "qdesktopwidget.h"
|
---|
50 | #include "qdrawutil.h"
|
---|
51 | #include "qevent.h"
|
---|
52 | #include "qframe.h"
|
---|
53 | #include "qlayout.h"
|
---|
54 | #include "qmap.h"
|
---|
55 | #include "qpainter.h"
|
---|
56 | #include "q3popupmenu.h"
|
---|
57 | #include "qstyle.h"
|
---|
58 | #include "qstyleoption.h"
|
---|
59 | #include "qtimer.h"
|
---|
60 | #include "qtoolbutton.h"
|
---|
61 | #include "qtooltip.h"
|
---|
62 |
|
---|
63 | QT_BEGIN_NAMESPACE
|
---|
64 |
|
---|
65 | static const char * const arrow_v_xpm[] = {
|
---|
66 | "7 9 3 1",
|
---|
67 | " c None",
|
---|
68 | ". c #000000",
|
---|
69 | "+ c none",
|
---|
70 | ".+++++.",
|
---|
71 | "..+++..",
|
---|
72 | "+..+..+",
|
---|
73 | "++...++",
|
---|
74 | ".++.++.",
|
---|
75 | "..+++..",
|
---|
76 | "+..+..+",
|
---|
77 | "++...++",
|
---|
78 | "+++.+++"};
|
---|
79 |
|
---|
80 | static const char * const arrow_h_xpm[] = {
|
---|
81 | "9 7 3 1",
|
---|
82 | " c None",
|
---|
83 | ". c #000000",
|
---|
84 | "+ c none",
|
---|
85 | "..++..+++",
|
---|
86 | "+..++..++",
|
---|
87 | "++..++..+",
|
---|
88 | "+++..++..",
|
---|
89 | "++..++..+",
|
---|
90 | "+..++..++",
|
---|
91 | "..++..+++"};
|
---|
92 |
|
---|
93 | class Q3ToolBarExtensionWidget;
|
---|
94 |
|
---|
95 | class Q3ToolBarPrivate
|
---|
96 | {
|
---|
97 | public:
|
---|
98 | Q3ToolBarPrivate() : moving(false), checkingExtension(false) {
|
---|
99 | }
|
---|
100 |
|
---|
101 | bool moving;
|
---|
102 | bool checkingExtension;
|
---|
103 | Q3ToolBarExtensionWidget *extension;
|
---|
104 | Q3PopupMenu *extensionPopup;
|
---|
105 |
|
---|
106 | QMap<QAction *, QWidget *> actions;
|
---|
107 | };
|
---|
108 |
|
---|
109 |
|
---|
110 | class Q3ToolBarSeparator : public QWidget
|
---|
111 | {
|
---|
112 | Q_OBJECT
|
---|
113 | public:
|
---|
114 | Q3ToolBarSeparator(Qt::Orientation, Q3ToolBar *parent, const char* name=0);
|
---|
115 |
|
---|
116 | QSize sizeHint() const;
|
---|
117 | Qt::Orientation orientation() const { return orient; }
|
---|
118 | public slots:
|
---|
119 | void setOrientation(Qt::Orientation);
|
---|
120 | protected:
|
---|
121 | void changeEvent(QEvent *);
|
---|
122 | void paintEvent(QPaintEvent *);
|
---|
123 |
|
---|
124 | private:
|
---|
125 | Qt::Orientation orient;
|
---|
126 | };
|
---|
127 |
|
---|
128 | class Q3ToolBarExtensionWidget : public QWidget
|
---|
129 | {
|
---|
130 | Q_OBJECT
|
---|
131 |
|
---|
132 | public:
|
---|
133 | Q3ToolBarExtensionWidget(QWidget *w);
|
---|
134 | void setOrientation(Qt::Orientation o);
|
---|
135 | QToolButton *button() const { return tb; }
|
---|
136 |
|
---|
137 | protected:
|
---|
138 | void resizeEvent(QResizeEvent *e) {
|
---|
139 | QWidget::resizeEvent(e);
|
---|
140 | layOut();
|
---|
141 | }
|
---|
142 |
|
---|
143 | private:
|
---|
144 | void layOut();
|
---|
145 | QToolButton *tb;
|
---|
146 | Qt::Orientation orient;
|
---|
147 |
|
---|
148 | };
|
---|
149 |
|
---|
150 | Q3ToolBarExtensionWidget::Q3ToolBarExtensionWidget(QWidget *w)
|
---|
151 | : QWidget(w, "qt_dockwidget_internal")
|
---|
152 | {
|
---|
153 | tb = new QToolButton(this, "qt_toolbar_ext_button");
|
---|
154 | tb->setAutoRaise(true);
|
---|
155 | setOrientation(Qt::Horizontal);
|
---|
156 | setAutoFillBackground(true);
|
---|
157 | }
|
---|
158 |
|
---|
159 | void Q3ToolBarExtensionWidget::setOrientation(Qt::Orientation o)
|
---|
160 | {
|
---|
161 | orient = o;
|
---|
162 | if (orient == Qt::Horizontal)
|
---|
163 | tb->setIcon(QPixmap((const char **)arrow_h_xpm));
|
---|
164 | else
|
---|
165 | tb->setIcon(QPixmap((const char **)arrow_v_xpm));
|
---|
166 | layOut();
|
---|
167 | }
|
---|
168 |
|
---|
169 | void Q3ToolBarExtensionWidget::layOut()
|
---|
170 | {
|
---|
171 | tb->setGeometry(2, 2, width() - 4, height() - 4);
|
---|
172 | }
|
---|
173 |
|
---|
174 | Q3ToolBarSeparator::Q3ToolBarSeparator(Qt::Orientation o , Q3ToolBar *parent,
|
---|
175 | const char* name)
|
---|
176 | : QWidget(parent, name)
|
---|
177 | {
|
---|
178 | connect(parent, SIGNAL(orientationChanged(Qt::Orientation)),
|
---|
179 | this, SLOT(setOrientation(Qt::Orientation)));
|
---|
180 | setOrientation(o);
|
---|
181 | setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
|
---|
182 | }
|
---|
183 |
|
---|
184 |
|
---|
185 |
|
---|
186 | void Q3ToolBarSeparator::setOrientation(Qt::Orientation o)
|
---|
187 | {
|
---|
188 | orient = o;
|
---|
189 | }
|
---|
190 |
|
---|
191 | void Q3ToolBarSeparator::changeEvent(QEvent *ev)
|
---|
192 | {
|
---|
193 | if(ev->type() == QEvent::StyleChange)
|
---|
194 | setOrientation(orient);
|
---|
195 | QWidget::changeEvent(ev);
|
---|
196 | }
|
---|
197 |
|
---|
198 | static QStyleOption getStyleOption(const Q3ToolBarSeparator *tbs)
|
---|
199 | {
|
---|
200 | QStyleOption opt(0);
|
---|
201 | opt.rect = tbs->rect();
|
---|
202 | opt.palette = tbs->palette();
|
---|
203 | if (tbs->orientation() == Qt::Horizontal)
|
---|
204 | opt.state = QStyle::State_Horizontal;
|
---|
205 | else
|
---|
206 | opt.state = QStyle::State_None;
|
---|
207 | return opt;
|
---|
208 | }
|
---|
209 |
|
---|
210 | QSize Q3ToolBarSeparator::sizeHint() const
|
---|
211 | {
|
---|
212 | QStyleOption opt = getStyleOption(this);
|
---|
213 | int extent = style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, this);
|
---|
214 | if (orient == Qt::Horizontal)
|
---|
215 | return QSize(extent, 0);
|
---|
216 | else
|
---|
217 | return QSize(0, extent);
|
---|
218 | }
|
---|
219 |
|
---|
220 | void Q3ToolBarSeparator::paintEvent(QPaintEvent *)
|
---|
221 | {
|
---|
222 | QPainter p(this);
|
---|
223 | QStyleOption opt = getStyleOption(this);
|
---|
224 | style()->drawPrimitive(QStyle::PE_Q3DockWindowSeparator, &opt, &p, this);
|
---|
225 | }
|
---|
226 |
|
---|
227 | QT_BEGIN_INCLUDE_NAMESPACE
|
---|
228 | #include "q3toolbar.moc"
|
---|
229 | QT_END_INCLUDE_NAMESPACE
|
---|
230 |
|
---|
231 |
|
---|
232 | /*!
|
---|
233 | \class Q3ToolBar
|
---|
234 | \brief The Q3ToolBar class provides a movable panel containing
|
---|
235 | widgets such as tool buttons.
|
---|
236 |
|
---|
237 | \compat
|
---|
238 |
|
---|
239 | A toolbar is a panel that contains a set of controls, usually
|
---|
240 | represented by small icons. It's purpose is to provide quick
|
---|
241 | access to frequently used commands or options. Within a
|
---|
242 | Q3MainWindow the user can drag toolbars within and between the
|
---|
243 | \link Q3DockArea dock areas\endlink. Toolbars can also be dragged
|
---|
244 | out of any dock area to float freely as top-level windows.
|
---|
245 |
|
---|
246 | Q3ToolBar is a specialization of QDockWindow, and so provides all
|
---|
247 | the functionality of a QDockWindow.
|
---|
248 |
|
---|
249 | To use Q3ToolBar you simply create a Q3ToolBar as a child of a
|
---|
250 | Q3MainWindow, create a number of QToolButton widgets (or other
|
---|
251 | widgets) in left to right (or top to bottom) order and call
|
---|
252 | addSeparator() when you want a separator. When a toolbar is
|
---|
253 | floated the caption used is the label given in the constructor
|
---|
254 | call. This can be changed with setLabel().
|
---|
255 |
|
---|
256 | You may use most widgets within a toolbar, with QToolButton and
|
---|
257 | QComboBox being the most common. But note that the toolbar's
|
---|
258 | actions must be \l {Q3Action}s.
|
---|
259 |
|
---|
260 | If you create a new widget on an already visible Q3ToolBar, this
|
---|
261 | widget will automatically become visible without needing a show()
|
---|
262 | call. (This differs from every other Qt widget container. We
|
---|
263 | recommend calling show() anyway since we hope to fix this anomaly
|
---|
264 | in a future release.)
|
---|
265 |
|
---|
266 | Q3ToolBars, like QDockWindows, are located in \l{Q3DockArea}s or
|
---|
267 | float as top-level windows. Q3MainWindow provides four Q3DockAreas
|
---|
268 | (top, left, right and bottom). When you create a new toolbar (as
|
---|
269 | in the example above) as a child of a Q3MainWindow the toolbar will
|
---|
270 | be added to the top dock area. You can move it to another dock
|
---|
271 | area (or float it) by calling Q3MainWindow::moveDockWindow(). Dock
|
---|
272 | areas lay out their windows in lines.
|
---|
273 |
|
---|
274 | If the main window is resized so that the area occupied by the
|
---|
275 | toolbar is too small to show all its widgets a little arrow button
|
---|
276 | (which looks like a right-pointing chevron, '»') will appear
|
---|
277 | at the right or bottom of the toolbar depending on its
|
---|
278 | orientation. Clicking this button pops up a menu that shows the
|
---|
279 | 'overflowing' items. QToolButtons are represented in the menu using
|
---|
280 | their textLabel property, other QAbstractButton subclasses are represented
|
---|
281 | using their text property, and QComboBoxes are represented as submenus,
|
---|
282 | with the caption text being used in the submenu item.
|
---|
283 |
|
---|
284 | Usually a toolbar will get precisely the space it needs. However,
|
---|
285 | with setHorizontalStretchable(), setVerticalStretchable() or
|
---|
286 | setStretchableWidget() you can tell the main window to expand the
|
---|
287 | toolbar to fill all available space in the specified orientation.
|
---|
288 |
|
---|
289 | The toolbar arranges its buttons either horizontally or vertically
|
---|
290 | (see orientation() for details). Generally, Q3DockArea will set the
|
---|
291 | orientation correctly for you, but you can set it yourself with
|
---|
292 | setOrientation() and track any changes by connecting to the
|
---|
293 | orientationChanged() signal.
|
---|
294 |
|
---|
295 | You can use the clear() method to remove all items from a toolbar.
|
---|
296 |
|
---|
297 | \img qdockwindow.png Toolbar (dock window)
|
---|
298 | \caption A floating QToolbar (dock window)
|
---|
299 |
|
---|
300 | \sa QToolButton Q3MainWindow
|
---|
301 | */
|
---|
302 |
|
---|
303 | /*!
|
---|
304 | Constructs an empty toolbar.
|
---|
305 |
|
---|
306 | The toolbar is called \a name and is a child of \a parent and is
|
---|
307 | managed by \a parent. It is initially located in dock area \a dock
|
---|
308 | and is labeled \a label. If \a newLine is true the toolbar will be
|
---|
309 | placed on a new line in the dock area.
|
---|
310 | */
|
---|
311 |
|
---|
312 | Q3ToolBar::Q3ToolBar(const QString &label,
|
---|
313 | Q3MainWindow * parent, Qt::ToolBarDock dock,
|
---|
314 | bool newLine, const char * name)
|
---|
315 | : Q3DockWindow(InDock, parent, name, 0, true)
|
---|
316 | {
|
---|
317 | mw = parent;
|
---|
318 | init();
|
---|
319 |
|
---|
320 | if (parent)
|
---|
321 | parent->addToolBar(this, label, dock, newLine);
|
---|
322 | }
|
---|
323 |
|
---|
324 |
|
---|
325 | /*!
|
---|
326 | Constructs an empty horizontal toolbar.
|
---|
327 |
|
---|
328 | The toolbar is called \a name and is a child of \a parent and is
|
---|
329 | managed by \a mainWindow. The \a label and \a newLine parameters
|
---|
330 | are passed straight to Q3MainWindow::addDockWindow(). \a name and
|
---|
331 | the widget flags \a f are passed on to the Q3DockWindow constructor.
|
---|
332 |
|
---|
333 | Use this constructor if you want to create torn-off (undocked,
|
---|
334 | floating) toolbars or toolbars in the \link QStatusBar status
|
---|
335 | bar\endlink.
|
---|
336 | */
|
---|
337 |
|
---|
338 | Q3ToolBar::Q3ToolBar(const QString &label, Q3MainWindow * mainWindow,
|
---|
339 | QWidget * parent, bool newLine, const char * name,
|
---|
340 | Qt::WindowFlags f)
|
---|
341 | : Q3DockWindow(InDock, parent, name, f, true)
|
---|
342 | {
|
---|
343 | mw = mainWindow;
|
---|
344 | init();
|
---|
345 |
|
---|
346 | setParent(parent);
|
---|
347 |
|
---|
348 | if (mainWindow)
|
---|
349 | mainWindow->addToolBar(this, label, Qt::DockUnmanaged, newLine);
|
---|
350 | }
|
---|
351 |
|
---|
352 |
|
---|
353 | /*!
|
---|
354 | \overload
|
---|
355 |
|
---|
356 | Constructs an empty toolbar called \a name, with parent \a parent,
|
---|
357 | in its \a parent's top dock area, without any label and without
|
---|
358 | requiring a newline.
|
---|
359 | */
|
---|
360 |
|
---|
361 | Q3ToolBar::Q3ToolBar(Q3MainWindow * parent, const char * name)
|
---|
362 | : Q3DockWindow(InDock, parent, name, 0, true)
|
---|
363 | {
|
---|
364 | mw = parent;
|
---|
365 | init();
|
---|
366 |
|
---|
367 | if (parent)
|
---|
368 | parent->addToolBar(this, QString(), Qt::DockTop);
|
---|
369 | }
|
---|
370 |
|
---|
371 | /*!
|
---|
372 | \internal
|
---|
373 |
|
---|
374 | Common initialization code. Requires that \c mw and \c o are set.
|
---|
375 | Does not call Q3MainWindow::addDockWindow().
|
---|
376 | */
|
---|
377 | void Q3ToolBar::init()
|
---|
378 | {
|
---|
379 | d = new Q3ToolBarPrivate;
|
---|
380 | d->extension = 0;
|
---|
381 | d->extensionPopup = 0;
|
---|
382 | sw = 0;
|
---|
383 |
|
---|
384 | setBackgroundRole(QPalette::Button);
|
---|
385 | setFocusPolicy(Qt::NoFocus);
|
---|
386 | setFrameStyle(QFrame::ToolBarPanel | QFrame::Raised);
|
---|
387 | }
|
---|
388 |
|
---|
389 | /*!
|
---|
390 | Destructor.
|
---|
391 | */
|
---|
392 |
|
---|
393 | Q3ToolBar::~Q3ToolBar()
|
---|
394 | {
|
---|
395 | delete d;
|
---|
396 | }
|
---|
397 |
|
---|
398 | /*!
|
---|
399 | \reimp
|
---|
400 | */
|
---|
401 |
|
---|
402 | void Q3ToolBar::setOrientation(Qt::Orientation o)
|
---|
403 | {
|
---|
404 | Q3DockWindow::setOrientation(o);
|
---|
405 | if (d->extension)
|
---|
406 | d->extension->setOrientation(o);
|
---|
407 | QObjectList childList = children();
|
---|
408 | for (int i = 0; i < childList.size(); ++i) {
|
---|
409 | Q3ToolBarSeparator* w = qobject_cast<Q3ToolBarSeparator*>(childList.at(i));
|
---|
410 | if (w)
|
---|
411 | w->setOrientation(o);
|
---|
412 | }
|
---|
413 | }
|
---|
414 |
|
---|
415 | /*!
|
---|
416 | Adds a separator to the right/bottom of the toolbar.
|
---|
417 | */
|
---|
418 |
|
---|
419 | void Q3ToolBar::addSeparator()
|
---|
420 | {
|
---|
421 | (void) new Q3ToolBarSeparator(orientation(), this, "toolbar separator");
|
---|
422 | }
|
---|
423 |
|
---|
424 | /*!
|
---|
425 | \reimp
|
---|
426 | */
|
---|
427 |
|
---|
428 | void Q3ToolBar::styleChange(QStyle &oldStyle)
|
---|
429 | {
|
---|
430 | Q3DockWindow::styleChange(oldStyle);
|
---|
431 | }
|
---|
432 |
|
---|
433 |
|
---|
434 | /*!
|
---|
435 | \reimp
|
---|
436 | */
|
---|
437 | void Q3ToolBar::setVisible(bool visible)
|
---|
438 | {
|
---|
439 | Q3DockWindow::setVisible(visible);
|
---|
440 | if (mw)
|
---|
441 | mw->triggerLayout(false);
|
---|
442 | if (visible)
|
---|
443 | checkForExtension(size());
|
---|
444 | }
|
---|
445 |
|
---|
446 | /*!
|
---|
447 | Returns a pointer to the Q3MainWindow which manages this toolbar.
|
---|
448 | */
|
---|
449 |
|
---|
450 | Q3MainWindow * Q3ToolBar::mainWindow() const
|
---|
451 | {
|
---|
452 | return mw;
|
---|
453 | }
|
---|
454 |
|
---|
455 |
|
---|
456 | /*!
|
---|
457 | Sets the widget \a w to be expanded if this toolbar is requested
|
---|
458 | to stretch.
|
---|
459 |
|
---|
460 | The request to stretch might occur because Q3MainWindow
|
---|
461 | right-justifies the dock area the toolbar is in, or because this
|
---|
462 | toolbar's isVerticalStretchable() or isHorizontalStretchable() is
|
---|
463 | set to true.
|
---|
464 |
|
---|
465 | If you call this function and the toolbar is not yet stretchable,
|
---|
466 | setStretchable() is called.
|
---|
467 |
|
---|
468 | \sa Q3MainWindow::setRightJustification(), setVerticalStretchable(),
|
---|
469 | setHorizontalStretchable()
|
---|
470 | */
|
---|
471 |
|
---|
472 | void Q3ToolBar::setStretchableWidget(QWidget * w)
|
---|
473 | {
|
---|
474 | sw = w;
|
---|
475 | boxLayout()->setStretchFactor(w, 1);
|
---|
476 |
|
---|
477 | if (!isHorizontalStretchable() && !isVerticalStretchable()) {
|
---|
478 | if (orientation() == Qt::Horizontal)
|
---|
479 | setHorizontalStretchable(true);
|
---|
480 | else
|
---|
481 | setVerticalStretchable(true);
|
---|
482 | }
|
---|
483 | }
|
---|
484 |
|
---|
485 |
|
---|
486 | /*!
|
---|
487 | \reimp
|
---|
488 | */
|
---|
489 |
|
---|
490 | bool Q3ToolBar::event(QEvent * e)
|
---|
491 | {
|
---|
492 | bool r = Q3DockWindow::event(e);
|
---|
493 | // After the event filters have dealt with it, do our stuff.
|
---|
494 | if (e->type() == QEvent::ChildInserted) {
|
---|
495 | QObject * child = ((QChildEvent*)e)->child();
|
---|
496 | if (child && child->isWidgetType() && !((QWidget*)child)->isWindow()
|
---|
497 | && child->parent() == this
|
---|
498 | && QLatin1String("qt_dockwidget_internal") != child->objectName()) {
|
---|
499 | boxLayout()->addWidget((QWidget*)child);
|
---|
500 | QLayoutItem *item = boxLayout()->itemAt(boxLayout()->indexOf((QWidget*)child));
|
---|
501 | if (QToolButton *button = qobject_cast<QToolButton*>(child)) {
|
---|
502 | item->setAlignment(Qt::AlignHCenter);
|
---|
503 | button->setFocusPolicy(Qt::NoFocus);
|
---|
504 | if (mw) {
|
---|
505 | QObject::connect(mw, SIGNAL(pixmapSizeChanged(bool)),
|
---|
506 | button, SLOT(setUsesBigPixmap(bool)));
|
---|
507 | button->setUsesBigPixmap(mw->usesBigPixmaps());
|
---|
508 | QObject::connect(mw, SIGNAL(usesTextLabelChanged(bool)),
|
---|
509 | child, SLOT(setUsesTextLabel(bool)));
|
---|
510 | button->setUsesTextLabel(mw->usesTextLabel());
|
---|
511 | }
|
---|
512 | button->setAutoRaise(true);
|
---|
513 | }
|
---|
514 | if (isVisible()) {
|
---|
515 | // toolbar compatibility: we auto show widgets that
|
---|
516 | // are not explicitly hidden
|
---|
517 | if (((QWidget*)child)->testAttribute(Qt::WA_WState_Hidden)
|
---|
518 | && !((QWidget*)child)->testAttribute(Qt::WA_WState_ExplicitShowHide))
|
---|
519 | ((QWidget*)child)->show();
|
---|
520 | checkForExtension(size());
|
---|
521 | }
|
---|
522 | }
|
---|
523 | if (child && child->isWidgetType() && ((QWidget*)child) == sw)
|
---|
524 | boxLayout()->setStretchFactor((QWidget*)child, 1);
|
---|
525 | } else if (e->type() == QEvent::Show) {
|
---|
526 | layout()->activate();
|
---|
527 | } else if (e->type() == QEvent::LayoutHint && place() == OutsideDock) {
|
---|
528 | adjustSize();
|
---|
529 | }
|
---|
530 | return r;
|
---|
531 | }
|
---|
532 |
|
---|
533 |
|
---|
534 | /*!
|
---|
535 | \property Q3ToolBar::label
|
---|
536 | \brief the toolbar's label.
|
---|
537 |
|
---|
538 | If the toolbar is floated the label becomes the toolbar window's
|
---|
539 | caption. There is no default label text.
|
---|
540 | */
|
---|
541 |
|
---|
542 | void Q3ToolBar::setLabel(const QString & label)
|
---|
543 | {
|
---|
544 | l = label;
|
---|
545 | setWindowTitle(l);
|
---|
546 | }
|
---|
547 |
|
---|
548 | QString Q3ToolBar::label() const
|
---|
549 | {
|
---|
550 | return l;
|
---|
551 | }
|
---|
552 |
|
---|
553 |
|
---|
554 | /*!
|
---|
555 | Deletes all the toolbar's child widgets.
|
---|
556 | */
|
---|
557 |
|
---|
558 | void Q3ToolBar::clear()
|
---|
559 | {
|
---|
560 | QObjectList childList = children();
|
---|
561 | d->extension = 0;
|
---|
562 | d->extensionPopup = 0; //they will both be destroyed by the following code
|
---|
563 | for (int i = 0; i < childList.size(); ++i) {
|
---|
564 | QObject *obj = childList.at(i);
|
---|
565 | if (obj->isWidgetType() && QLatin1String("qt_dockwidget_internal") != obj->objectName())
|
---|
566 | delete obj;
|
---|
567 | }
|
---|
568 | }
|
---|
569 |
|
---|
570 | /*!
|
---|
571 | \internal
|
---|
572 | */
|
---|
573 |
|
---|
574 | QSize Q3ToolBar::minimumSize() const
|
---|
575 | {
|
---|
576 | if (orientation() == Qt::Horizontal)
|
---|
577 | return QSize(0, Q3DockWindow::minimumSize().height());
|
---|
578 | return QSize(Q3DockWindow::minimumSize().width(), 0);
|
---|
579 | }
|
---|
580 |
|
---|
581 | /*!
|
---|
582 | \reimp
|
---|
583 | */
|
---|
584 |
|
---|
585 | QSize Q3ToolBar::minimumSizeHint() const
|
---|
586 | {
|
---|
587 | if (orientation() == Qt::Horizontal)
|
---|
588 | return QSize(0, Q3DockWindow::minimumSizeHint().height());
|
---|
589 | return QSize(Q3DockWindow::minimumSizeHint().width(), 0);
|
---|
590 | }
|
---|
591 |
|
---|
592 | void Q3ToolBar::createPopup()
|
---|
593 | {
|
---|
594 | if (!d->extensionPopup) {
|
---|
595 | d->extensionPopup = new Q3PopupMenu(this, "qt_dockwidget_internal");
|
---|
596 | connect(d->extensionPopup, SIGNAL(aboutToShow()), this, SLOT(createPopup()));
|
---|
597 | }
|
---|
598 |
|
---|
599 | if (!d->extension) {
|
---|
600 | d->extension = new Q3ToolBarExtensionWidget(this);
|
---|
601 | d->extension->setOrientation(orientation());
|
---|
602 | d->extension->button()->setPopup(d->extensionPopup);
|
---|
603 | d->extension->button()->setPopupMode(QToolButton::InstantPopup);
|
---|
604 | }
|
---|
605 |
|
---|
606 | d->extensionPopup->clear();
|
---|
607 |
|
---|
608 | // delete submenus
|
---|
609 | QObjectList popups = d->extensionPopup->queryList("Q3PopupMenu", 0, false, true);
|
---|
610 | while (!popups.isEmpty())
|
---|
611 | delete popups.takeFirst();
|
---|
612 |
|
---|
613 | QObjectList childlist = queryList("QWidget", 0, false, true);
|
---|
614 | bool hide = false;
|
---|
615 | bool doHide = false;
|
---|
616 | int id;
|
---|
617 | for (int i = 0; i < childlist.size(); ++i) {
|
---|
618 | QObject *obj = childlist.at(i);
|
---|
619 | if (!obj->isWidgetType() || obj == d->extension->button() || obj == d->extensionPopup
|
---|
620 | || QLatin1String("qt_dockwidget_internal") == obj->objectName()) {
|
---|
621 | continue;
|
---|
622 | }
|
---|
623 | int j = 2;
|
---|
624 | QWidget *w = (QWidget*)obj;
|
---|
625 | if (qobject_cast<Q3ComboBox*>(w))
|
---|
626 | j = 1;
|
---|
627 | hide = false;
|
---|
628 |
|
---|
629 | const int padding = 4; // extra pixels added by the layout hierarchy
|
---|
630 | QPoint p(mapTo(this, w->geometry().bottomRight()));
|
---|
631 | if (orientation() == Qt::Horizontal) {
|
---|
632 | if ((p.x() > (doHide ? width() - d->extension->width() / j - padding : width() - padding))
|
---|
633 | || (p.x() > parentWidget()->width() - d->extension->width()))
|
---|
634 | hide = true;
|
---|
635 | } else {
|
---|
636 | if ((p.y() > (doHide ? height()- d->extension->height() / j - padding : height() - padding))
|
---|
637 | || (p.y() > parentWidget()->height() - d->extension->height()))
|
---|
638 | hide = true;
|
---|
639 | }
|
---|
640 | if (hide && w->isVisible()) {
|
---|
641 | doHide = true;
|
---|
642 | if (qobject_cast<QToolButton*>(w)) {
|
---|
643 | QToolButton *b = (QToolButton*)w;
|
---|
644 | QString s = b->textLabel();
|
---|
645 | if (s.isEmpty())
|
---|
646 | s = b->text();
|
---|
647 | if (b->popup() && b->popupDelay() == 0)
|
---|
648 | id = d->extensionPopup->insertItem(b->iconSet(), s, b->popup());
|
---|
649 | else
|
---|
650 | id = d->extensionPopup->insertItem(b->iconSet(), s, b, SLOT(click())) ;
|
---|
651 | if (b->isToggleButton())
|
---|
652 | d->extensionPopup->setItemChecked(id, b->isOn());
|
---|
653 | if (!b->isEnabled())
|
---|
654 | d->extensionPopup->setItemEnabled(id, false);
|
---|
655 | } else if (qobject_cast<QAbstractButton*>(w)) {
|
---|
656 | QAbstractButton *b = (QAbstractButton*)w;
|
---|
657 | QString s = b->text();
|
---|
658 | if (s.isEmpty())
|
---|
659 | s = QLatin1String("");
|
---|
660 | if (b->pixmap())
|
---|
661 | id = d->extensionPopup->insertItem(*b->pixmap(), s, b, SLOT(click()));
|
---|
662 | else
|
---|
663 | id = d->extensionPopup->insertItem(s, b, SLOT(click()));
|
---|
664 | if (b->isToggleButton())
|
---|
665 | d->extensionPopup->setItemChecked(id, b->isOn());
|
---|
666 | if (!b->isEnabled())
|
---|
667 | d->extensionPopup->setItemEnabled(id, false);
|
---|
668 | #ifndef QT_NO_COMBOBOX
|
---|
669 | } else if (qobject_cast<Q3ComboBox*>(w)) {
|
---|
670 | Q3ComboBox *c = (Q3ComboBox*)w;
|
---|
671 | if (c->count() != 0) {
|
---|
672 | QString s = c->windowTitle();
|
---|
673 | if (s.isEmpty())
|
---|
674 | s = c->currentText();
|
---|
675 | int maxItems = 0;
|
---|
676 | Q3PopupMenu *cp = new Q3PopupMenu(d->extensionPopup);
|
---|
677 | cp->setEnabled(c->isEnabled());
|
---|
678 | d->extensionPopup->insertItem(s, cp);
|
---|
679 | connect(cp, SIGNAL(activated(int)), c, SLOT(internalActivate(int)));
|
---|
680 | for (int i = 0; i < c->count(); ++i) {
|
---|
681 | QString tmp = c->text(i);
|
---|
682 | cp->insertItem(tmp, i);
|
---|
683 | if (c->currentText() == tmp)
|
---|
684 | cp->setItemChecked(i, true);
|
---|
685 | if (!maxItems) {
|
---|
686 | if (cp->actions().count() == 10) {
|
---|
687 | int h = cp->sizeHint().height();
|
---|
688 | maxItems = QApplication::desktop()->height() * 10 / h;
|
---|
689 | }
|
---|
690 | } else if (cp->actions().count() >= maxItems - 1) {
|
---|
691 | Q3PopupMenu* sp = new Q3PopupMenu(d->extensionPopup);
|
---|
692 | cp->insertItem(tr("More..."), sp);
|
---|
693 | cp = sp;
|
---|
694 | connect(cp, SIGNAL(activated(int)), c, SLOT(internalActivate(int)));
|
---|
695 | }
|
---|
696 | }
|
---|
697 | }
|
---|
698 | #endif //QT_NO_COMBOBOX
|
---|
699 | }
|
---|
700 | }
|
---|
701 | }
|
---|
702 | }
|
---|
703 |
|
---|
704 | /*!
|
---|
705 | \reimp
|
---|
706 | */
|
---|
707 |
|
---|
708 | void Q3ToolBar::resizeEvent(QResizeEvent *e)
|
---|
709 | {
|
---|
710 | Q3DockWindow::resizeEvent(e);
|
---|
711 | checkForExtension(e->size());
|
---|
712 | }
|
---|
713 |
|
---|
714 | /*!
|
---|
715 | \internal
|
---|
716 |
|
---|
717 | This function is called when an action is triggered. The relevant
|
---|
718 | information is passed in the event \a e.
|
---|
719 | */
|
---|
720 | void Q3ToolBar::actionEvent(QActionEvent *e)
|
---|
721 | {
|
---|
722 | if (e->type() == QEvent::ActionAdded) {
|
---|
723 | QAction *a = e->action();
|
---|
724 | QWidget *w;
|
---|
725 | if (a->isSeparator()) {
|
---|
726 | w = new Q3ToolBarSeparator(orientation(), this, "toolbar separator");
|
---|
727 | } else {
|
---|
728 | QToolButton* btn = new QToolButton(this);
|
---|
729 | btn->setDefaultAction(a);
|
---|
730 | w = btn;
|
---|
731 | }
|
---|
732 | d->actions.insert(a, w);
|
---|
733 | } else if (e->type() == QEvent::ActionRemoved) {
|
---|
734 | QAction *a = e->action();
|
---|
735 | delete d->actions.take(a);
|
---|
736 | }
|
---|
737 | }
|
---|
738 |
|
---|
739 |
|
---|
740 | void Q3ToolBar::checkForExtension(const QSize &sz)
|
---|
741 | {
|
---|
742 | if (!isVisible())
|
---|
743 | return;
|
---|
744 |
|
---|
745 | if (d->checkingExtension)
|
---|
746 | return;
|
---|
747 | d->checkingExtension = true;
|
---|
748 |
|
---|
749 | bool tooSmall;
|
---|
750 | if (orientation() == Qt::Horizontal)
|
---|
751 | tooSmall = sz.width() < sizeHint().width();
|
---|
752 | else
|
---|
753 | tooSmall = sz.height() < sizeHint().height();
|
---|
754 |
|
---|
755 | if (tooSmall) {
|
---|
756 | createPopup();
|
---|
757 | if (d->extensionPopup->actions().count()) {
|
---|
758 | // parentWidget()->width() used since the Q3ToolBar width
|
---|
759 | // will never be less than minimumSize()
|
---|
760 | if (orientation() == Qt::Horizontal)
|
---|
761 | d->extension->setGeometry((parentWidget() ? parentWidget()->width() : width()) - 20,
|
---|
762 | 1, 20, height() - 2);
|
---|
763 | else
|
---|
764 | d->extension->setGeometry(1, (parentWidget() ? parentWidget()->height() : height()) - 20,
|
---|
765 | width() - 2, 20);
|
---|
766 | d->extension->show();
|
---|
767 | d->extension->raise();
|
---|
768 | } else {
|
---|
769 | delete d->extension;
|
---|
770 | d->extension = 0;
|
---|
771 | delete d->extensionPopup;
|
---|
772 | d->extensionPopup = 0;
|
---|
773 | }
|
---|
774 | } else {
|
---|
775 | delete d->extension;
|
---|
776 | d->extension = 0;
|
---|
777 | delete d->extensionPopup;
|
---|
778 | d->extensionPopup = 0;
|
---|
779 | }
|
---|
780 | d->checkingExtension = false;
|
---|
781 | }
|
---|
782 |
|
---|
783 |
|
---|
784 | /*!
|
---|
785 | \internal
|
---|
786 | */
|
---|
787 |
|
---|
788 | void Q3ToolBar::setMinimumSize(int, int)
|
---|
789 | {
|
---|
790 | }
|
---|
791 |
|
---|
792 | /* from chaunsee:
|
---|
793 |
|
---|
794 | 1. Tool Bars should contain only high-frequency functions. Avoid putting
|
---|
795 | things like About and Exit on a tool bar unless they are frequent functions.
|
---|
796 |
|
---|
797 | 2. All tool bar buttons must have some keyboard access method (it can be a
|
---|
798 | menu or shortcut key or a function in a dialog box that can be accessed
|
---|
799 | through the keyboard).
|
---|
800 |
|
---|
801 | 3. Make tool bar functions as efficient as possible (the common example is to
|
---|
802 | Print in Microsoft applications, it doesn't bring up the Print dialog box, it
|
---|
803 | prints immediately to the default printer).
|
---|
804 |
|
---|
805 | 4. Avoid turning tool bars into graphical menu bars. To me, a tool bar should
|
---|
806 | be efficient. Once you make almost all the items in a tool bar into graphical
|
---|
807 | pull-down menus, you start to lose efficiency.
|
---|
808 |
|
---|
809 | 5. Make sure that adjacent icons are distinctive. There are some tool bars
|
---|
810 | where you see a group of 4-5 icons that represent related functions, but they
|
---|
811 | are so similar that you can't differentiate among them. These tool bars are
|
---|
812 | often a poor attempt at a "common visual language".
|
---|
813 |
|
---|
814 | 6. Use any de facto standard icons of your platform (for windows use the
|
---|
815 | cut, copy and paste icons provided in dev kits rather than designing your
|
---|
816 | own).
|
---|
817 |
|
---|
818 | 7. Avoid putting a highly destructive tool bar button (delete database) by a
|
---|
819 | safe, high-frequency button (Find) -- this will yield 1-0ff errors).
|
---|
820 |
|
---|
821 | 8. Tooltips in many Microsoft products simply reiterate the menu text even
|
---|
822 | when that is not explanatory. Consider making your tooltips slightly more
|
---|
823 | verbose and explanatory than the corresponding menu item.
|
---|
824 |
|
---|
825 | 9. Keep the tool bar as stable as possible when you click on different
|
---|
826 | objects. Consider disabling tool bar buttons if they are used in most, but not
|
---|
827 | all contexts.
|
---|
828 |
|
---|
829 | 10. If you have multiple tool bars (like the Microsoft MMC snap-ins have),
|
---|
830 | put the most stable tool bar to at the left with less stable ones to the
|
---|
831 | right. This arrangement (stable to less stable) makes the tool bar somewhat
|
---|
832 | more predictable.
|
---|
833 |
|
---|
834 | 11. Keep a single tool bar to fewer than 20 items divided into 4-7 groups of
|
---|
835 | items.
|
---|
836 | */
|
---|
837 |
|
---|
838 | QT_END_NAMESPACE
|
---|
839 |
|
---|
840 | #endif
|
---|