/* 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 (); }
static void search_load_results (vfolderPtr searchResult) { feed_list_view_select (NULL); itemlist_add_search_result (vfolder_loader_new (searchResult->node)); }
/* 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); } }
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); }
/** * 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); }
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 (); }
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); }
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"); }