summaryrefslogtreecommitdiffstats
path: root/src/corelib/itemmodels
Commit message (Collapse)AuthorAgeFilesLines
* QAbstractItemModel: Add revisions to new methodsUlf Hermann2022-06-241-13/+13
| | | | | | | | | | | These methods show up in QML-exposed types. They should be revisioned in order to keep those types backwards-compatible. Pick-to: 6.4 Change-Id: I8e826dc2e7db49d8abe69f67605dfb1991855b96 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* QAbstractItemModel: Fix Qt::TextAlignmentRole when metatype is uintJonas Kvinge2022-05-221-4/+8
| | | | | | | | | | | When combining text alignment flags, it no longer works since the metatype for example QVariant(Qt::AlignRight | Qt::AlignVCenter) is uint, not int. Fixes: QTBUG-103576 Pick-to: 6.2 6.3 Change-Id: If0291b99606787081c4bc26fd00431f8a17a61a2 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Use SPDX license identifiersLucie Gérard2022-05-1621-800/+44
| | | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Task-number: QTBUG-67283 Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* Document the default value of QSFPM::sortOrder()Andreas Hartmetz2022-04-281-2/+5
| | | | | | | | | ...and how to change the value, which is by calling sort(). Also, this is not a property either. Pick-to: 5.15 6.2 6.3 Change-Id: I1b1be90dc43c29e85903a33d0f99569fd6c87abb Reviewed-by: David Faure <david.faure@kdab.com>
* Better document how to enable sorting in QSPFMAndreas Hartmetz2022-04-281-2/+7
| | | | | | | | | | | | | | This can be a big time sink otherwise. Unlike reimplementing filterAcceptsRow() for filtering, reimplementing lessThan() is *not* sufficient to enable sorting. As a drive-by, change \brief to \return because sortOrder() is not a (formal) property. Pick-to: 5.15 6.2 6.3 Change-Id: I7e7be6f1e8e6b03a9923a7f77f04005b19a69d41 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: David Faure <david.faure@kdab.com>
* Exploit the new macro varargs form of Q_GLOBAL_STATICEdward Welbourne2022-04-221-3/+3
| | | | | | | | Convert various uses of Q_GLOBAL_STATIC_WITH_ARGS() to the less verbose form the recent reworking makes possible. Change-Id: I57820660b5d00d39bf54b5a08cb921ebaec57c7c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QAbstractProxyModel: do not access invalid indexesGiuseppe D'Angelo2022-04-133-9/+112
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QAbstractProxyModel::headerData tries to do the "smart" thing and map sections in the proxy to sections in the source. However there's no "mapSectionToSource" virtual. Instead, to map horizontal headers, the code builds a proxy index at row 0 and section N, maps it to the source, and finds out which source column it gets mapped to. (Same story for the vertical headers). ... in general this can obviously fail, say you've got a "horizontal scrambling" proxy model, but in the common case this is OK. Except, if the proxy is empty (e.g. 0 rows or columns). In this case, it asks for an illegal index, and if you reimplemented index() yourself (which you must, since it's a pure virtual in QAPM) and you do bounds checking, you'll not be pleased at the result. This turns out to be a massive API liability. To fix this somehow properly, we can decide that empty models don't get the section remapped (easy). Less easy is the fact that, when the model does get some data, we have to emit headerDataChanged() otherwise the views will get broken. So add this logic too. Note that QAPM does not normally forward any source model's signal -- a subclass has to connect to them and handle them explicitly. That's *another* API liability, all over the place -- data(), headerData(), flags(), etc. What I mean by this is that one can create a valid QAPM (by implementing its pure virtuals) that however is immediately broken by the convenience that QAPM provides for the rest (data(), headerData(), etc.). This commit doesn't try and change this in any way, but I'm less and less convinced of the usefulness of QAPM in its current shape. Change-Id: I45a8c2139f2c1917ffbf429910fdb92f005f4feb Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: David Faure <david.faure@kdab.com>
* Itemviews: start fixing mixups of int/enum for Qt's item rolesGiuseppe D'Angelo2022-03-231-0/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | A model is supposed to return a Qt::CheckState for a CheckStateRole, and a Qt::Alignment for a Qt::TextAlignmentRole. This is what the documentation says (and what makes sense), but unfortunately Qt's default delegate expected a plain `int` instead. This sometimes worked (via QVariant conversions, e.g. when using a plain enum) and sometimes didn't (e.g. when using a flag type). This is confusing for end-users (and type unsafe, killing the whole point of using enums and flags in the first place). Adding some automatic flags<->int conversions through QVariant is frowned upon, so I don't want to go there. Instead, add some private convenience functions that extract either the right type from a variant, or try to extract an `int` and convert it to the expected type. Use these from within itemviews code. Change-Id: I44bee98c4a26a1ef6c3b2fa1b8de2edfee7aef32 Pick-to: 6.2 6.3 Fixes: QTBUG-75172 Task-number: QTBUG-74639 Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Core: Do not depend on transitive includesFabian Kosmale2022-03-175-0/+5
| | | | | Change-Id: I2c71188a4d27692a2d6ef1aa447b329627214b17 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QItemSelectionModel: avoid 24 relocationsMarc Mutz2022-03-111-35/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Use qOffsetStringArray() instead of an array of pairs of pointers. This unearthed a problem with SIGNAL and SLOT calling qFlagLocation() (meaning in debug mode, the array was runtime-initialized, not just relocated), which we work around by using the new QT_STRINGIFY_ {SIGNAL,SLOT} macros now. Saves 24 relocations, but, interestingly, saves only 4b in text size on GCC 11.2 Linux AMD64 -O2 C++20 builds (TEXT and DATA combined) while saving 760b on the equivalent Clang 10 libc++ build (expected, in both cases: 24 * (sizeof(void*) - sizeof(quint16))): Clang: $ size qtbase/lib/libQt6Core.so.6.4.0 text data bss dec hex filename 5476156 90520 16185 5582861 55300d qtbase/lib/libQt6Core.so.6.4.0 $ ~/bin/relinfo.pl qtbase/lib/libQt6Core.so.6.4.0 qtbase/lib/libQt6Core.so.6.4.0: 6528 relocations, 3598 relative (55%), 2540 PLT entries, 2227 for local syms (87%), 0 users $ ninja libQt6Core.so [6/6] Creating library symlink qtbase/lib/libQt6Core.so.6 qtbase/lib/libQt6Core.so $ size qtbase/lib/libQt6Core.so.6.4.0 text data bss dec hex filename 5475604 90312 16185 5582101 552d15 qtbase/lib/libQt6Core.so.6.4.0 $ ~/bin/relinfo.pl qtbase/lib/libQt6Core.so.6.4.0 qtbase/lib/libQt6Core.so.6.4.0: 6504 relocations, 3574 relative (54%), 2540 PLT entries, 2227 for local syms (87%), 0 users GCC: $ ~/bin/relinfo.pl qtbase/lib/libQt6Core.so.6.4.0 qtbase/lib/libQt6Core.so.6.4.0: 6300 relocations, 5343 relative (84%), 318 PLT entries, 1 for local syms (0%), 0 users $ size qtbase/lib/libQt6Core.so.6.4.0 text data bss dec hex filename 6019871 75896 16952 6112719 5d45cf qtbase/lib/libQt6Core.so.6.4.0 $ ninja libQt6Core.so [6/6] Creating library symlink qtbase/lib/libQt6Core.so.6 qtbase/lib/libQt6Core.so $ ~/bin/relinfo.pl qtbase/lib/libQt6Core.so.6.4.0 qtbase/lib/libQt6Core.so.6.4.0: 6276 relocations, 5319 relative (84%), 318 PLT entries, 1 for local syms (0%), 0 users $ size qtbase/lib/libQt6Core.so.6.4.0 text data bss dec hex filename 6020091 75672 16952 6112715 5d45cb qtbase/lib/libQt6Core.so.6.4.0 Pick-to: 6.3 Change-Id: I60749953f1a63d23d696a5a547cd924ec259ead3 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QAbstractItemModel: fix persistent index corruption when moving columnsDavid Faure2022-02-281-3/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | QHeaderView creates persistent indexes in _q_sectionsAboutToBeChanged(), called by the slot connected to rowsAboutToBeMoved/columnsAboutToBeMoved. In the case of rows, QAbstractItemModel emits the signal *before* preparing to update persistent indexes in itemsAboutToBeMoved(), so it can see the ones newly created by QHeaderView, all is well. In the case of columns, the emit was done *after* calling itemsAboutToBeMoved(), so the additional persistent indexes created by QHeaderView were ignored, and in endMoveRows() we could end up with: ASSERT failure in QPersistentModelIndex::~QPersistentModelIndex: "persistent model indexes corrupted" This bug has been there since the very beginning of beginMoveColumns(), but was undetected because moving columns in a model is pretty rare (in my case there's a QTransposeProxyModel that turns columns into rows in the underlying model, and a proxy that handles dropMimeData...) Pick-to: 6.3 6.2 5.15 Change-Id: I74bad137594019a04c2a19c2abb351ff3065c25a Reviewed-by: Andreas Buhr <andreas.buhr@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
* QAbstractItemModel: make naming of arguments consistentAndreas Buhr2022-02-192-10/+10
| | | | | | | | | The signals rowsAboutToBeMoved/rowsMoved have the same arguments, but use different argument names. This patch aligns the naming, making it consistent. Same for columnsAboutToBeMoved/columnsMoved. Change-Id: I1cefe54319e569b8d57f6579ae9d5c3e33b66dc2 Reviewed-by: David Faure <david.faure@kdab.com>
* Prevent repeated instantiations of some qRegisterNormalizedMetaType<>s [1/N] ↵Marc Mutz2022-01-214-9/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (QtGui) Create macros that wrap the magic developed in 7d63efc16f65f98c657caa90e0d7e9b72a879ade and apply it to all Q_DECLARE_METATYPE invocations that show up in Clang -ftime-trace for a PCH'ed QtGui build. Effects on compile times: Clang 10 -ftme-trace: $ ClangBuildAnalyzer --analyze qtgui-before.trace | head -n6 Analyzing build trace from 'qtgui-before.trace'... **** Time summary: Compilation (523 times): Parsing (frontend): 628.3 s Codegen & opts (backend): 304.5 s $ ClangBuildAnalyzer --analyze qtgui-after.trace | head -n6 Analyzing build trace from 'qtgui-after.trace'... **** Time summary: Compilation (523 times): Parsing (frontend): 546.0 s Codegen & opts (backend): 304.4 s GCC 11 time (bash builtin): before: $ time for ((i=0; i < 3; ++i)) do touch src/gui/painting/qpolygon.h ; ninja libQt6Gui.so; done real 4m13,539s user 49m24,416s sys 3m18,177s after: $ time for ((i=0; i < 3; ++i)) do touch src/gui/painting/qpolygon.h ; ninja libQt6Gui.so; done real 3m55,697s user 45m19,941s sys 3m7,370s Task-number: QTBUG-97601 Pick-to: 6.3 Change-Id: Ia8e37a58937568a7ed21cfeb4b27274deca4d53b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtCore: replace qSwap with std::swap/member-swap where possibleMarc Mutz2022-01-202-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | qSwap() is a monster that looks for ADL overloads of swap() and also detects the noexcept of the wrapped swap() function, so it should only be used when the argument type is unknown. In the vast majority of cases, the type is known to be efficiently std::swap()able or to have a member-swap. Call either of these. For the common case of pointer types, circumvent the expensive trait checks on std::swap() by providing a hand-rolled qt_ptr_swap() template, the advantage being that it can be unconditionally noexcept, removing all type traits instantiations. Don't document it, otherwise we'd be unable to pick it to 6.2. Effects on Clang -ftime-trace of a PCH'ed libQt6Gui.so build: before: **** Template sets that took longest to instantiate: [...] 27766 ms: qSwap<$> (9073 times, avg 3 ms) [...] 2806 ms: std::swap<$> (1229 times, avg 2 ms) (30572ms) after: **** Template sets that took longest to instantiate: [...] 5047 ms: qSwap<$> (641 times, avg 7 ms) [...] 3371 ms: std::swap<$> (1376 times, avg 2 ms) [qt_ptr_swap<$> does not appear in the top 400, so < 905ms] (< 9323ms) As a drive-by, remove superfluous inline keywords and template ornaments. Task-number: QTBUG-97601 Pick-to: 6.3 6.2 Change-Id: I88f9b4e3cbece268c4a1238b6d50e5712a1bab5a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Doc: Use \inmodule for all classes and headersTopi Reinio2022-01-171-0/+1
| | | | | | | | | | | | | | | QDoc made some assumptions about the module a class/header belongs to, based on the source file path. This feature is rather error-prone and unnecessarily complex and will be removed from QDoc. Define modules explicitly to avoid documentation warnings when this removal happens. Pick-to: 6.2 6.3 Change-Id: I7947d197db5ac36c12e816caa19bb2f74eda8849 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
* Prevent repeated instantiations of ↵Marc Mutz2022-01-152-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | qRegisterNormalizedMetaType<QList<QModelIndex>>() This, finally, shows some expected results: Clang -ftime-trace: $ ClangBuildAnalyzer --analyze qtgui-spec-before.trace | head -n6 Analyzing build trace from 'qtgui-spec-before.trace'... **** Time summary: Compilation (523 times): Parsing (frontend): 665.7 s Codegen & opts (backend): 298.9 s $ ClangBuildAnalyzer --analyze qtgui-spec-after.trace | head -n6 Analyzing build trace from 'qtgui-spec-after.trace'... **** Time summary: Compilation (525 times): Parsing (frontend): 628.3 s Codegen & opts (backend): 301.0 s GCC 11 time (bash builtin): $ time for ((i=0; i < 3; ++i)) do touch ../qt5/qtbase/src/gui/painting/qpolygon.h ; ninja libQt6Gui.so; done [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so real 4m10,918s user 49m10,099s sys 3m11,719s $ git revert --no-commit HEAD $ time for ((i=0; i < 3; ++i)) do touch ../qt5/qtbase/src/gui/painting/qpolygon.h ; ninja libQt6Gui.so; done [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so real 4m18,630s user 51m11,491s sys 3m16,479s The technique in the comment in qmetatype.h doesn't work on Clang - it runs into -Winstantiation-after-specialization. The whole extern template stuff so miserably fails to meet the goals set out in N1448, not only for MSVC and class templates, but, it seems, on all compilers, and for function templates, too, that I'm giving up on it for now. Unfortunately, I'm not really seeing a way to hide this stuff behind a macro, yet. Task-number: QTBUG-97601 Pick-to: 6.3 Change-Id: I500fd04555e0bd76ac021f75582bd8d8cf339378 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Make QAbstractItemModel::insert|move|remove(Columns|Rows)[s]() invokableVolker Krause2021-12-211-13/+13
| | | | | | | Useful for example for calling those from QML. Change-Id: I07fe32944c76b58cb074b6dd7eff17af1f0ae00f Reviewed-by: David Faure <david.faure@kdab.com>
* Doc: Reword, fix typos and some formattingIvan Tkachenko2021-12-081-1/+1
| | | | | Change-Id: I0929f7653cb07665842d0aa7bf18dc80471febdc Reviewed-by: Kai Koehne <kai.koehne@qt.io>
* Make QAbstractProxyModel itemData() behave like data()Luca Beldi2021-11-261-2/+4
| | | | | | | | | | | | | | | | | | | | | | QAbstractProxyModel::itemData/setItemData should behave just like data()/setData() instead of calling the QAbstractItemModel implementation. Before this change the QAbstractProxyModel implementation calls its the QAbstractItemModel implementation, which ends up calling data()/setData() in a loop bypassing the convenience of itemData/setItemData. [ChangeLog][QtCore][QAbstractProxyModel] The itemData() and setItemData() functions will now call the respective implementations in the source model (after mapping the index to a source index), matching what data() and setData() already did. Before, the proxy model simply called the default implementations of itemData()/setItemData() in its own base class (QAbstractItemModel). Change-Id: I9e680d355f44fa130660dd7e1c8ac37484c1566e Reviewed-by: David Faure <david.faure@kdab.com>
* QItemSelection: fix (some) O(n²) behavior in merge()Marc Mutz2021-11-161-9/+7
| | | | | | | | | | | | | | | Instead of taking a copy of the incoming data, followed by a quadratic modifying algorithm (single-element erase loop), guaranteeing a deep-copy detach of the original, just iterate over the incoming data, building the new dataset by appending only valid items. Also port to ranged for loop. There's more quadratic behavior in that function, later on, but that's for another patch. Change-Id: I284f3b7c9694c8eb226a198f6f97538765113b19 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QAbstractProxyModel: Use QCompatProperty with custom getterIevgenii Meshcheriakov2021-11-012-68/+5
| | | | | | | | | Use new API for QCompatProperty with custom getter instead of ad-hoc solution. Task-number: QTBUG-89655 Change-Id: I06481ad4d360b178be001ceb9c6c8460b73391f6 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Fix segfault in QItemSelectionModel::hasSelectionAndreas Buhr2021-10-141-2/+5
| | | | | | | | | | | Amends 0c2125458a9fdddaf3385b257ba4350da872a1d1. The code assumed that a QItemSelectionModel always has a model. But during initialization from QML, it hasn't. Fixes: QTBUG-97475 Pick-to: 6.2 6.2.1 Change-Id: Ie9c680f8989a23ef732faaf5da7ef7ae273126aa Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* corelib: Fix typos in source code commentsJonas Kvinge2021-10-121-1/+1
| | | | | | Pick-to: 6.2 Change-Id: Ic78afb67143112468c6f84677ac88f27a74b53aa Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QSFPM: remove redundant call to update_source_sort_column()David Faure2021-10-051-2/+1
| | | | | | | | | | | | | | | | | | | | | Everywhere else in this code, it says if (update_source_sort_column() && dynamic_sortfilter) so, doing the same here. This originally comes from commit 3ffcfc357dbc51bf62ffb but skelly isn't around anymore, and Milian (reviewer) had no objection to this change either. Looking into the implementation, calling it twice is a no-op anyway, create_mapping will early-return with "already done". On the other hand, now it has a chance of returning true, while before it would always return false in the second call ("return true if the column was changed"). I couldn't write a unittest for that case though, it would require that a source reset also changes the proxy->source column mapping somehow, but I don't see how that can be done (the latter being the QSFPM setup). Change-Id: Ie560facf1039a1afc02543e83bfdef0f8f2e09fc Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* emit layoutAboutToBeChanged timelyLuca Beldi2021-07-201-11/+19
| | | | | | | | | | | layoutAboutToBeChanged must be called before persistentIndexList as the user might create persistent indexes as a response to the signal Fixes: QTBUG-93466 Pick-to: 6.2 5.15 Change-Id: I73c24501f536ef9b6092c3374821497f0a8f0de4 Reviewed-by: David Faure <david.faure@kdab.com>
* Consistent handling of disabled items in QItemSelectionModelAndreas Buhr2021-07-153-22/+56
| | | | | | | | | | | | | | | | | | | | | | | | In QItemSelectionModel, items which are disabled or marked as not selectable should not be considered as selected. But this was not handled consistently. The following methods considered only items which are enabled and marked selectable: selectedIndexes(), rowIntersectsSelection(), and columnIntersectsSelection(). The following methods considered only items which are marked selectable, but did not check whether they are enabled: selectedRows(), selectedColumns(), isRowSelected(), isColumnSelected(), isSelected(). Finally there is hasSelection(), which did not check for enabled nor for selectable. This patch introduces consistent behavior. All methods check both whether the items are enabled and whether they are selectable now. [ChangeLog][QtCore][QItemSelectionModel][Important Behavior Changes] All methods in QItemSelectionModel now consider only items which are marked as enabled and selectable as part of the selection. Fixes: QTBUG-93829 Pick-to: 6.2 Change-Id: I4725243ea6b0db4f289ce34ada22c7a9d3282713 Reviewed-by: David Faure <david.faure@kdab.com>
* Consistent indentation for BINDABLE propertiesAndreas Buhr2021-06-242-7/+12
| | | | | | | | | Triggered by API review in Gerrit patch 355960. Task-number: QTBUG-94407 Pick-to: 6.2 Change-Id: I7cafc1cc9d4b929040b53c6bf92c91d73c3b39f2 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Add "We mean it" warning to qidentityproxymodel_p.hMitch Curtis2021-06-141-0/+12
| | | | | | | | This was missed in b42e2d70fbda5afb462b869583b925ad5f1a5480. Pick-to: 6.2 Change-Id: Id06bd880456534293cf6c0d215f794b6ad0552ca Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QSortFilterProxyModel: create mappings on demand againDavid Faure2021-06-031-10/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Calling create_mapping in setSourceModel as introduced by 8455bfee76ed3f1bd3bba8bd3688a7afa94ae0bb can lead to an early call to filterAcceptsRow, and some existing applications may crash. It is also an incomplete solution since it was only done for the toplevel index but not for child indexes. Instead, go back to creating mappings on demand. This means coming up with a different fix for QTBUG-87781 (dataChanged not emitted for indexes that haven't been mapped yet, i.e. not queried or shown anywhere). When this happens, we can't know if the index was previously filtered out or not (for lack of a dataAboutToBeChanged signal...). Creating the mapping with the new data only gives us the new state of affairs, there's no reference state to compare to. Therefore, when the mapping is missing (during dataChanged handling), create it, but skip all the logic about row insertion/removal, just forward the dataChanged signal if the row isn't filtered out. Creating the mapping might require creating first mappings for parents, recursively, which wasn't done anywhere in QSFPM yet, hence the new create_mapping_recursive() method. In addition to all this, the handling of removed items was incorrect, remove_source_items did nothing if the parent was gone, and then source_items_removed was trying to adjust indexes in an incorrect list. If the parent is gone, clear the proxy_to_source list, so there's nothing to adjust afterwards. This bug actually doesn't happen anymore in this version of the patch, but the change still seems right and might prevent repeating a long debugging session in the future. Thanks to ChunLin Wang for the unittest in this commit. Done-with: ChunLin Wang Pick-to: 6.1 6.0 5.15 Change-Id: Id543d0cc98f1a03b5852bda01d2f49b980e06be7 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
* Move QIdentityProxyModelPrivate out into its own headerMitch Curtis2021-06-012-36/+87
| | | | | | | | | qtquickcontrols2 needs to use it. Change-Id: Ic5e3105095a8fcd36a38a3ce4353db4057ada0de Reviewed-by: Andy Shaw <andy.shaw@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: David Faure <david.faure@kdab.com>
* Fix qdoc warningsVolker Hilsheimer2021-05-272-2/+3
| | | | | Change-Id: Ie51ccff3272f078e062380033678828a01f03eb8 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* Item models: code tidiesGiuseppe D'Angelo2021-05-182-3/+3
| | | | | | | | Use QFlags::testAnyFlag instead of relying on implicit conversions. Change-Id: I7ac8149535ad28e47fbf3e250042892bdf8c3a72 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch>
* Fix QItemSelectionModel::selectionChanged emissionAndreas Buhr2021-05-181-8/+32
| | | | | | | | | | | | | | | | | | | | QItemSelectionModel has the property selectedIndexes with the notification signal selectionChanged. When a row is deleted or inserted above the current selection, the row number of the current selection changes and thus the return value of selectedIndexes changes. This should trigger its notification signal. This signal was not emitted. This patch fixes this and adds a unit test to verify this. [ChangeLog][Important Behavior Changes][QtCore] QItemSelectionModel now emits the selectionChanged signal if only the indexes of the selected items change. Fixes: QTBUG-93305 Change-Id: Ia5fb5ca32d658c9c0e1d7093c57cc08a966b9402 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: David Faure <david.faure@kdab.com>
* QAbstractItemModel::match: code tidiesGiuseppe D'Angelo2021-05-121-1/+1
| | | | | | | | Remove a magic number from the code, by adding it (as a private value) to the right enumeration. Use toInt() to convert to integer. Change-Id: Id1b00dde900619684b5a3df247d46938439150ca Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QSFPM: make filterRegularExpression and filterCaseSensitivity bindableIvan Solovev2021-05-112-39/+133
| | | | | | | | | | | | | | | | | This takes care of the last two QSFPM properties. They were postponed because of the tricky relation between them and some bugs in handling the changes. The bug was fixed in bcbbbdb2d640c059c19e9337c7418b83b1b7e4ea and now the behavior is well-determined: updating filter regexp does trigger case sensitivity change and vice versa. However updating only regexp pattern (via QString overload or setFilterFixedString or setFilterWildcard) does not change case sensitivity. Task-number: QTBUG-85520 Change-Id: Idc41cf817de9e6263ed65a80fa40fc8415c8c856 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Andreas Buhr <andreas.buhr@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QSortFilterProxyModel: port to new property systemIvan Solovev2021-05-112-47/+192
| | | | | | | | | | filterRegularExpression and filterCaseSensitivity will be handled in a separate commit Task-number: QTBUG-85520 Change-Id: I848c5c6cbe8642efa156f4f5d33467976bbf0351 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> Reviewed-by: Andreas Buhr <andreas.buhr@qt.io>
* QAbstractProxyModel: port to new property systemIvan Solovev2021-05-043-6/+96
| | | | | | | | | | | | | | The biggest trick here is the getter (QAbstractProxyModel::sourceModel), which is returning nullptr, while internally using a global staticEmptyModel() instance. This lead to inconsistency while binding to a proxy model without source model. The bound object would point to staticEmptyModel() instance, while sourceModel() getter returns nullptr. To solve this issue a custom QBindableInterface is implemented. Task-number: QTBUG-85520 Change-Id: I597df891c7e425d51b55f50ccbacabdfe935cbac Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* QSFPM: fix filterCaseSensitivityChanged signal emission logicIvan Solovev2021-04-301-0/+4
| | | | | | | | | | | | | | | | | | This patch amends bcbbbdb2d640c059c19e9337c7418b83b1b7e4ea. It fixes the logic of filterCaseSensitivityChanged signal emission. The call to QRegularExpression overload of setFilterRegularExpression could change the filterCaseSensitivity, but the signal was never emitted. [ChangeLog][QtCore][QSortFilterProxyModel] A call to QRegularExpression overload of setFilterRegularExpression now emits a filterCaseSensitivityChanged signal, if required. Pick-to: 6.0 Pick-to: 6.1 Change-Id: Id4ef04227c1f8ed98153fa5107ec3fbe4c0c77fb Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Port of QItemSelectionModel::model to new property systemAndreas Buhr2021-04-273-24/+86
| | | | | | | | | | The property 'model' is ported to a bindable property. The properties hasSelection, selection, selectedIndexes, and currentIndex are left for later patches. Task-number: QTBUG-85520 Change-Id: Ia424ce99fc80c3d807c634c21d161a3ad94b27d2 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* Optimize quadratic-time insertion in QSortFilterProxyModelIgor Kushnir2021-04-241-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | Let N = proxy_to_source.size() before the code modified in this commit. Let M = (N - proxy_start). Let K = source_items.size(). The algorithmic complexity of the removed loop is O(N+K+K*M), assuming the number of O(N+K) reallocations is a constant. The complexity of the QList::insert and std::copy implementation is O(N+K). This is much faster in practice when K and M are of the same order of magnitude as N. For example, this quadratic complexity issue results in noticeable slowdown in the following scenario: * a QSortFilterProxyModel is used only for filtering, not sorting; * first set a filter that matches a single item in the middle of a huge number of items (about one million) - this is reasonably fast (takes about a second); * then clear the filter (i.e. set an empty filter so that no item is filtered out) and watch your application's UI freeze for a minute. The "Add QSortFilterProxyModel clear-filter benchmark" commit (with Change-Id I419a5521dd0be7676fbb09b34b4069d4a76423b1) adds a benchmark that runs much faster with this performance fix. Pick-to: 6.0 6.1 Change-Id: Ieaec173e6910f5d21eaee49402087f7711abbedf Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
* Fix case sensitivity handling QSFPMSamuel Gaist2021-04-221-24/+44
| | | | | | | | | | | | | | | | | | | | | | This patch fixes the breaking of case sensitivity handling. The removal of QRegExp killed the wrong code paths which leads to inconsistencies when changing the regular expression throuh methods like setFilterWildCard or setFilterFixedString. Changing the case sensitivity also nukes the original options that were set on the regular expression if it was set through setFilterRegularExpression. [ChangeLog][QtCore][QSortFilterProxyModel] Case sensitivity as well as regular expression options handling have been fixed. The original value is properly kept when using setFilterWildCard and setFilterFixedString. The regular expression options are now also properly kept when changing the case senstitivity through setFilterCaseSensitivity. Fixes: QTBUG-92260 Pick-to: 6.1 Pick-to: 6.0 Change-Id: Ifb4732306f0c7d79ad0b18d3f5437c4523bb40e5 Reviewed-by: Igor Kushnir <igorkuo@gmail.com> Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
* Allow proxy models access to the parent-child hierarchy of sourceLuca Beldi2021-04-195-6/+24
| | | | | | | | | | | As discussed in the related bug report, the current way proxy models access the parent-child hierarchy of the source model requires modifying Qt sources. This changes adds a method to allow easy implementation of this common feature to proxy model subclasses. Fixes: QTBUG-83911 Change-Id: Ic88d40c13c2be7b6b44fcc58118bac471a11da95 Reviewed-by: David Faure <david.faure@kdab.com>
* Fix get out of bounds index in QSortFilterProxyModel::filterAcceptsRowChunLin Wang2021-04-071-3/+5
| | | | | | | | | Before calling the index function, we need to check the validity of the parameters. Fixes: QTBUG-91878 Pick-to: 5.15 6.0 6.1 Change-Id: I9ec7265fff3f81b8a288c4ba8fae606a2ec808a6 Reviewed-by: David Faure <david.faure@kdab.com>
* Fix removing columns when QSortFilterProxyModel has not been sorted yetJoni Poikelin2021-03-251-1/+4
| | | | | | | Fixes: QTBUG-91788 Pick-to: 6.1 6.0 5.15 Change-Id: Iddcafd3171f0f3703b94893a32b4ccaaeea9e713 Reviewed-by: David Faure <david.faure@kdab.com>
* QConcatenateTablesProxyModel: skip dataChanged in hidden columnsDavid Faure2021-03-091-1/+6
| | | | | | | | | | | | | | | | When the source models don't have the same number of columns, the proxy keeps only the smallest number of columns across all source models. Afterwards, if a source model emits dataChanged in a column past that number (a "hidden" column), the proxy needs to ignore it rather than assert. But also, if the source model emits a dataChanged signal across both visible and hidden columns, then the last column number needs to be adjusted so that the signal is correctly processed and forwarded. Task-number: QTBUG-91253 Pick-to: 6.1 6.0 5.15 Change-Id: I939e8ec0faf41370472f86785851292e4372f72c Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
* Fix build of Core module without regularexpression featureAlexey Edelev2021-03-042-13/+1
| | | | | | | | | | | | | | | | | | qregularexpression.h requires FEATURE_regularexpression to be enabled. Add a condition to the 'qt_pch.h' header to fix the build when PCH are enabled and FEATURE_regularexpression is disabled. It seems that the filter implementation of QSortFilterProxyModel has QRegularExpression as its base. It's necessary to make sortfilterproxymodel dependent on the regularexpression feature. Fix the precompiler condition for the extractSections function in the QString implementation. Use the same precompiler condition for the QString::section and extractSections functions, since QString::section depends on extractSections. Change-Id: I5b775e0842a0aa1a8d47f8dded376bdfcf63b5bf Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
* Replace some more erase/remove patterns with removeIfGiuseppe D'Angelo2021-01-101-4/+1
| | | | | Change-Id: I6c6f33450fbfd798e5ef71a8ba18f590581dc3a2 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
* Remove the qmake project filesJoerg Bornemann2021-01-071-63/+0
| | | | | | | | | | | | | | | | Remove the qmake project files for most of Qt. Leave the qmake project files for examples, because we still test those in the CI to ensure qmake does not regress. Also leave the qmake project files for utils and other minor parts that lack CMake project files. Task-number: QTBUG-88742 Change-Id: I6cdf059e6204816f617f9624f3ea9822703f73cc Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Kai Koehne <kai.koehne@qt.io>
* Use (new) erase()/erase_if() algorithmsMarc Mutz2020-12-051-7/+2
| | | | | Change-Id: I45c18fd45c20b226e44d16315e3ebb6c305d4ab0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Dont' return a const ref to QModelIndexLars Knoll2020-12-042-6/+5
| | | | | | | | | | | The conversion operator from QPMI to QModelIndex should return by value, to hide implementation details and so that we don't have to rely on a static empty QModelIndex. Change-Id: I92b3f8451422f2b69bf31f28b387a124fd24ec46 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> (cherry picked from commit 0cd2935ed9d772f0eb06d03201baabd60764ec80) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>