340 lines
9.8 KiB
C
340 lines
9.8 KiB
C
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#include <gdk/gdkkeysyms.h>
|
|
#include <gtk/gtk.h>
|
|
#include <libgnomeui/libgnomeui.h>
|
|
#include <glade/glade.h>
|
|
|
|
#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();
|
|
}
|