summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/itemviews/qitemselectionmodel.cpp2
-rw-r--r--src/gui/itemviews/qlistwidget.cpp31
-rw-r--r--src/gui/itemviews/qlistwidget_p.h3
-rw-r--r--src/gui/kernel/qguiplatformplugin.cpp2
-rw-r--r--src/gui/widgets/qmenu.cpp4
-rw-r--r--src/gui/widgets/qmenubar.cpp29
-rw-r--r--src/sql/models/qsqlquerymodel.cpp2
-rw-r--r--tests/auto/qlistview/tst_qlistview.cpp6
-rw-r--r--tests/auto/qlistwidget/tst_qlistwidget.cpp59
-rw-r--r--tests/auto/qmenubar/tst_qmenubar.cpp29
-rw-r--r--tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp13
-rw-r--r--tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp18
12 files changed, 150 insertions, 48 deletions
diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp
index dfebe03..f2ccb6e 100644
--- a/src/gui/itemviews/qitemselectionmodel.cpp
+++ b/src/gui/itemviews/qitemselectionmodel.cpp
@@ -599,7 +599,7 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare
while (itParent.isValid() && itParent.parent() != parent)
itParent = itParent.parent();
- if (parent.isValid() && start <= itParent.row() && itParent.row() <= end) {
+ if (itParent.isValid() && start <= itParent.row() && itParent.row() <= end) {
deselected.append(*it);
it = ranges.erase(it);
} else {
diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp
index a978d0f..5dd1d76 100644
--- a/src/gui/itemviews/qlistwidget.cpp
+++ b/src/gui/itemviews/qlistwidget.cpp
@@ -169,6 +169,20 @@ QListWidgetItem *QListModel::take(int row)
return item;
}
+void QListModel::move(int srcRow, int dstRow)
+{
+ if (srcRow == dstRow
+ || srcRow < 0 || srcRow >= items.count()
+ || dstRow < 0 || dstRow >= items.count())
+ return;
+
+ beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow);
+ if (srcRow < dstRow)
+ --dstRow;
+ items.move(srcRow, dstRow);
+ endMoveRows();
+}
+
int QListModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : items.count();
@@ -1804,22 +1818,15 @@ void QListWidget::dropEvent(QDropEvent *event) {
if (persIndexes.contains(topIndex))
return;
+ qSort(persIndexes); // The dropped items will remain in the same visual order.
QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
- QList<QListWidgetItem *> taken;
- for (int i = 0; i < persIndexes.count(); ++i)
- taken.append(takeItem(persIndexes.at(i).row()));
-
- // insert them back in at their new positions
+ int r = row == -1 ? count() : (dropRow.row() >= 0 ? dropRow.row() : row);
for (int i = 0; i < persIndexes.count(); ++i) {
- // Either at a specific point or appended
- if (row == -1) {
- insertItem(count(), taken.takeFirst());
- } else {
- int r = dropRow.row() >= 0 ? dropRow.row() : row;
- insertItem(qMin(r, count()), taken.takeFirst());
- }
+ const QPersistentModelIndex &pIndex = persIndexes.at(i);
+ d->listModel()->move(pIndex.row(), r);
+ r = pIndex.row() + 1; // Dropped items are inserted contiguously and in the right order.
}
event->accept();
diff --git a/src/gui/itemviews/qlistwidget_p.h b/src/gui/itemviews/qlistwidget_p.h
index 69cfa26..b5f28e3 100644
--- a/src/gui/itemviews/qlistwidget_p.h
+++ b/src/gui/itemviews/qlistwidget_p.h
@@ -77,7 +77,7 @@ public:
{ return *i2 < *i1; }
};
-class QListModel : public QAbstractListModel
+class Q_AUTOTEST_EXPORT QListModel : public QAbstractListModel
{
Q_OBJECT
public:
@@ -90,6 +90,7 @@ public:
void insert(int row, const QStringList &items);
void remove(QListWidgetItem *item);
QListWidgetItem *take(int row);
+ void move(int srcRow, int dstRow);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp
index 6e074a1..b01d40f 100644
--- a/src/gui/kernel/qguiplatformplugin.cpp
+++ b/src/gui/kernel/qguiplatformplugin.cpp
@@ -288,6 +288,8 @@ int QGuiPlatformPlugin::platformHint(PlatformHint hint)
#endif
//by default keep ret = 0 so QCommonStyle will use the style default
break;
+ default:
+ break;
}
return ret;
}
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index ea25901..1b5d1cd 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -1878,6 +1878,10 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
if(snapToMouse) //position flowing left from the mouse
pos.setX(mouse.x()-size.width());
+ //if in a menubar, it should be right-aligned
+ if (qobject_cast<QMenuBar*>(d->causedPopup.widget))
+ pos.rx() -= size.width();
+
if (pos.x() < screen.left()+desktopFrame)
pos.setX(qMax(p.x(), screen.left()+desktopFrame));
if (pos.x()+size.width()-1 > screen.right()-desktopFrame)
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index f2f0722..689d2e1 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -336,30 +336,25 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
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))
diff --git a/src/sql/models/qsqlquerymodel.cpp b/src/sql/models/qsqlquerymodel.cpp
index a72ad8c..1719239 100644
--- a/src/sql/models/qsqlquerymodel.cpp
+++ b/src/sql/models/qsqlquerymodel.cpp
@@ -417,7 +417,7 @@ bool QSqlQueryModel::setHeaderData(int section, Qt::Orientation orientation,
const QVariant &value, int role)
{
Q_D(QSqlQueryModel);
- if (orientation != Qt::Horizontal || section < 0)
+ if (orientation != Qt::Horizontal || section < 0 || columnCount() <= section)
return false;
if (d->headers.size() <= section)
diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp
index 3968529..65ab12d 100644
--- a/tests/auto/qlistview/tst_qlistview.cpp
+++ b/tests/auto/qlistview/tst_qlistview.cpp
@@ -1785,12 +1785,12 @@ void tst_QListView::task262152_setModelColumnNavigate()
view.show();
QTest::qWaitForWindowShown(&view);
- QTest::qWait(10);
+ QTest::qWait(100);
QTest::keyClick(&view, Qt::Key_Down);
- QTest::qWait(10);
+ QTest::qWait(100);
QCOMPARE(view.currentIndex(), model.index(1,1));
QTest::keyClick(&view, Qt::Key_Down);
- QTest::qWait(10);
+ QTest::qWait(100);
QCOMPARE(view.currentIndex(), model.index(2,1));
}
diff --git a/tests/auto/qlistwidget/tst_qlistwidget.cpp b/tests/auto/qlistwidget/tst_qlistwidget.cpp
index e825c8f..5c6ed54 100644
--- a/tests/auto/qlistwidget/tst_qlistwidget.cpp
+++ b/tests/auto/qlistwidget/tst_qlistwidget.cpp
@@ -46,6 +46,7 @@
#include <qlist.h>
#include <qlistwidget.h>
+#include <private/qlistwidget_p.h>
//TESTED_CLASS=
//TESTED_FILES=
@@ -95,6 +96,8 @@ private slots:
void insertItem();
void insertItems_data();
void insertItems();
+ void moveItemsPriv_data();
+ void moveItemsPriv();
void itemAssignment();
void item_data();
@@ -849,6 +852,62 @@ void tst_QListWidget::removeItems()
}
+void tst_QListWidget::moveItemsPriv_data()
+{
+ QTest::addColumn<int>("rowCount");
+ QTest::addColumn<int>("srcRow");
+ QTest::addColumn<int>("dstRow");
+ QTest::addColumn<bool>("shouldHaveSignaled");
+
+ QTest::newRow("Empty") << 0 << 0 << 0 << false;
+ QTest::newRow("Overflow src") << 5 << 5 << 2 << false;
+ QTest::newRow("Underflow src") << 5 << -1 << 2 << false;
+ QTest::newRow("Overflow dst") << 5 << 2 << 5 << false;
+ QTest::newRow("Underflow dst") << 5 << 2 << -1 << false;
+ QTest::newRow("Same place") << 5 << 2 << 2 << false;
+ QTest::newRow("Up") << 5 << 4 << 2 << true;
+ QTest::newRow("Down") << 5 << 2 << 4 << true;
+}
+
+void tst_QListWidget::moveItemsPriv()
+{
+ QFETCH(int, rowCount);
+ QFETCH(int, srcRow);
+ QFETCH(int, dstRow);
+ QFETCH(bool, shouldHaveSignaled);
+
+ for (int r = 0; r < rowCount; ++r)
+ new QListWidgetItem(QString::number(r), testWidget);
+
+ QListModel *model = dynamic_cast<QListModel *>(testWidget->model());
+ QVERIFY(model);
+ QSignalSpy beginMoveSpy(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
+ QSignalSpy movedSpy(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
+ model->move(srcRow, dstRow);
+
+ if (shouldHaveSignaled) {
+ if (srcRow < dstRow)
+ QCOMPARE(testWidget->item(dstRow - 1)->text(), QString::number(srcRow));
+ else
+ QCOMPARE(testWidget->item(dstRow)->text(), QString::number(srcRow));
+
+ QCOMPARE(beginMoveSpy.count(), 1);
+ const QList<QVariant> &beginMoveArgs = beginMoveSpy.takeFirst();
+ QCOMPARE(beginMoveArgs.at(1).toInt(), srcRow);
+ QCOMPARE(beginMoveArgs.at(2).toInt(), srcRow);
+ QCOMPARE(beginMoveArgs.at(4).toInt(), dstRow);
+
+ QCOMPARE(movedSpy.count(), 1);
+ const QList<QVariant> &movedArgs = movedSpy.takeFirst();
+ QCOMPARE(movedArgs.at(1).toInt(), srcRow);
+ QCOMPARE(movedArgs.at(2).toInt(), srcRow);
+ QCOMPARE(movedArgs.at(4).toInt(), dstRow);
+ } else {
+ QCOMPARE(beginMoveSpy.count(), 0);
+ QCOMPARE(movedSpy.count(), 0);
+ }
+}
+
void tst_QListWidget::itemStreaming_data()
{
QTest::addColumn<QString>("text");
diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp
index 07aa9f4..4291c3e 100644
--- a/tests/auto/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/qmenubar/tst_qmenubar.cpp
@@ -86,6 +86,18 @@ private:
uint sel_count;
};
+class Menu : public QMenu
+{
+ Q_OBJECT
+ public slots:
+ void addActions()
+ {
+ //this will change the geometry of the menu
+ addAction("action1");
+ addAction("action2");
+ }
+};
+
class tst_QMenuBar : public QObject
{
Q_OBJECT
@@ -1442,7 +1454,7 @@ void tst_QMenuBar::check_menuPosition()
#ifdef Q_OS_WINCE_WM
QSKIP("Qt/CE uses native menubar", SkipAll);
#endif
- QMenu menu;
+ Menu menu;
#ifdef QT3_SUPPORT
initComplexMenubar();
#else
@@ -1496,6 +1508,21 @@ void tst_QMenuBar::check_menuPosition()
menu.close();
}
+ //in RTL, the menu should be stuck at the right of the action geometry
+ {
+ Qt::LayoutDirection dir = qApp->layoutDirection();
+ qApp->setLayoutDirection(Qt::RightToLeft);
+ menu.clear();
+ QObject::connect(&menu, SIGNAL(aboutToShow()), &menu, SLOT(addActions()));
+ QRect mbItemRect = mw->menuBar()->actionGeometry(menu_action);
+ mbItemRect.moveTo(mw->menuBar()->mapToGlobal(mbItemRect.topLeft()));
+ QTest::keyClick(mw, Qt::Key_M, Qt::AltModifier );
+ QVERIFY(menu.isActiveWindow());
+ QCOMPARE(menu.geometry().right(), mbItemRect.right());
+ menu.close();
+ qApp->setLayoutDirection(dir);
+ }
+
}
void tst_QMenuBar::task223138_triggered()
diff --git a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp
index aa6801a..f6afc5b 100644
--- a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp
+++ b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp
@@ -929,16 +929,13 @@ void tst_QSequentialAnimationGroup::startDelay()
group.addPause(125);
QCOMPARE(group.totalDuration(), 375);
- QEventLoop loop;
- QObject::connect(&group, SIGNAL(finished()), &loop, SLOT(quit()));
-
- QTime time;
- time.start();
group.start();
- loop.exec();
+ QCOMPARE(group.state(), QAnimationGroup::Running);
- QVERIFY(time.elapsed() >= 375);
- QVERIFY(time.elapsed() < 1000);
+ QTest::qWait(500);
+
+ QVERIFY(group.currentTime() == 375);
+ QCOMPARE(group.state(), QAnimationGroup::Stopped);
}
void tst_QSequentialAnimationGroup::clearGroup()
diff --git a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp
index 3131f35..02b48fa 100644
--- a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp
+++ b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp
@@ -96,6 +96,7 @@ private slots:
void task_180617();
void task_180617_data() { generic_data(); }
+ void task_QTBUG_4963_setHeaderDataWithProxyModel();
private:
void generic_data(const QString &engine=QString());
@@ -428,6 +429,8 @@ void tst_QSqlQueryModel::setHeaderData()
QVERIFY(!model.setHeaderData(5, Qt::Vertical, "foo"));
QVERIFY(model.headerData(5, Qt::Vertical).isValid());
+ model.setQuery(QSqlQuery("select * from " + qTableName("test"), db));
+
qRegisterMetaType<Qt::Orientation>("Qt::Orientation");
QSignalSpy spy(&model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)));
QVERIFY(model.setHeaderData(2, Qt::Horizontal, "bar"));
@@ -437,10 +440,8 @@ void tst_QSqlQueryModel::setHeaderData()
QCOMPARE(spy.value(0).value(1).toInt(), 2);
QCOMPARE(spy.value(0).value(2).toInt(), 2);
- QVERIFY(model.setHeaderData(7, Qt::Horizontal, "foo", Qt::ToolTipRole));
- QVERIFY(model.headerData(7, Qt::Horizontal, Qt::ToolTipRole).isValid());
-
- model.setQuery(QSqlQuery("select * from " + qTableName("test"), db));
+ QVERIFY(!model.setHeaderData(7, Qt::Horizontal, "foo", Qt::ToolTipRole));
+ QVERIFY(!model.headerData(7, Qt::Horizontal, Qt::ToolTipRole).isValid());
bool isToUpper = db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2");
QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), isToUpper ? QString("ID") : QString("id"));
@@ -603,5 +604,14 @@ void tst_QSqlQueryModel::task_180617()
QCOMPARE(view.rowAt(0), -1);
}
+void tst_QSqlQueryModel::task_QTBUG_4963_setHeaderDataWithProxyModel()
+{
+ QSqlQueryModel plainModel;
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&plainModel);
+ QVERIFY(!plainModel.setHeaderData(0, Qt::Horizontal, QObject::tr("ID")));
+ // And it should not crash.
+}
+
QTEST_MAIN(tst_QSqlQueryModel)
#include "tst_qsqlquerymodel.moc"