diff --git a/examples/quick/controls/tableview/images/header.png b/examples/quick/controls/tableview/images/header.png
deleted file mode 100644
index dba6646092ce4f4f6dcc52f05c3fa96535eab660..0000000000000000000000000000000000000000
Binary files a/examples/quick/controls/tableview/images/header.png and /dev/null differ
diff --git a/examples/quick/controls/tableview/images/selectedrow.png b/examples/quick/controls/tableview/images/selectedrow.png
deleted file mode 100644
index 71192ea4e2b72d820f7afa745d50275fa8a1fb82..0000000000000000000000000000000000000000
Binary files a/examples/quick/controls/tableview/images/selectedrow.png and /dev/null differ
diff --git a/examples/quick/controls/tableview/images/sort-up.png b/examples/quick/controls/tableview/images/sort-up.png
deleted file mode 100644
index 27fcb19153992dbc4003103460fd74004e6778e8..0000000000000000000000000000000000000000
Binary files a/examples/quick/controls/tableview/images/sort-up.png and /dev/null differ
diff --git a/examples/quick/controls/tableview/main.qml b/examples/quick/controls/tableview/main.qml
index b85f2d1d98ea0d3e3354afbc8b2116a7ac8c7fc2..49386289da0684744c1caff910e326e35c3a1019 100644
--- a/examples/quick/controls/tableview/main.qml
+++ b/examples/quick/controls/tableview/main.qml
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
 ** Contact: http://www.qt-project.org/legal
 **
 ** This file is part of the Qt Quick Controls module of the Qt Toolkit.
@@ -38,385 +38,150 @@
 **
 ****************************************************************************/
 
-
-
-
-
 import QtQuick 2.2
-import QtQuick.Window 2.1
+import QtQuick.Layouts 1.1
 import QtQuick.Controls 1.2
-import QtQuick.XmlListModel 2.0
+import org.qtproject.example 1.0
 
