grim/guifications2
Clone
Summary
Browse
Changes
Graph
Version bump
org.guifications.gf2
2007-05-05, Gary Kramlich
47667729a740
Version bump
/*
* 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
<string.h>
#include
<blist.h>
#include
<debug.h>
#include
<gtkutils.h>
#include
<plugin.h>
#include
<request.h>
#include
<version.h>
#ifdef HAVE_CONFIG_H
#
include
"../gf_config.h"
#endif
#include
"gf_blist.h"
#include
"gf_internal.h"
#include
"gf_notification.h"
#include
"gf_theme.h"
#include
"gf_theme_info.h"
#include
"gf_utils.h"
#define GF_NODE_SETTING "guifications-theme"
/******************************************************************************
* Structs
*****************************************************************************/
typedef
struct
_GfBlistDialog
{
PurpleBlistNode
*
node
;
PurpleRequestField
*
theme_field
;
gpointer
handle
;
}
GfBlistDialog
;
/******************************************************************************
* Enums
*****************************************************************************/
typedef
enum
_GfBlistThemeType
{
GF_BLIST_THEME_UNASSIGNED
=
0
,
GF_BLIST_THEME_RANDOM
,
GF_BLIST_THEME_NONE
,
GF_BLIST_THEME_SPECIFIC
,
GF_BLIST_THEME_TYPES
}
GfBlistThemeType
;
/******************************************************************************
* Globals
*****************************************************************************/
static
GList
*
dialogs
=
NULL
;
/******************************************************************************
* Dialog Callbacks
*****************************************************************************/
static
void
gf_blist_dialog_ok_cb
(
gpointer
data
,
PurpleRequestFields
*
fields
)
{
GfBlistDialog
*
diag
=
(
GfBlistDialog
*
)
data
;
GList
*
l
;
const
gchar
*
name
=
NULL
;
gint
value
=
0
;
value
=
purple_request_field_choice_get_value
(
diag
->
theme_field
);
l
=
purple_request_field_choice_get_labels
(
diag
->
theme_field
);
name
=
g_list_nth_data
(
l
,
value
);
if
(
diag
->
node
)
{
switch
(
value
)
{
case
GF_BLIST_THEME_UNASSIGNED
:
purple_blist_node_remove_setting
(
diag
->
node
,
GF_NODE_SETTING
);
break
;
case
GF_BLIST_THEME_RANDOM
:
purple_blist_node_set_string
(
diag
->
node
,
GF_NODE_SETTING
,
"(RANDOM)"
);
break
;
case
GF_BLIST_THEME_NONE
:
purple_blist_node_set_string
(
diag
->
node
,
GF_NODE_SETTING
,
"(NONE)"
);
break
;
default
:
purple_blist_node_set_string
(
diag
->
node
,
GF_NODE_SETTING
,
name
);
}
}
dialogs
=
g_list_remove
(
dialogs
,
diag
);
g_free
(
diag
);
}
static
void
gf_blist_dialog_cancel_cb
(
gpointer
data
,
PurpleRequestFields
*
fields
)
{
GfBlistDialog
*
diag
=
(
GfBlistDialog
*
)
data
;
dialogs
=
g_list_remove
(
dialogs
,
diag
);
g_free
(
diag
);
}
/******************************************************************************
* Dialog Stuff
*****************************************************************************/
static
void
gf_blist_dialog_new
(
PurpleBlistNode
*
node
)
{
GfBlistDialog
*
dialog
=
NULL
;
PurpleRequestFields
*
fields
;
PurpleRequestFieldGroup
*
group
;
PurpleAccount
*
account
=
NULL
;
GList
*
l
;
gchar
*
info
;
const
gchar
*
name
=
NULL
,
*
format
=
NULL
,
*
current
=
NULL
;
gint
history
=
0
,
i
=
0
;
dialog
=
g_new0
(
GfBlistDialog
,
1
);
if
(
!
dialog
)
return
;
dialog
->
node
=
node
;
/* wow this should really be in blist.[ch] someone remind me to
* write a patch at some point.
*/
if
(
PURPLE_BLIST_NODE_IS_BUDDY
(
node
))
{
PurpleBuddy
*
buddy
=
(
PurpleBuddy
*
)
node
;
if
(
buddy
->
alias
)
name
=
buddy
->
alias
;
else
name
=
buddy
->
name
;
account
=
purple_buddy_get_account
(
buddy
);
format
=
N_
(
"Please select a theme for the buddy %s"
);
}
else
if
(
PURPLE_BLIST_NODE_IS_CONTACT
(
node
))
{
PurpleContact
*
contact
=
(
PurpleContact
*
)
node
;
if
(
contact
->
alias
)
name
=
contact
->
alias
;
else
{
if
(
contact
->
priority
->
alias
)
name
=
contact
->
priority
->
alias
;
else
name
=
contact
->
priority
->
name
;
}
format
=
N_
(
"Please select a theme for the contact %s"
);
}
else
if
(
PURPLE_BLIST_NODE_IS_GROUP
(
node
))
{
PurpleGroup
*
group
=
(
PurpleGroup
*
)
node
;
name
=
group
->
name
;
format
=
N_
(
"Please select a theme for the group %s"
);
}
current
=
purple_blist_node_get_string
(
node
,
GF_NODE_SETTING
);
fields
=
purple_request_fields_new
();
group
=
purple_request_field_group_new
(
NULL
);
purple_request_fields_add_group
(
fields
,
group
);
dialog
->
theme_field
=
purple_request_field_choice_new
(
"theme"
,
_
(
"_Theme"
),
1
);
purple_request_field_group_add_field
(
group
,
dialog
->
theme_field
);
purple_request_field_choice_add
(
dialog
->
theme_field
,
_
(
"Clear setting"
));
purple_request_field_choice_add
(
dialog
->
theme_field
,
_
(
"Random"
));
if
(
!
gf_utils_strcmp
(
"(RANDOM)"
,
current
))
history
=
GF_BLIST_THEME_RANDOM
;
purple_request_field_choice_add
(
dialog
->
theme_field
,
_
(
"None"
));
if
(
!
gf_utils_strcmp
(
"(NONE)"
,
current
))
history
=
GF_BLIST_THEME_NONE
;
for
(
l
=
gf_themes_get_loaded
();
l
;
l
=
l
->
next
)
{
GfTheme
*
theme
=
GF_THEME
(
l
->
data
);
GfThemeInfo
*
info
=
gf_theme_get_theme_info
(
theme
);
const
gchar
*
theme_name
;
theme_name
=
gf_theme_info_get_name
(
info
);
purple_request_field_choice_add
(
dialog
->
theme_field
,
theme_name
);
if
(
!
gf_utils_strcmp
(
theme_name
,
current
))
history
=
i
+
GF_BLIST_THEME_SPECIFIC
;
i
++
;
}
purple_request_field_choice_set_default_value
(
dialog
->
theme_field
,
history
);
purple_request_field_choice_set_value
(
dialog
->
theme_field
,
history
);
info
=
g_strdup_printf
(
_
(
format
),
name
);
dialog
->
handle
=
purple_request_fields
(
NULL
,
_
(
"Select Guifications theme"
),
NULL
,
info
,
fields
,
_
(
"OK"
),
G_CALLBACK
(
gf_blist_dialog_ok_cb
),
_
(
"Cancel"
),
G_CALLBACK
(
gf_blist_dialog_cancel_cb
),
account
,
NULL
,
NULL
,
dialog
);
g_free
(
info
);
dialogs
=
g_list_append
(
dialogs
,
dialog
);
}
/******************************************************************************
* Menu Callbacks
*****************************************************************************/
static
void
gf_blist_menu_cb
(
PurpleBlistNode
*
node
,
gpointer
data
)
{
/* Fix this up when we actually have a way to know if a request window
* is still visible, ie: remind me to write a patch for that and to
* "show" that window for the next gaim release..
*/
gf_blist_dialog_new
(
node
);
}
static
void
gf_blist_drawing_menu_cb
(
PurpleBlistNode
*
node
,
GList
**
menu
)
{
PurpleMenuAction
*
action
;
/* theres no way to get the name of a chat yet so we don't support
* them yet.
*/
if
(
PURPLE_BLIST_NODE_IS_CHAT
(
node
))
return
;
/* add a separator */
(
*
menu
)
=
g_list_append
(
*
menu
,
NULL
);
/* add our menu item */
action
=
purple_menu_action_new
(
_
(
"Guifications Theme"
),
PURPLE_CALLBACK
(
gf_blist_menu_cb
),
NULL
,
NULL
);
(
*
menu
)
=
g_list_append
(
*
menu
,
action
);
}
/******************************************************************************
* Subsystem
*****************************************************************************/
void
gf_blist_init
(
PurplePlugin
*
plugin
)
{
purple_signal_connect
(
purple_blist_get_handle
(),
"blist-node-extended-menu"
,
plugin
,
PURPLE_CALLBACK
(
gf_blist_drawing_menu_cb
),
NULL
);
}
void
gf_blist_uninit
()
{
GfBlistDialog
*
diag
;
GList
*
l
,
*
ll
;
for
(
l
=
dialogs
;
l
;
l
=
ll
)
{
ll
=
l
->
next
;
diag
=
(
GfBlistDialog
*
)
l
->
data
;
purple_request_close
(
PURPLE_REQUEST_FIELDS
,
diag
->
handle
);
dialogs
=
g_list_remove
(
dialogs
,
diag
);
g_free
(
diag
);
}
dialogs
=
NULL
;
}
/* The pointer to a GfTheme is only used if gf_blist_get_theme_type returns
* GF_BLIST_THEME_SPECIFIC. If it returns random we handle that in the
* calling function.
*/
static
GfBlistThemeType
gf_blist_get_theme_type
(
PurpleBlistNode
*
node
,
GfTheme
**
theme
)
{
const
gchar
*
node_theme
=
NULL
;
g_return_val_if_fail
(
node
,
GF_BLIST_THEME_NONE
);
g_return_val_if_fail
(
theme
,
GF_BLIST_THEME_NONE
);
node_theme
=
purple_blist_node_get_string
(
node
,
GF_NODE_SETTING
);
if
(
!
node_theme
)
return
GF_BLIST_THEME_UNASSIGNED
;
if
(
!
gf_utils_strcmp
(
node_theme
,
"(RANDOM)"
))
{
return
GF_BLIST_THEME_RANDOM
;
}
else
if
(
!
gf_utils_strcmp
(
node_theme
,
"(NONE)"
))
{
return
GF_BLIST_THEME_NONE
;
}
else
{
*
theme
=
gf_theme_find_theme_by_name
(
node_theme
);
/* if the specific theme is not loaded we fallback to a random theme
* and do not touch the setting in the event that the user reloads
* said specific theme. In our words, lets not muck everything up if
* the user unloads a theme they don't mean to :)
*/
if
(
!*
theme
)
return
GF_BLIST_THEME_RANDOM
;
return
GF_BLIST_THEME_SPECIFIC
;
}
}
GfNotification
*
gf_blist_get_notification_for_buddy
(
PurpleBuddy
*
buddy
,
const
gchar
*
n_type
)
{
PurpleBlistNode
*
node
=
NULL
;
g_return_val_if_fail
(
buddy
,
NULL
);
g_return_val_if_fail
(
n_type
,
NULL
);
node
=
(
PurpleBlistNode
*
)
buddy
;
g_return_val_if_fail
(
node
,
NULL
);
/* i don't really like the way this is setup.. but I also don't liek the
* idea of typing this out three times...
*/
while
(
node
)
{
GfBlistThemeType
theme_type
;
GfTheme
*
theme
=
NULL
;
/* grab the theme type right away */
theme_type
=
gf_blist_get_theme_type
(
node
,
&
theme
);
/* then update the parent so we avoid excessive checking */
node
=
node
->
parent
;
/* no theme set, check the parent */
if
(
theme_type
==
GF_BLIST_THEME_UNASSIGNED
)
continue
;
if
(
theme_type
==
GF_BLIST_THEME_RANDOM
)
return
gf_notification_find_for_event
(
n_type
);
if
(
theme_type
==
GF_BLIST_THEME_NONE
)
return
NULL
;
if
(
theme_type
==
GF_BLIST_THEME_SPECIFIC
)
return
gf_notification_find_for_theme
(
theme
,
n_type
);
}
return
gf_notification_find_for_event
(
n_type
);
}