Ugly implementation of next unread item between different categories

Leonardo Robol [2011-10-28 08:01]
Ugly implementation of next unread item between different categories
Filename
images/larss.png
larss/mainwindow.cpp
larss/rssparser.cpp
qtresources.qrc
ui/editcategorydialog.ui
ui/editfeeddialog.ui
ui/mainwindow.ui
diff --git a/images/larss.png b/images/larss.png
index fb831ab..c926d8a 100644
Binary files a/images/larss.png and b/images/larss.png differ
diff --git a/larss/mainwindow.cpp b/larss/mainwindow.cpp
index 7966b95..7d626c7 100644
--- a/larss/mainwindow.cpp
+++ b/larss/mainwindow.cpp
@@ -75,12 +75,14 @@ MainWindow::MainWindow(QWidget *parent) :
         ui->feedTreeView->expand(index);
     }

-    systrayIcon = new QSystemTrayIcon (QIcon (":/images/larss.png"));
-    systrayIcon->setVisible(true);
+    // Create the systray icon
+    QIcon larssIcon(":larss32.png");
+    systrayIcon = new QSystemTrayIcon (larssIcon);
+    systrayIcon->show();

+    // Set the icon for the window.
     poller->connect(poller, SIGNAL(newElementsNotification(QString,QString)),
                     this, SLOT(showNewElement(QString,QString)));
-
 }

 MainWindow::~MainWindow()
@@ -214,7 +216,113 @@ void Larss::MainWindow::loadFeed(const QModelIndex& index)
 void Larss::MainWindow::on_actionNext_unread_news_triggered()
 {
     QModelIndex index = ui->newsTableView->selectionModel()->currentIndex();
-    int nextUnread = rssParser->getNextUnread(index);
+    QItemSelection startingFeedSelection = ui->feedTreeView->selectionModel()->selection();
+    int startingNewsRow = ui->newsTableView->currentIndex().row();
+    QModelIndex feedIndex = ui->feedTreeView->currentIndex();
+    QModelIndex categoryIndex;
+    int startingCategoryRow;
+    int nextUnread;
+
+    // Store the category or the index that is selected now, to be sure that after
+    // a complete round searching for new items we don't begin one time more.
+    FeedNode *selectedNode = feedModel->itemFromIndex(feedIndex);
+    int categoriesNumber = feedModel->rowCount();
+
+    if (selectedNode->type() == FeedNode::Category)
+    {
+        startingCategoryRow = feedIndex.row();
+
+        // Search for a feed, not a category
+        while (feedModel->rowCount(feedIndex) == 0)
+        {
+            // Step to the next category, since this is empty
+            if (feedIndex.row() == categoriesNumber - 1)
+                feedIndex = feedModel->index(0, 0);
+            else
+                feedIndex = feedModel->index(feedIndex.row() + 1, 0);
+
+            // Check if that was the starting category, in that case they are all empty
+            // so simply do nothing
+            if (feedIndex.row() == startingCategoryRow)
+            {
+                ui->feedTreeView->selectionModel()->select(startingFeedSelection, QItemSelectionModel::SelectCurrent);
+                on_feedTreeView_clicked(ui->feedTreeView->currentIndex());
+                ui->newsTableView->selectRow(startingNewsRow);
+                loadFeed (ui->newsTableView->selectionModel()->currentIndex());
+                return;
+            }
+        }
+
+        // Now we have a category with at least one child, so select id
+        categoryIndex = feedIndex;
+        feedIndex = feedIndex.child(0, 0);
+    }
+    else
+        categoryIndex = feedIndex.parent();
+
+    // Store the row of the starting catogory
+    startingCategoryRow = categoryIndex.row();
+
+    while ((nextUnread = rssParser->getNextUnread(index)) <= 0)
+    {
+        // If we have an invalid feedIndex return
+        if (!feedIndex.isValid())
+        {
+            ui->feedTreeView->selectionModel()->select(startingFeedSelection, QItemSelectionModel::SelectCurrent);
+            on_feedTreeView_clicked(ui->feedTreeView->currentIndex());
+            ui->newsTableView->selectRow(startingNewsRow);
+            loadFeed (ui->newsTableView->selectionModel()->currentIndex());
+            return;
+        }
+
+        // Check if there is a category next in which to step, if there
+        // are no more feeds in this.
+        if (feedIndex.row() == feedModel->rowCount(categoryIndex) - 1)
+        {
+            // Continue to iterate over categories while we found a non
+            // empty one OR we arrive to the starting one.
+            do
+            {
+                if (categoryIndex.row() < feedModel->rowCount())
+                    categoryIndex = feedModel->index(categoryIndex.row() + 1, 0);
+                else
+                    categoryIndex = feedModel->index(0, 0);
+            } while (feedModel->rowCount(categoryIndex) == 0 &&
+                     categoryIndex.row() != startingCategoryRow);
+
+            // We have done a complete round
+            if (categoryIndex.row() == startingCategoryRow)
+            {
+                ui->feedTreeView->selectionModel()->select(startingFeedSelection, QItemSelectionModel::SelectCurrent);
+                on_feedTreeView_clicked(ui->feedTreeView->currentIndex());
+                ui->newsTableView->selectRow(startingNewsRow);
+                loadFeed (ui->newsTableView->selectionModel()->currentIndex());
+                return;
+            }
+
+            // Got the Feed and select the first element.
+            feedIndex = categoryIndex.child(0, 0);
+        }
+        else
+        {
+            // Otherwise step to the next feed
+            feedIndex = categoryIndex.child(feedIndex.row() + 1, 0);
+        }
+
+        ui->feedTreeView->selectionModel()->select(QItemSelection(feedIndex, feedIndex), QItemSelectionModel::SelectCurrent);
+        on_feedTreeView_clicked(feedIndex);
+        index = rssParser->index(0, 0);
+
+        // This feed may be unread, so in that case, read it.
+        if (rssParser->record(index.row()).value("read").toInt() == 0)
+        {
+            ui->newsTableView->selectRow(0);
+            loadFeed(index);
+            return;
+        }
+    }
+
+    // Selec the next unread news in the feed.
     if (nextUnread > 0)
     {
         ui->newsTableView->selectRow(nextUnread);
@@ -222,6 +330,7 @@ void Larss::MainWindow::on_actionNext_unread_news_triggered()
     }
 }

