r2635 - in trunk/src/target/OM-2007.2/applications/openmoko-feedreader2: . src

zecke at sita.openmoko.org zecke at sita.openmoko.org
Sat Aug 4 21:12:23 CEST 2007


Author: zecke
Date: 2007-08-04 21:12:08 +0200 (Sat, 04 Aug 2007)
New Revision: 2635

Modified:
   trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/ChangeLog
   trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/application-data.h
   trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/callbacks.c
   trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/feed-data.c
   trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/feed-data.h
Log:
2007-08-04  Holger Hans Peter Freyther  <zecke at selfish.org>

        Move code around and we end up with an almost complete feed-data
        implementation. The main page to select feeds is still missing.

        * src/application-data.h:
        * src/callbacks.c:
        * src/feed-data.c:
        (rss_filter_entries):
        (rss_sort_dates):
        (add_mrss_item):
        (feed_update_thread):
        (feed_data_finalize):
        (feed_data_init):
        (feed_data_class_init):
        (feed_filter_init):
        (feed_sort_init):
        (feed_data_update_all):
        (feed_data_set_cache):
        (feed_data_load_from_cache):
        (feed_date_cell_data_func):
        * src/feed-data.h:



Modified: trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/ChangeLog
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/ChangeLog	2007-08-04 18:06:16 UTC (rev 2634)
+++ trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/ChangeLog	2007-08-04 19:12:08 UTC (rev 2635)
@@ -1,3 +1,26 @@
+2007-08-04  Holger Hans Peter Freyther  <zecke at selfish.org>
+
+        Move code around and we end up with an almost complete feed-data
+        implementation. The main page to select feeds is still missing.
+
+        * src/application-data.h:
+        * src/callbacks.c:
+        * src/feed-data.c:
+        (rss_filter_entries):
+        (rss_sort_dates):
+        (add_mrss_item):
+        (feed_update_thread):
+        (feed_data_finalize):
+        (feed_data_init):
+        (feed_data_class_init):
+        (feed_filter_init):
+        (feed_sort_init):
+        (feed_data_update_all):
+        (feed_data_set_cache):
+        (feed_data_load_from_cache):
+        (feed_date_cell_data_func):
+        * src/feed-data.h:
+
 2007-08-03  Holger Hans Peter Freyther  <zecke at selfish.org>
 
         Implement the feed_item_view which will be used to show

Modified: trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/application-data.h
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/application-data.h	2007-08-04 18:06:16 UTC (rev 2634)
+++ trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/application-data.h	2007-08-04 19:12:08 UTC (rev 2635)
@@ -37,33 +37,4 @@
     FeedItemView      *view;
 };
 
-/*
- * Instead of having a real model we have this... as our feed
- * model
- * Either there is a link or text is included. And we contain
- * the sourcename of the feed. This will be used by the ModelFilter
- * to implement the FilterMenu
- */
-enum {
-    RSS_READER_COLUMN_AUTHOR,
-    RSS_READER_COLUMN_SUBJECT,
-    RSS_READER_COLUMN_DATE,
-    RSS_READER_COLUMN_LINK,     /* Is this something like spiegel.de and only has a link */
-    RSS_READER_COLUMN_TEXT,     /* Either link is NULL, or this contains the article     */
-    RSS_READER_COLUMN_TEXT_TYPE,/* The Text Type of Atom feeds HTML, plain...            */
-    RSS_READER_COLUMN_CATEGORY, /* The category as shown in the filter box               */
-    RSS_READER_COLUMN_SOURCE,   /* the source of this entry, the URL of the feed, not the atom <source> */
-    RSS_READER_NUM_COLS,
-};
-
-/**
- * text type for atom feeds, default is none
- */
-enum {
-    RSS_READER_TEXT_TYPE_NONE,
-    RSS_READER_TEXT_TYPE_PLAIN,
-    RSS_READER_TEXT_TYPE_HTML,
-    RSS_READER_TEXT_TYPE_UNKNOWN
-};
-
 #endif

