grim/guifications2
Clone
Summary
Browse
Changes
Graph
as my comment says, there's no point offering to save a theme for a node
org.guifications.gf2
2007-06-14, Stu Tomlinson
f6740c94c079
as my comment says, there's no point offering to save a theme for a node
that won't be saved
/*
* 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
<glib.h>
#include
<gtk/gtk.h>
#include
<gdk/gdk.h>
#include
<account.h>
#include
<buddyicon.h>
#include
<debug.h>
#include
<xmlnode.h>
#include
<gtkblist.h>
#include
<gtkutils.h>
#ifdef HAVE_CONFIG_H
#
include
"../gf_config.h"
#endif
#include
"gf_gtk_utils.h"
#include
"gf_internal.h"
#include
"gf_item.h"
#include
"gf_item_icon.h"
struct
_GfItemIcon
{
GfItem
*
item
;
GfItemIconType
type
;
GfItemIconSize
size
;
};
static
GfItemIconType
item_icon_type_from_string
(
const
gchar
*
string
)
{
g_return_val_if_fail
(
string
,
GF_ITEM_ICON_TYPE_UNKNOWN
);
if
(
!
g_ascii_strcasecmp
(
string
,
"protocol"
))
return
GF_ITEM_ICON_TYPE_PROTOCOL
;
else
if
(
!
g_ascii_strcasecmp
(
string
,
"buddy"
))
return
GF_ITEM_ICON_TYPE_BUDDY
;
else
if
(
!
g_ascii_strcasecmp
(
string
,
"status"
))
return
GF_ITEM_ICON_TYPE_STATUS
;
else
return
GF_ITEM_ICON_TYPE_UNKNOWN
;
}
static
const
gchar
*
item_icon_type_to_string
(
GfItemIconType
type
)
{
g_return_val_if_fail
(
type
!=
GF_ITEM_ICON_TYPE_UNKNOWN
,
NULL
);
switch
(
type
)
{
case
GF_ITEM_ICON_TYPE_BUDDY
:
return
"buddy"
;
break
;
case
GF_ITEM_ICON_TYPE_PROTOCOL
:
return
"protocol"
;
break
;
case
GF_ITEM_ICON_TYPE_STATUS
:
return
"status"
;
break
;
case
GF_ITEM_ICON_TYPE_UNKNOWN
:
default
:
return
NULL
;
break
;
}
}
static
GfItemIconSize
item_icon_size_from_string
(
const
gchar
*
string
)
{
g_return_val_if_fail
(
string
,
GF_ITEM_ICON_SIZE_UNKNOWN
);
if
(
!
g_ascii_strcasecmp
(
string
,
"tiny"
))
return
GF_ITEM_ICON_SIZE_TINY
;
else
if
(
!
g_ascii_strcasecmp
(
string
,
"small"
))
return
GF_ITEM_ICON_SIZE_SMALL
;
else
if
(
!
g_ascii_strcasecmp
(
string
,
"little"
))
return
GF_ITEM_ICON_SIZE_LITTLE
;
else
if
(
!
g_ascii_strcasecmp
(
string
,
"normal"
))
return
GF_ITEM_ICON_SIZE_NORMAL
;
else
if
(
!
g_ascii_strcasecmp
(
string
,
"big"
))
return
GF_ITEM_ICON_SIZE_BIG
;
else
if
(
!
g_ascii_strcasecmp
(
string
,
"large"
))
return
GF_ITEM_ICON_SIZE_LARGE
;
else
if
(
!
g_ascii_strcasecmp
(
string
,
"huge"
))
return
GF_ITEM_ICON_SIZE_HUGE
;
else
return
GF_ITEM_ICON_SIZE_UNKNOWN
;
}
static
const
gchar
*
item_icon_size_to_string
(
GfItemIconSize
size
)
{
g_return_val_if_fail
(
size
!=
GF_ITEM_ICON_SIZE_UNKNOWN
,
NULL
);
switch
(
size
)
{
case
GF_ITEM_ICON_SIZE_HUGE
:
return
"huge"
;
break
;
case
GF_ITEM_ICON_SIZE_LARGE
:
return
"large"
;
break
;
case
GF_ITEM_ICON_SIZE_BIG
:
return
"big"
;
break
;
case
GF_ITEM_ICON_SIZE_NORMAL
:
return
"normal"
;
break
;
case
GF_ITEM_ICON_SIZE_LITTLE
:
return
"little"
;
break
;
case
GF_ITEM_ICON_SIZE_SMALL
:
return
"small"
;
break
;
case
GF_ITEM_ICON_SIZE_TINY
:
return
"tiny"
;
break
;
case
GF_ITEM_ICON_SIZE_UNKNOWN
:
default
:
return
NULL
;
break
;
}
}
void
gf_item_icon_destroy
(
GfItemIcon
*
item_icon
)
{
g_return_if_fail
(
item_icon
);
item_icon
->
item
=
NULL
;
item_icon
->
type
=
GF_ITEM_ICON_TYPE_UNKNOWN
;
item_icon
->
size
=
GF_ITEM_ICON_SIZE_UNKNOWN
;
g_free
(
item_icon
);
item_icon
=
NULL
;
}
GfItemIcon
*
gf_item_icon_new
(
GfItem
*
item
)
{
GfItemIcon
*
item_icon
;
g_return_val_if_fail
(
item
,
NULL
);
item_icon
=
g_new0
(
GfItemIcon
,
1
);
item_icon
->
item
=
item
;
return
item_icon
;
}
GfItemIcon
*
gf_item_icon_new_from_xmlnode
(
GfItem
*
item
,
xmlnode
*
node
)
{
GfItemIcon
*
item_icon
;
g_return_val_if_fail
(
item
,
NULL
);
g_return_val_if_fail
(
node
,
NULL
);
item_icon
=
gf_item_icon_new
(
item
);
item_icon
->
type
=
item_icon_type_from_string
(
xmlnode_get_attrib
(
node
,
"type"
));
if
(
item_icon
->
type
==
GF_ITEM_ICON_TYPE_UNKNOWN
)
{
purple_debug_info
(
"Guifications"
,
"** Error loading icon item: 'Unknown icon type'
\n
"
);
gf_item_icon_destroy
(
item_icon
);
return
NULL
;
}
item_icon
->
size
=
item_icon_size_from_string
(
xmlnode_get_attrib
(
node
,
"size"
));
if
(
item_icon
->
size
==
GF_ITEM_ICON_SIZE_UNKNOWN
)
{
purple_debug_info
(
"Guifications"
,
"** Error loading icon item: 'Unknown icon size'
\n
"
);
gf_item_icon_destroy
(
item_icon
);
return
NULL
;
}
return
item_icon
;
}
GfItemIcon
*
gf_item_icon_copy
(
GfItemIcon
*
icon
)
{
GfItemIcon
*
new_icon
;
g_return_val_if_fail
(
icon
,
NULL
);
new_icon
=
gf_item_icon_new
(
icon
->
item
);
new_icon
->
type
=
icon
->
type
;
new_icon
->
size
=
icon
->
size
;
return
new_icon
;
}
xmlnode
*
gf_item_icon_to_xmlnode
(
GfItemIcon
*
icon
)
{
xmlnode
*
parent
;
parent
=
xmlnode_new
(
"icon"
);
xmlnode_set_attrib
(
parent
,
"type"
,
item_icon_type_to_string
(
icon
->
type
));
xmlnode_set_attrib
(
parent
,
"size"
,
item_icon_size_to_string
(
icon
->
size
));
return
parent
;
}
void
gf_item_icon_set_type
(
GfItemIcon
*
icon
,
GfItemIconType
type
)
{
g_return_if_fail
(
icon
);
g_return_if_fail
(
type
!=
GF_ITEM_ICON_TYPE_UNKNOWN
);
icon
->
type
=
type
;
}
GfItemIconType
gf_item_icon_get_type
(
GfItemIcon
*
icon
)
{
g_return_val_if_fail
(
icon
,
GF_ITEM_ICON_TYPE_UNKNOWN
);
return
icon
->
type
;
}
void
gf_item_icon_set_size
(
GfItemIcon
*
icon
,
GfItemIconSize
size
)
{
g_return_if_fail
(
icon
);
g_return_if_fail
(
size
!=
GF_ITEM_ICON_SIZE_UNKNOWN
);
icon
->
size
=
size
;
}
GfItemIconSize
gf_item_icon_get_size
(
GfItemIcon
*
icon
)
{
g_return_val_if_fail
(
icon
,
GF_ITEM_ICON_SIZE_UNKNOWN
);
return
icon
->
size
;
}
void
gf_item_icon_set_item
(
GfItemIcon
*
icon
,
GfItem
*
item
)
{
g_return_if_fail
(
icon
);
g_return_if_fail
(
item
);
icon
->
item
=
item
;
}
GfItem
*
gf_item_icon_get_item
(
GfItemIcon
*
icon
)
{
g_return_val_if_fail
(
icon
,
NULL
);
return
icon
->
item
;
}
static
void
get_icon_dimensions
(
gint
*
width
,
gint
*
height
,
GfItemIconSize
size
)
{
switch
(
size
)
{
case
GF_ITEM_ICON_SIZE_TINY
:
*
width
=
*
height
=
16
;
break
;
case
GF_ITEM_ICON_SIZE_SMALL
:
*
width
=
*
height
=
24
;
break
;
case
GF_ITEM_ICON_SIZE_LITTLE
:
*
width
=
*
height
=
32
;
break
;
case
GF_ITEM_ICON_SIZE_BIG
:
*
width
=
*
height
=
64
;
break
;
case
GF_ITEM_ICON_SIZE_LARGE
:
*
width
=
*
height
=
96
;
break
;
case
GF_ITEM_ICON_SIZE_HUGE
:
*
width
=
*
height
=
144
;
break
;
case
GF_ITEM_ICON_SIZE_NORMAL
:
default
:
*
width
=
*
height
=
48
;
break
;
}
}
static
void
get_icon_position
(
gint
*
x
,
gint
*
y
,
gint
img_width
,
gint
img_height
,
GfItemIcon
*
item_icon
)
{
gint
width
=
0
,
height
=
0
;
g_return_if_fail
(
item_icon
);
get_icon_dimensions
(
&
width
,
&
height
,
item_icon
->
size
);
gf_item_get_render_position
(
x
,
y
,
width
,
height
,
img_width
,
img_height
,
item_icon
->
item
);
}
void
gf_item_icon_render
(
GfItemIcon
*
item_icon
,
GdkPixbuf
*
pixbuf
,
GfEventInfo
*
info
)
{
GfEvent
*
event
;
GdkPixbuf
*
original
=
NULL
,
*
scaled
=
NULL
;
gint
x
,
y
;
gint
width
,
height
;
gboolean
is_contact
;
g_return_if_fail
(
item_icon
);
g_return_if_fail
(
pixbuf
);
g_return_if_fail
(
info
);
event
=
gf_event_info_get_event
(
info
);
is_contact
=
gf_event_info_get_is_contact
(
info
);
if
(
item_icon
->
type
==
GF_ITEM_ICON_TYPE_PROTOCOL
)
{
if
(
is_contact
)
{
gchar
*
filename
;
filename
=
g_build_filename
(
DATADIR
,
"pixmaps"
,
"pidgin.png"
,
NULL
);
original
=
gdk_pixbuf_new_from_file
(
filename
,
NULL
);
g_free
(
filename
);
}
else
{
PurpleAccount
*
account
=
gf_event_info_get_account
(
info
);
original
=
pidgin_create_prpl_icon
(
account
,
1.0
);
}
}
else
if
(
item_icon
->
type
==
GF_ITEM_ICON_TYPE_BUDDY
)
{
PurpleBuddyIcon
*
icon
=
NULL
;
GdkPixbufLoader
*
loader
;
const
guchar
*
data
;
size_t
len
;
icon
=
purple_buddy_icons_find
(
gf_event_info_get_account
(
info
),
gf_event_info_get_target
(
info
));
if
(
icon
)
{
loader
=
gdk_pixbuf_loader_new
();
data
=
purple_buddy_icon_get_data
(
icon
,
&
len
);
gdk_pixbuf_loader_write
(
loader
,
data
,
len
,
NULL
);
if
((
original
=
gdk_pixbuf_loader_get_pixbuf
(
loader
)))
g_object_ref
(
G_OBJECT
(
original
));
gdk_pixbuf_loader_close
(
loader
,
NULL
);
g_object_unref
(
G_OBJECT
(
loader
));
}
}
else
if
(
item_icon
->
type
==
GF_ITEM_ICON_TYPE_STATUS
)
{
PurpleBuddy
*
buddy
=
NULL
;
if
((
buddy
=
gf_event_info_get_buddy
(
info
)))
{
original
=
pidgin_blist_get_status_icon
((
PurpleBlistNode
*
)
buddy
,
PIDGIN_STATUS_ICON_LARGE
);
}
}
/* if the original doesn't work for whatever reason we fallback to the
* protocol or the Pidgin guy(?) if it is a contact notification, this will
* be optional when we "enhance" the theme format. If it fails we return
* like we used to.
*/
if
(
!
original
)
{
PurpleAccount
*
account
=
gf_event_info_get_account
(
info
);
original
=
pidgin_create_prpl_icon
(
account
,
1.0
);
if
(
!
original
)
return
;
}
get_icon_position
(
&
x
,
&
y
,
gdk_pixbuf_get_width
(
pixbuf
),
gdk_pixbuf_get_height
(
pixbuf
),
item_icon
);
get_icon_dimensions
(
&
width
,
&
height
,
item_icon
->
size
);
scaled
=
gdk_pixbuf_scale_simple
(
original
,
width
,
height
,
GDK_INTERP_BILINEAR
);
g_object_unref
(
G_OBJECT
(
original
));
gf_gtk_pixbuf_clip_composite
(
scaled
,
x
,
y
,
pixbuf
);
g_object_unref
(
G_OBJECT
(
scaled
));
}