summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qtoolbarlayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets/qtoolbarlayout.cpp')
-rw-r--r--src/widgets/widgets/qtoolbarlayout.cpp742
1 files changed, 742 insertions, 0 deletions
diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp
new file mode 100644
index 0000000000..971fddaafd
--- /dev/null
+++ b/src/widgets/widgets/qtoolbarlayout.cpp
@@ -0,0 +1,742 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qaction.h>
+#include <qwidgetaction.h>
+#include <qtoolbar.h>
+#include <qstyleoption.h>
+#include <qtoolbutton.h>
+#include <qmenu.h>
+#include <qdebug.h>
+#include <qmath.h>
+
+#include "qmainwindowlayout_p.h"
+#include "qtoolbarextension_p.h"
+#include "qtoolbarlayout_p.h"
+#include "qtoolbarseparator_p.h"
+
+#ifndef QT_NO_TOOLBAR
+
+QT_BEGIN_NAMESPACE
+
+// qmainwindow.cpp
+extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
+
+/******************************************************************************
+** QToolBarItem
+*/
+
+QToolBarItem::QToolBarItem(QWidget *widget)
+ : QWidgetItem(widget), action(0), customWidget(false)
+{
+}
+
+bool QToolBarItem::isEmpty() const
+{
+ return action == 0 || !action->isVisible();
+}
+
+/******************************************************************************
+** QToolBarLayout
+*/
+
+QToolBarLayout::QToolBarLayout(QWidget *parent)
+ : QLayout(parent), expanded(false), animating(false), dirty(true),
+ expanding(false), empty(true), expandFlag(false), popupMenu(0)
+{
+ QToolBar *tb = qobject_cast<QToolBar*>(parent);
+ if (!tb)
+ return;
+
+ extension = new QToolBarExtension(tb);
+ extension->setFocusPolicy(Qt::NoFocus);
+ extension->hide();
+ QObject::connect(tb, SIGNAL(orientationChanged(Qt::Orientation)),
+ extension, SLOT(setOrientation(Qt::Orientation)));
+
+ setUsePopupMenu(qobject_cast<QMainWindow*>(tb->parentWidget()) == 0);
+}
+
+QToolBarLayout::~QToolBarLayout()
+{
+ while (!items.isEmpty()) {
+ QToolBarItem *item = items.takeFirst();
+ if (QWidgetAction *widgetAction = qobject_cast<QWidgetAction*>(item->action)) {
+ if (item->customWidget)
+ widgetAction->releaseWidget(item->widget());
+ }
+ delete item;
+ }
+}
+
+void QToolBarLayout::updateMarginAndSpacing()
+{
+ QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return;
+ QStyle *style = tb->style();
+ QStyleOptionToolBar opt;
+ tb->initStyleOption(&opt);
+ setMargin(style->pixelMetric(QStyle::PM_ToolBarItemMargin, &opt, tb)
+ + style->pixelMetric(QStyle::PM_ToolBarFrameWidth, &opt, tb));
+ setSpacing(style->pixelMetric(QStyle::PM_ToolBarItemSpacing, &opt, tb));
+}
+
+bool QToolBarLayout::hasExpandFlag() const
+{
+ return expandFlag;
+}
+
+void QToolBarLayout::setUsePopupMenu(bool set)
+{
+ if (!dirty && ((popupMenu == 0) == set))
+ invalidate();
+ if (!set) {
+ QObject::connect(extension, SIGNAL(clicked(bool)),
+ this, SLOT(setExpanded(bool)), Qt::UniqueConnection);
+ extension->setPopupMode(QToolButton::DelayedPopup);
+ extension->setMenu(0);
+ delete popupMenu;
+ popupMenu = 0;
+ } else {
+ QObject::disconnect(extension, SIGNAL(clicked(bool)),
+ this, SLOT(setExpanded(bool)));
+ extension->setPopupMode(QToolButton::InstantPopup);
+ if (!popupMenu) {
+ popupMenu = new QMenu(extension);
+ }
+ extension->setMenu(popupMenu);
+ }
+}
+
+void QToolBarLayout::checkUsePopupMenu()
+{
+ QToolBar *tb = static_cast<QToolBar *>(parent());
+ QMainWindow *mw = qobject_cast<QMainWindow *>(tb->parent());
+ Qt::Orientation o = tb->orientation();
+ setUsePopupMenu(!mw || tb->isFloating() || perp(o, expandedSize(mw->size())) >= perp(o, mw->size()));
+}
+
+void QToolBarLayout::addItem(QLayoutItem*)
+{
+ qWarning() << "QToolBarLayout::addItem(): please use addAction() instead";
+ return;
+}
+
+QLayoutItem *QToolBarLayout::itemAt(int index) const
+{
+ if (index < 0 || index >= items.count())
+ return 0;
+ return items.at(index);
+}
+
+QLayoutItem *QToolBarLayout::takeAt(int index)
+{
+ if (index < 0 || index >= items.count())
+ return 0;
+ QToolBarItem *item = items.takeAt(index);
+
+ if (popupMenu)
+ popupMenu->removeAction(item->action);
+
+ QWidgetAction *widgetAction = qobject_cast<QWidgetAction*>(item->action);
+ if (widgetAction != 0 && item->customWidget) {
+ widgetAction->releaseWidget(item->widget());
+ } else {
+ // destroy the QToolButton/QToolBarSeparator
+ item->widget()->hide();
+ item->widget()->deleteLater();
+ }
+
+ invalidate();
+ return item;
+}
+
+void QToolBarLayout::insertAction(int index, QAction *action)
+{
+ index = qMax(0, index);
+ index = qMin(items.count(), index);
+
+ QToolBarItem *item = createItem(action);
+ if (item) {
+ items.insert(index, item);
+ invalidate();
+ }
+}
+
+int QToolBarLayout::indexOf(QAction *action) const
+{
+ for (int i = 0; i < items.count(); ++i) {
+ if (items.at(i)->action == action)
+ return i;
+ }
+ return -1;
+}
+
+int QToolBarLayout::count() const
+{
+ return items.count();
+}
+
+bool QToolBarLayout::isEmpty() const
+{
+ if (dirty)
+ updateGeomArray();
+ return empty;
+}
+
+void QToolBarLayout::invalidate()
+{
+ dirty = true;
+ QLayout::invalidate();
+}
+
+Qt::Orientations QToolBarLayout::expandingDirections() const
+{
+ if (dirty)
+ updateGeomArray();
+ QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return Qt::Orientations(0);
+ Qt::Orientation o = tb->orientation();
+ return expanding ? Qt::Orientations(o) : Qt::Orientations(0);
+}
+
+bool QToolBarLayout::movable() const
+{
+ QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return false;
+ QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget());
+ return tb->isMovable() && win != 0;
+}
+
+void QToolBarLayout::updateGeomArray() const
+{
+ if (!dirty)
+ return;
+
+ QToolBarLayout *that = const_cast<QToolBarLayout*>(this);
+
+ QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return;
+ QStyle *style = tb->style();
+ QStyleOptionToolBar opt;
+ tb->initStyleOption(&opt);
+ const int handleExtent = movable()
+ ? style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb) : 0;
+ const int margin = this->margin();
+ const int spacing = this->spacing();
+ const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb);
+ Qt::Orientation o = tb->orientation();
+
+ that->minSize = QSize(0, 0);
+ that->hint = QSize(0, 0);
+ rperp(o, that->minSize) = style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb);
+ rperp(o, that->hint) = style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb);
+
+ that->expanding = false;
+ that->empty = false;
+
+ QVector<QLayoutStruct> a(items.count() + 1); // + 1 for the stretch
+
+ int count = 0;
+ for (int i = 0; i < items.count(); ++i) {
+ QToolBarItem *item = items.at(i);
+
+ QSize max = item->maximumSize();
+ QSize min = item->minimumSize();
+ QSize hint = item->sizeHint();
+ Qt::Orientations exp = item->expandingDirections();
+ bool empty = item->isEmpty();
+
+ that->expanding = expanding || exp & o;
+
+
+ if (item->widget()) {
+ if ((item->widget()->sizePolicy().horizontalPolicy() & QSizePolicy::ExpandFlag)) {
+ that->expandFlag = true;
+ }
+ }
+
+ if (!empty) {
+ if (count == 0) // the minimum size only displays one widget
+ rpick(o, that->minSize) += pick(o, min);
+ int s = perp(o, minSize);
+ rperp(o, that->minSize) = qMax(s, perp(o, min));
+
+ //we only add spacing before item (ie never before the first one)
+ rpick(o, that->hint) += (count == 0 ? 0 : spacing) + pick(o, hint);
+ s = perp(o, that->hint);
+ rperp(o, that->hint) = qMax(s, perp(o, hint));
+ ++count;
+ }
+
+ a[i].sizeHint = pick(o, hint);
+ a[i].maximumSize = pick(o, max);
+ a[i].minimumSize = pick(o, min);
+ a[i].expansive = exp & o;
+ if (o == Qt::Horizontal)
+ a[i].stretch = item->widget()->sizePolicy().horizontalStretch();
+ else
+ a[i].stretch = item->widget()->sizePolicy().verticalStretch();
+ a[i].empty = empty;
+ }
+
+ that->geomArray = a;
+ that->empty = count == 0;
+
+ rpick(o, that->minSize) += handleExtent;
+ that->minSize += QSize(2*margin, 2*margin);
+ if (items.count() > 1)
+ rpick(o, that->minSize) += spacing + extensionExtent;
+
+ rpick(o, that->hint) += handleExtent;
+ that->hint += QSize(2*margin, 2*margin);
+ that->dirty = false;
+#ifdef Q_WS_MAC
+ if (QMainWindow *mw = qobject_cast<QMainWindow *>(parentWidget()->parentWidget())) {
+ if (mw->unifiedTitleAndToolBarOnMac()
+ && mw->toolBarArea(static_cast<QToolBar *>(parentWidget())) == Qt::TopToolBarArea) {
+ if (expandFlag) {
+ tb->setMaximumSize(0xFFFFFF, 0xFFFFFF);
+ } else {
+ tb->setMaximumSize(hint);
+ }
+ }
+ }
+#endif
+
+ that->dirty = false;
+}
+
+static bool defaultWidgetAction(QToolBarItem *item)
+{
+ QWidgetAction *a = qobject_cast<QWidgetAction*>(item->action);
+ return a != 0 && a->defaultWidget() == item->widget();
+}
+
+void QToolBarLayout::setGeometry(const QRect &rect)
+{
+ QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return;
+ QStyle *style = tb->style();
+ QStyleOptionToolBar opt;
+ tb->initStyleOption(&opt);
+ const int margin = this->margin();
+ const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb);
+ Qt::Orientation o = tb->orientation();
+
+ QLayout::setGeometry(rect);
+
+ bool ranOutOfSpace = false;
+ if (!animating)
+ ranOutOfSpace = layoutActions(rect.size());
+
+ if (expanded || animating || ranOutOfSpace) {
+ Qt::ToolBarArea area = Qt::TopToolBarArea;
+ if (QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget()))
+ area = win->toolBarArea(tb);
+ QSize hint = sizeHint();
+
+ QPoint pos;
+ rpick(o, pos) = pick(o, rect.bottomRight()) - margin - extensionExtent + 2;
+ if (area == Qt::LeftToolBarArea || area == Qt::TopToolBarArea)
+ rperp(o, pos) = perp(o, rect.topLeft()) + margin;
+ else
+ rperp(o, pos) = perp(o, rect.bottomRight()) - margin - (perp(o, hint) - 2*margin) + 1;
+ QSize size;
+ rpick(o, size) = extensionExtent;
+ rperp(o, size) = perp(o, hint) - 2*margin;
+ QRect r(pos, size);
+
+ if (o == Qt::Horizontal)
+ r = QStyle::visualRect(parentWidget()->layoutDirection(), rect, r);
+
+ extension->setGeometry(r);
+
+ if (extension->isHidden())
+ extension->show();
+ } else {
+ if (!extension->isHidden())
+ extension->hide();
+ }
+#ifdef Q_WS_MAC
+ // Nothing to do for Carbon... probably
+# ifdef QT_MAC_USE_COCOA
+ if (QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget())) {
+ Qt::ToolBarArea area = win->toolBarArea(tb);
+ if (win->unifiedTitleAndToolBarOnMac() && area == Qt::TopToolBarArea) {
+ qt_mainwindow_layout(win)->fixSizeInUnifiedToolbar(tb);
+ }
+ }
+# endif
+#endif
+
+}
+
+bool QToolBarLayout::layoutActions(const QSize &size)
+{
+ if (dirty)
+ updateGeomArray();
+
+ QRect rect(0, 0, size.width(), size.height());
+
+ QList<QWidget*> showWidgets, hideWidgets;
+
+ QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return false;
+ QStyle *style = tb->style();
+ QStyleOptionToolBar opt;
+ tb->initStyleOption(&opt);
+ const int handleExtent = movable()
+ ? style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb) : 0;
+ const int margin = this->margin();
+ const int spacing = this->spacing();
+ const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb);
+ Qt::Orientation o = tb->orientation();
+ bool extensionMenuContainsOnlyWidgetActions = true;
+
+ int space = pick(o, rect.size()) - 2*margin - handleExtent;
+ if (space <= 0)
+ return false; // nothing to do.
+
+ if(popupMenu)
+ popupMenu->clear();
+
+ bool ranOutOfSpace = false;
+ int rows = 0;
+ int rowPos = perp(o, rect.topLeft()) + margin;
+ int i = 0;
+ while (i < items.count()) {
+ QVector<QLayoutStruct> a = geomArray;
+
+ int start = i;
+ int size = 0;
+ int prev = -1;
+ int rowHeight = 0;
+ int count = 0;
+ int maximumSize = 0;
+ bool expansiveRow = false;
+ for (; i < items.count(); ++i) {
+ if (a[i].empty)
+ continue;
+
+ int newSize = size + (count == 0 ? 0 : spacing) + a[i].minimumSize;
+ if (prev != -1 && newSize > space) {
+ if (rows == 0)
+ ranOutOfSpace = true;
+ // do we have to move the previous item to the next line to make space for
+ // the extension button?
+ if (count > 1 && size + spacing + extensionExtent > space)
+ i = prev;
+ break;
+ }
+
+ if (expanded)
+ rowHeight = qMax(rowHeight, perp(o, items.at(i)->sizeHint()));
+ expansiveRow = expansiveRow || a[i].expansive;
+ size = newSize;
+ maximumSize += spacing + (a[i].expansive ? a[i].maximumSize : a[i].smartSizeHint());
+ prev = i;
+ ++count;
+ }
+
+ // stretch at the end
+ a[i].sizeHint = 0;
+ a[i].maximumSize = QWIDGETSIZE_MAX;
+ a[i].minimumSize = 0;
+ a[i].expansive = true;
+ a[i].stretch = 0;
+ a[i].empty = true;
+
+ if (expansiveRow && maximumSize < space) {
+ expansiveRow = false;
+ a[i].maximumSize = space - maximumSize;
+ }
+
+ qGeomCalc(a, start, i - start + (expansiveRow ? 0 : 1), 0,
+ space - (ranOutOfSpace ? (extensionExtent + spacing) : 0),
+ spacing);
+
+ for (int j = start; j < i; ++j) {
+ QToolBarItem *item = items.at(j);
+
+ if (a[j].empty) {
+ if (!item->widget()->isHidden())
+ hideWidgets << item->widget();
+ continue;
+ }
+
+ QPoint pos;
+ rpick(o, pos) = margin + handleExtent + a[j].pos;
+ rperp(o, pos) = rowPos;
+ QSize size;
+ rpick(o, size) = a[j].size;
+ if (expanded)
+ rperp(o, size) = rowHeight;
+ else
+ rperp(o, size) = perp(o, rect.size()) - 2*margin;
+ QRect r(pos, size);
+
+ if (o == Qt::Horizontal)
+ r = QStyle::visualRect(parentWidget()->layoutDirection(), rect, r);
+
+ item->setGeometry(r);
+
+ if (item->widget()->isHidden())
+ showWidgets << item->widget();
+ }
+
+ if (!expanded) {
+ for (int j = i; j < items.count(); ++j) {
+ QToolBarItem *item = items.at(j);
+ if (!item->widget()->isHidden())
+ hideWidgets << item->widget();
+ if (popupMenu) {
+ if (!defaultWidgetAction(item)) {
+ popupMenu->addAction(item->action);
+ extensionMenuContainsOnlyWidgetActions = false;
+ }
+ }
+ }
+ break;
+ }
+
+ rowPos += rowHeight + spacing;
+ ++rows;
+ }
+
+ // if we are using a popup menu, not the expadning toolbar effect, we cannot move custom
+ // widgets into the menu. If only custom widget actions are chopped off, the popup menu
+ // is empty. So we show the little extension button to show something is chopped off,
+ // but we make it disabled.
+ extension->setEnabled(popupMenu == 0 || !extensionMenuContainsOnlyWidgetActions);
+
+ // we have to do the show/hide here, because it triggers more calls to setGeometry :(
+ for (int i = 0; i < showWidgets.count(); ++i)
+ showWidgets.at(i)->show();
+ for (int i = 0; i < hideWidgets.count(); ++i)
+ hideWidgets.at(i)->hide();
+
+ return ranOutOfSpace;
+}
+
+QSize QToolBarLayout::expandedSize(const QSize &size) const
+{
+ if (dirty)
+ updateGeomArray();
+
+ QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return QSize(0, 0);
+ QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget());
+ Qt::Orientation o = tb->orientation();
+ QStyle *style = tb->style();
+ QStyleOptionToolBar opt;
+ tb->initStyleOption(&opt);
+ const int handleExtent = movable()
+ ? style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb) : 0;
+ const int margin = this->margin();
+ const int spacing = this->spacing();
+ const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb);
+
+ int total_w = 0;
+ int count = 0;
+ for (int x = 0; x < items.count(); ++x) {
+ if (!geomArray[x].empty) {
+ total_w += (count == 0 ? 0 : spacing) + geomArray[x].minimumSize;
+ ++count;
+ }
+ }
+ if (count == 0)
+ return QSize(0, 0);
+
+ int min_w = pick(o, size);
+ int rows = (int)qSqrt(qreal(count));
+ if (rows == 1)
+ ++rows; // we want to expand to at least two rows
+ int space = total_w/rows + spacing + extensionExtent;
+ space = qMax(space, min_w - 2*margin - handleExtent);
+ if (win != 0)
+ space = qMin(space, pick(o, win->size()) - 2*margin - handleExtent);
+
+ int w = 0;
+ int h = 0;
+ int i = 0;
+ while (i < items.count()) {
+ int count = 0;
+ int size = 0;
+ int prev = -1;
+ int rowHeight = 0;
+ for (; i < items.count(); ++i) {
+ if (geomArray[i].empty)
+ continue;
+
+ int newSize = size + (count == 0 ? 0 : spacing) + geomArray[i].minimumSize;
+ rowHeight = qMax(rowHeight, perp(o, items.at(i)->sizeHint()));
+ if (prev != -1 && newSize > space) {
+ if (count > 1 && size + spacing + extensionExtent > space) {
+ size -= spacing + geomArray[prev].minimumSize;
+ i = prev;
+ }
+ break;
+ }
+
+ size = newSize;
+ prev = i;
+ ++count;
+ }
+
+ w = qMax(size, w);
+ h += rowHeight + spacing;
+ }
+
+ w += 2*margin + handleExtent + spacing + extensionExtent;
+ w = qMax(w, min_w);
+ if (win != 0)
+ w = qMin(w, pick(o, win->size()));
+ h += 2*margin - spacing; //there is no spacing before the first row
+
+ QSize result;
+ rpick(o, result) = w;
+ rperp(o, result) = h;
+ return result;
+}
+
+void QToolBarLayout::setExpanded(bool exp)
+{
+ QWidget *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return;
+ if (exp == expanded && !tb->isWindow())
+ return;
+
+ expanded = exp;
+ extension->setChecked(expanded);
+
+ if (QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget())) {
+#ifdef QT_NO_DOCKWIDGET
+ animating = false;
+#else
+ animating = !tb->isWindow() && win->isAnimated();
+#endif
+ QMainWindowLayout *layout = qt_mainwindow_layout(win);
+ if (expanded) {
+ tb->raise();
+ } else {
+ QList<int> path = layout->layoutState.indexOf(tb);
+ if (!path.isEmpty()) {
+ QRect rect = layout->layoutState.itemRect(path);
+ layoutActions(rect.size());
+ }
+ }
+ layout->layoutState.toolBarAreaLayout.apply(animating);
+ }
+}
+
+QSize QToolBarLayout::minimumSize() const
+{
+ if (dirty)
+ updateGeomArray();
+ return minSize;
+}
+
+QSize QToolBarLayout::sizeHint() const
+{
+ if (dirty)
+ updateGeomArray();
+ return hint;
+}
+
+QToolBarItem *QToolBarLayout::createItem(QAction *action)
+{
+ bool customWidget = false;
+ bool standardButtonWidget = false;
+ QWidget *widget = 0;
+ QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return (QToolBarItem *)0;
+
+ if (QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(action)) {
+ widget = widgetAction->requestWidget(tb);
+ if (widget != 0) {
+ widget->setAttribute(Qt::WA_LayoutUsesWidgetRect);
+ customWidget = true;
+ }
+ } else if (action->isSeparator()) {
+ QToolBarSeparator *sep = new QToolBarSeparator(tb);
+ connect(tb, SIGNAL(orientationChanged(Qt::Orientation)),
+ sep, SLOT(setOrientation(Qt::Orientation)));
+ widget = sep;
+ }
+
+ if (!widget) {
+ QToolButton *button = new QToolButton(tb);
+ button->setAutoRaise(true);
+ button->setFocusPolicy(Qt::NoFocus);
+ button->setIconSize(tb->iconSize());
+ button->setToolButtonStyle(tb->toolButtonStyle());
+ QObject::connect(tb, SIGNAL(iconSizeChanged(QSize)),
+ button, SLOT(setIconSize(QSize)));
+ QObject::connect(tb, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
+ button, SLOT(setToolButtonStyle(Qt::ToolButtonStyle)));
+ button->setDefaultAction(action);
+ QObject::connect(button, SIGNAL(triggered(QAction*)), tb, SIGNAL(actionTriggered(QAction*)));
+ widget = button;
+ standardButtonWidget = true;
+ }
+
+ widget->hide();
+ QToolBarItem *result = new QToolBarItem(widget);
+ if (standardButtonWidget)
+ result->setAlignment(Qt::AlignJustify);
+ result->customWidget = customWidget;
+ result->action = action;
+ return result;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_TOOLBAR