Modified: trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/callbacks.c
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/callbacks.c	2007-08-04 18:06:16 UTC (rev 2634)
+++ trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/callbacks.c	2007-08-04 19:12:08 UTC (rev 2635)
@@ -38,20 +38,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-struct FeedEntry {
-    gchar *category;
-    gchar *url;
-};
-
-static struct FeedEntry s_feeds[] = {
-    { "OpenMoko",   "http://planet.openmoko.org/atom.xml"  },
-    { "GNOME"   ,   "http://planet.gnome.org/atom.xml"     },
-    { "KDE",        "http://planet.kde.org/rss20.xml"      },
-    { "Linux Togo", "http://planet.linuxtogo.org/atom.xml" },
-    { "zecke"   , "http://zecke.blogspot.com/atom.xml"     },
-};
-static const int NUMBER_OF_FEEDS = sizeof(s_feeds)/sizeof(s_feeds[0]);
-
 static void remove_container_item( GtkWidget *item, GtkWidget *container ) {
     gtk_container_remove(GTK_CONTAINER(container), item);
 }
@@ -92,194 +78,7 @@
     return TRUE;
 }
 
-void cb_subscribe_button_clicked( GtkButton *btn, struct RSSReaderData *data ) {}
-
-
-static
-void add_mrss_item ( struct RSSReaderData *data, const mrss_t *rss_data, const gchar *url, const gchar *category)
-{
-    GtkTreeIter iter;
-    mrss_item_t *item = rss_data->item;
-
-    while ( item ) {
-        gint content_type = RSS_READER_TEXT_TYPE_NONE;
-        gchar *description = item->description;
-
-        /*
-         * let us try to find the 'content' tag
-         * and then extract the type
-         */
-        if ( !description && rss_data->version == MRSS_VERSION_ATOM_1_0 && item->other_tags ) {
-            for ( mrss_tag_t *tag = item->other_tags; tag; tag = tag->next ) {
-                if ( strcmp( tag->name, "content" ) == 0 ) {
-                    description = tag->value;
-
-                    for ( mrss_attribute_t *attribute = tag->attributes; attribute; attribute = attribute->next ) {
-                        /*
-                         * Detect the type of the content. Currently we know about text/plain and html
-                         */
-                        if ( strcmp( attribute->name, "type" ) == 0 ) {
-                            if ( strcmp( attribute->value, "plain" ) == 0 ) {
-                                content_type = RSS_READER_TEXT_TYPE_PLAIN;
-                            } else if ( strcmp( attribute->name, "html" ) == 0 ) {
-                                content_type = RSS_READER_TEXT_TYPE_HTML;
-                            } else {
-                                content_type = RSS_READER_TEXT_TYPE_UNKNOWN;
-                            }
-                        }
-                    }
-
-                    /* we are done */
-                    break;
-                }
-            }
-        }
-
-        /*
-         * update the model here. The order in gtk_list_store_set must match
-         * with the order in application-data.h
-         */
-        RSSRFCDate *date = RSS_RFC_DATE(rss_rfc_date_new ());
-        rss_rfc_date_set (date, item->pubDate ? item->pubDate : "");
-        gdk_threads_enter();
-        gtk_list_store_append( data->feed_data, &iter );
-        gtk_list_store_set   ( data->feed_data, &iter,
-                RSS_READER_COLUMN_AUTHOR, g_strdup( item->author  ),
-                RSS_READER_COLUMN_SUBJECT,g_strdup( item->title   ),
-                RSS_READER_COLUMN_DATE,   date,
-                RSS_READER_COLUMN_LINK,   g_strdup( item->link    ),
-                RSS_READER_COLUMN_TEXT,   g_strdup( description   ),
-                RSS_READER_COLUMN_TEXT_TYPE, content_type          ,
-                RSS_READER_COLUMN_CATEGORY, g_strdup( category ),
-                RSS_READER_COLUMN_SOURCE,  g_strdup( url ),
-                -1 );
-        gdk_threads_leave();
-        item = item->next;
-    }
-
-}
-
 /*
- * asynchronous update thread!
- * This breaks with ATK+. See http://wiki.ekiga.org/index.php/Bug::ATK::Threads and bugs
- * #329454, #349047, #335838
- *
- * DISCUSSION:
- *    - Should everything be updated?
- *    - What happens if we update but some feeds can not be connected? Should the old
- *      data be kept?
- *      ( Just keeping/building a new ListStore does not help, we need a model that consists
- *        out of models... )
- *
- *
- * Clear the current model
- *
- * For each feed:
- *    - Get the Data
- *    - Fill the GtkListStore
- *
- * Refilter the model...
- */
-static void feed_update_thread( struct RSSReaderData *data ) {
-    for ( int i = 0; i < NUMBER_OF_FEEDS; ++i ) {
-        mrss_t *rss_data;
-        gchar *url = s_feeds[i].url;
-        gchar *buffer = NULL;
-        int  size;
-        int ret = mrss_parse_url_and_transfer_buffer( url, &rss_data, NULL, &buffer, &size );
-        if ( ret ) {
-            /* TODO use the footer to report error? */
-            g_debug( "parse_url failed.." );
-            continue;
-        }
-
-        /*
-         * create the new item(s)
-         */
-        add_mrss_item (data, rss_data, url, s_feeds[i].category);
-
-        /*
-         * now cache the feed, a bit inefficient as we do not write to a file directly
-         */
-        if (buffer) {
-            moko_cache_write_object (data->cache, url, buffer, size, NULL);
-            free (buffer);
-        }
-
-        mrss_free( rss_data );
-    }
-
-    gdk_threads_enter();
-    filter_feeds( data );
-    gdk_threads_leave();
-}
-
-/**
- * read the feeds from disk
- * Similiar to the Thread, but
- *  -We do not run from a thread, so no gdk locking is necessary
- *  -We do not load from a url but from the cache
- *  -We do not need to cache ;)
- */
-void load_data_from_cache (struct RSSReaderData *data)
-{
-    gsize size;
-
-    for ( int i = 0; i < NUMBER_OF_FEEDS; ++i ) {
-        mrss_t *rss_data;
-        gchar *url = s_feeds[i].url;
-        g_debug ("Reading cached object '%s'\n", url);
-        gchar *content = moko_cache_read_object (data->cache, url, &size);
-        if ( !content || size == -1 ) {
-            g_debug ("Noting in the cache for '%s'\n", url);
-            continue;
-        }
-
-        int ret = mrss_parse_buffer( content, size, &rss_data );
-        if ( ret ) {
-            /* TODO use the footer to report error? */
-            g_debug( "parse_buffer of '%s' failed with '%d'", url, ret );
-            continue;
-        }
-
-        /*
-         * create the new item(s)
-         */
-        gdk_threads_leave();
-        add_mrss_item (data, rss_data, url, s_feeds[i].category);
-        gdk_threads_enter();
-
-        g_free (content);
-        mrss_free (rss_data);
-    }
-
-    g_debug ("Done loading from cache\n");
-}
-
-/*
- * Start the update-job in a separate thread
- */
-void cb_refresh_all_button_clicked( GtkButton *btn, struct RSSReaderData *data ) {
-    /*
-     * once we have a SCM make it not clear the list but remove all items
-     * with the same URL
-     */
-    gtk_list_store_clear( data->feed_data );
-
-    /*
-     * do the complete work in a new thread
-     */
-    GError *error = NULL;
-    (void)g_thread_create( (GThreadFunc)feed_update_thread, data, FALSE, &error );
-
-    /* XXX FOOTER do error reporting */
-    if ( error != NULL ) {
-        fprintf( stderr, "Can not create thread %s:%d '%s'\n", __FILE__, __LINE__, error->message );
-    }
-
-}
-
-/*
  * TODO: Update the text and make it rich text.
  *
  * TODO: Decide if a browser should be opened or not... e.g. spiegel.de only distributes

Modified: trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/feed-data.c
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/feed-data.c	2007-08-04 18:06:16 UTC (rev 2634)
+++ trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/feed-data.c	2007-08-04 19:12:08 UTC (rev 2635)
@@ -25,24 +25,271 @@
  */
 
 #include "feed-data.h"
