Exemple #1
0
/*
 Called when the indicator menu entry for a specific feed
 is clicked, meaning Liferea should switch to that feed.
*/ 
static void
on_indicator_clicked (IndicateIndicator *indicator, guint timestamp, gpointer user_data)
{
	feed_list_view_select ((nodePtr) user_data);
	liferea_shell_present ();
	remove_all_indicators ();
}
Exemple #2
0
static void
search_load_results (vfolderPtr searchResult)
{
	feed_list_view_select (NULL);
		
	itemlist_add_search_result (vfolder_loader_new (searchResult->node));
}
Exemple #3
0
/* methods to receive URLs which were dropped anywhere in the main window */
static void
liferea_shell_URL_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *data, guint info, guint time_received)
{
	gchar		*tmp1, *tmp2, *freeme;
	GtkWidget	*mainwindow;
	GtkAllocation	alloc;
	GtkTreeView	*treeview;
	GtkTreeModel	*model;
	GtkTreePath	*path;
	GtkTreeIter	iter;
	nodePtr		node;
	gint		tx, ty;
	
	g_return_if_fail (gtk_selection_data_get_data (data) != NULL);
		
	mainwindow = GTK_WIDGET (shell->priv->window);
	treeview = GTK_TREE_VIEW (shell->priv->feedlistView);
	model = gtk_tree_view_get_model (treeview);

	/* x and y are relative to the main window, make them relative to the treeview */
	gtk_widget_translate_coordinates (mainwindow, GTK_WIDGET (treeview), x, y, &tx, &ty);

	/* Allow link drops only over feed list widget. This is to avoid
	   the frequent accidental text drops in the HTML view. */

	gtk_widget_get_allocation(GTK_WIDGET(treeview), &alloc);

	if((x > alloc.x+alloc.width) || (x < alloc.x) ||
	   (y > alloc.y+alloc.height) || (y < alloc.y)) {
		gtk_drag_finish (context, FALSE, FALSE, time_received);
		return;
	}		

	if ((gtk_selection_data_get_length (data) >= 0) && (gtk_selection_data_get_format (data) == 8)) {
		/* extra handling to accept multiple drops */
		freeme = tmp1 = g_strdup (gtk_selection_data_get_data (data));
		while ((tmp2 = strsep (&tmp1, "\n\r"))) {
			if (strlen (tmp2)) {
				/* if the drop is over a node, select it so that feedlist_add_subscription()
				 * adds it in the correct folder */
				if (gtk_tree_view_get_dest_row_at_pos (treeview, tx, ty, &path, NULL)) {
					if (gtk_tree_model_get_iter (model, &iter, path)) {
						gtk_tree_model_get (model, &iter, FS_PTR, &node, -1);
						/* if node is NULL, feed_list_view_select() will unselect the tv */
						feed_list_view_select (node);
					}
					gtk_tree_path_free (path);
				}
				feedlist_add_subscription (g_strdup (tmp2), NULL, NULL,
				                           FEED_REQ_PRIORITY_HIGH);
			}
		}
		g_free (freeme);
		gtk_drag_finish (context, TRUE, FALSE, time_received);
	} else {
		gtk_drag_finish (context, FALSE, FALSE, time_received);
	}
}
Exemple #4
0
static void
feedlist_unselect (void)
{
	SELECTED = NULL;

	itemview_set_displayed_node (NULL);
	itemview_update ();
		
	itemlist_unload (FALSE /* mark all read */);
	feed_list_view_select (NULL);
	liferea_shell_update_feed_menu (TRUE, FALSE, FALSE);
	liferea_shell_update_allitems_actions (FALSE, FALSE);
}
Exemple #5
0
/** 
 * Loads a search result into the item list and renders
 * some info text into the HTML view pane.
 *
 * @param searchResult		valid search result node
 * @param searchString		search text (or NULL)
 */
