diff options
Diffstat (limited to 'src/gui/widgets')
54 files changed, 658 insertions, 254 deletions
diff --git a/src/gui/widgets/qabstractbutton.cpp b/src/gui/widgets/qabstractbutton.cpp index 354677d..57e517a 100644 --- a/src/gui/widgets/qabstractbutton.cpp +++ b/src/gui/widgets/qabstractbutton.cpp @@ -319,7 +319,7 @@ QList<QAbstractButton *>QAbstractButtonPrivate::queryButtonList() const return group->d_func()->buttonList; #endif - QList<QAbstractButton*>candidates = qFindChildren<QAbstractButton *>(parent); + QList<QAbstractButton*>candidates = parent->findChildren<QAbstractButton *>(); if (autoExclusive) { for (int i = candidates.count() - 1; i >= 0; --i) { QAbstractButton *candidate = candidates.at(i); diff --git a/src/gui/widgets/qabstractslider_p.h b/src/gui/widgets/qabstractslider_p.h index d32335f..fdbc0f9 100644 --- a/src/gui/widgets/qabstractslider_p.h +++ b/src/gui/widgets/qabstractslider_p.h @@ -117,7 +117,7 @@ public: ; } - inline int bound(int val) const { return qMax(minimum, qMin(maximum, val)); } + virtual int bound(int val) const { return qMax(minimum, qMin(maximum, val)); } inline int overflowSafeAdd(int add) const { int newValue = value + add; diff --git a/src/gui/widgets/qcheckbox.cpp b/src/gui/widgets/qcheckbox.cpp index 81270fc..9904a15 100644 --- a/src/gui/widgets/qcheckbox.cpp +++ b/src/gui/widgets/qcheckbox.cpp @@ -300,6 +300,15 @@ QSize QCheckBox::sizeHint() const return d->sizeHint; } + +/*! + \reimp +*/ +QSize QCheckBox::minimumSizeHint() const +{ + return sizeHint(); +} + /*! \reimp */ diff --git a/src/gui/widgets/qcheckbox.h b/src/gui/widgets/qcheckbox.h index 38ac143..263fa4a 100644 --- a/src/gui/widgets/qcheckbox.h +++ b/src/gui/widgets/qcheckbox.h @@ -65,6 +65,7 @@ public: QSize sizeHint() const; + QSize minimumSizeHint() const; void setTristate(bool y = true); bool isTristate() const; diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index e40404e..95075b9 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -44,9 +44,11 @@ #ifdef QT_MAC_USE_COCOA #import <private/qcocoamenu_mac_p.h> #import <private/qcocoamenuloader_mac_p.h> +#import <private/qcocoaapplication_mac_p.h> #include <private/qt_cocoa_helpers_mac_p.h> #include <private/qapplication_p.h> #include <private/qaction_p.h> +#include <private/qcocoaapplication_mac_p.h> #include <QtGui/QMenu> @@ -60,6 +62,7 @@ QT_FORWARD_DECLARE_CLASS(QEvent) QT_BEGIN_NAMESPACE extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication.cpp +extern NSString *qt_mac_removePrivateUnicode(NSString* string); QT_END_NAMESPACE QT_USE_NAMESPACE @@ -78,7 +81,7 @@ QT_USE_NAMESPACE return self; } -- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item; +- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item { Q_UNUSED(menu); @@ -99,7 +102,7 @@ QT_USE_NAMESPACE } } -- (void)menuWillOpen:(NSMenu*)menu; +- (void)menuWillOpen:(NSMenu*)menu { while (QWidget *popup = QApplication::activePopupWidget()) @@ -109,7 +112,7 @@ QT_USE_NAMESPACE qt_mac_menu_collapseSeparators(menu, qtmenu->separatorsCollapsible()); } -- (void)menuDidClose:(NSMenu*)menu; +- (void)menuDidClose:(NSMenu*)menu { qt_mac_emit_menuSignals(((QT_MANGLE_NAMESPACE(QCocoaMenu) *)menu)->qmenu, false); if (previousAction) { @@ -156,10 +159,13 @@ QT_USE_NAMESPACE // In every other case we return NO, which means that Cocoa can do as it pleases // (i.e., fire the menu action). NSMenuItem *whichItem; + // Change the private unicode keys to the ones used in setting the "Key Equivalents" + NSString *characters = qt_mac_removePrivateUnicode([event characters]); if ([self hasShortcut:menu - forKey:[event characters] - forModifiers:([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) - whichItem:&whichItem]) { + forKey:characters + // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ... + forModifiers:([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask)) + whichItem:&whichItem]) { QWidget *widget = 0; QAction *qaction = 0; if (whichItem && [whichItem tag]) { @@ -170,6 +176,9 @@ QT_USE_NAMESPACE qApp->activePopupWidget()->focusWidget() : qApp->activePopupWidget()); else if (QApplicationPrivate::focus_widget) widget = QApplicationPrivate::focus_widget; + // If we could not find any receivers, pass it to the active window + if (!widget) + widget = qApp->activeWindow(); if (qaction && widget) { int key = qaction->shortcut(); QKeyEvent accel_ev(QEvent::ShortcutOverride, (key & (~Qt::KeyboardModifierMask)), @@ -177,11 +186,10 @@ QT_USE_NAMESPACE accel_ev.ignore(); qt_sendSpontaneousEvent(widget, &accel_ev); if (accel_ev.isAccepted()) { - if (qt_dispatchKeyEvent(event, widget)) { - *target = nil; - *action = nil; - return YES; - } + qt_dispatchKeyEvent(event, widget); + *target = nil; + *action = nil; + return YES; } } } diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index f4a627b..621cae9 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -116,7 +116,7 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt QPalette resolvedpalette = option.palette.resolve(QApplication::palette("QMenu")); QVariant value = index.data(Qt::ForegroundRole); - if (qVariantCanConvert<QBrush>(value)) { + if (value.canConvert<QBrush>()) { resolvedpalette.setBrush(QPalette::WindowText, qvariant_cast<QBrush>(value)); resolvedpalette.setBrush(QPalette::ButtonText, qvariant_cast<QBrush>(value)); resolvedpalette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value)); @@ -152,7 +152,7 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt menuOption.icon = qvariant_cast<QPixmap>(variant); break; } - if (qVariantCanConvert<QBrush>(index.data(Qt::BackgroundRole))) { + if (index.data(Qt::BackgroundRole).canConvert<QBrush>()) { menuOption.palette.setBrush(QPalette::All, QPalette::Background, qvariant_cast<QBrush>(index.data(Qt::BackgroundRole))); } @@ -369,6 +369,7 @@ void QComboBoxPrivateContainer::timerEvent(QTimerEvent *timerEvent) if (timerEvent->timerId() == adjustSizeTimer.timerId()) { adjustSizeTimer.stop(); if (combo->sizeAdjustPolicy() == QComboBox::AdjustToContents) { + combo->updateGeometry(); combo->adjustSize(); combo->update(); } @@ -1093,6 +1094,8 @@ void QComboBoxPrivate::updateViewContainerPaletteAndOpacity() container->setPalette(q->palette()); container->setWindowOpacity(1.0); } + if (lineEdit) + lineEdit->setPalette(q->palette()); } /*! @@ -1303,7 +1306,7 @@ QComboBox::~QComboBox() By default, this property has a value of 10. \note This property is ignored for non-editable comboboxes in styles that returns - false for QStyle::SH_ComboBox_Popup such as the Mac style or the Gtk+ Style. + true for QStyle::SH_ComboBox_Popup such as the Mac style or the Gtk+ Style. */ int QComboBox::maxVisibleItems() const { @@ -2013,11 +2016,18 @@ void QComboBox::setCurrentIndex(int index) void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi) { Q_Q(QComboBox); - bool indexChanged = (mi != currentIndex); + + QModelIndex normalized; + if (mi.column() != modelColumn) + normalized = model->index(mi.row(), modelColumn, mi.parent()); + if (!normalized.isValid()) + normalized = mi; // Fallback to passed index. + + bool indexChanged = (normalized != currentIndex); if (indexChanged) - currentIndex = QPersistentModelIndex(mi); + currentIndex = QPersistentModelIndex(normalized); if (lineEdit) { - QString newText = q->itemText(currentIndex.row()); + QString newText = q->itemText(normalized.row()); if (lineEdit->text() != newText) lineEdit->setText(newText); updateLineEditGeometry(); @@ -2353,7 +2363,12 @@ void QComboBox::showPopup() initStyleOption(&opt); QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxListBoxPopup, this)); +#ifndef Q_WS_S60 QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this)); +#else + QRect screen = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()); +#endif + QPoint below = mapToGlobal(listRect.bottomLeft()); int belowHeight = screen.bottom() - below.y(); QPoint above = mapToGlobal(listRect.topLeft()); @@ -2476,18 +2491,10 @@ void QComboBox::showPopup() listRect.setWidth(listRect.height()); //by default popup is centered on screen in landscape listRect.moveCenter(screen.center()); - if (staConTopRect.IsEmpty()) { - TRect cbaRect = TRect(); - AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, cbaRect); - AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation(); - switch (cbaLocation) { - case AknLayoutUtils::EAknCbaLocationRight: - listRect.setRight(screen.right()); - break; - case AknLayoutUtils::EAknCbaLocationLeft: - listRect.setLeft(screen.left()); - break; - } + if (staConTopRect.IsEmpty() && AknLayoutUtils::CbaLocation() != AknLayoutUtils::EAknCbaLocationBottom) { + // landscape without stacon, menu should be at the right + (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : + listRect.setLeft(screen.left()); } } #endif @@ -2706,7 +2713,7 @@ void QComboBox::changeEvent(QEvent *e) initStyleOption(&opt); if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { - const QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this)); + QRect screen = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()); QRect listRect(style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxListBoxPopup, this)); @@ -2721,13 +2728,14 @@ void QComboBox::changeEvent(QEvent *e) listRect.setWidth(listRect.height()); //by default popup is centered on screen in landscape listRect.moveCenter(screen.center()); - if (staConTopRect.IsEmpty()) { + if (staConTopRect.IsEmpty() && AknLayoutUtils::CbaLocation() != AknLayoutUtils::EAknCbaLocationBottom) { // landscape without stacon, menu should be at the right (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : listRect.setLeft(screen.left()); } - d->container->setGeometry(listRect); } + + d->container->setGeometry(listRect); } } #endif @@ -2760,6 +2768,10 @@ void QComboBox::changeEvent(QEvent *e) void QComboBox::resizeEvent(QResizeEvent *) { Q_D(QComboBox); +#ifdef Q_WS_S60 + if (d->viewContainer() && d->viewContainer()->isVisible()) + showPopup(); +#endif d->updateLineEditGeometry(); } diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h index c08d83f..9cbf483 100644 --- a/src/gui/widgets/qcombobox.h +++ b/src/gui/widgets/qcombobox.h @@ -68,7 +68,7 @@ class Q_GUI_EXPORT QComboBox : public QWidget Q_PROPERTY(bool editable READ isEditable WRITE setEditable) Q_PROPERTY(int count READ count) Q_PROPERTY(QString currentText READ currentText) - Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged USER true) Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems) Q_PROPERTY(int maxCount READ maxCount WRITE setMaxCount) Q_PROPERTY(InsertPolicy insertPolicy READ insertPolicy WRITE setInsertPolicy) diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h index e1bb1fb..a17f9d9 100644 --- a/src/gui/widgets/qcombobox_p.h +++ b/src/gui/widgets/qcombobox_p.h @@ -337,7 +337,7 @@ private: QComboBox *mCombo; }; -class QComboBoxPrivate : public QWidgetPrivate +class Q_AUTOTEST_EXPORT QComboBoxPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QComboBox) public: diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp index 61ae21e..d9ff8a6 100644 --- a/src/gui/widgets/qdatetimeedit.cpp +++ b/src/gui/widgets/qdatetimeedit.cpp @@ -890,7 +890,13 @@ void QDateTimeEdit::setDisplayFormat(const QString &format) const bool dateShown = (d->sections & DateSections_Mask); Q_ASSERT(dateShown || timeShown); if (timeShown && !dateShown) { + QTime time = d->value.toTime(); setDateRange(d->value.toDate(), d->value.toDate()); + if (d->minimum.toTime() >= d->maximum.toTime()) { + setTimeRange(QDATETIMEEDIT_TIME_MIN, QDATETIMEEDIT_TIME_MAX); + // if the time range became invalid during the adjustment, the time would have been reset + setTime(time); + } } else if (dateShown && !timeShown) { setTimeRange(QDATETIMEEDIT_TIME_MIN, QDATETIMEEDIT_TIME_MAX); d->value = QDateTime(d->value.toDate(), QTime(), d->spec); @@ -1654,6 +1660,15 @@ void QDateTimeEditPrivate::updateTimeSpec() minimum = minimum.toDateTime().toTimeSpec(spec); maximum = maximum.toDateTime().toTimeSpec(spec); value = value.toDateTime().toTimeSpec(spec); + + // time zone changes can lead to 00:00:00 becomes 01:00:00 and 23:59:59 becomes 00:59:59 (invalid range) + const bool dateShown = (sections & QDateTimeEdit::DateSections_Mask); + if (!dateShown) { + if (minimum.toTime() >= maximum.toTime()){ + minimum = QDateTime(value.toDate(), QDATETIMEEDIT_TIME_MIN, spec); + maximum = QDateTime(value.toDate(), QDATETIMEEDIT_TIME_MAX, spec); + } + } } void QDateTimeEditPrivate::updateEdit() @@ -2523,20 +2538,32 @@ void QDateTimeEditPrivate::syncCalendarWidget() } QCalendarPopup::QCalendarPopup(QWidget * parent, QCalendarWidget *cw) - : QWidget(parent, Qt::Popup), calendar(0) + : QWidget(parent, Qt::Popup) { setAttribute(Qt::WA_WindowPropagation); dateChanged = false; if (!cw) { - cw = new QCalendarWidget(this); + verifyCalendarInstance(); + } else { + setCalendarWidget(cw); + } +} + +QCalendarWidget *QCalendarPopup::verifyCalendarInstance() +{ + if (calendar.isNull()) { + QCalendarWidget *cw = new QCalendarWidget(this); cw->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader); #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled()) cw->setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames); #endif + setCalendarWidget(cw); + return cw; + } else { + return calendar.data(); } - setCalendarWidget(cw); } void QCalendarPopup::setCalendarWidget(QCalendarWidget *cw) @@ -2548,28 +2575,29 @@ void QCalendarPopup::setCalendarWidget(QCalendarWidget *cw) widgetLayout->setMargin(0); widgetLayout->setSpacing(0); } - delete calendar; - calendar = cw; - widgetLayout->addWidget(calendar); + delete calendar.data(); + calendar = QWeakPointer<QCalendarWidget>(cw); + widgetLayout->addWidget(cw); - connect(calendar, SIGNAL(activated(QDate)), this, SLOT(dateSelected(QDate))); - connect(calendar, SIGNAL(clicked(QDate)), this, SLOT(dateSelected(QDate))); - connect(calendar, SIGNAL(selectionChanged()), this, SLOT(dateSelectionChanged())); + connect(cw, SIGNAL(activated(QDate)), this, SLOT(dateSelected(QDate))); + connect(cw, SIGNAL(clicked(QDate)), this, SLOT(dateSelected(QDate))); + connect(cw, SIGNAL(selectionChanged()), this, SLOT(dateSelectionChanged())); - calendar->setFocus(); + cw->setFocus(); } void QCalendarPopup::setDate(const QDate &date) { oldDate = date; - calendar->setSelectedDate(date); + verifyCalendarInstance()->setSelectedDate(date); } void QCalendarPopup::setDateRange(const QDate &min, const QDate &max) { - calendar->setMinimumDate(min); - calendar->setMaximumDate(max); + QCalendarWidget *cw = verifyCalendarInstance(); + cw->setMinimumDate(min); + cw->setMaximumDate(max); } void QCalendarPopup::mousePressEvent(QMouseEvent *event) @@ -2605,7 +2633,7 @@ bool QCalendarPopup::event(QEvent *event) void QCalendarPopup::dateSelectionChanged() { dateChanged = true; - emit newDateSelected(calendar->selectedDate()); + emit newDateSelected(verifyCalendarInstance()->selectedDate()); } void QCalendarPopup::dateSelected(const QDate &date) { diff --git a/src/gui/widgets/qdatetimeedit_p.h b/src/gui/widgets/qdatetimeedit_p.h index 164b8a5..3c6ca96 100644 --- a/src/gui/widgets/qdatetimeedit_p.h +++ b/src/gui/widgets/qdatetimeedit_p.h @@ -148,11 +148,11 @@ class QCalendarPopup : public QWidget Q_OBJECT public: QCalendarPopup(QWidget *parent = 0, QCalendarWidget *cw = 0); - QDate selectedDate() { return calendar->selectedDate(); } + QDate selectedDate() { return verifyCalendarInstance()->selectedDate(); } void setDate(const QDate &date); void setDateRange(const QDate &min, const QDate &max); - void setFirstDayOfWeek(Qt::DayOfWeek dow) { calendar->setFirstDayOfWeek(dow); } - QCalendarWidget *calendarWidget() const { return calendar; } + void setFirstDayOfWeek(Qt::DayOfWeek dow) { verifyCalendarInstance()->setFirstDayOfWeek(dow); } + QCalendarWidget *calendarWidget() const { return const_cast<QCalendarPopup*>(this)->verifyCalendarInstance(); } void setCalendarWidget(QCalendarWidget *cw); Q_SIGNALS: void activated(const QDate &date); @@ -171,7 +171,9 @@ protected: bool event(QEvent *e); private: - QCalendarWidget *calendar; + QCalendarWidget *verifyCalendarInstance(); + + QWeakPointer<QCalendarWidget> calendar; QDate oldDate; bool dateChanged; }; diff --git a/src/gui/widgets/qdial.cpp b/src/gui/widgets/qdial.cpp index f653589..e2b1983 100644 --- a/src/gui/widgets/qdial.cpp +++ b/src/gui/widgets/qdial.cpp @@ -83,6 +83,7 @@ public: int valueFromPoint(const QPoint &) const; double angle(const QPoint &, const QPoint &) const; void init(); + virtual int bound(int val) const; }; void QDialPrivate::init() @@ -97,6 +98,20 @@ void QDialPrivate::init() #endif } +int QDialPrivate::bound(int val) const +{ + if (wrapping) { + if ((val >= minimum) && (val <= maximum)) + return val; + val = minimum + ((val - minimum) % (maximum - minimum)); + if (val < minimum) + val += maximum - minimum; + return val; + } else { + return QAbstractSliderPrivate::bound(val); + } +} + /*! Initialize \a option with the values from this QDial. This method is useful for subclasses when they need a QStyleOptionSlider, but don't want diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp index 04673a3..6c29141 100644 --- a/src/gui/widgets/qdialogbuttonbox.cpp +++ b/src/gui/widgets/qdialogbuttonbox.cpp @@ -562,6 +562,14 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut } else { qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); } + +#ifdef Q_WS_MAC + // Since mnemonics is off by default on Mac, we add a Cmd-D + // shortcut here to e.g. make the "Don't Save" button work nativly: + if (sbutton == QDialogButtonBox::Discard) + button->setShortcut(QKeySequence(QLatin1String("Ctrl+D"))); +#endif + return button; } @@ -1229,7 +1237,7 @@ bool QDialogButtonBox::event(QEvent *event) break; } - foreach (QPushButton *pb, qFindChildren<QPushButton *>(dialog ? dialog : this)) { + foreach (QPushButton *pb, (dialog ? dialog : this)->findChildren<QPushButton *>()) { if (pb->isDefault() && pb != firstAcceptButton) { hasDefault = true; break; diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index e1c054b..83506e5 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -2100,7 +2100,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const bool gap = false; int tab_idx = 0; - bool changed = false; for (int i = 0; i < item_list.count(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) @@ -2121,7 +2120,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const tabBar->setTabToolTip(tab_idx, title); #endif tabBar->setTabData(tab_idx, id); - changed = true; } else if (qvariant_cast<quintptr>(tabBar->tabData(tab_idx)) != id) { if (tab_idx + 1 < tabBar->count() && qvariant_cast<quintptr>(tabBar->tabData(tab_idx + 1)) == id) @@ -2133,7 +2131,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const #endif tabBar->setTabData(tab_idx, id); } - changed = true; } if (title != tabBar->tabText(tab_idx)) { @@ -2141,7 +2138,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const #ifndef QT_NO_TOOLTIP tabBar->setTabToolTip(tab_idx, title); #endif - changed = true; } ++tab_idx; @@ -2149,7 +2145,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const while (tab_idx < tabBar->count()) { tabBar->removeTab(tab_idx); - changed = true; } tabBar->blockSignals(blocked); diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp index 6436c84..6e37683 100644 --- a/src/gui/widgets/qdockwidget.cpp +++ b/src/gui/widgets/qdockwidget.cpp @@ -161,7 +161,6 @@ void QDockWidgetTitleButton::paintEvent(QPaintEvent *) { QPainter p(this); - QRect r = rect(); QStyleOptionToolButton opt; opt.init(this); opt.state |= QStyle::State_AutoRaise; diff --git a/src/gui/widgets/qeffects.cpp b/src/gui/widgets/qeffects.cpp index 6d86464..adf1cc1 100644 --- a/src/gui/widgets/qeffects.cpp +++ b/src/gui/widgets/qeffects.cpp @@ -55,19 +55,6 @@ QT_BEGIN_NAMESPACE /* - Internal class to get access to protected QWidget-members -*/ - -class QAccessWidget : public QWidget -{ - friend class QAlphaWidget; - friend class QRollEffect; -public: - QAccessWidget(QWidget* parent=0, Qt::WindowFlags f = 0) - : QWidget(parent, f) {} -}; - -/* Internal class QAlphaWidget. The QAlphaWidget is shown while the animation lasts @@ -98,13 +85,12 @@ private: QImage backImage; QImage frontImage; QImage mixedImage; - QPointer<QAccessWidget> widget; + QPointer<QWidget> widget; int duration; int elapsed; bool showWidget; QTimer anim; QElapsedTimer checkTime; - double windowOpacity; }; static QAlphaWidget* q_blend = 0; @@ -119,8 +105,7 @@ QAlphaWidget::QAlphaWidget(QWidget* w, Qt::WindowFlags f) setEnabled(false); #endif setAttribute(Qt::WA_NoSystemBackground, true); - widget = (QAccessWidget*)w; - windowOpacity = w->windowOpacity(); + widget = w; alpha = 0; } @@ -129,7 +114,7 @@ QAlphaWidget::~QAlphaWidget() #if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) // Restore user-defined opacity value if (widget) - widget->setWindowOpacity(windowOpacity); + widget->setWindowOpacity(1); #endif } @@ -268,10 +253,10 @@ void QAlphaWidget::render() alpha = 1; #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - if (alpha >= windowOpacity || !showWidget) { + if (alpha >= 1 || !showWidget) { anim.stop(); qApp->removeEventFilter(this); - widget->setWindowOpacity(windowOpacity); + widget->setWindowOpacity(1); q_blend = 0; deleteLater(); } else { @@ -370,7 +355,7 @@ private slots: void scroll(); private: - QPointer<QAccessWidget> widget; + QPointer<QWidget> widget; int currentHeight; int currentWidth; @@ -401,7 +386,7 @@ QRollEffect::QRollEffect(QWidget* w, Qt::WindowFlags f, DirFlags orient) setEnabled(false); #endif - widget = (QAccessWidget*) w; + widget = w; Q_ASSERT(widget); setAttribute(Qt::WA_NoSystemBackground, true); diff --git a/src/gui/widgets/qfocusframe.cpp b/src/gui/widgets/qfocusframe.cpp index fb0f316..b41a71a 100644 --- a/src/gui/widgets/qfocusframe.cpp +++ b/src/gui/widgets/qfocusframe.cpp @@ -85,6 +85,9 @@ void QFocusFramePrivate::update() void QFocusFramePrivate::updateSize() { Q_Q(QFocusFrame); + if (!widget) + return; + int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin), hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin); QPoint pos(widget->x(), widget->y()); diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp index f2a6965..26dd0e1 100644 --- a/src/gui/widgets/qlabel.cpp +++ b/src/gui/widgets/qlabel.cpp @@ -1072,7 +1072,7 @@ void QLabel::paintEvent(QPaintEvent *) else #endif if (d->isTextLabel) { - QRectF lr = d->layoutRect(); + QRectF lr = d->layoutRect().toAlignedRect(); QStyleOption opt; opt.initFrom(this); #ifndef QT_NO_STYLE_STYLESHEET diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 1432f24..bf36033 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -112,7 +112,7 @@ void QLineControl::updateDisplayText(bool forceUpdate) Copies the currently selected text into the clipboard using the given \a mode. - + \note If the echo mode is set to a mode other than Normal then copy will not work. This is to prevent using copy as a method of bypassing password features of the line control. @@ -503,7 +503,7 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event) /*! \internal - Draws the display text for the line control using the given + Draws the display text for the line control using the given \a painter, \a clip, and \a offset. Which aspects of the display text are drawn is specified by the given \a flags. @@ -653,7 +653,12 @@ void QLineControl::internalSetText(const QString &txt, int pos, bool edited) m_modifiedState = m_undoState = 0; m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos; m_textDirty = (oldText != m_text); - finishChange(-1, true, edited); + bool changed = finishChange(-1, true, edited); + +#ifndef QT_NO_ACCESSIBILITY + if (changed) + QAccessible::updateAccessibility(parent(), 0, QAccessible::TextUpdated); +#endif } @@ -1240,6 +1245,9 @@ void QLineControl::emitCursorPositionChanged() const int oldLast = m_lastCursorPos; m_lastCursorPos = m_cursor; cursorPositionChanged(oldLast, m_cursor); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(parent(), 0, QAccessible::TextCaretMoved); +#endif } } @@ -1587,6 +1595,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event) } bool unknown = false; + bool visual = cursorMoveStyle() == Qt::VisualMoveStyle; if (false) { } @@ -1651,11 +1660,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event) #endif moveCursor(selectionEnd(), false); } else { - cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1); + cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1)); } } else if (event == QKeySequence::SelectNextChar) { - cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1); + cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1)); } else if (event == QKeySequence::MoveToPreviousChar) { #if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER) @@ -1666,11 +1675,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event) #endif moveCursor(selectionStart(), false); } else { - cursorForward(0, layoutDirection() == Qt::LeftToRight ? -1 : 1); + cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1)); } } else if (event == QKeySequence::SelectPreviousChar) { - cursorForward(1, layoutDirection() == Qt::LeftToRight ? -1 : 1); + cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1)); } else if (event == QKeySequence::MoveToNextWord) { if (echoMode() == QLineEdit::Normal) diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index e318b0a..cca4bfa 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -61,10 +61,10 @@ #include "QtGui/qtextlayout.h" #include "QtGui/qstyleoption.h" #include "QtCore/qpointer.h" -#include "QtGui/qlineedit.h" #include "QtGui/qclipboard.h" #include "QtCore/qpoint.h" #include "QtGui/qcompleter.h" +#include "QtGui/qaccessible.h" QT_BEGIN_HEADER @@ -160,6 +160,8 @@ public: int cursorWidth() const { return m_cursorWidth; } void setCursorWidth(int value) { m_cursorWidth = value; } + Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); } + void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); } void moveCursor(int pos, bool mark = false); void cursorForward(bool mark, int steps) @@ -167,10 +169,12 @@ public: int c = m_cursor; if (steps > 0) { while (steps--) - c = m_textLayout.nextCursorPosition(c); + c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c) + : m_textLayout.nextCursorPosition(c); } else if (steps < 0) { while (steps++) - c = m_textLayout.previousCursorPosition(c); + c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c) + : m_textLayout.previousCursorPosition(c); } moveCursor(c, mark); } diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 4d683fb..8a93c28 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1112,6 +1112,34 @@ void QLineEdit::setDragEnabled(bool b) /*! + \property QLineEdit::cursorMoveStyle + \brief the movement style of cursor in this line edit + \since 4.8 + + When this property is set to Qt::VisualMoveStyle, the line edit will use visual + movement style. Pressing the left arrow key will always cause the cursor to move + left, regardless of the text's writing direction. The same behavior applies to + right arrow key. + + When the property is Qt::LogicalMoveStyle (the default), within a LTR text block, + increase cursor position when pressing left arrow key, decrease cursor position + when pressing the right arrow key. If the text block is right to left, the opposite + behavior applies. +*/ + +Qt::CursorMoveStyle QLineEdit::cursorMoveStyle() const +{ + Q_D(const QLineEdit); + return d->control->cursorMoveStyle(); +} + +void QLineEdit::setCursorMoveStyle(Qt::CursorMoveStyle style) +{ + Q_D(QLineEdit); + d->control->setCursorMoveStyle(style); +} + +/*! \property QLineEdit::acceptableInput \brief whether the input satisfies the inputMask and the validator. diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index 9daa94e..73d2289 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -43,6 +43,7 @@ #define QLINEEDIT_H #include <QtGui/qframe.h> +#include <QtGui/qtextcursor.h> #include <QtCore/qstring.h> #include <QtCore/qmargins.h> @@ -84,6 +85,7 @@ class Q_GUI_EXPORT QLineEdit : public QWidget Q_PROPERTY(bool redoAvailable READ isRedoAvailable) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput) Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText) + Q_PROPERTY(Qt::CursorMoveStyle cursorMoveStyle READ cursorMoveStyle WRITE setCursorMoveStyle) public: explicit QLineEdit(QWidget* parent=0); @@ -158,6 +160,9 @@ public: void setDragEnabled(bool b); bool dragEnabled() const; + void setCursorMoveStyle(Qt::CursorMoveStyle style); + Qt::CursorMoveStyle cursorMoveStyle() const; + QString inputMask() const; void setInputMask(const QString &inputMask); bool hasAcceptableInput() const; @@ -283,6 +288,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_editFocusChange(bool)) #endif Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_updateNeeded(const QRect &)) }; #endif // QT_NO_LINEEDIT diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp index c6ce7da..090c0b6 100644 --- a/src/gui/widgets/qlineedit_p.cpp +++ b/src/gui/widgets/qlineedit_p.cpp @@ -59,6 +59,13 @@ QT_BEGIN_NAMESPACE const int QLineEditPrivate::verticalMargin(1); const int QLineEditPrivate::horizontalMargin(2); +QRect QLineEditPrivate::adjustedControlRect(const QRect &rect) const +{ + QRect cr = adjustedContentsRect(); + int cix = cr.x() - hscroll + horizontalMargin; + return rect.translated(QPoint(cix, vscroll)); +} + int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const { QRect cr = adjustedContentsRect(); @@ -68,11 +75,7 @@ int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const QRect QLineEditPrivate::cursorRect() const { - QRect cr = adjustedContentsRect(); - int cix = cr.x() - hscroll + horizontalMargin; - QRect crect = control->cursorRect(); - crect.moveTo(crect.topLeft() + QPoint(cix, vscroll)); - return crect; + return adjustedControlRect(control->cursorRect()); } #ifndef QT_NO_COMPLETER @@ -141,10 +144,16 @@ void QLineEditPrivate::_q_selectionChanged() emit q->selectionChanged(); } +void QLineEditPrivate::_q_updateNeeded(const QRect &rect) +{ + q_func()->update(adjustedControlRect(rect)); +} + void QLineEditPrivate::init(const QString& txt) { Q_Q(QLineEdit); control = new QLineControl(txt); + control->setParent(q); control->setFont(q->font()); QObject::connect(control, SIGNAL(textChanged(QString)), q, SIGNAL(textChanged(QString))); @@ -176,7 +185,7 @@ void QLineEditPrivate::init(const QString& txt) q, SLOT(update())); QObject::connect(control, SIGNAL(updateNeeded(QRect)), - q, SLOT(update())); + q, SLOT(_q_updateNeeded(QRect))); QStyleOptionFrameV2 opt; q->initStyleOption(&opt); @@ -216,9 +225,8 @@ void QLineEditPrivate::setCursorVisible(bool visible) if ((bool)cursorVisible == visible) return; cursorVisible = visible; - QRect r = cursorRect(); if (control->inputMask().isEmpty()) - q->update(r); + q->update(cursorRect()); else q->update(); } diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h index c0d2044..f396af6 100644 --- a/src/gui/widgets/qlineedit_p.h +++ b/src/gui/widgets/qlineedit_p.h @@ -84,7 +84,6 @@ public: ~QLineEditPrivate() { - delete control; } QLineControl *control; @@ -94,6 +93,8 @@ public: #endif void init(const QString&); + QRect adjustedControlRect(const QRect &) const; + int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const; QRect cursorRect() const; void setCursorVisible(bool visible); @@ -129,6 +130,7 @@ public: void _q_editFocusChange(bool); #endif void _q_selectionChanged(); + void _q_updateNeeded(const QRect &); #ifndef QT_NO_COMPLETER void _q_completionHighlighted(QString); #endif diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 3b073e9..8f468c6 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -1514,15 +1514,28 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set) if (!isWindow() || d->useHIToolBar == set || QSysInfo::MacintoshVersion < QSysInfo::MV_10_3) return; - // ### Disable the unified toolbar when using anything but the native graphics system. - // ### Disable when using alien widgets as well - if (windowSurface() || testAttribute(Qt::WA_NativeWindow) == false) - return; - d->useHIToolBar = set; createWinId(); // We need the hiview for down below. +#ifdef QT_MAC_USE_COCOA + // Activate the unified toolbar with the raster engine. + if (windowSurface() && set) { + d->layout->unifiedSurface = new QUnifiedToolbarSurface(this); + } +#endif // QT_MAC_USE_COCOA + d->layout->updateHIToolBarStatus(); + +#ifdef QT_MAC_USE_COCOA + // Deactivate the unified toolbar with the raster engine. + if (windowSurface() && !set) { + if (d->layout->unifiedSurface) { + delete d->layout->unifiedSurface; + d->layout->unifiedSurface = 0; + } + } +#endif // QT_MAC_USE_COCOA + // Enabling the unified toolbar clears the opaque size grip setting, update it. d->macUpdateOpaqueSizeGrip(); #else @@ -1632,7 +1645,7 @@ QMenu *QMainWindow::createPopupMenu() Q_D(QMainWindow); QMenu *menu = 0; #ifndef QT_NO_DOCKWIDGET - QList<QDockWidget *> dockwidgets = qFindChildren<QDockWidget *>(this); + QList<QDockWidget *> dockwidgets = findChildren<QDockWidget *>(); if (dockwidgets.size()) { menu = new QMenu(this); for (int i = 0; i < dockwidgets.size(); ++i) { @@ -1646,7 +1659,7 @@ QMenu *QMainWindow::createPopupMenu() } #endif // QT_NO_DOCKWIDGET #ifndef QT_NO_TOOLBAR - QList<QToolBar *> toolbars = qFindChildren<QToolBar *>(this); + QList<QToolBar *> toolbars = findChildren<QToolBar *>(); if (toolbars.size()) { if (!menu) menu = new QMenu(this); diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index f5b2805..fbde3a9 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -73,6 +73,10 @@ # include <private/qt_cocoa_helpers_mac_p.h> #endif +#ifdef QT_NO_DOCKWIDGET +extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window); +#endif + #ifdef Q_DEBUG_MAINWINDOW_LAYOUT # include <QTextStream> #endif diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 591841f..28e8764 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -43,6 +43,7 @@ #include <qtoolbar.h> #include <private/qtoolbarlayout_p.h> #include <private/qt_cocoa_helpers_mac_p.h> +#include <private/qtoolbar_p.h> #ifndef QT_MAC_USE_COCOA #include <Carbon/Carbon.h> @@ -354,7 +355,11 @@ void QMainWindowLayout::updateHIToolBarStatus() // Move everything out of the HIToolbar into the main toolbar. while (!qtoolbarsInUnifiedToolbarList.isEmpty()) { // Should shrink the list by one every time. - layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, qtoolbarsInUnifiedToolbarList.first()); + QToolBar *toolbar = qtoolbarsInUnifiedToolbarList.first(); +#if defined(QT_MAC_USE_COCOA) + unifiedSurface->removeToolbar(toolbar); +#endif + layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar); } macWindowToolbarSet(qt_mac_window_for(layoutState.mainWindow), 0); } else { @@ -362,7 +367,8 @@ void QMainWindowLayout::updateHIToolBarStatus() for (int i = 0; i < toolbars.size(); ++i) { QToolBar *toolbar = toolbars.at(i); if (toolBarArea(toolbar) == Qt::TopToolBarArea) { - removeWidget(toolbar); // Do this here, because we are in an in-between state. + // Do this here, because we are in an in-between state. + removeWidget(toolbar); layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar); } } @@ -386,10 +392,20 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar if (toolbar == 0) return; +#if defined(QT_MAC_USE_COCOA) + // toolbar will now become native (if not already) since we need + // an nsview for it inside the corresponding NSToolbarItem. + // Setting isInUnifiedToolbar will (among other things) stop alien + // siblings from becoming native when this happends since the toolbar + // will not overlap with other children of the QMainWindow. NB: Switching + // unified toolbar off after this stage is not supported, as this means + // that either the menubar must be alien again, or the sibling must + // be backed by an nsview to protect from overlapping issues: + toolbar->d_func()->isInUnifiedToolbar = true; +#endif QToolBarLayout *toolbarLayout = static_cast<QToolBarLayout *>(toolbar->layout()); - toolbarSaveState.insert(toolbar, ToolBarSaveState(toolbar->isMovable(), - toolbar->maximumSize())); + toolbarSaveState.insert(toolbar, ToolBarSaveState(toolbar->isMovable(), toolbar->maximumSize())); if (toolbarLayout->hasExpandFlag() == false) toolbar->setMaximumSize(toolbar->sizeHint()); @@ -398,8 +414,8 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar toolbarLayout->setUsePopupMenu(true); // Make the toolbar a child of the mainwindow to avoid creating a window. toolbar->setParent(layoutState.mainWindow); - toolbar->createWinId(); // Now create the OSViewRef. + toolbar->winId(); // Now create the OSViewRef. layoutState.mainWindow->createWinId(); OSWindowRef window = qt_mac_window_for(layoutState.mainWindow); @@ -408,6 +424,7 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar beforeIndex = qtoolbarsInUnifiedToolbarList.size(); int toolbarIndex = qtoolbarsInUnifiedToolbarList.indexOf(toolbar); + #ifndef QT_MAC_USE_COCOA HIToolbarRef macToolbar = NULL; if ((GetWindowToolbar(window, &macToolbar) == noErr) && !macToolbar) { @@ -444,6 +461,18 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar #endif } qtoolbarsInUnifiedToolbarList.insert(beforeIndex, toolbar); + + // Adding to the unified toolbar surface for the raster engine. + if (layoutState.mainWindow->windowSurface()) { + QPoint offset(0, 0); + for (int i = 0; i < beforeIndex; ++i) { + offset.setX(offset.x() + qtoolbarsInUnifiedToolbarList.at(i)->size().width()); + } +#ifdef QT_MAC_USE_COCOA + unifiedSurface->insertToolbar(toolbar, offset); +#endif // QT_MAC_USE_COCOA + } + #ifndef QT_MAC_USE_COCOA QCFType<HIToolbarItemRef> outItem; const QObject *stupidArray[] = { toolbar, this }; @@ -460,6 +489,19 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar #endif } +#ifdef QT_MAC_USE_COCOA +void QMainWindowLayout::updateUnifiedToolbarOffset() +{ + QPoint offset(0, 0); + + for (int i = 1; i < qtoolbarsInUnifiedToolbarList.length(); ++i) { + offset.setX(offset.x() + qtoolbarsInUnifiedToolbarList.at(i - 1)->size().width()); + qtoolbarsInUnifiedToolbarList.at(i)->d_func()->toolbar_offset = offset; + } +} +#endif // QT_MAC_USE_COCOA + + void QMainWindowLayout::removeFromMacToolbar(QToolBar *toolbar) { QHash<void *, QToolBar *>::iterator it = unifiedToolbarHash.begin(); @@ -533,11 +575,11 @@ void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const QMacCocoaAutoReleasePool pool; QWidgetItem layoutItem(tb); QSize size = layoutItem.maximumSize(); - NSSize nssize = NSMakeSize(size.width(), size.height() - 2); + NSSize nssize = NSMakeSize(size.width(), size.height()); [item setMaxSize:nssize]; size = layoutItem.minimumSize(); nssize.width = size.width(); - nssize.height = size.height() - 2; + nssize.height = size.height(); [item setMinSize:nssize]; } #else diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index d32ca80..14ec1fb 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -70,12 +70,12 @@ //#define Q_DEBUG_MAINWINDOW_LAYOUT -#ifdef Q_DEBUG_MAINWINDOW_LAYOUT +#if defined(Q_DEBUG_MAINWINDOW_LAYOUT) && !defined(QT_NO_DOCKWIDGET) QT_BEGIN_NAMESPACE class QTextStream; Q_GUI_EXPORT void qt_dumpLayout(QTextStream &qout, QMainWindow *window); QT_END_NAMESPACE -#endif // Q_DEBUG_MAINWINDOW_LAYOUT +#endif // Q_DEBUG_MAINWINDOW_LAYOUT && !QT_NO_DOCKWIDGET #ifdef Q_WS_MAC // Forward defs to make avoid including Carbon.h (faster compile you know ;). @@ -85,7 +85,11 @@ typedef HIObjectRef HIToolbarItemRef; typedef const void * CFTypeRef; typedef const struct __CFString * CFStringRef; -#endif +# ifdef QT_MAC_USE_COCOA +#include <private/qunifiedtoolbarsurface_mac_p.h> +# endif // QT_MAC_USE_COCOA + +#endif // Q_WS_MAC QT_BEGIN_NAMESPACE @@ -337,7 +341,13 @@ public: bool activateUnifiedToolbarAfterFullScreen; void syncUnifiedToolbarVisibility(); bool blockVisiblityCheck; -#endif + +#ifdef QT_MAC_USE_COCOA + QUnifiedToolbarSurface *unifiedSurface; + void updateUnifiedToolbarOffset(); +#endif // QT_MAC_USE_COCOA + +#endif // Q_WS_MAC }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qmdiarea.cpp b/src/gui/widgets/qmdiarea.cpp index 4e587eb..fde683d 100644 --- a/src/gui/widgets/qmdiarea.cpp +++ b/src/gui/widgets/qmdiarea.cpp @@ -674,6 +674,8 @@ QMdiAreaPrivate::QMdiAreaPrivate() viewMode(QMdiArea::SubWindowView), #ifndef QT_NO_TABBAR documentMode(false), + tabsClosable(false), + tabsMovable(false), #endif #ifndef QT_NO_TABWIDGET tabShape(QTabWidget::Rounded), @@ -792,6 +794,27 @@ void QMdiAreaPrivate::_q_currentTabChanged(int index) #endif // QT_NO_TABBAR } +void QMdiAreaPrivate::_q_closeTab(int index) +{ +#ifdef QT_NO_TABBAR + Q_UNUSED(index); +#else + QMdiSubWindow *subWindow = childWindows.at(index); + Q_ASSERT(subWindow); + subWindow->close(); +#endif // QT_NO_TABBAR +} + +void QMdiAreaPrivate::_q_moveTab(int from, int to) +{ +#ifdef QT_NO_TABBAR + Q_UNUSED(from); + Q_UNUSED(to); +#else + childWindows.move(from, to); +#endif // QT_NO_TABBAR +} + /*! \internal */ @@ -1519,6 +1542,8 @@ void QMdiAreaPrivate::setViewMode(QMdiArea::ViewMode mode) Q_ASSERT(!tabBar); tabBar = new QMdiAreaTabBar(q); tabBar->setDocumentMode(documentMode); + tabBar->setTabsClosable(tabsClosable); + tabBar->setMovable(tabsMovable); #ifndef QT_NO_TABWIDGET tabBar->setShape(tabBarShapeFrom(tabShape, tabPosition)); #endif @@ -1550,6 +1575,8 @@ void QMdiAreaPrivate::setViewMode(QMdiArea::ViewMode mode) updateTabBarGeometry(); QObject::connect(tabBar, SIGNAL(currentChanged(int)), q, SLOT(_q_currentTabChanged(int))); + QObject::connect(tabBar, SIGNAL(tabCloseRequested(int)), q, SLOT(_q_closeTab(int))); + QObject::connect(tabBar, SIGNAL(tabMoved(int,int)), q, SLOT(_q_moveTab(int,int))); } else #endif // QT_NO_TABBAR { // SubWindowView @@ -1636,6 +1663,8 @@ void QMdiAreaPrivate::refreshTabBar() return; tabBar->setDocumentMode(documentMode); + tabBar->setTabsClosable(tabsClosable); + tabBar->setMovable(tabsMovable); #ifndef QT_NO_TABWIDGET tabBar->setShape(tabBarShapeFrom(tabShape, tabPosition)); #endif @@ -2114,6 +2143,56 @@ void QMdiArea::setDocumentMode(bool enabled) d->documentMode = enabled; d->refreshTabBar(); } + +/*! + \property QMdiArea::tabsClosable + \brief whether the tab bar should place close buttons on each tab in tabbed view mode. + \since 4.8 + + Tabs are not closable by default. + + \sa QTabBar::tabsClosable, setViewMode() +*/ +bool QMdiArea::tabsClosable() const +{ + Q_D(const QMdiArea); + return d->tabsClosable; +} + +void QMdiArea::setTabsClosable(bool closable) +{ + Q_D(QMdiArea); + if (d->tabsClosable == closable) + return; + + d->tabsClosable = closable; + d->refreshTabBar(); +} + +/*! + \property QMdiArea::tabsMovable + \brief whether the user can move the tabs within the tabbar area in tabbed view mode. + \since 4.8 + + Tabs are not movable by default. + + \sa QTabBar::tabsMovable, setViewMode() +*/ +bool QMdiArea::tabsMovable() const +{ + Q_D(const QMdiArea); + return d->tabsMovable; +} + +void QMdiArea::setTabsMovable(bool movable) +{ + Q_D(QMdiArea); + if (d->tabsMovable == movable) + return; + + d->tabsMovable = movable; + d->refreshTabBar(); +} #endif // QT_NO_TABBAR #ifndef QT_NO_TABWIDGET diff --git a/src/gui/widgets/qmdiarea.h b/src/gui/widgets/qmdiarea.h index 3b14eee..48c1c7b 100644 --- a/src/gui/widgets/qmdiarea.h +++ b/src/gui/widgets/qmdiarea.h @@ -65,6 +65,8 @@ class Q_GUI_EXPORT QMdiArea : public QAbstractScrollArea Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode) #ifndef QT_NO_TABBAR Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode) + Q_PROPERTY(bool tabsClosable READ tabsClosable WRITE setTabsClosable) + Q_PROPERTY(bool tabsMovable READ tabsMovable WRITE setTabsMovable) #endif #ifndef QT_NO_TABWIDGET Q_PROPERTY(QTabWidget::TabShape tabShape READ tabShape WRITE setTabShape) @@ -116,6 +118,12 @@ public: #ifndef QT_NO_TABBAR bool documentMode() const; void setDocumentMode(bool enabled); + + void setTabsClosable(bool closable); + bool tabsClosable() const; + + void setTabsMovable(bool movable); + bool tabsMovable() const; #endif #ifndef QT_NO_TABWIDGET void setTabShape(QTabWidget::TabShape shape); @@ -156,7 +164,9 @@ private: Q_DECLARE_PRIVATE(QMdiArea) Q_PRIVATE_SLOT(d_func(), void _q_deactivateAllWindows()) Q_PRIVATE_SLOT(d_func(), void _q_processWindowStateChanged(Qt::WindowStates, Qt::WindowStates)) - Q_PRIVATE_SLOT(d_func(), void _q_currentTabChanged(int index)) + Q_PRIVATE_SLOT(d_func(), void _q_currentTabChanged(int)) + Q_PRIVATE_SLOT(d_func(), void _q_closeTab(int)) + Q_PRIVATE_SLOT(d_func(), void _q_moveTab(int, int)) }; Q_DECLARE_OPERATORS_FOR_FLAGS(QMdiArea::AreaOptions) diff --git a/src/gui/widgets/qmdiarea_p.h b/src/gui/widgets/qmdiarea_p.h index faaf48a..fe368f2 100644 --- a/src/gui/widgets/qmdiarea_p.h +++ b/src/gui/widgets/qmdiarea_p.h @@ -165,6 +165,8 @@ public: QMdiArea::ViewMode viewMode; #ifndef QT_NO_TABBAR bool documentMode; + bool tabsClosable; + bool tabsMovable; #endif #ifndef QT_NO_TABWIDGET QTabWidget::TabShape tabShape; @@ -189,6 +191,8 @@ public: void _q_deactivateAllWindows(QMdiSubWindow *aboutToActivate = 0); void _q_processWindowStateChanged(Qt::WindowStates oldState, Qt::WindowStates newState); void _q_currentTabChanged(int index); + void _q_closeTab(int index); + void _q_moveTab(int from, int to); // Functions. void appendChild(QMdiSubWindow *child); diff --git a/src/gui/widgets/qmdisubwindow.cpp b/src/gui/widgets/qmdisubwindow.cpp index e8175a9..5cbd620 100644 --- a/src/gui/widgets/qmdisubwindow.cpp +++ b/src/gui/widgets/qmdisubwindow.cpp @@ -2203,7 +2203,7 @@ void QMdiSubWindowPrivate::setSizeGrip(QSizeGrip *newSizeGrip) void QMdiSubWindowPrivate::setSizeGripVisible(bool visible) const { // See if we can find any size grips - QList<QSizeGrip *> sizeGrips = qFindChildren<QSizeGrip *>(q_func()); + QList<QSizeGrip *> sizeGrips = q_func()->findChildren<QSizeGrip *>(); foreach (QSizeGrip *grip, sizeGrips) grip->setVisible(visible); } @@ -2319,7 +2319,7 @@ void QMdiSubWindow::setWidget(QWidget *widget) widget->setParent(this); #ifndef QT_NO_SIZEGRIP - QSizeGrip *sizeGrip = qFindChild<QSizeGrip *>(widget); + QSizeGrip *sizeGrip = widget->findChild<QSizeGrip *>(); if (sizeGrip) sizeGrip->installEventFilter(this); if (d->sizeGrip) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 118c073..a490286 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -240,6 +240,12 @@ QList<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const void QMenuPrivate::updateActionRects() const { Q_Q(const QMenu); + updateActionRects(popupGeometry(q)); +} + +void QMenuPrivate::updateActionRects(const QRect &screen) const +{ + Q_Q(const QMenu); if (!itemsDirty) return; @@ -249,20 +255,10 @@ void QMenuPrivate::updateActionRects() const actionRects.resize(actions.count()); actionRects.fill(QRect()); - //let's try to get the last visible action - int lastVisibleAction = actions.count() - 1; - for(;lastVisibleAction >= 0; --lastVisibleAction) { - const QAction *action = actions.at(lastVisibleAction); - if (action->isVisible()) { - //removing trailing separators - if (action->isSeparator() && collapsibleSeparators) - continue; - break; - } - } + int lastVisibleAction = getLastVisibleAction(); int max_column_width = 0, - dh = popupGeometry(q).height(), + dh = screen.height(), y = 0; QStyle *style = q->style(); QStyleOption opt; @@ -363,7 +359,6 @@ void QMenuPrivate::updateActionRects() const const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin)); max_column_width = qMax(min_column_width, max_column_width); - //calculate position const int base_y = vmargin + fw + topmargin + (scroll ? scroll->scrollOffset : 0) + @@ -394,6 +389,34 @@ void QMenuPrivate::updateActionRects() const itemsDirty = 0; } +QSize QMenuPrivate::adjustMenuSizeForScreen(const QRect &screen) +{ + Q_Q(QMenu); + QSize ret = screen.size(); + itemsDirty = true; + updateActionRects(screen); + const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); + ret.setWidth(actionRects.at(getLastVisibleAction()).right() + fw); + return ret; +} + +int QMenuPrivate::getLastVisibleAction() const +{ + //let's try to get the last visible action + int lastVisibleAction = actions.count() - 1; + for (;lastVisibleAction >= 0; --lastVisibleAction) { + const QAction *action = actions.at(lastVisibleAction); + if (action->isVisible()) { + //removing trailing separators + if (action->isSeparator() && collapsibleSeparators) + continue; + break; + } + } + return lastVisibleAction; +} + + QRect QMenuPrivate::actionRect(QAction *act) const { int index = actions.indexOf(act); @@ -1825,9 +1848,20 @@ void QMenu::popup(const QPoint &p, QAction *atAction) else #endif screen = d->popupGeometry(QApplication::desktop()->screenNumber(p)); - const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this); bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen); + + // if the screens have very different geometries and the menu is too big, we have to recalculate + if (size.height() > screen.height() || size.width() > screen.width()) { + size = d->adjustMenuSizeForScreen(screen); + adjustToDesktop = true; + } + // Layout is not right, we might be able to save horizontal space + if (d->ncols >1 && size.height() < screen.height()) { + size = d->adjustMenuSizeForScreen(screen); + adjustToDesktop = true; + } + #ifdef QT_KEYPAD_NAVIGATION if (!atAction && QApplication::keypadNavigationEnabled()) { // Try to have one item activated @@ -1921,6 +1955,27 @@ void QMenu::popup(const QPoint &p, QAction *atAction) } } } + const int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this); + const QSize menuSize(sizeHint()); + QMenu *caused = qobject_cast<QMenu*>(d_func()->causedPopup.widget); + if (caused && caused->geometry().width() + menuSize.width() + subMenuOffset < screen.width()) { + QRect parentActionRect(caused->d_func()->actionRect(caused->d_func()->currentAction)); + const QPoint actionTopLeft = caused->mapToGlobal(parentActionRect.topLeft()); + parentActionRect.moveTopLeft(actionTopLeft); + if (isRightToLeft()) { + if ((pos.x() + menuSize.width() > parentActionRect.left() - subMenuOffset) + && (pos.x() < parentActionRect.right())) + { + pos.rx() = parentActionRect.right(); + } + } else { + if ((pos.x() < parentActionRect.right() + subMenuOffset) + && (pos.x() + menuSize.width() > parentActionRect.left())) + { + pos.rx() = parentActionRect.left() - menuSize.width(); + } + } + } setGeometry(QRect(pos, size)); #ifndef QT_NO_EFFECTS int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll; @@ -2799,7 +2854,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e) if (d->sloppyRegion.contains(e->pos())) { d->sloppyAction = action; QMenuPrivate::sloppyDelayTimer = startTimer(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6); - } else { + } else if (action != d->currentAction) { d->setCurrentAction(action, style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)); } } @@ -2953,28 +3008,8 @@ void QMenu::internalDelayedPopup() const QRect actionRect(d->actionRect(d->currentAction)); const QSize menuSize(d->activeMenu->sizeHint()); const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top()))); - const QPoint leftPos(mapToGlobal(QPoint(actionRect.left() - subMenuOffset - menuSize.width(), actionRect.top()))); QPoint pos(rightPos); - QMenu *caused = qobject_cast<QMenu*>(d->activeMenu->d_func()->causedPopup.widget); - - const QRect availGeometry(d->popupGeometry(caused)); - if (isRightToLeft()) { - pos = leftPos; - if ((caused && caused->x() < x()) || pos.x() < availGeometry.left()) { - if(rightPos.x() + menuSize.width() < availGeometry.right()) - pos = rightPos; - else - pos.rx() = availGeometry.left(); - } - } else { - if ((caused && caused->x() > x()) || pos.x() + menuSize.width() > availGeometry.right()) { - if(leftPos.x() < availGeometry.left()) - pos.rx() = availGeometry.right() - menuSize.width(); - else - pos = leftPos; - } - } //calc sloppy focus buffer if (style()->styleHint(QStyle::SH_Menu_SloppySubMenus, 0, this)) { diff --git a/src/gui/widgets/qmenu.h b/src/gui/widgets/qmenu.h index 7c552a6..053fdee 100644 --- a/src/gui/widgets/qmenu.h +++ b/src/gui/widgets/qmenu.h @@ -51,6 +51,10 @@ #include <QtGui/qpixmap.h> #endif +#ifdef Q_WS_WINCE +#include <windef.h> // for HMENU +#endif + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 9f7b130..9db068c 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -1254,15 +1254,11 @@ QMenuPrivate::QMacMenuPrivate::addAction(QMacMenuAction *action, QMacMenuAction NSString *keySequenceToKeyEqivalent(const QKeySequence &accel) { quint32 accel_key = (accel[0] & ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL)); - extern QChar qt_macSymbolForQtKey(int key); // qkeysequence.cpp - QChar keyEquiv = qt_macSymbolForQtKey(accel_key); - if (keyEquiv.isNull()) { - if (accel_key >= Qt::Key_F1 && accel_key <= Qt::Key_F15) - keyEquiv = (accel_key - Qt::Key_F1) + NSF1FunctionKey; - else - keyEquiv = unichar(QChar(accel_key).toLower().unicode()); - } - return [NSString stringWithCharacters:&keyEquiv.unicode() length:1]; + extern QChar qtKey2CocoaKey(Qt::Key key); + QChar cocoa_key = qtKey2CocoaKey(Qt::Key(accel_key)); + if (cocoa_key.isNull()) + cocoa_key = QChar(accel_key).toLower().unicode(); + return [NSString stringWithCharacters:&cocoa_key.unicode() length:1]; } // return the cocoa modifier mask for the QKeySequence (currently only looks at the first one). @@ -2052,8 +2048,7 @@ bool QMenuBar::macUpdateMenuBar() { #ifdef QT_MAC_USE_COCOA QMacCocoaAutoReleasePool pool; - if (!qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar))) - return QMenuBarPrivate::macUpdateMenuBarImmediatly(); + qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar)); return true; #else return QMenuBarPrivate::macUpdateMenuBarImmediatly(); diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 809555d..0e63799 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -194,10 +194,13 @@ public: mutable QVector<QRect> actionRects; mutable QHash<QAction *, QWidget *> widgetItems; void updateActionRects() const; + void updateActionRects(const QRect &screen) const; QRect popupGeometry(const QWidget *widget) const; QRect popupGeometry(int screen = -1) const; mutable uint ncols : 4; //4 bits is probably plenty uint collapsibleSeparators : 1; + QSize adjustMenuSizeForScreen(const QRect & screen); + int getLastVisibleAction() const; bool activationRecursionGuard; @@ -296,7 +299,6 @@ public: void updateLayoutDirection(); - //menu fading/scrolling effects bool doChildEffects; diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp index 2f9ada6..56eca9a 100644 --- a/src/gui/widgets/qmenu_symbian.cpp +++ b/src/gui/widgets/qmenu_symbian.cpp @@ -264,7 +264,8 @@ void qt_symbian_show_submenu( CEikMenuPane* menuPane, int id) // However if we don't have any items, we still need the item array. Otherwise // menupane will crash. That's why we create item array here manually, and // AddMenuItemL will then use the existing array. - CEikMenuPane::CItemArray* itemArray = q_check_ptr(new CEikMenuPane::CItemArray); + CEikMenuPane::CItemArray* itemArray = new CEikMenuPane::CItemArray; + Q_CHECK_PTR(itemArray); menuPane->SetItemArray(itemArray); menuPane->SetItemArrayOwnedExternally(EFalse); diff --git a/src/gui/widgets/qmenu_wince.cpp b/src/gui/widgets/qmenu_wince.cpp index 24df6a2..1157fff 100644 --- a/src/gui/widgets/qmenu_wince.cpp +++ b/src/gui/widgets/qmenu_wince.cpp @@ -113,8 +113,6 @@ static void resolveAygLibs() if (!aygResolved) { aygResolved = true; QLibrary aygLib(QLatin1String("aygshell")); - if (!aygLib.load()) - return; ptrCreateMenuBar = (AygCreateMenuBar) aygLib.resolve("SHCreateMenuBar"); ptrEnableSoftKey = (AygEnableSoftKey) aygLib.resolve("SHEnableSoftkey"); } diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index 6a41c74..3ff98a4 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -1073,8 +1073,11 @@ void QMenuBar::paintEvent(QPaintEvent *e) void QMenuBar::setVisible(bool visible) { #if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60) - if (isNativeMenuBar()) + if (isNativeMenuBar()) { + if (!visible) + QWidget::setVisible(false); return; + } #endif QWidget::setVisible(visible); } diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 52efaef..f2fca8f 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -483,6 +483,7 @@ int QPlainTextEditPrivate::verticalOffset(int topBlock, int topLine) const QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout()); Q_ASSERT(documentLayout); QRectF r = documentLayout->blockBoundingRect(currentBlock); + Q_UNUSED(r); QTextLayout *layout = currentBlock.layout(); if (layout && topLine <= layout->lineCount()) { QTextLine line = layout->lineAt(topLine - 1); @@ -648,6 +649,11 @@ void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx) } control->topBlock = blockNumber; topLine = lineNumber; + + bool vbarSignalsBlocked = vbar->blockSignals(true); + vbar->setValue(block.firstLineNumber() + lineNumber); + vbar->blockSignals(vbarSignalsBlocked); + if (dx || dy) viewport->scroll(q->isRightToLeft() ? -dx : dx, dy); else diff --git a/src/gui/widgets/qradiobutton.cpp b/src/gui/widgets/qradiobutton.cpp index 92d1a8d..eeef40e 100644 --- a/src/gui/widgets/qradiobutton.cpp +++ b/src/gui/widgets/qradiobutton.cpp @@ -207,6 +207,14 @@ QSize QRadioButton::sizeHint() const /*! \reimp */ +QSize QRadioButton::minimumSizeHint() const +{ + return sizeHint(); +} + +/*! + \reimp +*/ bool QRadioButton::hitButton(const QPoint &pos) const { QStyleOptionButton opt; diff --git a/src/gui/widgets/qradiobutton.h b/src/gui/widgets/qradiobutton.h index 5b5cce8..2e29876 100644 --- a/src/gui/widgets/qradiobutton.h +++ b/src/gui/widgets/qradiobutton.h @@ -62,6 +62,7 @@ public: explicit QRadioButton(const QString &text, QWidget *parent=0); QSize sizeHint() const; + QSize minimumSizeHint() const; protected: bool event(QEvent *e); diff --git a/src/gui/widgets/qsizegrip.cpp b/src/gui/widgets/qsizegrip.cpp index d566000..dd77a2f 100644 --- a/src/gui/widgets/qsizegrip.cpp +++ b/src/gui/widgets/qsizegrip.cpp @@ -78,15 +78,6 @@ static QWidget *qt_sizegrip_topLevelWidget(QWidget* w) return w; } -static inline bool hasHeightForWidth(QWidget *widget) -{ - if (!widget) - return false; - if (QLayout *layout = widget->layout()) - return layout->hasHeightForWidth(); - return widget->sizePolicy().hasHeightForWidth(); -} - class QSizeGripPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QSizeGrip) @@ -318,7 +309,8 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e) #ifdef Q_WS_X11 // Use a native X11 sizegrip for "real" top-level windows if supported. if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE)) - && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) { + && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint) + && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) { XEvent xev; xev.xclient.type = ClientMessage; xev.xclient.message_type = ATOM(_NET_WM_MOVERESIZE); @@ -340,7 +332,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e) } #endif // Q_WS_X11 #ifdef Q_WS_WIN - if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) { + if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) { uint orientation = 0; if (d->atBottom()) orientation = d->atLeft() ? SZ_SIZEBOTTOMLEFT : SZ_SIZEBOTTOMRIGHT; @@ -429,12 +421,13 @@ void QSizeGrip::mouseMoveEvent(QMouseEvent * e) #ifdef Q_WS_X11 if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE)) - && tlw->isTopLevel() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) + && tlw->isTopLevel() && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint) + && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) return; #endif #ifdef Q_WS_WIN if (tlw->isWindow() && GetSystemMenu(tlw->winId(), FALSE) != 0 && internalWinId() - && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) { + && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) { MSG msg; while(PeekMessage(&msg, winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)); return; diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp index e8382ed..952f9e2 100644 --- a/src/gui/widgets/qspinbox.cpp +++ b/src/gui/widgets/qspinbox.cpp @@ -697,6 +697,9 @@ void QDoubleSpinBox::setSuffix(const QString &suffix) d->suffix = suffix; d->updateEdit(); + + d->cachedSizeHint = QSize(); + updateGeometry(); } /*! diff --git a/src/gui/widgets/qsplashscreen.cpp b/src/gui/widgets/qsplashscreen.cpp index 40ce9a6..2da4a8b 100644 --- a/src/gui/widgets/qsplashscreen.cpp +++ b/src/gui/widgets/qsplashscreen.cpp @@ -64,7 +64,6 @@ public: int currAlign; inline QSplashScreenPrivate(); - void drawContents(); }; /*! @@ -121,10 +120,9 @@ public: perhaps Qt::WindowStaysOnTopHint. */ QSplashScreen::QSplashScreen(const QPixmap &pixmap, Qt::WindowFlags f) - : QWidget(*(new QSplashScreenPrivate()), 0, Qt::SplashScreen | f) + : QWidget(*(new QSplashScreenPrivate()), 0, Qt::SplashScreen | Qt::FramelessWindowHint | f) { - d_func()->pixmap = pixmap; - setPixmap(d_func()->pixmap); // Does an implicit repaint + setPixmap(pixmap); // Does an implicit repaint } /*! @@ -165,7 +163,6 @@ void QSplashScreen::mousePressEvent(QMouseEvent *) */ void QSplashScreen::repaint() { - d_func()->drawContents(); QWidget::repaint(); QApplication::flush(); } @@ -226,8 +223,8 @@ void QSplashScreen::finish(QWidget *mainWin) { if (mainWin) { #if defined(Q_WS_X11) - extern void qt_x11_wait_for_window_manager(QWidget *mainWin); - qt_x11_wait_for_window_manager(mainWin); + extern void qt_x11_wait_for_window_manager(QWidget *mainWin, bool); + qt_x11_wait_for_window_manager(mainWin, false); #endif } close(); @@ -241,23 +238,13 @@ void QSplashScreen::setPixmap(const QPixmap &pixmap) { Q_D(QSplashScreen); - if (pixmap.hasAlpha()) { - QPixmap opaque(pixmap.size()); - QPainter p(&opaque); - p.fillRect(0, 0, pixmap.width(), pixmap.height(), palette().background()); - p.drawPixmap(0, 0, pixmap); - p.end(); - d->pixmap = opaque; - } else { - d->pixmap = pixmap; - } + d->pixmap = pixmap; + setAttribute(Qt::WA_TranslucentBackground, pixmap.hasAlpha()); - QRect r(0, 0, d->pixmap.size().width(), d->pixmap.size().height()); - resize(d->pixmap.size()); + QRect r(QPoint(), d->pixmap.size()); + resize(r.size()); move(QApplication::desktop()->screenGeometry().center() - r.center()); - if (!isVisible()) - d->drawContents(); - else + if (isVisible()) repaint(); } @@ -271,23 +258,6 @@ const QPixmap QSplashScreen::pixmap() const } /*! - \internal -*/ -void QSplashScreenPrivate::drawContents() -{ - Q_Q(QSplashScreen); - QPixmap textPix = pixmap; - if (!textPix.isNull()) { - QPainter painter(&textPix); - painter.initFrom(q); - q->drawContents(&painter); - QPalette p = q->palette(); - p.setBrush(q->backgroundRole(), QBrush(textPix)); - q->setPalette(p); - } -} - -/*! \internal */ inline QSplashScreenPrivate::QSplashScreenPrivate() : currAlign(Qt::AlignLeft) @@ -304,8 +274,7 @@ void QSplashScreen::drawContents(QPainter *painter) { Q_D(QSplashScreen); painter->setPen(d->currColor); - QRect r = rect(); - r.setRect(r.x() + 5, r.y() + 5, r.width() - 10, r.height() - 10); + QRect r = rect().adjusted(5, 5, -5, -5); if (Qt::mightBeRichText(d->currStatus)) { QTextDocument doc; #ifdef QT_NO_TEXTHTMLPARSER @@ -346,6 +315,13 @@ void QSplashScreen::drawContents(QPainter *painter) /*! \reimp */ bool QSplashScreen::event(QEvent *e) { + if (e->type() == QEvent::Paint) { + Q_D(QSplashScreen); + QPainter painter(this); + if (!d->pixmap.isNull()) + painter.drawPixmap(QPoint(), d->pixmap); + drawContents(&painter); + } return QWidget::event(e); } diff --git a/src/gui/widgets/qstackedwidget.cpp b/src/gui/widgets/qstackedwidget.cpp index 294c780..c4bf79a 100644 --- a/src/gui/widgets/qstackedwidget.cpp +++ b/src/gui/widgets/qstackedwidget.cpp @@ -49,12 +49,54 @@ QT_BEGIN_NAMESPACE +/** + QStackedLayout does not support height for width (simply because it does not reimplement + heightForWidth() and hasHeightForWidth()). That is not possible to fix without breaking + binary compatibility. (QLayout is subject to multiple inheritance). + However, we can fix QStackedWidget by simply using a modified version of QStackedLayout + that reimplements the hfw-related functions: + */ +class QStackedLayoutHFW : public QStackedLayout +{ +public: + QStackedLayoutHFW(QWidget *parent = 0) : QStackedLayout(parent) {} + bool hasHeightForWidth() const; + int heightForWidth(int width) const; +}; + +bool QStackedLayoutHFW::hasHeightForWidth() const +{ + const int n = count(); + + for (int i = 0; i < n; ++i) { + if (QLayoutItem *item = itemAt(i)) { + if (item->hasHeightForWidth()) + return true; + } + } + return false; +} + +int QStackedLayoutHFW::heightForWidth(int width) const +{ + const int n = count(); + + int hfw = 0; + for (int i = 0; i < n; ++i) { + if (QLayoutItem *item = itemAt(i)) { + hfw = qMax(hfw, item->heightForWidth(width)); + } + } + return hfw; +} + + class QStackedWidgetPrivate : public QFramePrivate { Q_DECLARE_PUBLIC(QStackedWidget) public: QStackedWidgetPrivate():layout(0){} - QStackedLayout *layout; + QStackedLayoutHFW *layout; bool blockChildAdd; }; @@ -138,7 +180,7 @@ QStackedWidget::QStackedWidget(QWidget *parent) : QFrame(*new QStackedWidgetPrivate, parent) { Q_D(QStackedWidget); - d->layout = new QStackedLayout(this); + d->layout = new QStackedLayoutHFW(this); connect(d->layout, SIGNAL(widgetRemoved(int)), this, SIGNAL(widgetRemoved(int))); connect(d->layout, SIGNAL(currentChanged(int)), this, SIGNAL(currentChanged(int))); } diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index c551f3e..16e4aad 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -1292,6 +1292,8 @@ QSize QTabBar::sizeHint() const QSize QTabBar::minimumSizeHint() const { Q_D(const QTabBar); + if (d->layoutDirty) + const_cast<QTabBarPrivate*>(d)->layoutTabs(); if (!d->useScrollButtons) { QRect r; for (int i = 0; i < d->tabList.count(); ++i) @@ -1304,22 +1306,23 @@ QSize QTabBar::minimumSizeHint() const return QSize(d->rightB->sizeHint().width() * 2 + 75, sizeHint().height()); } +// Compute the most-elided possible text, for minimumSizeHint static QString computeElidedText(Qt::TextElideMode mode, const QString &text) { - if (text.length() <= 7) + if (text.length() <= 3) return text; static const QLatin1String Ellipses("..."); QString ret; switch (mode) { case Qt::ElideRight: - ret = text.left(4) + Ellipses; + ret = text.left(2) + Ellipses; break; case Qt::ElideMiddle: - ret = text.left(2) + Ellipses + text.right(2); + ret = text.left(1) + Ellipses + text.right(1); break; case Qt::ElideLeft: - ret = Ellipses + text.right(4); + ret = Ellipses + text.right(2); break; case Qt::ElideNone: ret = text; @@ -1966,7 +1969,7 @@ void QTabBar::keyPressEvent(QKeyEvent *event) event->ignore(); return; } - int offset = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1; + int offset = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1; d->setCurrentNextEnabledIndex(offset); } diff --git a/src/gui/widgets/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp index ae56e62..ade798f 100644 --- a/src/gui/widgets/qtabwidget.cpp +++ b/src/gui/widgets/qtabwidget.cpp @@ -195,6 +195,7 @@ public: void _q_removeTab(int); void _q_tabMoved(int from, int to); void init(); + bool hasHeightForWidth() const; QTabBar *tabs; QStackedWidget *stack; @@ -246,6 +247,15 @@ void QTabWidgetPrivate::init() } +bool QTabWidgetPrivate::hasHeightForWidth() const +{ + bool has = size_policy.hasHeightForWidth(); + if (!has && stack) + has = qt_widget_private(stack)->hasHeightForWidth(); + return has; +} + + /*! Initialize \a option with the values from this QTabWidget. This method is useful for subclasses when they need a QStyleOptionTabWidgetFrame, but don't want to fill @@ -816,8 +826,8 @@ QSize QTabWidget::sizeHint() const { Q_D(const QTabWidget); QSize lc(0, 0), rc(0, 0); - QStyleOption opt(0); - opt.init(this); + QStyleOptionTabWidgetFrameV2 opt; + initStyleOption(&opt); opt.state = QStyle::State_None; if (d->leftCornerWidget) @@ -865,14 +875,58 @@ QSize QTabWidget::minimumSizeHint() const QSize sz = basicSize(d->pos == North || d->pos == South, lc, rc, s, t); - QStyleOption opt(0); - opt.rect = rect(); + QStyleOptionTabWidgetFrameV2 opt; + initStyleOption(&opt); opt.palette = palette(); opt.state = QStyle::State_None; return style()->sizeFromContents(QStyle::CT_TabWidget, &opt, sz, this) .expandedTo(QApplication::globalStrut()); } +/* + \reimp +*/ +int QTabWidget::heightForWidth(int width) const +{ + Q_D(const QTabWidget); + QStyleOptionTabWidgetFrameV2 opt; + initStyleOption(&opt); + opt.state = QStyle::State_None; + + QSize zero(0,0); + const QSize padding = style()->sizeFromContents(QStyle::CT_TabWidget, &opt, zero, this) + .expandedTo(QApplication::globalStrut()); + + QSize lc(0, 0), rc(0, 0); + if (d->leftCornerWidget) + lc = d->leftCornerWidget->sizeHint(); + if(d->rightCornerWidget) + rc = d->rightCornerWidget->sizeHint(); + if (!d->dirty) { + QTabWidget *that = (QTabWidget*)this; + that->setUpLayout(true); + } + QSize t(d->tabs->sizeHint()); + + if(usesScrollButtons()) + t = t.boundedTo(QSize(200,200)); + else + t = t.boundedTo(QApplication::desktop()->size()); + + const bool tabIsHorizontal = (d->pos == North || d->pos == South); + const int contentsWidth = width - padding.width(); + int stackWidth = contentsWidth; + if (!tabIsHorizontal) + stackWidth -= qMax(t.width(), qMax(lc.width(), rc.width())); + + int stackHeight = d->stack->heightForWidth(stackWidth); + QSize s(stackWidth, stackHeight); + + QSize contentSize = basicSize(tabIsHorizontal, lc, rc, s, t); + return (contentSize + padding).expandedTo(QApplication::globalStrut()).height(); +} + + /*! \reimp */ diff --git a/src/gui/widgets/qtabwidget.h b/src/gui/widgets/qtabwidget.h index 696906d..6a026c0 100644 --- a/src/gui/widgets/qtabwidget.h +++ b/src/gui/widgets/qtabwidget.h @@ -129,6 +129,7 @@ public: QSize sizeHint() const; QSize minimumSizeHint() const; + int heightForWidth(int width) const; void setCornerWidget(QWidget * w, Qt::Corner corner = Qt::TopRightCorner); QWidget * cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const; diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index 6757d77..2670089 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -2614,7 +2614,6 @@ Qt::TextFormat QTextEdit::textFormat() const void QTextEdit::append(const QString &text) { Q_D(QTextEdit); - QTextBlock lastBlock = d->control->document()->lastBlock(); const bool atBottom = isReadOnly() ? d->verticalOffset() >= d->vbar->maximum() : d->control->textCursor().atEnd(); d->control->append(text); diff --git a/src/gui/widgets/qtoolbarlayout.cpp b/src/gui/widgets/qtoolbarlayout.cpp index 98b1fc5..971fdda 100644 --- a/src/gui/widgets/qtoolbarlayout.cpp +++ b/src/gui/widgets/qtoolbarlayout.cpp @@ -647,15 +647,15 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const void QToolBarLayout::setExpanded(bool exp) { - if (exp == expanded) + QWidget *tb = qobject_cast<QToolBar*>(parentWidget()); + if (!tb) + return; + if (exp == expanded && !tb->isWindow()) return; expanded = exp; extension->setChecked(expanded); - QToolBar *tb = qobject_cast<QToolBar*>(parentWidget()); - if (!tb) - return; if (QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget())) { #ifdef QT_NO_DOCKWIDGET animating = false; diff --git a/src/gui/widgets/qtoolbutton.cpp b/src/gui/widgets/qtoolbutton.cpp index 6c49c2b..0d765d2 100644 --- a/src/gui/widgets/qtoolbutton.cpp +++ b/src/gui/widgets/qtoolbutton.cpp @@ -394,9 +394,6 @@ void QToolButton::initStyleOption(QStyleOptionToolButton *option) const option->toolButtonStyle = Qt::ToolButtonTextOnly; else if (option->toolButtonStyle != Qt::ToolButtonTextOnly) option->toolButtonStyle = Qt::ToolButtonIconOnly; - } else { - if (d->text.isEmpty() && option->toolButtonStyle != Qt::ToolButtonIconOnly) - option->toolButtonStyle = Qt::ToolButtonIconOnly; } option->pos = pos(); diff --git a/src/gui/widgets/qvalidator.h b/src/gui/widgets/qvalidator.h index 3f4579f..70f656e 100644 --- a/src/gui/widgets/qvalidator.h +++ b/src/gui/widgets/qvalidator.h @@ -101,7 +101,7 @@ class Q_GUI_EXPORT QIntValidator : public QValidator public: explicit QIntValidator(QObject * parent = 0); - QIntValidator(int bottom, int top, QObject * parent); + QIntValidator(int bottom, int top, QObject *parent = 0); ~QIntValidator(); QValidator::State validate(QString &, int &) const; @@ -142,7 +142,7 @@ class Q_GUI_EXPORT QDoubleValidator : public QValidator public: explicit QDoubleValidator(QObject * parent = 0); - QDoubleValidator(double bottom, double top, int decimals, QObject * parent); + QDoubleValidator(double bottom, double top, int decimals, QObject *parent = 0); ~QDoubleValidator(); enum Notation { @@ -186,7 +186,7 @@ class Q_GUI_EXPORT QRegExpValidator : public QValidator public: explicit QRegExpValidator(QObject *parent = 0); - QRegExpValidator(const QRegExp& rx, QObject *parent); + QRegExpValidator(const QRegExp& rx, QObject *parent = 0); ~QRegExpValidator(); virtual QValidator::State validate(QString& input, int& pos) const; diff --git a/src/gui/widgets/qworkspace.cpp b/src/gui/widgets/qworkspace.cpp index b34a649..9516bca 100644 --- a/src/gui/widgets/qworkspace.cpp +++ b/src/gui/widgets/qworkspace.cpp @@ -1239,7 +1239,6 @@ QWidget * QWorkspace::addWindow(QWidget *w, Qt::WindowFlags flags) int x = w->x(); int y = w->y(); bool hasPos = w->testAttribute(Qt::WA_Moved); - QSize s = w->size().expandedTo(qSmartMinSize(w)); if (!hasSize && w->sizeHint().isValid()) w->adjustSize(); @@ -2923,7 +2922,7 @@ void QWorkspaceChild::setActive(bool b) iconw->setActive(act); update(); - QList<QWidget*> wl = qFindChildren<QWidget*>(childWidget); + QList<QWidget*> wl = childWidget->findChildren<QWidget*>(); if (act) { for (int i = 0; i < wl.size(); ++i) { QWidget *w = wl.at(i); diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri index 937b8d6..669b838 100644 --- a/src/gui/widgets/widgets.pri +++ b/src/gui/widgets/widgets.pri @@ -144,7 +144,7 @@ SOURCES += \ widgets/qplaintextedit.cpp \ widgets/qprintpreviewwidget.cpp -!embedded:mac { +!embedded:!qpa:mac { HEADERS += widgets/qmacnativewidget_mac.h \ widgets/qmaccocoaviewcontainer_mac.h OBJECTIVE_HEADERS += widgets/qcocoatoolbardelegate_mac_p.h \ |