#include #include "gm-mcp-icecrew-serverinfo.h" #include "gm-mcp.h" #include "gm-mcp-session.h" #include "widgets/gm-app-view.h" #include "gm-world.h" #include "dialogs/gm-world-info-dialog.h" #include "gm-support.h" #include "gm-debug.h" #include "gm-options.h" #define GM_MCP_ICECREW_SERVERINFO_GET_PRIVATE(object)( \ G_TYPE_INSTANCE_GET_PRIVATE((object), \ GM_TYPE_MCP_ICECREW_SERVERINFO, GmMcpIcecrewServerinfoPrivate)) typedef struct _GmMcpIcecrewServerinfoView { GmAppView *view; GmMcpIcecrewServerinfo *package; } GmMcpIcecrewServerinfoView; struct _GmMcpIcecrewServerinfoPrivate { gboolean has_info; GmWorldInfo info; GmFetchHandle *handle; }action; /* Signals */ enum { GOT_INFO, NUM_SIGNALS }; static guint gm_mcp_icecrew_serverinfo_signals[NUM_SIGNALS] = {0}; G_DEFINE_TYPE(GmMcpIcecrewServerinfo, gm_mcp_icecrew_serverinfo, GM_TYPE_MCP_PACKAGE) void gm_mcp_icecrew_serverinfo_handle_simple(GmMcpPackage *package, gchar *suffix, GList *fields); void gm_mcp_icecrew_serverinfo_create_view(GmMcpPackage *package, GObject *parent); void gm_mcp_icecrew_serverinfo_set_session(GmMcpPackage *package, GObject *session); void gm_mcp_icecrew_serverinfo_free_info(GmMcpIcecrewServerinfo *obj) { g_free(obj->priv->info.homepage); g_free(obj->priv->info.location); g_free(obj->priv->info.admin); g_free(obj->priv->info.contact); g_free(obj->priv->info.charset); g_free(obj->priv->info.language); g_free(obj->priv->info.system); g_free(obj->priv->info.logo); if (obj->priv->handle) { obj->priv->handle->aborted = TRUE; } memset(&(obj->priv->info), 0, sizeof(GmWorldInfo)); } static void gm_mcp_icecrew_serverinfo_finalize(GObject *object) { GmMcpIcecrewServerinfo *obj = GM_MCP_ICECREW_SERVERINFO(object); gm_mcp_icecrew_serverinfo_free_info(obj); G_OBJECT_CLASS(gm_mcp_icecrew_serverinfo_parent_class)->finalize(object); } static void gm_mcp_icecrew_serverinfo_class_init(GmMcpIcecrewServerinfoClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); GmMcpPackageClass *pklass = GM_MCP_PACKAGE_CLASS(klass); object_class->finalize = gm_mcp_icecrew_serverinfo_finalize; gm_mcp_icecrew_serverinfo_signals[GOT_INFO] = g_signal_new("got_info", G_OBJECT_CLASS_TYPE(object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GmMcpIcecrewServerinfoClass, got_info), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); pklass->name = "dns-nl-icecrew-serverinfo"; pklass->handle_simple = &gm_mcp_icecrew_serverinfo_handle_simple; pklass->create_view = &gm_mcp_icecrew_serverinfo_create_view; pklass->set_session = &gm_mcp_icecrew_serverinfo_set_session; pklass->min_version = 1.0; pklass->max_version = 1.1; g_type_class_add_private(object_class, sizeof(GmMcpIcecrewServerinfoPrivate)); } static void gm_mcp_icecrew_serverinfo_init(GmMcpIcecrewServerinfo *obj) { obj->priv = GM_MCP_ICECREW_SERVERINFO_GET_PRIVATE(obj); obj->priv->has_info = FALSE; } GmMcpIcecrewServerinfo * gm_mcp_icecrew_serverinfo_new() { GmMcpIcecrewServerinfo *obj = GM_MCP_ICECREW_SERVERINFO(g_object_new( \ GM_TYPE_MCP_ICECREW_SERVERINFO, NULL)); return obj; } void gm_mcp_icecrew_serverinfo_fetch_progress(GmFetchHandle *g, GmMcpIcecrewServerinfo *package) { gchar *path; GdkPixbuf *pixtest; GError *err = NULL; if (g->aborted) { if (GM_IS_MCP_ICECREW_SERVERINFO(package)) { package->priv->handle = NULL; } gm_debug_msg(DEBUG_MCP, "GmIcecrewServerInfo.FetchProgress: " "fetch aborted!"); return; } if (g->done) { if (GM_IS_MCP_ICECREW_SERVERINFO(package)) { package->priv->handle = NULL; } gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewServerinfo.FetchProgress: " "fetch done!"); return; } if (g->cur_phase == GNOME_VFS_XFER_PHASE_FILECOMPLETED) { path = gnome_vfs_get_local_path_from_uri(g->cur_file_name); pixtest = gdk_pixbuf_new_from_file(path, &err); gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewServerinfo.FetchProgress: %s " "fetched!", path); if (pixtest) { g_object_unref(pixtest); package->priv->info.logo = path; gm_options_set(gm_world_options(GM_MCP_SESSION_WORLD( GM_MCP_PACKAGE_SESSION(package))), "logo", path); g_signal_emit(package, gm_mcp_icecrew_serverinfo_signals[GOT_INFO], 0); g->aborted = TRUE; } else { gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewServerinfo.FetchProgress: " "Error on loading %s: %s", path, err->message); g_error_free(err); g_free(path); } } } void gm_mcp_icecrew_serverinfo_handle_simple(GmMcpPackage *package, gchar *suffix, GList *fields) { GmMcpIcecrewServerinfo *serverinfo = GM_MCP_ICECREW_SERVERINFO(package); gchar *base, *path, **alternatives, **ptr; gchar const *logo; GList *source = NULL, *dest = NULL; GnomeVFSResult result; GnomeVFSFileInfo *finfo; if (strcmp(suffix, "set") == 0) { gm_mcp_icecrew_serverinfo_free_info(serverinfo); serverinfo->priv->info.name = g_strdup(gm_mcp_find_value(fields, "name")); serverinfo->priv->info.homepage = g_strdup(gm_mcp_find_value(fields, "homepage")); serverinfo->priv->info.location = g_strdup(gm_mcp_find_value(fields, "location")); serverinfo->priv->info.admin = g_strdup(gm_mcp_find_value(fields, "admin")); serverinfo->priv->info.contact = g_strdup(gm_mcp_find_value(fields, "contact")); serverinfo->priv->info.charset = g_strdup(gm_mcp_find_value(fields, "charset")); serverinfo->priv->info.language = g_strdup(gm_mcp_find_value(fields, "language")); serverinfo->priv->info.system = g_strdup(gm_mcp_find_value(fields, "system")); gm_options_set(gm_world_options(GM_MCP_SESSION_WORLD( GM_MCP_PACKAGE_SESSION(package))), "mooname", serverinfo->priv->info.name); if ((logo = gm_mcp_find_value(fields, "logo")) != NULL) { alternatives = g_strsplit(logo, ";", 0); ptr = alternatives; while (*ptr) { finfo = gnome_vfs_file_info_new(); result = gnome_vfs_get_file_info(*ptr, finfo, GNOME_VFS_FILE_INFO_DEFAULT); gnome_vfs_file_info_unref(finfo); if (result != GNOME_VFS_OK) { gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewServerinfo.HandleSimple: " "Ignore logo alternative %s because it's invalid: %s", *ptr, gnome_vfs_result_to_string(result)); } else { base = g_path_get_basename(*ptr); if (base && *base != '\0' && base[1] != '\0') { path = g_strconcat(gm_world_path(GM_MCP_SESSION_WORLD( GM_MCP_PACKAGE_SESSION(package))), G_DIR_SEPARATOR_S, "pixmaps", G_DIR_SEPARATOR_S, base, NULL); source = g_list_append(source, g_strdup(*ptr)); dest = g_list_append(dest, path); } g_free(base); } ++ptr; } g_strfreev(alternatives); if (source != NULL) { if (serverinfo->priv->handle) { serverinfo->priv->handle->aborted = TRUE; while (serverinfo->priv->handle != NULL) { gm_do_events(); } } if (serverinfo->priv->info.logo) { if (g_file_test(serverinfo->priv->info.logo, G_FILE_TEST_EXISTS)) { unlink(serverinfo->priv->info.logo); } g_free(serverinfo->priv->info.logo); serverinfo->priv->info.logo = NULL; } gm_fetch(source, dest, (GFunc)gm_mcp_icecrew_serverinfo_fetch_progress, serverinfo); gm_g_list_free_simple(source); gm_g_list_free_simple(dest); } } serverinfo->priv->has_info = TRUE; g_signal_emit(serverinfo, gm_mcp_icecrew_serverinfo_signals[GOT_INFO], 0); } } void gm_mcp_icecrew_serverinfo_set_session(GmMcpPackage *package, GObject *session) { GmMcpPackageClass *parent_class = g_type_class_peek_parent( GM_MCP_ICECREW_SERVERINFO_GET_CLASS(package)); gchar *path; parent_class->set_session(package, session); path = g_strconcat(gm_world_path(GM_MCP_SESSION_WORLD( GM_MCP_SESSION(session))), G_DIR_SEPARATOR_S, "pixmaps", NULL); if (!g_file_test(path, G_FILE_TEST_EXISTS)) { mkdir(path, 0755); } g_free(path); if (gm_mcp_package_get_version(package) == 1.0) { gm_mcp_session_send_simple(GM_MCP_SESSION(session), "dns-nl-icecrew-serverinfo-get", NULL); } } gboolean gm_mcp_icecrew_serverinfo_has_info(GmMcpIcecrewServerinfo *package) { return package->priv->has_info; } GmWorldInfo const * gm_mcp_icecrew_serverinfo_info(GmMcpIcecrewServerinfo *package) { return &(package->priv->info); } /* GmMcpIcecrewServerinfoView */ void on_gm_mcp_icecrew_serverinfo_view_activate(GtkMenuItem *item, GmMcpIcecrewServerinfoView *view) { gm_world_info_dialog_new(gm_mcp_icecrew_serverinfo_info(view->package)); } void gm_mcp_icecrew_serverinfo_view_set_visible(GmMcpIcecrewServerinfoView *view, gboolean visible) { GtkAction *action = gm_app_view_action(view->view, "/MenuBar/WorldMenu/WorldInfoMenu"); if (gtk_action_get_visible(action) == visible) { return; } gtk_action_set_visible(action, visible); if (visible) { g_signal_connect(action, "activate", G_CALLBACK(on_gm_mcp_icecrew_serverinfo_view_activate), view); } else { g_signal_handlers_disconnect_by_func(action, on_gm_mcp_icecrew_serverinfo_view_activate, view); } } void on_gm_mcp_icecrew_serverinfo_view_active_changed(GmWorld *world, GParamSpec *pspec, GmMcpIcecrewServerinfoView *view) { gboolean active = gm_world_active(world); if (active && gm_mcp_icecrew_serverinfo_has_info(view->package)) { gm_mcp_icecrew_serverinfo_view_set_visible(view, TRUE); } else if (!active) { gm_mcp_icecrew_serverinfo_view_set_visible(view, FALSE); } } void on_gm_mcp_icecrew_serverinfo_view_weak_notify(gpointer data, GObject *obj) { GmMcpIcecrewServerinfoView *view = (GmMcpIcecrewServerinfoView *)(data); GmWorld *world = GM_MCP_SESSION_WORLD( GM_MCP_PACKAGE_SESSION(view->package)); g_signal_handlers_disconnect_by_func(world, on_gm_mcp_icecrew_serverinfo_view_active_changed, view); if (gm_world_active(world)) { gm_mcp_icecrew_serverinfo_view_set_visible(view, FALSE); } g_free(data); } void on_gm_mcp_icecrew_serverinfo_view_got_info(GmMcpIcecrewServerinfo *package, GmMcpIcecrewServerinfoView *view) { if (gm_world_active(GM_MCP_SESSION_WORLD( GM_MCP_PACKAGE_SESSION(package)))) { gm_mcp_icecrew_serverinfo_view_set_visible(view, TRUE); } /* Set the charset */ if (package->priv->info.charset && *package->priv->info.charset != '\0') gm_options_set(gm_world_options(GM_MCP_SESSION_WORLD( GM_MCP_PACKAGE_SESSION(package))), "charset", package->priv->info.charset); // TODO: set logo for world menu item } void gm_mcp_icecrew_serverinfo_create_view(GmMcpPackage *package, GObject *parent) { GmMcpIcecrewServerinfoView *view; if (!GM_IS_APP_VIEW(parent)) { return; } view = g_new(GmMcpIcecrewServerinfoView, 1); view->view = GM_APP_VIEW(parent); view->package = GM_MCP_ICECREW_SERVERINFO(package); // Connect the got_info signal to know when new information has arrived g_signal_connect(package, "got_info", G_CALLBACK(on_gm_mcp_icecrew_serverinfo_view_got_info), view); // Connect to active_changed signal of the world to alter the sensitivity // of the info menu item g_signal_connect(GM_MCP_SESSION_WORLD(GM_MCP_PACKAGE_SESSION(package)), "notify::active", G_CALLBACK(on_gm_mcp_icecrew_serverinfo_view_active_changed), view); // Connect a weak ref notifier to the McpPackage to know when to destroy // ourselfs g_object_weak_ref(G_OBJECT(package), on_gm_mcp_icecrew_serverinfo_view_weak_notify, view); }