Refactoring and model improvements
authorTofe <chris.chapuis+gitorious@gmail.com>
Thu, 23 Feb 2012 20:43:04 +0000 (21:43 +0100)
committerTofe <chris.chapuis+gitorious@gmail.com>
Thu, 23 Feb 2012 20:43:04 +0000 (21:43 +0100)
It is now possible to have independant sources, each one having its own
set of sub-models. It can go in-depth as long as necessary.

23 files changed:
qml/QuickNewsReader/content/modelimpl/FavoriteFeedsJournalModel.qml [deleted file]
qml/QuickNewsReader/content/modelimpl/FavoriteFeedsSourceModel.qml [new file with mode: 0644]
qml/QuickNewsReader/content/modelimpl/FavoriteRssFeeds.qml
qml/QuickNewsReader/content/modelimpl/LeMondeJournalModel.qml [deleted file]
qml/QuickNewsReader/content/modelimpl/LeMondeSequenceNews.qml
qml/QuickNewsReader/content/modelimpl/LeMondeSequencesList.qml
qml/QuickNewsReader/content/modelimpl/LeMondeSourceModel.qml [new file with mode: 0644]
qml/QuickNewsReader/content/modelimpl/RssFeedModel.qml
qml/QuickNewsReader/content/modelimpl/YahooJournalModel.qml [deleted file]
qml/QuickNewsReader/content/modelimpl/YahooRssFeeds.qml
qml/QuickNewsReader/content/modelimpl/YahooSourceModel.qml [new file with mode: 0644]
qml/QuickNewsReader/content/modelitf/JournalModel.qml [deleted file]
qml/QuickNewsReader/content/modelitf/SourceModel.qml [new file with mode: 0644]
qml/QuickNewsReader/content/view/Categories.qml
qml/QuickNewsReader/content/view/CategoryDelegate.qml
qml/QuickNewsReader/content/view/JournalDelegate.qml [deleted file]
qml/QuickNewsReader/content/view/Journals.qml [deleted file]
qml/QuickNewsReader/content/view/News.qml
qml/QuickNewsReader/content/view/NewsDelegate.qml
qml/QuickNewsReader/content/view/NewsDetail.qml
qml/QuickNewsReader/content/view/SourceDelegate.qml [new file with mode: 0644]
qml/QuickNewsReader/content/view/Sources.qml [new file with mode: 0644]
qml/QuickNewsReader/main.qml