+
 void Larss::MainWindow::on_actionUpdate_this_feed_triggered()
 {
     QModelIndex index = ui->feedTreeView->selectionModel()->currentIndex();
diff --git a/larss/rssparser.cpp b/larss/rssparser.cpp
index 62c0b66..36bda29 100644
--- a/larss/rssparser.cpp
+++ b/larss/rssparser.cpp
@@ -95,7 +95,7 @@ Larss::RssParser::data(const QModelIndex &idx, int role) const
     // Manage a nice rendering of Time
     if (role == Qt::DisplayRole && idx.column() == 6)
     {
-        return (QDateTime::fromTime_t(QSqlTableModel::data(idx, role).toInt()).toString());
+        return (QDateTime::fromTime_t(QSqlTableModel::data(idx, role).toInt()).toString("dd/MM/yyyy hh:mm"));
     }

     // Call the default implementaton in almost every case
diff --git a/qtresources.qrc b/qtresources.qrc
index ffdc804..af96e2f 100644
--- a/qtresources.qrc
+++ b/qtresources.qrc
@@ -1,5 +1,6 @@
 <RCC>
     <qresource prefix="/images">
-        <file>images/larss.png</file>
+        <file alias="larss.png">images/larss.png</file>
+        <file alias="larss32.png">images/larss32.png</file>
     </qresource>
 </RCC>
diff --git a/ui/editcategorydialog.ui b/ui/editcategorydialog.ui
index bba5ffa..57ad1ba 100644
--- a/ui/editcategorydialog.ui
+++ b/ui/editcategorydialog.ui
@@ -11,7 +11,7 @@
    </rect>
   </property>
   <property name="windowTitle">
-   <string>Dialog</string>
+   <string>Add a new category</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_2">
    <item>
diff --git a/ui/editfeeddialog.ui b/ui/editfeeddialog.ui
index 387abc2..9af81c6 100644
--- a/ui/editfeeddialog.ui
+++ b/ui/editfeeddialog.ui
@@ -11,7 +11,7 @@
    </rect>
   </property>
   <property name="windowTitle">
-   <string>Dialog</string>
+   <string>Add a new feed</string>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout">
    <item>
diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui
index 5c4de59..7d7e7e4 100644
--- a/ui/mainwindow.ui
+++ b/ui/mainwindow.ui
@@ -13,6 +13,10 @@
   <property name="windowTitle">
    <string>Larss 0.1</string>
   </property>
+  <property name="windowIcon">
+   <iconset resource="../qtresources.qrc">
+    <normaloff>:/images/larss.png</normaloff>:/images/larss.png</iconset>
+  </property>
   <widget class="QWidget" name="centralWidget">
    <layout class="QVBoxLayout" name="verticalLayout_3">
     <item>
@@ -176,6 +180,8 @@
    <header>QtWebKit/QWebView</header>
   </customwidget>
  </customwidgets>
- <resources/>
+ <resources>
+  <include location="../qtresources.qrc"/>
+ </resources>
  <connections/>
 </ui>
ViewGit