/** * Add "broadcast-friends" to the list of subscriptions if required */ static void google_source_add_broadcast_subscription (GoogleSourcePtr gsource) { const gchar* title = "Friend's Shared Items"; GSList * iter = NULL; nodePtr node; iter = gsource->root->children; while (iter) { node = (nodePtr) iter->data ; if (!node->subscription || !node->subscription->source) continue; if (g_str_equal (node->subscription->source, GOOGLE_READER_BROADCAST_FRIENDS_URL)) { return; } iter = g_slist_next (iter); } /* aha! add it! */ node = node_new (feed_get_node_type ()); node_set_title (node, title); node_set_data (node, feed_new ()); node_set_subscription (node, subscription_new (GOOGLE_READER_BROADCAST_FRIENDS_URL, NULL, NULL)); node->subscription->type = &googleSourceFeedSubscriptionType; node_set_parent (node, gsource->root, -1); feedlist_node_imported (node); subscription_update (node->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); subscription_update_favicon (node->subscription); }
static void on_propdialog_response (GtkDialog *dialog, gint response_id, gpointer user_data) { SearchFolderDialog *sfd = SEARCH_FOLDER_DIALOG (user_data); if (response_id == GTK_RESPONSE_OK) { /* save new search folder settings */ node_set_title (sfd->priv->node, gtk_entry_get_text (GTK_ENTRY (sfd->priv->nameEntry))); rule_editor_save (sfd->priv->re, sfd->priv->vfolder->itemset); sfd->priv->vfolder->itemset->anyMatch = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "anyRuleRadioBtn"))); /* update search folder */ itemview_clear (); vfolder_reset (sfd->priv->vfolder); itemlist_unload (FALSE); /* If we are finished editing a new search folder add it to the feed list */ if (!sfd->priv->node->parent) feedlist_node_added (sfd->priv->node); ui_node_update (sfd->priv->node->id); } gtk_widget_destroy (GTK_WIDGET (dialog)); }
/* * Find a node by the name under root or create it. */ static nodePtr theoldreader_source_find_or_create_folder (const gchar *name, nodePtr root) { nodePtr folder = NULL; GSList *iter_parent; /* find a node by the name under root */ iter_parent = root->children; while (iter_parent) { if (g_str_equal (name, node_get_title (iter_parent->data))) { folder = (nodePtr)iter_parent->data; break; } iter_parent = g_slist_next (iter_parent); } /* if not found, create new folder */ if (!folder) { folder = node_new (folder_get_node_type ()); node_set_title (folder, name); node_set_parent (folder, root, -1); feedlist_node_imported (folder); subscription_update (folder->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); } return folder; }
static void on_simple_search_dialog_response (GtkDialog *dialog, gint responseId, gpointer user_data) { SimpleSearchDialog *ssd = (SimpleSearchDialog *)user_data; const gchar *searchString; vfolderPtr vfolder = ssd->priv->vfolder; searchString = gtk_entry_get_text (GTK_ENTRY (ssd->priv->query)); if (1 == responseId) { /* Search */ search_clean_results (vfolder); /* Create new search... */ ssd->priv->vfolder = vfolder = vfolder_new (node_new (vfolder_get_node_type ())); node_set_title (vfolder->node, searchString); itemset_add_rule (vfolder->itemset, "exact", searchString, TRUE); search_load_results (vfolder); } if (2 == responseId) /* Advanced... */ search_dialog_open (searchString); /* Do not close the dialog when "just" searching. The user should click "Close" to close the dialog to be able to do subsequent searches... */ if (1 != responseId) g_object_unref (ssd); }
static void search_dialog_init (SearchDialog *sd) { sd->priv = SEARCH_DIALOG_GET_PRIVATE (sd); sd->priv->vfolder = vfolder_new (node_new (vfolder_get_node_type ())); node_set_title (sd->priv->vfolder->node, _("Saved Search")); }
static void theoldreader_source_merge_feed (TheOldReaderSourcePtr source, const gchar *url, const gchar *title, const gchar *id, nodePtr folder) { nodePtr node; node = feedlist_find_node (source->root, NODE_BY_URL, url); if (!node) { debug2 (DEBUG_UPDATE, "adding %s (%s)", title, url); node = node_new (feed_get_node_type ()); node_set_title (node, title); node_set_data (node, feed_new ()); node_set_subscription (node, subscription_new (url, NULL, NULL)); node->subscription->type = source->root->source->type->feedSubscriptionType; /* Save TheOldReader feed id which we need to fetch items... */ node->subscription->metadata = metadata_list_append (node->subscription->metadata, "theoldreader-feed-id", id); db_subscription_update (node->subscription); node_set_parent (node, folder?folder:source->root, -1); feedlist_node_imported (node); /** * @todo mark the ones as read immediately after this is done * the feed as retrieved by this has the read and unread * status inherently. */ subscription_update (node->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); subscription_update_favicon (node->subscription); } else { node_source_update_folder (node, folder); } }
static nodePtr default_source_add_folder (nodePtr node, const gchar *title) { /* For the local feed list source folders are always real folders implemented by the folder node type... */ nodePtr child = node_new (folder_get_node_type()); node_set_title (child, title); feedlist_node_added (child); return child; }
static void on_nodenamedialog_response (GtkDialog *dialog, gint response_id, gpointer user_data) { nodePtr node = (nodePtr)user_data; if (response_id == GTK_RESPONSE_OK) { node_set_title (node, (gchar *) gtk_entry_get_text (GTK_ENTRY (liferea_dialog_lookup (GTK_WIDGET (dialog), "nameentry")))); feed_list_view_update_node (node->id); feedlist_schedule_save (); } gtk_widget_destroy (GTK_WIDGET (dialog)); }
static nodePtr default_source_add_subscription (nodePtr node, subscriptionPtr subscription) { /* For the local feed list source subscriptions are always feed subscriptions implemented by the feed node and subscription type... */ nodePtr child = node_new (feed_get_node_type ()); node_set_title (child, _("New Subscription")); node_set_data (child, feed_new ()); node_set_subscription (child, subscription); /* feed subscription type is implicit */ feedlist_node_added (child); subscription_update (subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); return child; }
/* * Find a node by the name under root or create it. * * @param name Folder display name * @param parent Parent folder or source root node * * @returns a valid nodePtr */ static nodePtr ttrss_source_find_or_create_folder (const gchar *name, nodePtr parent) { nodePtr folder = NULL; folder = feedlist_find_node (parent, FOLDER_BY_TITLE, name); if (!folder) { folder = node_new (folder_get_node_type ()); node_set_title (folder, name); node_set_parent (folder, parent, -1); feedlist_node_imported (folder); subscription_update (folder->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); } return folder; }
static void ttrss_source_merge_feed (ttrssSourcePtr source, const gchar *url, const gchar *title, gint64 id) { nodePtr node; gchar *tmp; /* check if node to be merged already exists */ node = feedlist_find_node (source->root, NODE_BY_URL, url); if (!node) { debug2 (DEBUG_UPDATE, "adding %s (%s)", title, url); node = node_new (feed_get_node_type ()); node_set_title (node, title); node_set_data (node, feed_new ()); node_set_subscription (node, subscription_new (url, NULL, NULL)); node->subscription->type = &ttrssSourceFeedSubscriptionType; /* Save tt-rss feed id which we need to fetch items... */ tmp = g_strdup_printf ("%" G_GINT64_FORMAT, id); metadata_list_set (&node->subscription->metadata, "ttrss-feed-id", tmp); g_free (tmp); node_set_parent (node, source->root, -1); feedlist_node_imported (node); /** * @todo mark the ones as read immediately after this is done * the feed as retrieved by this has the read and unread * status inherently. */ subscription_update (node->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); subscription_update_favicon (node->subscription); /* Important: we must not loose the feed id! */ db_subscription_update (node->subscription); } debug2 (DEBUG_UPDATE, "updating folder for %s (%s)", title, url); ttrss_source_update_folder (source, node); }
static void inoreader_source_merge_feed (InoreaderSourcePtr source, const gchar *url, const gchar *title, const gchar *id) { nodePtr node; GSList *iter; /* check if node to be merged already exists */ iter = source->root->children; while (iter) { node = (nodePtr)iter->data; if (g_str_equal (node->subscription->source, url)) return; iter = g_slist_next (iter); } debug2 (DEBUG_UPDATE, "adding %s (%s)", title, url); node = node_new (feed_get_node_type ()); node_set_title (node, title); node_set_data (node, feed_new ()); node_set_subscription (node, subscription_new (url, NULL, NULL)); node->subscription->type = &inoreaderSourceFeedSubscriptionType; /* Save Inoreader feed id which we need to fetch items... */ node->subscription->metadata = metadata_list_append (node->subscription->metadata, "inoreader-feed-id", id); db_subscription_update (node->subscription); node_set_parent (node, source->root, -1); feedlist_node_imported (node); /** * @todo mark the ones as read immediately after this is done * the feed as retrieved by this has the read and unread * status inherently. */ subscription_update (node->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); subscription_update_favicon (node->subscription); }
vfolderPtr vfolder_new (nodePtr node) { vfolderPtr vfolder; debug_enter ("vfolder_new"); vfolder = g_new0 (struct vfolder, 1); vfolder->itemset = g_new0 (struct itemSet, 1); vfolder->itemset->nodeId = node->id; vfolder->itemset->ids = NULL; vfolder->itemset->anyMatch = TRUE; vfolder->node = node; vfolders = g_slist_append (vfolders, vfolder); if (!node->title) node_set_title (node, _("New Search Folder")); /* set default title */ node_set_data (node, (gpointer) vfolder); debug_exit ("vfolder_new"); return vfolder; }
static void on_simple_search_dialog_response (GtkDialog *dialog, gint responseId, gpointer user_data) { SimpleSearchDialog *ssd = (SimpleSearchDialog *)user_data; const gchar *searchString; searchString = gtk_entry_get_text (GTK_ENTRY (ssd->priv->query)); if (1 == responseId) { /* Search */ /* Clean up old search result data and display... */ if (ssd->priv->searchResult) { if (ssd->priv->searchResult == itemlist_get_displayed_node ()) itemlist_unload (FALSE); node_free (ssd->priv->searchResult); } /* Create new search... */ ssd->priv->searchResult = node_new (vfolder_get_node_type ()); ssd->priv->vfolder = vfolder_new (ssd->priv->searchResult); node_set_title (ssd->priv->searchResult, searchString); itemset_add_rule (ssd->priv->vfolder->itemset, "exact", searchString, TRUE); vfolder_reset (ssd->priv->vfolder); search_load_results (ssd->priv->searchResult, searchString); } if (2 == responseId) /* Advanced... */ search_dialog_open (searchString); /* Do not close the dialog when "just" searching. The user should click "Close" to close the dialog to be able to do subsequent searches... */ if (1 != responseId) g_object_unref (ssd); }
static void aol_source_merge_feed (xmlNodePtr match, gpointer user_data) { AolSourcePtr gsource = (AolSourcePtr)user_data; nodePtr node, parent = NULL, subnode = NULL; GSList *iter, *iter_sub; xmlNodePtr xml; xmlChar *title = NULL, *id = NULL, *label = NULL; gchar *url = NULL; xml = xpath_find (match, "./string[@name='title']"); if (xml) title = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); xml = xpath_find (match, "./string[@name='id']"); if (xml) { id = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); url = g_strdup (id + strlen ("feed/")); } /* Note: ids look like "feed/http://rss.slashdot.org" */ if (id && title) { /* check if node to be merged already exists */ iter = gsource->root->children; while (iter) { node = (nodePtr)iter->data; if (node->subscription != NULL && g_str_equal (node->subscription->source, url)) { node->subscription->type = &aolSourceFeedSubscriptionType; aol_source_update_folder (match, gsource, node); goto cleanup; } else if (node->type->capabilities & NODE_CAPABILITY_SUBFOLDERS) { iter_sub = node->children; while (iter_sub) { subnode = (nodePtr)iter_sub->data; if (subnode->subscription != NULL && g_str_equal (subnode->subscription->source, url)) { subnode->subscription->type = &aolSourceFeedSubscriptionType; aol_source_update_folder (match, gsource, subnode); goto cleanup; } iter_sub = g_slist_next (iter_sub); } } iter = g_slist_next (iter); } /* if a new feed contains label, put its node under a folder with the same name */ xml = xpath_find (match, "./list[@name='categories']/object/string[@name='label']"); if (xml) { label = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); parent = aol_source_find_or_create_folder ((gchar*)label, gsource->root); xmlFree (label); } else { parent = gsource->root; } g_assert (NULL != parent); debug2 (DEBUG_UPDATE, "adding %s (%s)", title, url); node = node_new (feed_get_node_type ()); node_set_title (node, title); node_set_data (node, feed_new ()); node_set_subscription (node, subscription_new (url, NULL, NULL)); node->subscription->type = &aolSourceFeedSubscriptionType; node_set_parent (node, parent, -1); feedlist_node_imported (node); /** * @todo mark the ones as read immediately after this is done * the feed as retrieved by this has the read and unread * status inherently. */ subscription_update (node->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); subscription_update_favicon (node->subscription); } else { g_warning("Unable to parse subscription information from Google"); } cleanup: xmlFree (id); xmlFree (title); g_free (url) ; }
static void on_propdialog_response (GtkDialog *dialog, gint response_id, gpointer user_data) { SubscriptionPropDialog *spd = (SubscriptionPropDialog *)user_data; if(response_id == GTK_RESPONSE_OK) { gchar *newSource; const gchar *newFilter; gboolean needsUpdate = FALSE; subscriptionPtr subscription = spd->priv->subscription; nodePtr node = spd->priv->subscription->node; feedPtr feed = (feedPtr)node->data; if (SUBSCRIPTION_TYPE(subscription) == feed_get_subscription_type ()) { /* "General" */ node_set_title(node, gtk_entry_get_text(GTK_ENTRY(spd->priv->feedNameEntry))); /* Source */ newSource = ui_subscription_dialog_decode_source(spd->priv); /* Filter handling */ newFilter = gtk_entry_get_text(GTK_ENTRY(liferea_dialog_lookup(spd->priv->dialog, "filterEntry"))); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(spd->priv->dialog, "filterCheckbox"))) && strcmp(newFilter,"")) { /* Maybe this should be a test to see if the file exists? */ if(subscription_get_filter(subscription) == NULL || strcmp(newFilter, subscription_get_filter(subscription))) { subscription_set_filter(subscription, newFilter); needsUpdate = TRUE; } } else { if(subscription_get_filter(subscription)) { subscription_set_filter(subscription, NULL); needsUpdate = TRUE; } } /* if URL has changed... */ if(strcmp(newSource, subscription_get_source(subscription))) { subscription_set_source(subscription, newSource); needsUpdate = TRUE; } g_free(newSource); /* Update interval handling */ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "updateIntervalNever")))) subscription_set_update_interval (subscription, -2); else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "updateIntervalDefault")))) subscription_set_update_interval (subscription, -1); else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "updateIntervalSpecific")))) { gint intervalUnit = gtk_combo_box_get_active (GTK_COMBO_BOX (spd->priv->refreshIntervalUnit)); gint updateInterval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spd->priv->refreshInterval)); if (intervalUnit == 1) updateInterval *= 60; /* hours */ if (intervalUnit == 2) updateInterval *= 1440; /* days */ subscription_set_update_interval (subscription, updateInterval); db_subscription_update (subscription); } } /* "Archive" handling */ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheDefault")))) feed->cacheLimit = CACHE_DEFAULT; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheDisable")))) feed->cacheLimit = CACHE_DISABLE; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheUnlimited")))) feed->cacheLimit = CACHE_UNLIMITED; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheLimited")))) feed->cacheLimit = gtk_spin_button_get_value(GTK_SPIN_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "cacheItemLimit"))); if (SUBSCRIPTION_TYPE(subscription) == feed_get_subscription_type ()) { /* "Download" Options */ subscription->updateOptions->dontUseProxy = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "dontUseProxyCheck"))); } /* "Advanced" options */ feed->encAutoDownload = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "enclosureDownloadCheck"))); node->loadItemLink = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "loadItemLinkCheck"))); feed->ignoreComments = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "ignoreCommentFeeds"))); feed->enforcePopup = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "enforcePopupCheck"))); feed->preventPopup = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "preventPopupCheck"))); feed->markAsRead = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "markAsReadCheck"))); if (feed->enforcePopup && feed->preventPopup) feed->enforcePopup = FALSE; ui_node_update (node->id); feedlist_schedule_save (); db_subscription_update (subscription); if (needsUpdate) subscription_update (subscription, FEED_REQ_PRIORITY_HIGH); } g_object_unref(spd); }
static void google_source_merge_feed (xmlNodePtr match, gpointer user_data) { GoogleSourcePtr gsource = (GoogleSourcePtr)user_data; nodePtr node; GSList *iter; xmlNodePtr xml; xmlChar *title = NULL, *id = NULL; gchar *url = NULL; xml = xpath_find (match, "./string[@name='title']"); if (xml) title = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); xml = xpath_find (match, "./string[@name='id']"); if (xml) { id = xmlNodeListGetString (xml->doc, xml->xmlChildrenNode, 1); url = g_strdup(id + strlen ("feed/")); } /* Note: ids look like "feed/http://rss.slashdot.org" */ if (id && title) { /* check if node to be merged already exists */ iter = gsource->root->children; while (iter) { node = (nodePtr)iter->data; if (g_str_equal (node->subscription->source, url)) { node->subscription->type = &googleSourceFeedSubscriptionType; goto cleanup ; } iter = g_slist_next (iter); } debug2 (DEBUG_UPDATE, "adding %s (%s)", title, url); node = node_new (feed_get_node_type ()); node_set_title (node, title); node_set_data (node, feed_new ()); node_set_subscription (node, subscription_new (url, NULL, NULL)); node->subscription->type = &googleSourceFeedSubscriptionType; node_set_parent (node, gsource->root, -1); feedlist_node_imported (node); /** * @todo mark the ones as read immediately after this is done * the feed as retrieved by this has the read and unread * status inherently. */ subscription_update (node->subscription, FEED_REQ_RESET_TITLE | FEED_REQ_PRIORITY_HIGH); subscription_update_favicon (node->subscription); } else g_warning("Unable to parse subscription information from Google"); cleanup: if (id) xmlFree (id); if (title) xmlFree (title); g_free (url) ; }