diff --git a/qml/QuickNewsReader/content/modelimpl/FavoriteFeedsJournalModel.qml b/qml/QuickNewsReader/content/modelimpl/FavoriteFeedsJournalModel.qml
deleted file mode 100644 (file)
index db533d4..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-import QtQuick 1.0
-import "../modelitf"
-
-JournalModel {
-    name: "Preferred feeds"
-
-    categoriesModel: FavoriteRssFeeds { }
-    newsModel: RssFeedModel {
-        currentFeed: categoriesModel.get(window.currentCategoryIndex).feed
-    }
-
-    loading: newsModel.loading
-}
diff --git a/qml/QuickNewsReader/content/modelimpl/FavoriteFeedsSourceModel.qml b/qml/QuickNewsReader/content/modelimpl/FavoriteFeedsSourceModel.qml
new file mode 100644 (file)
index 0000000..fbbf451
--- /dev/null
@@ -0,0 +1,22 @@
+import QtQuick 1.0
+import "../modelitf"
+
+SourceModel {
+    name: "Favorite Feeds"
+
+    listViews: [
+        { viewComponent: 'content/view/Categories.qml', viewId: 'categoriesRect' } ,
+        { viewComponent: 'content/view/News.qml', viewId: 'newsRect' }
+    ]
+    listModels: [
+        categoriesModel,
+        newsModel,
+    ]
+
+    property variant categoriesModel: FavoriteRssFeeds { }
+    property variant newsModel: RssFeedModel {
+        currentFeed: categoriesModel.get(window.currentCategoryIndex).feed
+    }
+
+    loading: newsModel.loading
+}
index 6d1143e..6a8e9fd 100644 (file)
@@ -3,6 +3,7 @@ import "../modelitf"
 
 ListModel {
     id: rssFeedsModel
+    property int sourceDepth: 1
 
     ListElement { name: "xkcd"; feed: "xkcd.com/rss.xml" }
 //    ListElement { name: "Journal du Geek"; feed: "www.journaldugeek.com/rss.php" }
diff --git a/qml/QuickNewsReader/content/modelimpl/LeMondeJournalModel.qml b/qml/QuickNewsReader/content/modelimpl/LeMondeJournalModel.qml
deleted file mode 100644 (file)
index 5cc1670..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-import QtQuick 1.0
-import "../modelitf"
-
-JournalModel {
-    name: "Le Monde"
-
-    function getSeqId(categoryIndex)
-    {
-        if( typeof categoriesModel.get(categoryIndex) != "undefined" )
-            if( typeof categoriesModel.get(categoryIndex).seqid != "undefined" )
-                return categoriesModel.get(categoryIndex).seqid
-
-        return ""
-    }
-
-    categoriesModel: LeMondeSequencesList { }
-    newsModel: LeMondeSequenceNews {
-        seqid: getSeqId(window.currentCategoryIndex)
-    }
-
-    loading: categoriesModel.loading || newsModel.loading
-}
index c8be7fd..48c0a0c 100644 (file)
@@ -5,6 +5,7 @@ XmlListModel {
 
     property string seqid: "3210"
     property bool loading: feedModel.status === XmlListModel.Loading
+    property int sourceDepth: 2
 
     source: "http://www.lemonde.fr/widget/nokia/sequence/" + seqid + ".xml"
     query: "/sequence/element"
index 8d4debb..0ca663e 100644 (file)
@@ -4,6 +4,7 @@ XmlListModel {
     id: rssFeedsModel
 
     property bool loading: rssFeedsModel.status === XmlListModel.Loading
+    property int sourceDepth: 1
 
     source: "http://www.lemonde.fr/widget/nokia/liste_sequences.xml"
     query: "/sequences/sequence"
@@ -15,7 +16,7 @@ XmlListModel {
         if(status === XmlListModel.Ready)
         {
             // trigger a re-evaluation of the news readings
-            currentCategoryIndex = 0
+            //currentCategoryIndex = 0
         }
     }
 }
diff --git a/qml/QuickNewsReader/content/modelimpl/LeMondeSourceModel.qml b/qml/QuickNewsReader/content/modelimpl/LeMondeSourceModel.qml
new file mode 100644 (file)
index 0000000..7fd5e3f
--- /dev/null
@@ -0,0 +1,33 @@
+import QtQuick 1.0
+import "../modelitf"
+
+SourceModel {
+    name: "Le Monde"
+
+    listViews: [
+        { viewComponent: 'content/view/Categories.qml', viewId: 'categoriesRect' } ,
+        { viewComponent: 'content/view/News.qml', viewId: 'newsRect' },
+        { viewComponent: 'content/view/NewsDetail.qml', viewId: 'newsDetailRect' }
+    ]
+    listModels: [
+        categoriesModel,
+        newsModel,
+        newsModel
+    ]
+
+    function getSeqId(categoryIndex)
+    {
+        if( typeof categoriesModel.get(categoryIndex) != "undefined" )
+            if( typeof categoriesModel.get(categoryIndex).seqid != "undefined" )
+                return categoriesModel.get(categoryIndex).seqid
+
+        return ""
+    }
+
+    property variant categoriesModel: LeMondeSequencesList { }
+    property variant newsModel: LeMondeSequenceNews {
+        seqid: getSeqId(currentPath[1])
+    }
+
+    loading: categoriesModel.loading || newsModel.loading
+}
index 34bb48b..3e1c432 100644 (file)
@@ -5,6 +5,7 @@ XmlListModel {
 
     property string currentFeed: ""
     property bool loading: feedModel.status === XmlListModel.Loading
+    property int sourceDepth: 2
 
     source: "http://" + currentFeed
     query: "/rss/channel/item"
diff --git a/qml/QuickNewsReader/content/modelimpl/YahooJournalModel.qml b/qml/QuickNewsReader/content/modelimpl/YahooJournalModel.qml
deleted file mode 100644 (file)
index 982731c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-import QtQuick 1.0
-import "../modelitf"
-
-JournalModel {
-    name: "Yahoo! News"
-
-    categoriesModel: YahooRssFeeds { }
-    newsModel: RssFeedModel {
-        currentFeed: categoriesModel.get(window.currentCategoryIndex).feed
-    }
-
-    loading: newsModel.loading
-}
index 654a0e8..aae3ede 100644 (file)
@@ -3,6 +3,7 @@ import "../modelitf"
 
 ListModel {
     id: rssFeedsModel
+    property int sourceDepth: 1
 
     ListElement { name: "Top Stories"; feed: "rss.news.yahoo.com/rss/topstories" }
     ListElement { name: "World"; feed: "rss.news.yahoo.com/rss/world" }
diff --git a/qml/QuickNewsReader/content/modelimpl/YahooSourceModel.qml b/qml/QuickNewsReader/content/modelimpl/YahooSourceModel.qml
new file mode 100644 (file)
index 0000000..971a99a
--- /dev/null
@@ -0,0 +1,22 @@
+import QtQuick 1.0
+import "../modelitf"
+
+SourceModel {
+    name: "Yahoo! News"
+
+    listViews: [
+        { viewComponent: 'content/view/Categories.qml', viewId: 'categoriesRect' } ,
+        { viewComponent: 'content/view/News.qml', viewId: 'newsRect' }
+    ]
+    listModels: [
+        categoriesModel,
+        newsModel,
+    ]
+
+    property variant categoriesModel: YahooRssFeeds { }
+    property variant newsModel: RssFeedModel {
+        currentFeed: categoriesModel.get(window.currentCategoryIndex).feed
+    }
+
+    loading: newsModel.loading
+}
diff --git a/qml/QuickNewsReader/content/modelitf/JournalModel.qml b/qml/QuickNewsReader/content/modelitf/JournalModel.qml
deleted file mode 100644 (file)
index 9f93d81..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-import QtQuick 1.0
-
-QtObject {
-    id: journalModel
-    property string name: "Journal"
-
-    property bool loading
-
-    property variant categoriesModel
-    property variant newsModel
-}
-
diff --git a/qml/QuickNewsReader/content/modelitf/SourceModel.qml b/qml/QuickNewsReader/content/modelitf/SourceModel.qml
new file mode 100644 (file)
index 0000000..5e6bb0a
--- /dev/null
@@ -0,0 +1,14 @@
+import QtQuick 1.0
+
+QtObject {
+    id: sourceModel
+    property string name: "Source"
+
+    property bool loading
+
+    property variant listViews;
+    property variant listModels;
+
+    property variant currentPath: [];
+}
+
index 04288ce..bca890e 100644 (file)
@@ -3,7 +3,7 @@ import QtQuick 1.0
 Rectangle {
 
     id: categoriesRect
-    width: 220
+    width: 220; height: window.height
     color: "#efefef"
 
     ListView {
@@ -11,11 +11,13 @@ Rectangle {
         id: categories
         x: 0; y: 0
         width: 220; height: window.height
-        model: currentJournal.categoriesModel
+        model: currentSource.listModels[componentDepth-1]
         footer: quitButtonDelegate
-        delegate: CategoryDelegate {}
+        delegate: CategoryDelegate { }
         highlight: Rectangle { color: "steelblue" }
         highlightMoveSpeed: 9999999
     }
     ScrollBar { scrollArea: categories; height: categories.height; width: 8; anchors.right: categories.right }
+
+    Component.onCompleted: categories.currentIndex = -1
 }
index 71422dc..16a3717 100644 (file)
@@ -75,9 +75,20 @@ Item {
     MouseArea {
         anchors.fill: delegate
         onClicked: {
+            var currentSourceDepth = delegate.ListView.view.model.sourceDepth
+
+            // here we remove everything in viewsModel after index "nextSourceDepth"
+            while(window.windowViewsModel.count>currentSourceDepth+1)
+                window.windowViewsModel.remove(window.windowViewsModel.count-1)
+
             delegate.ListView.view.currentIndex = index
-            window.currentCategoryIndex = index
-            window.currentNewsIndex = -1
+            var path = listSourceModel[window.currentSourceIndex].currentPath
+            path[currentSourceDepth] = index
+            listSourceModel[window.currentSourceIndex].currentPath = path
+
+            window.windowViewsModel.append({ component: listSourceModel[window.currentSourceIndex].listViews[currentSourceDepth].viewComponent,
+                                             componentId: listSourceModel[window.currentSourceIndex].listViews[currentSourceDepth].viewId,
+                                             componentDepth: currentSourceDepth+1 })
         }
     }
 }
diff --git a/qml/QuickNewsReader/content/view/JournalDelegate.qml b/qml/QuickNewsReader/content/view/JournalDelegate.qml
deleted file mode 100644 (file)
index 9e4f45e..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 1.0
-
-Item {
-    id: delegate
-
-    width: delegate.ListView.view.width; height: 60
-
-    Text {
-        text: journalName
-        color: delegate.ListView.isCurrentItem ? "white" : "black"
-        font { family: "Helvetica"; pixelSize: 16; bold: true }
-        anchors {
-            left: parent.left; leftMargin: 15
-            verticalCenter: parent.verticalCenter
-        }
-    }
-
-    BusyIndicator {
-        scale: 0.6
-        on: delegate.ListView.isCurrentItem && window.loading
-        anchors { right: parent.right; rightMargin: 10; verticalCenter: parent.verticalCenter }
-    }
-
-    Rectangle {
-        width: delegate.width; height: 1; color: "#cccccc"
-        anchors.bottom: delegate.bottom
-        visible: delegate.ListView.isCurrentItem ? false : true
-    }
-    Rectangle {
-        width: delegate.width; height: 1; color: "white"
-        visible: delegate.ListView.isCurrentItem ? false : true
-    }
-
-    MouseArea {
-        anchors.fill: delegate
-        onClicked: {
-            delegate.ListView.view.currentIndex = index
-            window.currentJournalIndex = index
-            window.currentCategoryIndex = 0
-            window.currentNewsIndex = 0
-        }
-    }
-}
diff --git a/qml/QuickNewsReader/content/view/Journals.qml b/qml/QuickNewsReader/content/view/Journals.qml
deleted file mode 100644 (file)
index be35893..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-import QtQuick 1.0
-
-Rectangle {
-    id: journalsRect
-    width: 150
-    color: "#dfdfdf"
-
-    ListView {
-        focus: true
-        id: journals
-        x: 0; y: 0
-        width: 150; height: window.height
-        currentIndex: currentJournalIndex
-        model: journalList
-        footer: quitButtonDelegate
-        delegate: JournalDelegate {}
-        highlight: Rectangle { color: "steelblue" }
-        highlightMoveSpeed: 9999999
-    }
-    ScrollBar { scrollArea: journals; height: journals.height; width: 8; anchors.right: journals.right }
-}
index b6a7c1b..1e4f022 100644 (file)
@@ -8,7 +8,7 @@ Item {
         x: 0; y: 0
         id: list
         width: newsRect.width; height: window.height
-        model: currentJournal.newsModel
+        model: currentSource.listModels[componentDepth-1]
         delegate: NewsDelegate { }
     }
     ScrollBar { scrollArea: list; height: list.height; width: 8; anchors.right: list.right }
index 517e86f..a0db12d 100644 (file)
@@ -78,9 +78,23 @@ Item {
 
         onDoubleClicked: {
             if (typeof detailedContent != "undefined") {
+                var currentSourceDepth = delegate.ListView.view.model.sourceDepth
+
+                // here we remove everything in viewsModel after index "nextSourceDepth"
+                while(window.windowViewsModel.count>currentSourceDepth+1)
+                    window.windowViewsModel.remove(window.windowViewsModel.count-1)
+
+                delegate.ListView.view.currentIndex = index
+                var path = listSourceModel[window.currentSourceIndex].currentPath
+                path[currentSourceDepth] = index
+                listSourceModel[window.currentSourceIndex].currentPath = path
+
+                window.windowViewsModel.append({ component: listSourceModel[window.currentSourceIndex].listViews[currentSourceDepth].viewComponent,
+                                                 componentId: listSourceModel[window.currentSourceIndex].listViews[currentSourceDepth].viewId,
+                                                 componentDepth: currentSourceDepth+1 })
+
                 //newsDetailRect.webViewAction.enabled = false
-                currentNewsIndex = index
-           ////     journalsRect.x -= window.width + newsRect.x
+           ////     sourcesRect.x -= window.width + newsRect.x
                 //newsDetailRect.webViewAction.enabled = true
                 //newsDetailRect.webViewAction.trigger()
             }
index 211b395..049de65 100644 (file)
@@ -5,19 +5,21 @@ Item {
     id: newsDetailRect
     width: window.width; height: window.height
 
-    function getNewsModelItem(newsIndex, prop)
+    function getNewsModelItem(prop)
     {
-        if( typeof currentJournal.newsModel.get(newsIndex) != "undefined" )
-            if( typeof currentJournal.newsModel.get(newsIndex)[prop] != "undefined" )
-                return currentJournal.newsModel.get(newsIndex)[prop]
+        var newsIndex = listSourceModel[window.currentSourceIndex].currentPath[componentDepth-1]
+
+        if( typeof currentSource.listModels[componentDepth-1].get(newsIndex) != "undefined" )
+            if( typeof currentSource.listModels[componentDepth-1].get(newsIndex)[prop] != "undefined" )
+                return currentSource.listModels[componentDepth-1].get(newsIndex)[prop]
 
         return ""
     }
 
-    property string urllink: getNewsModelItem(currentNewsIndex, 'link')
-    property string htmlcontent: getNewsModelItem(currentNewsIndex, 'detailedContent')
-    property string title: getNewsModelItem(currentNewsIndex, 'title')
-    property string image: getNewsModelItem(currentNewsIndex, 'image')
+    property string urllink: getNewsModelItem('link')
+    property string htmlcontent: getNewsModelItem('detailedContent')
+    property string title: getNewsModelItem('title')
+    property string image: getNewsModelItem('image')
 
     VisualItemModel {
         id: itemModel
diff --git a/qml/QuickNewsReader/content/view/SourceDelegate.qml b/qml/QuickNewsReader/content/view/SourceDelegate.qml
new file mode 100644 (file)
index 0000000..dfb2880
--- /dev/null
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+Item {
+    id: delegate
+    width: delegate.ListView.view.width; height: 60
+
+    Text {
+        text: listSourceModel[index].name
+        color: delegate.ListView.isCurrentItem ? "white" : "black"
+        font { family: "Helvetica"; pixelSize: 16; bold: true }
+        anchors {
+            left: parent.left; leftMargin: 15
+            verticalCenter: parent.verticalCenter
+        }
+    }
+
+    BusyIndicator {
+        scale: 0.6
+        on: delegate.ListView.isCurrentItem && window.loading
+        anchors { right: parent.right; rightMargin: 10; verticalCenter: parent.verticalCenter }
+    }
+
+    Rectangle {
+        width: delegate.width; height: 1; color: "#cccccc"
+        anchors.bottom: delegate.bottom
+        visible: delegate.ListView.isCurrentItem ? false : true
+    }
+    Rectangle {
+        width: delegate.width; height: 1; color: "white"
+        visible: delegate.ListView.isCurrentItem ? false : true
+    }
+
+    MouseArea {
+        anchors.fill: delegate
+        onClicked: {
+            if( delegate.ListView.view.currentIndex !== index )
+            {
+                // here we remove everything in viewsModel after index our depth
+                while(window.windowViewsModel.count>1)
+                    window.windowViewsModel.remove(window.windowViewsModel.count-1)
+
+                delegate.ListView.view.currentIndex = index
+
+                window.windowViewsModel.append({ component: listSourceModel[index].listViews[0].viewComponent,
+                                                 componentId: listSourceModel[index].listViews[0].viewId,
+                                                 componentDepth: 1 })
+
+                listSourceModel[window.currentSourceIndex].currentPath = [index]
+
+                window.currentSourceIndex = index
+            }
+        }
+    }
+}
diff --git a/qml/QuickNewsReader/content/view/Sources.qml b/qml/QuickNewsReader/content/view/Sources.qml
new file mode 100644 (file)
index 0000000..ab3e640
--- /dev/null
@@ -0,0 +1,31 @@
+import QtQuick 1.0
+
+Rectangle {
+    id: sourcesRect
+    width: 150; height: window.height
+    color: "#dfdfdf"
+
+    ListModel {
+        id: sourceList
+
+        ListElement {  }
+        ListElement {  }
+        ListElement {  }
+    }
+
+    ListView {
+        focus: true
+        id: sources
+        x: 0; y: 0
+        width: 150; height: window.height
+        currentIndex: currentSourceIndex
+        model: sourceList
+        footer: quitButtonDelegate
+        delegate: SourceDelegate {}
+        highlight: Rectangle { color: "steelblue" }
+        highlightMoveSpeed: 9999999
+    }
+    ScrollBar { scrollArea: sources; height: sources.height; width: 8; anchors.right: sources.right }
+
+    Component.onCompleted: sources.currentIndex = -1
+}
index 0c5cf69..ebee529 100644 (file)
@@ -7,58 +7,23 @@ Rectangle {
     id: window
     width: 800; height: 480
 
-    property int currentJournalIndex: 0
-    property int currentCategoryIndex: -1
-    property int currentNewsIndex: -1
+    property int currentSourceIndex: 0
 
-    property list<JournalModel> listJournalModel: [
-        LeMondeJournalModel{},
-        FavoriteFeedsJournalModel{},
-        YahooJournalModel{}
+    property list<SourceModel> listSourceModel: [
+        LeMondeSourceModel{},
+        FavoriteFeedsSourceModel{},
+        YahooSourceModel{}
     ]
 
     ListModel {
-        id: journalList
+        id: viewsModel
 
-        ListElement {
-            journalName: 'Le Monde'
-            journalHierarchy: [
-                // list of journals
-                ListElement { component: "content/view/Journals.qml"; componentId: "journalsRect" },
-                // list of categories for a given journal
-                ListElement { component: "content/view/Categories.qml"; componentId: "categoriesRect" },
-                // list of news for a given category
-                ListElement { component: "content/view/News.qml"; componentId: "newsRect" },
-                // Details for a given news
-                ListElement { component: "content/view/NewsDetail.qml"; componentId: "newsDetailRect" }
-            ]
-        }
-        ListElement {
-            journalName: 'Favorite RSS'
-            journalHierarchy: [
-                // list of journals
-                ListElement { component: "content/view/Journals.qml"; componentId: "journalsRect" },
-                // list of categories for a given journal
-                ListElement { component: "content/view/Categories.qml"; componentId: "categoriesRect" },
-                // list of news for a given category
-                ListElement { component: "content/view/News.qml"; componentId: "newsRect" }
-            ]
-        }
-        ListElement {
-            journalName: 'Yahoo! News'
-            journalHierarchy: [
-                // list of journals
-                ListElement { component: "content/view/Journals.qml"; componentId: "journalsRect" },
-                // list of categories for a given journal
-                ListElement { component: "content/view/Categories.qml"; componentId: "categoriesRect" },
-                // list of news for a given category
-                ListElement { component: "content/view/News.qml"; componentId: "newsRect" }
-            ]
-        }
+        ListElement { component: "content/view/Sources.qml"; componentId: "sourcesRect"; componentDepth: 0 }
     }
 
-    property variant currentJournal: listJournalModel[currentJournalIndex]
-    property bool loading: currentJournal.loading
+    property variant currentSource: listSourceModel[currentSourceIndex]
+    property bool loading: currentSource.loading
+    property ListModel windowViewsModel: viewsModel
 
     ListView {
         id: viewsList
@@ -68,7 +33,7 @@ Rectangle {
         snapMode: ListView.SnapOneItem
         flickDeceleration: 500
 
-        model: journalList.get(currentJournalIndex).journalHierarchy
+        model: viewsModel
         delegate: Loader {
             id: componentId
             source: component