static void popular_tile_clicked (GsPopularTile *tile, gpointer data) { GsShellOverview *self = GS_SHELL_OVERVIEW (data); GsShellOverviewPrivate *priv = gs_shell_overview_get_instance_private (self); GsApp *app; app = gs_popular_tile_get_app (tile); gs_shell_show_app (priv->shell, app); }
static void category_tile_clicked (GsCategoryTile *tile, gpointer data) { GsShellOverview *self = GS_SHELL_OVERVIEW (data); GsShellOverviewPrivate *priv = gs_shell_overview_get_instance_private (self); GsCategory *category; category = gs_category_tile_get_category (tile); gs_shell_show_category (priv->shell, category); }
static void gs_shell_overview_dispose (GObject *object) { GsShellOverview *self = GS_SHELL_OVERVIEW (object); GsShellOverviewPrivate *priv = gs_shell_overview_get_instance_private (self); g_clear_object (&priv->builder); g_clear_object (&priv->plugin_loader); g_clear_object (&priv->cancellable); g_clear_pointer (&priv->category_of_day, g_free); G_OBJECT_CLASS (gs_shell_overview_parent_class)->dispose (object); }
static void gs_shell_overview_get_featured_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GsShellOverview *self = GS_SHELL_OVERVIEW (user_data); GsShellOverviewPrivate *priv = gs_shell_overview_get_instance_private (self); GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source_object); GtkWidget *tile; GsApp *app; g_autoptr(GError) error = NULL; g_autoptr(GsAppList) list = NULL; list = gs_plugin_loader_get_featured_finish (plugin_loader, res, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) goto out; if (g_getenv ("GNOME_SOFTWARE_FEATURED") == NULL) { /* Don't show apps from the category that's currently featured as the category of the day */ gs_plugin_list_filter (&list, filter_category, priv->category_of_day); gs_plugin_list_randomize (&list); } gs_container_remove_all (GTK_CONTAINER (priv->bin_featured)); gtk_widget_set_visible (priv->featured_heading, list != NULL); if (list == NULL) { g_warning ("failed to get featured apps: %s", error ? error->message : "no apps to show"); goto out; } /* at the moment, we only care about the first app */ app = GS_APP (list->data); tile = gs_feature_tile_new (app); g_signal_connect (tile, "clicked", G_CALLBACK (feature_tile_clicked), self); gtk_container_add (GTK_CONTAINER (priv->bin_featured), tile); priv->empty = FALSE; out: priv->loading_featured = FALSE; priv->refresh_count--; if (priv->refresh_count == 0) { priv->cache_valid = TRUE; g_signal_emit (self, signals[SIGNAL_REFRESHED], 0); } }
/** * gs_shell_overview_get_popular_cb: **/ static void gs_shell_overview_get_popular_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GsShellOverview *self = GS_SHELL_OVERVIEW (user_data); GsShellOverviewPrivate *priv = gs_shell_overview_get_instance_private (self); GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source_object); GList *l; GsApp *app; gint i; GtkWidget *tile; g_autoptr(GError) error = NULL; g_autoptr(GsAppList) list = NULL; /* get popular apps */ list = gs_plugin_loader_get_popular_finish (plugin_loader, res, &error); gtk_widget_set_visible (priv->box_popular, list != NULL); gtk_widget_set_visible (priv->popular_heading, list != NULL); if (list == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("failed to get popular apps: %s", error->message); goto out; } /* Don't show apps from the category that's currently featured as the category of the day */ gs_plugin_list_filter (&list, filter_category, priv->category_of_day); gs_plugin_list_randomize (&list); gs_container_remove_all (GTK_CONTAINER (priv->box_popular)); for (l = list, i = 0; l != NULL && i < N_TILES; l = l->next, i++) { app = GS_APP (l->data); tile = gs_popular_tile_new (app); g_signal_connect (tile, "clicked", G_CALLBACK (popular_tile_clicked), self); gtk_container_add (GTK_CONTAINER (priv->box_popular), tile); } priv->empty = FALSE; out: priv->loading_popular = FALSE; priv->refresh_count--; if (priv->refresh_count == 0) { priv->cache_valid = TRUE; g_signal_emit (self, signals[SIGNAL_REFRESHED], 0); } }
/** * gs_shell_overview_get_categories_cb: **/ static void gs_shell_overview_get_categories_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GsShellOverview *self = GS_SHELL_OVERVIEW (user_data); GsShellOverviewPrivate *priv = gs_shell_overview_get_instance_private (self); GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source_object); GList *l; GsCategory *cat; GtkWidget *tile; gboolean has_category = FALSE; g_autoptr(GError) error = NULL; g_autoptr(GsAppList) list = NULL; list = gs_plugin_loader_get_categories_finish (plugin_loader, res, &error); if (list == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("failed to get categories: %s", error->message); goto out; } gs_container_remove_all (GTK_CONTAINER (priv->flowbox_categories)); for (l = list; l; l = l->next) { cat = GS_CATEGORY (l->data); if (gs_category_get_size (cat) == 0) continue; tile = gs_category_tile_new (cat); g_signal_connect (tile, "clicked", G_CALLBACK (category_tile_clicked), self); gtk_flow_box_insert (GTK_FLOW_BOX (priv->flowbox_categories), tile, -1); gtk_widget_set_can_focus (gtk_widget_get_parent (tile), FALSE); has_category = TRUE; } out: if (has_category) { priv->empty = FALSE; } gtk_widget_set_visible (priv->category_heading, has_category); priv->loading_categories = FALSE; priv->refresh_count--; if (priv->refresh_count == 0) { priv->cache_valid = TRUE; g_signal_emit (self, signals[SIGNAL_REFRESHED], 0); } }
/** * gs_shell_overview_new: **/ GsShellOverview * gs_shell_overview_new (void) { return GS_SHELL_OVERVIEW (g_object_new (GS_TYPE_SHELL_OVERVIEW, NULL)); }
/** * gs_shell_setup: */ void gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *cancellable) { GsShellPrivate *priv = gs_shell_get_instance_private (shell); GtkWidget *widget; g_return_if_fail (GS_IS_SHELL (shell)); priv->plugin_loader = g_object_ref (plugin_loader); g_signal_connect (priv->plugin_loader, "updates-changed", G_CALLBACK (gs_shell_updates_changed_cb), shell); priv->cancellable = g_object_ref (cancellable); gs_shell_monitor_permission (shell); /* get UI */ priv->builder = gtk_builder_new_from_resource ("/org/gnome/Software/gnome-software.ui"); priv->main_window = GTK_WINDOW (gtk_builder_get_object (priv->builder, "window_software")); g_signal_connect (priv->main_window, "map", G_CALLBACK (gs_shell_main_window_mapped_cb), shell); /* add application specific icons to search path */ gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), GS_DATA G_DIR_SEPARATOR_S "icons"); g_signal_connect (priv->main_window, "delete-event", G_CALLBACK (main_window_closed_cb), shell); /* fix up the header bar */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "header")); g_object_ref (widget); gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (widget)), widget); gtk_window_set_titlebar (GTK_WINDOW (priv->main_window), widget); g_object_unref (widget); /* global keynav */ g_signal_connect_after (priv->main_window, "key_press_event", G_CALLBACK (window_key_press_event), shell); /* mouse hardware back button */ g_signal_connect_after (priv->main_window, "button_press_event", G_CALLBACK (window_button_press_event), shell); /* setup buttons */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_back")); g_signal_connect (widget, "clicked", G_CALLBACK (gs_shell_back_button_cb), shell); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_all")); g_object_set_data (G_OBJECT (widget), "gnome-software::overview-mode", GINT_TO_POINTER (GS_SHELL_MODE_OVERVIEW)); g_signal_connect (widget, "clicked", G_CALLBACK (gs_shell_overview_button_cb), shell); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_installed")); g_object_set_data (G_OBJECT (widget), "gnome-software::overview-mode", GINT_TO_POINTER (GS_SHELL_MODE_INSTALLED)); g_signal_connect (widget, "clicked", G_CALLBACK (gs_shell_overview_button_cb), shell); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_updates")); g_object_set_data (G_OBJECT (widget), "gnome-software::overview-mode", GINT_TO_POINTER (GS_SHELL_MODE_UPDATES)); g_signal_connect (widget, "clicked", G_CALLBACK (gs_shell_overview_button_cb), shell); priv->shell_overview = GS_SHELL_OVERVIEW (gtk_builder_get_object (priv->builder, "shell_overview")); gs_shell_overview_setup (priv->shell_overview, shell, priv->plugin_loader, priv->builder, priv->cancellable); priv->shell_updates = GS_SHELL_UPDATES (gtk_builder_get_object (priv->builder, "shell_updates")); gs_shell_updates_setup (priv->shell_updates, shell, priv->plugin_loader, priv->builder, priv->cancellable); priv->shell_installed = GS_SHELL_INSTALLED (gtk_builder_get_object (priv->builder, "shell_installed")); gs_shell_installed_setup (priv->shell_installed, shell, priv->plugin_loader, priv->builder, priv->cancellable); priv->shell_moderate = GS_SHELL_MODERATE (gtk_builder_get_object (priv->builder, "shell_moderate")); gs_shell_moderate_setup (priv->shell_moderate, shell, priv->plugin_loader, priv->builder, priv->cancellable); priv->shell_search = GS_SHELL_SEARCH (gtk_builder_get_object (priv->builder, "shell_search")); gs_shell_search_setup (priv->shell_search, shell, priv->plugin_loader, priv->builder, priv->cancellable); priv->shell_details = GS_SHELL_DETAILS (gtk_builder_get_object (priv->builder, "shell_details")); gs_shell_details_setup (priv->shell_details, shell, priv->plugin_loader, priv->builder, priv->cancellable); priv->shell_category = GS_SHELL_CATEGORY (gtk_builder_get_object (priv->builder, "shell_category")); gs_shell_category_setup (priv->shell_category, shell, priv->plugin_loader, priv->builder, priv->cancellable); priv->shell_extras = GS_SHELL_EXTRAS (gtk_builder_get_object (priv->builder, "shell_extras")); gs_shell_extras_setup (priv->shell_extras, shell, priv->plugin_loader, priv->builder, priv->cancellable); /* set up search */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "entry_search")); g_signal_connect (GTK_EDITABLE (widget), "activate", G_CALLBACK (gs_shell_search_activated_cb), shell); g_signal_connect (priv->main_window, "key-press-event", G_CALLBACK (window_keypress_handler), shell); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "entry_search")); g_signal_connect (widget, "key-press-event", G_CALLBACK (entry_keypress_handler), shell); g_signal_connect (widget, "search-changed", G_CALLBACK (search_changed_handler), shell); /* load content */ g_signal_connect (priv->shell_overview, "refreshed", G_CALLBACK (initial_overview_load_done), shell); }