+#include "feed-configuration.h"
+#include "rfcdate.h"
 
+#include <mrss.h>
+#include <string.h>
+#include <stdlib.h>
+
+    
+static gboolean
+rss_filter_entries (GtkTreeModel *model, GtkTreeIter *iter, FeedFilter *data)
+{
+    /*
+     * filter the category
+     */
+    if (!data->is_all_filter) {
+        gchar *category;
+        gtk_tree_model_get (model, iter,  RSS_READER_COLUMN_CATEGORY, &category,  -1);
+
+        /*
+         * how does this happen?
+         */
+        if (!category)
+            return FALSE;
+
+        if (strcmp(category, data->filter_string) != 0)
+            return FALSE;
+
+        g_free (category);
+    }
+
+
+    /*
+     * filter the text according to the search now
+     */
+    if (data->filter_string) {
+        gchar *text;
+
+        #define FILTER_SEARCH(column)                                      \
+        gtk_tree_model_get (model, iter, column, &text, -1);               \
+        if (text && strcasestr (text, data->filter_string) != NULL) {      \
+            g_free (text);                                                 \
+            return TRUE;                                                   \
+        }
+
+        FILTER_SEARCH(RSS_READER_COLUMN_AUTHOR)
+        FILTER_SEARCH(RSS_READER_COLUMN_SUBJECT)
+        FILTER_SEARCH(RSS_READER_COLUMN_SOURCE)
+        FILTER_SEARCH(RSS_READER_COLUMN_LINK)
+        FILTER_SEARCH(RSS_READER_COLUMN_TEXT)
+
+        #undef FILTER_SEARCH
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*
+ * sort the dates according to zsort. Ideally they should sort ascending
+ */
+static gint
+rss_sort_dates (GtkTreeModel *model, GtkTreeIter *_left, GtkTreeIter *_right, gpointer that)
+{
+    RSSRFCDate *left, *right;
+    gtk_tree_model_get (model, _left,  RSS_READER_COLUMN_DATE, &left,  -1);
+    gtk_tree_model_get (model, _right, RSS_READER_COLUMN_DATE, &right, -1);
+
+    int result;
+    if (left == NULL)
+        result = -1;
+    else if (right == NULL)
+        result = 1;
+    else
+        result = rss_rfc_date_compare (left, right);
+
+    if (left)
+        g_object_unref (left);
+    if (right)
+        g_object_unref (right);
+
+    return result;
+}
+
+/*
+ * Add items from rss_data to the GtkListStore/FeedData
+ */
+static void
+add_mrss_item (FeedData *data, const mrss_t *rss_data, const gchar *url, const gchar *category)
+{
+    GtkTreeIter iter;
+    mrss_item_t *item = rss_data->item;
+
+    while (item) {
+        gint content_type = RSS_READER_TEXT_TYPE_NONE;
+        gchar *description = item->description;
+
+        /*
+         * let us try to find the 'content' tag
+         * and then extract the type
+         */
+        if (!description && rss_data->version == MRSS_VERSION_ATOM_1_0 && item->other_tags) {
+            for (mrss_tag_t *tag = item->other_tags; tag; tag = tag->next) {
+                if (strcmp( tag->name, "content") == 0) {
+                    description = tag->value;
+
+                    for (mrss_attribute_t *attribute = tag->attributes; attribute; attribute = attribute->next) {
+                        /*
+                         * Detect the type of the content. Currently we know about text/plain and html
+                         */
+                        if ( strcmp( attribute->name, "type" ) == 0 ) {
+                            if ( strcmp( attribute->value, "plain" ) == 0 ) {
+                                content_type = RSS_READER_TEXT_TYPE_PLAIN;
+                            } else if ( strcmp( attribute->name, "html" ) == 0 ) {
+                                content_type = RSS_READER_TEXT_TYPE_HTML;
+                            } else {
+                                content_type = RSS_READER_TEXT_TYPE_UNKNOWN;
+                            }
+                        }
+                    }
+
+                    /* we are done */
+                    break;
+                }
+            }
+        }
+
+        /*
+         * update the model here. The order in gtk_list_store_set must match
+         * with the order in application-data.h
+         */
+        RSSRFCDate *date = RSS_RFC_DATE(rss_rfc_date_new ());
+        rss_rfc_date_set (date, item->pubDate ? item->pubDate : "");
+        gdk_threads_enter();
+        gtk_list_store_append ( GTK_LIST_STORE (data), &iter );
+        gtk_list_store_set    ( GTK_LIST_STORE (data), &iter,
+                RSS_READER_COLUMN_AUTHOR, g_strdup( item->author  ),
+                RSS_READER_COLUMN_SUBJECT,g_strdup( item->title   ),
+                RSS_READER_COLUMN_DATE,   date,
+                RSS_READER_COLUMN_LINK,   g_strdup( item->link    ),
+                RSS_READER_COLUMN_TEXT,   g_strdup( description   ),
+                RSS_READER_COLUMN_TEXT_TYPE, content_type          ,
+                RSS_READER_COLUMN_CATEGORY, g_strdup( category ),
+                RSS_READER_COLUMN_SOURCE,  g_strdup( url ),
+                -1 );
+        gdk_threads_leave();
+        item = item->next;
+    }
+
+}
+
+/*
+ * asynchronous update thread!
+ * This breaks with ATK+. See http://wiki.ekiga.org/index.php/Bug::ATK::Threads and bugs
+ * #329454, #349047, #335838
+ *
+ * DISCUSSION:
+ *    - Should everything be updated?
+ *    - What happens if we update but some feeds can not be connected? Should the old
+ *      data be kept?
+ *      ( Just keeping/building a new ListStore does not help, we need a model that consists
+ *        out of models... )
+ *
+ *
+ * Clear the current model
+ *
+ * For each feed:
+ *    - Get the Data
+ *    - Fill the GtkListStore
+ *
+ * Refilter the model...
+ */
+static void
+feed_update_thread (FeedData *data) {
+    GtkTreeModel *store = GTK_TREE_MODEL (feed_configuration_get_configuration ());
+    GtkTreeIter iter;
+
+    gboolean valid = gtk_tree_model_get_iter_first (store, &iter);
+    while (valid) {
+        mrss_t *rss_data;
+        gchar *url;
+        gchar *category;
+        gchar *buffer = NULL;
+        int  size;
+
+        gtk_tree_model_get (store, &iter, FEED_URL, &url, FEED_NAME, &category, -1);
+        int ret = mrss_parse_url_and_transfer_buffer( url, &rss_data, NULL, &buffer, &size );
+
+        if (ret) {
+            /* TODO use the footer to report error? */
+            g_debug ("parse_url failed.. '%s'", url);
+            goto next;
+        }
+
+        /*
+         * create the new item(s)
+         */
+        add_mrss_item (data, rss_data, url, category);
+
+        /*
+         * now cache the feed, a bit inefficient as we do not write to a file directly
+         */
+        if (buffer) {
+            moko_cache_write_object (data->cache, url, buffer, size, NULL);
+            free (buffer);
+        }
+
+        mrss_free( rss_data );
+
+next:
+        g_free (url);
+        g_free (category);
+        valid = gtk_tree_model_iter_next (store, &iter);
+    }
+
+#ifdef UNSURE
+    gdk_threads_enter();
+    filter_feeds( data );
+    gdk_threads_leave();
+#endif
+}
+
 G_DEFINE_TYPE(FeedData,   feed_data,   GTK_TYPE_LIST_STORE)
 G_DEFINE_TYPE(FeedFilter, feed_filter, GTK_TYPE_TREE_MODEL_FILTER)
 G_DEFINE_TYPE(FeedSort,   feed_sort,   GTK_TYPE_TREE_MODEL_SORT)
 
 static void
+feed_data_finalize (GObject* obj)
+{
+    if (RSS_FEED_DATA (obj)->cache) {
+        g_object_unref (RSS_FEED_DATA (obj)->cache);
+        RSS_FEED_DATA (obj)->cache = NULL;
+    }
+
+    G_OBJECT_CLASS (feed_data_parent_class)->finalize (obj);
+}
+
+static void
 feed_data_init (FeedData *data)
 {
+    GType types[RSS_READER_NUM_COLS];
+    types[0] = G_TYPE_STRING;     /* Author    */
+    types[1] = G_TYPE_STRING;     /* Subject   */
+    types[2] = RSS_TYPE_RFC_DATE; /* Date      */
+    types[3] = G_TYPE_STRING;     /* Link      */
+    types[4] = G_TYPE_STRING;     /* Text      */
+    types[5] = G_TYPE_INT;        /* Text_Type */
+    types[6] = G_TYPE_STRING;     /* Category/Feed name  */
+    types[7] = G_TYPE_STRING;     /* Source    */
+    gtk_list_store_set_column_types (GTK_LIST_STORE (data), RSS_READER_NUM_COLS, types);
 }
 
 static void
 feed_data_class_init (FeedDataClass *feed_class)
 {
+    G_OBJECT_CLASS(feed_class)->finalize = feed_data_finalize;
 }
 
 static void
 feed_filter_init (FeedFilter *filter)
 {
+    filter->is_all_filter = TRUE;
+    filter->category = NULL;
+    filter->filter_string = NULL,
+
+    gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter), (GtkTreeModelFilterVisibleFunc)rss_filter_entries, filter, NULL);
 }
 
 static void
