pidgin/pidgin
Clone
Summary
Browse
Changes
Graph
Use Meson summary() function.
2021-07-27, Elliott Sales de Andrade
cb640ea0f315
Use Meson summary() function.
Now that we require at least 0.52, we can use Meson's builtin summary printing to display the results of configuration.
Testing Done:
Configured with defaults, and with pixmaps disabled to trigger the warning: https://asciinema.org/a/mV2oxOoVCJNdmrPwgqqUJ3mkU?t=17
Reviewed at https://reviews.imfreedom.org/r/848/
/* pidgin
*
* Pidgin 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
*/
#ifdef HAVE_CONFIG_H
#
include
<config.h>
#endif
#include
<glib/gi18n-lib.h>
#include
<purple.h>
#include
<pidgin.h>
#include
"gtkdisco.h"
#include
"xmppdisco.h"
GList
*
dialogs
=
NULL
;
enum
{
PIXBUF_COLUMN
=
0
,
NAME_COLUMN
,
DESCRIPTION_COLUMN
,
SERVICE_COLUMN
,
NUM_OF_COLUMNS
};
static
void
pidgin_disco_list_destroy
(
PidginDiscoList
*
list
)
{
g_hash_table_destroy
(
list
->
services
);
if
(
list
->
dialog
&&
list
->
dialog
->
discolist
==
list
)
list
->
dialog
->
discolist
=
NULL
;
g_free
((
gchar
*
)
list
->
server
);
g_free
(
list
);
}
PidginDiscoList
*
pidgin_disco_list_ref
(
PidginDiscoList
*
list
)
{
g_return_val_if_fail
(
list
!=
NULL
,
NULL
);
++
list
->
ref
;
purple_debug_misc
(
"xmppdisco"
,
"reffing list, ref count now %d
\n
"
,
list
->
ref
);
return
list
;
}
void
pidgin_disco_list_unref
(
PidginDiscoList
*
list
)
{
g_return_if_fail
(
list
!=
NULL
);
--
list
->
ref
;
purple_debug_misc
(
"xmppdisco"
,
"unreffing list, ref count now %d
\n
"
,
list
->
ref
);
if
(
list
->
ref
==
0
)
pidgin_disco_list_destroy
(
list
);
}
void
pidgin_disco_list_set_in_progress
(
PidginDiscoList
*
list
,
gboolean
in_progress
)
{
PidginDiscoDialog
*
dialog
=
list
->
dialog
;
if
(
!
dialog
)
return
;
list
->
in_progress
=
in_progress
;
if
(
in_progress
)
{
gtk_widget_set_sensitive
(
dialog
->
account_chooser
,
FALSE
);
gtk_widget_set_sensitive
(
dialog
->
stop_button
,
TRUE
);
gtk_widget_set_sensitive
(
dialog
->
browse_button
,
FALSE
);
}
else
{
gtk_progress_bar_set_fraction
(
GTK_PROGRESS_BAR
(
dialog
->
progress
),
0.0
);
gtk_widget_set_sensitive
(
dialog
->
account_chooser
,
TRUE
);
gtk_widget_set_sensitive
(
dialog
->
stop_button
,
FALSE
);
gtk_widget_set_sensitive
(
dialog
->
browse_button
,
TRUE
);
/*
gtk_widget_set_sensitive(dialog->register_button, FALSE);
gtk_widget_set_sensitive(dialog->add_button, FALSE);
*/
}
}
static
GdkPixbuf
*
pidgin_disco_load_icon
(
XmppDiscoService
*
service
,
const
char
*
size
)
{
GdkPixbuf
*
pixbuf
=
NULL
;
char
*
filename
=
NULL
;
gchar
*
tmp_size
;
g_return_val_if_fail
(
service
!=
NULL
,
NULL
);
g_return_val_if_fail
(
size
!=
NULL
,
NULL
);
tmp_size
=
g_strdup_printf
(
"%sx%s"
,
size
,
size
);
if
(
service
->
type
==
XMPP_DISCO_SERVICE_TYPE_GATEWAY
&&
service
->
gateway_type
)
{
char
*
tmp
=
g_strconcat
(
"im-"
,
service
->
gateway_type
,
".png"
,
NULL
);
filename
=
g_build_filename
(
PURPLE_DATADIR
,
"pidgin"
,
"icons"
,
"hicolor"
,
tmp_size
,
"apps"
,
tmp
,
NULL
);
g_free
(
tmp
);
#if 0
} else if (service->type == XMPP_DISCO_SERVICE_TYPE_USER) {
filename = g_build_filename(PURPLE_DATADIR,
"pixmaps", "pidgin", "status", size, "person.png", NULL);
#endif
}
else
if
(
service
->
type
==
XMPP_DISCO_SERVICE_TYPE_CHAT
)
{
filename
=
g_build_filename
(
PURPLE_DATADIR
,
"pidgin"
,
"icons"
,
"hicolor"
,
tmp_size
,
"status"
,
"chat.png"
,
NULL
);
}
g_free
(
tmp_size
);
if
(
filename
)
{
pixbuf
=
gdk_pixbuf_new_from_file
(
filename
,
NULL
);
g_free
(
filename
);
}
return
pixbuf
;
}
static
void
dialog_select_account_cb
(
GtkWidget
*
chooser
,
PidginDiscoDialog
*
dialog
)
{
PurpleAccount
*
account
=
pidgin_account_chooser_get_selected
(
PIDGIN_ACCOUNT_CHOOSER
(
chooser
));
gboolean
change
=
(
account
!=
dialog
->
account
);
dialog
->
account
=
account
;
gtk_widget_set_sensitive
(
dialog
->
browse_button
,
account
!=
NULL
);
if
(
change
)
{
g_clear_pointer
(
&
dialog
->
discolist
,
pidgin_disco_list_unref
);
}
}
static
void
register_button_cb
(
GtkWidget
*
unused
,
PidginDiscoDialog
*
dialog
)
{
xmpp_disco_service_register
(
dialog
->
selected
);
}
static
void
discolist_cancel_cb
(
PidginDiscoList
*
pdl
,
const
char
*
server
)
{
pdl
->
dialog
->
prompt_handle
=
NULL
;
pidgin_disco_list_set_in_progress
(
pdl
,
FALSE
);
pidgin_disco_list_unref
(
pdl
);
}
static
void
discolist_ok_cb
(
PidginDiscoList
*
pdl
,
const
char
*
server
)
{
pdl
->
dialog
->
prompt_handle
=
NULL
;
gtk_widget_set_sensitive
(
pdl
->
dialog
->
browse_button
,
TRUE
);
if
(
!
server
||
!*
server
)
{
purple_notify_error
(
my_plugin
,
_
(
"Invalid Server"
),
_
(
"Invalid Server"
),
NULL
,
purple_request_cpar_from_connection
(
pdl
->
pc
));
pidgin_disco_list_set_in_progress
(
pdl
,
FALSE
);
pidgin_disco_list_unref
(
pdl
);
return
;
}
pdl
->
server
=
g_strdup
(
server
);
pidgin_disco_list_set_in_progress
(
pdl
,
TRUE
);
xmpp_disco_start
(
pdl
);
}
static
void
browse_button_cb
(
GtkWidget
*
button
,
PidginDiscoDialog
*
dialog
)
{
PurpleConnection
*
pc
;
PidginDiscoList
*
pdl
;
const
char
*
username
;
const
char
*
at
,
*
slash
;
char
*
server
=
NULL
;
pc
=
purple_account_get_connection
(
dialog
->
account
);
if
(
!
pc
)
return
;
gtk_widget_set_sensitive
(
dialog
->
browse_button
,
FALSE
);
gtk_widget_set_sensitive
(
dialog
->
add_button
,
FALSE
);
gtk_widget_set_sensitive
(
dialog
->
register_button
,
FALSE
);
g_clear_pointer
(
&
dialog
->
discolist
,
pidgin_disco_list_unref
);
gtk_tree_store_clear
(
dialog
->
model
);
pdl
=
dialog
->
discolist
=
g_new0
(
PidginDiscoList
,
1
);
pdl
->
services
=
g_hash_table_new_full
(
NULL
,
NULL
,
NULL
,
(
GDestroyNotify
)
gtk_tree_row_reference_free
);
pdl
->
pc
=
pc
;
/* We keep a copy... */
pidgin_disco_list_ref
(
pdl
);
pdl
->
dialog
=
dialog
;
gtk_widget_set_sensitive
(
dialog
->
account_chooser
,
FALSE
);
username
=
purple_account_get_username
(
dialog
->
account
);
at
=
strchr
(
username
,
'@'
);
slash
=
strchr
(
username
,
'/'
);
if
(
at
&&
!
slash
)
{
server
=
g_strdup
(
at
+
1
);
}
else
if
(
at
&&
slash
&&
at
+
1
<
slash
)
{
server
=
g_strdup_printf
(
"%.*s"
,
(
int
)(
slash
-
(
at
+
1
)),
at
+
1
);
}
if
(
server
==
NULL
)
/* This shouldn't ever happen since the account is connected */
server
=
g_strdup
(
"jabber.org"
);
/* Translators: The string "Enter an XMPP Server" is asking the user to
type the name of an XMPP server which will then be queried */
dialog
->
prompt_handle
=
purple_request_input
(
my_plugin
,
_
(
"Server name request"
),
_
(
"Enter an XMPP Server"
),
_
(
"Select an XMPP server to query"
),
server
,
FALSE
,
FALSE
,
NULL
,
_
(
"Find Services"
),
PURPLE_CALLBACK
(
discolist_ok_cb
),
_
(
"Cancel"
),
PURPLE_CALLBACK
(
discolist_cancel_cb
),
purple_request_cpar_from_connection
(
pc
),
pdl
);
g_free
(
server
);
}
static
void
add_to_blist_cb
(
GtkWidget
*
unused
,
PidginDiscoDialog
*
dialog
)
{
XmppDiscoService
*
service
=
dialog
->
selected
;
PurpleAccount
*
account
;
const
char
*
jid
;
g_return_if_fail
(
service
!=
NULL
);
account
=
purple_connection_get_account
(
service
->
list
->
pc
);
jid
=
service
->
jid
;
if
(
service
->
type
==
XMPP_DISCO_SERVICE_TYPE_CHAT
)
purple_blist_request_add_chat
(
account
,
NULL
,
NULL
,
jid
);
else
purple_blist_request_add_buddy
(
account
,
jid
,
NULL
,
NULL
);
}
static
gboolean
service_click_cb
(
GtkTreeView
*
tree
,
GdkEventButton
*
event
,
gpointer
user_data
)
{
PidginDiscoDialog
*
dialog
=
user_data
;
XmppDiscoService
*
service
;
GtkWidget
*
menu
;
GtkWidget
*
menuitem
=
NULL
;
GtkTreePath
*
path
;
GtkTreeIter
iter
;
GValue
val
;
if
(
!
gdk_event_triggers_context_menu
((
GdkEvent
*
)
event
))
return
FALSE
;
/* Figure out what was clicked */
if
(
!
gtk_tree_view_get_path_at_pos
(
tree
,
event
->
x
,
event
->
y
,
&
path
,
NULL
,
NULL
,
NULL
))
return
FALSE
;
gtk_tree_model_get_iter
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
path
);
gtk_tree_path_free
(
path
);
val
.
g_type
=
0
;
gtk_tree_model_get_value
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
SERVICE_COLUMN
,
&
val
);
service
=
g_value_get_pointer
(
&
val
);
if
(
!
service
)
return
FALSE
;
menu
=
gtk_menu_new
();
if
(
service
->
flags
&
XMPP_DISCO_ADD
)
{
menuitem
=
gtk_menu_item_new_with_label
(
_
(
"Add to Buddy List"
));
g_signal_connect
(
G_OBJECT
(
menuitem
),
"activate"
,
G_CALLBACK
(
add_to_blist_cb
),
dialog
);
gtk_menu_shell_append
(
GTK_MENU_SHELL
(
menu
),
menuitem
);
}
if
(
service
->
flags
&
XMPP_DISCO_REGISTER
)
{
menuitem
=
gtk_menu_item_new_with_label
(
_
(
"Register"
));
g_signal_connect
(
G_OBJECT
(
menuitem
),
"activate"
,
G_CALLBACK
(
register_button_cb
),
dialog
);
gtk_menu_shell_append
(
GTK_MENU_SHELL
(
menu
),
menuitem
);
}
gtk_widget_show_all
(
menu
);
gtk_menu_popup_at_pointer
(
GTK_MENU
(
menu
),
(
GdkEvent
*
)
event
);
return
FALSE
;
}
static
void
selection_changed_cb
(
GtkTreeSelection
*
selection
,
PidginDiscoDialog
*
dialog
)
{
GtkTreeIter
iter
;
GValue
val
;
if
(
gtk_tree_selection_get_selected
(
selection
,
NULL
,
&
iter
))
{
val
.
g_type
=
0
;
gtk_tree_model_get_value
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
SERVICE_COLUMN
,
&
val
);
dialog
->
selected
=
g_value_get_pointer
(
&
val
);
if
(
!
dialog
->
selected
)
{
gtk_widget_set_sensitive
(
dialog
->
add_button
,
FALSE
);
gtk_widget_set_sensitive
(
dialog
->
register_button
,
FALSE
);
return
;
}
gtk_widget_set_sensitive
(
dialog
->
add_button
,
dialog
->
selected
->
flags
&
XMPP_DISCO_ADD
);
gtk_widget_set_sensitive
(
dialog
->
register_button
,
dialog
->
selected
->
flags
&
XMPP_DISCO_REGISTER
);
}
else
{
gtk_widget_set_sensitive
(
dialog
->
add_button
,
FALSE
);
gtk_widget_set_sensitive
(
dialog
->
register_button
,
FALSE
);
}
}
static
void
row_expanded_cb
(
GtkTreeView
*
tree
,
GtkTreeIter
*
arg1
,
GtkTreePath
*
rg2
,
gpointer
user_data
)
{
PidginDiscoDialog
*
dialog
=
user_data
;
XmppDiscoService
*
service
;
GValue
val
;
val
.
g_type
=
0
;
gtk_tree_model_get_value
(
GTK_TREE_MODEL
(
dialog
->
model
),
arg1
,
SERVICE_COLUMN
,
&
val
);
service
=
g_value_get_pointer
(
&
val
);
xmpp_disco_service_expand
(
service
);
}
static
void
row_activated_cb
(
GtkTreeView
*
tree_view
,
GtkTreePath
*
path
,
GtkTreeViewColumn
*
column
,
gpointer
user_data
)
{
PidginDiscoDialog
*
dialog
=
user_data
;
GtkTreeIter
iter
;
XmppDiscoService
*
service
;
GValue
val
;
if
(
!
gtk_tree_model_get_iter
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
path
))
{
return
;
}
val
.
g_type
=
0
;
gtk_tree_model_get_value
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
SERVICE_COLUMN
,
&
val
);
service
=
g_value_get_pointer
(
&
val
);
if
(
service
->
flags
&
XMPP_DISCO_BROWSE
)
{
if
(
gtk_tree_view_row_expanded
(
GTK_TREE_VIEW
(
dialog
->
tree
),
path
))
{
gtk_tree_view_collapse_row
(
GTK_TREE_VIEW
(
dialog
->
tree
),
path
);
}
else
{
gtk_tree_view_expand_row
(
GTK_TREE_VIEW
(
dialog
->
tree
),
path
,
FALSE
);
}
}
else
if
(
service
->
flags
&
XMPP_DISCO_REGISTER
)
{
register_button_cb
(
NULL
,
dialog
);
}
else
if
(
service
->
flags
&
XMPP_DISCO_ADD
)
{
add_to_blist_cb
(
NULL
,
dialog
);
}
}
static
void
destroy_win_cb
(
GtkWidget
*
window
,
G_GNUC_UNUSED
gpointer
data
)
{
PidginDiscoDialog
*
dialog
=
PIDGIN_DISCO_DIALOG
(
window
);
PidginDiscoList
*
list
=
dialog
->
discolist
;
if
(
dialog
->
prompt_handle
)
purple_request_close
(
PURPLE_REQUEST_INPUT
,
dialog
->
prompt_handle
);
if
(
list
)
{
list
->
dialog
=
NULL
;
if
(
list
->
in_progress
)
list
->
in_progress
=
FALSE
;
pidgin_disco_list_unref
(
list
);
}
dialogs
=
g_list_remove
(
dialogs
,
dialog
);
}
static
void
stop_button_cb
(
GtkButton
*
button
,
PidginDiscoDialog
*
dialog
)
{
pidgin_disco_list_set_in_progress
(
dialog
->
discolist
,
FALSE
);
}
static
void
close_button_cb
(
GtkButton
*
button
,
PidginDiscoDialog
*
dialog
)
{
gtk_widget_destroy
(
GTK_WIDGET
(
dialog
));
}
static
gboolean
disco_query_tooltip
(
GtkWidget
*
widget
,
int
x
,
int
y
,
gboolean
keyboard_mode
,
GtkTooltip
*
tooltip
,
gpointer
data
)
{
PidginDiscoDialog
*
dialog
=
data
;
GtkTreePath
*
path
=
NULL
;
GtkTreeIter
iter
;
XmppDiscoService
*
service
;
GValue
val
;
const
char
*
type
=
NULL
;
char
*
markup
,
*
jid
,
*
name
,
*
desc
=
NULL
;
if
(
keyboard_mode
)
{
GtkTreeSelection
*
selection
=
gtk_tree_view_get_selection
(
GTK_TREE_VIEW
(
widget
));
if
(
!
gtk_tree_selection_get_selected
(
selection
,
NULL
,
&
iter
))
{
return
FALSE
;
}
path
=
gtk_tree_model_get_path
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
);
}
else
{
gint
bx
,
by
;
gtk_tree_view_convert_widget_to_bin_window_coords
(
GTK_TREE_VIEW
(
widget
),
x
,
y
,
&
bx
,
&
by
);
gtk_tree_view_get_path_at_pos
(
GTK_TREE_VIEW
(
widget
),
bx
,
by
,
&
path
,
NULL
,
NULL
,
NULL
);
if
(
path
==
NULL
)
{
return
FALSE
;
}
if
(
!
gtk_tree_model_get_iter
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
path
))
{
gtk_tree_path_free
(
path
);
return
FALSE
;
}
}
val
.
g_type
=
0
;
gtk_tree_model_get_value
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
SERVICE_COLUMN
,
&
val
);
service
=
g_value_get_pointer
(
&
val
);
if
(
!
service
)
{
gtk_tree_path_free
(
path
);
return
FALSE
;
}
switch
(
service
->
type
)
{
case
XMPP_DISCO_SERVICE_TYPE_UNSET
:
type
=
_
(
"Unknown"
);
break
;
case
XMPP_DISCO_SERVICE_TYPE_GATEWAY
:
type
=
_
(
"Gateway"
);
break
;
case
XMPP_DISCO_SERVICE_TYPE_DIRECTORY
:
type
=
_
(
"Directory"
);
break
;
case
XMPP_DISCO_SERVICE_TYPE_CHAT
:
type
=
_
(
"Chat"
);
break
;
case
XMPP_DISCO_SERVICE_TYPE_PUBSUB_COLLECTION
:
type
=
_
(
"PubSub Collection"
);
break
;
case
XMPP_DISCO_SERVICE_TYPE_PUBSUB_LEAF
:
type
=
_
(
"PubSub Leaf"
);
break
;
case
XMPP_DISCO_SERVICE_TYPE_OTHER
:
type
=
_
(
"Other"
);
break
;
}
markup
=
g_strdup_printf
(
"<span size='x-large' weight='bold'>%s</span>
\n
<b>%s:</b> %s%s%s"
,
name
=
g_markup_escape_text
(
service
->
name
,
-1
),
type
,
jid
=
g_markup_escape_text
(
service
->
jid
,
-1
),
service
->
description
?
_
(
"
\n
<b>Description:</b> "
)
:
""
,
service
->
description
?
desc
=
g_markup_escape_text
(
service
->
description
,
-1
)
:
""
);
gtk_tooltip_set_markup
(
tooltip
,
markup
);
gtk_tree_view_set_tooltip_row
(
GTK_TREE_VIEW
(
widget
),
tooltip
,
path
);
g_free
(
markup
);
g_free
(
jid
);
g_free
(
name
);
g_free
(
desc
);
gtk_tree_path_free
(
path
);
return
TRUE
;
}
void
pidgin_disco_signed_off_cb
(
PurpleConnection
*
pc
)
{
GList
*
node
;
for
(
node
=
dialogs
;
node
;
node
=
node
->
next
)
{
PidginDiscoDialog
*
dialog
=
node
->
data
;
PidginDiscoList
*
list
=
dialog
->
discolist
;
if
(
list
&&
list
->
pc
==
pc
)
{
PurpleAccount
*
account
=
NULL
;
if
(
list
->
in_progress
)
pidgin_disco_list_set_in_progress
(
list
,
FALSE
);
gtk_tree_store_clear
(
dialog
->
model
);
pidgin_disco_list_unref
(
list
);
dialog
->
discolist
=
NULL
;
account
=
pidgin_account_chooser_get_selected
(
PIDGIN_ACCOUNT_CHOOSER
(
dialog
->
account_chooser
));
gtk_widget_set_sensitive
(
dialog
->
browse_button
,
account
!=
NULL
);
gtk_widget_set_sensitive
(
dialog
->
register_button
,
FALSE
);
gtk_widget_set_sensitive
(
dialog
->
add_button
,
FALSE
);
}
}
}
void
pidgin_disco_dialogs_destroy_all
(
void
)
{
while
(
dialogs
)
{
GtkWidget
*
dialog
=
dialogs
->
data
;
gtk_widget_destroy
(
dialog
);
/* destroy_win_cb removes the dialog from the list */
}
}
/******************************************************************************
* GObject implementation
*****************************************************************************/
G_DEFINE_DYNAMIC_TYPE
(
PidginDiscoDialog
,
pidgin_disco_dialog
,
GTK_TYPE_DIALOG
)
static
void
pidgin_disco_dialog_class_init
(
PidginDiscoDialogClass
*
klass
)
{
GtkWidgetClass
*
widget_class
=
GTK_WIDGET_CLASS
(
klass
);
gtk_widget_class_set_template_from_resource
(
widget_class
,
"/im/pidgin/Pidgin/Plugin/XMPPDisco/disco.ui"
);
gtk_widget_class_bind_template_child
(
widget_class
,
PidginDiscoDialog
,
account_chooser
);
gtk_widget_class_bind_template_child
(
widget_class
,
PidginDiscoDialog
,
progress
);
gtk_widget_class_bind_template_child
(
widget_class
,
PidginDiscoDialog
,
stop_button
);
gtk_widget_class_bind_template_child
(
widget_class
,
PidginDiscoDialog
,
browse_button
);
gtk_widget_class_bind_template_child
(
widget_class
,
PidginDiscoDialog
,
register_button
);
gtk_widget_class_bind_template_child
(
widget_class
,
PidginDiscoDialog
,
add_button
);
gtk_widget_class_bind_template_child
(
widget_class
,
PidginDiscoDialog
,
tree
);
gtk_widget_class_bind_template_child
(
widget_class
,
PidginDiscoDialog
,
model
);
gtk_widget_class_bind_template_callback
(
widget_class
,
destroy_win_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
stop_button_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
browse_button_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
register_button_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
add_to_blist_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
close_button_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
dialog_select_account_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
row_activated_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
row_expanded_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
service_click_cb
);
gtk_widget_class_bind_template_callback
(
widget_class
,
selection_changed_cb
);
}
static
void
pidgin_disco_dialog_class_finalize
(
PidginDiscoDialogClass
*
klass
)
{
}
static
void
pidgin_disco_dialog_init
(
PidginDiscoDialog
*
dialog
)
{
dialogs
=
g_list_prepend
(
dialogs
,
dialog
);
gtk_widget_init_template
(
GTK_WIDGET
(
dialog
));
/* accounts dropdown list */
dialog
->
account
=
pidgin_account_chooser_get_selected
(
PIDGIN_ACCOUNT_CHOOSER
(
dialog
->
account_chooser
));
/* browse button */
gtk_widget_set_sensitive
(
dialog
->
browse_button
,
dialog
->
account
!=
NULL
);
gtk_widget_set_has_tooltip
(
GTK_WIDGET
(
dialog
->
tree
),
TRUE
);
g_signal_connect
(
G_OBJECT
(
dialog
->
tree
),
"query-tooltip"
,
G_CALLBACK
(
disco_query_tooltip
),
dialog
);
}
/******************************************************************************
* Public API
*****************************************************************************/
void
pidgin_disco_dialog_register
(
PurplePlugin
*
plugin
)
{
pidgin_disco_dialog_register_type
(
G_TYPE_MODULE
(
plugin
));
}
PidginDiscoDialog
*
pidgin_disco_dialog_new
(
void
)
{
PidginDiscoDialog
*
dialog
=
g_object_new
(
PIDGIN_TYPE_DISCO_DIALOG
,
NULL
);
gtk_widget_show_all
(
GTK_WIDGET
(
dialog
));
return
dialog
;
}
void
pidgin_disco_add_service
(
PidginDiscoList
*
pdl
,
XmppDiscoService
*
service
,
XmppDiscoService
*
parent
)
{
PidginDiscoDialog
*
dialog
;
GtkTreeIter
iter
,
parent_iter
,
child
;
GdkPixbuf
*
pixbuf
=
NULL
;
gboolean
append
=
TRUE
;
dialog
=
pdl
->
dialog
;
g_return_if_fail
(
dialog
!=
NULL
);
if
(
service
!=
NULL
)
purple_debug_info
(
"xmppdisco"
,
"Adding service
\"
%s
\"\n
"
,
service
->
name
);
else
purple_debug_info
(
"xmppdisco"
,
"Service
\"
%s
\"
has no childrens
\n
"
,
parent
->
name
);
gtk_progress_bar_pulse
(
GTK_PROGRESS_BAR
(
dialog
->
progress
));
if
(
parent
)
{
GtkTreeRowReference
*
rr
;
GtkTreePath
*
path
;
rr
=
g_hash_table_lookup
(
pdl
->
services
,
parent
);
path
=
gtk_tree_row_reference_get_path
(
rr
);
if
(
path
)
{
gtk_tree_model_get_iter
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
parent_iter
,
path
);
gtk_tree_path_free
(
path
);
if
(
gtk_tree_model_iter_children
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
child
,
&
parent_iter
))
{
PidginDiscoList
*
tmp
;
gtk_tree_model_get
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
child
,
SERVICE_COLUMN
,
&
tmp
,
-1
);
if
(
!
tmp
)
append
=
FALSE
;
}
}
}
if
(
service
==
NULL
)
{
if
(
parent
!=
NULL
&&
!
append
)
gtk_tree_store_remove
(
dialog
->
model
,
&
child
);
return
;
}
if
(
append
)
{
gtk_tree_store_append
(
dialog
->
model
,
&
iter
,
(
parent
?
&
parent_iter
:
NULL
));
}
else
{
iter
=
child
;
}
if
(
service
->
flags
&
XMPP_DISCO_BROWSE
)
{
GtkTreeRowReference
*
rr
;
GtkTreePath
*
path
;
gtk_tree_store_append
(
dialog
->
model
,
&
child
,
&
iter
);
path
=
gtk_tree_model_get_path
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
);
rr
=
gtk_tree_row_reference_new
(
GTK_TREE_MODEL
(
dialog
->
model
),
path
);
g_hash_table_insert
(
pdl
->
services
,
service
,
rr
);
gtk_tree_path_free
(
path
);
}
pixbuf
=
pidgin_disco_load_icon
(
service
,
"16"
);
gtk_tree_store_set
(
dialog
->
model
,
&
iter
,
PIXBUF_COLUMN
,
pixbuf
,
NAME_COLUMN
,
service
->
name
,
DESCRIPTION_COLUMN
,
service
->
description
,
SERVICE_COLUMN
,
service
,
-1
);
if
(
pixbuf
)
g_object_unref
(
pixbuf
);
}