* Guifications - The end all, be all, toaster popup plugin * Copyright (C) 2003-2005 Gary Kramlich * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # include "../gf_config.h" #include "gf_event_info.h" #include "gf_item_icon.h" #include "gf_item_image.h" #include "gf_item_offset.h" #include "gf_item_text.h" #include "gf_notification.h" #include "gf_preferences.h" /* This setup sucks, but meh.. it works... be sure to update both the translated * and the English versions if you add or remove anything. The english is used * only for the files, so they're case insentive. The i18n are used in the * I'd fix this.. But whats translated doesn't match what is in the themes, and * while we could use the text that's used in the theme's as display text, why * mess with it while this, as ugly as it is, does work. const gchar *items_norm[] = { "icon", "image", "text", NULL }; const gchar *items_i18n[] = { N_("Icon"), N_("Image"), N_("Text"), NULL }; const gchar *positions_norm[] = { "north-west", "north", "north-east", "west", "center", "east", "south-west", "south", "south-east", const gchar *positions_i18n[] = { N_("North West"), N_("North"), N_("North East"), N_("West"), N_("Center"), N_("East"), N_("South West"), N_("South"), N_("South East"), NULL }; GfNotification *notification; gf_item_get_render_position(gint *x, gint *y, gint width, gint height, gint img_width, gint img_height, GfItem *item) gint north, east, south, west, lat, lon; img_h_h = img_height / 2; if(gf_item_offset_get_is_percentage(item->h_offset)) h_offset = (img_width * gf_item_offset_get_value(item->h_offset)) / 100; h_offset = gf_item_offset_get_value(item->h_offset); if(gf_item_offset_get_is_percentage(item->v_offset)) v_offset = (img_height * gf_item_offset_get_value(item->v_offset)) / 100; v_offset = gf_item_offset_get_value(item->v_offset); east = img_width - width + h_offset; south = img_height - height + v_offset; lon = img_h_w - item_h_w + h_offset; lat = img_h_h - item_h_h + v_offset; case GF_ITEM_POSITION_NW: *x = west; *y = north; break; case GF_ITEM_POSITION_N: *x = lon; *y = north; break; case GF_ITEM_POSITION_NE: *x = east; *y = north; break; case GF_ITEM_POSITION_W: *x = west; *y = lat; break; case GF_ITEM_POSITION_C: *x = lon; *y = lat; break; case GF_ITEM_POSITION_E: *x = east; *y = lat; break; case GF_ITEM_POSITION_SW: *x = west; *y = south; break; case GF_ITEM_POSITION_S: *x = lon; *y = south; break; case GF_ITEM_POSITION_SE: *x = east; *y = south; break; default: *x = 0; *y = 0; break; gf_item_type_to_string(GfItemType type, gboolean i18n) { g_return_val_if_fail(type < GF_ITEM_TYPE_UNKNOWN, NULL); g_return_val_if_fail(type >= 0, NULL); return _(items_i18n[type]); gf_item_type_from_string(const gchar *string, gboolean i18n) { g_return_val_if_fail(string, GF_ITEM_TYPE_UNKNOWN); for(i = 0; i < GF_ITEM_TYPE_UNKNOWN; i++) { return GF_ITEM_TYPE_UNKNOWN; if(!g_ascii_strcasecmp(string, val)) return GF_ITEM_TYPE_UNKNOWN; gf_item_position_to_string(GfItemPosition position, gboolean i18n) { g_return_val_if_fail(position < GF_ITEM_POSITION_UNKNOWN, NULL); g_return_val_if_fail(position >= 0, NULL); return _(positions_i18n[position]); return positions_norm[position]; gf_item_position_from_string(const gchar *position, gboolean i18n) { g_return_val_if_fail(position, GF_ITEM_POSITION_UNKNOWN); for(i = 0; i < GF_ITEM_POSITION_UNKNOWN; i++) { val = _(positions_i18n[i]); return GF_ITEM_POSITION_UNKNOWN; if(!g_ascii_strcasecmp(val, position)) return GF_ITEM_POSITION_UNKNOWN; gf_item_new(GfNotification *notification) { g_return_val_if_fail(notification, NULL); item = g_new0(GfItem, 1); item->notification = notification; gf_item_new_from_xmlnode(GfNotification *notification, xmlnode *node) { g_return_val_if_fail(node, NULL); g_return_val_if_fail(notification, NULL); item = gf_item_new(notification); item->type = gf_item_type_from_string(xmlnode_get_attrib(node, "type"), FALSE); if(item->type == GF_ITEM_TYPE_UNKNOWN) { purple_debug_info("Guifications", "** Error: unknown item type\n"); if((child = xmlnode_get_child(node, "position"))) { item->position = gf_item_position_from_string(xmlnode_get_attrib(child, "value"), FALSE); if(item->position == GF_ITEM_POSITION_UNKNOWN) { purple_debug_info("Guifications", "** Error: invalid position\n"); } else { /* if we don't have a position we drop the item */ purple_debug_info("Guifications", "** Error: no positioning found for item\n"); /* if we don't have an offset node, we create it anyways so it can be * changed in the theme editor. if((child = xmlnode_get_child(node, "h_offset"))) item->h_offset = gf_item_offset_new_from_xmlnode(item, child); item->h_offset = gf_item_offset_new(item); if((child = xmlnode_get_child(node, "v_offset"))) item->v_offset = gf_item_offset_new_from_xmlnode(item, child); item->v_offset = gf_item_offset_new(item); if((child = xmlnode_get_child(node, "icon"))) { item->u.icon = gf_item_icon_new_from_xmlnode(item, child); purple_debug_info("Guifications", "** Error loading icon item: 'No icon element found'\n"); if((child = xmlnode_get_child(node, "image"))) { item->u.image = gf_item_image_new_from_xmlnode(item, child); purple_debug_info("Guifications", "** Error loading image item: 'No image element found'\n"); if((child = xmlnode_get_child(node, "text"))) { item->u.text = gf_item_text_new_from_xmlnode(item, child); purple_debug_info("Guifications", "** Error loading text item: 'No text element found'\n"); case GF_ITEM_TYPE_UNKNOWN: purple_debug_info("Guifications", "** Error loading item: 'Unknown item type'\n"); gf_item_copy(GfItem *item) { g_return_val_if_fail(item, NULL); new_item = gf_item_new(item->notification); new_item->type = item->type; new_item->position = item->position; new_item->h_offset = gf_item_offset_copy(item->h_offset); new_item->v_offset = gf_item_offset_copy(item->v_offset); if(item->type == GF_ITEM_TYPE_ICON) new_item->u.icon = gf_item_icon_copy(item->u.icon); else if(item->type == GF_ITEM_TYPE_ICON) new_item->u.image = gf_item_image_copy(item->u.image); else if(item->type == GF_ITEM_TYPE_TEXT) new_item->u.text = gf_item_text_copy(item->u.text); gf_item_destroy(new_item); gf_item_to_xmlnode(GfItem *item) { parent = xmlnode_new("item"); xmlnode_set_attrib(parent, "type", gf_item_type_to_string(item->type, FALSE)); child = xmlnode_new_child(parent, "position"); xmlnode_set_attrib(child, "value", gf_item_position_to_string(item->position, FALSE)); child = xmlnode_new_child(parent, "h_offset"); offset = g_strdup_printf("%d%s", gf_item_offset_get_value(item->h_offset), gf_item_offset_get_is_percentage(item->h_offset) ? "%" : ""); xmlnode_set_attrib(child, "value", offset); child = xmlnode_new_child(parent, "v_offset"); offset = g_strdup_printf("%d%s", gf_item_offset_get_value(item->v_offset), gf_item_offset_get_is_percentage(item->v_offset) ? "%" : ""); xmlnode_set_attrib(child, "value", offset); child = gf_item_icon_to_xmlnode(item->u.icon); child = gf_item_image_to_xmlnode(item->u.image); child = gf_item_text_to_xmlnode(item->u.text); case GF_ITEM_TYPE_UNKNOWN: xmlnode_insert_child(parent, child); gf_item_destroy(GfItem *item) { gf_item_offset_destroy(item->h_offset); gf_item_offset_destroy(item->v_offset); if(item->type == GF_ITEM_TYPE_ICON && item->u.icon) { gf_item_icon_destroy(item->u.icon); if(item->type == GF_ITEM_TYPE_IMAGE && item->u.image) { gf_item_image_destroy(item->u.image); if(item->type == GF_ITEM_TYPE_TEXT && item->u.text) { gf_item_text_destroy(item->u.text); gf_item_set_type(GfItem *item, GfItemType type) { g_return_if_fail(type != GF_ITEM_TYPE_UNKNOWN); gf_item_get_type(GfItem *item) { g_return_val_if_fail(item, GF_ITEM_TYPE_UNKNOWN); gf_item_set_notification(GfItem *item, GfNotification *notification) { g_return_if_fail(notification); item->notification = notification; gf_item_get_notification(GfItem *item) { g_return_val_if_fail(item, NULL); return item->notification; gf_item_set_horz_offset(GfItem *item, GfItemOffset *offset) { g_return_if_fail(offset); gf_item_get_horz_offset(GfItem *item) { g_return_val_if_fail(item, NULL); gf_item_set_vert_offset(GfItem *item, GfItemOffset *offset) { g_return_if_fail(offset); gf_item_get_vert_offset(GfItem *item) { g_return_val_if_fail(item, NULL); gf_item_set_position(GfItem *item, GfItemPosition position) { g_return_if_fail(position != GF_ITEM_POSITION_UNKNOWN); item->position = position; gf_item_get_position(GfItem *item) { g_return_val_if_fail(item, GF_ITEM_POSITION_UNKNOWN); gf_item_free_old_subtype(GfItem *item) { if(item->type == GF_ITEM_TYPE_ICON && item->u.icon) gf_item_icon_destroy(item->u.icon); else if(item->type == GF_ITEM_TYPE_IMAGE && item->u.image) gf_item_image_destroy(item->u.image); else if(item->type == GF_ITEM_TYPE_TEXT && item->u.text) gf_item_text_destroy(item->u.text); gf_item_set_item_icon(GfItem *item, GfItemIcon *icon) { gf_item_free_old_subtype(item); gf_item_get_item_icon(GfItem *item) { g_return_val_if_fail(item->type == GF_ITEM_TYPE_ICON, NULL); gf_item_set_item_image(GfItem *item, GfItemImage *image) { gf_item_free_old_subtype(item); gf_item_get_item_image(GfItem *item) { g_return_val_if_fail(item->type == GF_ITEM_TYPE_IMAGE, NULL); gf_item_set_item_text(GfItem *item, GfItemText *text) { gf_item_free_old_subtype(item); gf_item_get_item_text(GfItem *item) { g_return_val_if_fail(item->type == GF_ITEM_TYPE_TEXT, NULL); gf_item_render(GfItem *item, GdkPixbuf *pixbuf, GfEventInfo *info) { g_return_if_fail(pixbuf); gf_item_icon_render(item->u.icon, pixbuf, info); gf_item_text_render(item->u.text, pixbuf, info); gf_item_image_render(item->u.image, pixbuf, info); gf_items_swap(GfItem *item1, GfItem *item2) { GList *l = NULL, *l1 = NULL, *l2 = NULL; g_return_if_fail(item1->notification == item2->notification); for(l = gf_notification_get_items(item1->notification); l; l = l->next) {