pidgin/pidgin
Clone
Summary
Browse
Changes
Graph
Merged in default (pull request #656)
2019-11-22, Gary Kramlich
b82ecf28c2e4
Merged in default (pull request #656)
Add 2.1x.y Since tags and fix some missing docs
Approved-by: Gary Kramlich
/*
* Evolution integration plugin for Purple
*
* Copyright (C) 2003 Christian Hammond.
*
* 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
"internal.h"
#include
"gtkblist.h"
#include
"pidgin.h"
#include
"gtkutils.h"
#include
"debug.h"
#include
"gevolution.h"
#include
<stdlib.h>
#include
<gtk/gtk.h>
enum
{
COLUMN_NAME
,
COLUMN_DATA
,
NUM_COLUMNS
};
static
gint
delete_win_cb
(
GtkWidget
*
w
,
GdkEvent
*
event
,
GevoAssociateBuddyDialog
*
dialog
)
{
gtk_widget_destroy
(
dialog
->
win
);
g_list_free_full
(
dialog
->
contacts
,
g_object_unref
);
g_object_unref
(
dialog
->
book
);
gevo_addrbooks_model_unref
(
dialog
->
addrbooks
);
g_free
(
dialog
);
return
0
;
}
static
void
search_changed_cb
(
GtkEntry
*
entry
,
GevoAssociateBuddyDialog
*
dialog
)
{
const
char
*
text
=
gtk_entry_get_text
(
entry
);
GList
*
l
;
gtk_list_store_clear
(
dialog
->
model
);
for
(
l
=
dialog
->
contacts
;
l
!=
NULL
;
l
=
l
->
next
)
{
EContact
*
contact
=
E_CONTACT
(
l
->
data
);
const
char
*
name
;
GtkTreeIter
iter
;
name
=
e_contact_get_const
(
contact
,
E_CONTACT_FULL_NAME
);
if
(
text
!=
NULL
&&
*
text
!=
'\0'
&&
name
!=
NULL
&&
g_ascii_strncasecmp
(
name
,
text
,
strlen
(
text
)))
{
continue
;
}
gtk_list_store_append
(
dialog
->
model
,
&
iter
);
gtk_list_store_set
(
dialog
->
model
,
&
iter
,
COLUMN_NAME
,
name
,
COLUMN_DATA
,
contact
,
-1
);
}
}
static
void
clear_cb
(
GtkWidget
*
w
,
GevoAssociateBuddyDialog
*
dialog
)
{
static
gboolean
lock
=
FALSE
;
if
(
lock
)
return
;
lock
=
TRUE
;
gtk_entry_set_text
(
GTK_ENTRY
(
dialog
->
search_field
),
""
);
lock
=
FALSE
;
}
static
void
selected_cb
(
GtkTreeSelection
*
sel
,
GevoAssociateBuddyDialog
*
dialog
)
{
GtkTreeSelection
*
selection
;
selection
=
gtk_tree_view_get_selection
(
GTK_TREE_VIEW
(
dialog
->
treeview
));
gtk_widget_set_sensitive
(
dialog
->
assoc_button
,
gtk_tree_selection_get_selected
(
selection
,
NULL
,
NULL
));
}
static
void
add_columns
(
GevoAssociateBuddyDialog
*
dialog
)
{
GtkCellRenderer
*
renderer
;
GtkTreeViewColumn
*
column
;
/* Name column */
column
=
gtk_tree_view_column_new
();
gtk_tree_view_column_set_title
(
column
,
_
(
"Name"
));
gtk_tree_view_insert_column
(
GTK_TREE_VIEW
(
dialog
->
treeview
),
column
,
-1
);
gtk_tree_view_column_set_sort_column_id
(
column
,
COLUMN_NAME
);
renderer
=
gtk_cell_renderer_text_new
();
gtk_tree_view_column_pack_start
(
column
,
renderer
,
TRUE
);
gtk_tree_view_column_add_attribute
(
column
,
renderer
,
"text"
,
COLUMN_NAME
);
}
static
void
populate_treeview
(
GevoAssociateBuddyDialog
*
dialog
,
const
gchar
*
uid
)
{
EBook
*
book
;
EBookQuery
*
query
;
gboolean
status
;
GList
*
cards
,
*
c
;
GError
*
err
=
NULL
;
if
(
dialog
->
book
!=
NULL
)
{
g_object_unref
(
dialog
->
book
);
dialog
->
book
=
NULL
;
}
if
(
dialog
->
contacts
!=
NULL
)
{
g_list_free_full
(
dialog
->
contacts
,
g_object_unref
);
dialog
->
contacts
=
NULL
;
}
gtk_list_store_clear
(
dialog
->
model
);
if
(
!
gevo_load_addressbook
(
uid
,
&
book
,
&
err
))
{
purple_debug_error
(
"evolution"
,
"Error retrieving addressbook: %s
\n
"
,
err
->
message
);
g_error_free
(
err
);
return
;
}
query
=
e_book_query_field_exists
(
E_CONTACT_FULL_NAME
);
if
(
query
==
NULL
)
{
purple_debug_error
(
"evolution"
,
"Error in creating query
\n
"
);
g_object_unref
(
book
);
return
;
}
status
=
e_book_get_contacts
(
book
,
query
,
&
cards
,
NULL
);
e_book_query_unref
(
query
);
if
(
!
status
)
{
purple_debug_error
(
"evolution"
,
"Error %d in getting card list
\n
"
,
status
);
g_object_unref
(
book
);
return
;
}
for
(
c
=
cards
;
c
!=
NULL
;
c
=
c
->
next
)
{
EContact
*
contact
=
E_CONTACT
(
c
->
data
);
const
char
*
name
;
GtkTreeIter
iter
;
EContactField
protocol_field
=
0
;
name
=
e_contact_get_const
(
contact
,
E_CONTACT_FULL_NAME
);
gtk_list_store_append
(
dialog
->
model
,
&
iter
);
gtk_list_store_set
(
dialog
->
model
,
&
iter
,
COLUMN_NAME
,
name
,
COLUMN_DATA
,
contact
,
-1
);
/* See if this user has the buddy in its list. */
protocol_field
=
gevo_protocol_get_field
(
purple_buddy_get_account
(
dialog
->
buddy
),
dialog
->
buddy
);
if
(
protocol_field
>
0
)
{
GList
*
ims
,
*
l
;
ims
=
e_contact_get
(
contact
,
protocol_field
);
for
(
l
=
ims
;
l
!=
NULL
;
l
=
l
->
next
)
{
if
(
purple_strequal
(
l
->
data
,
purple_buddy_get_name
(
dialog
->
buddy
)))
{
GtkTreeSelection
*
selection
;
/* This is it. Select it. */
selection
=
gtk_tree_view_get_selection
(
GTK_TREE_VIEW
(
dialog
->
treeview
));
gtk_tree_selection_select_iter
(
selection
,
&
iter
);
break
;
}
}
}
}
dialog
->
contacts
=
cards
;
dialog
->
book
=
book
;
}
static
void
addrbook_change_cb
(
GtkComboBox
*
combo
,
GevoAssociateBuddyDialog
*
dialog
)
{
GtkTreeIter
iter
;
const
char
*
esource_uid
;
if
(
!
gtk_combo_box_get_active_iter
(
combo
,
&
iter
))
return
;
gtk_tree_model_get
(
GTK_TREE_MODEL
(
dialog
->
addrbooks
),
&
iter
,
ADDRBOOK_COLUMN_UID
,
&
esource_uid
,
-1
);
populate_treeview
(
dialog
,
esource_uid
);
}
static
void
new_person_cb
(
GtkWidget
*
w
,
GevoAssociateBuddyDialog
*
dialog
)
{
gevo_new_person_dialog_show
(
dialog
->
book
,
NULL
,
purple_buddy_get_account
(
dialog
->
buddy
),
purple_buddy_get_name
(
dialog
->
buddy
),
NULL
,
dialog
->
buddy
,
TRUE
);
delete_win_cb
(
NULL
,
NULL
,
dialog
);
}
static
void
cancel_cb
(
GtkWidget
*
w
,
GevoAssociateBuddyDialog
*
dialog
)
{
delete_win_cb
(
NULL
,
NULL
,
dialog
);
}
static
void
assoc_buddy_cb
(
GtkWidget
*
w
,
GevoAssociateBuddyDialog
*
dialog
)
{
GtkTreeSelection
*
selection
;
GtkTreeIter
iter
;
GList
*
list
;
const
char
*
fullname
;
EContactField
protocol_field
;
EContact
*
contact
;
selection
=
gtk_tree_view_get_selection
(
GTK_TREE_VIEW
(
dialog
->
treeview
));
if
(
!
gtk_tree_selection_get_selected
(
selection
,
NULL
,
&
iter
))
return
;
gtk_tree_model_get
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
COLUMN_NAME
,
&
fullname
,
COLUMN_DATA
,
&
contact
,
-1
);
protocol_field
=
gevo_protocol_get_field
(
purple_buddy_get_account
(
dialog
->
buddy
),
dialog
->
buddy
);
if
(
protocol_field
==
0
)
return
;
/* XXX */
list
=
e_contact_get
(
contact
,
protocol_field
);
list
=
g_list_append
(
list
,
g_strdup
(
purple_buddy_get_name
(
dialog
->
buddy
)));
e_contact_set
(
contact
,
protocol_field
,
list
);
if
(
!
e_book_commit_contact
(
dialog
->
book
,
contact
,
NULL
))
purple_debug_error
(
"evolution"
,
"Error adding contact to book
\n
"
);
/* Free the list. */
g_list_free_full
(
list
,
g_free
);
delete_win_cb
(
NULL
,
NULL
,
dialog
);
}
GevoAssociateBuddyDialog
*
gevo_associate_buddy_dialog_new
(
PurpleBuddy
*
buddy
)
{
GevoAssociateBuddyDialog
*
dialog
;
GtkWidget
*
button
;
GtkWidget
*
label
;
GtkWidget
*
vbox
;
GtkWidget
*
hbox
;
GtkWidget
*
bbox
;
GtkWidget
*
sep
;
GtkTreeSelection
*
selection
;
GtkCellRenderer
*
cell
;
g_return_val_if_fail
(
buddy
!=
NULL
,
NULL
);
dialog
=
g_new0
(
GevoAssociateBuddyDialog
,
1
);
dialog
->
buddy
=
buddy
;
dialog
->
win
=
pidgin_create_window
(
NULL
,
PIDGIN_HIG_BORDER
,
"assoc_buddy"
,
TRUE
);
g_signal_connect
(
G_OBJECT
(
dialog
->
win
),
"delete_event"
,
G_CALLBACK
(
delete_win_cb
),
dialog
);
/* Setup the vbox */
vbox
=
gtk_box_new
(
GTK_ORIENTATION_VERTICAL
,
12
);
gtk_container_add
(
GTK_CONTAINER
(
dialog
->
win
),
vbox
);
gtk_widget_show
(
vbox
);
/* Add the label. */
label
=
gtk_label_new
(
_
(
"Select a person from your address book to "
"add this buddy to, or create a new person."
));
gtk_label_set_line_wrap
(
GTK_LABEL
(
label
),
TRUE
);
gtk_label_set_xalign
(
GTK_LABEL
(
label
),
0
);
gtk_label_set_yalign
(
GTK_LABEL
(
label
),
0
);
gtk_box_pack_start
(
GTK_BOX
(
vbox
),
label
,
FALSE
,
TRUE
,
0
);
gtk_widget_show
(
label
);
/* Add the search hbox */
hbox
=
gtk_box_new
(
GTK_ORIENTATION_HORIZONTAL
,
6
);
gtk_box_pack_start
(
GTK_BOX
(
vbox
),
hbox
,
FALSE
,
TRUE
,
0
);
gtk_widget_show
(
hbox
);
/* "Search" */
label
=
gtk_label_new
(
_
(
"Search"
));
gtk_box_pack_start
(
GTK_BOX
(
hbox
),
label
,
FALSE
,
FALSE
,
0
);
gtk_widget_show
(
label
);
/* Addressbooks */
dialog
->
addrbooks
=
gevo_addrbooks_model_new
();
dialog
->
addrbooks_combo
=
gtk_combo_box_new_with_model
(
dialog
->
addrbooks
);
cell
=
gtk_cell_renderer_text_new
();
gtk_cell_layout_pack_start
(
GTK_CELL_LAYOUT
(
dialog
->
addrbooks_combo
),
cell
,
TRUE
);
gtk_cell_layout_set_attributes
(
GTK_CELL_LAYOUT
(
dialog
->
addrbooks_combo
),
cell
,
"text"
,
ADDRBOOK_COLUMN_NAME
,
NULL
);
gtk_box_pack_start
(
GTK_BOX
(
hbox
),
dialog
->
addrbooks_combo
,
FALSE
,
FALSE
,
0
);
gtk_widget_show
(
dialog
->
addrbooks_combo
);
/* Search field */
dialog
->
search_field
=
gtk_entry_new
();
gtk_box_pack_start
(
GTK_BOX
(
hbox
),
dialog
->
search_field
,
TRUE
,
TRUE
,
0
);
gtk_widget_show
(
dialog
->
search_field
);
g_signal_connect
(
G_OBJECT
(
dialog
->
search_field
),
"changed"
,
G_CALLBACK
(
search_changed_cb
),
dialog
);
/* Clear button */
button
=
gtk_button_new_with_mnemonic
(
_
(
"C_lear"
));
gtk_box_pack_start
(
GTK_BOX
(
hbox
),
button
,
FALSE
,
FALSE
,
0
);
gtk_widget_show
(
button
);
g_signal_connect
(
G_OBJECT
(
button
),
"clicked"
,
G_CALLBACK
(
clear_cb
),
dialog
);
/* Create the list model for the treeview. */
dialog
->
model
=
gtk_list_store_new
(
NUM_COLUMNS
,
G_TYPE_STRING
,
G_TYPE_POINTER
);
/* Now for the treeview */
dialog
->
treeview
=
gtk_tree_view_new_with_model
(
GTK_TREE_MODEL
(
dialog
->
model
));
gtk_box_pack_start
(
GTK_BOX
(
vbox
),
pidgin_make_scrollable
(
dialog
->
treeview
,
GTK_POLICY_AUTOMATIC
,
GTK_POLICY_ALWAYS
,
GTK_SHADOW_IN
,
-1
,
-1
),
TRUE
,
TRUE
,
0
);
gtk_widget_show
(
dialog
->
treeview
);
selection
=
gtk_tree_view_get_selection
(
GTK_TREE_VIEW
(
dialog
->
treeview
));
gtk_tree_selection_set_mode
(
selection
,
GTK_SELECTION_SINGLE
);
g_signal_connect
(
G_OBJECT
(
selection
),
"changed"
,
G_CALLBACK
(
selected_cb
),
dialog
);
add_columns
(
dialog
);
/*
* Catch addressbook selection and populate treeview with the first
* addressbook
*/
gevo_addrbooks_model_populate
(
dialog
->
addrbooks
);
g_signal_connect
(
G_OBJECT
(
dialog
->
addrbooks_combo
),
"changed"
,
G_CALLBACK
(
addrbook_change_cb
),
dialog
);
gtk_combo_box_set_active
(
GTK_COMBO_BOX
(
dialog
->
addrbooks_combo
),
0
);
/* Separator. */
sep
=
gtk_separator_new
(
GTK_ORIENTATION_HORIZONTAL
);
gtk_box_pack_start
(
GTK_BOX
(
vbox
),
sep
,
FALSE
,
FALSE
,
0
);
gtk_widget_show
(
sep
);
/* Button box */
bbox
=
gtk_button_box_new
(
GTK_ORIENTATION_HORIZONTAL
);
gtk_box_set_spacing
(
GTK_BOX
(
bbox
),
6
);
gtk_button_box_set_layout
(
GTK_BUTTON_BOX
(
bbox
),
GTK_BUTTONBOX_END
);
gtk_box_pack_end
(
GTK_BOX
(
vbox
),
bbox
,
FALSE
,
TRUE
,
0
);
gtk_widget_show
(
bbox
);
/* "New Person" button */
button
=
gtk_button_new_with_mnemonic
(
_
(
"_New Person"
));
gtk_box_pack_start
(
GTK_BOX
(
bbox
),
button
,
FALSE
,
FALSE
,
0
);
gtk_widget_show
(
button
);
g_signal_connect
(
G_OBJECT
(
button
),
"clicked"
,
G_CALLBACK
(
new_person_cb
),
dialog
);
/* "Cancel" button */
button
=
gtk_button_new_with_mnemonic
(
_
(
"_Cancel"
));
gtk_box_pack_start
(
GTK_BOX
(
bbox
),
button
,
FALSE
,
FALSE
,
0
);
gtk_widget_show
(
button
);
g_signal_connect
(
G_OBJECT
(
button
),
"clicked"
,
G_CALLBACK
(
cancel_cb
),
dialog
);
/* "Associate Buddy" button */
button
=
gtk_button_new_with_mnemonic
(
_
(
"_Associate Buddy"
));,
dialog
->
assoc_button
=
button
;
gtk_box_pack_start
(
GTK_BOX
(
bbox
),
button
,
FALSE
,
FALSE
,
0
);
gtk_widget_set_sensitive
(
button
,
FALSE
);
gtk_widget_show
(
button
);
g_signal_connect
(
G_OBJECT
(
button
),
"clicked"
,
G_CALLBACK
(
assoc_buddy_cb
),
dialog
);
/* Show it. */
gtk_widget_show
(
dialog
->
win
);
return
dialog
;
}