From 756a169e2530987f1b875589d196877e93704858 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 19 Jul 2016 13:17:29 +0200 Subject: texteditor example: check if document is null before using it This hasn't been an issue so far probably because those properties were accessed after m_doc had been set. However, adding some debug text can trigger a crash: Text { text: "document.cursorPosition=" + document.cursorPosition } Change-Id: Ib468815cdc0b103a2384457ab937cc3b764b96c8 Reviewed-by: Friedemann Kleint --- examples/quickcontrols/controls/texteditor/src/documenthandler.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/quickcontrols/controls/texteditor/src/documenthandler.cpp b/examples/quickcontrols/controls/texteditor/src/documenthandler.cpp index 2e03f747..b07099e2 100644 --- a/examples/quickcontrols/controls/texteditor/src/documenthandler.cpp +++ b/examples/quickcontrols/controls/texteditor/src/documenthandler.cpp @@ -169,6 +169,9 @@ void DocumentHandler::reset() QTextCursor DocumentHandler::textCursor() const { + if (!m_doc) + return QTextCursor(); + QTextCursor cursor = QTextCursor(m_doc); if (m_selectionStart != m_selectionEnd) { cursor.setPosition(m_selectionStart); @@ -199,6 +202,9 @@ void DocumentHandler::setSelectionEnd(int position) void DocumentHandler::setAlignment(Qt::Alignment a) { + if (!m_doc) + return; + QTextBlockFormat fmt; fmt.setAlignment((Qt::Alignment) a); QTextCursor cursor = QTextCursor(m_doc); -- cgit v1.2.1 From 56d711667f4601016b474b3d463ce07659c42b9a Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Tue, 26 Jul 2016 15:34:48 +0100 Subject: Don't activate transient parent if it was closed meanwhile Closing a window while a popup is open should not trigger an activation event when the popup is closed. Prevents QGuiApplicationPrivate::focus_window from being changed to a stale window, which happens inside QGuiApplicationPrivate::processActivatedEvent(). Change-Id: I3145b3d191abb20d56fa9acbec8a0776a6bf8526 Reviewed-by: Laszlo Agocs Reviewed-by: Gabriel de Dietrich --- src/controls/qquickpopupwindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/controls/qquickpopupwindow.cpp b/src/controls/qquickpopupwindow.cpp index 88d91137..ac961709 100644 --- a/src/controls/qquickpopupwindow.cpp +++ b/src/controls/qquickpopupwindow.cpp @@ -224,7 +224,8 @@ void QQuickPopupWindow::hideEvent(QHideEvent *e) { if (QWindow *tp = !m_needsActivatedEvent ? transientParent() : 0) { m_needsActivatedEvent = true; - QWindowSystemInterface::handleWindowActivated(tp); + if (tp->isVisible()) + QWindowSystemInterface::handleWindowActivated(tp); } QQuickWindow::hideEvent(e); -- cgit v1.2.1 From c0f58d5283ce981b8cfbc43f602a3b6553e26ce2 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 12 Aug 2016 11:12:22 +0200 Subject: Doc: Change instances of 'OS X' to 'macOS' As of version 10.12 (Sierra), the name of Apple's desktop operating system will be macOS. Change all occurrences where the platform is discussed to use the macro \macos (defined in the documentation configuration in qtbase). Change-Id: I5ca47e4d830c12df297ee298ed22fd2d41dee739 Reviewed-by: Leena Miettinen --- src/controls/Private/qquickstyleitem.cpp | 2 +- src/controls/doc/src/qtquickcontrols-examples.qdoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controls/Private/qquickstyleitem.cpp b/src/controls/Private/qquickstyleitem.cpp index d7d2d4c3..7b0446db 100644 --- a/src/controls/Private/qquickstyleitem.cpp +++ b/src/controls/Private/qquickstyleitem.cpp @@ -67,7 +67,7 @@ static inline HIRect qt_hirectForQRect(const QRect &convertRect, const QRect &re returned if it can't be obtained. It is the caller's responsibility to CGContextRelease the context when finished using it. - \warning This function is only available on Mac OS X. + \warning This function is only available on \macos. \warning This function is duplicated in qmacstyle_mac.mm */ CGContextRef qt_mac_cg_context(const QPaintDevice *pdev) diff --git a/src/controls/doc/src/qtquickcontrols-examples.qdoc b/src/controls/doc/src/qtquickcontrols-examples.qdoc index 7ad34a30..0e0e1ee2 100644 --- a/src/controls/doc/src/qtquickcontrols-examples.qdoc +++ b/src/controls/doc/src/qtquickcontrols-examples.qdoc @@ -46,7 +46,7 @@ \endraw \image qtquickcontrols-example-gallery-osx.png - \caption OS X + \caption \macos \raw HTML \endraw -- cgit v1.2.1 From efdd81ce80b018b7b5779876e94f1b722af7fb9a Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sat, 13 Aug 2016 16:58:44 +0200 Subject: Fix ColorDialog.color and FontDialog.font update on accept When using native dialogs, ColorDialog.color was not updated at all, and FontDialog.font was incorrectly following FontDialog.currentFont. Promote the overridden accept() methods to the abstract base classes so the native dialogs get the appropriate property updates on accept the same way compared to the non-native dialogs. Task-number: QTBUG-55298 Change-Id: I9ac8f5ecc60884cd98b58d09ef3dcb4baf47772d Reviewed-by: Mitch Curtis --- src/dialogs/qquickabstractcolordialog.cpp | 6 ++++++ src/dialogs/qquickabstractcolordialog_p.h | 3 +++ src/dialogs/qquickabstractfontdialog.cpp | 6 ++++++ src/dialogs/qquickabstractfontdialog_p.h | 3 +++ src/dialogs/qquickcolordialog.cpp | 6 ------ src/dialogs/qquickcolordialog_p.h | 3 --- src/dialogs/qquickfontdialog.cpp | 6 ------ src/dialogs/qquickfontdialog_p.h | 3 --- src/dialogs/qquickplatformfontdialog.cpp | 2 +- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/dialogs/qquickabstractcolordialog.cpp b/src/dialogs/qquickabstractcolordialog.cpp index 2101fe0e..44c203df 100644 --- a/src/dialogs/qquickabstractcolordialog.cpp +++ b/src/dialogs/qquickabstractcolordialog.cpp @@ -124,4 +124,10 @@ void QQuickAbstractColorDialog::setShowAlphaChannel(bool arg) emit showAlphaChannelChanged(); } +void QQuickAbstractColorDialog::accept() +{ + setColor(m_currentColor); + QQuickAbstractDialog::accept(); +} + QT_END_NAMESPACE diff --git a/src/dialogs/qquickabstractcolordialog_p.h b/src/dialogs/qquickabstractcolordialog_p.h index 99be766c..16b39c26 100644 --- a/src/dialogs/qquickabstractcolordialog_p.h +++ b/src/dialogs/qquickabstractcolordialog_p.h @@ -96,6 +96,9 @@ Q_SIGNALS: void currentColorChanged(); void selectionAccepted(); +protected Q_SLOTS: + virtual void accept(); + protected: QPlatformColorDialogHelper *m_dlgHelper; QSharedPointer m_options; diff --git a/src/dialogs/qquickabstractfontdialog.cpp b/src/dialogs/qquickabstractfontdialog.cpp index fb715c35..0886449b 100644 --- a/src/dialogs/qquickabstractfontdialog.cpp +++ b/src/dialogs/qquickabstractfontdialog.cpp @@ -154,4 +154,10 @@ void QQuickAbstractFontDialog::setProportionalFonts(bool arg) emit proportionalFontsChanged(); } +void QQuickAbstractFontDialog::accept() +{ + setFont(m_currentFont); + QQuickAbstractDialog::accept(); +} + QT_END_NAMESPACE diff --git a/src/dialogs/qquickabstractfontdialog_p.h b/src/dialogs/qquickabstractfontdialog_p.h index 3162be2a..f60c4ddb 100644 --- a/src/dialogs/qquickabstractfontdialog_p.h +++ b/src/dialogs/qquickabstractfontdialog_p.h @@ -101,6 +101,9 @@ Q_SIGNALS: void currentFontChanged(); void selectionAccepted(); +protected Q_SLOTS: + virtual void accept(); + protected: QPlatformFontDialogHelper *m_dlgHelper; QSharedPointer m_options; diff --git a/src/dialogs/qquickcolordialog.cpp b/src/dialogs/qquickcolordialog.cpp index 875c6740..686bd850 100644 --- a/src/dialogs/qquickcolordialog.cpp +++ b/src/dialogs/qquickcolordialog.cpp @@ -118,10 +118,4 @@ QQuickColorDialog::~QQuickColorDialog() \l Window or an \l Item. */ -void QQuickColorDialog::accept() -{ - setColor(m_currentColor); - QQuickAbstractColorDialog::accept(); -} - QT_END_NAMESPACE diff --git a/src/dialogs/qquickcolordialog_p.h b/src/dialogs/qquickcolordialog_p.h index d3c3463b..619b7b10 100644 --- a/src/dialogs/qquickcolordialog_p.h +++ b/src/dialogs/qquickcolordialog_p.h @@ -65,9 +65,6 @@ public: explicit QQuickColorDialog(QObject *parent = 0); ~QQuickColorDialog(); -protected Q_SLOTS: - virtual void accept(); - protected: virtual QPlatformColorDialogHelper *helper() { return 0; } diff --git a/src/dialogs/qquickfontdialog.cpp b/src/dialogs/qquickfontdialog.cpp index 0e27d29a..00acf238 100644 --- a/src/dialogs/qquickfontdialog.cpp +++ b/src/dialogs/qquickfontdialog.cpp @@ -119,10 +119,4 @@ QQuickFontDialog::~QQuickFontDialog() \l Window or an \l Item. */ -void QQuickFontDialog::accept() -{ - setFont(m_currentFont); - QQuickAbstractFontDialog::accept(); -} - QT_END_NAMESPACE diff --git a/src/dialogs/qquickfontdialog_p.h b/src/dialogs/qquickfontdialog_p.h index 71301a76..bd04f536 100644 --- a/src/dialogs/qquickfontdialog_p.h +++ b/src/dialogs/qquickfontdialog_p.h @@ -65,9 +65,6 @@ public: explicit QQuickFontDialog(QObject *parent = 0); ~QQuickFontDialog(); -protected Q_SLOTS: - virtual void accept(); - protected: virtual QPlatformFontDialogHelper *helper() { return 0; } diff --git a/src/dialogs/qquickplatformfontdialog.cpp b/src/dialogs/qquickplatformfontdialog.cpp index 247e869e..2c501a1c 100644 --- a/src/dialogs/qquickplatformfontdialog.cpp +++ b/src/dialogs/qquickplatformfontdialog.cpp @@ -170,7 +170,7 @@ QPlatformFontDialogHelper *QQuickPlatformFontDialog::helper() return m_dlgHelper; connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept())); connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject())); - connect(m_dlgHelper, SIGNAL(currentFontChanged(QFont)), this, SLOT(setFont(QFont))); + connect(m_dlgHelper, SIGNAL(currentFontChanged(QFont)), this, SLOT(setCurrentFont(QFont))); connect(m_dlgHelper, SIGNAL(fontSelected(QFont)), this, SLOT(setFont(QFont))); } -- cgit v1.2.1 From 69af774a54198a83f774c89b5d5d7135b8fb1f7a Mon Sep 17 00:00:00 2001 From: Nikita Krupenko Date: Sun, 31 Jan 2016 23:38:55 +0200 Subject: Update scroll indicator position on content size change If scroll indicator is at the beginning and data prepended to contentItem, scroll indicator should change position to previous content beginning. This is especially important with so-called "infinite scrolling", when scrolling goes upwards and new content added at the top of the view. Task-number: QTBUG-50795 Change-Id: I250d6535b1146a54c6a70062b659cc49ed43709f Reviewed-by: Mitch Curtis --- src/controls/Private/ScrollViewHelper.qml | 10 +++++ tests/auto/controls/data/tst_scrollview.qml | 63 +++++++++++++++++++++++++++++ tests/auto/testplugin/testcppmodels.h | 52 ++++++++++++++++++++++++ tests/auto/testplugin/testplugin.cpp | 1 + 4 files changed, 126 insertions(+) diff --git a/src/controls/Private/ScrollViewHelper.qml b/src/controls/Private/ScrollViewHelper.qml index b4a589bf..bc3d9eb8 100644 --- a/src/controls/Private/ScrollViewHelper.qml +++ b/src/controls/Private/ScrollViewHelper.qml @@ -131,6 +131,11 @@ Item { anchors.right: cornerFill.left anchors.leftMargin: leftMargin anchors.bottomMargin: bottomMargin + onScrollAmountChanged: { + if (flickableItem && (flickableItem.atXBeginning || flickableItem.atXEnd)) { + value = flickableItem.contentX - flickableItem.originX + } + } onValueChanged: { if (!blockUpdates) { flickableItem.contentX = value + flickableItem.originX @@ -180,6 +185,11 @@ Item { anchors.top: parent.top anchors.topMargin: __scrollBarTopMargin + topMargin anchors.rightMargin: rightMargin + onScrollAmountChanged: { + if (flickableItem && (flickableItem.atYBeginning || flickableItem.atYEnd)) { + value = flickableItem.contentY - flickableItem.originY + } + } onValueChanged: { if (flickableItem && !blockUpdates && enabled) { flickableItem.contentY = value + flickableItem.originY diff --git a/tests/auto/controls/data/tst_scrollview.qml b/tests/auto/controls/data/tst_scrollview.qml index e687c9bc..cb96c3db 100644 --- a/tests/auto/controls/data/tst_scrollview.qml +++ b/tests/auto/controls/data/tst_scrollview.qml @@ -41,6 +41,7 @@ import QtQuick 2.2 import QtTest 1.0 import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.1 import QtQuickControlsTests 1.0 Item { @@ -90,6 +91,68 @@ TestCase { scrollView.destroy() } + Component { + id: dragFetchAppendComponent + + ScrollView { + width: 400; height: 400 + frameVisible: false + style: ScrollViewStyle { + transientScrollBars: false + handle: Rectangle { + implicitWidth: 16; implicitHeight: 16 + color: "red" + } + scrollBarBackground: Item {width: 16 ; height: 16} + incrementControl: Rectangle { + width: 16; height: 16 + color: "blue" + } + decrementControl: Rectangle { + width: 16; height: 16 + color: "blue" + } + } + ListView { + id: view + + verticalLayoutDirection: ListView.BottomToTop + model: TestFetchAppendModel { } + delegate: Text { + width: view.width + height: 60 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: "Item %1".arg(model.index) + } + } + } + } + + function test_dragFetchAppend() { // QTBUG-50795 + var scrollView = dragFetchAppendComponent.createObject(container) + verify(scrollView !== null, "view created is null") + waitForRendering(scrollView) + verify(scrollView.flickableItem.contentHeight === 60 * 20) + + // After scrolling to the end, view should ask the model to fetch more + // data, content height should increase and scrollbar handle should move + // to the center. + mouseDrag(scrollView, scrollView.width - 2, scrollView.height - 8 - 16, 0, -scrollView.height + 8 + 16) + waitForRendering(scrollView) + + // Move it again to fetch more data from the model. + mouseDrag(scrollView, scrollView.width - 2, scrollView.height / 2, 0, -scrollView.height / 2 + 8 + 16) + waitForRendering(scrollView) + + mouseRelease(scrollView, scrollView.width - 2, 8 + 16) + waitForRendering(scrollView) + + verify(Math.round(scrollView.flickableItem.contentHeight) > 60 * 20) + verify(Math.round(scrollView.flickableItem.contentY) < -(60 * 20)) + + scrollView.destroy() + } function test_scrollbars() { var component = scrollViewComponent diff --git a/tests/auto/testplugin/testcppmodels.h b/tests/auto/testplugin/testcppmodels.h index f5cc6298..6298bd13 100644 --- a/tests/auto/testplugin/testcppmodels.h +++ b/tests/auto/testplugin/testcppmodels.h @@ -96,6 +96,58 @@ private: QList m_testobject; }; +class TestFetchAppendModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit TestFetchAppendModel(QObject *parent = 0) + : QAbstractListModel(parent) { } + + virtual int rowCount(const QModelIndex &parent) const + { + if (parent.isValid()) { + return 0; + } + + return m_data.size(); + } + virtual QVariant data(const QModelIndex &index, int role) const + { + if (!index.isValid() || role != Qt::DisplayRole) { + return QVariant(); + } + + return QVariant::fromValue(index.row()); + } + + virtual bool canFetchMore(const QModelIndex &parent) const + { + Q_UNUSED(parent) + + return true; + } + virtual void fetchMore(const QModelIndex & parent) + { + Q_UNUSED(parent) + + addMoreData(); + } + +private: + void addMoreData() + { + static const int insertCount = 20; + + beginInsertRows(QModelIndex(), m_data.size(), m_data.size() + insertCount - 1); + for (int i = 0; i < insertCount; i++) { + m_data.append(int()); + } + endInsertRows(); + } + + QList m_data; +}; + #endif // TESTCPPMODELS_H diff --git a/tests/auto/testplugin/testplugin.cpp b/tests/auto/testplugin/testplugin.cpp index 0f23f0b4..ee6a9711 100644 --- a/tests/auto/testplugin/testplugin.cpp +++ b/tests/auto/testplugin/testplugin.cpp @@ -48,6 +48,7 @@ void TestPlugin::registerTypes(const char *uri) qmlRegisterType(uri, 1, 0, "TestObject"); qmlRegisterType(uri, 1, 0, "TestItemModel"); qmlRegisterType(uri, 1, 0, "TreeModel"); + qmlRegisterType(uri, 1, 0, "TestFetchAppendModel"); } void TestPlugin::initializeEngine(QQmlEngine *engine, const char * /*uri*/) -- cgit v1.2.1 From c0be938232f4f44e064546cbf365314c07f2c35a Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Thu, 11 Aug 2016 17:58:35 +0200 Subject: Fix typo in documentation Change-Id: Ibd33614206e8d770bd7ee0888a8806662e3a1a73 Reviewed-by: J-P Nurmi --- src/controls/doc/src/qtquickcontrols-examples.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controls/doc/src/qtquickcontrols-examples.qdoc b/src/controls/doc/src/qtquickcontrols-examples.qdoc index 0e0e1ee2..fb674bc8 100644 --- a/src/controls/doc/src/qtquickcontrols-examples.qdoc +++ b/src/controls/doc/src/qtquickcontrols-examples.qdoc @@ -171,7 +171,7 @@ import org.qtproject.example 1.0 \endcode - For more information about registering C++ classses as QML types, see + For more information about registering C++ classes as QML types, see \l {Defining QML Types from C++}. \include examples-run.qdocinc @@ -212,7 +212,7 @@ import org.qtproject.example 1.0 \endcode - For more information about registering C++ classses as QML types, see + For more information about registering C++ classes as QML types, see \l {Defining QML Types from C++}. \include examples-run.qdocinc -- cgit v1.2.1 From 5bd57528b5cf7b22a81b1195d90b0a364c0428aa Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Fri, 12 Aug 2016 12:07:51 +0200 Subject: Fix typo (word repetition) in documentation Change-Id: I6242fa1ab805d13753678feb5929da67ae0f4385 Reviewed-by: J-P Nurmi --- src/controls/doc/src/qtquickcontrols-tableview.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controls/doc/src/qtquickcontrols-tableview.qdoc b/src/controls/doc/src/qtquickcontrols-tableview.qdoc index e188ac9e..92efcff7 100644 --- a/src/controls/doc/src/qtquickcontrols-tableview.qdoc +++ b/src/controls/doc/src/qtquickcontrols-tableview.qdoc @@ -243,7 +243,7 @@ \endcode \b Example: To iterate over selected indexes, you can pass a callback function. - \a rowIndex is passed as as an argument to the callback function. + \a rowIndex is passed as an argument to the callback function. \code tableview.selection.forEach( function(rowIndex) {console.log(rowIndex)} ) \endcode -- cgit v1.2.1 From f44ef9daf9f0f9db6775fdb6d3fc8703b6ce77e4 Mon Sep 17 00:00:00 2001 From: Filipe Azevedo Date: Mon, 1 Aug 2016 19:01:03 +0200 Subject: macOS: Fix native dangling menu still visible on screen and crash If the parent window gets destroyed while a QtQuick Controls menu is open the macOS native platform menu is not dismissed and you see a blank gray rectangle without any text. Also, at this point the QQmlEngine was already destroyed but it's still present on the call stack, so you get a crash when the stack unwinds to the original right mouse click that created the context menu. Change-Id: I638b0de13734815995d2994e6dd6603bcb0ebefc Reviewed-by: Gabriel de Dietrich --- src/controls/qquickmenu.cpp | 17 +++++++++++++++++ src/controls/qquickmenu_p.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/src/controls/qquickmenu.cpp b/src/controls/qquickmenu.cpp index b725bbbf..3c243ba3 100644 --- a/src/controls/qquickmenu.cpp +++ b/src/controls/qquickmenu.cpp @@ -436,6 +436,10 @@ void QQuickMenu1::__popup(const QRectF &targetRect, int atItemIndex, MenuType me // parentWindow may not be a QQuickWindow (happens when using QQuickWidget) if (m_platformMenu) { + if (m_windowConnection) + QObject::disconnect(m_windowConnection); + m_windowConnection = connect(parentWindow, &QWindow::visibleChanged, this, + &QQuickMenu1::platformMenuWindowVisibleChanged, Qt::UniqueConnection); QRectF globalTargetRect = targetRect.translated(m_xOffset, m_yOffset); if (visualItem()) { if (qGuiApp->isRightToLeft()) { @@ -565,6 +569,19 @@ void QQuickMenu1::windowVisibleChanged(bool v) } } +void QQuickMenu1::platformMenuWindowVisibleChanged(bool visible) +{ + if (!visible) { + if (m_windowConnection) { + QObject::disconnect(m_windowConnection); + m_windowConnection = QMetaObject::Connection(); + } + if (m_platformMenu) { + m_platformMenu->dismiss(); + } + } +} + void QQuickMenu1::clearPopupWindow() { m_popupWindow = 0; diff --git a/src/controls/qquickmenu_p.h b/src/controls/qquickmenu_p.h index 576ae5fd..8510efbe 100644 --- a/src/controls/qquickmenu_p.h +++ b/src/controls/qquickmenu_p.h @@ -165,6 +165,7 @@ protected Q_SLOTS: void updateText(); void windowVisibleChanged(bool); + void platformMenuWindowVisibleChanged(bool); private: QQuickWindow *findParentWindow(); @@ -205,6 +206,7 @@ private: QFont m_font; int m_triggerCount; bool m_proxy; + QMetaObject::Connection m_windowConnection; }; QT_END_NAMESPACE -- cgit v1.2.1 From 69b3136bae16897492d27558c5909cd61a5e598e Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Wed, 6 Apr 2016 13:50:08 +0300 Subject: Fix moving of TreeView items Property binding for row property in styleData causes an update which tries to read new value for the index property, but index is changed afterwards which causes old value to be read. This may lead to crashes and other unwanted behavior. Depth changes are now delivered to update item depths in visible items and model index changes though role instead of looking for a row change. Task-number: QTBUG-47523 Change-Id: I540cd06a25281f18e4628f4b030cf969dc8e0a7f Reviewed-by: Alex Blasche --- .../Private/TreeViewItemDelegateLoader.qml | 2 +- src/controls/Private/qquicktreemodeladaptor.cpp | 51 ++++++++++++++++++++-- src/controls/Private/qquicktreemodeladaptor_p.h | 5 ++- .../tst_qquicktreemodeladaptor.cpp | 51 ++++++++++++++++++++++ tests/auto/shared/testmodel.h | 2 +- 5 files changed, 103 insertions(+), 8 deletions(-) diff --git a/src/controls/Private/TreeViewItemDelegateLoader.qml b/src/controls/Private/TreeViewItemDelegateLoader.qml index 8b8801fc..01492eda 100644 --- a/src/controls/Private/TreeViewItemDelegateLoader.qml +++ b/src/controls/Private/TreeViewItemDelegateLoader.qml @@ -78,7 +78,7 @@ TableViewItemDelegateLoader { readonly property color textColor: __rowItem ? __rowItem.itemTextColor : "black" readonly property string role: __column ? __column.role : "" readonly property var value: model && model.hasOwnProperty(role) ? model[role] : "" - readonly property var index: __treeModel.mapRowToModelIndex(row) + readonly property var index: model ? model["_q_TreeView_ModelIndex"] : __treeModel.index(-1,-1,null) readonly property int depth: model && column === 0 ? model["_q_TreeView_ItemDepth"] : 0 readonly property bool hasChildren: model ? model["_q_TreeView_HasChildren"] : false readonly property bool hasSibling: model ? model["_q_TreeView_HasSibling"] : false diff --git a/src/controls/Private/qquicktreemodeladaptor.cpp b/src/controls/Private/qquicktreemodeladaptor.cpp index 666fafc9..52b231d0 100644 --- a/src/controls/Private/qquicktreemodeladaptor.cpp +++ b/src/controls/Private/qquicktreemodeladaptor.cpp @@ -153,6 +153,7 @@ QHash QQuickTreeModelAdaptor::roleNames() const modelRoleNames.insert(ExpandedRole, "_q_TreeView_ItemExpanded"); modelRoleNames.insert(HasChildrenRole, "_q_TreeView_HasChildren"); modelRoleNames.insert(HasSiblingRole, "_q_TreeView_HasSibling"); + modelRoleNames.insert(ModelIndexRole, "_q_TreeView_ModelIndex"); return modelRoleNames; } @@ -177,6 +178,8 @@ QVariant QQuickTreeModelAdaptor::data(const QModelIndex &index, int role) const return !(modelIndex.flags() & Qt::ItemNeverHasChildren) && m_model->hasChildren(modelIndex); case HasSiblingRole: return modelIndex.row() != m_model->rowCount(modelIndex.parent()) - 1; + case ModelIndexRole: + return modelIndex; default: return m_model->data(modelIndex, role); } @@ -192,6 +195,7 @@ bool QQuickTreeModelAdaptor::setData(const QModelIndex &index, const QVariant &v case ExpandedRole: case HasChildrenRole: case HasSiblingRole: + case ModelIndexRole: return false; default: { const QModelIndex &pmi = mapToModel(index); @@ -716,8 +720,11 @@ void QQuickTreeModelAdaptor::modelRowsAboutToBeMoved(const QModelIndex & sourceP destIndex = itemIndex(m_model->index(destinationRow, 0, destinationParent)); } - beginMoveRows(QModelIndex(), startIndex, endIndex, QModelIndex(), destIndex); int totalMovedCount = endIndex - startIndex + 1; + + const bool visibleRowsMoved = startIndex != destIndex && + beginMoveRows(QModelIndex(), startIndex, endIndex, QModelIndex(), destIndex); + const QList &buffer = m_items.mid(startIndex, totalMovedCount); int bufferCopyOffset; if (destIndex > endIndex) { @@ -726,6 +733,7 @@ void QQuickTreeModelAdaptor::modelRowsAboutToBeMoved(const QModelIndex & sourceP } bufferCopyOffset = destIndex - totalMovedCount; } else { + // NOTE: we will not enter this loop if startIndex == destIndex for (int i = startIndex - 1; i >= destIndex; i--) { m_items.swap(i, i + totalMovedCount); // Fast move from 1st to 2nd position } @@ -736,14 +744,49 @@ void QQuickTreeModelAdaptor::modelRowsAboutToBeMoved(const QModelIndex & sourceP item.depth += depthDifference; m_items.replace(bufferCopyOffset + i, item); } - endMoveRows(); + + if (visibleRowsMoved) + endMoveRows(); + + if (depthDifference != 0) { + const QModelIndex &topLeft = index(bufferCopyOffset, 0, QModelIndex()); + const QModelIndex &bottomRight = index(bufferCopyOffset + totalMovedCount - 1, 0, QModelIndex()); + const QVector changedRole(1, DepthRole); + emit dataChanged(topLeft, bottomRight, changedRole); + } } } void QQuickTreeModelAdaptor::modelRowsMoved(const QModelIndex & sourceParent, int sourceStart, int sourceEnd, const QModelIndex & destinationParent, int destinationRow) { - if (!childrenVisible(sourceParent) && childrenVisible(destinationParent)) - modelRowsInserted(destinationParent, destinationRow, destinationRow + sourceEnd - sourceStart); + if (childrenVisible(destinationParent)) { + if (!childrenVisible(sourceParent)) + modelRowsInserted(destinationParent, destinationRow, destinationRow + sourceEnd - sourceStart); + else { + int destIndex = -1; + if (destinationRow == m_model->rowCount(destinationParent)) { + const QModelIndex &emi = m_model->index(destinationRow - 1, 0, destinationParent); + destIndex = lastChildIndex(emi) + 1; + } else { + destIndex = itemIndex(m_model->index(destinationRow, 0, destinationParent)); + } + + const QModelIndex &emi = m_model->index(destinationRow + sourceEnd - sourceStart, 0, destinationParent); + int endIndex = -1; + if (isExpanded(emi)) { + int rowCount = m_model->rowCount(emi); + if (rowCount > 0) + endIndex = lastChildIndex(m_model->index(rowCount - 1, 0, emi)); + } + if (endIndex == -1) + endIndex = itemIndex(emi); + + const QModelIndex &topLeft = index(destIndex, 0, QModelIndex()); + const QModelIndex &bottomRight = index(endIndex, 0, QModelIndex()); + const QVector changedRole(1, ModelIndexRole); + emit dataChanged(topLeft, bottomRight, changedRole); + } + } ASSERT_CONSISTENCY(); } diff --git a/src/controls/Private/qquicktreemodeladaptor_p.h b/src/controls/Private/qquicktreemodeladaptor_p.h index 3eefbe77..56c6ea08 100644 --- a/src/controls/Private/qquicktreemodeladaptor_p.h +++ b/src/controls/Private/qquicktreemodeladaptor_p.h @@ -74,10 +74,11 @@ public: void resetRootIndex(); enum { - DepthRole = Qt::UserRole - 4, + DepthRole = Qt::UserRole - 5, ExpandedRole, HasChildrenRole, - HasSiblingRole + HasSiblingRole, + ModelIndexRole }; QHash roleNames() const; diff --git a/tests/auto/qquicktreemodeladaptor/tst_qquicktreemodeladaptor.cpp b/tests/auto/qquicktreemodeladaptor/tst_qquicktreemodeladaptor.cpp index 13a92ea7..34c8f7cc 100644 --- a/tests/auto/qquicktreemodeladaptor/tst_qquicktreemodeladaptor.cpp +++ b/tests/auto/qquicktreemodeladaptor/tst_qquicktreemodeladaptor.cpp @@ -81,6 +81,7 @@ private slots: void moveRows_data(); void moveRows(); + void reparentOnSameRow(); void selectionForRowRange(); @@ -1160,6 +1161,56 @@ void tst_QQuickTreeModelAdaptor::moveRows() compareModels(tma, model); } +void tst_QQuickTreeModelAdaptor::reparentOnSameRow() +{ + TestModel model(2, 1); + model.alternateChildlessRows = false; + QQuickTreeModelAdaptor tma; + tma.setModel(&model); + + const QModelIndex &destParent = model.index(0, 0); + const QModelIndex &sourceParent = QModelIndex(); + QVERIFY(destParent.isValid()); + tma.expand(destParent); + QVERIFY(tma.isExpanded(destParent)); + + QSignalSpy dataChangedSpy(&tma, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector))); + QSignalSpy rowsMovedSpy(&tma, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QVERIFY(rowsMovedSpy.isValid()); + QVERIFY(dataChangedSpy.isValid()); + + QVERIFY(model.moveRows(sourceParent, 1, 1, destParent, 2)); + + QModelIndex movedIndex = tma.index(3, 0, QModelIndex()); + QVERIFY(movedIndex.isValid()); + QCOMPARE(movedIndex.data(QQuickTreeModelAdaptor::DepthRole).toInt(), 1); + QCOMPARE(tma.data(movedIndex, QQuickTreeModelAdaptor::ModelIndexRole).toModelIndex(), model.index(2, 0, destParent)); + + // at least DepthRole and ModeIndexRole changes should have happened for the affected row + bool depthChanged = false; + bool modelIndexChanged = false; + QList > &changes = dataChangedSpy; + foreach (QList change, changes) { + if (change.at(0) == movedIndex) { + if (change.at(2).value >().contains(QQuickTreeModelAdaptor::DepthRole)) + depthChanged = true; + if (change.at(2).value >().contains(QQuickTreeModelAdaptor::ModelIndexRole)) + modelIndexChanged = true; + } + } + + QCOMPARE(depthChanged, true); + QCOMPARE(modelIndexChanged, true); + + QCOMPARE(rowsMovedSpy.count(), 0); + + model.moveRow(destParent, 2, QModelIndex(), 1); + + QCOMPARE(rowsMovedSpy.count(), 0); + QVERIFY(tma.testConsistency()); + compareModels(tma, model); +} + void tst_QQuickTreeModelAdaptor::selectionForRowRange() { const int ModelRowCount = 9; diff --git a/tests/auto/shared/testmodel.h b/tests/auto/shared/testmodel.h index 00e74129..d1f49a4d 100644 --- a/tests/auto/shared/testmodel.h +++ b/tests/auto/shared/testmodel.h @@ -238,7 +238,7 @@ public: bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) { Q_ASSERT_X(sourceRow >= 0 && sourceRow < rowCount(sourceParent) - && count > 0 && sourceRow + count < rowCount(sourceParent) + && count > 0 && sourceRow + count - 1 < rowCount(sourceParent) && destinationChild >= 0 && destinationChild <= rowCount(destinationParent), Q_FUNC_INFO, "Rows out of range."); Q_ASSERT_X(!(sourceParent == destinationParent && destinationChild >= sourceRow && destinationChild < sourceRow + count), -- cgit v1.2.1 From 846d04cec8d946c28ddbeecc79c63553e0891736 Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Thu, 10 Mar 2016 08:28:35 +0200 Subject: RangeModel: Emit min/max and value changes after component is complete Prevent extra value changed signal to be fired in case when Slider with minimum > 0 and value > minimum are set. Change-Id: I86824c403a7c0296f782d2eec7ed30acfc13b304 Reviewed-by: Mitch Curtis --- src/controls/Private/qquickrangemodel.cpp | 33 ++++++++++++++-- src/controls/Private/qquickrangemodel_p.h | 7 +++- src/controls/Private/qquickrangemodel_p_p.h | 3 ++ tests/auto/controls/data/rangemodel/init.qml | 56 ++++++++++++++++++++++++++++ tests/auto/controls/data/tst_rangemodel.qml | 10 ++++- 5 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 tests/auto/controls/data/rangemodel/init.qml diff --git a/src/controls/Private/qquickrangemodel.cpp b/src/controls/Private/qquickrangemodel.cpp index 02ce0e57..36d7dd34 100644 --- a/src/controls/Private/qquickrangemodel.cpp +++ b/src/controls/Private/qquickrangemodel.cpp @@ -69,6 +69,9 @@ void QQuickRangeModelPrivate::init() posatmin = 0; posatmax = 0; inverted = false; + isComplete = false; + positionChanged = false; + valueChanged = false; } /*! @@ -155,10 +158,16 @@ void QQuickRangeModelPrivate::emitValueAndPositionIfChanged(const qreal oldValue // unchanged. This will be the case when operating with values outside range: const qreal newValue = q->value(); const qreal newPosition = q->position(); - if (!qFuzzyCompare(newValue, oldValue)) - emit q->valueChanged(newValue); - if (!qFuzzyCompare(newPosition, oldPosition)) - emit q->positionChanged(newPosition); + + if (isComplete) { + if (!qFuzzyCompare(newValue, oldValue)) + emit q->valueChanged(newValue); + if (!qFuzzyCompare(newPosition, oldPosition)) + emit q->positionChanged(newPosition); + } else { + positionChanged |= qFuzzyCompare(oldPosition, newPosition); + valueChanged |= !qFuzzyCompare(oldValue, newValue); + } } /*! @@ -346,6 +355,22 @@ qreal QQuickRangeModel::positionForValue(qreal value) const return d->publicPosition(unconstrainedPosition); } +void QQuickRangeModel::classBegin() +{ +} + +void QQuickRangeModel::componentComplete() +{ + Q_D(QQuickRangeModel); + d->isComplete = true; + emit minimumChanged(minimum()); + emit maximumChanged(maximum()); + if (d->valueChanged) + emit valueChanged(value()); + if (d->positionChanged) + emit positionChanged(position()); +} + /*! \property QQuickRangeModel::position \brief the current position of the model diff --git a/src/controls/Private/qquickrangemodel_p.h b/src/controls/Private/qquickrangemodel_p.h index 06d00202..47376ded 100644 --- a/src/controls/Private/qquickrangemodel_p.h +++ b/src/controls/Private/qquickrangemodel_p.h @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE class QQuickRangeModelPrivate; -class QQuickRangeModel : public QObject +class QQuickRangeModel : public QObject, public QQmlParserStatus { Q_OBJECT Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged USER true) @@ -56,6 +56,8 @@ class QQuickRangeModel : public QObject Q_PROPERTY(qreal positionAtMaximum READ positionAtMaximum WRITE setPositionAtMaximum NOTIFY positionAtMaximumChanged) Q_PROPERTY(bool inverted READ inverted WRITE setInverted NOTIFY invertedChanged) + Q_INTERFACES(QQmlParserStatus) + public: QQuickRangeModel(QObject *parent = 0); virtual ~QQuickRangeModel(); @@ -87,6 +89,9 @@ public: Q_INVOKABLE qreal valueForPosition(qreal position) const; Q_INVOKABLE qreal positionForValue(qreal value) const; + void classBegin(); + void componentComplete(); + public Q_SLOTS: void toMinimum(); void toMaximum(); diff --git a/src/controls/Private/qquickrangemodel_p_p.h b/src/controls/Private/qquickrangemodel_p_p.h index 235ba069..6097ff3d 100644 --- a/src/controls/Private/qquickrangemodel_p_p.h +++ b/src/controls/Private/qquickrangemodel_p_p.h @@ -67,6 +67,9 @@ public: uint inverted : 1; QQuickRangeModel *q_ptr; + bool isComplete; + bool positionChanged; + bool valueChanged; inline qreal effectivePosAtMin() const { return inverted ? posatmax : posatmin; diff --git a/tests/auto/controls/data/rangemodel/init.qml b/tests/auto/controls/data/rangemodel/init.qml new file mode 100644 index 00000000..9d050143 --- /dev/null +++ b/tests/auto/controls/data/rangemodel/init.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Private 1.0 +import QtTest 1.0 + +RangeModel { + id: rangemodel + positionAtMinimum: 0 + positionAtMaximum: 100 + stepSize: 1 + + property QtObject spy: SignalSpy { + target: rangemodel + signalName: "valueChanged" + } +} diff --git a/tests/auto/controls/data/tst_rangemodel.qml b/tests/auto/controls/data/tst_rangemodel.qml index db3aceb7..6d95f279 100644 --- a/tests/auto/controls/data/tst_rangemodel.qml +++ b/tests/auto/controls/data/tst_rangemodel.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -68,6 +68,14 @@ TestCase { spy.clear() } + function test_delayedinit() { + var component = Qt.createComponent("rangemodel/init.qml"); + compare(component.status, Component.Ready) + var r = component.createObject(testCase, {minimumValue: 40, maximumValue: 90, value: 80}); + compare(r.value, 80) + compare(r.spy.count, 1) + } + function test_setminimumvalue() { spy.signalName = "minimumChanged" compare(spy.count, 0) -- cgit v1.2.1 From 41669ca64f923324ced7c23d0bb027e503437447 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 30 Aug 2016 11:50:22 +0200 Subject: Remove test exclusion of Tests_CircularTickmarkLabel::test_tickmarksAndLabels Bug is fixed now in declarative. Task-number: QTBUG-54394 Change-Id: I5fcc39125eca2bca3c597fc472b596dc317275e5 Reviewed-by: Simon Hausmann --- tests/auto/extras/BLACKLIST | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/extras/BLACKLIST b/tests/auto/extras/BLACKLIST index a22550c4..3a502904 100644 --- a/tests/auto/extras/BLACKLIST +++ b/tests/auto/extras/BLACKLIST @@ -1,5 +1,3 @@ -[Tests_CircularTickmarkLabel::test_tickmarksAndLabels] -* [Tests_Tumbler::test_focusPastLastColumn] * [Tests_Tumbler::test_itemsCorrectlyPositioned] -- cgit v1.2.1 From deb7bcec278dea1d5903c6d83de234a960051873 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 5 Sep 2016 13:07:12 +0200 Subject: Attempt to stabilize tst_scrollview Task-number: QTBUG-55727 Change-Id: I6cbc1f020ead184fd8475f965f69db635ee2cc7b Reviewed-by: Mitch Curtis --- tests/auto/controls/data/tst_scrollview.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/controls/data/tst_scrollview.qml b/tests/auto/controls/data/tst_scrollview.qml index cb96c3db..cc737664 100644 --- a/tests/auto/controls/data/tst_scrollview.qml +++ b/tests/auto/controls/data/tst_scrollview.qml @@ -133,7 +133,7 @@ TestCase { var scrollView = dragFetchAppendComponent.createObject(container) verify(scrollView !== null, "view created is null") waitForRendering(scrollView) - verify(scrollView.flickableItem.contentHeight === 60 * 20) + tryCompare(scrollView.flickableItem, "contentHeight", 60 * 20) // After scrolling to the end, view should ask the model to fetch more // data, content height should increase and scrollbar handle should move -- cgit v1.2.1 From ffcdd1d6742986e46920919800a382ecf7b58011 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Sun, 28 Aug 2016 18:21:24 +0200 Subject: SplitView: clarify how item sizes should be set It's not exactly clear from the documentation. Change-Id: If173c63e080709c13b4a7b0bf18ef9b02eeec474 Reviewed-by: Richard Moe Gustavsen --- src/controls/SplitView.qml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/controls/SplitView.qml b/src/controls/SplitView.qml index 868108aa..02b788bc 100644 --- a/src/controls/SplitView.qml +++ b/src/controls/SplitView.qml @@ -58,9 +58,13 @@ import QtQuick.Window 2.1 item will get all leftover space when other items have been laid out. By default, the last visible child of the SplitView will have this set, but it can be changed by explicitly setting fillWidth to \c true on another item. + As the fillWidth item will automatically be resized to fit the extra space, explicit assignments - to width and height will be ignored (but \l{Layout::minimumWidth}{Layout.minimumWidth} and + to its width and height properties will be ignored (but \l{Layout::minimumWidth}{Layout.minimumWidth} and \l{Layout::maximumWidth}{Layout.maximumWidth} will still be respected). + The initial sizes of other items should be set via their width and height properties. + Any binding assignment to an item's width or height will be broken as soon as the user + drags that item's splitter handle. A handle can belong to the item either on the left or top side, or on the right or bottom side: \list -- cgit v1.2.1 From 9be0d5b9e8ad510801ea8fab93b8e5433ea47f3e Mon Sep 17 00:00:00 2001 From: Iikka Eklund Date: Wed, 7 Sep 2016 09:33:05 +0300 Subject: Add changes file for 5.6.2 Change-Id: I7676b06dfe58898b655e575208277f6a9a9ab7cf Reviewed-by: Mitch Curtis --- dist/changes-5.6.2 | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 dist/changes-5.6.2 diff --git a/dist/changes-5.6.2 b/dist/changes-5.6.2 new file mode 100644 index 00000000..ac1d5f92 --- /dev/null +++ b/dist/changes-5.6.2 @@ -0,0 +1,30 @@ +Qt 5.6.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.6.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.6 series is binary compatible with the 5.5.x series. +Applications compiled for 5.5 will continue to run with 5.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - [QTBUG-50795] ScrollView: fixed to update the position of the scroll + bars on content size change. + - [QTBUG-47523] TreeView: fixed moving of items + - RangeModel: fixed to emit min/max and value changes after component is + complete + - Menu: fixed native menu on macOS to to get dismissed when its parent + window is destroyed -- cgit v1.2.1 From 49bd4b76d08ec11d08105ca71e8dda4f8d459b5c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 8 Sep 2016 12:47:24 +0200 Subject: Static builds: show QML files in QtCreator After b4c1391, QML files does no longer show up in QtCreator for static builds. Before they would show as resources, but since we now only create resources explicit for dynamic builds (and implicit otherwise), QtCreator cannot see them. This patch will add all the qml files as OTHER_FILES when doing static builds, so they show up in QtCreator. Change-Id: I8ee7d53e938cd96da23b0dc0ca78406449e3504d Reviewed-by: J-P Nurmi --- src/controls/controls.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/controls/controls.pro b/src/controls/controls.pro index 794a6e36..e2ecacd8 100644 --- a/src/controls/controls.pro +++ b/src/controls/controls.pro @@ -85,6 +85,8 @@ osx: LIBS_PRIVATE += -framework Carbon QML_FILES *= $$CONTROLS_QML_FILES \ $$PRIVATE_QML_FILES \ $$STYLES_QML_FILES + OTHER_FILES += $$QML_FILES } + CONFIG += no_cxx_module load(qml_plugin) -- cgit v1.2.1 From 94c511b63af10a5507936ab7fbdd517144cde872 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 12 Sep 2016 13:08:58 +0200 Subject: Fix sqlite detection There is now a sql-sqlite feature in qtbase that should get used. Change-Id: I8abc60bec5c0fa64d180150c598f0a6605844473 Reviewed-by: Simon Hausmann --- examples/quickcontrols/controls/calendar/calendar.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/quickcontrols/controls/calendar/calendar.pro b/examples/quickcontrols/controls/calendar/calendar.pro index 67960e27..0c79fb40 100644 --- a/examples/quickcontrols/controls/calendar/calendar.pro +++ b/examples/quickcontrols/controls/calendar/calendar.pro @@ -1,7 +1,7 @@ QT += qml quick sql TARGET = calendar -!contains(sql-drivers, sqlite): QTPLUGIN += qsqlite +!qtConfig(sql-sqlite): QTPLUGIN += qsqlite include(src/src.pri) include(../shared/shared.pri) -- cgit v1.2.1 From e61eceda62c661b50ed9210e95c0710f652ce9ec Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 12 Sep 2016 15:13:57 +0200 Subject: CheckBox: fix missing indicator frame on certain DPIs Specifying width and height is typically a bad idea, as they can be overridden by the layouting engine. implicitWidth and implicitHeight are better. Change-Id: Ib597f1fa98f82f00236c79bb5f9f07405593c35e Task-number: QTBUG-51842 Reviewed-by: Andy Shaw Reviewed-by: J-P Nurmi --- src/controls/Styles/Base/CheckBoxStyle.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controls/Styles/Base/CheckBoxStyle.qml b/src/controls/Styles/Base/CheckBoxStyle.qml index a4028fef..68b1aa76 100644 --- a/src/controls/Styles/Base/CheckBoxStyle.qml +++ b/src/controls/Styles/Base/CheckBoxStyle.qml @@ -111,7 +111,7 @@ Style { /*! This defines the indicator button. */ property Component indicator: Item { implicitWidth: Math.round(TextSingleton.implicitHeight) - height: width + implicitHeight: implicitWidth Rectangle { anchors.fill: parent anchors.bottomMargin: -1 -- cgit v1.2.1 From 3aee127f969cabec0819d93d305d47afc4cf25d6 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 12 Sep 2016 14:01:50 +0200 Subject: Add missing period to TableViewColumn documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I625e7d3e4b5003105587769edb8fc68747ceac35 Reviewed-by: Topi Reiniƶ --- src/controls/TableViewColumn.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controls/TableViewColumn.qml b/src/controls/TableViewColumn.qml index 3f5a8468..6e253614 100644 --- a/src/controls/TableViewColumn.qml +++ b/src/controls/TableViewColumn.qml @@ -74,7 +74,7 @@ QtObject { /*! The model \c role of the column. */ property string role - /*! The current width of the column + /*! The current width of the column. The default value depends on platform. If only one column is defined, the width expands to the viewport. */ -- cgit v1.2.1 From 59c6c0e0b1b5b46747595a58e11311b7393d7e70 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 13 Sep 2016 10:23:22 +0200 Subject: Fix crash on exit when using default property aliases with layouts The layout was being destroyed before the text, which meant that the removeItemChangeListener() call never got hit. To ensure that the listener is always removed, loop through each child in QQuickLayout's destructor. Task-number: QTBUG-51927 Change-Id: I4235579501bd1790e9483a8741915e55f1b1b803 Reviewed-by: Frederik Gladhorn Reviewed-by: J-P Nurmi --- src/layouts/qquicklayout.cpp | 3 ++ tests/auto/controls/data/layout/Container.qml | 55 +++++++++++++++++++++++ tests/auto/controls/data/layout/ContainerUser.qml | 53 ++++++++++++++++++++++ tests/auto/controls/data/tst_layout.qml | 11 +++++ 4 files changed, 122 insertions(+) create mode 100644 tests/auto/controls/data/layout/Container.qml create mode 100644 tests/auto/controls/data/layout/ContainerUser.qml diff --git a/src/layouts/qquicklayout.cpp b/src/layouts/qquicklayout.cpp index f28a7d07..a7e63195 100644 --- a/src/layouts/qquicklayout.cpp +++ b/src/layouts/qquicklayout.cpp @@ -695,6 +695,9 @@ QQuickLayout::QQuickLayout(QQuickLayoutPrivate &dd, QQuickItem *parent) QQuickLayout::~QQuickLayout() { d_func()->m_isReady = false; + + foreach (QQuickItem *child, d_func()->childItems) + QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::SiblingOrder); } QQuickLayoutAttached *QQuickLayout::qmlAttachedProperties(QObject *object) diff --git a/tests/auto/controls/data/layout/Container.qml b/tests/auto/controls/data/layout/Container.qml new file mode 100644 index 00000000..db3d68c4 --- /dev/null +++ b/tests/auto/controls/data/layout/Container.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Layouts 1.2 + +Item { + objectName: "qtbug51927-window" + visible: true + + default property alias _contents: customContent.data + + ColumnLayout { + id: customContent + objectName: "qtbug51927-columnLayout" + anchors.fill: parent + } +} diff --git a/tests/auto/controls/data/layout/ContainerUser.qml b/tests/auto/controls/data/layout/ContainerUser.qml new file mode 100644 index 00000000..ff7ce622 --- /dev/null +++ b/tests/auto/controls/data/layout/ContainerUser.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Window 2.2 + +Container { + visible: true + + Text { + objectName: "qtbug51927-text" + text: qsTr("Hello World") + anchors.centerIn: parent + renderType: Text.QtRendering + } +} diff --git a/tests/auto/controls/data/tst_layout.qml b/tests/auto/controls/data/tst_layout.qml index fc62b8a4..da0b1dd9 100644 --- a/tests/auto/controls/data/tst_layout.qml +++ b/tests/auto/controls/data/tst_layout.qml @@ -53,5 +53,16 @@ TestCase { var object = Qt.createQmlObject('import QtQuick 2.2; import QtQuick.Layouts 1.0; QtObject { Layout.fillWidth: true }', testCase, ''); object.destroy() } + + function test_defaultPropertyAliasCrash() { + var containerUserComponent = Qt.createComponent("layout/ContainerUser.qml"); + compare(containerUserComponent.status, Component.Ready); + + var containerUser = containerUserComponent.createObject(testCase); + verify(containerUser); + + // Shouldn't crash. + containerUser.destroy(); + } } -- cgit v1.2.1 From 5d4e7366718d3784063bdf64725a5371355f179a Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 12 Sep 2016 17:06:04 +0200 Subject: Slider: fix the handle's position when minimumValue is not 0 __handlePos (badly named; it should be, e.g. __handleValueForPos) represents the value of the handle based on "fakeHandle"'s position. It is the result of range.valueForPosition() being called. However, the arguments to this function (fakeHandle.x and fakeHandle.y) don't always change when the values of the slider change, which leads to the x calculation for the handle delegate in SliderStyle having outdated information, causing the related bug. The fix for another bug already works around this issue by passing the relevant properties as arguments (which are ignored) to the function call. This is presumably done this way because it should be cheaper than forcing the JavaScript engine to evaluate a more clearly written expression where each related property is on its own line, for example. property real __handlePos: { range.positionAtMinimum, range.positionAtMaximum; return range.valueForPosition(__horizontal ? fakeHandle.x : fakeHandle.y); } In the case of the related bug, minimumValue has been updated, but __handlePos is still using the old value, causing the handle to be positioned incorrectly. So, we continue this tradition and add another property to the list of arguments. Task-number: QTBUG-51765 Change-Id: I40882872e668a867a8f5e5768244e199618bd769 Reviewed-by: J-P Nurmi --- src/controls/Slider.qml | 6 +++-- tests/auto/controls/data/tst_slider.qml | 40 +++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/controls/Slider.qml b/src/controls/Slider.qml index 20d11025..981a619b 100644 --- a/src/controls/Slider.qml +++ b/src/controls/Slider.qml @@ -173,9 +173,11 @@ Control { /*! \internal The extra arguments positionAtMinimum and positionAtMaximum are there to force - re-evaluation of the handle position when the constraints change (QTBUG-41255). + re-evaluation of the handle position when the constraints change (QTBUG-41255), + and the same for range.minimumValue (QTBUG-51765). */ - property real __handlePos: range.valueForPosition(__horizontal ? fakeHandle.x : fakeHandle.y, range.positionAtMinimum, range.positionAtMaximum) + property real __handlePos: range.valueForPosition(__horizontal ? fakeHandle.x : fakeHandle.y, + range.positionAtMinimum, range.positionAtMaximum, range.minimumValue) activeFocusOnTab: true diff --git a/tests/auto/controls/data/tst_slider.qml b/tests/auto/controls/data/tst_slider.qml index 83ba299e..9b79bc29 100644 --- a/tests/auto/controls/data/tst_slider.qml +++ b/tests/auto/controls/data/tst_slider.qml @@ -38,11 +38,12 @@ ** ****************************************************************************/ -import QtQuick 2.2 +import QtQuick 2.6 import QtTest 1.0 import QtQuickControlsTests 1.0 -import QtQuick.Controls 1.2 +import QtQuick.Controls 1.4 import QtQuick.Controls.Private 1.0 +import QtQuick.Controls.Styles 1.4 Item { id: container @@ -64,6 +65,12 @@ Item { id: util } + Component { + id: sliderComponent + + Slider {} + } + function test_vertical() { var slider = Qt.createQmlObject('import QtQuick.Controls 1.2; Slider {}', testCase, ''); verify(slider.height < slider.width) @@ -361,5 +368,34 @@ Item { control.destroy() component.destroy() } + + Component { + id: namedHandleStyle + + SliderStyle { + handle: Rectangle { + objectName: "sliderHandle" + implicitWidth: 20 + implicitHeight: 20 + color: "salmon" + } + } + } + + function test_minimumValueLargerThanValue() { + var control = sliderComponent.createObject(container, { "style": namedHandleStyle, "minimumValue": 0, "maximumValue": 2, value: "minimumValue" }); + verify(control); + + var handle = findChild(control, "sliderHandle"); + verify(handle); + + // The handle should stay within the bounds of the slider when + // minimumValue is set to a value larger than "value". + control.minimumValue = 1; + compare(control.value, control.minimumValue); + compare(handle.mapToItem(null, 0, 0).x, 0) + + control.destroy(); + } } } -- cgit v1.2.1