summaryrefslogtreecommitdiffstats
path: root/src/gui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/widgets')
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp83
-rw-r--r--src/gui/widgets/qabstractscrollarea.h2
-rw-r--r--src/gui/widgets/qabstractslider.cpp46
-rw-r--r--src/gui/widgets/qcalendarwidget.cpp14
-rw-r--r--src/gui/widgets/qcombobox.cpp115
-rw-r--r--src/gui/widgets/qcombobox.h5
-rw-r--r--src/gui/widgets/qcombobox_p.h6
-rw-r--r--src/gui/widgets/qdialogbuttonbox.cpp41
-rw-r--r--src/gui/widgets/qdockarealayout.cpp39
-rw-r--r--src/gui/widgets/qdockarealayout_p.h9
-rw-r--r--src/gui/widgets/qdockwidget.cpp17
-rw-r--r--src/gui/widgets/qfontcombobox.cpp13
-rw-r--r--src/gui/widgets/qlabel.cpp38
-rw-r--r--src/gui/widgets/qlabel_p.h2
-rw-r--r--src/gui/widgets/qlcdnumber.cpp50
-rw-r--r--src/gui/widgets/qlcdnumber.h7
-rw-r--r--src/gui/widgets/qlinecontrol.cpp33
-rw-r--r--src/gui/widgets/qlinecontrol_p.h6
-rw-r--r--src/gui/widgets/qlineedit.cpp32
-rw-r--r--src/gui/widgets/qlineedit.h3
-rw-r--r--src/gui/widgets/qmainwindowlayout.cpp3
-rw-r--r--src/gui/widgets/qmenu.cpp139
-rw-r--r--src/gui/widgets/qmenu_mac.mm26
-rw-r--r--src/gui/widgets/qmenu_p.h8
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp8
-rw-r--r--src/gui/widgets/qmenubar.cpp42
-rw-r--r--src/gui/widgets/qmenubar_p.h3
-rw-r--r--src/gui/widgets/qplaintextedit.cpp63
-rw-r--r--src/gui/widgets/qprintpreviewwidget.cpp12
-rw-r--r--src/gui/widgets/qprintpreviewwidget.h3
-rw-r--r--src/gui/widgets/qpushbutton.cpp4
-rw-r--r--src/gui/widgets/qsplitter.cpp17
-rw-r--r--src/gui/widgets/qtabbar.cpp19
-rw-r--r--src/gui/widgets/qtabbar_p.h10
-rw-r--r--src/gui/widgets/qtabwidget.cpp16
-rw-r--r--src/gui/widgets/qtextedit.cpp23
-rw-r--r--src/gui/widgets/qtoolbar.cpp18
-rw-r--r--src/gui/widgets/qtoolbar.h1
-rw-r--r--src/gui/widgets/qtoolbararealayout.cpp50
-rw-r--r--src/gui/widgets/qtoolbararealayout_p.h6
-rw-r--r--src/gui/widgets/qtoolbarlayout.cpp5
-rw-r--r--src/gui/widgets/qtoolbarlayout_p.h2
-rw-r--r--src/gui/widgets/qwidgetanimator.cpp9
-rw-r--r--src/gui/widgets/qwidgetanimator_p.h1
44 files changed, 672 insertions, 377 deletions
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index 08962567d2..35639b705e 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -51,6 +51,7 @@
#include "qdebug.h"
#include "qboxlayout.h"
#include "qpainter.h"
+#include "qmargins.h"
#include "qabstractscrollarea_p.h"
#include <qwidget.h>
@@ -293,13 +294,16 @@ void QAbstractScrollAreaPrivate::init()
q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layoutChildren();
+ viewport->grabGesture(Qt::PanGesture);
}
#ifdef Q_WS_WIN
void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on)
{
singleFingerPanEnabled = on;
- winSetupGestures();
+ QWidgetPrivate *dd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(viewport));
+ if (dd)
+ dd->winSetupGestures();
}
#endif // Q_WS_WIN
@@ -539,6 +543,7 @@ void QAbstractScrollArea::setViewport(QWidget *widget)
d->viewport->setParent(this);
d->viewport->setFocusProxy(this);
d->viewport->installEventFilter(d->viewportFilter.data());
+ d->viewport->grabGesture(Qt::PanGesture);
d->layoutChildren();
if (isVisible())
d->viewport->show();
@@ -864,6 +869,22 @@ void QAbstractScrollArea::setViewportMargins(int left, int top, int right, int b
}
/*!
+ \since 4.6
+ Sets \a margins around the scrolling area. This is useful for
+ applications such as spreadsheets with "locked" rows and columns.
+ The marginal space is is left blank; put widgets in the unused
+ area.
+
+ By default all margins are zero.
+
+*/
+void QAbstractScrollArea::setViewportMargins(const QMargins &margins)
+{
+ setViewportMargins(margins.left(), margins.top(),
+ margins.right(), margins.bottom());
+}
+
+/*!
\fn bool QAbstractScrollArea::event(QEvent *event)
\reimp
@@ -935,6 +956,26 @@ bool QAbstractScrollArea::event(QEvent *e)
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
return false;
+ case QEvent::Gesture:
+ {
+ QGestureEvent *ge = static_cast<QGestureEvent *>(e);
+ QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
+ if (g) {
+ QScrollBar *hBar = horizontalScrollBar();
+ QScrollBar *vBar = verticalScrollBar();
+ QPointF delta = g->delta();
+ if (!delta.isNull()) {
+ if (QApplication::isRightToLeft())
+ delta.rx() *= -1;
+ int newX = hBar->value() - delta.x();
+ int newY = vBar->value() - delta.y();
+ hBar->setValue(newX);
+ vBar->setValue(newY);
+ }
+ return true;
+ }
+ return false;
+ }
case QEvent::StyleChange:
case QEvent::LayoutDirectionChange:
case QEvent::ApplicationLayoutDirectionChange:
@@ -990,6 +1031,8 @@ bool QAbstractScrollArea::viewportEvent(QEvent *e)
#endif
return QFrame::event(e);
case QEvent::LayoutRequest:
+ case QEvent::Gesture:
+ case QEvent::GestureOverride:
return event(e);
default:
break;
@@ -1087,10 +1130,13 @@ void QAbstractScrollArea::mouseMoveEvent(QMouseEvent *e)
void QAbstractScrollArea::wheelEvent(QWheelEvent *e)
{
Q_D(QAbstractScrollArea);
- if (static_cast<QWheelEvent*>(e)->orientation() == Qt::Horizontal)
- QApplication::sendEvent(d->hbar, e);
- else
- QApplication::sendEvent(d->vbar, e);
+ QScrollBar *const bars[2] = { d->hbar, d->vbar };
+ int idx = (e->orientation() == Qt::Vertical) ? 1 : 0;
+ int other = (idx + 1) % 2;
+ if (!bars[idx]->isVisible() && bars[other]->isVisible())
+ idx = other; // If the scrollbar of the event orientation is hidden, fallback to the other.
+
+ QApplication::sendEvent(bars[idx], e);
}
#endif
@@ -1266,11 +1312,13 @@ void QAbstractScrollAreaPrivate::_q_vslide(int y)
void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars()
{
layoutChildren();
-#ifdef Q_OS_WIN
+#ifdef Q_WS_WIN
// Need to re-subscribe to gestures as the content changes to make sure we
// enable/disable panning when needed.
- winSetupGestures();
-#endif // Q_OS_WIN
+ QWidgetPrivate *dd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(viewport));
+ if (dd)
+ dd->winSetupGestures();
+#endif // Q_WS_WIN
}
QPoint QAbstractScrollAreaPrivate::contentsOffset() const
@@ -1335,25 +1383,6 @@ void QAbstractScrollArea::setupViewport(QWidget *viewport)
Q_UNUSED(viewport);
}
-//void QAbstractScrollAreaPrivate::_q_gestureTriggered()
-//{
-// Q_Q(QAbstractScrollArea);
-// QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
-// if (!g)
-// return;
-// QScrollBar *hBar = q->horizontalScrollBar();
-// QScrollBar *vBar = q->verticalScrollBar();
-// QSizeF delta = g->lastOffset();
-// if (!delta.isNull()) {
-// if (QApplication::isRightToLeft())
-// delta.rwidth() *= -1;
-// int newX = hBar->value() - delta.width();
-// int newY = vBar->value() - delta.height();
-// hbar->setValue(newX);
-// vbar->setValue(newY);
-// }
-//}
-
QT_END_NAMESPACE
#include "moc_qabstractscrollarea.cpp"
diff --git a/src/gui/widgets/qabstractscrollarea.h b/src/gui/widgets/qabstractscrollarea.h
index b3a18616c6..18d1e96e62 100644
--- a/src/gui/widgets/qabstractscrollarea.h
+++ b/src/gui/widgets/qabstractscrollarea.h
@@ -52,6 +52,7 @@ QT_MODULE(Gui)
#ifndef QT_NO_SCROLLAREA
+class QMargins;
class QScrollBar;
class QAbstractScrollAreaPrivate;
@@ -95,6 +96,7 @@ protected Q_SLOTS:
protected:
QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = 0);
void setViewportMargins(int left, int top, int right, int bottom);
+ void setViewportMargins(const QMargins &margins);
bool event(QEvent *);
virtual bool viewportEvent(QEvent *);
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp
index 588a48ee8a..e0db9c29e2 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/gui/widgets/qabstractslider.cpp
@@ -690,32 +690,28 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e)
{
Q_D(QAbstractSlider);
e->ignore();
- if (e->orientation() != d->orientation && !rect().contains(e->pos()))
- return;
- qreal currentOffset = qreal(e->delta()) / 120;
- d->offset_accumulated += currentOffset;
- if (int(d->offset_accumulated) == 0) {
- // QAbstractSlider works on integer values. So if the accumulated
- // offset is less than +/- 1, we need to wait until we get more
- // wheel events (this means that the wheel resolution is higher than
- // 15 degrees, e.g. when using mac mighty mouse/trackpad):
- return;
- }
+ int stepsToScroll = 0;
+ qreal offset = qreal(e->delta()) / 120;
- int stepsToScroll;
if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) {
- stepsToScroll = currentOffset > 0 ? d->pageStep : -d->pageStep;
+ // Scroll one page regardless of delta:
+ stepsToScroll = qBound(-d->pageStep, int(offset * d->pageStep), d->pageStep);
+ d->offset_accumulated = 0;
} else {
- // Calculate the number of steps to scroll (per 15 degrees of rotate):
-#ifdef Q_OS_MAC
- // On mac, since mouse wheel scrolling is accelerated and
- // fine tuned by the OS, we skip applying acceleration:
- stepsToScroll = int(d->offset_accumulated);
-#else
- stepsToScroll = int(d->offset_accumulated) * QApplication::wheelScrollLines() * d->singleStep;
-#endif
- stepsToScroll = qBound(-d->pageStep, stepsToScroll, d->pageStep);
+ // Calculate how many lines to scroll. Depending on what delta is (and
+ // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
+ // only scroll whole lines, so we keep the reminder until next event.
+ qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * d->singleStep;
+ // Check if wheel changed direction since last event:
+ if (d->offset_accumulated != 0 && (offset / d->offset_accumulated) < 0)
+ d->offset_accumulated = 0;
+
+ d->offset_accumulated += stepsToScrollF;
+ stepsToScroll = qBound(-d->pageStep, int(d->offset_accumulated), d->pageStep);
+ d->offset_accumulated -= int(d->offset_accumulated);
+ if (stepsToScroll == 0)
+ return;
}
if (d->invertedControls)
@@ -725,12 +721,10 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e)
d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
triggerAction(SliderMove);
- if (prevValue == d->value) {
+ if (prevValue == d->value)
d->offset_accumulated = 0;
- } else {
- d->offset_accumulated -= int(d->offset_accumulated);
+ else
e->accept();
- }
}
#endif
#ifdef QT_KEYPAD_NAVIGATION
diff --git a/src/gui/widgets/qcalendarwidget.cpp b/src/gui/widgets/qcalendarwidget.cpp
index 08ed7f6a22..ee536ee43c 100644
--- a/src/gui/widgets/qcalendarwidget.cpp
+++ b/src/gui/widgets/qcalendarwidget.cpp
@@ -2297,7 +2297,21 @@ int QCalendarWidget::monthShown() const
void QCalendarWidget::setCurrentPage(int year, int month)
{
Q_D(QCalendarWidget);
+ QDate currentDate = d->getCurrentDate();
+ int day = currentDate.day();
+ int daysInMonths = QDate(year, month, 1).daysInMonth();
+ if (day > daysInMonths)
+ day = daysInMonths;
+
d->showMonth(year, month);
+
+ QDate newDate(year, month, day);
+ int row = -1, col = -1;
+ d->m_model->cellForDate(newDate, &row, &col);
+ if (row != -1 && col != -1) {
+ d->m_view->selectionModel()->setCurrentIndex(d->m_model->index(row, col),
+ QItemSelectionModel::NoUpdate);
+ }
}
/*!
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index b60653812c..bd1d8ba1f2 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -192,6 +192,8 @@ void QComboBoxPrivate::_q_modelReset()
lineEdit->setText(QString());
updateLineEditGeometry();
}
+ if (currentIndex.row() != indexBeforeChange)
+ _q_emitCurrentIndexChanged(currentIndex);
q->update();
}
@@ -314,7 +316,7 @@ QSize QComboBoxPrivate::recomputeSizeHint(QSize &sh) const
// height
- sh.setHeight(qMax(fm.lineSpacing(), 14) + 2);
+ sh.setHeight(qMax(fm.height(), 14) + 2);
if (hasIcon) {
sh.setHeight(qMax(sh.height(), iconSize.height() + 2));
}
@@ -402,13 +404,6 @@ QComboBoxPrivateContainer::QComboBoxPrivateContainer(QAbstractItemView *itemView
layout->setSpacing(0);
layout->setMargin(0);
-#ifdef QT_SOFTKEYS_ENABLED
- selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, this);
- cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Escape, this);
- addAction(selectAction);
- addAction(cancelAction);
-#endif
-
// set item view
setItemView(itemView);
@@ -494,18 +489,6 @@ void QComboBoxPrivateContainer::viewDestroyed()
}
/*
- Sets currentIndex on entered if the LeftButton is not pressed. This
- means that if mouseTracking(...) is on, we setCurrentIndex and select
- even when LeftButton is not pressed.
-*/
-void QComboBoxPrivateContainer::setCurrentIndex(const QModelIndex &index)
-{
- if (QComboBoxDelegate::isSeparator(index))
- return;
- view->setCurrentIndex(index);
-}
-
-/*
Returns the item view used for the combobox popup.
*/
QAbstractItemView *QComboBoxPrivateContainer::itemView() const
@@ -530,8 +513,6 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView)
disconnect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),
this, SLOT(updateScrollers()));
#endif
- disconnect(view, SIGNAL(entered(QModelIndex)),
- this, SLOT(setCurrentIndex(QModelIndex)));
disconnect(view, SIGNAL(destroyed()),
this, SLOT(viewDestroyed()));
@@ -568,10 +549,15 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView)
connect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),
this, SLOT(updateScrollers()));
#endif
- connect(view, SIGNAL(entered(QModelIndex)),
- this, SLOT(setCurrentIndex(QModelIndex)));
connect(view, SIGNAL(destroyed()),
this, SLOT(viewDestroyed()));
+
+#ifdef QT_SOFTKEYS_ENABLED
+ selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, itemView);
+ cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Escape, itemView);
+ addAction(selectAction);
+ addAction(cancelAction);
+#endif
}
/*!
@@ -653,16 +639,20 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
break;
}
break;
- case QEvent::MouseMove: {
+ case QEvent::MouseMove:
if (isVisible()) {
QMouseEvent *m = static_cast<QMouseEvent *>(e);
QWidget *widget = static_cast<QWidget *>(o);
QPoint vector = widget->mapToGlobal(m->pos()) - initialClickPosition;
if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive())
blockMouseReleaseTimer.stop();
+ QModelIndex indexUnderMouse = view->indexAt(m->pos());
+ if (indexUnderMouse.isValid() && indexUnderMouse != view->currentIndex()
+ && !QComboBoxDelegate::isSeparator(indexUnderMouse)) {
+ view->setCurrentIndex(indexUnderMouse);
+ }
}
break;
- }
case QEvent::MouseButtonRelease: {
QMouseEvent *m = static_cast<QMouseEvent *>(e);
if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid()
@@ -992,14 +982,6 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn
}
}
-void QComboBoxPrivate::_q_rowsAboutToBeInserted(const QModelIndex & parent,
- int /*start*/, int /*end*/)
-{
- if (parent != root)
- return;
- indexBeforeChange = currentIndex.row();
-}
-
void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end)
{
Q_Q(QComboBox);
@@ -1022,11 +1004,8 @@ void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int
}
}
-void QComboBoxPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int /*start*/, int /*end*/)
+void QComboBoxPrivate::_q_updateIndexBeforeChange()
{
- if (parent != root)
- return;
-
indexBeforeChange = currentIndex.row();
}
@@ -1132,6 +1111,32 @@ void QComboBoxPrivate::updateLineEditGeometry()
lineEdit->setGeometry(editRect);
}
+Qt::MatchFlags QComboBoxPrivate::matchFlags() const
+{
+ // Base how duplicates are determined on the autocompletion case sensitivity
+ Qt::MatchFlags flags = Qt::MatchFixedString;
+#ifndef QT_NO_COMPLETER
+ if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
+#endif
+ flags |= Qt::MatchCaseSensitive;
+ return flags;
+}
+
+
+void QComboBoxPrivate::_q_editingFinished()
+{
+ Q_Q(QComboBox);
+ if (lineEdit && !lineEdit->text().isEmpty()) {
+ //here we just check if the current item was entered
+ const int index = q_func()->findText(lineEdit->text(), matchFlags());
+ if (index != -1 && itemText(currentIndex) != lineEdit->text()) {
+ q->setCurrentIndex(index);
+ emitActivated(currentIndex);
+ }
+ }
+
+}
+
void QComboBoxPrivate::_q_returnPressed()
{
Q_Q(QComboBox);
@@ -1144,13 +1149,7 @@ void QComboBoxPrivate::_q_returnPressed()
// check for duplicates (if not enabled) and quit
int index = -1;
if (!duplicatesEnabled) {
- // Base how duplicates are determined on the autocompletion case sensitivity
- Qt::MatchFlags flags = Qt::MatchFixedString;
-#ifndef QT_NO_COMPLETER
- if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
-#endif
- flags |= Qt::MatchCaseSensitive;
- index = q->findText(text, flags);
+ index = q->findText(text, matchFlags());
if (index != -1) {
q->setCurrentIndex(index);
emitActivated(currentIndex);
@@ -1685,6 +1684,7 @@ void QComboBox::setLineEdit(QLineEdit *edit)
if (d->lineEdit->parent() != this)
d->lineEdit->setParent(this);
connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed()));
+ connect(d->lineEdit, SIGNAL(editingFinished()), this, SLOT(_q_editingFinished()));
connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(editTextChanged(QString)));
#ifdef QT3_SUPPORT
connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString)));
@@ -1868,15 +1868,17 @@ void QComboBox::setModel(QAbstractItemModel *model)
disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)));
+ this, SLOT(_q_updateIndexBeforeChange()));
disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ this, SLOT(_q_updateIndexBeforeChange()));
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(destroyed()),
this, SLOT(_q_modelDestroyed()));
+ disconnect(d->model, SIGNAL(modelAboutToBeReset()),
+ this, SLOT(_q_updateIndexBeforeChange()));
disconnect(d->model, SIGNAL(modelReset()),
this, SLOT(_q_modelReset()));
if (d->model->QObject::parent() == this)
@@ -1888,15 +1890,17 @@ void QComboBox::setModel(QAbstractItemModel *model)
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int)));
+ this, SLOT(_q_updateIndexBeforeChange()));
connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ this, SLOT(_q_updateIndexBeforeChange()));
connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
connect(model, SIGNAL(destroyed()),
this, SLOT(_q_modelDestroyed()));
+ connect(model, SIGNAL(modelAboutToBeReset()),
+ this, SLOT(_q_updateIndexBeforeChange()));
connect(model, SIGNAL(modelReset()),
this, SLOT(_q_modelReset()));
@@ -1977,7 +1981,7 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi)
if (lineEdit) {
QString newText = q->itemText(currentIndex.row());
if (lineEdit->text() != newText)
- lineEdit->setText(q->itemText(currentIndex.row()));
+ lineEdit->setText(newText);
updateLineEditGeometry();
}
if (indexChanged) {
@@ -2174,11 +2178,14 @@ void QComboBox::insertSeparator(int index)
/*!
Removes the item at the given \a index from the combobox.
This will update the current index if the index is removed.
+
+ This function does nothing if \a index is out of range.
*/
void QComboBox::removeItem(int index)
{
- Q_ASSERT(index >= 0 && index < count());
Q_D(QComboBox);
+ if (index < 0 || index >= count())
+ return;
d->model->removeRows(index, 1, d->root);
}
@@ -2449,15 +2456,15 @@ void QComboBox::showPopup()
#if defined(Q_WS_WIN) && !defined(QT_NO_EFFECTS)
bool scrollDown = (listRect.topLeft() == below);
- if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo)
+ if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo)
&& !style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this) && !window()->testAttribute(Qt::WA_DontShowOnScreen))
qScrollEffect(container, scrollDown ? QEffects::DownScroll : QEffects::UpScroll, 150);
#endif
// Don't disable updates on Mac OS X. Windows are displayed immediately on this platform,
// which means that the window will be visible before the call to container->show() returns.
-// If updates are disabled at this point we'll miss our chance at painting the popup
-// menu before it's shown, causing flicker since the window then displays the standard gray
+// If updates are disabled at this point we'll miss our chance at painting the popup
+// menu before it's shown, causing flicker since the window then displays the standard gray
// background.
#ifndef Q_WS_MAC
container->setUpdatesEnabled(false);
diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h
index 6a85096467..5d5ea21287 100644
--- a/src/gui/widgets/qcombobox.h
+++ b/src/gui/widgets/qcombobox.h
@@ -52,7 +52,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-
#ifndef QT_NO_COMBOBOX
class QAbstractItemView;
@@ -305,12 +304,12 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_itemSelected(const QModelIndex &item))
Q_PRIVATE_SLOT(d_func(), void _q_emitHighlighted(const QModelIndex &))
Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentIndexChanged(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_editingFinished())
Q_PRIVATE_SLOT(d_func(), void _q_returnPressed())
Q_PRIVATE_SLOT(d_func(), void _q_resetButton())
Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateIndexBeforeChange())
Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end))
Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex & parent, int start, int end))
Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
Q_PRIVATE_SLOT(d_func(), void _q_modelReset())
diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h
index f7458c44b4..f6ba57cd84 100644
--- a/src/gui/widgets/qcombobox_p.h
+++ b/src/gui/widgets/qcombobox_p.h
@@ -231,7 +231,6 @@ public:
public Q_SLOTS:
void scrollItemView(int action);
void updateScrollers();
- void setCurrentIndex(const QModelIndex &index);
void viewDestroyed();
protected:
@@ -343,6 +342,8 @@ public:
void init();
QComboBoxPrivateContainer* viewContainer();
void updateLineEditGeometry();
+ Qt::MatchFlags matchFlags() const;
+ void _q_editingFinished();
void _q_returnPressed();
void _q_complete();
void _q_itemSelected(const QModelIndex &item);
@@ -357,9 +358,8 @@ public:
#endif
void _q_resetButton();
void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void _q_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end);
+ void _q_updateIndexBeforeChange();
void _q_rowsInserted(const QModelIndex & parent, int start, int end);
- void _q_rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end);
void _q_rowsRemoved(const QModelIndex & parent, int start, int end);
void updateArrow(QStyle::StateFlag state);
bool updateHoverControl(const QPoint &pos);
diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp
index 280ca6340b..2ee5751782 100644
--- a/src/gui/widgets/qdialogbuttonbox.cpp
+++ b/src/gui/widgets/qdialogbuttonbox.cpp
@@ -315,9 +315,9 @@ void QDialogButtonBoxPrivate::initLayout()
buttonLayout = new QVBoxLayout(q);
}
- int left, top, right, bottom;
+ int left, top, right, bottom;
setLayoutItemMargins(QStyle::SE_PushButtonLayoutItem);
- getLayoutItemMargins(&left, &top, &right, &bottom);
+ getLayoutItemMargins(&left, &top, &right, &bottom);
buttonLayout->setContentsMargins(-left, -top, -right, -bottom);
if (!q->testAttribute(Qt::WA_WState_OwnSizePolicy)) {
@@ -356,7 +356,7 @@ void QDialogButtonBoxPrivate::addButtonsToLayout(const QList<QAbstractButton *>
void QDialogButtonBoxPrivate::layoutButtons()
{
Q_Q(QDialogButtonBox);
- const int MacGap = 36 - 8; // 8 is the default gap between a widget and a spacer item
+ const int MacGap = 36 - 8; // 8 is the default gap between a widget and a spacer item
for (int i = buttonLayout->count() - 1; i >= 0; --i) {
QLayoutItem *item = buttonLayout->takeAt(i);
@@ -560,7 +560,7 @@ QAction* QDialogButtonBoxPrivate::createSoftKey(QAbstractButton *button, QDialog
Q_Q(QDialogButtonBox);
QAction::SoftKeyRole softkeyRole;
- QAction *action = new QAction(button->text(), q);
+ QAction *action = new QAction(button->text(), button);
switch (role) {
case ApplyRole:
@@ -581,7 +581,22 @@ QAction* QDialogButtonBoxPrivate::createSoftKey(QAbstractButton *button, QDialog
}
QObject::connect(action, SIGNAL(triggered()), button, SIGNAL(clicked()));
action->setSoftKeyRole(softkeyRole);
- action->setEnabled(button->isEnabled());
+
+
+ QWidget *dialog = 0;
+ QWidget *p = q;
+ while (p && !p->isWindow()) {
+ p = p->parentWidget();
+ if ((dialog = qobject_cast<QDialog *>(p)))
+ break;
+ }
+
+ if (dialog) {
+ dialog->addAction(action);
+ } else {
+ q->addAction(action);
+ }
+
return action;
}
#endif
@@ -874,6 +889,11 @@ void QDialogButtonBox::setOrientation(Qt::Orientation orientation)
void QDialogButtonBox::clear()
{
Q_D(QDialogButtonBox);
+#ifdef QT_SOFTKEYS_ENABLED
+ // Delete softkey actions as they have the buttons as parents
+ qDeleteAll(d->softKeyActions.values());
+ d->softKeyActions.clear();
+#endif
// Remove the created standard buttons, they should be in the other lists, which will
// do the deletion
d->standardButtonHash.clear();
@@ -1026,6 +1046,11 @@ QPushButton *QDialogButtonBox::addButton(StandardButton button)
void QDialogButtonBox::setStandardButtons(StandardButtons buttons)
{
Q_D(QDialogButtonBox);
+#ifdef QT_SOFTKEYS_ENABLED
+ // Delete softkey actions since they have the buttons as parents
+ qDeleteAll(d->softKeyActions.values());
+ d->softKeyActions.clear();
+#endif
// Clear out all the old standard buttons, then recreate them.
qDeleteAll(d->standardButtonHash.keys());
d->standardButtonHash.clear();
@@ -1184,12 +1209,8 @@ bool QDialogButtonBox::event(QEvent *event)
if (!hasDefault && firstAcceptButton)
firstAcceptButton->setDefault(true);
#ifdef QT_SOFTKEYS_ENABLED
- if (dialog) {
+ if (dialog)
setFixedSize(0,0);
- dialog->addActions(d->softKeyActions.values());
- } else {
- addActions(d->softKeyActions.values());
- }
#endif
}else if (event->type() == QEvent::LanguageChange) {
d->retranslateStrings();
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
index 5a0a9d4815..07914b292f 100644
--- a/src/gui/widgets/qdockarealayout.cpp
+++ b/src/gui/widgets/qdockarealayout.cpp
@@ -1556,9 +1556,10 @@ void QDockAreaLayoutInfo::apply(bool animate)
}
}
}
-
+#ifndef QT_NO_TABBAR
if (sep == 1)
updateSeparatorWidgets();
+#endif //QT_NO_TABBAR
}
static void paintSep(QPainter *p, QWidget *w, const QRect &r, Qt::Orientation o, bool mouse_over)
@@ -1840,7 +1841,6 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const
}
}
-#ifdef Q_WS_MAC
static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos)
{
switch (pos) {
@@ -1852,7 +1852,6 @@ static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos)
}
return Qt::NoDockWidgetArea;
}
-#endif
static QRect constrainedRect(QRect rect, const QRect &desktop)
{
@@ -1969,19 +1968,19 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
if (!testing) {
widget->setVisible(flags & StateFlagVisible);
+ item_list.append(item);
}
} else {
int dummy;
stream >> item.pos >> item.size >> dummy >> dummy;
if (!testing) {
+ item_list.append(item);
widget->setFloating(false);
widget->setVisible(flags & StateFlagVisible);
+ emit widget->dockLocationChanged(toDockWidgetArea(dockPos));
}
}
- if (!testing) {
- item_list.append(item);
- }
}
} else if (nextMarker == SequenceMarker) {
int dummy;
@@ -2008,13 +2007,14 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
updateTabBar();
setCurrentTabId(tabId(item_list.at(index)));
}
-#endif
if (!testing && sep == 1)
updateSeparatorWidgets();
+#endif
return true;
}
+#ifndef QT_NO_TABBAR
void QDockAreaLayoutInfo::updateSeparatorWidgets() const
{
if (tabbed) {
@@ -2065,6 +2065,7 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const
separatorWidgets.resize(j);
Q_ASSERT(separatorWidgets.size() == j);
}
+#endif //QT_NO_TABBAR
#ifndef QT_NO_TABBAR
void QDockAreaLayoutInfo::updateTabBar() const
@@ -2259,7 +2260,7 @@ QRect QDockAreaLayoutInfo::tabContentRect() const
** QDockAreaLayout
*/
-QDockAreaLayout::QDockAreaLayout(QMainWindow *win)
+QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(true)
{
mainWindow = win;
sep = win->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, win);
@@ -2346,6 +2347,9 @@ bool QDockAreaLayout::restoreState(QDataStream &stream, const QList<QDockWidget*
for (int i = 0; i < 4; ++i)
corners[i] = static_cast<Qt::DockWidgetArea>(cornerData[i]);
}
+
+ if (!testing)
+ fallbackToSizeHints = false;
}
return ok;
@@ -2582,7 +2586,7 @@ void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list,
{
QSize center_hint(0, 0);
QSize center_min(0, 0);
- bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty();
+ const bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty();
if (have_central) {
center_hint = centralWidgetRect.size();
if (!center_hint.isValid())
@@ -2601,33 +2605,35 @@ void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list,
center_rect.setBottom(rect.bottom() - docks[QInternal::BottomDock].rect.height() - sep);
QSize left_hint = docks[QInternal::LeftDock].size();
- if (left_hint.isNull())
+ if (left_hint.isNull() || fallbackToSizeHints)
left_hint = docks[QInternal::LeftDock].sizeHint();
QSize left_min = docks[QInternal::LeftDock].minimumSize();
QSize left_max = docks[QInternal::LeftDock].maximumSize();
left_hint = left_hint.boundedTo(left_max).expandedTo(left_min);
QSize right_hint = docks[QInternal::RightDock].size();
- if (right_hint.isNull())
+ if (right_hint.isNull() || fallbackToSizeHints)
right_hint = docks[QInternal::RightDock].sizeHint();
QSize right_min = docks[QInternal::RightDock].minimumSize();
QSize right_max = docks[QInternal::RightDock].maximumSize();
right_hint = right_hint.boundedTo(right_max).expandedTo(right_min);
QSize top_hint = docks[QInternal::TopDock].size();
- if (top_hint.isNull())
+ if (top_hint.isNull() || fallbackToSizeHints)
top_hint = docks[QInternal::TopDock].sizeHint();
QSize top_min = docks[QInternal::TopDock].minimumSize();
QSize top_max = docks[QInternal::TopDock].maximumSize();
top_hint = top_hint.boundedTo(top_max).expandedTo(top_min);
QSize bottom_hint = docks[QInternal::BottomDock].size();
- if (bottom_hint.isNull())
+ if (bottom_hint.isNull() || fallbackToSizeHints)
bottom_hint = docks[QInternal::BottomDock].sizeHint();
QSize bottom_min = docks[QInternal::BottomDock].minimumSize();
QSize bottom_max = docks[QInternal::BottomDock].maximumSize();
bottom_hint = bottom_hint.boundedTo(bottom_max).expandedTo(bottom_min);
+ fallbackToSizeHints = !have_central;
+
if (_ver_struct_list != 0) {
QVector<QLayoutStruct> &ver_struct_list = *_ver_struct_list;
ver_struct_list.resize(3);
@@ -3073,9 +3079,10 @@ void QDockAreaLayout::apply(bool animate)
widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect,
animate);
}
-
+#ifndef QT_NO_TABBAR
if (sep == 1)
updateSeparatorWidgets();
+#endif //QT_NO_TABBAR
}
void QDockAreaLayout::paintSeparators(QPainter *p, QWidget *widget,
@@ -3153,6 +3160,7 @@ int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &or
return delta;
}
+#ifndef QT_NO_TABBAR
// Sets the correct positions for the seperator widgets
// Allocates new sepearator widgets with getSeparatorWidget
void QDockAreaLayout::updateSeparatorWidgets() const
@@ -3186,6 +3194,7 @@ void QDockAreaLayout::updateSeparatorWidgets() const
separatorWidgets.resize(j);
}
+#endif //QT_NO_TABBAR
QLayoutItem *QDockAreaLayout::itemAt(int *x, int index) const
{
@@ -3238,7 +3247,6 @@ QSet<QTabBar*> QDockAreaLayout::usedTabBars() const
}
return result;
}
-#endif
// Returns the set of all used separator widgets
QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const
@@ -3253,6 +3261,7 @@ QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const
}
return result;
}
+#endif
QRect QDockAreaLayout::gapRect(const QList<int> &path) const
{
diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h
index 99a9dbb9b9..bd2067b3e8 100644
--- a/src/gui/widgets/qdockarealayout_p.h
+++ b/src/gui/widgets/qdockarealayout_p.h
@@ -196,9 +196,10 @@ public:
QRect rect;
QMainWindow *mainWindow;
QList<QDockAreaLayoutItem> item_list;
-
+#ifndef QT_NO_TABBAR
void updateSeparatorWidgets() const;
QSet<QWidget*> usedSeparatorWidgets() const;
+#endif //QT_NO_TABBAR
#ifndef QT_NO_TABBAR
quintptr currentTabId() const;
@@ -233,6 +234,7 @@ public:
QDockAreaLayout(QMainWindow *win);
QDockAreaLayoutInfo docks[4];
int sep; // separator extent
+ bool fallbackToSizeHints; //determines if we should use the sizehint for the dock areas (true until the layout is restored or the central widget is set)
mutable QVector<QWidget*> separatorWidgets;
bool isValid() const;
@@ -278,7 +280,9 @@ public:
const QPoint &mouse) const;
QRegion separatorRegion() const;
int separatorMove(const QList<int> &separator, const QPoint &origin, const QPoint &dest);
+#ifndef QT_NO_TABBAR
void updateSeparatorWidgets() const;
+#endif //QT_NO_TABBAR
QLayoutItem *itemAt(int *x, int index) const;
QLayoutItem *takeAt(int *x, int index);
@@ -292,9 +296,10 @@ public:
QRect gapRect(const QList<int> &path) const;
void keepSize(QDockWidget *w);
-
+#ifndef QT_NO_TABBAR
QSet<QTabBar*> usedTabBars() const;
QSet<QWidget*> usedSeparatorWidgets() const;
+#endif //QT_NO_TABBAR
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp
index a574262f27..9cf6af1245 100644
--- a/src/gui/widgets/qdockwidget.cpp
+++ b/src/gui/widgets/qdockwidget.cpp
@@ -456,7 +456,7 @@ int QDockWidgetLayout::titleHeight() const
int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);
- return qMax(buttonHeight + 2, titleFontMetrics.lineSpacing() + 2*mw);
+ return qMax(buttonHeight + 2, titleFontMetrics.height() + 2*mw);
}
void QDockWidgetLayout::setGeometry(const QRect &geometry)
@@ -685,8 +685,6 @@ void QDockWidgetPrivate::_q_toggleTopLevel()
void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
{
- Q_Q(QDockWidget);
-
if (state != 0)
return;
@@ -694,8 +692,6 @@ void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
Q_ASSERT(win != 0);
QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout());
Q_ASSERT(layout != 0);
- if (layout->layoutState.indexOf(q).isEmpty()) //The dock widget has not been added into the main window
- return;
if (layout->pluggingWidget != 0) // the main window is animating a docking operation
return;
@@ -1012,6 +1008,12 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect
{
Q_Q(QDockWidget);
+ if (!floating && parent) {
+ QMainWindowLayout *mwlayout = qobject_cast<QMainWindowLayout *>(q->parentWidget()->layout());
+ if (!mwlayout || mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea)
+ return; // this dockwidget can't be redocked
+ }
+
bool wasFloating = q->isFloating();
bool hidden = q->isHidden();
@@ -1223,6 +1225,7 @@ void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features)
features &= DockWidgetFeatureMask;
if (d->features == features)
return;
+ const bool closableChanged = (d->features ^ features) & DockWidgetClosable;
d->features = features;
QDockWidgetLayout *layout
= qobject_cast<QDockWidgetLayout*>(this->layout());
@@ -1231,6 +1234,10 @@ void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features)
d->toggleViewAction->setEnabled((d->features & DockWidgetClosable) == DockWidgetClosable);
emit featuresChanged(d->features);
update();
+ if (closableChanged && layout->nativeWindowDeco()) {
+ //this ensures the native decoration is drawn
+ d->setWindowState(true /*floating*/, true /*unplug*/);
+ }
}
QDockWidget::DockWidgetFeatures QDockWidget::features() const
diff --git a/src/gui/widgets/qfontcombobox.cpp b/src/gui/widgets/qfontcombobox.cpp
index 7b39823583..d601f81eb6 100644
--- a/src/gui/widgets/qfontcombobox.cpp
+++ b/src/gui/widgets/qfontcombobox.cpp
@@ -194,7 +194,7 @@ QSize QFontFamilyDelegate::sizeHint(const QStyleOptionViewItem &option,
// font.setFamily(text);
font.setPointSize(QFontInfo(font).pointSize() * 3/2);
QFontMetrics fontMetrics(font);
- return QSize(fontMetrics.width(text), fontMetrics.lineSpacing());
+ return QSize(fontMetrics.width(text), fontMetrics.height());
}
@@ -247,7 +247,14 @@ void QFontComboBoxPrivate::_q_updateModel()
}
list = result;
+ //we need to block the signals so that the model doesn't emit reset
+ //this prevents the current index from changing
+ //it will be updated just after this
+ ///TODO: we should finda way to avoid blocking signals and have a real update of the model
+ const bool old = m->blockSignals(true);
m->setStringList(list);
+ m->blockSignals(old);
+
if (list.isEmpty()) {
if (currentFont != QFont()) {
currentFont = QFont();
@@ -420,8 +427,10 @@ void QFontComboBox::setCurrentFont(const QFont &font)
Q_D(QFontComboBox);
if (font != d->currentFont) {
d->currentFont = font;
- emit currentFontChanged(d->currentFont);
d->_q_updateModel();
+ if (d->currentFont == font) { //else the signal has already be emitted by _q_updateModel
+ emit currentFontChanged(d->currentFont);
+ }
}
}
diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp
index 3d908a160b..ea711e805b 100644
--- a/src/gui/widgets/qlabel.cpp
+++ b/src/gui/widgets/qlabel.cpp
@@ -1170,22 +1170,10 @@ void QLabelPrivate::updateShortcut()
// But then we do want to hide the ampersands, so we can't use shortcutId.
hasShortcut = false;
- if (control) {
- ensureTextPopulated();
- // Underline the first character that follows an ampersand
- shortcutCursor = control->document()->find(QLatin1String("&"));
- if (shortcutCursor.isNull())
- return;
- hasShortcut = true;
- shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
- shortcutCursor.deleteChar(); // remove the ampersand
- shortcutCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
- } else {
- if (!text.contains(QLatin1Char('&')))
- return;
- hasShortcut = true;
- shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
- }
+ if (!text.contains(QLatin1Char('&')))
+ return;
+ hasShortcut = true;
+ shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
}
#endif // QT_NO_SHORTCUT
@@ -1456,6 +1444,24 @@ void QLabelPrivate::ensureTextPopulated() const
doc->setPlainText(text);
#endif
doc->setUndoRedoEnabled(false);
+
+#ifndef QT_NO_SHORTCUT
+ if (hasShortcut) {
+ // Underline the first character that follows an ampersand (and remove the others ampersands)
+ int from = 0;
+ bool found = false;
+ QTextCursor cursor;
+ while (!(cursor = control->document()->find((QLatin1String("&")), from)).isNull()) {
+ cursor.deleteChar(); // remove the ampersand
+ cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
+ from = cursor.position();
+ if (!found && cursor.selectedText() != QLatin1String("&")) { //not a second &
+ found = true;
+ shortcutCursor = cursor;
+ }
+ }
+ }
+#endif
}
}
textDirty = false;
diff --git a/src/gui/widgets/qlabel_p.h b/src/gui/widgets/qlabel_p.h
index c5a74e2855..ca17a359e0 100644
--- a/src/gui/widgets/qlabel_p.h
+++ b/src/gui/widgets/qlabel_p.h
@@ -113,7 +113,7 @@ public:
mutable uint hasShortcut : 1;
Qt::TextFormat textformat;
mutable QTextControl *control;
- QTextCursor shortcutCursor;
+ mutable QTextCursor shortcutCursor;
Qt::TextInteractionFlags textInteractionFlags;
inline bool needTextControl() const {
diff --git a/src/gui/widgets/qlcdnumber.cpp b/src/gui/widgets/qlcdnumber.cpp
index 9f9e353906..69c52cfc49 100644
--- a/src/gui/widgets/qlcdnumber.cpp
+++ b/src/gui/widgets/qlcdnumber.cpp
@@ -85,7 +85,7 @@ public:
decimal point with setSmallDecimalPoint().
QLCDNumber emits the overflow() signal when it is asked to display
- something beyond its range. The range is set by setNumDigits(),
+ something beyond its range. The range is set by setDigitCount(),
but setSmallDecimalPoint() also influences it. If the display is
set to hexadecimal, octal or binary, the integer equivalent of the
value is displayed.
@@ -160,7 +160,7 @@ public:
This signal is emitted whenever the QLCDNumber is asked to display
a too-large number or a too-long string.
- It is never emitted by setNumDigits().
+ It is never emitted by setDigitCount().
*/
@@ -345,7 +345,7 @@ static const char *getSegments(char ch) // gets list of segments f
The \a parent and \a name arguments are passed to the QFrame
constructor.
- \sa setNumDigits(), setSmallDecimalPoint()
+ \sa setDigitCount(), setSmallDecimalPoint()
*/
QLCDNumber::QLCDNumber(QWidget *parent, const char *name)
@@ -367,7 +367,7 @@ QLCDNumber::QLCDNumber(QWidget *parent, const char *name)
The \a parent and \a name arguments are passed to the QFrame
constructor.
- \sa setNumDigits(), setSmallDecimalPoint()
+ \sa setDigitCount(), setSmallDecimalPoint()
*/
QLCDNumber::QLCDNumber(uint numDigits, QWidget *parent, const char *name)
@@ -387,7 +387,7 @@ QLCDNumber::QLCDNumber(uint numDigits, QWidget *parent, const char *name)
The \a parent argument is passed to the QFrame constructor.
- \sa setNumDigits(), setSmallDecimalPoint()
+ \sa setDigitCount(), setSmallDecimalPoint()
*/
QLCDNumber::QLCDNumber(QWidget *parent)
@@ -407,7 +407,7 @@ QLCDNumber::QLCDNumber(QWidget *parent)
The \a parent argument is passed to the QFrame constructor.
- \sa setNumDigits(), setSmallDecimalPoint()
+ \sa setDigitCount(), setSmallDecimalPoint()
*/
QLCDNumber::QLCDNumber(uint numDigits, QWidget *parent)
@@ -426,7 +426,7 @@ void QLCDNumberPrivate::init()
val = 0;
base = QLCDNumber::Dec;
smallPoint = false;
- q->setNumDigits(ndigits);
+ q->setDigitCount(ndigits);
q->setSegmentStyle(QLCDNumber::Filled);
q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
}
@@ -441,8 +441,21 @@ QLCDNumber::~QLCDNumber()
/*!
+ \deprecated
\property QLCDNumber::numDigits
\brief the current number of digits displayed
+ \sa digitCount
+*/
+
+void QLCDNumber::setNumDigits(int numDigits)
+{
+ setDigitCount(numDigits);
+}
+
+/*!
+ \since 4.6
+ \property QLCDNumber::digitCount
+ \brief the current number of digits displayed
Corresponds to the current number of digits. If \l
QLCDNumber::smallDecimalPoint is false, the decimal point occupies
@@ -453,7 +466,11 @@ QLCDNumber::~QLCDNumber()
\sa smallDecimalPoint
*/
-void QLCDNumber::setNumDigits(int numDigits)
+/*!
+ Sets the current number of digits to \a numDigits. Must
+ be in the range 0..99.
+ */
+void QLCDNumber::setDigitCount(int numDigits)
{
Q_D(QLCDNumber);
if (numDigits > 99) {
@@ -470,7 +487,7 @@ void QLCDNumber::setNumDigits(int numDigits)
d->ndigits = numDigits;
d->digitStr.fill(QLatin1Char(' '), d->ndigits);
d->points.fill(0, d->ndigits);
- d->digitStr[d->ndigits - 1] = QLatin1Char('0'); // "0" is the default number
+ d->digitStr[d->ndigits - 1] = QLatin1Char('0'); // "0" is the default number
} else {
bool doDisplay = d->ndigits == 0;
if (numDigits == d->ndigits) // no change
@@ -509,12 +526,21 @@ int QLCDNumber::numDigits() const
}
/*!
+ Returns the current number of digits.
+ */
+int QLCDNumber::digitCount() const
+{
+ Q_D(const QLCDNumber);
+ return d->ndigits;
+}
+
+/*!
\overload
Returns true if \a num is too big to be displayed in its entirety;
otherwise returns false.
- \sa display(), numDigits(), smallDecimalPoint()
+ \sa display(), digitCount(), smallDecimalPoint()
*/
bool QLCDNumber::checkOverflow(int num) const
@@ -530,7 +556,7 @@ bool QLCDNumber::checkOverflow(int num) const
Returns true if \a num is too big to be displayed in its entirety;
otherwise returns false.
- \sa display(), numDigits(), smallDecimalPoint()
+ \sa display(), digitCount(), smallDecimalPoint()
*/
bool QLCDNumber::checkOverflow(double num) const
@@ -1256,7 +1282,7 @@ QLCDNumber::SegmentStyle QLCDNumber::segmentStyle() const
*/
QSize QLCDNumber::sizeHint() const
{
- return QSize(10 + 9 * (numDigits() + (smallDecimalPoint() ? 0 : 1)), 23);
+ return QSize(10 + 9 * (digitCount() + (smallDecimalPoint() ? 0 : 1)), 23);
}
/*! \reimp */
diff --git a/src/gui/widgets/qlcdnumber.h b/src/gui/widgets/qlcdnumber.h
index 9753f312ba..e65637deef 100644
--- a/src/gui/widgets/qlcdnumber.h
+++ b/src/gui/widgets/qlcdnumber.h
@@ -60,6 +60,7 @@ class Q_GUI_EXPORT QLCDNumber : public QFrame // LCD number widget
Q_ENUMS(Mode SegmentStyle)
Q_PROPERTY(bool smallDecimalPoint READ smallDecimalPoint WRITE setSmallDecimalPoint)
Q_PROPERTY(int numDigits READ numDigits WRITE setNumDigits)
+ Q_PROPERTY(int digitCount READ digitCount WRITE setDigitCount)
Q_PROPERTY(Mode mode READ mode WRITE setMode)
Q_PROPERTY(SegmentStyle segmentStyle READ segmentStyle WRITE setSegmentStyle)
Q_PROPERTY(double value READ value WRITE display)
@@ -82,8 +83,10 @@ public:
bool smallDecimalPoint() const;
- int numDigits() const;
- void setNumDigits(int nDigits);
+ QT_DEPRECATED int numDigits() const;
+ QT_DEPRECATED void setNumDigits(int nDigits);
+ int digitCount() const;
+ void setDigitCount(int nDigits);
bool checkOverflow(double num) const;
bool checkOverflow(int num) const;
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index 194df05895..ac3609cf12 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -401,7 +401,8 @@ void QLineControl::moveCursor(int pos, bool mark)
void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
{
int priorState = 0;
- bool isGettingInput = !event->commitString().isEmpty() || !event->preeditString().isEmpty()
+ bool isGettingInput = !event->commitString().isEmpty()
+ || event->preeditString() != preeditAreaText()
|| event->replacementLength() > 0;
bool cursorPositionChanged = false;
@@ -413,7 +414,7 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
int c = m_cursor; // cursor position after insertion of commit string
- if (event->replacementStart() <= 0)
+ if (event->replacementStart() == 0)
c += event->commitString().length() + qMin(-event->replacementStart(), event->replacementLength());
m_cursor += event->replacementStart();
@@ -447,8 +448,9 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
cursorPositionChanged = true;
}
}
-
+#ifndef QT_NO_IM
setPreeditArea(m_cursor, event->preeditString());
+#endif //QT_NO_IM
m_preeditCursor = event->preeditString().length();
m_hideCursor = false;
QList<QTextLayout::FormatRange> formats;
@@ -1290,7 +1292,7 @@ void QLineControl::setCursorBlinkPeriod(int msec)
m_blinkStatus = 1;
} else {
m_blinkTimer = 0;
- if (m_blinkStatus == 0)
+ if (m_blinkStatus == 1)
emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
}
m_blinkPeriod = msec;
@@ -1509,6 +1511,18 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
}
#endif // QT_NO_COMPLETER
+ if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
+ if (hasAcceptableInput() || fixup()) {
+ emit accepted();
+ emit editingFinished();
+ }
+ if (inlineCompletionAccepted)
+ event->accept();
+ else
+ event->ignore();
+ return;
+ }
+
if (echoMode() == QLineEdit::PasswordEchoOnEdit
&& !passwordEchoEditing()
&& !isReadOnly()
@@ -1529,17 +1543,6 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
clear();
}
- if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
- if (hasAcceptableInput() || fixup()) {
- emit accepted();
- emit editingFinished();
- }
- if (inlineCompletionAccepted)
- event->accept();
- else
- event->ignore();
- return;
- }
bool unknown = false;
if (false) {
diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h
index 68898b6098..f8e1a5d168 100644
--- a/src/gui/widgets/qlinecontrol_p.h
+++ b/src/gui/widgets/qlinecontrol_p.h
@@ -174,8 +174,10 @@ public:
void setMaxLength(int maxLength);
int maxLength() const;
+#ifndef QT_NO_VALIDATOR
const QValidator *validator() const;
void setValidator(const QValidator *);
+#endif
#ifndef QT_NO_COMPLETER
QCompleter *completer() const;
@@ -282,7 +284,9 @@ private:
bool finishChange(int validateFromState = -1, bool update = false, bool edited = true);
+#ifndef QT_NO_VALIDATOR
QPointer<QValidator> m_validator;
+#endif
QPointer<QCompleter> m_completer;
#ifndef QT_NO_COMPLETER
bool advanceToEnabledItem(int dir);
@@ -623,6 +627,7 @@ inline int QLineControl::maxLength() const
return m_maxLength;
}
+#ifndef QT_NO_VALIDATOR
inline const QValidator *QLineControl::validator() const
{
return m_validator;
@@ -632,6 +637,7 @@ inline void QLineControl::setValidator(const QValidator *v)
{
m_validator = const_cast<QValidator*>(v);
}
+#endif
#ifndef QT_NO_COMPLETER
inline QCompleter *QLineControl::completer() const
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index 629e839408..9f3fe4f98e 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -624,7 +624,7 @@ QSize QLineEdit::sizeHint() const
Q_D(const QLineEdit);
ensurePolished();
QFontMetrics fm(font());
- int h = qMax(fm.lineSpacing(), 14) + 2*d->verticalMargin
+ int h = qMax(fm.height(), 14) + 2*d->verticalMargin
+ d->topTextMargin + d->bottomTextMargin
+ d->topmargin + d->bottommargin;
int w = fm.width(QLatin1Char('x')) * 17 + 2*d->horizontalMargin
@@ -1102,6 +1102,17 @@ void QLineEdit::setTextMargins(int left, int top, int right, int bottom)
}
/*!
+ \since 4.6
+ Sets the \a margins around the text inside the frame.
+
+ See also textMargins().
+*/
+void QLineEdit::setTextMargins(const QMargins &margins)
+{
+ setTextMargins(margins.left(), margins.top(), margins.right(), margins.bottom());
+}
+
+/*!
Returns the widget's text margins for \a left, \a top, \a right, and \a bottom.
\since 4.5
@@ -1121,6 +1132,18 @@ void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) con
}
/*!
+ \since 4.6
+ Returns the widget's text margins.
+
+ \sa setTextMargins()
+*/
+QMargins QLineEdit::textMargins() const
+{
+ Q_D(const QLineEdit);
+ return QMargins(d->leftTextMargin, d->topTextMargin, d->rightTextMargin, d->bottomTextMargin);
+}
+
+/*!
\property QLineEdit::inputMask
\brief The validation input mask
@@ -1492,7 +1515,8 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
}
#endif
- d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
+ if (!isReadOnly())
+ d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
d->clickCausedFocus = 0;
}
@@ -1571,7 +1595,9 @@ void QLineEdit::keyPressEvent(QKeyEvent *event)
&& !isReadOnly())
{
setEditFocus(true);
+#ifndef Q_OS_SYMBIAN
clear();
+#endif
} else {
event->ignore();
return;
@@ -1628,7 +1654,9 @@ void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
&& hasFocus() && !hasEditFocus()
&& !e->preeditString().isEmpty()) {
setEditFocus(true);
+#ifndef Q_OS_SYMBIAN
selectAll(); // so text is replaced rather than appended to
+#endif
}
#endif
diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h
index 214509a505..ac918c716e 100644
--- a/src/gui/widgets/qlineedit.h
+++ b/src/gui/widgets/qlineedit.h
@@ -44,6 +44,7 @@
#include <QtGui/qframe.h>
#include <QtCore/qstring.h>
+#include <QtCore/qmargins.h>
QT_BEGIN_HEADER
@@ -158,7 +159,9 @@ public:
bool hasAcceptableInput() const;
void setTextMargins(int left, int top, int right, int bottom);
+ void setTextMargins(const QMargins &margins);
void getTextMargins(int *left, int *top, int *right, int *bottom) const;
+ QMargins textMargins() const;
public Q_SLOTS:
void setText(const QString &);
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp
index 027a5d6527..fa6f7a1777 100644
--- a/src/gui/widgets/qmainwindowlayout.cpp
+++ b/src/gui/widgets/qmainwindowlayout.cpp
@@ -1641,6 +1641,9 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
savedState.clear();
currentGapPos.clear();
pluggingWidget = 0;
+ //applying the state will make sure that the currentGap is updated correctly
+ //and all the geometries (especially the one from the central widget) is correct
+ layoutState.apply(false);
}
if (!widgetAnimator.animating()) {
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 687e1bc3b4..fc88d06600 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -180,6 +180,21 @@ int QMenuPrivate::scrollerHeight() const
}
//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
+QRect QMenuPrivate::popupGeometry(const QWidget *widget) const
+{
+#ifdef Q_WS_WIN
+ return QApplication::desktop()->screenGeometry(widget);
+#elif defined Q_WS_X11
+ if (X11->desktopEnvironment == DE_KDE)
+ return QApplication::desktop()->screenGeometry(widget);
+ else
+ return QApplication::desktop()->availableGeometry(widget);
+#else
+ return QApplication::desktop()->availableGeometry(widget);
+#endif
+}
+
+//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
QRect QMenuPrivate::popupGeometry(int screen) const
{
#ifdef Q_WS_WIN
@@ -234,7 +249,7 @@ void QMenuPrivate::updateActionRects() const
}
int max_column_width = 0,
- dh = popupGeometry(QApplication::desktop()->screenNumber(q)).height(),
+ dh = popupGeometry(q).height(),
y = 0;
QStyle *style = q->style();
QStyleOption opt;
@@ -258,7 +273,7 @@ void QMenuPrivate::updateActionRects() const
for (int i = 0; i < actions.count(); ++i) {
QAction *action = actions.at(i);
- if (action->isSeparator() || !action->isVisible() || widgetItems.at(i))
+ if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action))
continue;
//..and some members
hasCheckableItems |= action->isCheckable();
@@ -286,7 +301,7 @@ void QMenuPrivate::updateActionRects() const
const QFontMetrics &fm = opt.fontMetrics;
QSize sz;
- if (QWidget *w = widgetItems.at(i)) {
+ if (QWidget *w = widgetItems.value(action)) {
sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize());
} else {
//calc what I think the size is..
@@ -355,7 +370,7 @@ void QMenuPrivate::updateActionRects() const
rect.setWidth(max_column_width); //uniform width
//we need to update the widgets geometry
- if (QWidget *widget = widgetItems.at(i)) {
+ if (QWidget *widget = widgetItems.value(actions.at(i))) {
widget->setGeometry(rect);
widget->setVisible(actions.at(i)->isVisible());
}
@@ -568,8 +583,7 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
q->update(actionRect(action));
if (reason == SelectedFromKeyboard) {
- const int actionIndex = actions.indexOf(action);
- QWidget *widget = widgetItems.at(actionIndex);
+ QWidget *widget = widgetItems.value(action);
if (widget) {
if (widget->focusPolicy() != Qt::NoFocus)
widget->setFocus(Qt::TabFocusReason);
@@ -588,14 +602,7 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
}
#ifndef QT_NO_STATUSTIP
} else if (previousAction) {
- QWidget *w = causedPopup.widget;
- while (QMenu *m = qobject_cast<QMenu*>(w))
- w = m->d_func()->causedPopup.widget;
- if (w) {
- QString empty;
- QStatusTipEvent tip(empty);
- QApplication::sendEvent(w, &tip);
- }
+ previousAction->d_func()->showStatusText(topCausedWidget(), QString());
#endif
}
if (hideActiveMenu) {
@@ -609,6 +616,15 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
}
}
+//return the top causedPopup.widget that is not a QMenu
+QWidget *QMenuPrivate::topCausedWidget() const
+{
+ QWidget* top = causedPopup.widget;
+ while (QMenu* m = qobject_cast<QMenu *>(top))
+ top = m->d_func()->causedPopup.widget;
+ return top;
+}
+
QAction *QMenuPrivate::actionAt(QPoint p) const
{
if (!q_func()->rect().contains(p)) //sanity check
@@ -744,7 +760,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
if (newScrollFlags & QMenuScroller::ScrollUp)
newOffset -= vmargin;
- QRect screen = popupGeometry(QApplication::desktop()->screenNumber(q));
+ QRect screen = popupGeometry(q);
const int desktopFrame = q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q);
if (q->height() < screen.height()-(desktopFrame*2)-1) {
QRect geom = q->geometry();
@@ -785,7 +801,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
current.moveTop(current.top() + delta);
//we need to update the widgets geometry
- if (QWidget *w = widgetItems.at(i))
+ if (QWidget *w = widgetItems.value(actions.at(i)))
w->setGeometry(current);
}
}
@@ -960,10 +976,19 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
return false;
}
+class ExceptionGuard
+{
+public:
+ inline ExceptionGuard(bool *w = 0) : watched(w) { Q_ASSERT(!(*watched)); *watched = true; }
+ inline ~ExceptionGuard() { *watched = false; }
+ inline operator bool() { return *watched; }
+private:
+ bool *watched;
+};
+
void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self)
{
- Q_ASSERT(!activationRecursionGuard);
- activationRecursionGuard = true;
+ ExceptionGuard guard(&activationRecursionGuard);
#ifdef QT3_SUPPORT
const int actionId = q_func()->findIdForAction(action);
#endif
@@ -1008,7 +1033,6 @@ void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget> > &causedSt
#endif
}
}
- activationRecursionGuard = false;
}
void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e, bool self)
@@ -1072,10 +1096,7 @@ void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e
QAccessible::updateAccessibility(q, actionIndex, QAccessible::Selection);
}
#endif
- QWidget *w = causedPopup.widget;
- while (QMenu *m = qobject_cast<QMenu*>(w))
- w = m->d_func()->causedPopup.widget;
- action->showStatusText(w);
+ action->showStatusText(topCausedWidget());
} else {
actionAboutToTrigger = 0;
}
@@ -1085,6 +1106,7 @@ void QMenuPrivate::_q_actionTriggered()
{
Q_Q(QMenu);
if (QAction *action = qobject_cast<QAction *>(q->sender())) {
+ QWeakPointer<QAction> actionGuard = action;
#ifdef QT3_SUPPORT
//we store it here because the action might be deleted/changed by connected slots
const int id = q->findIdForAction(action);
@@ -1094,7 +1116,7 @@ void QMenuPrivate::_q_actionTriggered()
emit q->activated(id);
#endif
- if (!activationRecursionGuard) {
+ if (!activationRecursionGuard && actionGuard) {
//in case the action has not been activated by the mouse
//we check the parent hierarchy
QList< QPointer<QWidget> > list;
@@ -1369,11 +1391,12 @@ QMenu::QMenu(QMenuPrivate &dd, QWidget *parent)
QMenu::~QMenu()
{
Q_D(QMenu);
- for (int i = 0; i < d->widgetItems.count(); ++i) {
- if (QWidget *widget = d->widgetItems.at(i)) {
- QWidgetAction *action = static_cast<QWidgetAction *>(d->actions.at(i));
+ QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin();
+ for (; it != d->widgetItems.end(); ++it) {
+ if (QWidget *widget = it.value()) {
+ QWidgetAction *action = static_cast<QWidgetAction *>(it.key());
action->releaseWidget(widget);
- d->widgetItems[i] = 0;
+ *it = 0;
}
}
@@ -1778,10 +1801,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
#ifndef QT_NO_MENUBAR
// if this menu is part of a chain attached to a QMenuBar, set the
// _NET_WM_WINDOW_TYPE_DROPDOWN_MENU X11 window type
- QWidget* top = this;
- while (QMenu* m = qobject_cast<QMenu *>(top))
- top = m->d_func()->causedPopup.widget;
- setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(top) != 0);
+ setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(d->topCausedWidget()) != 0);
#endif
ensurePolished(); // Get the right font
@@ -1789,7 +1809,15 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
d->updateActionRects();
QPoint pos = p;
QSize size = sizeHint();
- QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(p));
+ QRect screen;
+#ifndef QT_NO_GRAPHICSVIEW
+ bool isEmbedded = d->nearestGraphicsProxyWidget(this);
+ if (isEmbedded)
+ screen = d->popupGeometry(this);
+ 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);
#ifdef QT_KEYPAD_NAVIGATION
@@ -1847,6 +1875,12 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
if(snapToMouse) //position flowing left from the mouse
pos.setX(mouse.x()-size.width());
+#ifndef QT_NO_MENUBAR
+ //if in a menubar, it should be right-aligned
+ if (qobject_cast<QMenuBar*>(d->causedPopup.widget))
+ pos.rx() -= size.width();
+#endif //QT_NO_MENUBAR
+
if (pos.x() < screen.left()+desktopFrame)
pos.setX(qMax(p.x(), screen.left()+desktopFrame));
if (pos.x()+size.width()-1 > screen.right()-desktopFrame)
@@ -2116,7 +2150,7 @@ void QMenu::paintEvent(QPaintEvent *e)
QAction *action = d->actions.at(i);
QRect adjustedActionRect = d->actionRects.at(i);
if (!e->rect().intersects(adjustedActionRect)
- || d->widgetItems.at(i))
+ || d->widgetItems.value(action))
continue;
//set the clip region to be extra safe (and adjust for the scrollers)
QRegion adjustedActionReg(adjustedActionRect);
@@ -2715,18 +2749,14 @@ void QMenu::keyPressEvent(QKeyEvent *e)
}
}
if (!key_consumed) {
- if (QWidget *caused = d->causedPopup.widget) {
- while(QMenu *m = qobject_cast<QMenu*>(caused))
- caused = m->d_func()->causedPopup.widget;
#ifndef QT_NO_MENUBAR
- if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
- QAction *oldAct = mb->d_func()->currentAction;
- QApplication::sendEvent(mb, e);
- if (mb->d_func()->currentAction != oldAct)
- key_consumed = true;
- }
-#endif
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->topCausedWidget())) {
+ QAction *oldAct = mb->d_func()->currentAction;
+ QApplication::sendEvent(mb, e);
+ if (mb->d_func()->currentAction != oldAct)
+ key_consumed = true;
}
+#endif
}
#ifdef Q_OS_WIN32
@@ -2827,25 +2857,20 @@ void QMenu::actionEvent(QActionEvent *e)
connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
}
- QWidget *widget = 0;
- if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action()))
- widget = wa->requestWidget(this);
-
- int index = d->actions.indexOf(e->action());
- Q_ASSERT(index != -1);
- d->widgetItems.insert(index, widget);
-
+ if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
+ QWidget *widget = wa->requestWidget(this);
+ if (widget)
+ d->widgetItems.insert(wa, widget);
+ }
} else if (e->type() == QEvent::ActionRemoved) {
e->action()->disconnect(this);
if (e->action() == d->currentAction)
d->currentAction = 0;
- int index = d->actions.indexOf(e->before()) + 1;
if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
- if (QWidget *widget = d->widgetItems.at(index))
+ if (QWidget *widget = d->widgetItems.value(wa))
wa->releaseWidget(widget);
}
- Q_ASSERT(index != -1);
- d->widgetItems.removeAt(index);
+ d->widgetItems.remove(e->action());
}
#ifdef Q_WS_MAC
@@ -2927,7 +2952,7 @@ void QMenu::internalDelayedPopup()
QPoint pos(rightPos);
QMenu *caused = qobject_cast<QMenu*>(d->activeMenu->d_func()->causedPopup.widget);
- const QRect availGeometry(d->popupGeometry(QApplication::desktop()->screenNumber(caused)));
+ const QRect availGeometry(d->popupGeometry(caused));
if (isRightToLeft()) {
pos = leftPos;
if ((caused && caused->x() < x()) || pos.x() < availGeometry.left()) {
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index 4fc3d3d589..9510cc666d 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -1191,7 +1191,7 @@ QMenuPrivate::QMacMenuPrivate::addAction(QMacMenuAction *action, QMacMenuAction
#endif
}
- QWidget *widget = qmenu ? qmenu->widgetItems.value(qmenu->actions.indexOf(action->action)) : 0;
+ QWidget *widget = qmenu ? qmenu->widgetItems.value(action->action) : 0;
if (widget) {
#ifndef QT_MAC_USE_COCOA
ChangeMenuAttributes(action->menu, kMenuAttrDoNotCacheImage, 0);
@@ -1425,7 +1425,7 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action)
SetMenuItemProperty(data.submenuHandle, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), &caused);
#else
NSMenu *subMenu = static_cast<NSMenu *>(action->action->menu()->macMenu());
- if ([subMenu supermenu] != nil) {
+ if ([subMenu supermenu] && [subMenu supermenu] != [item menu]) {
// The menu is already a sub-menu of another one. Cocoa will throw an exception,
// in such cases. For the time being, a new QMenu with same set of actions is the
// only workaround.
@@ -1718,7 +1718,7 @@ QMenuBarPrivate::QMacMenuBarPrivate::syncAction(QMacMenuAction *action)
GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(caused), 0, &caused);
SetMenuItemProperty(submenu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), &caused);
#else
- if ([submenu supermenu] != nil)
+ if ([submenu supermenu] && [submenu supermenu] != [item menu])
return;
else
[item setSubmenu:submenu];
@@ -1771,6 +1771,16 @@ QMenuBarPrivate::QMacMenuBarPrivate::removeAction(QMacMenuAction *action)
actionItems.removeAll(action);
}
+bool QMenuBarPrivate::macWidgetHasNativeMenubar(QWidget *widget)
+{
+ // This function is different from q->isNativeMenuBar(), as
+ // it returns true only if a native menu bar is actually
+ // _created_.
+ if (!widget)
+ return false;
+ return menubars()->contains(widget->window());
+}
+
void
QMenuBarPrivate::macCreateMenuBar(QWidget *parent)
{
@@ -1778,16 +1788,22 @@ QMenuBarPrivate::macCreateMenuBar(QWidget *parent)
static int dontUseNativeMenuBar = -1;
// We call the isNativeMenuBar function here
// because that will make sure that local overrides
- // are dealt with correctly.
+ // are dealt with correctly. q->isNativeMenuBar() will, if not
+ // overridden, depend on the attribute Qt::AA_DontUseNativeMenuBar:
bool qt_mac_no_native_menubar = !q->isNativeMenuBar();
if (qt_mac_no_native_menubar == false && dontUseNativeMenuBar < 0) {
+ // The menubar is set to be native. Let's check (one time only
+ // for all menubars) if this is OK with the rest of the environment.
+ // As a result, Qt::AA_DontUseNativeMenuBar is set. NB: the application
+ // might still choose to not respect, or change, this flag.
bool isPlugin = QApplication::testAttribute(Qt::AA_MacPluginApplication);
bool environmentSaysNo = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty();
dontUseNativeMenuBar = isPlugin || environmentSaysNo;
QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, dontUseNativeMenuBar);
qt_mac_no_native_menubar = !q->isNativeMenuBar();
}
- if (!qt_mac_no_native_menubar) {
+ if (qt_mac_no_native_menubar == false) {
+ // INVARIANT: Use native menubar.
extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp
qt_event_request_menubarupdate();
if (!parent && !fallback) {
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
index 9c4f260896..c021063309 100644
--- a/src/gui/widgets/qmenu_p.h
+++ b/src/gui/widgets/qmenu_p.h
@@ -190,13 +190,14 @@ public:
QRect actionRect(QAction *) const;
mutable QVector<QRect> actionRects;
- mutable QWidgetList widgetItems;
+ mutable QHash<QAction *, QWidget *> widgetItems;
void updateActionRects() const;
- QRect popupGeometry(int screen=-1) 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;
- uint activationRecursionGuard : 1;
+ bool activationRecursionGuard;
//selection
static QPointer<QMenu> mouseDown;
@@ -214,6 +215,7 @@ public:
SelectedFromKeyboard,
SelectedFromElsewhere
};
+ QWidget *topCausedWidget() const;
QAction *actionAt(QPoint p) const;
void setFirstActionActive();
void setCurrentAction(QAction *, int popup = -1, SelectionReason reason = SelectedFromElsewhere, bool activateFirst = false);
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
index d757f98818..94c4177871 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -243,11 +243,14 @@ void qt_symbian_show_submenu( CEikMenuPane* menuPane, int id)
}
#endif // Q_WS_S60
-void QMenuBarPrivate::symbianCommands(int command)
+int QMenuBarPrivate::symbianCommands(int command)
{
+ int ret = 0;
+
if (command == contexMenuCommand && !widgetWithContextMenu.isNull()) {
QContextMenuEvent* event = new QContextMenuEvent(QContextMenuEvent::Keyboard, QPoint(0,0));
QCoreApplication::postEvent(widgetWithContextMenu, event);
+ ret = 1;
}
int size = nativeMenuBars.size();
@@ -258,8 +261,11 @@ void QMenuBarPrivate::symbianCommands(int command)
emit nativeMenuBars.at(i)->triggered(menu->action);
menu->action->activate(QAction::Trigger);
+ ret = 1;
break;
}
+
+ return ret;
}
void QMenuBarPrivate::symbianCreateMenuBar(QWidget *parent)
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index 13e7de4fd2..b1ff662cb0 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -332,34 +332,31 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));
QSize popup_size = activeMenu->sizeHint();
- QRect screenRect = QApplication::desktop()->screenGeometry(pos);
+ //we put the popup menu on the screen containing the bottom-center of the action rect
+ QRect screenRect = QApplication::desktop()->screenGeometry(pos + QPoint(adjustedActionRect.width() / 2, 0));
+ pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
const bool fitUp = (q->mapToGlobal(adjustedActionRect.topLeft()).y() >= popup_size.height());
const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
+ const bool rtl = q->isRightToLeft();
const int actionWidth = adjustedActionRect.width();
if (!fitUp && !fitDown) { //we should shift the menu
- bool shouldShiftToRight = !q->isRightToLeft();
- if (q->isRightToLeft() && popup_size.width() > pos.x())
+ bool shouldShiftToRight = !rtl;
+ if (rtl && popup_size.width() > pos.x())
shouldShiftToRight = true;
else if (actionWidth + popup_size.width() + pos.x() > screenRect.right())
shouldShiftToRight = false;
- if (shouldShiftToRight)
- pos.rx() += actionWidth;
- else
- pos.rx() -= popup_size.width();
- } else if (q->isRightToLeft()) {
- pos.setX(pos.x()-(popup_size.width() - actionWidth));
- }
-
- if(pos.x() < screenRect.x()) {
- pos.setX(screenRect.x());
- } else {
- const int off = pos.x()+popup_size.width() - screenRect.right();
- if(off > 0)
- pos.setX(qMax(screenRect.x(), pos.x()-off));
-
+ if (shouldShiftToRight) {
+ pos.rx() += actionWidth + (rtl ? popup_size.width() : 0);
+ } else {
+ //shift to left
+ if (!rtl)
+ pos.rx() -= popup_size.width();
+ }
+ } else if (rtl) {
+ pos.rx() += actionWidth;
}
if(!defaultPopDown || (fitUp && !fitDown))
@@ -1370,8 +1367,13 @@ void QMenuBarPrivate::handleReparent()
oldWindow = newWindow;
#ifdef Q_WS_MAC
- macDestroyMenuBar();
- macCreateMenuBar(newParent);
+ if (q->isNativeMenuBar() && !macWidgetHasNativeMenubar(newParent)) {
+ // If the new parent got a native menubar from before, keep that
+ // menubar rather than replace it with this one (because a parents
+ // menubar has precedence over children menubars).
+ macDestroyMenuBar();
+ macCreateMenuBar(newParent);
+ }
#endif
#ifdef Q_WS_WINCE
diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h
index 0b27b97f12..da2b8d7f19 100644
--- a/src/gui/widgets/qmenubar_p.h
+++ b/src/gui/widgets/qmenubar_p.h
@@ -196,6 +196,7 @@ public:
return 0;
}
} *mac_menubar;
+ bool macWidgetHasNativeMenubar(QWidget *widget);
void macCreateMenuBar(QWidget *);
void macDestroyMenuBar();
OSMenuRef macMenu();
@@ -265,7 +266,7 @@ public:
void insertNativeMenuItems(const QList<QAction*> &actions);
} *symbian_menubar;
- static void symbianCommands(int command);
+ static int symbianCommands(int command);
#endif
};
diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp
index 22438bff17..c7759e854f 100644
--- a/src/gui/widgets/qplaintextedit.cpp
+++ b/src/gui/widgets/qplaintextedit.cpp
@@ -357,10 +357,8 @@ void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
Q_D(QPlainTextDocumentLayout);
QTextDocument *doc = document();
qreal margin = doc->documentMargin();
- QFontMetrics fm(doc->defaultFont());
qreal blockMaximumWidth = 0;
- int leading = qMax(0, fm.leading());
qreal height = 0;
QTextLayout *tl = block.layout();
QTextOption option = doc->defaultTextOption();
@@ -381,9 +379,8 @@ void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
QTextLine line = tl->createLine();
if (!line.isValid())
break;
+ line.setLeadingIncluded(true);
line.setLineWidth(availableWidth);
-
- height += leading;
line.setPosition(QPointF(margin, height));
height += line.height();
blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
@@ -733,9 +730,6 @@ QPlainTextEditPrivate::QPlainTextEditPrivate()
backgroundVisible = false;
centerOnScroll = false;
inDrag = false;
-#ifdef Q_WS_WIN
- singleFingerPanEnabled = true;
-#endif
}
@@ -792,6 +786,9 @@ void QPlainTextEditPrivate::init(const QString &txt)
viewport->setCursor(Qt::IBeamCursor);
#endif
originalOffsetY = 0;
+#ifdef Q_WS_WIN
+ setSingleFingerPanEnabled(true);
+#endif
}
void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
@@ -1453,6 +1450,29 @@ bool QPlainTextEdit::event(QEvent *e)
d->sendControlEvent(e);
}
#endif
+ else if (e->type() == QEvent::Gesture) {
+ QGestureEvent *ge = static_cast<QGestureEvent *>(e);
+ QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
+ if (g) {
+ QScrollBar *hBar = horizontalScrollBar();
+ QScrollBar *vBar = verticalScrollBar();
+ if (g->state() == Qt::GestureStarted)
+ d->originalOffsetY = vBar->value();
+ QPointF offset = g->offset();
+ if (!offset.isNull()) {
+ if (QApplication::isRightToLeft())
+ offset.rx() *= -1;
+ // QPlainTextEdit scrolls by lines only in vertical direction
+ QFontMetrics fm(document()->defaultFont());
+ int lineHeight = fm.height();
+ int newX = hBar->value() - g->delta().x();
+ int newY = d->originalOffsetY - offset.y()/lineHeight;
+ hBar->setValue(newX);
+ vBar->setValue(newY);
+ }
+ }
+ return true;
+ }
return QAbstractScrollArea::event(e);
}
@@ -1602,7 +1622,6 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
return;
}
}
-#endif // QT_NO_SHORTCUT
if (!(tif & Qt::TextEditable)) {
switch (e->key()) {
@@ -1630,6 +1649,7 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
}
return;
}
+#endif // QT_NO_SHORTCUT
d->sendControlEvent(e);
#ifdef QT_KEYPAD_NAVIGATION
@@ -1946,7 +1966,8 @@ void QPlainTextEdit::mouseReleaseEvent(QMouseEvent *e)
d->ensureCursorVisible();
}
- d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
+ if (!isReadOnly())
+ d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
d->clickCausedFocus = 0;
}
@@ -2932,30 +2953,6 @@ QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() cons
(\a available is true) or unavailable (\a available is false).
*/
-//void QPlainTextEditPrivate::_q_gestureTriggered()
-//{
-// Q_Q(QPlainTextEdit);
-// QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
-// if (!g)
-// return;
-// QScrollBar *hBar = q->horizontalScrollBar();
-// QScrollBar *vBar = q->verticalScrollBar();
-// if (g->state() == Qt::GestureStarted)
-// originalOffsetY = vBar->value();
-// QSizeF totalOffset = g->totalOffset();
-// if (!totalOffset.isNull()) {
-// if (QApplication::isRightToLeft())
-// totalOffset.rwidth() *= -1;
-// // QPlainTextEdit scrolls by lines only in vertical direction
-// QFontMetrics fm(q->document()->defaultFont());
-// int lineHeight = fm.height();
-// int newX = hBar->value() - g->lastOffset().width();
-// int newY = originalOffsetY - totalOffset.height()/lineHeight;
-// hbar->setValue(newX);
-// vbar->setValue(newY);
-// }
-//}
-
QT_END_NAMESPACE
#include "moc_qplaintextedit.cpp"
diff --git a/src/gui/widgets/qprintpreviewwidget.cpp b/src/gui/widgets/qprintpreviewwidget.cpp
index d92b1ea3a2..0074c91cc7 100644
--- a/src/gui/widgets/qprintpreviewwidget.cpp
+++ b/src/gui/widgets/qprintpreviewwidget.cpp
@@ -663,7 +663,9 @@ void QPrintPreviewWidget::setZoomFactor(qreal factor)
}
/*!
+ \obsolete
Returns the number of pages in the preview.
+ \sa pageCount()
*/
int QPrintPreviewWidget::numPages() const
{
@@ -672,6 +674,16 @@ int QPrintPreviewWidget::numPages() const
}
/*!
+ \since 4.6
+ Returns the number of pages in the preview.
+*/
+int QPrintPreviewWidget::pageCount() const
+{
+ Q_D(const QPrintPreviewWidget);
+ return d->pages.size();
+}
+
+/*!
Returns the currently viewed page in the preview.
*/
int QPrintPreviewWidget::currentPage() const
diff --git a/src/gui/widgets/qprintpreviewwidget.h b/src/gui/widgets/qprintpreviewwidget.h
index 2823873a6c..08e596d43a 100644
--- a/src/gui/widgets/qprintpreviewwidget.h
+++ b/src/gui/widgets/qprintpreviewwidget.h
@@ -82,7 +82,8 @@ public:
ViewMode viewMode() const;
ZoomMode zoomMode() const;
int currentPage() const;
- int numPages() const;
+ QT_DEPRECATED int numPages() const;
+ int pageCount() const;
void setVisible(bool visible);
public Q_SLOTS:
diff --git a/src/gui/widgets/qpushbutton.cpp b/src/gui/widgets/qpushbutton.cpp
index 1352e1b614..eb34336a53 100644
--- a/src/gui/widgets/qpushbutton.cpp
+++ b/src/gui/widgets/qpushbutton.cpp
@@ -590,7 +590,7 @@ void QPushButtonPrivate::_q_popupPressed()
int x = globalPos.x();
int y = globalPos.y();
if (horizontal) {
- if (globalPos.y() + rect.height() + menuSize.height() <= QApplication::desktop()->height()) {
+ if (globalPos.y() + rect.height() + menuSize.height() <= QApplication::desktop()->availableGeometry(q).height()) {
y += rect.height();
} else {
y -= menuSize.height();
@@ -598,7 +598,7 @@ void QPushButtonPrivate::_q_popupPressed()
if (q->layoutDirection() == Qt::RightToLeft)
x += rect.width() - menuSize.width();
} else {
- if (globalPos.x() + rect.width() + menu->sizeHint().width() <= QApplication::desktop()->width())
+ if (globalPos.x() + rect.width() + menu->sizeHint().width() <= QApplication::desktop()->availableGeometry(q).width())
x += rect.width();
else
x -= menuSize.width();
diff --git a/src/gui/widgets/qsplitter.cpp b/src/gui/widgets/qsplitter.cpp
index e3121ae534..520a8022fe 100644
--- a/src/gui/widgets/qsplitter.cpp
+++ b/src/gui/widgets/qsplitter.cpp
@@ -360,13 +360,26 @@ void QSplitterPrivate::recalc(bool update)
before a hidden widget must be hidden.
*/
bool first = true;
+ bool allInvisible = n != 0;
for (int i = 0; i < n ; ++i) {
QSplitterLayoutStruct *s = list.at(i);
- s->handle->setHidden(first || s->widget->isHidden());
- if (!s->widget->isHidden())
+ bool widgetHidden = s->widget->isHidden();
+ if (allInvisible && !widgetHidden && !s->collapsed)
+ allInvisible = false;
+ s->handle->setHidden(first || widgetHidden);
+ if (!widgetHidden)
first = false;
}
+ if (allInvisible)
+ for (int i = 0; i < n ; ++i) {
+ QSplitterLayoutStruct *s = list.at(i);
+ if (!s->widget->isHidden()) {
+ s->collapsed = false;
+ break;
+ }
+ }
+
int fi = 2 * q->frameWidth();
int maxl = fi;
int minl = fi;
diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp
index 6c9761c94a..3935c55626 100644
--- a/src/gui/widgets/qtabbar.cpp
+++ b/src/gui/widgets/qtabbar.cpp
@@ -1694,6 +1694,9 @@ void QTabBar::mousePressEvent(QMouseEvent *event)
d->moveTabFinished(d->pressedIndex);
d->pressedIndex = d->indexAtPos(event->pos());
+#ifdef Q_WS_MAC
+ d->previousPressedIndex = d->pressedIndex;
+#endif
if (d->validIndex(d->pressedIndex)) {
QStyleOptionTabBarBaseV2 optTabBase;
optTabBase.init(this);
@@ -1774,6 +1777,17 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event)
update();
}
+#ifdef Q_WS_MAC
+ } else if (!d->documentMode && event->buttons() == Qt::LeftButton && d->previousPressedIndex != -1) {
+ int newPressedIndex = d->indexAtPos(event->pos());
+ if (d->pressedIndex == -1 && d->previousPressedIndex == newPressedIndex) {
+ d->pressedIndex = d->previousPressedIndex;
+ update(tabRect(d->pressedIndex));
+ } else if(d->pressedIndex != newPressedIndex) {
+ d->pressedIndex = -1;
+ update(tabRect(d->previousPressedIndex));
+ }
+#endif
}
if (event->buttons() != Qt::LeftButton) {
@@ -1798,6 +1812,7 @@ void QTabBarPrivate::setupMovableTab()
QPixmap grabImage(grabRect.size());
grabImage.fill(Qt::transparent);
QStylePainter p(&grabImage, q);
+ p.initFrom(q);
QStyleOptionTabV3 tab;
q->initStyleOption(&tab, pressedIndex);
@@ -1865,7 +1880,9 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event)
event->ignore();
return;
}
-
+#ifdef Q_WS_MAC
+ d->previousPressedIndex = -1;
+#endif
if (d->movable && d->dragInProgress && d->validIndex(d->pressedIndex)) {
int length = d->tabList[d->pressedIndex].dragOffset;
int width = verticalTabs(d->shape)
diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h
index 494a340205..9f3285ba1b 100644
--- a/src/gui/widgets/qtabbar_p.h
+++ b/src/gui/widgets/qtabbar_p.h
@@ -77,7 +77,11 @@ public:
:currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false),
drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false),
selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false),
- dragInProgress(false), documentMode(false), movingTab(0) {}
+ dragInProgress(false), documentMode(false), movingTab(0)
+#ifdef Q_WS_MAC
+ , previousPressedIndex(-1)
+#endif
+ {}
int currentIndex;
int pressedIndex;
@@ -195,7 +199,9 @@ public:
bool documentMode;
QWidget *movingTab;
-
+#ifdef Q_WS_MAC
+ int previousPressedIndex;
+#endif
// shared by tabwidget and qtabbar
static void initStyleBaseOption(QStyleOptionTabBarBaseV2 *optTabBase, QTabBar *tabbar, QSize size)
{
diff --git a/src/gui/widgets/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp
index 9aeb033f61..d22bd54e87 100644
--- a/src/gui/widgets/qtabwidget.cpp
+++ b/src/gui/widgets/qtabwidget.cpp
@@ -313,7 +313,16 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
: QTabBar::TriangularEast;
break;
}
+
option->tabBarSize = t;
+
+ if (QStyleOptionTabWidgetFrameV2 *tabframe = qstyleoption_cast<QStyleOptionTabWidgetFrameV2*>(option)) {
+ QRect tbRect = tabBar()->geometry();
+ QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex());
+ tabframe->tabBarRect = tbRect;
+ selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft());
+ tabframe->selectedTabRect = selectedTabRect;
+ }
}
/*!
@@ -756,7 +765,7 @@ void QTabWidget::setUpLayout(bool onlyCheck)
if (onlyCheck && !d->dirty)
return; // nothing to do
- QStyleOptionTabWidgetFrame option;
+ QStyleOptionTabWidgetFrameV2 option;
initStyleOption(&option);
// this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
@@ -1167,8 +1176,8 @@ void QTabWidget::tabRemoved(int index)
void QTabWidget::paintEvent(QPaintEvent *)
{
Q_D(QTabWidget);
- QStylePainter p(this);
if (documentMode()) {
+ QStylePainter p(this, tabBar());
if (QWidget *w = cornerWidget(Qt::TopLeftCorner)) {
QStyleOptionTabBarBaseV2 opt;
QTabBarPrivate::initStyleBaseOption(&opt, tabBar(), w->size());
@@ -1185,8 +1194,9 @@ void QTabWidget::paintEvent(QPaintEvent *)
}
return;
}
+ QStylePainter p(this);
- QStyleOptionTabWidgetFrame opt;
+ QStyleOptionTabWidgetFrameV2 opt;
initStyleOption(&opt);
opt.rect = d->panelRect;
p.drawPrimitive(QStyle::PE_FrameTabWidget, opt);
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index b894aa8292..1c49ef0491 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -116,9 +116,6 @@ QTextEditPrivate::QTextEditPrivate()
preferRichText = false;
showCursorOnInitialShow = true;
inDrag = false;
-#ifdef Q_WS_WIN
- setSingleFingerPanEnabled(true);
-#endif
}
void QTextEditPrivate::createAutoBulletList()
@@ -186,6 +183,9 @@ void QTextEditPrivate::init(const QString &html)
#ifndef QT_NO_CURSOR
viewport->setCursor(Qt::IBeamCursor);
#endif
+#ifdef Q_WS_WIN
+ setSingleFingerPanEnabled(true);
+#endif
}
void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
@@ -530,7 +530,9 @@ void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
when the property is set.
If the text edit has another content type, it will not be replaced
- by plain text if you call toPlainText().
+ by plain text if you call toPlainText(). The only exception to this
+ is the non-break space, \e{nbsp;}, that will be converted into
+ standard space.
By default, for an editor with no contents, this property contains
an empty string.
@@ -1210,7 +1212,9 @@ void QTextEdit::keyPressEvent(QKeyEvent *e)
if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) {
if (e->text()[0].isPrint()) {
setEditFocus(true);
+#ifndef Q_OS_SYMBIAN
clear();
+#endif
} else {
e->ignore();
return;
@@ -1246,7 +1250,6 @@ void QTextEdit::keyPressEvent(QKeyEvent *e)
return;
}
}
-#endif // QT_NO_SHORTCUT
if (!(tif & Qt::TextEditable)) {
switch (e->key()) {
@@ -1274,6 +1277,7 @@ void QTextEdit::keyPressEvent(QKeyEvent *e)
}
return;
}
+#endif // QT_NO_SHORTCUT
{
QTextCursor cursor = d->control->textCursor();
@@ -1574,7 +1578,8 @@ void QTextEdit::mouseReleaseEvent(QMouseEvent *e)
d->autoScrollTimer.stop();
ensureCursorVisible();
}
- d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
+ if (!isReadOnly())
+ d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
d->clickCausedFocus = 0;
}
@@ -1672,7 +1677,9 @@ void QTextEdit::inputMethodEvent(QInputMethodEvent *e)
&& QApplication::keypadNavigationEnabled()
&& !hasEditFocus()) {
setEditFocus(true);
+#ifndef Q_OS_SYMBIAN
selectAll(); // so text is replaced rather than appended to
+#endif
}
#endif
d->sendControlEvent(e);
@@ -1899,7 +1906,7 @@ void QTextEdit::setOverwriteMode(bool overwrite)
\brief the tab stop width in pixels
\since 4.1
- By default, this property contains a value of 80.
+ By default, this property contains a value of 80 pixels.
*/
int QTextEdit::tabStopWidth() const
@@ -2079,8 +2086,8 @@ void QTextEdit::setReadOnly(bool ro)
} else {
flags = Qt::TextEditorInteraction;
}
- setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
d->control->setTextInteractionFlags(flags);
+ setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
}
/*!
diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp
index 40c0b02fd5..58a3d280c1 100644
--- a/src/gui/widgets/qtoolbar.cpp
+++ b/src/gui/widgets/qtoolbar.cpp
@@ -183,6 +183,9 @@ void QToolBarPrivate::setWindowState(bool floating, bool unplug, const QRect &re
if (visible)
q->show();
+
+ if (floating != wasFloating)
+ emit q->topLevelChanged(floating);
}
void QToolBarPrivate::initDrag(const QPoint &pos)
@@ -393,7 +396,7 @@ bool QToolBarPrivate::mouseMoveEvent(QMouseEvent *event)
void QToolBarPrivate::unplug(const QRect &_r)
{
Q_Q(QToolBar);
- layout->setExpanded(false, false);
+ layout->setExpanded(false);
QRect r = _r;
r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
setWindowState(true, true, r);
@@ -518,6 +521,19 @@ void QToolBarPrivate::plug(const QRect &r)
*/
/*!
+ \since 4.6
+
+ \fn void QToolBar::topLevelChanged(bool topLevel)
+
+ This signal is emitted when the \l floating property changes.
+ The \a topLevel parameter is true if the toolbar is now floating;
+ otherwise it is false.
+
+ \sa isWindow()
+*/
+
+
+/*!
Constructs a QToolBar with the given \a parent.
*/
QToolBar::QToolBar(QWidget *parent)
diff --git a/src/gui/widgets/qtoolbar.h b/src/gui/widgets/qtoolbar.h
index a084673093..a1a24f0d3e 100644
--- a/src/gui/widgets/qtoolbar.h
+++ b/src/gui/widgets/qtoolbar.h
@@ -142,6 +142,7 @@ Q_SIGNALS:
void orientationChanged(Qt::Orientation orientation);
void iconSizeChanged(const QSize &iconSize);
void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle);
+ void topLevelChanged(bool topLevel);
protected:
void actionEvent(QActionEvent *event);
diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp
index de11625dd5..b7e985cf3d 100644
--- a/src/gui/widgets/qtoolbararealayout.cpp
+++ b/src/gui/widgets/qtoolbararealayout.cpp
@@ -480,7 +480,7 @@ void QToolBarAreaLayoutInfo::moveToolBar(QToolBar *toolbar, int pos)
}
-QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos) const
+QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos, int *minDistance) const
{
int p = pick(o, pos);
@@ -509,12 +509,19 @@ QList<int> QToolBarAreaLayoutInfo::gapIndex(const QPoint &pos) const
QList<int> result;
result << j << k;
+ *minDistance = 0; //we found a perfect match
+ return result;
+ }
+ } else {
+ const int dist = distance(pos);
+ //it will only return a path if the minDistance is higher than the current distance
+ if (dist >= 0 && *minDistance > dist) {
+ *minDistance = dist;
+
+ QList<int> result;
+ result << lines.count() << 0;
return result;
}
- } else if (appendLineDropRect().contains(pos)) {
- QList<int> result;
- result << lines.count() << 0;
- return result;
}
return QList<int>();
@@ -587,32 +594,20 @@ QRect QToolBarAreaLayoutInfo::itemRect(const QList<int> &path) const
return result;
}
-QRect QToolBarAreaLayoutInfo::appendLineDropRect() const
+int QToolBarAreaLayoutInfo::distance(const QPoint &pos) const
{
- QRect result;
-
switch (dockPos) {
case QInternal::LeftDock:
- result = QRect(rect.right(), rect.top(),
- EmptyDockAreaSize, rect.height());
- break;
+ return pos.x() - rect.right();
case QInternal::RightDock:
- result = QRect(rect.left() - EmptyDockAreaSize, rect.top(),
- EmptyDockAreaSize, rect.height());
- break;
+ return rect.left() - pos.x();
case QInternal::TopDock:
- result = QRect(rect.left(), rect.bottom() + 1,
- rect.width(), EmptyDockAreaSize);
- break;
+ return pos.y() - rect.bottom();
case QInternal::BottomDock:
- result = QRect(rect.left(), rect.top() - EmptyDockAreaSize,
- rect.width(), EmptyDockAreaSize);
- break;
+ return rect.top() - pos.y();
default:
- break;
+ return -1;
}
-
- return result;
}
/******************************************************************************
@@ -1022,21 +1017,24 @@ QList<int> QToolBarAreaLayout::indexOf(QWidget *toolBar) const
return result;
}
+//this functions returns the path to the possible gapindex for the position pos
QList<int> QToolBarAreaLayout::gapIndex(const QPoint &pos) const
{
Qt::LayoutDirection dir = mainWindow->layoutDirection();
+ int minDistance = 80; // when a dock area is empty, how "wide" is it?
+ QList<int> ret; //return value
for (int i = 0; i < QInternal::DockCount; ++i) {
QPoint p = pos;
if (docks[i].o == Qt::Horizontal)
p = QStyle::visualPos(dir, docks[i].rect, p);
- QList<int> result = docks[i].gapIndex(p);
+ QList<int> result = docks[i].gapIndex(p, &minDistance);
if (!result.isEmpty()) {
result.prepend(i);
- return result;
+ ret = result;
}
}
- return QList<int>();
+ return ret;
}
QList<int> QToolBarAreaLayout::currentGapIndex() const
diff --git a/src/gui/widgets/qtoolbararealayout_p.h b/src/gui/widgets/qtoolbararealayout_p.h
index 1e113b7c74..f0ab80c350 100644
--- a/src/gui/widgets/qtoolbararealayout_p.h
+++ b/src/gui/widgets/qtoolbararealayout_p.h
@@ -155,8 +155,6 @@ public:
class QToolBarAreaLayoutInfo
{
public:
- enum { EmptyDockAreaSize = 80 }; // when a dock area is empty, how "wide" is it?
-
QToolBarAreaLayoutInfo(QInternal::DockPosition pos = QInternal::TopDock);
QList<QToolBarAreaLayoutLine> lines;
@@ -173,11 +171,11 @@ public:
void removeToolBarBreak(QToolBar *before);
void moveToolBar(QToolBar *toolbar, int pos);
- QList<int> gapIndex(const QPoint &pos) const;
+ QList<int> gapIndex(const QPoint &pos, int *maxDistance) const;
bool insertGap(const QList<int> &path, QLayoutItem *item);
void clear();
QRect itemRect(const QList<int> &path) const;
- QRect appendLineDropRect() const;
+ int distance(const QPoint &pos) const;
QRect rect;
Qt::Orientation o;
diff --git a/src/gui/widgets/qtoolbarlayout.cpp b/src/gui/widgets/qtoolbarlayout.cpp
index 7dc1e01949..0afe5d8e56 100644
--- a/src/gui/widgets/qtoolbarlayout.cpp
+++ b/src/gui/widgets/qtoolbarlayout.cpp
@@ -642,7 +642,7 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const
return result;
}
-void QToolBarLayout::setExpanded(bool exp, bool animated)
+void QToolBarLayout::setExpanded(bool exp)
{
if (exp == expanded)
return;
@@ -654,7 +654,6 @@ void QToolBarLayout::setExpanded(bool exp, bool animated)
if (!tb)
return;
if (QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget())) {
- animating = true;
QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout());
if (expanded) {
tb->raise();
@@ -665,7 +664,7 @@ void QToolBarLayout::setExpanded(bool exp, bool animated)
layoutActions(rect.size());
}
}
- layout->layoutState.toolBarAreaLayout.apply(animated);
+ layout->layoutState.toolBarAreaLayout.apply(win->isAnimated());
}
}
diff --git a/src/gui/widgets/qtoolbarlayout_p.h b/src/gui/widgets/qtoolbarlayout_p.h
index d49a5dfffc..afd0227194 100644
--- a/src/gui/widgets/qtoolbarlayout_p.h
+++ b/src/gui/widgets/qtoolbarlayout_p.h
@@ -112,7 +112,7 @@ public:
bool hasExpandFlag() const;
public Q_SLOTS:
- void setExpanded(bool b, bool animated = true);
+ void setExpanded(bool b);
private:
QList<QToolBarItem*> items;
diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp
index f440961954..13ee346445 100644
--- a/src/gui/widgets/qwidgetanimator.cpp
+++ b/src/gui/widgets/qwidgetanimator.cpp
@@ -88,8 +88,6 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo
const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry :
QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
- if (r == final_geometry)
- return; //the widget is already where it should be
#ifndef QT_NO_ANIMATION
AnimationMap::const_iterator it = m_animation_map.constFind(widget);
if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
@@ -105,7 +103,9 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo
#else
//we do it in one shot
widget->setGeometry(final_geometry);
+#ifndef QT_NO_MAINWINDOW
m_mainWindowLayout->animationFinished(widget);
+#endif //QT_NO_MAINWINDOW
#endif //QT_NO_ANIMATION
}
@@ -114,9 +114,4 @@ bool QWidgetAnimator::animating() const
return !m_animation_map.isEmpty();
}
-bool QWidgetAnimator::animating(QWidget *widget) const
-{
- return m_animation_map.contains(widget);
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h
index 68d93441ea..095380feb1 100644
--- a/src/gui/widgets/qwidgetanimator_p.h
+++ b/src/gui/widgets/qwidgetanimator_p.h
@@ -70,7 +70,6 @@ public:
QWidgetAnimator(QMainWindowLayout *layout);
void animate(QWidget *widget, const QRect &final_geometry, bool animate);
bool animating() const;
- bool animating(QWidget *widget) const;
void abort(QWidget *widget);