pidgin/purple-plugin-pack
Clone
Summary
Browse
Changes
Graph
Tweak plugins.cfg for switchspell to note the change in enchant support
org.guifications.plugins
2008-07-22, rekkanoryo
6bf9c444fc79
Tweak plugins.cfg for switchspell to note the change in enchant support
status, which is unfortunately somewhat buggy. I'll trust the distro
packagers to handle this correctly for their individual distros.
/*************************************************************************
* Buddy Edit Module
*
* A Gaim plugin that adds an edit to to buddies allowing you to change
* various details you can't normally change. It also provides a mechanism
* for subsequent plugins to add themselves to that dialog.
*
* by Martijn van Oosterhout <kleptog@svana.org> (C) April 2006
* Some code copyright (C) 2006, Richard Laager <rlaager@users.sf.net>
*
* 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.
*************************************************************************/
#define GAIM_PLUGINS
#define PLUGIN "core-kleptog-buddyedit"
#include
<glib.h>
#include
<string.h>
#include
"gaim-compat.h"
#include
"notify.h"
#include
"plugin.h"
#include
"util.h"
#include
"version.h"
#include
"debug.h"
/* Debug output functions */
#include
"request.h"
/* Requests stuff */
static
GaimPlugin
*
plugin_self
;
static
void
buddyedit_editcomplete_cb
(
GaimBlistNode
*
data
,
GaimRequestFields
*
fields
)
{
gboolean
blist_destroy
=
FALSE
;
GaimBlistNode
*
olddata
=
data
;
/* Keep pointer in case we need to destroy it */
/* Account detail stuff */
switch
(
data
->
type
)
{
case
GAIM_BLIST_BUDDY_NODE
:
{
GaimBuddy
*
buddy
=
(
GaimBuddy
*
)
data
;
GaimAccount
*
account
=
gaim_request_fields_get_account
(
fields
,
"account"
);
const
char
*
name
=
gaim_request_fields_get_string
(
fields
,
"name"
);
const
char
*
alias
=
gaim_request_fields_get_string
(
fields
,
"alias"
);
/* If any details changes, create the buddy */
if
((
account
!=
buddy
->
account
)
||
strcmp
(
name
,
buddy
->
name
))
{
GHashTable
*
tmp
;
GaimBuddy
*
newbuddy
=
gaim_buddy_new
(
account
,
name
,
alias
);
gaim_blist_add_buddy
(
newbuddy
,
NULL
,
NULL
,
data
);
/* Copy it to correct location */
/* Now this is ugly, but we want to copy the settings and avoid issues with memory management */
tmp
=
((
GaimBlistNode
*
)
buddy
)
->
settings
;
((
GaimBlistNode
*
)
buddy
)
->
settings
=
((
GaimBlistNode
*
)
newbuddy
)
->
settings
;
((
GaimBlistNode
*
)
newbuddy
)
->
settings
=
tmp
;
blist_destroy
=
TRUE
;
data
=
(
GaimBlistNode
*
)
newbuddy
;
}
else
gaim_blist_alias_buddy
(
buddy
,
alias
);
break
;
}
case
GAIM_BLIST_CONTACT_NODE
:
{
GaimContact
*
contact
=
(
GaimContact
*
)
data
;
const
char
*
alias
=
gaim_request_fields_get_string
(
fields
,
"alias"
);
gaim_contact_set_alias
(
contact
,
alias
);
break
;
}
case
GAIM_BLIST_GROUP_NODE
:
{
GaimGroup
*
group
=
(
GaimGroup
*
)
data
;
const
char
*
alias
=
gaim_request_fields_get_string
(
fields
,
"alias"
);
gaim_blist_rename_group
(
group
,
alias
);
break
;
}
case
GAIM_BLIST_CHAT_NODE
:
{
GaimChat
*
chat
=
(
GaimChat
*
)
data
;
gboolean
new_chat
=
FALSE
;
GaimConnection
*
gc
;
GList
*
list
=
NULL
,
*
tmp
;
gc
=
gaim_account_get_connection
(
chat
->
account
);
if
(
GAIM_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
)
->
chat_info
!=
NULL
)
list
=
GAIM_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
)
->
chat_info
(
gc
);
GaimAccount
*
newaccount
=
gaim_request_fields_get_account
(
fields
,
"account"
);
/* In Gaim2 each prot_chat_entry has a field "required". We use
* this to determine if a field is important enough to recreate
* the chat if it changes. Non-required fields we jsut change
* in-situ. In Gaim1.5 this field doesn't exist so we always
* recreate */
#if GAIM_MAJOR_VERSION >= 2
if
(
newaccount
!=
chat
->
account
)
new_chat
=
TRUE
;
else
{
const
char
*
oldvalue
,
*
newvalue
;
for
(
tmp
=
g_list_first
(
list
);
tmp
&&
!
new_chat
;
tmp
=
g_list_next
(
tmp
))
{
struct
proto_chat_entry
*
pce
=
tmp
->
data
;
if
(
!
pce
->
required
)
/* Only checking required fields at this point */
continue
;
if
(
pce
->
is_int
)
continue
;
/* Not yet */
oldvalue
=
g_hash_table_lookup
(
chat
->
components
,
pce
->
identifier
);
newvalue
=
gaim_request_fields_get_string
(
fields
,
pce
->
identifier
);
if
(
oldvalue
==
NULL
)
oldvalue
=
""
;
if
(
newvalue
==
NULL
)
newvalue
=
""
;
if
(
strcmp
(
oldvalue
,
newvalue
)
!=
0
)
new_chat
=
TRUE
;
}
}
#else
new_chat
=
TRUE
;
#endif
if
(
new_chat
)
{
const
char
*
oldvalue
,
*
newvalue
;
GHashTable
*
components
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
g_free
);
for
(
tmp
=
g_list_first
(
list
);
tmp
;
tmp
=
g_list_next
(
tmp
))
{
struct
proto_chat_entry
*
pce
=
tmp
->
data
;
if
(
pce
->
is_int
)
{
oldvalue
=
g_hash_table_lookup
(
chat
->
components
,
pce
->
identifier
);
g_hash_table_replace
(
components
,
g_strdup
(
pce
->
identifier
),
g_strdup
(
oldvalue
));
}
else
{
newvalue
=
gaim_request_fields_get_string
(
fields
,
pce
->
identifier
);
g_hash_table_replace
(
components
,
g_strdup
(
pce
->
identifier
),
g_strdup
(
newvalue
));
}
}
GaimChat
*
newchat
=
gaim_chat_new
(
newaccount
,
NULL
,
components
);
gaim_blist_add_chat
(
newchat
,
NULL
,
data
);
/* Copy it to correct location */
data
=
(
GaimBlistNode
*
)
newchat
;
blist_destroy
=
TRUE
;
}
else
/* Just updating values in old chat */
{
const
char
*
newvalue
;
for
(
tmp
=
g_list_first
(
list
);
tmp
;
tmp
=
g_list_next
(
tmp
))
{
struct
proto_chat_entry
*
pce
=
tmp
->
data
;
#if GAIM_MAJOR_VERSION >= 2
if
(
pce
->
required
)
continue
;
#endif
if
(
pce
->
is_int
)
{
/* Do nothing, yet */
}
else
{
newvalue
=
gaim_request_fields_get_string
(
fields
,
pce
->
identifier
);
g_hash_table_replace
(
chat
->
components
,
g_strdup
(
pce
->
identifier
),
g_strdup
(
newvalue
));
}
}
}
const
char
*
alias
=
gaim_request_fields_get_string
(
fields
,
"alias"
);
gaim_blist_alias_chat
(
chat
,
alias
);
break
;
}
case
GAIM_BLIST_OTHER_NODE
:
break
;
}
gaim_signal_emit
(
gaim_blist_get_handle
(),
PLUGIN
"-submit-fields"
,
fields
,
data
);
if
(
blist_destroy
)
{
if
(
olddata
->
type
==
GAIM_BLIST_BUDDY_NODE
)
gaim_blist_remove_buddy
((
GaimBuddy
*
)
olddata
);
else
if
(
olddata
->
type
==
GAIM_BLIST_CHAT_NODE
)
gaim_blist_remove_chat
((
GaimChat
*
)
olddata
);
}
/* Save any changes */
gaim_blist_schedule_save
();
}
static
GaimAccount
*
buddyedit_account_filter_func_data
;
static
gboolean
buddyedit_account_filter_func
(
GaimAccount
*
account
)
{
GaimPluginProtocolInfo
*
gppi1
=
GAIM_PLUGIN_PROTOCOL_INFO
(
gaim_account_get_connection
(
account
)
->
prpl
);
GaimPluginProtocolInfo
*
gppi2
=
GAIM_PLUGIN_PROTOCOL_INFO
(
gaim_account_get_connection
(
buddyedit_account_filter_func_data
)
->
prpl
);
return
gppi1
==
gppi2
;
}
/* Node is either a contact or a buddy */
static
void
buddy_edit_cb
(
GaimBlistNode
*
node
,
gpointer
data
)
{
gaim_debug
(
GAIM_DEBUG_INFO
,
PLUGIN
,
"buddy_edit_cb(%p)
\n
"
,
node
);
GaimRequestFields
*
fields
;
GaimRequestField
*
field
;
GaimRequestFieldGroup
*
group
;
char
*
request_title
=
NULL
;
fields
=
gaim_request_fields_new
();
switch
(
node
->
type
)
{
case
GAIM_BLIST_BUDDY_NODE
:
{
GaimBuddy
*
buddy
=
(
GaimBuddy
*
)
node
;
group
=
gaim_request_field_group_new
(
"Buddy Details"
);
gaim_request_fields_add_group
(
fields
,
group
);
field
=
gaim_request_field_account_new
(
"account"
,
"Account"
,
buddy
->
account
);
gaim_request_field_account_set_show_all
(
field
,
TRUE
);
gaim_request_field_group_add_field
(
group
,
field
);
field
=
gaim_request_field_string_new
(
"name"
,
"Name"
,
buddy
->
name
,
FALSE
);
gaim_request_field_group_add_field
(
group
,
field
);
field
=
gaim_request_field_string_new
(
"alias"
,
"Alias"
,
buddy
->
alias
,
FALSE
);
gaim_request_field_group_add_field
(
group
,
field
);
request_title
=
"Edit Buddy"
;
break
;
}
case
GAIM_BLIST_CONTACT_NODE
:
{
GaimContact
*
contact
=
(
GaimContact
*
)
node
;
group
=
gaim_request_field_group_new
(
"Contact Details"
);
gaim_request_fields_add_group
(
fields
,
group
);
field
=
gaim_request_field_string_new
(
"alias"
,
"Alias"
,
contact
->
alias
,
FALSE
);
gaim_request_field_group_add_field
(
group
,
field
);
request_title
=
"Edit Contact"
;
break
;
}
case
GAIM_BLIST_GROUP_NODE
:
{
GaimGroup
*
grp
=
(
GaimGroup
*
)
node
;
group
=
gaim_request_field_group_new
(
"Group Details"
);
gaim_request_fields_add_group
(
fields
,
group
);
field
=
gaim_request_field_string_new
(
"alias"
,
"Name"
,
grp
->
name
,
FALSE
);
gaim_request_field_group_add_field
(
group
,
field
);
request_title
=
"Edit Group"
;
break
;
}
case
GAIM_BLIST_CHAT_NODE
:
{
GaimChat
*
chat
=
(
GaimChat
*
)
node
;
group
=
gaim_request_field_group_new
(
"Chat Details"
);
gaim_request_fields_add_group
(
fields
,
group
);
field
=
gaim_request_field_account_new
(
"account"
,
"Account"
,
chat
->
account
);
gaim_request_field_account_set_filter
(
field
,
buddyedit_account_filter_func
);
buddyedit_account_filter_func_data
=
chat
->
account
;
gaim_request_field_group_add_field
(
group
,
field
);
GaimConnection
*
gc
;
GList
*
list
=
NULL
,
*
tmp
;
gc
=
gaim_account_get_connection
(
chat
->
account
);
if
(
GAIM_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
)
->
chat_info
!=
NULL
)
list
=
GAIM_PLUGIN_PROTOCOL_INFO
(
gc
->
prpl
)
->
chat_info
(
gc
);
for
(
tmp
=
g_list_first
(
list
);
tmp
;
tmp
=
g_list_next
(
tmp
))
{
struct
proto_chat_entry
*
pce
=
tmp
->
data
;
const
char
*
value
;
#if GAIM_MAJOR_VERSION >= 2
gaim_debug
(
GAIM_DEBUG_INFO
,
PLUGIN
,
"identifier=%s, label=%s, is_int=%d, required=%d
\n
"
,
pce
->
identifier
,
pce
->
label
,
pce
->
is_int
,
pce
->
required
);
#endif
if
(
pce
->
is_int
)
continue
;
/* Not yet */
value
=
g_hash_table_lookup
(
chat
->
components
,
pce
->
identifier
);
field
=
gaim_request_field_string_new
(
pce
->
identifier
,
pce
->
label
,
value
,
FALSE
);
#if GAIM_MAJOR_VERSION >= 2
gaim_request_field_set_required
(
field
,
pce
->
required
);
#endif
gaim_request_field_group_add_field
(
group
,
field
);
}
field
=
gaim_request_field_string_new
(
"alias"
,
"Alias"
,
chat
->
alias
,
FALSE
);
gaim_request_field_group_add_field
(
group
,
field
);
request_title
=
"Edit Chat"
;
break
;
}
default
:
request_title
=
"Edit"
;
break
;
}
gaim_signal_emit
(
gaim_blist_get_handle
(),
PLUGIN
"-create-fields"
,
fields
,
node
);
gaim_request_fields
(
plugin_self
,
request_title
,
NULL
,
NULL
,
fields
,
"OK"
,
G_CALLBACK
(
buddyedit_editcomplete_cb
),
"Cancel"
,
NULL
,
node
);
}
static
void
buddy_menu_cb
(
GaimBlistNode
*
node
,
GList
**
menu
,
void
*
data
)
{
#if GAIM_MAJOR_VERSION < 2
GaimBlistNodeAction
*
action
;
#else
GaimMenuAction
*
action
;
#endif
switch
(
node
->
type
)
{
/* These are the types we handle */
case
GAIM_BLIST_BUDDY_NODE
:
case
GAIM_BLIST_CONTACT_NODE
:
case
GAIM_BLIST_GROUP_NODE
:
case
GAIM_BLIST_CHAT_NODE
:
break
;
case
GAIM_BLIST_OTHER_NODE
:
default
:
return
;
}
#if GAIM_MAJOR_VERSION < 2
action
=
gaim_blist_node_action_new
(
"Edit..."
,
buddy_edit_cb
,
NULL
);
#else
action
=
gaim_menu_action_new
(
"Edit..."
,
GAIM_CALLBACK
(
buddy_edit_cb
),
NULL
,
NULL
);
#endif
*
menu
=
g_list_append
(
*
menu
,
action
);
}
static
gboolean
plugin_load
(
GaimPlugin
*
plugin
)
{
plugin_self
=
plugin
;
void
*
blist_handle
=
gaim_blist_get_handle
();
gaim_signal_register
(
blist_handle
,
PLUGIN
"-create-fields"
,
/* Called when about to create dialog */
gaim_marshal_VOID__POINTER_POINTER
,
NULL
,
2
,
/* (FieldList*,BlistNode*) */
gaim_value_new
(
GAIM_TYPE_SUBTYPE
,
GAIM_TYPE_POINTER
),
/* FieldList */
gaim_value_new
(
GAIM_TYPE_SUBTYPE
,
GAIM_SUBTYPE_BLIST
));
gaim_signal_register
(
blist_handle
,
PLUGIN
"-submit-fields"
,
/* Called when dialog submitted */
gaim_marshal_VOID__POINTER_POINTER
,
NULL
,
2
,
/* (FieldList*,BlistNode*) */
gaim_value_new
(
GAIM_TYPE_SUBTYPE
,
GAIM_TYPE_POINTER
),
/* FieldList */
gaim_value_new
(
GAIM_TYPE_SUBTYPE
,
GAIM_SUBTYPE_BLIST
));
gaim_signal_connect
(
blist_handle
,
"blist-node-extended-menu"
,
plugin
,
GAIM_CALLBACK
(
buddy_menu_cb
),
NULL
);
return
TRUE
;
}
static
GaimPluginInfo
info
=
{
GAIM_PLUGIN_MAGIC
,
GAIM_MAJOR_VERSION
,
GAIM_MINOR_VERSION
,
GAIM_PLUGIN_STANDARD
,
NULL
,
0
,
NULL
,
GAIM_PRIORITY_DEFAULT
,
PLUGIN
,
"Buddy Edit Module"
,
G_STRINGIFY
(
PLUGIN_VERSION
),
"Enable editing of buddy properties"
,
"A plugin that adds an edit to to buddies allowing you to change various details you can't normally change. "
"It also provides a mechanism for subsequent plugins to add themselves to that dialog. "
,
"Martijn van Oosterhout <kleptog@svana.org>"
,
"http://svana.org/kleptog/gaim/"
,
plugin_load
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
};
static
void
init_plugin
(
GaimPlugin
*
plugin
)
{
}
PURPLE_INIT_PLUGIN
(
buddyedit
,
init_plugin
,
info
);