@@ -51,8 +298,10 @@
 }
 
 static void
-feed_sort_init (FeedSort* init)
+feed_sort_init (FeedSort* sort)
 {
+    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), RSS_READER_COLUMN_DATE, GTK_SORT_DESCENDING);
+    gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sort), RSS_READER_COLUMN_DATE, rss_sort_dates, NULL, NULL);
 }
 
 static void
@@ -73,16 +322,77 @@
 void
 feed_data_update_all (FeedData* data)
 {
+    gtk_list_store_clear (GTK_LIST_STORE (data));
+
+    GError *error = NULL;
+    (void)g_thread_create( (GThreadFunc)feed_update_thread, data, FALSE, &error );
+
+    /* XXX FOOTER do error reporting */
+    if (error != NULL)
+        fprintf( stderr, "Can not create thread %s:%d '%s'\n", __FILE__, __LINE__, error->message );
 }
 
 void
 feed_data_set_cache (FeedData* data, MokoCache* cache)
 {
+    if (data->cache)
+        g_object_unref (data->cache);
+
+    g_object_ref (cache);
+    data->cache = cache; 
 }
 
+/*
+ * read the feeds from disk
+ * Similiar to the Thread, but
+ *  -We do not run from a thread, so no gdk locking is necessary
+ *  -We do not load from a url but from the cache
+ *  -We do not need to cache ;)
+ */
 void
 feed_data_load_from_cache (FeedData* data)
 {
+    gsize size;
+    GtkTreeIter iter;
+
+    gboolean valid = gtk_tree_model_get_iter_first ( GTK_TREE_MODEL (data), &iter);
+
+    while (valid) {
+        mrss_t *rss_data;
+        gchar *url;
+        gchar *category;
+
+        gtk_tree_model_get ( GTK_TREE_MODEL (data), &iter, FEED_URL, &url, FEED_NAME, &category, -1);
+        g_debug ("Reading cached object '%s'\n", url);
+        gchar *content = moko_cache_read_object (data->cache, url, &size);
+        if ( !content || size == -1 ) {
+            g_debug ("Noting in the cache for '%s'\n", url);
+            goto next;
+        }
+
+        int ret = mrss_parse_buffer( content, size, &rss_data );
+        if ( ret ) {
+            /* TODO use the footer to report error? */
+            g_debug( "parse_buffer of '%s' failed with '%d'", url, ret );
+            goto next;
+        }
+
+        /*
+         * create the new item(s)
+         */
+        gdk_threads_leave();
+        add_mrss_item (data, rss_data, url, category);
+        gdk_threads_enter();
+
+        g_free (content);
+        mrss_free (rss_data);
+    next:
+        g_free (url);
+        g_free (category);
+        valid = gtk_tree_model_iter_next ( GTK_TREE_MODEL (data), &iter);
+    }
+
+    g_debug ("Done loading from cache\n");
 }
 
 
