This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
gnoemoe/gnoemoe/mcp/gm-mcp-icecrew-serverinfo.c

402 lines
11 KiB
C

#include <string.h>
#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);
}