diff --git a/src/ovirt-foreign-menu.c b/src/ovirt-foreign-menu.c index ef3ddd9..2939ae5 100644 --- a/src/ovirt-foreign-menu.c +++ b/src/ovirt-foreign-menu.c @@ -350,22 +350,6 @@ ovirt_foreign_menu_fetch_iso_names_finish(OvirtForeignMenu *foreign_menu, } -static void -ovirt_foreign_menu_activate_item_cb(GtkMenuItem *menuitem, gpointer user_data); - - -static void -menu_item_set_active_no_signal(GtkMenuItem *menuitem, - gboolean active, - GCallback callback, - gpointer user_data) -{ - g_signal_handlers_block_by_func(menuitem, callback, user_data); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), active); - g_signal_handlers_unblock_by_func(menuitem, callback, user_data); -} - - static void iso_name_set_cb(GObject *source_object, GAsyncResult *result, gpointer user_data) @@ -447,88 +431,6 @@ gboolean ovirt_foreign_menu_set_current_iso_name_finish(OvirtForeignMenu *foreig } -static void -ovirt_foreign_menu_iso_name_changed(GObject *source_object, - GAsyncResult *result, - gpointer user_data G_GNUC_UNUSED) -{ - OvirtForeignMenu *foreign_menu = OVIRT_FOREIGN_MENU(source_object); - GError *error = NULL; - - if (!ovirt_foreign_menu_set_current_iso_name_finish(foreign_menu, result, &error)) { - g_warning(error ? error->message : "Failed to change CD"); - g_clear_error(&error); - return; - } - - g_object_notify(G_OBJECT(foreign_menu), "file"); -} - - -static void -ovirt_foreign_menu_activate_item_cb(GtkMenuItem *menuitem, gpointer user_data) -{ - OvirtForeignMenu *foreign_menu; - const char *iso_name = NULL; - gboolean checked; - - checked = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)); - foreign_menu = OVIRT_FOREIGN_MENU(user_data); - g_return_if_fail(foreign_menu->priv->cdrom != NULL); - g_return_if_fail(foreign_menu->priv->next_iso_name == NULL); - - g_debug("'%s' clicked", gtk_menu_item_get_label(menuitem)); - - /* We only want to move the check mark for the currently selected ISO - * when ovirt_cdrom_update_async() is successful, so for now we move - * the check mark back to where it was before - */ - menu_item_set_active_no_signal(menuitem, !checked, - (GCallback)ovirt_foreign_menu_activate_item_cb, - foreign_menu); - - if (checked) { - iso_name = gtk_menu_item_get_label(menuitem); - } - ovirt_foreign_menu_set_current_iso_name_async(foreign_menu, iso_name, NULL, - ovirt_foreign_menu_iso_name_changed, - menuitem); -} - - -GtkWidget *ovirt_foreign_menu_get_gtk_menu(OvirtForeignMenu *foreign_menu) -{ - GtkWidget *gtk_menu; - GList *it; - char *current_iso; - - if (foreign_menu->priv->iso_names == NULL) { - g_debug("ISO list is empty, no menu to show"); - return NULL; - } - g_debug("Creating GtkMenu for foreign menu"); - current_iso = ovirt_foreign_menu_get_current_iso_name(foreign_menu); - gtk_menu = gtk_menu_new(); - for (it = foreign_menu->priv->iso_names; it != NULL; it = it->next) { - GtkWidget *menuitem; - - menuitem = gtk_check_menu_item_new_with_label((char *)it->data); - if (g_strcmp0((char *)it->data, current_iso) == 0) { - g_warn_if_fail(g_strcmp0(current_iso, foreign_menu->priv->current_iso_name) == 0); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), - TRUE); - } - g_signal_connect(menuitem, "activate", - G_CALLBACK(ovirt_foreign_menu_activate_item_cb), - foreign_menu); - gtk_menu_shell_append(GTK_MENU_SHELL(gtk_menu), menuitem); - } - g_free(current_iso); - - return gtk_menu; -} - - static void ovirt_foreign_menu_set_files(OvirtForeignMenu *menu, const GList *files) { @@ -594,7 +496,6 @@ static void cdrom_file_refreshed_cb(GObject *source_object, "file", &menu->priv->current_iso_name, NULL); } - g_object_notify(G_OBJECT(menu), "file"); if (menu->priv->cdrom != NULL) { ovirt_foreign_menu_next_async_step(menu, task, STATE_CDROM_FILE); } else { diff --git a/src/remote-viewer.c b/src/remote-viewer.c index c84a35b..d04dbb5 100644 --- a/src/remote-viewer.c +++ b/src/remote-viewer.c @@ -67,12 +67,18 @@ G_DEFINE_TYPE (RemoteViewer, remote_viewer, VIRT_VIEWER_TYPE_APP) #define GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), REMOTE_VIEWER_TYPE, RemoteViewerPrivate)) +enum RemoteViewerProperties { + PROP_0, +#ifdef HAVE_OVIRT + PROP_OVIRT_FOREIGN_MENU, +#endif +}; + #ifdef HAVE_OVIRT static OvirtVm * choose_vm(GtkWindow *main_window, char **vm_name, OvirtCollection *vms, GError **error); -static gboolean remote_viewer_refresh_ovirt_foreign_menu(gpointer user_data); #endif static gboolean remote_viewer_start(VirtViewerApp *self, GError **error); @@ -213,6 +219,25 @@ end: return ret; } +static void +remote_viewer_get_property(GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + RemoteViewer *self = REMOTE_VIEWER(object); + RemoteViewerPrivate *priv = self->priv; + + switch (property_id) { +#ifdef HAVE_OVIRT + case PROP_OVIRT_FOREIGN_MENU: + g_value_set_object(value, priv->ovirt_foreign_menu); + break; +#endif + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + static void remote_viewer_class_init (RemoteViewerClass *klass) { @@ -223,6 +248,7 @@ remote_viewer_class_init (RemoteViewerClass *klass) g_type_class_add_private (klass, sizeof (RemoteViewerPrivate)); + object_class->get_property = remote_viewer_get_property; object_class->dispose = remote_viewer_dispose; g_app_class->local_command_line = remote_viewer_local_command_line; @@ -236,6 +262,16 @@ remote_viewer_class_init (RemoteViewerClass *klass) #else (void) gtk_app_class; #endif + +#ifdef HAVE_OVIRT + g_object_class_install_property(object_class, + PROP_OVIRT_FOREIGN_MENU, + g_param_spec_object("ovirt-foreign-menu", + "oVirt Foreign Menu", + "Object which is used as interface to oVirt", + OVIRT_TYPE_FOREIGN_MENU, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); +#endif } static void @@ -735,33 +771,11 @@ authenticate_cb(RestProxy *proxy, G_GNUC_UNUSED RestProxyAuth *auth, static void ovirt_foreign_menu_update(GtkApplication *gtkapp, GtkWindow *gtkwin, G_GNUC_UNUSED gpointer data) { - RemoteViewer *app = REMOTE_VIEWER(gtkapp); + RemoteViewer *self = REMOTE_VIEWER(gtkapp); VirtViewerWindow *win = g_object_get_data(G_OBJECT(gtkwin), "virt-viewer-window"); - GtkWidget *menu = g_object_get_data(G_OBJECT(win), "foreign-menu"); - GtkWidget *submenu; - - if (app->priv->ovirt_foreign_menu == NULL) { - /* nothing to do */ - return; - } - - submenu = ovirt_foreign_menu_get_gtk_menu(app->priv->ovirt_foreign_menu); - if (submenu == NULL) { - /* No items to show, no point in showing the menu */ - if (menu != NULL) - gtk_widget_set_visible(menu, FALSE); - g_object_set_data(G_OBJECT(win), "foreign-menu", NULL); - return; - } - - if (menu == NULL) { - menu = GTK_WIDGET(gtk_builder_get_object(virt_viewer_window_get_builder(win), "menu-change-cd")); - g_object_set_data(G_OBJECT(win), "foreign-menu", menu); - gtk_widget_set_visible(menu, TRUE); - } - - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu), submenu); - gtk_widget_show_all(menu); + GtkBuilder *builder = virt_viewer_window_get_builder(win); + GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(builder, "menu-change-cd")); + gtk_widget_set_visible(menu, self->priv->ovirt_foreign_menu != NULL); } static void @@ -783,52 +797,6 @@ ovirt_foreign_menu_updated(RemoteViewer *self) g_list_foreach(windows, ovirt_foreign_menu_update_each, self); } -static void -ovirt_foreign_menu_fetch_iso_names_cb(GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - OvirtForeignMenu *foreign_menu = OVIRT_FOREIGN_MENU(source_object); - RemoteViewer *self = REMOTE_VIEWER(user_data); - VirtViewerApp *app = VIRT_VIEWER_APP(user_data); - GError *error = NULL; - GList *iso_list; - - iso_list = ovirt_foreign_menu_fetch_iso_names_finish(foreign_menu, result, &error); - - if (!iso_list) { - virt_viewer_app_simple_message_dialog(app, error ? error->message : _("Failed to fetch CD names")); - g_clear_error(&error); - return; - } - - ovirt_foreign_menu_updated(self); - g_timeout_add_seconds(300, remote_viewer_refresh_ovirt_foreign_menu, self); -} - -static gboolean -remote_viewer_refresh_ovirt_foreign_menu(gpointer user_data) -{ - VirtViewerApp *app = VIRT_VIEWER_APP(user_data); - RemoteViewer *self = REMOTE_VIEWER(user_data); - - g_debug("Refreshing foreign menu iso list"); - ovirt_foreign_menu_fetch_iso_names_async(self->priv->ovirt_foreign_menu, - NULL, - ovirt_foreign_menu_fetch_iso_names_cb, - app); - return G_SOURCE_REMOVE; -} - -static void -ovirt_foreign_menu_changed(OvirtForeignMenu *foreign_menu G_GNUC_UNUSED, - GParamSpec *pspec G_GNUC_UNUSED, - VirtViewerApp *app) -{ - ovirt_foreign_menu_updated(REMOTE_VIEWER(app)); -} - - static void virt_viewer_app_set_ovirt_foreign_menu(VirtViewerApp *app, OvirtForeignMenu *foreign_menu) @@ -838,17 +806,11 @@ virt_viewer_app_set_ovirt_foreign_menu(VirtViewerApp *app, g_return_if_fail(OVIRT_IS_FOREIGN_MENU(foreign_menu)); self = REMOTE_VIEWER(app); - if (self->priv->ovirt_foreign_menu != NULL) { - g_object_unref(G_OBJECT(self->priv->ovirt_foreign_menu)); - } + g_clear_object(&self->priv->ovirt_foreign_menu); self->priv->ovirt_foreign_menu = foreign_menu; - g_signal_connect(G_OBJECT(foreign_menu), "notify::file", - (GCallback)ovirt_foreign_menu_changed, app); - g_signal_connect(G_OBJECT(app), "window-added", (GCallback)ovirt_foreign_menu_update, NULL); - - remote_viewer_refresh_ovirt_foreign_menu(self); + ovirt_foreign_menu_updated(self); } static gboolean diff --git a/src/resources/ui/virt-viewer.ui b/src/resources/ui/virt-viewer.ui index 6e3c5ad..e9609ec 100644 --- a/src/resources/ui/virt-viewer.ui +++ b/src/resources/ui/virt-viewer.ui @@ -1,6 +1,7 @@ + - + False @@ -72,6 +73,14 @@ + + + False + _Change CD + True + + + True @@ -247,14 +256,6 @@ - - - False - False - _Change CD - True - - False diff --git a/src/virt-viewer-window.c b/src/virt-viewer-window.c index 99fd102..8eda12e 100644 --- a/src/virt-viewer-window.c +++ b/src/virt-viewer-window.c @@ -43,6 +43,8 @@ #include "virt-viewer-util.h" #include "virt-viewer-timed-revealer.h" +#include "remote-viewer-iso-list-dialog.h" + #define ZOOM_STEP 10 /* Signal handlers for main window (move in a VirtViewerMainWindow?) */ @@ -62,6 +64,7 @@ void virt_viewer_window_menu_file_smartcard_insert(GtkWidget *menu, VirtViewerWi void virt_viewer_window_menu_file_smartcard_remove(GtkWidget *menu, VirtViewerWindow *self); void virt_viewer_window_menu_view_release_cursor(GtkWidget *menu, VirtViewerWindow *self); void virt_viewer_window_menu_preferences_cb(GtkWidget *menu, VirtViewerWindow *self); +void virt_viewer_window_menu_change_cd_activate(GtkWidget *menu, VirtViewerWindow *self); /* Internal methods */ @@ -1056,6 +1059,40 @@ virt_viewer_window_menu_help_about(GtkWidget *menu G_GNUC_UNUSED, g_object_unref(G_OBJECT(about)); } +static void +iso_dialog_response(GtkDialog *dialog, + gint response_id, + gpointer user_data G_GNUC_UNUSED) +{ + if (response_id == GTK_RESPONSE_NONE) + return; + + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + +void +virt_viewer_window_menu_change_cd_activate(GtkWidget *menu G_GNUC_UNUSED, + VirtViewerWindow *self) +{ + VirtViewerWindowPrivate *priv = self->priv; + GtkWidget *dialog; + GObject *foreign_menu; + + g_object_get(G_OBJECT(priv->app), "ovirt-foreign-menu", &foreign_menu, NULL); + dialog = remote_viewer_iso_list_dialog_new(GTK_WINDOW(priv->window), foreign_menu); + g_object_unref(foreign_menu); + + if (!dialog) + dialog = gtk_message_dialog_new(GTK_WINDOW(priv->window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _("Unable to connnect to oVirt")); + + g_signal_connect(dialog, "response", G_CALLBACK(iso_dialog_response), NULL); + gtk_widget_show_all(dialog); + gtk_dialog_run(GTK_DIALOG(dialog)); +} static void virt_viewer_window_toolbar_setup(VirtViewerWindow *self)