Пример #1
0
void
feed_list_view_select (nodePtr node)
{
	GtkTreeModel *model = gtk_tree_view_get_model (flv->treeview);

	if (model && node && node != feedlist_get_root ()) {
		GtkTreePath *path;

		/* in filtered mode we need to convert the iterator */
		if (flv->feedlist_reduced_unread) {
			GtkTreeIter iter;
			gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (flv->filter), &iter, feed_list_view_to_iter (node->id));
			path = gtk_tree_model_get_path (model, &iter);
		} else {
			path = gtk_tree_model_get_path (model, feed_list_view_to_iter (node->id));
		}

		if (node->parent)
			feed_list_view_expand (node->parent);

		if (path) {
			gtk_tree_view_scroll_to_cell (flv->treeview, path, NULL, FALSE, 0.0, 0.0);
			gtk_tree_view_set_cursor (flv->treeview, path, NULL, FALSE);
			gtk_tree_path_free (path);
		}
 	} else {
		GtkTreeSelection *selection = gtk_tree_view_get_selection (flv->treeview);
		gtk_tree_selection_unselect_all (selection);
	}
}
Пример #2
0
gboolean
liferea_dbus_refresh (LifereaDBus *self, gboolean *ret, GError **err)
{
	node_update_subscription (feedlist_get_root (), GUINT_TO_POINTER (0));
	*ret = TRUE;
	return TRUE;
}
Пример #3
0
void
feedlist_reset_update_counters (nodePtr node) 
{
	GTimeVal now;
	
	if (!node)
		node = feedlist_get_root ();	
	
	g_get_current_time (&now);
	node_foreach_child_data (node, node_reset_update_counter, &now);
}
Пример #4
0
void
on_action_mark_all_read (GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
	nodePtr 	feedlist;
	gboolean 	confirm_mark_read;
	gboolean 	do_mark_read = TRUE;

	if (!g_strcmp0 (g_action_get_name (G_ACTION (action)), "mark-all-feeds-read"))
		feedlist = feedlist_get_root ();
	else if (user_data)
		feedlist = (nodePtr) user_data;
	else
		feedlist = feedlist_get_selected ();

	conf_get_bool_value (CONFIRM_MARK_ALL_READ, &confirm_mark_read);

	if (confirm_mark_read) {
		gint result;
		GtkMessageDialog *confirm_dialog = GTK_MESSAGE_DIALOG (liferea_dialog_new ("mark_read_dialog"));
		GtkWidget *dont_ask_toggle = liferea_dialog_lookup (GTK_WIDGET (confirm_dialog), "dontAskAgainToggle");
		const gchar *feed_title = (feedlist_get_root () == feedlist) ? _("all feeds"):node_get_title (feedlist);
		gchar *primary_message = g_strdup_printf (_("Mark %s as read ?"), feed_title);

		g_object_set (confirm_dialog, "text", primary_message, NULL);
		g_free (primary_message);
		gtk_message_dialog_format_secondary_text (confirm_dialog, _("Are you sure you want to mark all items in %s as read ?"), feed_title);

		conf_bind (CONFIRM_MARK_ALL_READ, dont_ask_toggle, "active", G_SETTINGS_BIND_DEFAULT | G_SETTINGS_BIND_INVERT_BOOLEAN);

		result = gtk_dialog_run (GTK_DIALOG (confirm_dialog));
		if (result != GTK_RESPONSE_OK)
			do_mark_read = FALSE;
		gtk_widget_destroy (GTK_WIDGET (confirm_dialog));
	}

	if (do_mark_read)
		feedlist_mark_all_read (feedlist);
}
Пример #5
0
static void
feedlist_init (FeedList *fl)
{
	gint	startup_feed_action;

	debug_enter ("feedlist_init");
	
	/* 1. Prepare globally accessible singleton */
	g_assert (NULL == feedlist);
	feedlist = fl;
	
	feedlist->priv = FEEDLIST_GET_PRIVATE (fl);
	feedlist->priv->loading = TRUE;
	
	/* 2. Set up a root node and import the feed list source structure. */
	debug0 (DEBUG_CACHE, "Setting up root node");
	ROOTNODE = node_source_setup_root ();

	/* 3. Ensure folder expansion and unread count*/
	debug0 (DEBUG_CACHE, "Initializing node state");
	feedlist_foreach (feedlist_init_node);

	ui_tray_update ();

	/* 4. Check if feeds do need updating. */
	debug0 (DEBUG_UPDATE, "Performing initial feed update");
	conf_get_int_value (STARTUP_FEED_ACTION, &startup_feed_action);
	if (0 == startup_feed_action) {
		/* Update all feeds */
		if (network_monitor_is_online ()) {
			debug0 (DEBUG_UPDATE, "initial update: updating all feeds");		
			node_update_subscription (feedlist_get_root (), GUINT_TO_POINTER (0));
		} else {
			debug0 (DEBUG_UPDATE, "initial update: prevented because we are offline");
		}
	} else {
		debug0 (DEBUG_UPDATE, "initial update: resetting feed counter");
		feedlist_reset_update_counters (NULL);
	}

	/* 5. Start automatic updating */
	feedlist->priv->autoUpdateTimer = g_timeout_add_seconds (10, feedlist_auto_update, NULL);
	g_signal_connect (network_monitor_get (), "online-status-changed", G_CALLBACK (on_network_status_changed), NULL);

	/* 6. Finally save the new feed list state */
	feedlist->priv->loading = FALSE;
	feedlist_schedule_save ();
	
	debug_exit ("feedlist_init");	
}
Пример #6
0
void
feed_list_node_add (nodePtr node)
{
	gint		position;
	GtkTreeIter	*iter, *parentIter = NULL;

	debug2 (DEBUG_GUI, "adding node \"%s\" as child of parent=\"%s\"", node_get_title(node), (NULL != node->parent)?node_get_title(node->parent):"feed list root");

	g_assert (NULL != node->parent);
	g_assert (NULL == feed_list_node_to_iter (node->id));

	/* if parent is NULL we have the root folder and don't create a new row! */
	iter = (GtkTreeIter *)g_new0 (GtkTreeIter, 1);
	
	/* if reduced feedlist, show flat treeview */
	if (feedlist_reduced_unread)
		parentIter = NULL;
	else if (node->parent != feedlist_get_root ())
		parentIter = feed_list_node_to_iter (node->parent->id);

	position = g_slist_index (node->parent->children, node);

	if (feedlist_reduced_unread || position < 0)
		gtk_tree_store_append (feedstore, iter, parentIter);
	else
		gtk_tree_store_insert (feedstore, iter, parentIter, position);

	gtk_tree_store_set (feedstore, iter, FS_PTR, node, -1);
	feed_list_node_add_iter (node->id, iter);
	feed_list_node_update (node->id);
	
	if (node->parent != feedlist_get_root ())
		feed_list_node_check_if_folder_is_empty (node->parent->id);

	if (IS_FOLDER (node))
		feed_list_node_check_if_folder_is_empty (node->id);
}
Пример #7
0
static void
default_source_export (nodePtr node)
{
	gchar	*filename;
	
	if (feedlistImport)
		return;

	debug_enter ("default_source_source_export");
	
	g_assert (node->source->root == feedlist_get_root ());

	filename = default_source_source_get_feedlist (node);
	export_OPML_feedlist (filename, node->source->root, TRUE);
	g_free (filename);

	debug_exit ("default_source_source_export");
}
Пример #8
0
void
feed_list_node_reload_feedlist ()
{
	feed_list_node_clear_feedlist ();
	feed_list_node_load_feedlist (feedlist_get_root ());
}
Пример #9
0
static gboolean
ui_dnd_feed_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData *selection_data)
{
	GtkTreeIter	iter, iter2, parentIter;
	nodePtr		node, oldParent, newParent;
	gboolean	result, valid, added;
	gint		oldPos, pos;

	result = old_feed_drag_data_received (drag_dest, dest, selection_data);
	if (result) {
		if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest), &iter, dest)) {
			gtk_tree_model_get (GTK_TREE_MODEL (drag_dest), &iter, FS_PTR, &node, -1);

			/* If we don't do anything, then because DnD is implemented by removal and
			   re-insertion, and the removed node is selected, the treeview selects
			   the next row after the removal, which is supremely irritating.
			   But setting a selection at this point is pointless, because the treeview
			   will reset it as soon as the DnD callback returns. Instead, we set
			   the cursor, which controls where treeview resets the selection later.
			 */
			gtk_tree_view_set_cursor(GTK_TREE_VIEW (liferea_shell_lookup ("feedlist")),
			    dest, NULL, FALSE);

			/* remove from old parents child list */
			oldParent = node->parent;
			g_assert (oldParent);
			oldPos = g_slist_index (oldParent->children, node);
			oldParent->children = g_slist_remove (oldParent->children, node);
			node_update_counters (oldParent);
			
			if (0 == g_slist_length (oldParent->children))
				feed_list_node_add_empty_node (feed_list_node_to_iter (oldParent->id));
			
			/* and rebuild new parents child list */
			if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (drag_dest), &parentIter, &iter)) {
				gtk_tree_model_get (GTK_TREE_MODEL (drag_dest), &parentIter, FS_PTR, &newParent, -1);
			} else {
				gtk_tree_model_get_iter_first (GTK_TREE_MODEL (drag_dest), &parentIter);
				newParent = feedlist_get_root ();
			}

			/* drop old list... */
			debug3 (DEBUG_GUI, "old parent is %s (%d, position=%d)", oldParent->title, g_slist_length (oldParent->children), oldPos);
			debug2 (DEBUG_GUI, "new parent is %s (%d)", newParent->title, g_slist_length (newParent->children));
			g_slist_free (newParent->children);
			newParent->children = NULL;
			node->parent = newParent;
			
			debug0 (DEBUG_GUI, "new newParent child list:");
				
			/* and rebuild it from the tree model */
			if (feedlist_get_root() != newParent)
				valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (drag_dest), &iter2, &parentIter);
			else
				valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (drag_dest), &iter2, NULL);
				
			pos = 0;
			added = FALSE;
			while (valid) {
				nodePtr	child;			
				gtk_tree_model_get (GTK_TREE_MODEL (drag_dest), &iter2, FS_PTR, &child, -1);
				if (child) {
					/* Well this is a bit complicated... If we move a feed inside a folder
					   we need to skip the old insertion point (oldPos). This is easy if the
					   feed is added behind this position. If it is dropped before the flag
					   added is set once the new copy is encountered. The remaining copy
					   is skipped automatically when the flag is set.
					 */
					 
					/* check if this is a copy of the dragged node or the original itself */
					if ((newParent == oldParent) && !strcmp(node->id, child->id)) {
						if ((pos == oldPos) || added) {
							/* it is the original */
							debug2 (DEBUG_GUI, "   -> %d: skipping old insertion point %s", pos, child->title);
						} else {
							/* it is a copy inserted before the original */
							added = TRUE;
							debug2 (DEBUG_GUI, "   -> %d: new insertion point of %s", pos, child->title);
							newParent->children = g_slist_append (newParent->children, child);
						}
					} else {
						/* all other nodes */
						debug2 (DEBUG_GUI, "   -> %d: adding %s", pos, child->title);
						newParent->children = g_slist_append (newParent->children, child);
					}
				} else {
					debug0 (DEBUG_GUI, "   -> removing empty node");
					/* remove possible existing "(empty)" node from newParent */
					feed_list_node_remove_empty_node (&parentIter);
				}
				valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (drag_dest), &iter2);
				pos++;
			}
			
			db_node_update (node);
			node_update_counters (newParent);
			
			feedlist_schedule_save ();
		}
	}
						      
	return result;
}
Пример #10
0
void
feed_list_view_reload_feedlist ()
{
	feed_list_view_clear_feedlist ();
	feed_list_view_load_feedlist (feedlist_get_root ());
}
Пример #11
0
void
on_menu_update_all(GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
	do_menu_update (feedlist_get_root ());
}