@@ -121,3 +431,16 @@
 
     return obj;
 }
+
+
+
+void
+feed_date_cell_data_func (GtkTreeViewColumn *tree_column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
+{
+    RSSRFCDate *date;
+    gtk_tree_model_get (tree_model, iter, RSS_READER_COLUMN_DATE, &date, -1);
+
+    g_assert (date);
+    g_object_set ( G_OBJECT(renderer), "text", rss_rfc_date_as_string(date), NULL);
+    g_object_unref (G_OBJECT(date));
+}

Modified: trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/feed-data.h
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/feed-data.h	2007-08-04 18:06:16 UTC (rev 2634)
+++ trunk/src/target/OM-2007.2/applications/openmoko-feedreader2/src/feed-data.h	2007-08-04 19:12:08 UTC (rev 2635)
@@ -83,7 +83,7 @@
     /*
      * Do we have a filter set at all?
      */
-    gboolean all_filter;
+    gboolean is_all_filter;
 
     /*
      * The category to filter. Coming from the feed-configuration
@@ -108,7 +108,32 @@
     GtkTreeModelSortClass parent;
 };
 
+/**
+ * Column's of the FeedData model
+ */
+enum {
+    RSS_READER_COLUMN_AUTHOR,
+    RSS_READER_COLUMN_SUBJECT,
+    RSS_READER_COLUMN_DATE,
+    RSS_READER_COLUMN_LINK,     /* Is this something like spiegel.de and only has a link */
+    RSS_READER_COLUMN_TEXT,     /* Either link is NULL, or this contains the article     */
+    RSS_READER_COLUMN_TEXT_TYPE,/* The Text Type of Atom feeds HTML, plain...            */
+    RSS_READER_COLUMN_CATEGORY, /* The category as shown in the filter box               */
+    RSS_READER_COLUMN_SOURCE,   /* the source of this entry, the URL of the feed, not the atom <source> */
+    RSS_READER_NUM_COLS,
+};
 
+/**
+ * text type for atom feeds, default is none
+ */
+enum {
+    RSS_READER_TEXT_TYPE_NONE,
+    RSS_READER_TEXT_TYPE_PLAIN,
+    RSS_READER_TEXT_TYPE_HTML,
+    RSS_READER_TEXT_TYPE_UNKNOWN
+};
+
+
 GType       feed_data_get_type          (void);
 GObject*    feed_data_get_instance      (void);
 
@@ -123,9 +148,14 @@
 void        feed_filter_filter_category (FeedFilter*, GtkTreeIter*);
 void        feed_filter_filter_text     (FeedFilter*, const gchar*);
 
-GType       feed_sort_get_type        (void);
-GObject*    feed_sort_new             (const FeedFilter*);
+GType       feed_sort_get_type          (void);
+GObject*    feed_sort_new               (const FeedFilter*);
 
+/*
+ * helper for the GtkTreeView CellRenderer
+ */
+void        feed_date_cell_data_func    (GtkTreeViewColumn *tree_column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data);
+
 G_END_DECLS
 
 #endif





More information about the commitlog mailing list