static void
search_load_results (nodePtr searchResult, const gchar *searchString)
{
	GString	*buffer;
	itemSetPtr itemSet;
	nodeViewType viewMode;
	
	/* Clear feed and item display and load search results */
	feed_list_view_select (NULL);
	itemlist_unload (FALSE);
	
	/* Ensure that we are in a useful viewing mode (3 paned) */
	viewMode = itemlist_get_view_mode ();
	if ((NODE_VIEW_MODE_NORMAL != viewMode) &&
	    (NODE_VIEW_MODE_WIDE != viewMode))
		itemview_set_layout (NODE_VIEW_MODE_NORMAL);
		
	itemSet = node_get_itemset (searchResult);
	itemlist_load_search_result (itemSet);
	itemset_free (itemSet);

	buffer = g_string_new (NULL);
	htmlview_start_output (buffer, NULL, TRUE, FALSE);
	g_string_append_printf (buffer, "<div class='content'><h2>");
	
	if (searchString)
		g_string_append_printf (buffer, ngettext("%d Search Result for \"%s\"", 
	                                        	 "%d Search Results for \"%s\"",
	                                        	 searchResult->itemCount),
	                        	searchResult->itemCount, searchString);
	else 
		g_string_append_printf (buffer, ngettext("%d Search Result", 
	                                        	 "%d Search Results",
	                                        	 searchResult->itemCount),
	                        	searchResult->itemCount);
					
	g_string_append_printf (buffer, "</h2><p>");
	g_string_append_printf (buffer, _("The item list now contains all items matching the "
	                                "specified search pattern. If you want to save this search "
	                                "result permanently you can click the \"Search Folder\" button in "
	                                "the search dialog and Liferea will add a search folder to your "
	                                "feed list."));
	g_string_append_printf (buffer, "</p></div>");
	htmlview_finish_output (buffer);
	itemview_display_info (buffer->str);
	g_string_free (buffer, TRUE);
}
Exemple #6
0
static void
notif_libnotify_callback_open (NotifyNotification *n, gchar *action, gpointer user_data)
{
	nodePtr node_p;

	g_assert(action != NULL);
	g_assert(strcmp(action, "open") == 0);

	node_p = node_from_id (user_data);

	if (node_p)
		feed_list_view_select (node_p);
	else
		ui_show_error_box (_("This feed does not exist anymore!"));

	notify_notification_close (n, NULL);

	liferea_shell_present ();
}
Exemple #7
0
void
feedlist_node_added (nodePtr node)
{
	gint	position = -1;
	
	g_assert (NULL == node->parent);
	
	if (SELECTED && !IS_FOLDER(SELECTED)) {
		position = g_slist_index (SELECTED->parent->children, SELECTED);
		if (position > -1)
			position++;	/* insert after selected child index */
	}

	node_set_parent (node, feedlist_get_parent_node (), position);
	
	if (node->subscription)
		db_subscription_update (node->subscription);
	
	db_node_update(node);

	feedlist_node_imported (node);
	
	feed_list_view_select (node);
}
Exemple #8
0
void
liferea_shell_create (GtkApplication *app, const gchar *overrideWindowState)
{
	GtkUIManager	*ui_manager;
	GtkAccelGroup	*accel_group;
	GError		*error = NULL;	
	gboolean	toggle;
	gchar		*id;
	
	debug_enter ("liferea_shell_create");

	g_object_new (LIFEREA_SHELL_TYPE, NULL);

	shell->priv->window = GTK_WINDOW (liferea_shell_lookup ("mainwindow"));

	gtk_window_set_application (GTK_WINDOW (shell->priv->window), app);
	
	/* 1.) menu creation */
	
	debug0 (DEBUG_GUI, "Setting up menues");

	shell->priv->itemlist = itemlist_create ();

	/* Prepare some toggle button states */	
	conf_get_bool_value (REDUCED_FEEDLIST, &toggle);
	liferea_shell_feedlist_toggle_entries[0].is_active = toggle;

	ui_manager = gtk_ui_manager_new ();

	shell->priv->generalActions = gtk_action_group_new ("GeneralActions");
	gtk_action_group_set_translation_domain (shell->priv->generalActions, PACKAGE);
	gtk_action_group_add_actions (shell->priv->generalActions, liferea_shell_action_entries, G_N_ELEMENTS (liferea_shell_action_entries), shell->priv);
	gtk_action_group_add_toggle_actions (shell->priv->generalActions, liferea_shell_action_toggle_entries, G_N_ELEMENTS (liferea_shell_action_toggle_entries), shell->priv);
	gtk_action_group_add_radio_actions (shell->priv->generalActions, liferea_shell_view_radio_entries, G_N_ELEMENTS (liferea_shell_view_radio_entries), itemlist_get_view_mode (), (GCallback)on_view_activate, (gpointer)TRUE);
	gtk_action_group_add_toggle_actions (shell->priv->generalActions, liferea_shell_feedlist_toggle_entries, G_N_ELEMENTS (liferea_shell_feedlist_toggle_entries), shell->priv);
	gtk_ui_manager_insert_action_group (ui_manager, shell->priv->generalActions, 0);

	shell->priv->addActions = gtk_action_group_new ("AddActions");
	gtk_action_group_set_translation_domain (shell->priv->addActions, PACKAGE);
	gtk_action_group_add_actions (shell->priv->addActions, liferea_shell_add_action_entries, G_N_ELEMENTS (liferea_shell_add_action_entries), shell->priv);
	gtk_ui_manager_insert_action_group (ui_manager, shell->priv->addActions, 0);

	shell->priv->feedActions = gtk_action_group_new ("FeedActions");
	gtk_action_group_set_translation_domain (shell->priv->feedActions, PACKAGE);
	gtk_action_group_add_actions (shell->priv->feedActions, liferea_shell_feed_action_entries, G_N_ELEMENTS (liferea_shell_feed_action_entries), shell->priv);
	gtk_ui_manager_insert_action_group (ui_manager, shell->priv->feedActions, 0);

	shell->priv->readWriteActions = gtk_action_group_new("ReadWriteActions");
	gtk_action_group_set_translation_domain (shell->priv->readWriteActions, PACKAGE);
	gtk_action_group_add_actions (shell->priv->readWriteActions, liferea_shell_read_write_action_entries, G_N_ELEMENTS (liferea_shell_read_write_action_entries), shell->priv);
	gtk_ui_manager_insert_action_group (ui_manager, shell->priv->readWriteActions, 0);

	shell->priv->itemActions = gtk_action_group_new ("ItemActions");
	gtk_action_group_set_translation_domain (shell->priv->itemActions, PACKAGE);
	gtk_action_group_add_actions (shell->priv->itemActions, liferea_shell_item_action_entries, G_N_ELEMENTS (liferea_shell_item_action_entries), shell->priv);
	gtk_ui_manager_insert_action_group (ui_manager, shell->priv->itemActions, 0);

	accel_group = gtk_ui_manager_get_accel_group (ui_manager);
	gtk_window_add_accel_group (GTK_WINDOW (shell->priv->window), accel_group);
	g_object_unref (accel_group);

	g_signal_connect (gtk_accel_map_get (), "changed", G_CALLBACK (on_accel_change), NULL);

	if (!gtk_ui_manager_add_ui_from_string (ui_manager, liferea_shell_ui_desc, -1, &error))
		g_error ("building menus failed: %s", error->message);

	shell->priv->menubar = gtk_ui_manager_get_widget (ui_manager, "/MainwindowMenubar");
	shell->priv->toolbar = gtk_ui_manager_get_widget (ui_manager, "/maintoolbar");

	/* Ensure GTK3 toolbar shadows... */
	gtk_style_context_add_class (gtk_widget_get_style_context (shell->priv->toolbar), "primary-toolbar");

	/* what a pain, why is there no markup for this option? */
	g_object_set (G_OBJECT (gtk_ui_manager_get_widget (ui_manager, "/maintoolbar/newFeedButton")), "is_important", TRUE, NULL);
	g_object_set (G_OBJECT (gtk_ui_manager_get_widget (ui_manager, "/maintoolbar/nextUnreadButton")), "is_important", TRUE, NULL);
	g_object_set (G_OBJECT (gtk_ui_manager_get_widget (ui_manager, "/maintoolbar/MarkAsReadButton")), "is_important", TRUE, NULL);
	g_object_set (G_OBJECT (gtk_ui_manager_get_widget (ui_manager, "/maintoolbar/UpdateAllButton")), "is_important", TRUE, NULL);
	g_object_set (G_OBJECT (gtk_ui_manager_get_widget (ui_manager, "/maintoolbar/SearchButton")), "is_important", TRUE, NULL);

	/* 2.) setup containers */
	
	debug0 (DEBUG_GUI, "Setting up widget containers");

	gtk_box_pack_start (GTK_BOX (liferea_shell_lookup ("vbox1")), shell->priv->toolbar, FALSE, FALSE, 0);
	gtk_box_reorder_child (GTK_BOX (liferea_shell_lookup ("vbox1")), shell->priv->toolbar, 0);
	gtk_box_pack_start (GTK_BOX (liferea_shell_lookup ("vbox1")), shell->priv->menubar, FALSE, FALSE, 0);
	gtk_box_reorder_child (GTK_BOX (liferea_shell_lookup ("vbox1")), shell->priv->menubar, 0);

	gtk_widget_show_all(GTK_WIDGET(shell->priv->toolbar));

	g_signal_connect ((gpointer) liferea_shell_lookup ("itemtabs"), "key_press_event",
	                  G_CALLBACK (on_key_press_event_null_cb), NULL);

	g_signal_connect ((gpointer) liferea_shell_lookup ("itemtabs"), "key_release_event",
	                  G_CALLBACK (on_key_press_event_null_cb), NULL);
	
	g_signal_connect ((gpointer) liferea_shell_lookup ("itemtabs"), "scroll_event",
	                  G_CALLBACK (on_notebook_scroll_event_null_cb), NULL);
	
	g_signal_connect (G_OBJECT (shell->priv->window), "delete_event", G_CALLBACK(on_close), shell->priv);
	g_signal_connect (G_OBJECT (shell->priv->window), "window_state_event", G_CALLBACK(on_window_state_event), shell->priv);
	g_signal_connect (G_OBJECT (shell->priv->window), "key_press_event", G_CALLBACK(on_key_press_event), shell->priv);
	
	/* 3.) setup status bar */
	
	debug0 (DEBUG_GUI, "Setting up status bar");
	
	shell->priv->statusbar = GTK_STATUSBAR (liferea_shell_lookup ("statusbar"));
	shell->priv->statusbarLocked = FALSE;
	shell->priv->statusbarLockTimer = 0;
	shell->priv->statusbar_feedsinfo = gtk_label_new("");
	gtk_widget_show(shell->priv->statusbar_feedsinfo);
	gtk_box_pack_start (GTK_BOX (shell->priv->statusbar), shell->priv->statusbar_feedsinfo, FALSE, FALSE, 5);

	/* 4.) setup tabs */
	
	debug0 (DEBUG_GUI, "Setting up tabbed browsing");	
	shell->priv->tabs = browser_tabs_create (GTK_NOTEBOOK (liferea_shell_lookup ("browsertabs")));
	
	/* 5.) setup feed list */

	debug0 (DEBUG_GUI, "Setting up feed list");
	shell->priv->feedlistView = GTK_TREE_VIEW (liferea_shell_lookup ("feedlist"));
	feed_list_view_init (shell->priv->feedlistView);

	/* 6.) setup menu sensivity */
	
	debug0 (DEBUG_GUI, "Initialising menues");
		
	/* On start, no item or feed is selected, so Item menu should be insensitive: */
	liferea_shell_update_item_menu (FALSE);

	/* necessary to prevent selection signals when filling the feed list
	   and setting the 2/3 pane mode view */
	gtk_widget_set_sensitive (GTK_WIDGET (shell->priv->feedlistView), FALSE);
	
	/* 7.) setup item view */
	
	debug0 (DEBUG_GUI, "Setting up item view");

	shell->priv->itemview = itemview_create (GTK_WIDGET (shell->priv->window));

        /* 8.) load icons as required */
        
        debug0 (DEBUG_GUI, "Loading icons");
        
        icons_load ();
	
	/* 9.) update and restore all menu elements */

	liferea_shell_update_toolbar ();
	liferea_shell_update_history_actions ();
	liferea_shell_setup_URL_receiver ();
	liferea_shell_restore_state (overrideWindowState);
	
	gtk_widget_set_sensitive (GTK_WIDGET (shell->priv->feedlistView), TRUE);

	/* 10.) After main window is realized get theme colors and set up feed
 	        list and tray icon */
	render_init_theme_colors (GTK_WIDGET (shell->priv->window));

	shell->priv->feedlist = feedlist_create ();
	g_signal_connect (shell->priv->feedlist, "new-items",
	                  G_CALLBACK (liferea_shell_update_unread_stats), shell->priv->feedlist);

	/* 11.) Restore latest selection */

	// FIXME: Move to feed list code
	if (conf_get_str_value (LAST_NODE_SELECTED, &id)) {
		feed_list_view_select (node_from_id (id));
		g_free (id);
	}

	/* 12. Setup shell plugins */

	shell->priv->extensions = peas_extension_set_new (PEAS_ENGINE (liferea_plugins_engine_get_default ()),
		                             LIFEREA_TYPE_SHELL_ACTIVATABLE, "shell", shell, NULL);

	g_signal_connect (shell->priv->extensions, "extension-added", G_CALLBACK (on_extension_added), shell);
	g_signal_connect (shell->priv->extensions, "extension-removed",	G_CALLBACK (on_extension_removed), shell);

	peas_extension_set_call (shell->priv->extensions, "activate");

	/* 14. Rebuild search folders if needed */
	if (searchFolderRebuild)
		vfolder_foreach (vfolder_rebuild);

	debug_exit ("liferea_shell_create");
}