#ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include "gm-support.h" #include "gm-debug.h" #include "gm-app.h" #include "gm-worlds-list-dialog.h" #include "gm-world-properties-dialog.h" #include "gm-pixbuf.h" #include "widgets/gm-worlds-view.h" typedef struct _GmWorldsListDialog { GladeXML *xml; GtkWidget *dialog; } GmWorldsListDialog; void on_gm_worlds_list_dialog_button_delete_clicked(GtkButton * utton, gpointer user_data); void on_gm_worlds_list_dialog_button_new_clicked(GtkButton *button, gpointer user_data); void on_gm_worlds_list_dialog_button_modify_clicked(GtkButton *button, gpointer user_data); void on_gm_worlds_list_dialog_button_duplicate_clicked(GtkButton *button, gpointer user_data); void on_gm_worlds_list_dialog_button_connect_clicked(GtkButton *button, gpointer user_data); void on_gm_worlds_list_dialog_tree_view_worlds_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data); void on_gm_worlds_list_dialog_tree_view_worlds_row_activated( GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data); void on_gm_worlds_list_dialog_response(GtkDialog *dialog, gint response, gpointer user_data); static GmWorldsListDialog *gm_worlds_list_dialog_instance; GtkWidget * gm_worlds_list_dialog_widget(gchar *name) { return glade_xml_get_widget(gm_worlds_list_dialog_instance->xml, name); } #define GM_WORLDS_LIST_DIALOG_XML PACKAGE_DATA_DIR "/" PACKAGE \ "/ui/gm-worlds-list.glade" GtkWidget * gm_worlds_list_dialog_create_tree_view(gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2) { GtkWidget *tree_view = gm_worlds_view_new(); g_signal_connect(tree_view, "key-press-event", G_CALLBACK(on_gm_worlds_list_dialog_tree_view_worlds_key_press), NULL); g_signal_connect(tree_view, "row-activated", G_CALLBACK(on_gm_worlds_list_dialog_tree_view_worlds_row_activated), NULL); gtk_widget_show(GTK_WIDGET(tree_view)); return GTK_WIDGET(tree_view); } void gm_worlds_list_dialog_run() { GladeXML *xml; if (gm_worlds_list_dialog_instance) { gtk_widget_show(gm_worlds_list_dialog_instance->dialog); gtk_window_present(GTK_WINDOW(gm_worlds_list_dialog_instance->dialog)); return; } xml = glade_xml_new(GM_WORLDS_LIST_DIALOG_XML, "gm_worlds_list_dialog", NULL); if (xml == NULL) { gm_debug_msg(DEBUG_ALWAYS, "Couldn't find glade file %s!", GM_WORLDS_LIST_DIALOG_XML); return; } gm_worlds_list_dialog_instance = g_new0(GmWorldsListDialog, 1); gm_worlds_list_dialog_instance->xml = xml; glade_xml_signal_connect(xml, "on_button_delete_clicked", G_CALLBACK(on_gm_worlds_list_dialog_button_delete_clicked)); glade_xml_signal_connect(xml, "on_button_new_clicked", G_CALLBACK(on_gm_worlds_list_dialog_button_new_clicked)); glade_xml_signal_connect(xml, "on_button_modify_clicked", G_CALLBACK(on_gm_worlds_list_dialog_button_modify_clicked)); glade_xml_signal_connect(xml, "on_button_duplicate_clicked", G_CALLBACK(on_gm_worlds_list_dialog_button_duplicate_clicked)); glade_xml_signal_connect(xml, "on_button_connect_clicked", G_CALLBACK(on_gm_worlds_list_dialog_button_connect_clicked)); gm_worlds_list_dialog_instance->dialog = gm_worlds_list_dialog_widget("gm_worlds_list_dialog"); gtk_window_set_icon(GTK_WINDOW(gm_worlds_list_dialog_instance->dialog), gm_pixbuf_get("world.svg")); g_signal_connect(gm_worlds_list_dialog_instance->dialog, "response", G_CALLBACK(on_gm_worlds_list_dialog_response), NULL); gtk_widget_show(gm_worlds_list_dialog_instance->dialog); } static void gm_worlds_list_dialog_delete_selected_worlds() { GtkTreeView *tree_view = GTK_TREE_VIEW( gm_worlds_list_dialog_widget("tree_view_worlds")); GtkTreeModel *model = gm_worlds_view_model(GM_WORLDS_VIEW(tree_view)); GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view); GtkTreeIter iter; GList *paths = gtk_tree_selection_get_selected_rows(selection, &model); GList *refs = NULL; GList *node = NULL; gchar *message; gpointer proxy = g_object_newv(G_TYPE_OBJECT, 0, NULL); GmWorld *world; for (node = paths; node; node = node->next) { refs = g_list_append(refs, gtk_tree_row_reference_new_proxy(proxy, model, node->data)); gtk_tree_path_free(node->data); } g_list_free(paths); if (refs) { for (node = refs; node; node = node->next) { GtkTreePath *path = gtk_tree_row_reference_get_path(node->data); gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, GM_WORLDS_VIEW_WORLD_COLUMN, &world, -1); if (!(world && gm_world_loaded(world))) { gm_app_remove_world(gm_app_instance(), world); } else { message = g_strdup_printf(_ ("The world %s is still open. Do you want to close " "and remove the world?"), gm_world_name(world)); if (gm_question_dialog(message, GTK_WINDOW(gm_worlds_list_dialog_instance->dialog)) == GTK_RESPONSE_YES) { gm_world_unload(world); gm_app_remove_world(gm_app_instance(), world); } g_free(message); } gtk_tree_row_reference_deleted(proxy, path); gtk_tree_path_free(path); gtk_tree_row_reference_free(node->data); } } else { gm_error_dialog(_("You first need to select a world to delete."), GTK_WINDOW(gm_worlds_list_dialog_instance->dialog)); } g_list_free(refs); g_object_unref(proxy); } void gm_worlds_list_dialog_modify_world() { GtkTreeView *tree_view = GTK_TREE_VIEW( gm_worlds_list_dialog_widget("tree_view_worlds")); GtkTreeModel *model = gm_worlds_view_model(GM_WORLDS_VIEW(tree_view)); GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view); GtkTreeIter iter; GList *first_path = gtk_tree_selection_get_selected_rows(selection, &model); GmWorld *world; if (first_path) { gtk_tree_model_get_iter(model, &iter, first_path->data); gtk_tree_model_get(model, &iter, GM_WORLDS_VIEW_WORLD_COLUMN, &world, -1); gm_world_properties_dialog_run(world); } else { gm_error_dialog(_("You first need to select a world to modify."), GTK_WINDOW(gm_worlds_list_dialog_instance->dialog)); } g_list_free(first_path); } GList * gm_worlds_list_dialog_selected_path() { GtkTreeView *tree_view = GTK_TREE_VIEW( gm_worlds_list_dialog_widget("tree_view_worlds")); GtkTreeModel *model = gm_worlds_view_model(GM_WORLDS_VIEW(tree_view)); GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view); return gtk_tree_selection_get_selected_rows(selection, &model); } GmWorld * gm_worlds_list_dialog_selected_world() { GtkTreeView *tree_view = GTK_TREE_VIEW( gm_worlds_list_dialog_widget("tree_view_worlds")); GtkTreeModel *model = gm_worlds_view_model(GM_WORLDS_VIEW(tree_view)); GtkTreeIter iter; GList *first_path = gm_worlds_list_dialog_selected_path(); GmWorld *world = NULL; if (first_path) { gtk_tree_model_get_iter(model, &iter, first_path->data); gtk_tree_model_get(model, &iter, GM_WORLDS_VIEW_WORLD_COLUMN, &world, -1); } g_list_free(first_path); return world; } void gm_worlds_list_dialog_connect_world() { GtkTreeView *tree_view = GTK_TREE_VIEW( gm_worlds_list_dialog_widget("tree_view_worlds")); GtkTreeModel *model = gm_worlds_view_model(GM_WORLDS_VIEW(tree_view)); GList *first_path = gm_worlds_list_dialog_selected_path(); GList *path; GmWorld *world; GtkTreeIter iter; if (first_path) { for (path = first_path; path; path = path->next) { gtk_tree_model_get_iter(model, &iter, first_path->data); gtk_tree_model_get(model, &iter, GM_WORLDS_VIEW_WORLD_COLUMN, &world, -1); gm_world_load(world); } } else { gm_error_dialog( _("You first need to select a world to connect to."), GTK_WINDOW(gm_worlds_list_dialog_instance->dialog)); } g_list_free(first_path); } // Callbacks void on_gm_worlds_list_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) { g_object_unref(gm_worlds_list_dialog_instance->xml); gtk_widget_destroy(gm_worlds_list_dialog_instance->dialog); g_free(gm_worlds_list_dialog_instance); gm_worlds_list_dialog_instance = NULL; } void on_gm_worlds_list_dialog_button_delete_clicked(GtkButton *button, gpointer user_data) { gm_worlds_list_dialog_delete_selected_worlds(); } void on_gm_worlds_list_dialog_tree_view_worlds_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { switch (event->keyval) { case GDK_D: case GDK_d: gm_worlds_list_dialog_delete_selected_worlds(); break; case GDK_O: case GDK_o: break; case GDK_N: case GDK_n: gm_world_properties_dialog_run_new(NULL); break; case GDK_M: case GDK_m: gm_worlds_list_dialog_modify_world(); break; } } void on_gm_worlds_list_dialog_tree_view_worlds_row_activated( GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data) { gm_worlds_list_dialog_modify_world(); } void on_gm_worlds_list_dialog_button_new_clicked(GtkButton *button, gpointer user_data) { gm_world_properties_dialog_run_new(NULL); } void on_gm_worlds_list_dialog_button_modify_clicked(GtkButton *button, gpointer user_data) { gm_worlds_list_dialog_modify_world(); } void on_gm_worlds_list_dialog_button_duplicate_clicked(GtkButton *button, gpointer user_data) { GmWorld *world = gm_worlds_list_dialog_selected_world(); GmWorld *new_world; if (world) { // now duplicate the world new_world = gm_world_dup(world); // Yeah we got some world, now show the props! gm_world_properties_dialog_run_new(new_world); } else { gm_error_dialog( _("You first need to select a world to duplicate."), GTK_WINDOW(gm_worlds_list_dialog_instance->dialog)); } } void on_gm_worlds_list_dialog_button_connect_clicked(GtkButton *button, gpointer user_data) { gm_worlds_list_dialog_connect_world(); }