Hello community,

here is the log from the commit of package kitemmodels for openSUSE:Factory 
checked in at 2015-09-02 07:46:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kitemmodels (Old)
 and      /work/SRC/openSUSE:Factory/.kitemmodels.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kitemmodels"

Changes:
--------
--- /work/SRC/openSUSE:Factory/kitemmodels/kitemmodels.changes  2015-07-14 
17:28:10.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.kitemmodels.new/kitemmodels.changes     
2015-09-02 07:46:40.000000000 +0200
@@ -1,0 +2,13 @@
+Tue Aug  4 19:20:32 UTC 2015 - hrvoje.sen...@gmail.com
+
+- Update to 5.13.0
+  * The Qt version requirement has been bumped from 5.2 to 5.3
+  * Debug output has been ported to categorized output, for less
+    noise by default
+  * Docbook documentation has been reviewed and updated
+  * New proxy: KExtraColumnsProxyModel, allows to add columns to
+    an existing model.
+  * For more details please see:
+    https://www.kde.org/announcements/kde-frameworks-5.13.0.php
+
+-------------------------------------------------------------------

Old:
----
  kitemmodels-5.12.0.tar.xz

New:
----
  kitemmodels-5.13.0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kitemmodels.spec ++++++
--- /var/tmp/diff_new_pack.WQKJtF/_old  2015-09-02 07:46:41.000000000 +0200
+++ /var/tmp/diff_new_pack.WQKJtF/_new  2015-09-02 07:46:41.000000000 +0200
@@ -17,15 +17,15 @@
 
 
 %define lname   libKF5ItemModels5
-%define _tar_path 5.12
+%define _tar_path 5.13
 Name:           kitemmodels
-Version:        5.12.0
+Version:        5.13.0
 Release:        0
 BuildRequires:  cmake >= 2.8.12
 BuildRequires:  extra-cmake-modules >= %{_tar_path}
 BuildRequires:  fdupes
 BuildRequires:  kf5-filesystem
-BuildRequires:  pkgconfig(Qt5Core) >= 5.2.0
+BuildRequires:  cmake(Qt5Core) >= 5.3.0
 Summary:        Set of item models extending the Qt model-view framework
 License:        LGPL-2.1+
 Group:          System/GUI/KDE
@@ -50,7 +50,7 @@
 Group:          Development/Libraries/KDE
 Requires:       %lname = %{version}
 Requires:       extra-cmake-modules
-Requires:       pkgconfig(Qt5Core) >= 5.2.0
+Requires:       cmake(Qt5Core) >= 5.3.0
 
 %description devel
 KItemModels provides a set of item models extending the Qt model-view 
framework.

++++++ kitemmodels-5.12.0.tar.xz -> kitemmodels-5.13.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitemmodels-5.12.0/CMakeLists.txt 
new/kitemmodels-5.13.0/CMakeLists.txt
--- old/kitemmodels-5.12.0/CMakeLists.txt       2015-07-04 22:37:34.000000000 
+0200
+++ new/kitemmodels-5.13.0/CMakeLists.txt       2015-08-01 14:41:18.000000000 
+0200
@@ -3,7 +3,7 @@
 project(KItemModels)
 
 include(FeatureSummary)
-find_package(ECM 5.12.0  NO_MODULE)
+find_package(ECM 5.13.0  NO_MODULE)
 set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake 
Modules." URL 
"https://projects.kde.org/projects/kdesupport/extra-cmake-modules";)
 feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND 
FATAL_ON_MISSING_REQUIRED_PACKAGES)
 
@@ -14,7 +14,7 @@
 include(KDEFrameworkCompilerSettings)
 include(KDECMakeSettings)
 