-Window {
+ApplicationWindow {
+    id: window
     visible: true
-    width: 538 + frame.margins * 2
-    height: 360 + frame.margins * 2
-
-    ToolBar {
-        id: toolbar
-        width: parent.width
+    title: "Table View Example"
 
-        ListModel {
-            id: delegatemenu
-            ListElement { text: "Shiny delegate" }
-            ListElement { text: "Scale selected" }
-            ListElement { text: "Editable items" }
-        }
+    toolBar: ToolBar {
+        TextField {
+            id: searchBox
 
-        ComboBox {
-            id: delegateChooser
-            enabled: frame.currentIndex === 3 ? 1 : 0
-            model: delegatemenu
-            width: 150
-            anchors.left: parent.left
-            anchors.leftMargin: 8
-            anchors.verticalCenter: parent.verticalCenter
-        }
+            placeholderText: "Search..."
+            inputMethodHints: Qt.ImhNoPredictiveText
 
-        CheckBox {
-            id: enabledCheck
-            text: "Enabled"
-            checked: true
+            width: window.width / 5 * 2
             anchors.right: parent.right
             anchors.verticalCenter: parent.verticalCenter
         }
     }
 
-    SystemPalette {id: syspal}
-    color: syspal.window
-
-    XmlListModel {
-        id: flickerModel
-        source: "http://api.flickr.com/services/feeds/photos_public.gne?format=rss2&tags=" + "Qt"
-        query: "/rss/channel/item"
-        namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";"
-        XmlRole { name: "title"; query: "title/string()" }
-        XmlRole { name: "imagesource"; query: "media:thumbnail/@url/string()" }
-        XmlRole { name: "credit"; query: "media:credit/string()" }
-    }
-
-    ListModel {
-        id: nestedModel
-        ListElement{content: ListElement { description: "Core" ; color:"#ffaacc"}}
-        ListElement{content: ListElement { description: "Second" ; color:"#ffccaa"}}
-        ListElement{content: ListElement { description: "Third" ; color:"#ffffaa"}}
-    }
+    TableView {
+        id: tableView
 
-    ListModel {
-        id: largeModel
-        Component.onCompleted: {
-            for (var i=0 ; i< 500 ; ++i)
-                largeModel.append({"name":"Person "+i , "age": Math.round(Math.random()*100), "gender": Math.random()>0.5 ? "Male" : "Female"})
-        }
-    }
+        frameVisible: false
+        sortIndicatorVisible: true
 
-    Column {
-        anchors.top: toolbar.bottom
-        anchors.right: parent.right
-        anchors.left: parent.left
-        anchors.bottom:  parent.bottom
-        anchors.margins: 8
+        anchors.fill: parent
 
-        TabView {
-            id:frame
-            focus:true
-            enabled: enabledCheck.checked
+        Layout.minimumWidth: 400
+        Layout.minimumHeight: 240
+        Layout.preferredWidth: 600
+        Layout.preferredHeight: 400
 
-            property int margins: Qt.platform.os === "osx" ? 16 : 0
+        TableViewColumn {
+            id: titleColumn
+            title: "Title"
+            role: "title"
+            movable: false
+            resizable: false
+            width: tableView.viewport.width - authorColumn.width
+        }
 
-            height: parent.height - 34
-            anchors.right: parent.right
-            anchors.left: parent.left
-            anchors.margins: margins
+        TableViewColumn {
+            id: authorColumn
+            title: "Author"
+            role: "author"
+            movable: false
+            resizable: false
+            width: tableView.viewport.width / 3
+        }
 
-            Tab {
-                title: "XmlListModel"
+        model: SortFilterProxyModel {
+            id: proxyModel
+            source: sourceModel.count > 0 ? sourceModel : null
 
-                TableView {
-                    model: flickerModel
-                    anchors.fill: parent
-                    anchors.margins: 12
+            sortOrder: tableView.sortIndicatorOrder
+            sortCaseSensitivity: Qt.CaseInsensitive
+            sortRole: sourceModel.count > 0 ? tableView.getColumn(tableView.sortIndicatorColumn).role : ""
 
-                    TableViewColumn {
-                        role: "title"
-                        title: "Title"
-                        width: 120
-                    }
-                    TableViewColumn {
-                        role: "credit"
-                        title: "Credit"
-                        width: 120
-                    }
-                    TableViewColumn {
-                        role: "imagesource"
-                        title: "Image source"
-                        width: 200
-                        visible: true
-                    }
+            filterString: "*" + searchBox.text + "*"
+            filterSyntax: SortFilterProxyModel.Wildcard
+            filterCaseSensitivity: Qt.CaseInsensitive
+        }
 
-                    frameVisible: frameCheckbox.checked
-                    headerVisible: headerCheckbox.checked
-                    sortIndicatorVisible: sortableCheckbox.checked
-                    alternatingRowColors: alternateCheckbox.checked
-                }
+        ListModel {
+            id: sourceModel
+            ListElement {
+                title: "Moby-Dick"
+                author: "Herman Melville"
             }
-            Tab {
-                title: "Multivalue"
-
-                TableView {
-                    model: nestedModel
-                    anchors.fill: parent
-                    anchors.margins: 12
-
-                    TableViewColumn {
-                        role: "content"
-                        title: "Text and Color"
-                        width: 220
-                    }
-
-                    itemDelegate: Item {
-                        Rectangle{
-                            color: styleData.value.get(0).color
-                            anchors.top:parent.top
-                            anchors.right:parent.right
-                            anchors.bottom:parent.bottom
-                            anchors.margins: 4
-                            width:32
-                            border.color:"#666"
-                        }
-                        Text {
-                            width: parent.width
-                            anchors.margins: 4
-                            anchors.left: parent.left
-                            anchors.verticalCenter: parent.verticalCenter
-                            elide: styleData.elideMode
-                            text: styleData.value.get(0).description
-                            color: styleData.textColor
-                        }
-                    }
-
-                    frameVisible: frameCheckbox.checked
-                    headerVisible: headerCheckbox.checked
-                    sortIndicatorVisible: sortableCheckbox.checked
-                    alternatingRowColors: alternateCheckbox.checked
-                }
+            ListElement {
+                title: "The Adventures of Tom Sawyer"
+                author: "Mark Twain"
             }
-            Tab {
-                title: "Generated"
-
-                TableView {
-                    model: largeModel
-                    anchors.margins: 12
-                    anchors.fill: parent
-                    TableViewColumn {
-                        role: "name"
-                        title: "Name"
-                        width: 120
-                    }
-                    TableViewColumn {
-                        role: "age"
-                        title: "Age"
-                        width: 120
-                    }
-                    TableViewColumn {
-                        role: "gender"
-                        title: "Gender"
-                        width: 120
-                    }
-                    frameVisible: frameCheckbox.checked
-                    headerVisible: headerCheckbox.checked
-                    sortIndicatorVisible: sortableCheckbox.checked
-                    alternatingRowColors: alternateCheckbox.checked
-                }
+            ListElement {
+                title: "Cat’s Cradle"
+                author: "Kurt Vonnegut"
             }
-
-            Tab {
-                title: "Delegates"
-                Item {
-                    anchors.fill: parent
-
-                    Component {
-                        id: delegate1
-                        Item {
-                            clip: true
-                            Text {
-                                width: parent.width
-                                anchors.margins: 4
-                                anchors.left: parent.left
-                                anchors.verticalCenter: parent.verticalCenter
-                                elide: styleData.elideMode
-                                text: styleData.value !== undefined  ? styleData.value : ""
-                                color: styleData.textColor
-                            }
-                        }
-                    }
-
-                    Component {
-                        id: delegate2
-                        Text {
-                            width: parent.width
-                            anchors.margins: 4
-                            anchors.left: parent.left
-                            anchors.verticalCenter: parent.verticalCenter
-                            elide: styleData.elideMode
-                            text: styleData.value !== undefined  ? styleData.value : ""
-                            color: styleData.textColor
-                        }
-                    }
-
-                    Component {
-                        id: editableDelegate
-                        Item {
-
-                            Text {
-                                width: parent.width
-                                anchors.margins: 4
-                                anchors.left: parent.left
-                                anchors.verticalCenter: parent.verticalCenter
-                                elide: styleData.elideMode
-                                text: styleData.value !== undefined ? styleData.value : ""
-                                color: styleData.textColor
-                                visible: !styleData.selected
-                            }
-                            Loader { // Initialize text editor lazily to improve performance
-                                id: loaderEditor
-                                anchors.fill: parent
-                                anchors.margins: 4
-                                Connections {
-                                    target: loaderEditor.item
-                                    onAccepted: {
-                                        if (typeof styleData.value === 'number')
-                                            largeModel.setProperty(styleData.row, styleData.role, Number(parseFloat(loaderEditor.item.text).toFixed(0)))
-                                        else
-                                            largeModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text)
-                                    }
-                                }
-                                sourceComponent: styleData.selected ? editor : null
-                                Component {
-                                    id: editor
-                                    TextInput {
-                                        id: textinput
-                                        color: styleData.textColor
-                                        text: styleData.value
-                                        MouseArea {
-                                            id: mouseArea
-                                            anchors.fill: parent
-                                            hoverEnabled: true
-                                            onClicked: textinput.forceActiveFocus()
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    TableView {
-                        id: delegatesView
-                        model: largeModel
-                        anchors.margins: 12
-                        anchors.fill:parent
-                        frameVisible: frameCheckbox.checked
-                        headerVisible: headerCheckbox.checked
-                        sortIndicatorVisible: sortableCheckbox.checked
-                        alternatingRowColors: alternateCheckbox.checked
-
-                        TableViewColumn {
-                            role: "name"
-                            title: "Name"
-                            width: 120
-                        }
-                        TableViewColumn {
-                            role: "age"
-                            title: "Age"
-                            width: 120
-                        }
-                        TableViewColumn {
-                            role: "gender"
-                            title: "Gender"
-                            width: 120
-                        }
-
-                        headerDelegate: BorderImage{
-                            source: "images/header.png"
-                            border{left:2;right:2;top:2;bottom:2}
-                            Text {
-                                anchors.verticalCenter: parent.verticalCenter
-                                anchors.left: parent.left
-                                anchors.right: indicator.visible ? indicator.left : parent.right
-                                anchors.margins: 6
-                                text: styleData.value
-                                elide: Text.ElideRight
-                                color:"#333"
-                            }
-                            // Sort indicator
-                            Image {
-                                id: indicator
-                                anchors.verticalCenter: parent.verticalCenter
-                                anchors.right: parent.right
-                                anchors.rightMargin: 6
-                                source: "images/sort-up.png"
-                                visible: delegatesView.sortIndicatorVisible &&
-                                            styleData.column === delegatesView.sortIndicatorColumn
-                                rotation: delegatesView.sortIndicatorOrder === Qt.AscendingOrder ? 180 : 0
-                                Behavior on rotation { NumberAnimation { } }
-                            }
-
-                        }
-
-                        rowDelegate: Rectangle {
-                            height: (delegateChooser.currentIndex == 1 && styleData.selected) ? 30 : 20
-                            Behavior on height{ NumberAnimation{} }
-
-                            color: styleData.selected ? "#448" : (styleData.alternate? "#eee" : "#fff")
-                            BorderImage{
-                                id: selected
-                                anchors.fill: parent
-                                source: "images/selectedrow.png"
-                                visible: styleData.selected
-                                border{left:2; right:2; top:2; bottom:2}
-                                SequentialAnimation {
-                                    running: true; loops: Animation.Infinite
-                                    NumberAnimation { target:selected; property: "opacity"; to: 1.0; duration: 900}
-                                    NumberAnimation { target:selected; property: "opacity"; to: 0.5; duration: 900}
-                                }
-                            }
-                        }
-
-                        itemDelegate: {
-                            if (delegateChooser.currentIndex == 2)
-                                return editableDelegate;
-                            else
-                                return delegate1;
-                        }
-                    }
-                }
+            ListElement {
+                title: "Farenheit 451"
+                author: "Ray Bradbury"
             }
-        }
-        Row{
-            x: 12
-            height: 34
-            CheckBox{
-                id: alternateCheckbox
-                checked: true
-                text: "Alternate"
-                anchors.verticalCenter: parent.verticalCenter
+            ListElement {
+                title: "It"
+                author: "Stephen King"
+            }
+            ListElement {
+                title: "On the Road"
+                author: "Jack Kerouac"
+            }
+            ListElement {
+                title: "Of Mice and Men"
+                author: "John Steinbeck"
+            }
+            ListElement {
+                title: "Do Androids Dream of Electric Sheep?"
+                author: "Philip K. Dick"
+            }
+            ListElement {
+                title: "Uncle Tom’s Cabin"
+                author: "Harriet Beecher Stowe"
+            }
+            ListElement {
+                title: "The Call of the Wild"
+                author: "Jack London"
+            }
+            ListElement {
+                title: "The Old Man and the Sea"
+                author: "Ernest Hemingway"
+            }
+            ListElement {
+                title: "A Streetcar Named Desire"
+                author: "Tennessee Williams"
+            }
+            ListElement {
+                title: "Catch-22"
+                author: "Joseph Heller"
+            }
+            ListElement {
+                title: "One Flew Over the Cuckoo’s Nest"
+                author: "Ken Kesey"
+            }
+            ListElement {
+                title: "The Murders in the Rue Morgue"
+                author: "Edgar Allan Poe"
+            }
+            ListElement {
+                title: "Breakfast at Tiffany’s"
+                author: "Truman Capote"
             }
-            CheckBox{
-                id: sortableCheckbox
-                checked: false
-                text: "Sort indicator"
-                anchors.verticalCenter: parent.verticalCenter
+            ListElement {
+                title: "Death of a Salesman"
+                author: "Arthur Miller"
             }
-            CheckBox{
-                id: frameCheckbox
-                checked: true
-                text: "Frame"
-                anchors.verticalCenter: parent.verticalCenter
+            ListElement {
+                title: "Post Office"
+                author: "Charles Bukowski"
             }
-            CheckBox{
-                id: headerCheckbox
-                checked: true
-                text: "Headers"
-                anchors.verticalCenter: parent.verticalCenter
+            ListElement {
+                title: "Herbert West—Reanimator"
+                author: "H. P. Lovecraft"
             }
         }
     }
diff --git a/examples/quick/controls/tableview/resources.qrc b/examples/quick/controls/tableview/resources.qrc
deleted file mode 100644
index 83d3f6a76c31f2ec3b0d1a8be27f540093b5a6f0..0000000000000000000000000000000000000000
--- a/examples/quick/controls/tableview/resources.qrc
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/">
-  <file>main.qml</file>
-  <file>images/selectedrow.png</file>
-  <file>images/header.png</file>
-  <file>images/sort-up.png</file>
-</qresource>
-</RCC>
diff --git a/examples/quick/controls/tableview/src/main.cpp b/examples/quick/controls/tableview/src/main.cpp
index a757f4853bfbf9bcd6469529cfbc00854b38de47..1406b84cec5d0799a5691bea174af49b955aa3bd 100644
--- a/examples/quick/controls/tableview/src/main.cpp
+++ b/examples/quick/controls/tableview/src/main.cpp
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
 ** Contact: http://www.qt-project.org/legal
 **
 ** This file is part of the Qt Quick Controls module of the Qt Toolkit.
@@ -39,11 +39,21 @@
 ****************************************************************************/
 
 #include "qtquickcontrolsapplication.h"
-#include <QtQml/QQmlApplicationEngine>
+#include "sortfilterproxymodel.h"
+#include <QtQml/qqmlapplicationengine.h>
+#include <QtGui/qsurfaceformat.h>
+#include <QtQml/qqml.h>
 
 int main(int argc, char *argv[])
 {
     QtQuickControlsApplication app(argc, argv);
+    if (QCoreApplication::arguments().contains(QLatin1String("--coreprofile"))) {
+        QSurfaceFormat fmt;
+        fmt.setVersion(4, 4);
+        fmt.setProfile(QSurfaceFormat::CoreProfile);
+        QSurfaceFormat::setDefaultFormat(fmt);
+    }
+    qmlRegisterType<SortFilterProxyModel>("org.qtproject.example", 1, 0, "SortFilterProxyModel");
     QQmlApplicationEngine engine(QUrl("qrc:/main.qml"));
     return app.exec();
 }
diff --git a/examples/quick/controls/tableview/src/sortfilterproxymodel.cpp b/examples/quick/controls/tableview/src/sortfilterproxymodel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7b999470f37e96ec71a31b6df747d26bcbeeb80d
--- /dev/null
+++ b/examples/quick/controls/tableview/src/sortfilterproxymodel.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Quick Controls module 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 Digia Plc and its Subsidiary(-ies) 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$
+**
+****************************************************************************/
+
+#include "sortfilterproxymodel.h"
+#include <QtDebug>
+#include <QtQml>
+
+SortFilterProxyModel::SortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent), m_complete(false)
+{
+    connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(countChanged()));
+    connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(countChanged()));
+}
+
+int SortFilterProxyModel::count() const
+{
+    return rowCount();
+}
+
+QObject *SortFilterProxyModel::source() const
+{
+    return sourceModel();
+}
+
+void SortFilterProxyModel::setSource(QObject *source)
+{
+    setSourceModel(qobject_cast<QAbstractItemModel *>(source));
+}
+
+QByteArray SortFilterProxyModel::sortRole() const
+{
+    return m_sortRole;
+}
+
+void SortFilterProxyModel::setSortRole(const QByteArray &role)
+{
+    if (m_sortRole != role) {
+        m_sortRole = role;
+        if (m_complete)
+            QSortFilterProxyModel::setSortRole(roleKey(role));
+    }
+}
+
+void SortFilterProxyModel::setSortOrder(Qt::SortOrder order)
+{
+    QSortFilterProxyModel::sort(0, order);
+}
+
+QByteArray SortFilterProxyModel::filterRole() const
+{
+    return m_filterRole;
+}
+
+void SortFilterProxyModel::setFilterRole(const QByteArray &role)
+{
+    if (m_filterRole != role) {
+        m_filterRole = role;
+        if (m_complete)
+            QSortFilterProxyModel::setFilterRole(roleKey(role));
+    }
+}
+
+QString SortFilterProxyModel::filterString() const
+{
+    return filterRegExp().pattern();
+}
+
+void SortFilterProxyModel::setFilterString(const QString &filter)
+{
+    setFilterRegExp(QRegExp(filter, filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(filterSyntax())));
+}
+
+SortFilterProxyModel::FilterSyntax SortFilterProxyModel::filterSyntax() const
+{
+    return static_cast<FilterSyntax>(filterRegExp().patternSyntax());
+}
+
+void SortFilterProxyModel::setFilterSyntax(SortFilterProxyModel::FilterSyntax syntax)
+{
+    setFilterRegExp(QRegExp(filterString(), filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(syntax)));
+}
+
+QJSValue SortFilterProxyModel::get(int idx) const
+{
+    QJSEngine *engine = qmlEngine(this);
+    QJSValue value = engine->newObject();
+    if (idx >= 0 && idx < count()) {
+        QHash<int, QByteArray> roles = roleNames();
+        QHashIterator<int, QByteArray> it(roles);
+        while (it.hasNext()) {
+            it.next();
+            value.setProperty(QString::fromUtf8(it.value()), data(index(idx, 0), it.key()).toString());
+        }
+    }
+    return value;
+}
+
+void SortFilterProxyModel::classBegin()
+{
+}
+
+void SortFilterProxyModel::componentComplete()
+{
+    m_complete = true;
+    if (!m_sortRole.isEmpty())
+        QSortFilterProxyModel::setSortRole(roleKey(m_sortRole));
+    if (!m_filterRole.isEmpty())
+        QSortFilterProxyModel::setFilterRole(roleKey(m_filterRole));
+}
+
+int SortFilterProxyModel::roleKey(const QByteArray &role) const
+{
+    QHash<int, QByteArray> roles = roleNames();
+    QHashIterator<int, QByteArray> it(roles);
+    while (it.hasNext()) {
+        it.next();
+        if (it.value() == role)
+            return it.key();
+    }
+    return -1;
+}
+
+QHash<int, QByteArray> SortFilterProxyModel::roleNames() const
+{
+    if (QAbstractItemModel *source = sourceModel())
+        return source->roleNames();
+    return QHash<int, QByteArray>();
+}
+
+bool SortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+    QRegExp rx = filterRegExp();
+    if (rx.isEmpty())
+        return true;
+    QAbstractItemModel *model = sourceModel();
+    if (filterRole().isEmpty()) {
+        QHash<int, QByteArray> roles = roleNames();
+        QHashIterator<int, QByteArray> it(roles);
+        while (it.hasNext()) {
+            it.next();
+            QModelIndex sourceIndex = model->index(sourceRow, 0, sourceParent);
+            QString key = model->data(sourceIndex, it.key()).toString();
+            if (key.contains(rx))
+                return true;
+        }
+        return false;
+    }
+    QModelIndex sourceIndex = model->index(sourceRow, 0, sourceParent);
+    if (!sourceIndex.isValid())
+        return true;
+    QString key = model->data(sourceIndex, roleKey(filterRole())).toString();
+    return key.contains(rx);
+}
diff --git a/examples/quick/controls/tableview/src/sortfilterproxymodel.h b/examples/quick/controls/tableview/src/sortfilterproxymodel.h
new file mode 100644
index 0000000000000000000000000000000000000000..026b5d124bc7997f88710fe7f1bc0d70654daae5
--- /dev/null
+++ b/examples/quick/controls/tableview/src/sortfilterproxymodel.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Quick Controls module 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 Digia Plc and its Subsidiary(-ies) 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$
+**
+****************************************************************************/
+
+#ifndef SORTFILTERPROXYMODEL_H
+#define SORTFILTERPROXYMODEL_H
+
+#include <QtCore/qsortfilterproxymodel.h>
+#include <QtQml/qqmlparserstatus.h>
+#include <QtQml/qjsvalue.h>
+
+class SortFilterProxyModel : public QSortFilterProxyModel, public QQmlParserStatus
+{
+    Q_OBJECT
+    Q_INTERFACES(QQmlParserStatus)
+
+    Q_PROPERTY(int count READ count NOTIFY countChanged)
+    Q_PROPERTY(QObject *source READ source WRITE setSource)
+
+    Q_PROPERTY(QByteArray sortRole READ sortRole WRITE setSortRole)
+    Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder)
+
+    Q_PROPERTY(QByteArray filterRole READ filterRole WRITE setFilterRole)
+    Q_PROPERTY(QString filterString READ filterString WRITE setFilterString)
+    Q_PROPERTY(FilterSyntax filterSyntax READ filterSyntax WRITE setFilterSyntax)
+
+    Q_ENUMS(FilterSyntax)
+
+public:
+    explicit SortFilterProxyModel(QObject *parent = 0);
+
+    QObject *source() const;
+    void setSource(QObject *source);
+
+    QByteArray sortRole() const;
+    void setSortRole(const QByteArray &role);
+
+    void setSortOrder(Qt::SortOrder order);
+
+    QByteArray filterRole() const;
+    void setFilterRole(const QByteArray &role);
+
+    QString filterString() const;
+    void setFilterString(const QString &filter);
+
+    enum FilterSyntax {
+        RegExp,
+        Wildcard,
+        FixedString
+    };
+
+    FilterSyntax filterSyntax() const;
+    void setFilterSyntax(FilterSyntax syntax);
+
+    int count() const;
+    Q_INVOKABLE QJSValue get(int index) const;
+
+    void classBegin();
+    void componentComplete();
+
+signals:
+    void countChanged();
+
+protected:
+    int roleKey(const QByteArray &role) const;
+    QHash<int, QByteArray> roleNames() const;
+    bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+
+private:
+    bool m_complete;
+    QByteArray m_sortRole;
+    QByteArray m_filterRole;
+};
+
+#endif // SORTFILTERPROXYMODEL_H
diff --git a/examples/quick/controls/tableview/src/src.pri b/examples/quick/controls/tableview/src/src.pri
index 66d903eacf02b2c8c3cf57b9c10fc4835937357a..491f851c916c23f86cae2a84a24368c93cd149e2 100644
--- a/examples/quick/controls/tableview/src/src.pri
+++ b/examples/quick/controls/tableview/src/src.pri
@@ -1,2 +1,8 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+    $$PWD/sortfilterproxymodel.h
+
 SOURCES += \
-    $$PWD/main.cpp
+    $$PWD/main.cpp \
+    $$PWD/sortfilterproxymodel.cpp
diff --git a/examples/quick/controls/tableview/tableview.pro b/examples/quick/controls/tableview/tableview.pro
index c982ac2038c1e1b55eb8564117bda3c8589a1cce..c0ed1a2f99e3d20865968642202b95907663ef6a 100644
--- a/examples/quick/controls/tableview/tableview.pro
+++ b/examples/quick/controls/tableview/tableview.pro
@@ -1,12 +1,11 @@
-QT += qml quick
+TEMPLATE = app
 TARGET = tableview
-!no_desktop: QT += widgets
 
-include(src/src.pri)
-include(../shared/shared.pri)
+RESOURCES += \
+    tableview.qrc
 
 OTHER_FILES += \
     main.qml
 
-RESOURCES += \
-    resources.qrc
+include(src/src.pri)
+include(../shared/shared.pri)
diff --git a/examples/quick/controls/tableview/tableview.qmlproject b/examples/quick/controls/tableview/tableview.qmlproject
deleted file mode 100644
index e5a8bf02ca789d31c0265da83b2cb6f09e10ba15..0000000000000000000000000000000000000000
--- a/examples/quick/controls/tableview/tableview.qmlproject
+++ /dev/null
@@ -1,16 +0,0 @@
-import QmlProject 1.1
-
-Project {
-    mainFile: "main.qml"
-
-    /* Include .qml, .js, and image files from current directory and subdirectories */
-    QmlFiles {
-        directory: "."
-    }
-    JavaScriptFiles {
-        directory: "."
-    }
-    ImageFiles {
-        directory: "."
-    }
-}
diff --git a/examples/quick/controls/tableview/tableview.qrc b/examples/quick/controls/tableview/tableview.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..3b111a90752fef76205223287fddd1637480c7b9
--- /dev/null
+++ b/examples/quick/controls/tableview/tableview.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+  <file>main.qml</file>
+</qresource>
+</RCC>
diff --git a/src/controls/doc/images/qtquickcontrols-example-tableview.png b/src/controls/doc/images/qtquickcontrols-example-tableview.png
index b9dc67c317a8f071841bbc5a6ffa78b997854723..c4ab8d9973ca1a9de080446f33e19c142e48d34a 100644
Binary files a/src/controls/doc/images/qtquickcontrols-example-tableview.png and b/src/controls/doc/images/qtquickcontrols-example-tableview.png differ
diff --git a/src/controls/doc/src/qtquickcontrols-examples.qdoc b/src/controls/doc/src/qtquickcontrols-examples.qdoc
index ca293df0e0965c06d2a81e1891f2f70f2df0aa42..4e6fccb08696b0efd2aa60fe6bb4348f5a5c93e6 100644
--- a/src/controls/doc/src/qtquickcontrols-examples.qdoc
+++ b/src/controls/doc/src/qtquickcontrols-examples.qdoc
@@ -69,10 +69,34 @@
     \brief An example for the TableView control.
     \image qtquickcontrols-example-tableview.png
 
-    This example shows how a \l{TableView} from \l{Qt Quick Controls}
-    can be used together with different types of data models to display
-    lists of information with support for scroll bars, selections and
-    resizable header sections.
+    This example project demonstrates the usage of \l {TableView} from
+    \l{Qt Quick Controls} - a control to display one or more columns of
+    information from a data list model. The example includes a model
+    that supports sorting and filtering.
+
+    The C++ class, SortFilterProxyModel, is registered as a QML type
+    under the namespace, "\c{org.qtproject.example 1.0}".
+
+    The following snippets show how the type is registered under
+    a namespace and later imported by \e main.qml.
+
+    QML type registration:
+
+    \code
+    #include <QtQml/qqml.h>
+    ...
+    qmlRegisterType<SortFilterProxyModel>("org.qtproject.example", 1, 0, "SortFilterProxyModel");
+    ...
+    \endcode
+
+    QML namespace import:
+
+    \qml
+    import org.qtproject.example 1.0
+    \endqml
+
+    For more information about registering C++ classses as QML types, see
+    \l {Defining QML Types from C++}.
 
     \include examples-run.qdocinc
 */