qulogic/pidgin
Clone
Summary
Browse
Changes
Graph
Mark the Jabber/XMPP protocol plugin as deprecated
6 months ago, Gary Kramlich
6aaf9a66f9d9
Mark the Jabber/XMPP protocol plugin as deprecated
This is to allow us to distinguish the new XMPP protocol plugin that we will be
starting shortly.
Testing Done:
Compiled and verified the ui looked alright with the change.
Reviewed at https://reviews.imfreedom.org/r/2855/
/*
* finch
*
* Finch is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
* source distribution.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include
<glib/gi18n-lib.h>
#include
<purple.h>
#include
<gnt.h>
#include
"gntrequest.h"
typedef
struct
{
void
*
user_data
;
GntWidget
*
dialog
;
GCallback
*
cbs
;
gboolean
save
;
}
FinchFileRequest
;
static
GntWidget
*
setup_request_window
(
const
char
*
title
,
const
char
*
primary
,
const
char
*
secondary
,
PurpleRequestType
type
)
{
GntWidget
*
window
;
window
=
gnt_vbox_new
(
FALSE
);
gnt_box_set_toplevel
(
GNT_BOX
(
window
),
TRUE
);
gnt_box_set_title
(
GNT_BOX
(
window
),
title
);
gnt_box_set_alignment
(
GNT_BOX
(
window
),
GNT_ALIGN_MID
);
if
(
primary
)
gnt_box_add_widget
(
GNT_BOX
(
window
),
gnt_label_new_with_format
(
primary
,
GNT_TEXT_FLAG_BOLD
));
if
(
secondary
)
gnt_box_add_widget
(
GNT_BOX
(
window
),
gnt_label_new
(
secondary
));
g_signal_connect_swapped
(
G_OBJECT
(
window
),
"destroy"
,
G_CALLBACK
(
purple_request_close
),
GINT_TO_POINTER
(
type
));
return
window
;
}
/*
* If the window is closed by the wm (ie, without triggering any of
* the buttons, then do some default callback.
*/
static
void
setup_default_callback
(
GntWidget
*
window
,
gpointer
default_cb
,
gpointer
data
)
{
if
(
default_cb
==
NULL
)
return
;
g_object_set_data
(
G_OBJECT
(
window
),
"default-callback"
,
default_cb
);
g_signal_connect_swapped
(
G_OBJECT
(
window
),
"destroy"
,
G_CALLBACK
(
default_cb
),
data
);
}
static
void
action_performed
(
G_GNUC_UNUSED
GntWidget
*
button
,
gpointer
data
)
{
g_signal_handlers_disconnect_matched
(
data
,
G_SIGNAL_MATCH_FUNC
,
0
,
0
,
NULL
,
g_object_get_data
(
data
,
"default-callback"
),
NULL
);
}
/*
* setup_button_box:
* @win: this is the window
* @userdata: the userdata to pass to the primary callbacks
* @cb: the callback
* @data: data for the callback
* @...: (text, primary-callback) pairs, ended by a NULL
*
* The cancellation callback should be the last callback sent.
*/
static
GntWidget
*
setup_button_box
(
GntWidget
*
win
,
gpointer
userdata
,
gpointer
cb
,
gpointer
data
,
...)
{
GntWidget
*
box
;
GntWidget
*
button
=
NULL
;
va_list
list
;
const
char
*
text
;
gpointer
callback
;
box
=
gnt_hbox_new
(
FALSE
);
va_start
(
list
,
data
);
while
((
text
=
va_arg
(
list
,
const
char
*
)))
{
callback
=
va_arg
(
list
,
gpointer
);
button
=
gnt_button_new
(
text
);
gnt_box_add_widget
(
GNT_BOX
(
box
),
button
);
g_object_set_data
(
G_OBJECT
(
button
),
"activate-callback"
,
callback
);
g_object_set_data
(
G_OBJECT
(
button
),
"activate-userdata"
,
userdata
);
g_signal_connect
(
G_OBJECT
(
button
),
"activate"
,
G_CALLBACK
(
action_performed
),
win
);
g_signal_connect
(
G_OBJECT
(
button
),
"activate"
,
G_CALLBACK
(
cb
),
data
);
}
if
(
button
)
g_object_set_data
(
G_OBJECT
(
button
),
"cancellation-function"
,
GINT_TO_POINTER
(
TRUE
));
va_end
(
list
);
return
box
;
}
static
void
notify_input_cb
(
GntWidget
*
button
,
GntWidget
*
entry
)
{
PurpleRequestInputCb
callback
=
g_object_get_data
(
G_OBJECT
(
button
),
"activate-callback"
);
gpointer
data
=
g_object_get_data
(
G_OBJECT
(
button
),
"activate-userdata"
);
const
char
*
text
=
gnt_entry_get_text
(
GNT_ENTRY
(
entry
));
GntWidget
*
window
;
if
(
callback
)
callback
(
data
,
text
);
window
=
gnt_widget_get_toplevel
(
button
);
purple_request_close
(
PURPLE_REQUEST_INPUT
,
window
);
}
static
void
*
finch_request_input
(
const
char
*
title
,
const
char
*
primary
,
const
char
*
secondary
,
const
char
*
default_value
,
G_GNUC_UNUSED
gboolean
multiline
,
gboolean
masked
,
G_GNUC_UNUSED
gchar
*
hint
,
const
char
*
ok_text
,
GCallback
ok_cb
,
const
char
*
cancel_text
,
GCallback
cancel_cb
,
G_GNUC_UNUSED
PurpleRequestCommonParameters
*
cpar
,
void
*
user_data
)
{
GntWidget
*
window
,
*
box
,
*
entry
;
window
=
setup_request_window
(
title
,
primary
,
secondary
,
PURPLE_REQUEST_INPUT
);
entry
=
gnt_entry_new
(
default_value
);
if
(
masked
)
gnt_entry_set_masked
(
GNT_ENTRY
(
entry
),
TRUE
);
gnt_box_add_widget
(
GNT_BOX
(
window
),
entry
);
box
=
setup_button_box
(
window
,
user_data
,
notify_input_cb
,
entry
,
ok_text
,
ok_cb
,
cancel_text
,
cancel_cb
,
NULL
);
gnt_box_add_widget
(
GNT_BOX
(
window
),
box
);
setup_default_callback
(
window
,
cancel_cb
,
user_data
);
gnt_widget_show
(
window
);
return
window
;
}
static
void
finch_close_request
(
G_GNUC_UNUSED
PurpleRequestType
type
,
gpointer
ui_handle
)
{
GntWidget
*
widget
=
GNT_WIDGET
(
ui_handle
);
widget
=
gnt_widget_get_toplevel
(
widget
);
gnt_widget_destroy
(
widget
);
}
static
void
request_choice_cb
(
GntWidget
*
button
,
GntComboBox
*
combo
)
{
PurpleRequestChoiceCb
callback
=
g_object_get_data
(
G_OBJECT
(
button
),
"activate-callback"
);
gpointer
data
=
g_object_get_data
(
G_OBJECT
(
button
),
"activate-userdata"
);
gpointer
choice
=
gnt_combo_box_get_selected_data
(
GNT_COMBO_BOX
(
combo
));
GntWidget
*
window
;
if
(
callback
)
callback
(
data
,
choice
);
window
=
gnt_widget_get_toplevel
(
button
);
purple_request_close
(
PURPLE_REQUEST_INPUT
,
window
);
}
static
void
*
finch_request_choice
(
const
char
*
title
,
const
char
*
primary
,
const
char
*
secondary
,
gpointer
default_value
,
const
char
*
ok_text
,
GCallback
ok_cb
,
const
char
*
cancel_text
,
GCallback
cancel_cb
,
G_GNUC_UNUSED
PurpleRequestCommonParameters
*
cpar
,
void
*
user_data
,
va_list
choices
)
{
GntWidget
*
window
,
*
combo
,
*
box
;
const
char
*
text
;
int
val
;
window
=
setup_request_window
(
title
,
primary
,
secondary
,
PURPLE_REQUEST_CHOICE
);
combo
=
gnt_combo_box_new
();
gnt_box_add_widget
(
GNT_BOX
(
window
),
combo
);
while
((
text
=
va_arg
(
choices
,
const
char
*
)))
{
val
=
va_arg
(
choices
,
int
);
gnt_combo_box_add_data
(
GNT_COMBO_BOX
(
combo
),
GINT_TO_POINTER
(
val
+
1
),
text
);
}
gnt_combo_box_set_selected
(
GNT_COMBO_BOX
(
combo
),
default_value
);
box
=
setup_button_box
(
window
,
user_data
,
request_choice_cb
,
combo
,
ok_text
,
ok_cb
,
cancel_text
,
cancel_cb
,
NULL
);
gnt_box_add_widget
(
GNT_BOX
(
window
),
box
);
setup_default_callback
(
window
,
cancel_cb
,
user_data
);
gnt_widget_show
(
window
);
return
window
;
}
static
void
request_action_cb
(
GntWidget
*
button
,
GntWidget
*
window
)
{
PurpleRequestActionCb
callback
=
g_object_get_data
(
G_OBJECT
(
button
),
"activate-callback"
);
gpointer
data
=
g_object_get_data
(
G_OBJECT
(
button
),
"activate-userdata"
);
int
id
=
GPOINTER_TO_INT
(
g_object_get_data
(
G_OBJECT
(
button
),
"activate-id"
));
if
(
callback
)
callback
(
data
,
id
);
purple_request_close
(
PURPLE_REQUEST_ACTION
,
window
);
}
static
void
*
finch_request_action
(
const
char
*
title
,
const
char
*
primary
,
const
char
*
secondary
,
int
default_value
,
G_GNUC_UNUSED
PurpleRequestCommonParameters
*
cpar
,
void
*
user_data
,
size_t
actioncount
,
va_list
actions
)
{
GntWidget
*
window
,
*
box
,
*
button
,
*
focus
=
NULL
;
gsize
i
;
window
=
setup_request_window
(
title
,
primary
,
secondary
,
PURPLE_REQUEST_ACTION
);
box
=
gnt_hbox_new
(
FALSE
);
gnt_box_add_widget
(
GNT_BOX
(
window
),
box
);
for
(
i
=
0
;
i
<
actioncount
;
i
++
)
{
const
char
*
text
=
va_arg
(
actions
,
const
char
*
);
PurpleRequestActionCb
callback
=
va_arg
(
actions
,
PurpleRequestActionCb
);
button
=
gnt_button_new
(
text
);
gnt_box_add_widget
(
GNT_BOX
(
box
),
button
);
g_object_set_data
(
G_OBJECT
(
button
),
"activate-callback"
,
callback
);
g_object_set_data
(
G_OBJECT
(
button
),
"activate-userdata"
,
user_data
);
g_object_set_data
(
G_OBJECT
(
button
),
"activate-id"
,
GINT_TO_POINTER
(
i
));
g_signal_connect
(
G_OBJECT
(
button
),
"activate"
,
G_CALLBACK
(
request_action_cb
),
window
);
if
(
default_value
>=
0
&&
i
==
(
gsize
)
default_value
)
focus
=
button
;
}
gnt_widget_show
(
window
);
if
(
focus
)
gnt_box_give_focus_to_child
(
GNT_BOX
(
window
),
focus
);
return
window
;
}
static
void
request_fields_cb
(
GntWidget
*
button
,
PurpleRequestPage
*
page
)
{
PurpleRequestFieldsCb
callback
=
g_object_get_data
(
G_OBJECT
(
button
),
"activate-callback"
);
gpointer
data
=
g_object_get_data
(
G_OBJECT
(
button
),
"activate-userdata"
);
GntWidget
*
window
;
guint
n_groups
;
/* Update the data of the fields. Pidgin does this differently. Instead of
* updating the fields at the end like here, it updates the appropriate field
* instantly whenever a change is made. That allows it to make sure the
* 'required' fields are entered before the user can hit OK. It's not the case
* here, although it can be done. */
n_groups
=
g_list_model_get_n_items
(
G_LIST_MODEL
(
page
));
for
(
guint
group_index
=
0
;
group_index
<
n_groups
;
group_index
++
)
{
GListModel
*
group
=
NULL
;
guint
n_fields
;
group
=
g_list_model_get_item
(
G_LIST_MODEL
(
page
),
group_index
);
n_fields
=
g_list_model_get_n_items
(
group
);
for
(
guint
field_index
=
0
;
field_index
<
n_fields
;
field_index
++
)
{
PurpleRequestField
*
field
=
NULL
;
field
=
g_list_model_get_item
(
group
,
field_index
);
if
(
!
purple_request_field_is_visible
(
field
))
{
g_object_unref
(
field
);
continue
;
}
if
(
PURPLE_IS_REQUEST_FIELD_BOOL
(
field
))
{
GntWidget
*
check
=
g_object_get_data
(
G_OBJECT
(
field
),
"finch-ui-data"
);
gboolean
value
=
gnt_check_box_get_checked
(
GNT_CHECK_BOX
(
check
));
purple_request_field_bool_set_value
(
PURPLE_REQUEST_FIELD_BOOL
(
field
),
value
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_STRING
(
field
))
{
GntWidget
*
entry
=
g_object_get_data
(
G_OBJECT
(
field
),
"finch-ui-data"
);
const
char
*
text
=
gnt_entry_get_text
(
GNT_ENTRY
(
entry
));
if
(
purple_strempty
(
text
))
{
text
=
NULL
;
}
purple_request_field_string_set_value
(
PURPLE_REQUEST_FIELD_STRING
(
field
),
text
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_INT
(
field
))
{
GntWidget
*
entry
=
g_object_get_data
(
G_OBJECT
(
field
),
"finch-ui-data"
);
const
char
*
text
=
gnt_entry_get_text
(
GNT_ENTRY
(
entry
));
int
value
=
(
text
&&
*
text
)
?
atoi
(
text
)
:
0
;
purple_request_field_int_set_value
(
PURPLE_REQUEST_FIELD_INT
(
field
),
value
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_CHOICE
(
field
))
{
GntWidget
*
combo
=
g_object_get_data
(
G_OBJECT
(
field
),
"finch-ui-data"
);
gpointer
value
=
gnt_combo_box_get_selected_data
(
GNT_COMBO_BOX
(
combo
));
purple_request_field_choice_set_value
(
PURPLE_REQUEST_FIELD_CHOICE
(
field
),
value
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_LIST
(
field
))
{
PurpleRequestFieldList
*
lfield
=
PURPLE_REQUEST_FIELD_LIST
(
field
);
GList
*
selected
=
NULL
;
GList
*
list
=
purple_request_field_list_get_items
(
lfield
);
if
(
purple_request_field_list_get_multi_select
(
lfield
))
{
GntWidget
*
tree
=
g_object_get_data
(
G_OBJECT
(
field
),
"finch-ui-data"
);
for
(;
list
;
list
=
list
->
next
)
{
PurpleKeyValuePair
*
item
=
list
->
data
;
const
char
*
text
=
item
->
key
;
gpointer
key
=
NULL
;
key
=
purple_request_field_list_get_data
(
lfield
,
text
);
if
(
gnt_tree_get_choice
(
GNT_TREE
(
tree
),
key
))
{
selected
=
g_list_prepend
(
selected
,
(
gpointer
)
text
);
}
}
}
else
{
GntWidget
*
combo
=
g_object_get_data
(
G_OBJECT
(
field
),
"finch-ui-data"
);
gpointer
data
=
gnt_combo_box_get_selected_data
(
GNT_COMBO_BOX
(
combo
));
for
(;
list
;
list
=
list
->
next
)
{
PurpleKeyValuePair
*
item
=
list
->
data
;
const
char
*
text
=
item
->
key
;
gpointer
key
=
NULL
;
key
=
purple_request_field_list_get_data
(
lfield
,
text
);
if
(
key
==
data
)
{
selected
=
g_list_prepend
(
selected
,
(
gpointer
)
text
);
break
;
}
}
}
purple_request_field_list_set_selected
(
lfield
,
selected
);
g_list_free
(
selected
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_ACCOUNT
(
field
))
{
GntWidget
*
combo
=
NULL
;
PurpleAccount
*
acc
=
NULL
;
PurpleRequestFieldAccount
*
afield
=
NULL
;
combo
=
g_object_get_data
(
G_OBJECT
(
field
),
"finch-ui-data"
);
acc
=
gnt_combo_box_get_selected_data
(
GNT_COMBO_BOX
(
combo
));
afield
=
PURPLE_REQUEST_FIELD_ACCOUNT
(
field
);
purple_request_field_account_set_value
(
afield
,
acc
);
}
g_object_unref
(
field
);
}
g_object_unref
(
group
);
}
purple_notify_close_with_handle
(
button
);
if
(
!
g_object_get_data
(
G_OBJECT
(
button
),
"cancellation-function"
)
&&
!
purple_request_page_is_valid
(
page
))
{
purple_notify_error
(
button
,
_
(
"Error"
),
_
(
"You must properly fill all the required fields."
),
_
(
"The required fields are underlined."
),
NULL
);
return
;
}
if
(
callback
)
{
callback
(
data
,
page
);
}
window
=
gnt_widget_get_toplevel
(
button
);
purple_request_close
(
PURPLE_REQUEST_FIELDS
,
window
);
}
static
void
update_selected_account
(
GntEntry
*
username
,
G_GNUC_UNUSED
const
char
*
start
,
G_GNUC_UNUSED
const
char
*
end
,
GntComboBox
*
accountlist
)
{
GList
*
accounts
=
gnt_tree_get_rows
(
GNT_TREE
(
gnt_combo_box_get_dropdown
(
accountlist
)));
const
char
*
name
=
gnt_entry_get_text
(
username
);
while
(
accounts
)
{
if
(
purple_blist_find_buddy
(
accounts
->
data
,
name
))
{
gnt_combo_box_set_selected
(
accountlist
,
accounts
->
data
);
gnt_widget_draw
(
GNT_WIDGET
(
accountlist
));
break
;
}
accounts
=
accounts
->
next
;
}
}
static
GntWidget
*
create_boolean_field
(
PurpleRequestField
*
field
)
{
PurpleRequestFieldBool
*
boolfield
=
PURPLE_REQUEST_FIELD_BOOL
(
field
);
const
char
*
label
=
purple_request_field_get_label
(
field
);
GntWidget
*
check
=
gnt_check_box_new
(
label
);
gnt_check_box_set_checked
(
GNT_CHECK_BOX
(
check
),
purple_request_field_bool_get_default_value
(
boolfield
));
return
check
;
}
static
GntWidget
*
create_string_field
(
PurpleRequestField
*
field
,
GntWidget
**
username
)
{
PurpleRequestFieldString
*
strfield
=
PURPLE_REQUEST_FIELD_STRING
(
field
);
const
char
*
hint
=
purple_request_field_get_type_hint
(
field
);
GntWidget
*
entry
=
gnt_entry_new
(
purple_request_field_string_get_default_value
(
strfield
));
gnt_entry_set_masked
(
GNT_ENTRY
(
entry
),
purple_request_field_string_is_masked
(
strfield
));
if
(
hint
&&
g_str_has_prefix
(
hint
,
"screenname"
))
{
PurpleBlistNode
*
node
=
purple_blist_get_default_root
();
gboolean
offline
=
g_str_has_suffix
(
hint
,
"all"
);
for
(;
node
;
node
=
purple_blist_node_next
(
node
,
offline
))
{
if
(
!
PURPLE_IS_BUDDY
(
node
))
continue
;
gnt_entry_add_suggest
(
GNT_ENTRY
(
entry
),
purple_buddy_get_name
((
PurpleBuddy
*
)
node
));
}
gnt_entry_set_always_suggest
(
GNT_ENTRY
(
entry
),
TRUE
);
if
(
username
)
*
username
=
entry
;
}
else
if
(
purple_strequal
(
hint
,
"group"
))
{
PurpleBlistNode
*
node
;
for
(
node
=
purple_blist_get_default_root
();
node
;
node
=
purple_blist_node_get_sibling_next
(
node
))
{
if
(
PURPLE_IS_GROUP
(
node
))
gnt_entry_add_suggest
(
GNT_ENTRY
(
entry
),
purple_group_get_name
((
PurpleGroup
*
)
node
));
}
}
return
entry
;
}
static
GntWidget
*
create_integer_field
(
PurpleRequestField
*
field
)
{
PurpleRequestFieldInt
*
intfield
=
PURPLE_REQUEST_FIELD_INT
(
field
);
char
str
[
256
];
int
val
=
purple_request_field_int_get_default_value
(
intfield
);
GntWidget
*
entry
;
g_snprintf
(
str
,
sizeof
(
str
),
"%d"
,
val
);
entry
=
gnt_entry_new
(
str
);
gnt_entry_set_flag
(
GNT_ENTRY
(
entry
),
GNT_ENTRY_FLAG_INT
);
return
entry
;
}
static
GntWidget
*
create_choice_field
(
PurpleRequestField
*
field
)
{
PurpleRequestFieldChoice
*
cfield
=
PURPLE_REQUEST_FIELD_CHOICE
(
field
);
GntWidget
*
combo
=
gnt_combo_box_new
();
for
(
GList
*
it
=
purple_request_field_choice_get_elements
(
cfield
);
it
!=
NULL
;
it
=
g_list_next
(
it
))
{
PurpleKeyValuePair
*
choice
=
it
->
data
;
gnt_combo_box_add_data
(
GNT_COMBO_BOX
(
combo
),
choice
->
value
,
choice
->
key
);
}
gnt_combo_box_set_selected
(
GNT_COMBO_BOX
(
combo
),
purple_request_field_choice_get_default_value
(
cfield
));
return
combo
;
}
static
GntWidget
*
create_list_field
(
PurpleRequestField
*
field
)
{
PurpleRequestFieldList
*
lfield
=
PURPLE_REQUEST_FIELD_LIST
(
field
);
GntWidget
*
ret
=
NULL
;
GList
*
list
=
purple_request_field_list_get_items
(
lfield
);
if
(
purple_request_field_list_get_multi_select
(
lfield
))
{
GntWidget
*
tree
=
gnt_tree_new
();
for
(;
list
;
list
=
list
->
next
)
{
PurpleKeyValuePair
*
item
=
list
->
data
;
const
char
*
text
=
item
->
key
;
gpointer
key
=
purple_request_field_list_get_data
(
lfield
,
text
);
gnt_tree_add_choice
(
GNT_TREE
(
tree
),
key
,
gnt_tree_create_row
(
GNT_TREE
(
tree
),
text
),
NULL
,
NULL
);
if
(
purple_request_field_list_is_selected
(
lfield
,
text
))
{
gnt_tree_set_choice
(
GNT_TREE
(
tree
),
key
,
TRUE
);
}
}
ret
=
tree
;
}
else
{
GntWidget
*
combo
=
gnt_combo_box_new
();
for
(;
list
;
list
=
list
->
next
)
{
PurpleKeyValuePair
*
item
=
list
->
data
;
const
char
*
text
=
item
->
key
;
gpointer
key
=
purple_request_field_list_get_data
(
lfield
,
text
);
gnt_combo_box_add_data
(
GNT_COMBO_BOX
(
combo
),
key
,
text
);
if
(
purple_request_field_list_is_selected
(
lfield
,
text
))
{
gnt_combo_box_set_selected
(
GNT_COMBO_BOX
(
combo
),
key
);
}
}
ret
=
combo
;
}
return
ret
;
}
static
void
add_account_to_combo
(
GntWidget
*
combo
,
PurpleAccount
*
account
)
{
PurpleContactInfo
*
info
=
PURPLE_CONTACT_INFO
(
account
);
char
*
text
=
NULL
;
text
=
g_strdup_printf
(
"%s (%s)"
,
purple_contact_info_get_username
(
info
),
purple_account_get_protocol_name
(
account
));
gnt_combo_box_add_data
(
GNT_COMBO_BOX
(
combo
),
account
,
text
);
g_free
(
text
);
}
static
GntWidget
*
create_account_field
(
PurpleRequestField
*
field
)
{
PurpleRequestFieldAccount
*
afield
=
PURPLE_REQUEST_FIELD_ACCOUNT
(
field
);
gboolean
all
;
PurpleAccount
*
def
;
GntWidget
*
combo
=
gnt_combo_box_new
();
all
=
purple_request_field_account_get_show_all
(
afield
);
def
=
purple_request_field_account_get_value
(
afield
);
if
(
!
PURPLE_IS_ACCOUNT
(
def
))
{
def
=
purple_request_field_account_get_default_value
(
afield
);
}
if
(
all
)
{
GListModel
*
manager_model
=
NULL
;
guint
n_items
=
0
;
manager_model
=
purple_account_manager_get_default_as_model
();
n_items
=
g_list_model_get_n_items
(
manager_model
);
for
(
guint
index
=
0
;
index
<
n_items
;
index
++
)
{
PurpleAccount
*
account
;
account
=
g_list_model_get_item
(
manager_model
,
index
);
add_account_to_combo
(
combo
,
account
);
if
(
account
==
def
)
{
gnt_combo_box_set_selected
(
GNT_COMBO_BOX
(
combo
),
account
);
}
g_object_unref
(
account
);
}
}
else
{
GList
*
list
=
purple_connections_get_all
();
for
(;
list
;
list
=
list
->
next
)
{
PurpleAccount
*
account
=
NULL
;
account
=
purple_connection_get_account
(
list
->
data
);
add_account_to_combo
(
combo
,
account
);
if
(
account
==
def
)
{
gnt_combo_box_set_selected
(
GNT_COMBO_BOX
(
combo
),
account
);
}
}
}
gnt_widget_set_size
(
combo
,
20
,
3
);
/* ew */
return
combo
;
}
static
void
multifield_extra_cb
(
GntWidget
*
button
,
PurpleRequestPage
*
page
)
{
PurpleRequestFieldsCb
cb
;
gpointer
cb_data
;
gpointer
handle
;
handle
=
g_object_get_data
(
G_OBJECT
(
button
),
"ui-handle"
);
cb
=
g_object_get_data
(
G_OBJECT
(
button
),
"extra-cb"
);
cb_data
=
g_object_get_data
(
G_OBJECT
(
button
),
"extra-cb-data"
);
if
(
cb
!=
NULL
)
{
cb
(
cb_data
,
page
);
}
action_performed
(
button
,
handle
);
purple_request_close
(
PURPLE_REQUEST_FIELDS
,
handle
);
}
static
void
*
finch_request_fields
(
const
char
*
title
,
const
char
*
primary
,
const
char
*
secondary
,
PurpleRequestPage
*
page
,
const
char
*
ok
,
GCallback
ok_cb
,
const
char
*
cancel
,
GCallback
cancel_cb
,
PurpleRequestCommonParameters
*
cpar
,
void
*
userdata
)
{
GntWidget
*
window
,
*
box
;
GntWidget
*
username
=
NULL
,
*
accountlist
=
NULL
;
PurpleRequestHelpCb
help_cb
;
gpointer
help_data
;
GSList
*
extra_actions
;
guint
n_groups
;
window
=
setup_request_window
(
title
,
primary
,
secondary
,
PURPLE_REQUEST_FIELDS
);
/* This is how it's going to work: the request-groups are going to be
* stacked vertically one after the other. A GntLine will be separating
* the groups. */
box
=
gnt_vbox_new
(
FALSE
);
gnt_box_set_pad
(
GNT_BOX
(
box
),
0
);
gnt_box_set_fill
(
GNT_BOX
(
box
),
TRUE
);
n_groups
=
g_list_model_get_n_items
(
G_LIST_MODEL
(
page
));
for
(
guint
group_index
=
0
;
group_index
<
n_groups
;
group_index
++
)
{
PurpleRequestGroup
*
group
=
NULL
;
GntWidget
*
hbox
;
const
char
*
title
=
NULL
;
guint
n_fields
;
group
=
g_list_model_get_item
(
G_LIST_MODEL
(
page
),
group_index
);
title
=
purple_request_group_get_title
(
group
);
if
(
title
)
gnt_box_add_widget
(
GNT_BOX
(
box
),
gnt_label_new_with_format
(
title
,
GNT_TEXT_FLAG_BOLD
));
n_fields
=
g_list_model_get_n_items
(
G_LIST_MODEL
(
group
));
for
(
guint
field_index
=
0
;
field_index
<
n_fields
;
field_index
++
)
{
PurpleRequestField
*
field
=
NULL
;
const
char
*
label
=
NULL
;
GntWidget
*
widget
=
NULL
;
field
=
g_list_model_get_item
(
G_LIST_MODEL
(
group
),
field_index
);
label
=
purple_request_field_get_label
(
field
);
if
(
!
purple_request_field_is_visible
(
field
))
{
g_object_unref
(
field
);
continue
;
}
hbox
=
gnt_hbox_new
(
TRUE
);
/* hrm */
gnt_box_add_widget
(
GNT_BOX
(
box
),
hbox
);
if
(
!
PURPLE_IS_REQUEST_FIELD_BOOL
(
field
)
&&
label
)
{
GntWidget
*
l
;
if
(
purple_request_field_is_required
(
field
))
l
=
gnt_label_new_with_format
(
label
,
GNT_TEXT_FLAG_UNDERLINE
);
else
l
=
gnt_label_new
(
label
);
gnt_widget_set_size
(
l
,
0
,
1
);
gnt_box_add_widget
(
GNT_BOX
(
hbox
),
l
);
}
if
(
PURPLE_IS_REQUEST_FIELD_BOOL
(
field
))
{
widget
=
create_boolean_field
(
field
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_STRING
(
field
))
{
widget
=
create_string_field
(
field
,
&
username
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_INT
(
field
))
{
widget
=
create_integer_field
(
field
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_CHOICE
(
field
))
{
widget
=
create_choice_field
(
field
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_LIST
(
field
))
{
widget
=
create_list_field
(
field
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_ACCOUNT
(
field
))
{
accountlist
=
create_account_field
(
field
);
widget
=
accountlist
;
}
else
{
widget
=
gnt_label_new_with_format
(
_
(
"Not implemented yet."
),
GNT_TEXT_FLAG_BOLD
);
}
gnt_box_set_alignment
(
GNT_BOX
(
hbox
),
GNT_ALIGN_MID
);
gnt_box_add_widget
(
GNT_BOX
(
hbox
),
widget
);
g_object_set_data
(
G_OBJECT
(
field
),
"finch-ui-data"
,
widget
);
g_object_unref
(
field
);
}
if
(
group_index
<
n_groups
-
1
)
{
gnt_box_add_widget
(
GNT_BOX
(
box
),
gnt_hline_new
());
}
g_object_unref
(
group
);
}
gnt_box_add_widget
(
GNT_BOX
(
window
),
box
);
box
=
setup_button_box
(
window
,
userdata
,
request_fields_cb
,
page
,
ok
,
ok_cb
,
cancel
,
cancel_cb
,
NULL
);
extra_actions
=
purple_request_cpar_get_extra_actions
(
cpar
);
for
(
GSList
*
it
=
extra_actions
;
it
;
it
=
it
->
next
)
{
PurpleKeyValuePair
*
extra_action
=
it
->
data
;
GntWidget
*
button
=
gnt_button_new
(
extra_action
->
key
);
gnt_box_add_widget_in_front
(
GNT_BOX
(
box
),
button
);
g_object_set_data
(
G_OBJECT
(
button
),
"ui-handle"
,
window
);
g_object_set_data
(
G_OBJECT
(
button
),
"extra-cb"
,
extra_action
->
value
);
g_object_set_data
(
G_OBJECT
(
button
),
"extra-cb-data"
,
userdata
);
g_signal_connect
(
G_OBJECT
(
button
),
"activate"
,
G_CALLBACK
(
multifield_extra_cb
),
page
);
}
help_cb
=
purple_request_cpar_get_help_cb
(
cpar
,
&
help_data
);
if
(
help_cb
)
{
GntWidget
*
button
=
gnt_button_new
(
_
(
"Help"
));
gnt_box_add_widget_in_front
(
GNT_BOX
(
box
),
button
);
g_signal_connect_swapped
(
G_OBJECT
(
button
),
"activate"
,
G_CALLBACK
(
help_cb
),
help_data
);
}
gnt_box_add_widget
(
GNT_BOX
(
window
),
box
);
setup_default_callback
(
window
,
cancel_cb
,
userdata
);
gnt_widget_show
(
window
);
if
(
username
&&
accountlist
)
{
g_signal_connect
(
username
,
"completion"
,
G_CALLBACK
(
update_selected_account
),
accountlist
);
}
g_object_set_data_full
(
G_OBJECT
(
window
),
"fields"
,
page
,
g_object_unref
);
return
window
;
}
static
void
file_cancel_cb
(
G_GNUC_UNUSED
GntWidget
*
wid
,
gpointer
fq
)
{
FinchFileRequest
*
data
=
fq
;
if
(
data
->
dialog
==
NULL
)
{
/* We've already handled this request, and are in the destroy handler. */
return
;
}
if
(
data
->
cbs
[
1
]
!=
NULL
)
((
PurpleRequestFileCb
)
data
->
cbs
[
1
])(
data
->
user_data
,
NULL
);
purple_request_close
(
PURPLE_REQUEST_FILE
,
data
->
dialog
);
data
->
dialog
=
NULL
;
}
static
void
file_ok_cb
(
G_GNUC_UNUSED
GntWidget
*
widget
,
const
char
*
path
,
const
char
*
file
,
gpointer
fq
)
{
FinchFileRequest
*
data
=
fq
;
char
*
dir
=
g_path_get_dirname
(
path
);
if
(
data
->
cbs
[
0
]
!=
NULL
)
((
PurpleRequestFileCb
)
data
->
cbs
[
0
])(
data
->
user_data
,
file
);
purple_prefs_set_path
(
data
->
save
?
"/finch/filelocations/last_save_folder"
:
"/finch/filelocations/last_open_folder"
,
dir
);
g_free
(
dir
);
purple_request_close
(
PURPLE_REQUEST_FILE
,
data
->
dialog
);
data
->
dialog
=
NULL
;
}
static
void
file_request_destroy
(
FinchFileRequest
*
data
)
{
g_free
(
data
->
cbs
);
g_free
(
data
);
}
static
FinchFileRequest
*
finch_file_request_window
(
const
char
*
title
,
const
char
*
path
,
GCallback
ok_cb
,
GCallback
cancel_cb
,
void
*
user_data
)
{
GntWidget
*
window
=
gnt_file_sel_new
();
GntFileSel
*
sel
=
GNT_FILE_SEL
(
window
);
FinchFileRequest
*
data
=
g_new0
(
FinchFileRequest
,
1
);
data
->
user_data
=
user_data
;
data
->
cbs
=
g_new0
(
GCallback
,
2
);
data
->
cbs
[
0
]
=
ok_cb
;
data
->
cbs
[
1
]
=
cancel_cb
;
data
->
dialog
=
window
;
gnt_box_set_title
(
GNT_BOX
(
window
),
title
);
gnt_file_sel_set_current_location
(
sel
,
(
path
&&
*
path
)
?
path
:
g_get_home_dir
());
g_signal_connect
(
G_OBJECT
(
sel
),
"destroy"
,
G_CALLBACK
(
file_cancel_cb
),
data
);
g_signal_connect
(
G_OBJECT
(
sel
),
"cancelled"
,
G_CALLBACK
(
file_cancel_cb
),
data
);
g_signal_connect
(
G_OBJECT
(
sel
),
"file_selected"
,
G_CALLBACK
(
file_ok_cb
),
data
);
g_object_set_data_full
(
G_OBJECT
(
window
),
"filerequestdata"
,
data
,
(
GDestroyNotify
)
file_request_destroy
);
return
data
;
}
static
void
*
finch_request_file
(
const
char
*
title
,
const
char
*
filename
,
gboolean
savedialog
,
GCallback
ok_cb
,
GCallback
cancel_cb
,
G_GNUC_UNUSED
PurpleRequestCommonParameters
*
cpar
,
void
*
user_data
)
{
FinchFileRequest
*
data
;
const
char
*
path
;
path
=
purple_prefs_get_path
(
savedialog
?
"/finch/filelocations/last_save_folder"
:
"/finch/filelocations/last_open_folder"
);
data
=
finch_file_request_window
(
title
?
title
:
(
savedialog
?
_
(
"Save File..."
)
:
_
(
"Open File..."
)),
path
,
ok_cb
,
cancel_cb
,
user_data
);
data
->
save
=
savedialog
;
if
(
savedialog
)
gnt_file_sel_set_suggested_filename
(
GNT_FILE_SEL
(
data
->
dialog
),
filename
);
gnt_widget_show
(
data
->
dialog
);
return
data
->
dialog
;
}
static
void
*
finch_request_folder
(
const
char
*
title
,
const
char
*
dirname
,
GCallback
ok_cb
,
GCallback
cancel_cb
,
G_GNUC_UNUSED
PurpleRequestCommonParameters
*
cpar
,
gpointer
user_data
)
{
FinchFileRequest
*
data
;
data
=
finch_file_request_window
(
title
?
title
:
_
(
"Choose Location..."
),
dirname
,
ok_cb
,
cancel_cb
,
user_data
);
data
->
save
=
TRUE
;
gnt_file_sel_set_dirs_only
(
GNT_FILE_SEL
(
data
->
dialog
),
TRUE
);
gnt_widget_show
(
data
->
dialog
);
return
data
->
dialog
;
}
static
PurpleRequestUiOps
uiops
=
{
.
request_input
=
finch_request_input
,
.
request_choice
=
finch_request_choice
,
.
request_action
=
finch_request_action
,
.
request_fields
=
finch_request_fields
,
.
request_file
=
finch_request_file
,
.
request_folder
=
finch_request_folder
,
.
close_request
=
finch_close_request
,
};
PurpleRequestUiOps
*
finch_request_get_ui_ops
(
void
)
{
return
&
uiops
;
}
void
finch_request_init
(
void
)
{
}
void
finch_request_uninit
(
void
)
{
}
void
finch_request_save_in_prefs
(
G_GNUC_UNUSED
gpointer
data
,
PurpleRequestPage
*
page
)
{
guint
n_groups
;
n_groups
=
g_list_model_get_n_items
(
G_LIST_MODEL
(
page
));
for
(
guint
group_index
=
0
;
group_index
<
n_groups
;
group_index
++
)
{
GListModel
*
group
=
NULL
;
guint
n_fields
;
group
=
g_list_model_get_item
(
G_LIST_MODEL
(
page
),
group_index
);
n_fields
=
g_list_model_get_n_items
(
group
);
for
(
guint
field_index
=
0
;
field_index
<
n_fields
;
field_index
++
)
{
PurpleRequestField
*
field
=
NULL
;
PurplePrefType
pt
;
gpointer
val
=
NULL
;
const
char
*
id
=
NULL
;
field
=
g_list_model_get_item
(
group
,
field_index
);
id
=
purple_request_field_get_id
(
field
);
if
(
PURPLE_IS_REQUEST_FIELD_CHOICE
(
field
))
{
PurpleRequestFieldChoice
*
choice
=
PURPLE_REQUEST_FIELD_CHOICE
(
field
);
val
=
purple_request_field_choice_get_value
(
choice
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_LIST
(
field
))
{
PurpleRequestFieldList
*
lfield
=
PURPLE_REQUEST_FIELD_LIST
(
field
);
val
=
purple_request_field_list_get_selected
(
lfield
)
->
data
;
val
=
purple_request_field_list_get_data
(
lfield
,
val
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_BOOL
(
field
))
{
PurpleRequestFieldBool
*
bfield
=
PURPLE_REQUEST_FIELD_BOOL
(
field
);
val
=
GINT_TO_POINTER
(
purple_request_field_bool_get_value
(
bfield
));
}
else
if
(
PURPLE_IS_REQUEST_FIELD_INT
(
field
))
{
PurpleRequestFieldInt
*
ifield
=
PURPLE_REQUEST_FIELD_INT
(
field
);
val
=
GINT_TO_POINTER
(
purple_request_field_int_get_value
(
ifield
));
}
else
if
(
PURPLE_IS_REQUEST_FIELD_STRING
(
field
))
{
PurpleRequestFieldString
*
sfield
=
PURPLE_REQUEST_FIELD_STRING
(
field
);
val
=
(
gpointer
)
purple_request_field_string_get_value
(
sfield
);
}
pt
=
purple_prefs_get_pref_type
(
id
);
switch
(
pt
)
{
case
PURPLE_PREF_INT
:
{
long
int
tmp
=
GPOINTER_TO_INT
(
val
);
if
(
PURPLE_IS_REQUEST_FIELD_LIST
(
field
))
{
/* Lists always return string */
if
(
sscanf
(
val
,
"%ld"
,
&
tmp
)
!=
1
)
tmp
=
0
;
}
purple_prefs_set_int
(
id
,
(
gint
)
tmp
);
break
;
}
case
PURPLE_PREF_BOOLEAN
:
purple_prefs_set_bool
(
id
,
GPOINTER_TO_INT
(
val
));
break
;
case
PURPLE_PREF_STRING
:
purple_prefs_set_string
(
id
,
val
);
break
;
default
:
break
;
}
g_object_unref
(
field
);
}
g_object_unref
(
group
);
}
}
GntWidget
*
finch_request_field_get_widget
(
PurpleRequestField
*
field
)
{
GntWidget
*
ret
=
NULL
;
if
(
PURPLE_IS_REQUEST_FIELD_BOOL
(
field
))
{
ret
=
create_boolean_field
(
field
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_STRING
(
field
))
{
ret
=
create_string_field
(
field
,
NULL
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_INT
(
field
))
{
ret
=
create_integer_field
(
field
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_CHOICE
(
field
))
{
ret
=
create_choice_field
(
field
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_ACCOUNT
(
field
))
{
ret
=
create_account_field
(
field
);
}
else
if
(
PURPLE_IS_REQUEST_FIELD_LIST
(
field
))
{
ret
=
create_list_field
(
field
);
}
else
{
purple_debug_error
(
"GntRequest"
,
"Unimplemented request-field %s"
,
G_OBJECT_TYPE_NAME
(
field
));
}
return
ret
;
}