-set(REQUIRED_QT_VERSION 5.2.0)
+set(REQUIRED_QT_VERSION 5.3.0)
 find_package(Qt5Core ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
 
 
@@ -23,7 +23,7 @@
 include(ECMSetupVersion)
 include(ECMGenerateHeaders)
 
-set(KF5_VERSION "5.12.0") # handled by release scripts
+set(KF5_VERSION "5.13.0") # handled by release scripts
 
 ecm_setup_version(${KF5_VERSION} VARIABLE_PREFIX KITEMMODELS
                         VERSION_HEADER 
"${CMAKE_CURRENT_BINARY_DIR}/kitemmodels_version.h"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitemmodels-5.12.0/README.md 
new/kitemmodels-5.13.0/README.md
--- old/kitemmodels-5.12.0/README.md    2015-07-04 22:37:34.000000000 +0200
+++ new/kitemmodels-5.13.0/README.md    2015-08-01 14:41:18.000000000 +0200
@@ -10,6 +10,7 @@
   breadcrumbs
 * KCheckableProxyModel - Adds a checkable capability to a source model
 * KDescendantsProxyModel - Proxy Model for restructuring a Tree into a list
+* KExtraColumnsProxyModel - Adds columns after existing columns
 * KLinkItemSelectionModel - Share a selection in multiple views which do not
   have the same source model
 * KModelIndexProxyMapper - Mapping of indexes and selections through proxy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitemmodels-5.12.0/autotests/CMakeLists.txt 
new/kitemmodels-5.13.0/autotests/CMakeLists.txt
--- old/kitemmodels-5.12.0/autotests/CMakeLists.txt     2015-07-04 
22:37:34.000000000 +0200
+++ new/kitemmodels-5.13.0/autotests/CMakeLists.txt     2015-08-01 
14:41:18.000000000 +0200
@@ -16,6 +16,7 @@
 
 ecm_add_tests(
   kdescendantsproxymodel_smoketest.cpp
+  kextracolumnsproxymodeltest.cpp
   klinkitemselectionmodeltest.cpp
   testmodelqueuedconnections.cpp
   kselectionproxymodeltest.cpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kitemmodels-5.12.0/autotests/kextracolumnsproxymodeltest.cpp 
new/kitemmodels-5.13.0/autotests/kextracolumnsproxymodeltest.cpp
--- old/kitemmodels-5.12.0/autotests/kextracolumnsproxymodeltest.cpp    
1970-01-01 01:00:00.000000000 +0100
+++ new/kitemmodels-5.13.0/autotests/kextracolumnsproxymodeltest.cpp    
2015-08-01 14:41:18.000000000 +0200
@@ -0,0 +1,339 @@
+/*
+    Copyright (c) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, 
i...@kdab.com
+    Authors: David Faure <david.fa...@kdab.com>
+
+    This library is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Library General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    This library is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+    License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to the
+    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+*/
+
+#include <QSignalSpy>
+#include <QSortFilterProxyModel>
+#include <QTest>
+#include <QDebug>
+#include <QStandardItemModel>
+
+#include <QTreeView>
+
+#include <kextracolumnsproxymodel.h>
+#include "test_model_helpers.h"
+using namespace TestModelHelpers;
+
+Q_DECLARE_METATYPE(QModelIndex)
+
+class tst_KExtraColumnsProxyModel : public QObject
+{
+    Q_OBJECT
+
+private:
+    class NoExtraColumns : public KExtraColumnsProxyModel
+    {
+        QVariant extraColumnData(const QModelIndex &, int, int, int) const 
Q_DECL_OVERRIDE
+        {
+            Q_ASSERT(0);
+            return QVariant();
+        }
+    };
+
+    class TwoExtraColumnsProxyModel : public KExtraColumnsProxyModel
+    {
+    public:
+        TwoExtraColumnsProxyModel() : KExtraColumnsProxyModel(), 
m_extraColumnData('Z')
+        {
+            appendColumn("H5");
+            appendColumn("H6");
+        }
+        QVariant extraColumnData(const QModelIndex &, int row, int 
extraColumn, int role) const Q_DECL_OVERRIDE
+        {
+            Q_ASSERT(role == Qt::DisplayRole);
+            switch (extraColumn) {
+            case 0:
+                return QString(m_extraColumnData);
+            case 1:
+                return QString::number(row);
+            default:
+                Q_ASSERT(0);
+                return QVariant();
+            }
+        }
+        bool setExtraColumnData(const QModelIndex &parent, int row, int 
extraColumn, const QVariant &data, int role) Q_DECL_OVERRIDE {
+            if (extraColumn == 0 && role == Qt::EditRole)
+            {
+                m_extraColumnData = data.toString().at(0);
+                extraColumnDataChanged(QModelIndex(), 0, extraColumn, 
QVector<int>() << Qt::EditRole);
+                return true;
+            }
+            return KExtraColumnsProxyModel::setExtraColumnData(parent, row, 
extraColumn, data, role);
+        }
+        void changeExtraColumnData() {
+            m_extraColumnData = '<';
+            extraColumnDataChanged(QModelIndex(), 0, 0, QVector<int>() << 
Qt::EditRole);
+        }
+    private:
+        QChar m_extraColumnData;
+    };
+
+private Q_SLOTS:
+
+    void initTestCase()
+    {
+        qRegisterMetaType<QModelIndex>();
+    }
+
+    void init()
+    {
+        // Prepare the source model to use later on
+        mod.clear();
+        mod.appendRow(makeStandardItems(QStringList() << "A" << "B" << "C" << 
"D"));
+        mod.item(0, 0)->appendRow(makeStandardItems(QStringList() << "m" << 
"n" << "o" << "p"));
+        mod.item(0, 0)->appendRow(makeStandardItems(QStringList() << "q" << 
"r" << "s" << "t"));
+        mod.appendRow(makeStandardItems(QStringList() << "E" << "F" << "G" << 
"H"));
+        mod.item(1, 0)->appendRow(makeStandardItems(QStringList() << "x" << 
"y" << "z" << "."));
+        mod.setHorizontalHeaderLabels(QStringList() << "H1" << "H2" << "H3" << 
"H4");
+
+        QCOMPARE(extractRowTexts(&mod, 0), QString("ABCD"));
+        QCOMPARE(extractRowTexts(&mod, 0, mod.index(0, 0)), QString("mnop"));
+        QCOMPARE(extractRowTexts(&mod, 1, mod.index(0, 0)), QString("qrst"));
+        QCOMPARE(extractRowTexts(&mod, 1), QString("EFGH"));
+        QCOMPARE(extractRowTexts(&mod, 0, mod.index(1, 0)), QString("xyz."));
+        QCOMPARE(extractHorizontalHeaderTexts(&mod), QString("H1H2H3H4"));
+
+        // test code to see the model
+        // showModel(&mod);
+    }
+
+    void shouldDoNothingIfNoExtraColumns()
+    {
+        // Given a extra-columns proxy
+        NoExtraColumns pm;
+
+        // When setting it to a source model
+        pm.setSourceModel(&mod);
+
+        // Then the proxy should show the same as the model
+        QCOMPARE(pm.rowCount(), mod.rowCount());
+        QCOMPARE(pm.columnCount(), mod.columnCount());
+
+        QCOMPARE(pm.rowCount(pm.index(0, 0)), 2);
+        QCOMPARE(pm.index(0, 0).parent(), QModelIndex());
+
+        // (verify that the mapFromSource(mapToSource(x)) == x roundtrip works)
+        for (int row = 0; row < pm.rowCount(); ++row) {
+            for (int col = 0; col < pm.columnCount(); ++col) {
+                QCOMPARE(pm.mapFromSource(pm.mapToSource(pm.index(row, col))), 
pm.index(row, col));
+            }
+        }
+
+        QCOMPARE(extractRowTexts(&pm, 0), QString("ABCD"));
+        QCOMPARE(extractRowTexts(&pm, 0, pm.index(0, 0)), QString("mnop"));
+        QCOMPARE(extractRowTexts(&pm, 1, pm.index(0, 0)), QString("qrst"));
+        QCOMPARE(extractRowTexts(&pm, 1), QString("EFGH"));
+        QCOMPARE(extractRowTexts(&pm, 0, pm.index(1, 0)), QString("xyz."));
+        QCOMPARE(extractHorizontalHeaderTexts(&pm), QString("H1H2H3H4"));
+    }
+
+    void shouldShowExtraColumns()
+    {
+        // Given a extra-columns proxy with two extra columns
+        TwoExtraColumnsProxyModel pm;
+
+        // When setting it to a source model
+        pm.setSourceModel(&mod);
+
+        // Then the proxy should show the extra column
+        QCOMPARE(extractRowTexts(&pm, 0), QString("ABCDZ0"));
+        QCOMPARE(extractRowTexts(&pm, 0, pm.index(0, 0)), QString("mnopZ0"));
+        QCOMPARE(extractRowTexts(&pm, 1, pm.index(0, 0)), QString("qrstZ1"));
+        QCOMPARE(extractRowTexts(&pm, 1), QString("EFGHZ1"));
+        QCOMPARE(extractRowTexts(&pm, 0, pm.index(1, 0)), QString("xyz.Z0"));
+        QCOMPARE(extractHorizontalHeaderTexts(&pm), QString("H1H2H3H4H5H6"));
+
+        // Verify tree structure of proxy
+        const QModelIndex secondParent = pm.index(1, 0);
+        QVERIFY(!secondParent.parent().isValid());
+        QCOMPARE(indexToText(pm.index(0, 0, secondParent).parent()), 
indexToText(secondParent));
+        QCOMPARE(indexToText(pm.index(0, 3, secondParent).parent()), 
indexToText(secondParent));
+        QVERIFY(indexToText(pm.index(0, 4)).startsWith("0,4,"));
+        QCOMPARE(indexToText(pm.index(0, 4, secondParent).parent()), 
indexToText(secondParent));
+        QVERIFY(indexToText(pm.index(0, 5)).startsWith("0,5,"));
+        QCOMPARE(indexToText(pm.index(0, 5, secondParent).parent()), 
indexToText(secondParent));
+
+        QVERIFY(!pm.canFetchMore(QModelIndex()));
+    }
+
+    void shouldHandleDataChanged()
+    {
+        // Given a extra-columns proxy, with two extra columns
+        TwoExtraColumnsProxyModel pm;
+        setup(pm);
+        QSignalSpy dataChangedSpy(&pm, 
SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+        // When a cell in a source model changes
+        mod.item(0, 2)->setData("c", Qt::EditRole);
+
+        // Then the change should be notified to the proxy
+        QCOMPARE(dataChangedSpy.count(), 1);
+        QCOMPARE(dataChangedSpy.at(0).at(0).value<QModelIndex>(), pm.index(0, 
2));
+        QCOMPARE(extractRowTexts(&pm, 0), QString("ABcDZ0"));
+    }
+
+    void shouldHandleDataChangedInExtraColumn()
+    {
+        // Given a extra-columns proxy, with two extra columns
+        TwoExtraColumnsProxyModel pm;
+        setup(pm);
+        QSignalSpy dataChangedSpy(&pm, 
SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+        // When the proxy wants to signal a change in an extra column
+        pm.changeExtraColumnData();
+
+        // Then the change should be available and notified
+        QCOMPARE(extractRowTexts(&pm, 0), QString("ABCD<0"));
+        QCOMPARE(dataChangedSpy.count(), 1);
+        QCOMPARE(dataChangedSpy.at(0).at(0).value<QModelIndex>(), pm.index(0, 
4));
+    }
+
+    void shouldHandleSetDataInNormalColumn()
+    {
+        // Given a extra-columns proxy, with two extra columns
+        TwoExtraColumnsProxyModel pm;
+        setup(pm);
+        QSignalSpy dataChangedSpy(&pm, 
SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+        // When editing a cell in the proxy
+        QVERIFY(pm.setData(pm.index(0, 2), "c", Qt::EditRole));
+
+        // Then the change should be available and notified
+        QCOMPARE(extractRowTexts(&pm, 0), QString("ABcDZ0"));
+        QCOMPARE(dataChangedSpy.count(), 1);
+        QCOMPARE(dataChangedSpy.at(0).at(0).value<QModelIndex>(), pm.index(0, 
2));
+    }
+
+    void shouldHandleSetDataInExtraColumn()
+    {
+        // Given a extra-columns proxy, with two extra columns
+        TwoExtraColumnsProxyModel pm;
+        setup(pm);
+        QSignalSpy dataChangedSpy(&pm, 
SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+        // When editing a cell in the proxy
+        QVERIFY(pm.setData(pm.index(0, 4), "-", Qt::EditRole));
+
+        // Then the change should be available and notified
+        QCOMPARE(extractRowTexts(&pm, 0), QString("ABCD-0"));
+        QCOMPARE(dataChangedSpy.count(), 1);
+        QCOMPARE(dataChangedSpy.at(0).at(0).value<QModelIndex>(), pm.index(0, 
4));
+    }
+
+    void shouldHandleRowInsertion()
+    {
+        // Given a extra-columns proxy, with two extra columns
+        TwoExtraColumnsProxyModel pm;
+        setup(pm);
+
+        QSignalSpy rowATBISpy(&pm, 
SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+        QSignalSpy rowInsertedSpy(&pm, 
SIGNAL(rowsInserted(QModelIndex,int,int)));
+
+        // When a source model inserts a new (child) row
+        mod.item(1, 0)->appendRow(makeStandardItems(QStringList() << "1" << 
"2" << "3" << "4"));
+
+        // Then the proxy should notify its users and show changes
+        QCOMPARE(rowSpyToText(rowATBISpy), QString("1,1"));
+        QCOMPARE(rowSpyToText(rowInsertedSpy), QString("1,1"));
+        QCOMPARE(pm.rowCount(), 2);
+        QCOMPARE(extractRowTexts(&pm, 0), QString("ABCDZ0"));
+        QCOMPARE(extractRowTexts(&pm, 0, pm.index(0, 0)), QString("mnopZ0"));
+        QCOMPARE(extractRowTexts(&pm, 1, pm.index(0, 0)), QString("qrstZ1"));
+        QCOMPARE(extractRowTexts(&pm, 1), QString("EFGHZ1"));
+        QCOMPARE(extractRowTexts(&pm, 0, pm.index(1, 0)), QString("xyz.Z0"));
+        QCOMPARE(extractRowTexts(&pm, 1, pm.index(1, 0)), QString("1234Z1"));
+        QCOMPARE(extractHorizontalHeaderTexts(&pm), QString("H1H2H3H4H5H6"));
+    }
+
+    void shouldHandleColumnInsertion()
+    {
+        // Given a extra-columns proxy, with two extra columns
+        TwoExtraColumnsProxyModel pm;
+        setup(pm);
+
+        QCOMPARE(pm.columnCount(), 6);
+        QCOMPARE(mod.columnCount(), 4);
+
+        QSignalSpy colATBISpy(&pm, 
SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)));
+        QSignalSpy colInsertedSpy(&pm, 
SIGNAL(columnsInserted(QModelIndex,int,int)));
+
+        // When a source model inserts a new column
+        mod.setColumnCount(5); // like QStandardItem::setChild does
+        QCOMPARE(mod.columnCount(), 5);
+        // QStandardItemModel is quite dumb, it records the number of columns 
in each item
+        for (int row = 0; row < mod.rowCount(); ++row) {
+            mod.item(row, 0)->setColumnCount(5);
+        }
+
+        // Then the proxy should notify its users and show changes
+        QCOMPARE(rowSpyToText(colATBISpy), QString("4,4;4,4;4,4")); // 
QStandardItemModel emits it for each parent
+        QCOMPARE(rowSpyToText(colInsertedSpy), QString("4,4;4,4;4,4"));
+        QCOMPARE(pm.columnCount(), 7);
+        QCOMPARE(extractRowTexts(&pm, 0), QString("ABCD Z0"));
+        QCOMPARE(extractRowTexts(&pm, 0, pm.index(0, 0)), QString("mnop Z0"));
+        QCOMPARE(extractRowTexts(&pm, 1, pm.index(0, 0)), QString("qrst Z1"));
+        QCOMPARE(extractRowTexts(&pm, 1), QString("EFGH Z1"));
+        QCOMPARE(extractRowTexts(&pm, 0, pm.index(1, 0)), QString("xyz. Z0"));
+        QCOMPARE(extractHorizontalHeaderTexts(&pm), QString("H1H2H3H45H5H6")); 
// '5' was inserted in there
+    }
+
+    // row removal, layoutChanged, modelReset -> same thing, works via 
QIdentityProxyModel
+    // missing: test for mapSelectionToSource
+
+    void shouldHandleLayoutChanged()
+    {
+        // Given a extra-columns proxy, with two extra columns
+        TwoExtraColumnsProxyModel pm;
+        // And a QSFPM underneath
+        QSortFilterProxyModel proxy;
+        proxy.setSourceModel(&mod);
+        pm.setSourceModel(&proxy);
+        // And a selection
+        QItemSelectionModel selection(&pm);
+        selection.select(pm.index(0, 0), QItemSelectionModel::Select | 
QItemSelectionModel::Rows);
+
+        // When sorting
+        pm.sort(0, Qt::DescendingOrder);
+        QCOMPARE(extractRowTexts(&pm, 0), QString("EFGHZ0"));
+        QCOMPARE(extractRowTexts(&pm, 1), QString("ABCDZ1"));
+    }
+
+private:
+
+    void setup(KExtraColumnsProxyModel &pm)
+    {
+        pm.setSourceModel(&mod);
+    }
+
+    static QString indexToText(const QModelIndex &index)
+    {
+        if (!index.isValid()) {
+            return "invalid";
+        }
+        return QString::number(index.row()) + "," + 
QString::number(index.column()) + ","
+               + 
QString::number(reinterpret_cast<qulonglong>(index.internalPointer()), 16)
+               + " in " + 
QString::number(reinterpret_cast<qulonglong>(index.model()), 16);
+    }
+
+    QStandardItemModel mod;
+};
+
+QTEST_MAIN(tst_KExtraColumnsProxyModel)
+
+#include "kextracolumnsproxymodeltest.moc"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitemmodels-5.12.0/autotests/test_model_helpers.h 
new/kitemmodels-5.13.0/autotests/test_model_helpers.h
--- old/kitemmodels-5.12.0/autotests/test_model_helpers.h       2015-07-04 
22:37:34.000000000 +0200
+++ new/kitemmodels-5.13.0/autotests/test_model_helpers.h       2015-08-01 
14:41:18.000000000 +0200
@@ -58,5 +58,20 @@
     return result;
 }
 
+inline QString rowSpyToText(const QSignalSpy &spy)
+{
+    if (!spy.isValid()) {
+        return QString::fromLatin1("THE SIGNALSPY IS INVALID!");
+    }
+    QString str;
+    for (int i = 0; i < spy.count(); ++i) {
+        str += spy.at(i).at(1).toString() + ',' + spy.at(i).at(2).toString();
+        if (i + 1 < spy.count()) {
+            str += QLatin1Char(';');
+        }
+    }
+    return str;
+}
+
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitemmodels-5.12.0/src/CMakeLists.txt 
new/kitemmodels-5.13.0/src/CMakeLists.txt
--- old/kitemmodels-5.12.0/src/CMakeLists.txt   2015-07-04 22:37:34.000000000 
+0200
+++ new/kitemmodels-5.13.0/src/CMakeLists.txt   2015-08-01 14:41:18.000000000 
+0200
@@ -3,6 +3,7 @@
   kbreadcrumbselectionmodel.cpp
   kcheckableproxymodel.cpp
   kdescendantsproxymodel.cpp
+  kextracolumnsproxymodel.cpp
   klinkitemselectionmodel.cpp
   kmodelindexproxymapper.cpp
   krearrangecolumnsproxymodel.cpp
@@ -27,6 +28,7 @@
   HEADER_NAMES
   KBreadcrumbSelectionModel
   KCheckableProxyModel
+  KExtraColumnsProxyModel
   KLinkItemSelectionModel
   KRearrangeColumnsProxyModel
   KRecursiveFilterProxyModel
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitemmodels-5.12.0/src/kextracolumnsproxymodel.cpp 
new/kitemmodels-5.13.0/src/kextracolumnsproxymodel.cpp
--- old/kitemmodels-5.12.0/src/kextracolumnsproxymodel.cpp      1970-01-01 
01:00:00.000000000 +0100
+++ new/kitemmodels-5.13.0/src/kextracolumnsproxymodel.cpp      2015-08-01 
14:41:18.000000000 +0200
@@ -0,0 +1,315 @@
+/*
+    Copyright (c) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, 
i...@kdab.com
+    Authors: David Faure <david.fa...@kdab.com>
+
+    This library is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Library General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    This library is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+    License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to the
+    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+*/
+
+#include "kextracolumnsproxymodel.h"
+#include <QItemSelection>
+#include <QDebug>
+
+class KExtraColumnsProxyModelPrivate
+{
+    Q_DECLARE_PUBLIC(KExtraColumnsProxyModel)
+    KExtraColumnsProxyModel *const q_ptr;
+
+public:
+    KExtraColumnsProxyModelPrivate(KExtraColumnsProxyModel *model)
+        : q_ptr(model)
+    {
+    }
+
+    void _ec_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> 
&sourceParents, QAbstractItemModel::LayoutChangeHint hint);
+    void _ec_sourceLayoutChanged(const QList<QPersistentModelIndex> 
&sourceParents, QAbstractItemModel::LayoutChangeHint hint);
+
+    // Configuration (doesn't change once source model is plugged in)
+    QVector<QString> m_extraHeaders;
+
+    // for layoutAboutToChanged/layoutChanged
+    QVector<QPersistentModelIndex> layoutChangePersistentIndexes;
+    QVector<int> layoutChangeProxyColumns;
+    QModelIndexList proxyIndexes;
+};
+
+KExtraColumnsProxyModel::KExtraColumnsProxyModel(QObject *parent)
+    : QIdentityProxyModel(parent),
+      d_ptr(new KExtraColumnsProxyModelPrivate(this))
+{
+}
+
+KExtraColumnsProxyModel::~KExtraColumnsProxyModel()
+{
+}
+
+void KExtraColumnsProxyModel::appendColumn(const QString &header)
+{
+    Q_D(KExtraColumnsProxyModel);
+    d->m_extraHeaders.append(header);
+}
+
+bool KExtraColumnsProxyModel::setExtraColumnData(const QModelIndex &parent, 
int row, int extraColumn, const QVariant &data, int role)
+{
+    Q_UNUSED(parent);
+    Q_UNUSED(row);
+    Q_UNUSED(extraColumn);
+    Q_UNUSED(data);
+    Q_UNUSED(role);
+    return false;
+}
+
+void KExtraColumnsProxyModel::extraColumnDataChanged(const QModelIndex 
&parent, int row, int extraColumn, const QVector<int> & roles)
+{
+    const QModelIndex idx = index(row, proxyColumnForExtraColumn(extraColumn), 
parent);
+    emit dataChanged(idx, idx, roles);
+}
+
+void KExtraColumnsProxyModel::setSourceModel(QAbstractItemModel *model)
+{
+    if (sourceModel()) {
+        disconnect(sourceModel(), 
SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
+                this, 
SLOT(_ec_sourceLayoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
+        disconnect(sourceModel(), 
SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
+                this, 
SLOT(_ec_sourceLayoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
+    }
+
+    QIdentityProxyModel::setSourceModel(model);
+
+    if (model) {
+        // The handling of persistent model indexes assumes mapToSource can be 
called for any index
+        // This breaks for the extra column, so we'll have to do it ourselves
+        disconnect(model, 
SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
+                this, 
SLOT(_q_sourceLayoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
+        disconnect(model, 
SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
+                this, 
SLOT(_q_sourceLayoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
+        connect(model, 
SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
+                this, 
SLOT(_ec_sourceLayoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
+        connect(model, 
SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
+                this, 
SLOT(_ec_sourceLayoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
+    }
+}
+
+QModelIndex KExtraColumnsProxyModel::mapToSource(const QModelIndex 
&proxyIndex) const
+{
+    if (!proxyIndex.isValid()) { // happens in e.g. 
rowCount(mapToSource(parent))
+        return QModelIndex();
+    }
+    const int column = proxyIndex.column();
+    if (column >= sourceModel()->columnCount()) {
+        qDebug() << "Returning invalid index in mapToSource";
+        return QModelIndex();
+    }
+    return QIdentityProxyModel::mapToSource(proxyIndex);
+}
+
+QModelIndex KExtraColumnsProxyModel::sibling(int row, int column, const 
QModelIndex &idx) const
+{
+    if (idx.column() >= sourceModel()->columnCount()) {
+        return index(row, column, parent(idx));
+    }
+    return mapFromSource(sourceModel()->sibling(row, column, 
mapToSource(idx)));
+}
+
+QItemSelection KExtraColumnsProxyModel::mapSelectionToSource(const 
QItemSelection &selection) const
+{
+    Q_D(const KExtraColumnsProxyModel);
+    QItemSelection sourceSelection;
+
+    if (!sourceModel()) {
+        return sourceSelection;
+    }
+
+    // mapToSource will give invalid index for our additional columns, so 
truncate the selection
+    // to the columns known by the source model
+    const int sourceColumnCount = sourceModel()->columnCount();
+    QItemSelection::const_iterator it = selection.constBegin();
+    const QItemSelection::const_iterator end = selection.constEnd();
+    for (; it != end; ++it) {
+        Q_ASSERT(it->model() == this);
+        QModelIndex topLeft = it->topLeft();
+        Q_ASSERT(topLeft.isValid());
+        Q_ASSERT(topLeft.model() == this);
+        topLeft = topLeft.sibling(topLeft.row(), 0);
+        QModelIndex bottomRight = it->bottomRight();
+        Q_ASSERT(bottomRight.isValid());
+        Q_ASSERT(bottomRight.model() == this);
+        if (bottomRight.column() >= sourceColumnCount) {
+            bottomRight = bottomRight.sibling(bottomRight.row(), 
sourceColumnCount - 1);
+        }
+        // This can lead to duplicate source indexes, so use merge().
+        const QItemSelectionRange range(mapToSource(topLeft), 
mapToSource(bottomRight));
+        QItemSelection newSelection; newSelection << range;
+        sourceSelection.merge(newSelection, QItemSelectionModel::Select);
+    }
+
+    return sourceSelection;
+}
+
+int KExtraColumnsProxyModel::columnCount(const QModelIndex &parent) const
+{
+    Q_D(const KExtraColumnsProxyModel);
+    return QIdentityProxyModel::columnCount(parent) + 
d->m_extraHeaders.count();
+}
+
+QVariant KExtraColumnsProxyModel::data(const QModelIndex &index, int role) 
const
+{
+    Q_D(const KExtraColumnsProxyModel);
+    const int extraCol = extraColumnForProxyColumn(index.column());
+    if (extraCol >= 0 && !d->m_extraHeaders.isEmpty()) {
+        return extraColumnData(index.parent(), index.row(), extraCol, role);
+    }
+    return sourceModel()->data(mapToSource(index), role);
+}
+
+bool KExtraColumnsProxyModel::setData(const QModelIndex &index, const QVariant 
&value, int role)
+{
+    Q_D(const KExtraColumnsProxyModel);
+    const int extraCol = extraColumnForProxyColumn(index.column());
+    if (extraCol >= 0 && !d->m_extraHeaders.isEmpty()) {
+        return setExtraColumnData(index.parent(), index.row(), extraCol, 
value, role);
+    }
+    return sourceModel()->setData(mapToSource(index), value, role);
+}
+
+Qt::ItemFlags KExtraColumnsProxyModel::flags(const QModelIndex &index) const
+{
+    const int extraCol = extraColumnForProxyColumn(index.column());
+    if (extraCol >= 0) {
+        // extra columns are readonly
+        return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+    }
+    return sourceModel()->flags(mapToSource(index));
+}
+
+QVariant KExtraColumnsProxyModel::headerData(int section, Qt::Orientation 
orientation, int role) const
+{
+    Q_D(const KExtraColumnsProxyModel);
+    if (orientation == Qt::Horizontal) {
+        const int extraCol = extraColumnForProxyColumn(section);
+        if (extraCol >= 0) {
+            // Only text is supported, in headers for extra columns
+            if (role == Qt::DisplayRole) {
+                return d->m_extraHeaders.at(extraCol);
+            }
+            return QVariant();
+        }
+    }
+    return QIdentityProxyModel::headerData(section, orientation, role);
+}
+
+QModelIndex KExtraColumnsProxyModel::index(int row, int column, const 
QModelIndex &parent) const
+{
+    const int extraCol = extraColumnForProxyColumn(column);
+    if (extraCol >= 0) {
+        // We store the internal pointer of the index for column 0 in the 
proxy index for extra columns.
+        // This will be useful in the parent method.
+        return createIndex(row, column, QIdentityProxyModel::index(row, 0, 
parent).internalPointer());
+    }
+    return QIdentityProxyModel::index(row, column, parent);
+}
+
+QModelIndex KExtraColumnsProxyModel::parent(const QModelIndex &child) const
+{
+    const int extraCol = extraColumnForProxyColumn(child.column());
+    if (extraCol >= 0) {
+        // Create an index for column 0 and use that to get the parent.
+        const QModelIndex proxySibling = createIndex(child.row(), 0, 
child.internalPointer());
+        return QIdentityProxyModel::parent(proxySibling);
+    }
+    return QIdentityProxyModel::parent(child);
+}
+
+int KExtraColumnsProxyModel::extraColumnForProxyColumn(int proxyColumn) const
+{
+    const int sourceColumnCount = sourceModel()->columnCount();
+    if (proxyColumn >= sourceColumnCount) {
+        return proxyColumn - sourceColumnCount;
+    }
+    return -1;
+}
+
+int KExtraColumnsProxyModel::proxyColumnForExtraColumn(int extraColumn) const
+{
+    return sourceModel()->columnCount() + extraColumn;
+}
+
+void KExtraColumnsProxyModelPrivate::_ec_sourceLayoutAboutToBeChanged(const 
QList<QPersistentModelIndex> &sourceParents, 
QAbstractItemModel::LayoutChangeHint hint)
+{
+    Q_Q(KExtraColumnsProxyModel);
+    const QModelIndexList persistentIndexList = q->persistentIndexList();
+    layoutChangePersistentIndexes.reserve(persistentIndexList.size());
+    layoutChangeProxyColumns.reserve(persistentIndexList.size());
+
+    foreach (QPersistentModelIndex proxyPersistentIndex, persistentIndexList) {
+        proxyIndexes << proxyPersistentIndex;
+        Q_ASSERT(proxyPersistentIndex.isValid());
+        const int column = proxyPersistentIndex.column();
+        layoutChangeProxyColumns << column;
+        if (column >= q->sourceModel()->columnCount()) {
+            proxyPersistentIndex = 
proxyPersistentIndex.sibling(proxyPersistentIndex.row(), 0);
+        }
+        const QPersistentModelIndex srcPersistentIndex = 
q->mapToSource(proxyPersistentIndex);
+        Q_ASSERT(srcPersistentIndex.isValid());
+        layoutChangePersistentIndexes << srcPersistentIndex;
+    }
+
+    QList<QPersistentModelIndex> parents;
+    parents.reserve(sourceParents.size());
+    foreach (const QPersistentModelIndex &parent, sourceParents) {
+        if (!parent.isValid()) {
+            parents << QPersistentModelIndex();
+            continue;
+        }
+        const QModelIndex mappedParent = q->mapFromSource(parent);
+        Q_ASSERT(mappedParent.isValid());
+        parents << mappedParent;
+    }
+
+    emit q->layoutAboutToBeChanged(parents, hint);
+}
+
+void KExtraColumnsProxyModelPrivate::_ec_sourceLayoutChanged(const 
QList<QPersistentModelIndex> &sourceParents, 
QAbstractItemModel::LayoutChangeHint hint)
+{
+    Q_Q(KExtraColumnsProxyModel);
+    for (int i = 0; i < proxyIndexes.size(); ++i) {
+        const QModelIndex proxyIdx = proxyIndexes.at(i);
+        QModelIndex newProxyIdx = 
q->mapFromSource(layoutChangePersistentIndexes.at(i));
+        if (proxyIdx.column() >= q->sourceModel()->columnCount()) {
+            newProxyIdx = newProxyIdx.sibling(newProxyIdx.row(), 
layoutChangeProxyColumns.at(i));
+        }
+        q->changePersistentIndex(proxyIdx, newProxyIdx);
+    }
+
+    layoutChangePersistentIndexes.clear();
+    layoutChangeProxyColumns.clear();
+    proxyIndexes.clear();
+
+    QList<QPersistentModelIndex> parents;
+    parents.reserve(sourceParents.size());
+    foreach (const QPersistentModelIndex &parent, sourceParents) {
+        if (!parent.isValid()) {
+            parents << QPersistentModelIndex();
+            continue;
+        }
+        const QModelIndex mappedParent = q->mapFromSource(parent);
+        Q_ASSERT(mappedParent.isValid());
+        parents << mappedParent;
+    }
+
+    emit q->layoutChanged(parents, hint);
+}
+
+#include "moc_kextracolumnsproxymodel.cpp"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kitemmodels-5.12.0/src/kextracolumnsproxymodel.h 
new/kitemmodels-5.13.0/src/kextracolumnsproxymodel.h
--- old/kitemmodels-5.12.0/src/kextracolumnsproxymodel.h        1970-01-01 
01:00:00.000000000 +0100
+++ new/kitemmodels-5.13.0/src/kextracolumnsproxymodel.h        2015-08-01 
14:41:18.000000000 +0200
@@ -0,0 +1,142 @@
+/*
+    Copyright (c) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, 
i...@kdab.com
+    Authors: David Faure <david.fa...@kdab.com>
+
+    This library is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Library General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    This library is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
+    License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to the
+    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+*/
+
+#ifndef KEXTRACOLUMNSPROXYMODEL_H
+#define KEXTRACOLUMNSPROXYMODEL_H
+
+#include <QIdentityProxyModel>
+#include <QScopedPointer>
+#include "kitemmodels_export.h"
+
+class KExtraColumnsProxyModelPrivate;
+
+/**
+ * This proxy appends extra columns (after all existing columns).
+ *
+ * The proxy supports source models that have a tree structure.
+ * It also supports editing, and propagating changes from the source model.
+ * Row insertion/removal, column insertion/removal in the source model are 
supported.
+ *
+ * Not supported: adding/removing extra columns at runtime; having a different 
number of columns in subtrees;
+ * drag-n-drop support in the extra columns; moving columns.
+ *
+ * Derive from KExtraColumnsProxyModel, call appendColumn (typically in the 
constructor) for each extra column,
+ * and reimplement extraColumnData() to allow KExtraColumnsProxyModel to 
retrieve the data to show in the extra columns.
+ *
+ * If you want your new column(s) to be somewhere else than at the right of 
the existing columns, you can
+ * use a KRearrangeColumnsProxyModel on top.
+ *
+ * Author: David Faure, KDAB
+ * @since 5.13
+ */
+class KITEMMODELS_EXPORT KExtraColumnsProxyModel : public QIdentityProxyModel
+{
+    Q_OBJECT
+public:
+    /**
+     * Base class constructor.
+     * Remember to call setSourceModel afterwards, and appendColumn.
+     */
+    explicit KExtraColumnsProxyModel(QObject *parent = 0);
+    /**
+     * Destructor.
+     */
+    ~KExtraColumnsProxyModel();
+
+    // API
+
+    /**
+     * Appends an extra column.
+     * @param header an optional text for the horizontal header
+     */
+    void appendColumn(const QString &header = QString());
+
+    /**
+     * This method is called by data() for extra columns.
+     * Reimplement this method to return the data for the extra columns.
+     *
+     * @param parent the parent model index (only useful in tree models)
+     * @param row the row number for which the model is querying for data 
(child of @p parent, if set)
+     * @param extraColumn the number of the extra column, starting at 0 (this 
doesn't require knowing how many columns the source model has)
+     * @param role the role being queried
+     * @return the data at @p row and @p extraColumn
+     */
+    virtual QVariant extraColumnData(const QModelIndex &parent, int row, int 
extraColumn, int role = Qt::DisplayRole) const = 0;
+
+    /**
+     * This method is called by setData() for extra columns.
+     * Reimplement this method to set the data for the extra columns, if 
editing is supported.
+     * Remember to call extraColumnDataChanged() after changing the data 
storage.
+     * The default implementation returns false.
+     */
+    virtual bool setExtraColumnData(const QModelIndex &parent, int row, int 
extraColumn, const QVariant &data, int role = Qt::EditRole);
+
+    /**
+     * This method can be called by your derived class when the data in an 
extra column has changed.
+     * The use case is data that changes "by itself", unrelated to setData.
+     */
+    void extraColumnDataChanged(const QModelIndex &parent, int row, int 
extraColumn, const QVector<int> &roles);
+
+    /**
+     * Returns the extra column number (0, 1, ...) for a given column number 
of the proxymodel.
+     * This basically means subtracting the amount of columns in the source 
model.
+     */
+    int extraColumnForProxyColumn(int proxyColumn) const;
+    /**
+     * Returns the proxy column number for a given extra column number 
(starting at 0).
+     * This basically means adding the amount of columns in the source model.
+     */
+    int proxyColumnForExtraColumn(int extraColumn) const;
+
+
+    // Implementation
+    /// @reimp
+    void setSourceModel(QAbstractItemModel *model) Q_DECL_OVERRIDE;
+    /// @reimp
+    QModelIndex mapToSource(const QModelIndex &proxyIndex) const 
Q_DECL_OVERRIDE;
+    /// @reimp
+    QItemSelection mapSelectionToSource(const QItemSelection &selection) const 
Q_DECL_OVERRIDE;
+    /// @reimp
+    int columnCount(const QModelIndex &parent = QModelIndex()) const 
Q_DECL_OVERRIDE;
+    /// @reimp
+    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const 
Q_DECL_OVERRIDE;
+    /// @reimp
+    bool setData(const QModelIndex &index, const QVariant &value, int role = 
Qt::EditRole) Q_DECL_OVERRIDE;
+    /// @reimp
+    QModelIndex sibling(int row, int column, const QModelIndex &idx) const 
Q_DECL_OVERRIDE;
+    /// @reimp
+    Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
+    /// @reimp
+    QVariant headerData(int section, Qt::Orientation orientation,
+                        int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
+    /// @reimp
+    QModelIndex index(int row, int column, const QModelIndex &parent = 
QModelIndex()) const Q_DECL_OVERRIDE;
+    /// @reimp
+    QModelIndex parent(const QModelIndex &child) const Q_DECL_OVERRIDE;
+
+private:
+    Q_DECLARE_PRIVATE(KExtraColumnsProxyModel)
+    Q_PRIVATE_SLOT(d_func(), void _ec_sourceLayoutAboutToBeChanged(const 
QList<QPersistentModelIndex> &, QAbstractItemModel::LayoutChangeHint))
+    Q_PRIVATE_SLOT(d_func(), void _ec_sourceLayoutChanged(const 
QList<QPersistentModelIndex> &, QAbstractItemModel::LayoutChangeHint))
+    const QScopedPointer<KExtraColumnsProxyModelPrivate> d_ptr;
+
+};
+
+#endif


Reply via email to