00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qtoolbar.h"
00025
00026 #ifndef QT_NO_TOOLBAR
00027
00028 #include <qapplication.h>
00029 #include <qcombobox.h>
00030 #include <qevent.h>
00031 #include <qlayout.h>
00032 #include <qmainwindow.h>
00033 #include <qmenu.h>
00034 #include <qmenubar.h>
00035 #include <qpainter.h>
00036 #include <qrubberband.h>
00037 #include <qsignalmapper.h>
00038 #include <qstyle.h>
00039 #include <qstyleoption.h>
00040 #include <qtoolbutton.h>
00041 #include <qwidgetaction.h>
00042 #include <private/qwidgetaction_p.h>
00043 #ifdef Q_WS_MAC
00044 #include <private/qt_mac_p.h>
00045 #endif
00046
00047 #include <private/qmainwindowlayout_p.h>
00048
00049 #include "qtoolbar_p.h"
00050 #include "qtoolbarextension_p.h"
00051 #include "qtoolbarhandle_p.h"
00052 #include "qtoolbarseparator_p.h"
00053
00054 #include "qdebug.h"
00055 static int positionForArea(Qt::ToolBarArea area)
00056 {
00057 switch (area) {
00058 case Qt::LeftToolBarArea: return 0;
00059 case Qt::RightToolBarArea: return 1;
00060 case Qt::TopToolBarArea: return 2;
00061 case Qt::BottomToolBarArea: return 3;
00062 default: return -1;
00063 }
00064 }
00065
00066 static QStyleOptionToolBar getStyleOption(QToolBar *toolBar)
00067 {
00068 QStyleOptionToolBar option;
00069 option.init(toolBar);
00070 if (toolBar->orientation() == Qt::Horizontal)
00071 option.state |= QStyle::State_Horizontal;
00072 option.lineWidth = toolBar->style()->pixelMetric(QStyle::PM_ToolBarFrameWidth);
00073 option.features = toolBar->isMovable() ? QStyleOptionToolBar::Movable : QStyleOptionToolBar::None;
00074
00075
00076 QMainWindow *mainWindow = qobject_cast<QMainWindow *>(toolBar->parent());
00077
00078 if (!mainWindow)
00079 return option;
00080
00081 QMainWindowLayout *layout = qobject_cast<QMainWindowLayout *>(mainWindow->layout());
00082 Q_ASSERT_X(layout != 0, "QToolBarPrivate::getStyleOption()",
00083 "QMainWindow->layout() != QMainWindowLayout");
00084
00085
00086 int layoutIndex = layout->indexOf(toolBar);
00087 if (layoutIndex != -1)
00088 option.toolBarArea = layout->toolBarArea(toolBar);
00089
00090
00091 int toolBarTotalLineCount = 0;
00092 int toolBarLineCount = 0;
00093
00094
00095 foreach (QMainWindowLayout::ToolBarLineInfo lineInfo, layout->tb_layout_info) {
00096
00097 if (lineInfo.pos != positionForArea(option.toolBarArea))
00098 continue;
00099 int toolBarIndex = -1;
00100 bool lineVisible = false;
00101
00102 for (int i = 0; i < lineInfo.list.size(); ++i){
00103 QMainWindowLayout::ToolBarLayoutInfo layoutInfo = lineInfo.list.at(i);
00104
00105 if (layoutInfo.item->widget()->isVisible())
00106 lineVisible = true;
00107
00108 if (layoutInfo.item->widget() == toolBar) {
00109
00110 toolBarLineCount = toolBarTotalLineCount;
00111
00112
00113 int visibleLines = 0;
00114 for (int j = 0; j < lineInfo.list.size(); ++j){
00115 QMainWindowLayout::ToolBarLayoutInfo info = lineInfo.list.at(j);
00116 if (info.item->widget() == toolBar)
00117 toolBarIndex = visibleLines;
00118 if (info.item->widget()->isVisible())
00119 visibleLines++;
00120 }
00121
00122
00123 if (toolBarIndex == 0) {
00124 if (visibleLines == 1)
00125 option.positionWithinLine = QStyleOptionToolBar::OnlyOne;
00126 else
00127 option.positionWithinLine = QStyleOptionToolBar::Beginning;
00128 } else if (toolBarIndex < visibleLines - 1) {
00129 option.positionWithinLine = QStyleOptionToolBar::Middle;
00130 } else if (toolBarIndex == visibleLines - 1) {
00131 option.positionWithinLine = QStyleOptionToolBar::End;
00132 }
00133 break;
00134 }
00135 }
00136 if(lineVisible)
00137 ++toolBarTotalLineCount;
00138 }
00139
00140 Q_ASSERT_X(toolBarLineCount >= 0, "QToolBarPrivate::getStyleOption()",
00141 "toolbar not found in layout");
00142
00143
00144
00145 if (option.toolBarArea== Qt::BottomToolBarArea || option.toolBarArea==Qt::RightToolBarArea){
00146 toolBarLineCount = toolBarTotalLineCount-toolBarLineCount-1;
00147 }
00148
00149
00150 if (toolBarLineCount == 0) {
00151 if (toolBarTotalLineCount == 1)
00152 option.positionOfLine = QStyleOptionToolBar::OnlyOne;
00153 else
00154 option.positionOfLine = QStyleOptionToolBar::Beginning;
00155 } else if (toolBarLineCount < toolBarTotalLineCount - 1) {
00156 option.positionOfLine = QStyleOptionToolBar::Middle;
00157 } else if (toolBarLineCount == toolBarTotalLineCount - 1) {
00158 option.positionOfLine = QStyleOptionToolBar::End;
00159 }
00160
00161 return option;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 void QToolBarPrivate::init()
00182 {
00183 Q_Q(QToolBar);
00184 movable = true;
00185 q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding));
00186 q->setBackgroundRole(QPalette::Button);
00187
00188
00189 QStyleOptionToolBar opt = getStyleOption(q);
00190
00191 QBoxLayout *layout = new QBoxLayout(QBoxLayout::LeftToRight, q);
00192 QStyle *style = q->style();
00193
00194 int e = style->pixelMetric(QStyle::PM_ToolBarIconSize);
00195 iconSize = QSize(e, e);
00196
00197 layout->setAlignment(Qt::AlignLeft);
00198 layout->setMargin(style->pixelMetric(QStyle::PM_ToolBarFrameWidth, &opt, q)
00199 + style->pixelMetric(QStyle::PM_ToolBarItemMargin, &opt, q));
00200 layout->setSpacing(style->pixelMetric(QStyle::PM_ToolBarItemSpacing, &opt, q));
00201
00202 handle = new QToolBarHandle(q);
00203 QObject::connect(q, SIGNAL(orientationChanged(Qt::Orientation)),
00204 handle, SLOT(setOrientation(Qt::Orientation)));
00205 layout->addWidget(handle);
00206 handle->setVisible(movable && (qobject_cast<QMainWindow *>(q->parentWidget()) != 0));
00207
00208 extension = new QToolBarExtension(q);
00209 QObject::connect(q, SIGNAL(orientationChanged(Qt::Orientation)),
00210 extension, SLOT(setOrientation(Qt::Orientation)));
00211 extension->setFocusPolicy(Qt::NoFocus);
00212 extension->hide();
00213
00214 #ifdef Q_WS_MAC
00215 if (q->parentWidget() && q->parentWidget()->isWindow()) {
00216
00217 reinterpret_cast<QToolBar *>(q->parentWidget())->d_func()->createWinId();
00218 extern WindowPtr qt_mac_window_for(const QWidget *);
00219 ChangeWindowAttributes(qt_mac_window_for(q->parentWidget()), kWindowToolbarButtonAttribute,
00220 kWindowNoAttributes);
00221 }
00222 #endif
00223
00224 toggleViewAction = new QAction(q);
00225 toggleViewAction->setCheckable(true);
00226 QObject::connect(toggleViewAction, SIGNAL(triggered(bool)), q, SLOT(_q_toggleView(bool)));
00227 }
00228
00229 void QToolBarPrivate::_q_toggleView(bool b)
00230 {
00231 Q_Q(QToolBar);
00232 if (b == q->isHidden()) {
00233 if (b)
00234 q->show();
00235 else
00236 q->close();
00237 }
00238 }
00239
00240 void QToolBarPrivate::_q_updateIconSize(const QSize &sz)
00241 {
00242 Q_Q(QToolBar);
00243 if (!explicitIconSize) {
00244
00245 q->setIconSize(sz);
00246 explicitIconSize = false;
00247 }
00248 }
00249
00250 void QToolBarPrivate::_q_updateToolButtonStyle(Qt::ToolButtonStyle style)
00251 {
00252 Q_Q(QToolBar);
00253 if (!explicitToolButtonStyle) {
00254 q->setToolButtonStyle(style);
00255 explicitToolButtonStyle = false;
00256 }
00257 }
00258
00259 QToolBarItem QToolBarPrivate::createItem(QAction *action)
00260 {
00261 Q_Q(QToolBar);
00262 QToolBarItem item;
00263 item.action = action;
00264 item.hidden = false;
00265 item.hasCustomWidget = false;
00266
00267 QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(action);
00268 if (widgetAction) {
00269 item.widget = widgetAction->requestWidget(q);
00270 if (item.widget) {
00271 item.hasCustomWidget = true;
00272 return item;
00273 }
00274 }
00275 if (action->isSeparator()) {
00276 item.widget = new QToolBarSeparator(q);
00277 QObject::connect(q, SIGNAL(orientationChanged(Qt::Orientation)),
00278 item.widget, SLOT(setOrientation(Qt::Orientation)));
00279 } else {
00280 QToolButton *button = new QToolButton(q);
00281 button->setAutoRaise(true);
00282 button->setFocusPolicy(Qt::NoFocus);
00283 button->setIconSize(iconSize);
00284 button->setToolButtonStyle(toolButtonStyle);
00285 QObject::connect(q, SIGNAL(iconSizeChanged(QSize)),
00286 button, SLOT(setIconSize(QSize)));
00287 QObject::connect(q, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
00288 button, SLOT(setToolButtonStyle(Qt::ToolButtonStyle)));
00289 button->setDefaultAction(action);
00290 QObject::connect(button, SIGNAL(triggered(QAction*)), q, SIGNAL(actionTriggered(QAction*)));
00291 item.widget = button;
00292 }
00293
00294 return item;
00295 }
00296
00297
00298
00299
00300
00301 int QToolBarPrivate::indexOf(QAction *action) const
00302 {
00303 for (int i = 0; i < items.size(); ++i) {
00304 const QToolBarItem &item = items.at(i);
00305 if (item.action == action)
00306 return i;
00307 }
00308 return -1;
00309 }
00310
00410 QToolBar::QToolBar(QWidget *parent)
00411 : QWidget(*new QToolBarPrivate, parent, 0)
00412 {
00413 Q_D(QToolBar);
00414 d->init();
00415 }
00416
00425 QToolBar::QToolBar(const QString &title, QWidget *parent)
00426 : QWidget(*new QToolBarPrivate, parent, 0)
00427 {
00428 Q_D(QToolBar);
00429 d->init();
00430 setWindowTitle(title);
00431 }
00432
00433 #ifdef QT3_SUPPORT
00434
00437 QToolBar::QToolBar(QWidget *parent, const char *name)
00438 : QWidget(*new QToolBarPrivate, parent, 0)
00439 {
00440 Q_D(QToolBar);
00441 d->init();
00442 setObjectName(QString::fromAscii(name));
00443 }
00444 #endif
00445
00449 QToolBar::~QToolBar()
00450 {
00451
00452 QMainWindow *mainwindow = qobject_cast<QMainWindow *>(parentWidget());
00453 if (mainwindow) {
00454 QMainWindowLayout *mainwin_layout = qobject_cast<QMainWindowLayout *>(mainwindow->layout());
00455 mainwin_layout->removeToolBarInfo(this);
00456 mainwin_layout->relayout();
00457 #ifdef Q_WS_MAC
00458 if (mainwin_layout && mainwin_layout->tb_layout_info.isEmpty()
00459 && mainwindow->testAttribute(Qt::WA_WState_Created))
00460 ChangeWindowAttributes(qt_mac_window_for(mainwindow), kWindowNoAttributes,
00461 kWindowToolbarButtonAttribute);
00462 #endif
00463 }
00464 Q_D(QToolBar);
00465 while (!d->items.isEmpty()) {
00466 const QToolBarItem item = d->items.takeFirst();
00467 QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(item.action);
00468 if (item.hasCustomWidget && widgetAction) {
00469 widgetAction->releaseWidget(item.widget);
00470 }
00471 }
00472 }
00473
00486 void QToolBar::setMovable(bool movable)
00487 {
00488 Q_D(QToolBar);
00489 if (!movable == !d->movable)
00490 return;
00491 d->movable = movable;
00492 d->handle->setVisible(d->movable && (qobject_cast<QMainWindow *>(parentWidget()) != 0));
00493 emit movableChanged(d->movable);
00494 }
00495
00496 bool QToolBar::isMovable() const
00497 { Q_D(const QToolBar); return d->movable; }
00498
00511 void QToolBar::setAllowedAreas(Qt::ToolBarAreas areas)
00512 {
00513 Q_D(QToolBar);
00514 areas &= Qt::ToolBarArea_Mask;
00515 if (areas == d->allowedAreas)
00516 return;
00517 d->allowedAreas = areas;
00518 emit allowedAreasChanged(d->allowedAreas);
00519 }
00520
00521 Qt::ToolBarAreas QToolBar::allowedAreas() const
00522 { Q_D(const QToolBar); return d->allowedAreas; }
00523
00533 void QToolBar::setOrientation(Qt::Orientation orientation)
00534 {
00535 Q_D(QToolBar);
00536 if (orientation == d->orientation)
00537 return;
00538
00539 d->orientation = orientation;
00540
00541 QBoxLayout *box = qobject_cast<QBoxLayout *>(layout());
00542 Q_ASSERT_X(box != 0, "QToolBar::setOrientation", "internal error");
00543
00544 switch (d->orientation) {
00545 case Qt::Vertical:
00546 box->setDirection(QBoxLayout::TopToBottom);
00547 box->setAlignment(Qt::AlignTop);
00548 setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
00549 break;
00550
00551 case Qt::Horizontal:
00552 box->setDirection(QBoxLayout::LeftToRight);
00553 box->setAlignment(Qt::AlignLeft);
00554 setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding));
00555 break;
00556 }
00557
00558 emit orientationChanged(d->orientation);
00559 }
00560
00561 Qt::Orientation QToolBar::orientation() const
00562 { Q_D(const QToolBar); return d->orientation; }
00563
00570 QSize QToolBar::iconSize() const
00571 { Q_D(const QToolBar); return d->iconSize; }
00572
00573 void QToolBar::setIconSize(const QSize &iconSize)
00574 {
00575 Q_D(QToolBar);
00576 QSize sz = iconSize;
00577 if (!sz.isValid()) {
00578 QMainWindow *mw = qobject_cast<QMainWindow *>(parentWidget());
00579 if (mw && mw->layout()) {
00580 QLayout *layout = mw->layout();
00581 int i = 0;
00582 QLayoutItem *item = 0;
00583 do {
00584 item = layout->itemAt(i++);
00585 if (item && (item->widget() == this))
00586 sz = mw->iconSize();
00587 } while (!sz.isValid() && item != 0);
00588 }
00589 }
00590 if (!sz.isValid()) {
00591 const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
00592 sz = QSize(metric, metric);
00593 }
00594 if (d->iconSize != sz) {
00595 d->iconSize = sz;
00596 setMinimumSize(0, 0);
00597 emit iconSizeChanged(d->iconSize);
00598 }
00599 d->explicitIconSize = iconSize.isValid();
00600 }
00601
00609 Qt::ToolButtonStyle QToolBar::toolButtonStyle() const
00610 { Q_D(const QToolBar); return d->toolButtonStyle; }
00611
00612 void QToolBar::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
00613 {
00614 Q_D(QToolBar);
00615 d->explicitToolButtonStyle = true;
00616 if (d->toolButtonStyle == toolButtonStyle)
00617 return;
00618 d->toolButtonStyle = toolButtonStyle;
00619 setMinimumSize(0, 0);
00620 emit toolButtonStyleChanged(d->toolButtonStyle);
00621 }
00622
00628 void QToolBar::clear()
00629 {
00630 QList<QAction *> actions = this->actions();
00631 for(int i = 0; i < actions.size(); i++)
00632 removeAction(actions.at(i));
00633 }
00634
00641 QAction *QToolBar::addAction(const QString &text)
00642 {
00643 QAction *action = new QAction(text, this);
00644 addAction(action);
00645 return action;
00646 }
00647
00654 QAction *QToolBar::addAction(const QIcon &icon, const QString &text)
00655 {
00656 QAction *action = new QAction(icon, text, this);
00657 addAction(action);
00658 return action;
00659 }
00660
00669 QAction *QToolBar::addAction(const QString &text,
00670 const QObject *receiver, const char* member)
00671 {
00672 QAction *action = new QAction(text, this);
00673 QObject::connect(action, SIGNAL(triggered()), receiver, member);
00674 addAction(action);
00675 return action;
00676 }
00677
00686 QAction *QToolBar::addAction(const QIcon &icon, const QString &text,
00687 const QObject *receiver, const char* member)
00688 {
00689 QAction *action = new QAction(icon, text, this);
00690 QObject::connect(action, SIGNAL(triggered()), receiver, member);
00691 addAction(action);
00692 return action;
00693 }
00694
00700 QAction *QToolBar::addSeparator()
00701 {
00702 QAction *action = new QAction(this);
00703 action->setSeparator(true);
00704 addAction(action);
00705 return action;
00706 }
00707
00714 QAction *QToolBar::insertSeparator(QAction *before)
00715 {
00716 QAction *action = new QAction(this);
00717 action->setSeparator(true);
00718 insertAction(before, action);
00719 return action;
00720 }
00721
00732 QAction *QToolBar::addWidget(QWidget *widget)
00733 {
00734 QWidgetAction *action = new QWidgetAction(this);
00735 action->setDefaultWidget(widget);
00736 action->d_func()->autoCreated = true;
00737 addAction(action);
00738 return action;
00739 }
00740
00751 QAction *QToolBar::insertWidget(QAction *before, QWidget *widget)
00752 {
00753 QWidgetAction *action = new QWidgetAction(this);
00754 action->setDefaultWidget(widget);
00755 action->d_func()->autoCreated = true;
00756 insertAction(before, action);
00757 return action;
00758 }
00759
00766 QRect QToolBar::actionGeometry(QAction *action) const
00767 {
00768 Q_D(const QToolBar);
00769 for (int i = 0; i < d->items.size(); ++i) {
00770 const QToolBarItem &item = d->items.at(i);
00771 if (item.action == action)
00772 return item.widget->geometry();
00773 }
00774 return QRect();
00775 }
00776
00783 QAction *QToolBar::actionAt(const QPoint &p) const
00784 {
00785 Q_D(const QToolBar);
00786 QWidget *widget = childAt(p);
00787 for (int i = 0; i < d->items.size(); ++i) {
00788 const QToolBarItem &item = d->items.at(i);
00789 if (item.widget == widget)
00790 return item.action;
00791 }
00792 return 0;
00793 }
00794
00803 void QToolBar::actionEvent(QActionEvent *event)
00804 {
00805 Q_D(QToolBar);
00806 QAction *action = event->action();
00807 QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(action);
00808
00809 switch (event->type()) {
00810 case QEvent::ActionAdded:
00811 {
00812 Q_ASSERT_X(!widgetAction || d->indexOf(widgetAction) == -1,
00813 "QToolBar", "widgets cannot be inserted multiple times");
00814
00815 QToolBarItem item = d->createItem(action);
00816 bool visible = item.action->isVisible();
00817
00818
00819
00820
00821
00822 if (widgetAction && widgetAction->d_func()->autoCreated)
00823 widgetAction->setParent(this);
00824
00825 item.widget->hide();
00826 if (event->before()) {
00827 int index = d->indexOf(event->before());
00828 Q_ASSERT_X(index >= 0 && index < d->items.size(), "QToolBar::insertAction",
00829 "internal error");
00830 d->items.insert(index, item);
00831 qobject_cast<QBoxLayout *>(layout())->insertWidget(index + 1, item.widget);
00832 } else {
00833 d->items.append(item);
00834 qobject_cast<QBoxLayout *>(layout())->insertWidget(d->items.size(), item.widget);
00835 }
00836 item.widget->setVisible(visible);
00837 if (isVisible())
00838 QApplication::postEvent(this, new QResizeEvent(size(), size()));
00839 break;
00840 }
00841
00842 case QEvent::ActionChanged:
00843 {
00844 int index = d->indexOf(action);
00845 Q_ASSERT_X(index >= 0 && index < d->items.size(),
00846 "QToolBar::actionEvent", "internal error");
00847 const QToolBarItem &item = d->items.at(index);
00848 if (!item.hidden) {
00849 item.widget->setVisible(item.action->isVisible());
00850 } else {
00851
00852 if (isVisible())
00853 QApplication::postEvent(this, new QResizeEvent(size(), size()));
00854 }
00855
00856 break;
00857 }
00858
00859 case QEvent::ActionRemoved:
00860 {
00861 int index = d->indexOf(action);
00862 Q_ASSERT_X(index >= 0 && index < d->items.size(),
00863 "QToolBar::removeAction", "internal error");
00864 QToolBarItem item = d->items.takeAt(index);
00865 layout()->removeWidget(item.widget);
00866 if (widgetAction && item.hasCustomWidget) {
00867 widgetAction->releaseWidget(item.widget);
00868 } else {
00869
00870 item.widget->hide();
00871 item.widget->deleteLater();
00872 }
00873
00874
00875 for (int i = 0; i< d->items.size(); ++i)
00876 d->items[i].widget->show();
00877
00878 if (isVisible())
00879 QApplication::postEvent(this, new QResizeEvent(size(), size()));
00880 break;
00881 }
00882
00883 default:
00884 Q_ASSERT_X(false, "QToolBar::actionEvent", "internal error");
00885 }
00886 }
00887
00889 void QToolBar::changeEvent(QEvent *event)
00890 {
00891 Q_D(QToolBar);
00892 switch (event->type()) {
00893 case QEvent::WindowTitleChange:
00894 d->toggleViewAction->setText(windowTitle());
00895 break;
00896 case QEvent::StyleChange:
00897 {
00898 QStyleOptionToolBar opt = getStyleOption(this);
00899 d->layout->setMargin(style()->pixelMetric(QStyle::PM_ToolBarFrameWidth, &opt, this)
00900 + style()->pixelMetric(QStyle::PM_ToolBarItemMargin, &opt, this));
00901 d->layout->setSpacing(style()->pixelMetric(QStyle::PM_ToolBarItemSpacing, &opt, this));
00902 break;
00903 }
00904 default:
00905 break;
00906 }
00907 QWidget::changeEvent(event);
00908 }
00909
00911 void QToolBar::childEvent(QChildEvent *event)
00912 {
00913 Q_D(QToolBar);
00914 QWidget *widget = qobject_cast<QWidget *>(event->child());
00915 if (widget && event->type() == QEvent::ChildRemoved) {
00916 for (int i = 0; i < d->items.size(); ++i) {
00917 const QToolBarItem &item = d->items.at(i);
00918 QWidgetAction *widgetAction = 0;
00919 if (item.widget == widget
00920 && (widgetAction = qobject_cast<QWidgetAction *>(item.action))) {
00921 removeAction(widgetAction);
00922
00923
00924 }
00925 }
00926 }
00927 QWidget::childEvent(event);
00928 }
00929
00931 void QToolBar::paintEvent(QPaintEvent *event)
00932 {
00933 Q_UNUSED(event);
00934 QPainter p(this);
00935 QStyleOptionToolBar opt = getStyleOption(this);
00936 style()->drawControl(QStyle::CE_ToolBar, &opt, &p, this);
00937 }
00938
00940 void QToolBar::resizeEvent(QResizeEvent *event)
00941 {
00942 Q_D(QToolBar);
00943 if (d->inResizeEvent)
00944 return;
00945 d->inResizeEvent = true;
00946
00947 QBoxLayout *box = qobject_cast<QBoxLayout *>(layout());
00948 Qt::Orientation orientation = (box->direction() == QBoxLayout::LeftToRight
00949 || box->direction() == QBoxLayout::RightToLeft)
00950 ? Qt::Horizontal
00951 : Qt::Vertical;
00952 const int margin = box->margin();
00953 int i = 0;
00954 int extension_size = 0;
00955 int hidden_count = 0;
00956 int max_item_extent = 0;
00957 i = d->items.size();
00958 while (i > 0) {
00959 QWidget *w = box->itemAt(i)->widget();
00960 bool hide = false;
00961 if (QApplication::layoutDirection() == Qt::RightToLeft && orientation == Qt::Horizontal) {
00962 if (w->isHidden()) {
00963 if (box->itemAt(i-1) && !box->itemAt(i-1)->widget()->isHidden()) {
00964 QWidget *pw = box->itemAt(i-1)->widget();
00965 hide = pw->pos().x() < (extension_size + w->size().width() + margin + box->spacing());
00966 } else {
00967
00968 int pos = 0;
00969 for (int k = 1; k < i; ++k) {
00970 QWidget * pw = box->itemAt(k)->widget();
00971 if (pw == w)
00972 break;
00973 pos = pw->isHidden()
00974 ? pos - pw->size().width() - box->spacing()
00975 : pw->pos().x();
00976 }
00977 pos = pos - w->size().width() - box->spacing();
00978 hide = pos < extension_size + margin;
00979 }
00980 } else {
00981 hide = w->pos().x() < extension_size + margin;
00982 }
00983 } else {
00984 hide = pick(orientation, w->pos()) + pick(orientation, w->size())
00985 >= pick(orientation, size()) - extension_size;
00986 }
00987 if (hide && i > 1) {
00988 w->hide();
00989 if (d->items[i - 1].action->isVisible()) {
00990 d->items[i - 1].hidden = true;
00991 ++hidden_count;
00992 }
00993
00994
00995 extension_size = pick(orientation, d->extension->sizeHint());
00996 } else {
00997 w->setVisible(d->items[i - 1].action->isVisible());
00998 d->items[i - 1].hidden = false;
00999 if (orientation == Qt::Horizontal)
01000 max_item_extent = qMax(max_item_extent, w->sizeHint().height());
01001 else
01002 max_item_extent = qMax(max_item_extent, w->sizeHint().width());
01003 }
01004 --i;
01005 }
01006
01007 int box_spacing = (d->items.size() > 1) ? box->spacing()*2 : box->spacing();
01008 int item_min_size = (orientation == Qt::Horizontal) ? d->iconSize.width() : d->iconSize.height();
01009 if (!d->items.isEmpty()) {
01010 QSize sz(d->items[0].widget->sizeHint());
01011 #ifndef QT_NO_MENUBAR
01012 if (qobject_cast<QMenuBar *>(d->items[0].widget))
01013 sz = d->items[0].widget->minimumSizeHint();
01014 #endif
01015 item_min_size = (orientation == Qt::Horizontal) ? sz.width() : sz.height();
01016 }
01017 if (orientation == Qt::Horizontal) {
01018 setMinimumSize(d->handle->sizeHint().width() + box_spacing + extension_size + margin*2
01019 + item_min_size, max_item_extent + margin*2);
01020 } else {
01021 setMinimumSize(max_item_extent + margin*2,
01022 d->handle->sizeHint().height() + box_spacing + extension_size
01023 + margin*2 + item_min_size);
01024 }
01025
01026 if (hidden_count > 0) {
01027 if (orientation == Qt::Horizontal) {
01028 int x = QApplication::layoutDirection() == Qt::RightToLeft
01029 ? margin
01030 : width() - d->extension->sizeHint().width() - margin;
01031 d->extension->setGeometry(x, margin, d->extension->sizeHint().width(), max_item_extent);
01032 } else {
01033 d->extension->setGeometry(margin,
01034 height() - d->extension->sizeHint().height() - margin,
01035 max_item_extent,
01036 d->extension->sizeHint().height());
01037 }
01038
01039 #ifndef QT_NO_MENU
01040 QMenu *pop = d->extension->menu();
01041 if (!pop) {
01042 pop = new QMenu(this);
01043 d->extension->setMenu(pop);
01044 }
01045 pop->clear();
01046 for(int i = 0; i < d->items.size(); ++i) {
01047 const QToolBarItem &item = d->items.at(i);
01048 if (!item.hidden) continue;
01049
01050 if (!qobject_cast<QWidgetAction *>(item.action)) {
01051 pop->addAction(item.action);
01052 } else {
01053 #if !defined(QT_NO_SIGNALMAPPER) && !defined(QT_NO_COMBOBOX)
01054 if (QComboBox *cb = qobject_cast<QComboBox *>(item.widget)) {
01055 QMenu *cb_menu = new QMenu(cb->windowTitle(), pop);
01056 QSignalMapper *cb_mapper = new QSignalMapper(cb_menu);
01057 pop->addMenu(cb_menu);
01058 QActionGroup *ag = new QActionGroup(cb_menu);
01059 ag->setExclusive(true);
01060 for (int i=0; i<cb->count(); ++i) {
01061 QAction *ac = cb_menu->addAction(cb->itemIcon(i), cb->itemText(i));
01062 ac->setActionGroup(ag);
01063 ac->setCheckable(true);
01064 ac->setChecked(cb->currentIndex() == i);
01065 connect(ac, SIGNAL(triggered(bool)), cb_mapper, SLOT(map()));
01066 cb_mapper->setMapping(ac, i);
01067 cb_mapper->setMapping(ac, cb->itemText(i));
01068 }
01069 connect(cb_mapper, SIGNAL(mapped(int)), cb, SIGNAL(activated(int)));
01070 connect(cb_mapper, SIGNAL(mapped(int)), cb, SLOT(setCurrentIndex(int)));
01071 connect(cb_mapper, SIGNAL(mapped(QString)), cb, SIGNAL(activated(QString)));
01072 } else
01073 #endif // QT_NO_SIGNALMAPPER
01074 if (QToolButton *tb = qobject_cast<QToolButton *>(item.widget)) {
01075 QAction *ac = pop->addAction(tb->icon(), tb->text());
01076 connect(ac, SIGNAL(triggered()), tb, SLOT(click()));
01077 } else {
01078 QList<QAbstractButton *> children = qFindChildren<QAbstractButton *>(item.widget);
01079 QList<QAbstractButton *>::const_iterator it = children.constBegin();
01080 while (it != children.constEnd()) {
01081 QAction *ac = pop->addAction((*it)->icon(), (*it)->text());
01082 ac->setCheckable((*it)->isCheckable());
01083 ac->setChecked((*it)->isChecked());
01084 ac->setEnabled((*it)->isEnabled());
01085 connect(ac, SIGNAL(triggered()), *it, SLOT(click()));
01086 ++it;
01087 }
01088 }
01089 }
01090 }
01091 if (pop->actions().size() > 0) {
01092 d->extension->show();
01093 d->extension->setEnabled(true);
01094 } else {
01095
01096
01097
01098 d->extension->show();
01099 d->extension->setEnabled(false);
01100 }
01101 #endif // QT_NO_MENU
01102 } else if (!d->extension->isHidden()) {
01103 if (d->extension->menu())
01104 d->extension->menu()->clear();
01105 d->extension->hide();
01106 }
01107 QWidget::resizeEvent(event);
01108
01109 d->inResizeEvent = false;
01110 }
01111
01113 bool QToolBar::event(QEvent *event)
01114 {
01115 Q_D(QToolBar);
01116
01117 switch (event->type()) {
01118 case QEvent::Hide:
01119 if (!isHidden())
01120 break;
01121
01122 case QEvent::Show:
01123 d->toggleViewAction->setChecked(event->type() == QEvent::Show);
01124 break;
01125 case QEvent::ParentChange:
01126 d->handle->setVisible(d->movable && (qobject_cast<QMainWindow *>(parentWidget()) != 0));
01127 break;
01128 case QEvent::StyleChange:
01129 if (!d->explicitIconSize)
01130 setIconSize(QSize());
01131 break;
01132 default:
01133 break;
01134 }
01135 return QWidget::event(event);
01136 }
01137
01146 QAction *QToolBar::toggleViewAction() const
01147 { Q_D(const QToolBar); return d->toggleViewAction; }
01148
01168 QWidget *QToolBar::widgetForAction(QAction *action) const
01169 {
01170 Q_D(const QToolBar);
01171
01172 int index = d->indexOf(action);
01173 if (index < 0 || index >= d->items.size())
01174 return 0;
01175
01176 return d->items.at(index).widget;
01177 }
01178
01179 #include "moc_qtoolbar.cpp"
01180 #endif // QT_NO_TOOLBAR