aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy-gtk
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy-gtk')
-rw-r--r--libempathy-gtk/Makefile.am4
-rw-r--r--libempathy-gtk/empathy-account-chooser.c10
-rw-r--r--libempathy-gtk/empathy-account-widget-irc.c2
-rw-r--r--libempathy-gtk/empathy-avatar-chooser.c10
-rw-r--r--libempathy-gtk/empathy-avatar-image.c2
-rw-r--r--libempathy-gtk/empathy-cell-renderer-expander.c38
-rw-r--r--libempathy-gtk/empathy-chat-text-view.c10
-rw-r--r--libempathy-gtk/empathy-chat.c104
-rw-r--r--libempathy-gtk/empathy-contact-dialogs.c21
-rw-r--r--libempathy-gtk/empathy-contact-dialogs.h4
-rw-r--r--libempathy-gtk/empathy-contact-list-store.c44
-rw-r--r--libempathy-gtk/empathy-contact-list-store.h1
-rw-r--r--libempathy-gtk/empathy-contact-list-view.c62
-rw-r--r--libempathy-gtk/empathy-contact-list-view.h1
-rw-r--r--libempathy-gtk/empathy-contact-menu.c135
-rw-r--r--libempathy-gtk/empathy-contact-menu.h2
-rw-r--r--libempathy-gtk/empathy-contact-widget.c15
-rw-r--r--libempathy-gtk/empathy-contact-widget.ui12
-rw-r--r--libempathy-gtk/empathy-geometry.c20
-rw-r--r--libempathy-gtk/empathy-kludge-label.c89
-rw-r--r--libempathy-gtk/empathy-kludge-label.h53
-rw-r--r--libempathy-gtk/empathy-new-message-dialog.ui84
-rw-r--r--libempathy-gtk/empathy-presence-chooser.c12
-rw-r--r--libempathy-gtk/empathy-share-my-desktop.c245
-rw-r--r--libempathy-gtk/empathy-share-my-desktop.h28
-rw-r--r--libempathy-gtk/empathy-status-preset-dialog.c4
-rw-r--r--libempathy-gtk/empathy-theme-adium.c388
-rw-r--r--libempathy-gtk/empathy-theme-manager.c67
-rw-r--r--libempathy-gtk/empathy-theme-manager.h1
-rw-r--r--libempathy-gtk/empathy-ui-utils.c9
-rw-r--r--libempathy-gtk/empathy-video-widget.c6
31 files changed, 1260 insertions, 223 deletions
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index 94cc4ee15..7f93accd3 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -41,6 +41,7 @@ libempathy_gtk_handwritten_source = \
empathy-contact-list-store.c \
empathy-contact-list-view.c \
empathy-contact-menu.c \
+ empathy-share-my-desktop.c \
empathy-contact-selector.c \
empathy-contact-widget.c \
empathy-geometry.c \
@@ -60,6 +61,7 @@ libempathy_gtk_handwritten_source = \
empathy-theme-boxes.c \
empathy-theme-irc.c \
empathy-theme-manager.c \
+ empathy-kludge-label.c \
empathy-ui-utils.c
libempathy_gtk_la_SOURCES = \
@@ -100,6 +102,7 @@ libempathy_gtk_headers = \
empathy-contact-list-store.h \
empathy-contact-list-view.h \
empathy-contact-menu.h \
+ empathy-share-my-desktop.h \
empathy-contact-selector.h \
empathy-contact-widget.h \
empathy-geometry.h \
@@ -120,6 +123,7 @@ libempathy_gtk_headers = \
empathy-theme-boxes.h \
empathy-theme-irc.h \
empathy-theme-manager.h \
+ empathy-kludge-label.h \
empathy-ui-utils.h
check_c_sources = \
diff --git a/libempathy-gtk/empathy-account-chooser.c b/libempathy-gtk/empathy-account-chooser.c
index fa05bbcc9..7c6f52fa5 100644
--- a/libempathy-gtk/empathy-account-chooser.c
+++ b/libempathy-gtk/empathy-account-chooser.c
@@ -56,6 +56,7 @@
typedef struct {
EmpathyAccountManager *manager;
gboolean set_active_item;
+ gboolean account_manually_set;
gboolean has_all_option;
EmpathyAccountChooserFilterFunc filter;
gpointer filter_data;
@@ -151,6 +152,7 @@ empathy_account_chooser_init (EmpathyAccountChooser *chooser)
chooser->priv = priv;
priv->set_active_item = FALSE;
+ priv->account_manually_set = FALSE;
priv->filter = NULL;
priv->filter_data = NULL;
@@ -320,6 +322,7 @@ gboolean
empathy_account_chooser_set_account (EmpathyAccountChooser *chooser,
EmpathyAccount *account)
{
+ EmpathyAccountChooserPriv *priv;
GtkComboBox *combobox;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -327,6 +330,8 @@ empathy_account_chooser_set_account (EmpathyAccountChooser *chooser,
g_return_val_if_fail (EMPATHY_IS_ACCOUNT_CHOOSER (chooser), FALSE);
+ priv = GET_PRIV (chooser);
+
combobox = GTK_COMBO_BOX (chooser);
model = gtk_combo_box_get_model (combobox);
gtk_combo_box_get_active_iter (combobox, &iter);
@@ -338,6 +343,8 @@ empathy_account_chooser_set_account (EmpathyAccountChooser *chooser,
(GtkTreeModelForeachFunc) account_chooser_set_account_foreach,
&data);
+ priv->account_manually_set = data.set;
+
return data.set;
}
@@ -620,7 +627,8 @@ account_chooser_update_iter (EmpathyAccountChooser *chooser,
-1);
/* set first connected account as active account */
- if (priv->set_active_item == FALSE && is_enabled) {
+ if (priv->account_manually_set == FALSE &&
+ priv->set_active_item == FALSE && is_enabled) {
priv->set_active_item = TRUE;
gtk_combo_box_set_active_iter (combobox, iter);
}
diff --git a/libempathy-gtk/empathy-account-widget-irc.c b/libempathy-gtk/empathy-account-widget-irc.c
index 4bca91073..c04f3463d 100644
--- a/libempathy-gtk/empathy-account-widget-irc.c
+++ b/libempathy-gtk/empathy-account-widget-irc.c
@@ -431,7 +431,7 @@ empathy_account_widget_irc_new (EmpathyAccountSettings *account_settings)
settings = g_slice_new0 (EmpathyAccountWidgetIrc);
settings->settings = g_object_ref (account_settings);
- dir = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, NULL);
+ dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
user_file_with_path = g_build_filename (dir, IRC_NETWORKS_FILENAME, NULL);
g_free (dir);
diff --git a/libempathy-gtk/empathy-avatar-chooser.c b/libempathy-gtk/empathy-avatar-chooser.c
index 83475b565..af96885e4 100644
--- a/libempathy-gtk/empathy-avatar-chooser.c
+++ b/libempathy-gtk/empathy-avatar-chooser.c
@@ -786,24 +786,24 @@ avatar_chooser_drag_data_received_cb (GtkWidget *widget,
gchar *target_type;
gboolean handled = FALSE;
- target_type = gdk_atom_name (selection_data->target);
+ target_type = gdk_atom_name (gtk_selection_data_get_target (selection_data));
if (!strcmp (target_type, URI_LIST_TYPE)) {
GFile *file;
GFileInputStream *input_stream;
gchar *nl;
gchar *data = NULL;
- nl = strstr (selection_data->data, "\r\n");
+ nl = strstr (gtk_selection_data_get_data (selection_data), "\r\n");
if (nl) {
gchar *uri;
- uri = g_strndup (selection_data->data,
- nl - (gchar *) selection_data->data);
+ uri = g_strndup (gtk_selection_data_get_data (selection_data),
+ nl - (gchar *) gtk_selection_data_get_data (selection_data));
file = g_file_new_for_uri (uri);
g_free (uri);
} else {
- file = g_file_new_for_uri (selection_data->data);
+ file = g_file_new_for_uri (gtk_selection_data_get_data (selection_data));
}
input_stream = g_file_read (file, NULL, NULL);
diff --git a/libempathy-gtk/empathy-avatar-image.c b/libempathy-gtk/empathy-avatar-image.c
index d430c0fa6..f7898e1bd 100644
--- a/libempathy-gtk/empathy-avatar-image.c
+++ b/libempathy-gtk/empathy-avatar-image.c
@@ -232,7 +232,7 @@ avatar_image_button_press_event (GtkWidget *widget, GdkEventButton *event)
gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
g_object_unref (pixbuf);
- gdk_window_get_origin (priv->image->window, &x, &y);
+ gdk_window_get_origin (gtk_widget_get_window (priv->image), &x, &y);
x = x - (popup_width - width) / 2;
y = y - (popup_height - height) / 2;
diff --git a/libempathy-gtk/empathy-cell-renderer-expander.c b/libempathy-gtk/empathy-cell-renderer-expander.c
index 6fb7cfded..bd5c89f19 100644
--- a/libempathy-gtk/empathy-cell-renderer-expander.c
+++ b/libempathy-gtk/empathy-cell-renderer-expander.c
@@ -101,9 +101,11 @@ empathy_cell_renderer_expander_init (EmpathyCellRendererExpander *expander)
priv->activatable = TRUE;
priv->animation_node = NULL;
- GTK_CELL_RENDERER (expander)->xpad = 2;
- GTK_CELL_RENDERER (expander)->ypad = 2;
- GTK_CELL_RENDERER (expander)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
+ g_object_set (expander,
+ "xpad", 2,
+ "ypad", 2,
+ "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
+ NULL);
}
static void
@@ -252,18 +254,27 @@ empathy_cell_renderer_expander_get_size (GtkCellRenderer *cell,
{
EmpathyCellRendererExpander *expander;
EmpathyCellRendererExpanderPriv *priv;
+ gfloat xalign, yalign;
+ guint xpad, ypad;
expander = (EmpathyCellRendererExpander *) cell;
priv = GET_PRIV (expander);
+ g_object_get (cell,
+ "xalign", &xalign,
+ "yalign", &yalign,
+ "xpad", &xpad,
+ "ypad", &ypad,
+ NULL);
+
if (cell_area) {
if (x_offset) {
- *x_offset = cell->xalign * (cell_area->width - (priv->expander_size + (2 * cell->xpad)));
+ *x_offset = xalign * (cell_area->width - (priv->expander_size + (2 * xpad)));
*x_offset = MAX (*x_offset, 0);
}
if (y_offset) {
- *y_offset = cell->yalign * (cell_area->height - (priv->expander_size + (2 * cell->ypad)));
+ *y_offset = yalign * (cell_area->height - (priv->expander_size + (2 * ypad)));
*y_offset = MAX (*y_offset, 0);
}
} else {
@@ -275,10 +286,10 @@ empathy_cell_renderer_expander_get_size (GtkCellRenderer *cell,
}
if (width)
- *width = cell->xpad * 2 + priv->expander_size;
+ *width = xpad * 2 + priv->expander_size;
if (height)
- *height = cell->ypad * 2 + priv->expander_size;
+ *height = ypad * 2 + priv->expander_size;
}
static void
@@ -294,6 +305,8 @@ empathy_cell_renderer_expander_render (GtkCellRenderer *cell,
EmpathyCellRendererExpanderPriv *priv;
GtkExpanderStyle expander_style;
gint x_offset, y_offset;
+ guint xpad, ypad;
+
expander = (EmpathyCellRendererExpander *) cell;
priv = GET_PRIV (expander);
@@ -319,14 +332,19 @@ empathy_cell_renderer_expander_render (GtkCellRenderer *cell,
&x_offset, &y_offset,
NULL, NULL);
- gtk_paint_expander (widget->style,
+ g_object_get (cell,
+ "xpad", &xpad,
+ "ypad", &ypad,
+ NULL);
+
+ gtk_paint_expander (gtk_widget_get_style (widget),
window,
GTK_STATE_NORMAL,
expose_area,
widget,
"treeview",
- cell_area->x + x_offset + cell->xpad + priv->expander_size / 2,
- cell_area->y + y_offset + cell->ypad + priv->expander_size / 2,
+ cell_area->x + x_offset + xpad + priv->expander_size / 2,
+ cell_area->y + y_offset + ypad + priv->expander_size / 2,
expander_style);
}
diff --git a/libempathy-gtk/empathy-chat-text-view.c b/libempathy-gtk/empathy-chat-text-view.c
index 5ed7c69c3..d7ebda647 100644
--- a/libempathy-gtk/empathy-chat-text-view.c
+++ b/libempathy-gtk/empathy-chat-text-view.c
@@ -495,7 +495,9 @@ chat_text_view_size_allocate (GtkWidget *widget,
GtkAdjustment *adj;
adj = GTK_TEXT_VIEW (widget)->vadjustment;
- gtk_adjustment_set_value (adj, adj->upper - adj->page_size);
+ gtk_adjustment_set_value (adj,
+ gtk_adjustment_get_upper (adj) -
+ gtk_adjustment_get_page_size (adj));
}
}
@@ -652,7 +654,7 @@ chat_text_view_scroll_cb (EmpathyChatTextView *view)
priv = GET_PRIV (view);
adj = GTK_TEXT_VIEW (view)->vadjustment;
- max_val = adj->upper - adj->page_size;
+ max_val = gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj);
g_return_val_if_fail (priv->scroll_time != NULL, FALSE);
@@ -817,6 +819,10 @@ chat_text_view_clear (EmpathyChatView *view)
priv = GET_PRIV (view);
priv->last_timestamp = 0;
+ if (priv->last_contact) {
+ g_object_unref (priv->last_contact);
+ priv->last_contact = NULL;
+ }
}
static gboolean
diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c
index 1f5225348..a8ca745e2 100644
--- a/libempathy-gtk/empathy-chat.c
+++ b/libempathy-gtk/empathy-chat.c
@@ -748,13 +748,14 @@ chat_input_key_press_event_cb (GtkWidget *widget,
if (!(event->state & GDK_CONTROL_MASK) &&
event->keyval == GDK_Page_Up) {
adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (text_view_sw));
- gtk_adjustment_set_value (adj, adj->value - adj->page_size);
+ gtk_adjustment_set_value (adj, gtk_adjustment_get_value (adj) - gtk_adjustment_get_page_size (adj));
return TRUE;
}
if ((event->state & GDK_CONTROL_MASK) != GDK_CONTROL_MASK &&
event->keyval == GDK_Page_Down) {
adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (text_view_sw));
- val = MIN (adj->value + adj->page_size, adj->upper - adj->page_size);
+ val = MIN (gtk_adjustment_get_value (adj) + gtk_adjustment_get_page_size (adj),
+ gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj));
gtk_adjustment_set_value (adj, val);
return TRUE;
}
@@ -1161,6 +1162,56 @@ chat_contacts_completion_func (const gchar *s1,
return ret;
}
+static gchar *
+build_part_message (guint reason,
+ const gchar *name,
+ EmpathyContact *actor,
+ const gchar *message)
+{
+ GString *s = g_string_new ("");
+ const gchar *actor_name = NULL;
+
+ if (actor != NULL) {
+ actor_name = empathy_contact_get_name (actor);
+ }
+
+ /* Having an actor only really makes sense for a few actions... */
+ switch (reason) {
+ case TP_CHANNEL_GROUP_CHANGE_REASON_OFFLINE:
+ g_string_append_printf (s, _("%s has disconnected"), name);
+ break;
+ case TP_CHANNEL_GROUP_CHANGE_REASON_KICKED:
+ if (actor_name != NULL) {
+ g_string_append_printf (s, _("%s was kicked by %s"),
+ name, actor_name);
+ } else {
+ g_string_append_printf (s, _("%s was kicked"), name);
+ }
+ break;
+ case TP_CHANNEL_GROUP_CHANGE_REASON_BANNED:
+ if (actor_name != NULL) {
+ g_string_append_printf (s, _("%s was banned by %s"),
+ name, actor_name);
+ } else {
+ g_string_append_printf (s, _("%s was banned"), name);
+ }
+ break;
+ default:
+ g_string_append_printf (s, _("%s has left the room"), name);
+ }
+
+ if (!EMP_STR_EMPTY (message)) {
+ /* Note to translators: this string is appended to
+ * notifications like "foo has left the room", with the message
+ * given by the user living the room. If this poses a problem,
+ * please let us know. :-)
+ */
+ g_string_append_printf (s, _(" (%s)"), message);
+ }
+
+ return g_string_free (s, FALSE);
+}
+
static void
chat_members_changed_cb (EmpathyTpChat *tp_chat,
EmpathyContact *contact,
@@ -1171,20 +1222,21 @@ chat_members_changed_cb (EmpathyTpChat *tp_chat,
EmpathyChat *chat)
{
EmpathyChatPriv *priv = GET_PRIV (chat);
+ const gchar *name = empathy_contact_get_name (contact);
+ gchar *str;
- if (priv->block_events_timeout_id == 0) {
- gchar *str;
+ if (priv->block_events_timeout_id != 0)
+ return;
- if (is_member) {
- str = g_strdup_printf (_("%s has joined the room"),
- empathy_contact_get_name (contact));
- } else {
- str = g_strdup_printf (_("%s has left the room"),
- empathy_contact_get_name (contact));
- }
- empathy_chat_view_append_event (chat->view, str);
- g_free (str);
+ if (is_member) {
+ str = g_strdup_printf (_("%s has joined the room"),
+ name);
+ } else {
+ str = build_part_message (reason, name, actor, message);
}
+
+ empathy_chat_view_append_event (chat->view, str);
+ g_free (str);
}
static gboolean
@@ -1427,15 +1479,18 @@ chat_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
GtkBin *bin = GTK_BIN (widget);
+ GtkWidget *child;
+
+ requisition->width = gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2;
+ requisition->height = gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2;
- requisition->width = GTK_CONTAINER (widget)->border_width * 2;
- requisition->height = GTK_CONTAINER (widget)->border_width * 2;
+ child = gtk_bin_get_child (bin);
- if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+ if (child && GTK_WIDGET_VISIBLE (child))
{
GtkRequisition child_requisition;
- gtk_widget_size_request (bin->child, &child_requisition);
+ gtk_widget_size_request (child, &child_requisition);
requisition->width += child_requisition.width;
requisition->height += child_requisition.height;
@@ -1448,17 +1503,20 @@ chat_size_allocate (GtkWidget *widget,
{
GtkBin *bin = GTK_BIN (widget);
GtkAllocation child_allocation;
+ GtkWidget *child;
widget->allocation = *allocation;
- if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+ child = gtk_bin_get_child (bin);
+
+ if (child && GTK_WIDGET_VISIBLE (child))
{
- child_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width;
- child_allocation.y = allocation->y + GTK_CONTAINER (widget)->border_width;
- child_allocation.width = MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0);
- child_allocation.height = MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0);
+ child_allocation.x = allocation->x + gtk_container_get_border_width (GTK_CONTAINER (widget));
+ child_allocation.y = allocation->y + gtk_container_get_border_width (GTK_CONTAINER (widget));
+ child_allocation.width = MAX (allocation->width - gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2, 0);
+ child_allocation.height = MAX (allocation->height - gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2, 0);
- gtk_widget_size_allocate (bin->child, &child_allocation);
+ gtk_widget_size_allocate (child, &child_allocation);
}
}
diff --git a/libempathy-gtk/empathy-contact-dialogs.c b/libempathy-gtk/empathy-contact-dialogs.c
index 5b11ddc2e..fc1cbbc8e 100644
--- a/libempathy-gtk/empathy-contact-dialogs.c
+++ b/libempathy-gtk/empathy-contact-dialogs.c
@@ -191,7 +191,7 @@ empathy_contact_information_dialog_show (EmpathyContact *contact,
EMPATHY_CONTACT_WIDGET_SHOW_LOCATION |
EMPATHY_CONTACT_WIDGET_EDIT_NONE);
gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
contact_widget,
TRUE, TRUE, 0);
gtk_widget_show (contact_widget);
@@ -250,7 +250,7 @@ empathy_contact_edit_dialog_show (EmpathyContact *contact,
EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
EMPATHY_CONTACT_WIDGET_EDIT_GROUPS);
gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
contact_widget,
TRUE, TRUE, 0);
gtk_widget_show (contact_widget);
@@ -302,7 +302,7 @@ empathy_contact_personal_dialog_show (GtkWindow *parent)
EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
EMPATHY_CONTACT_WIDGET_EDIT_AVATAR);
gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (personal_dialog)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (personal_dialog))),
contact_widget,
TRUE, TRUE, 0);
empathy_contact_widget_set_account_filter (contact_widget,
@@ -334,9 +334,11 @@ can_add_contact_to_account (EmpathyAccount *account,
gboolean result;
connection = empathy_account_get_connection (account);
+ if (connection == NULL)
+ return FALSE;
contact_manager = empathy_contact_manager_dup_singleton ();
- result = empathy_contact_manager_can_add (contact_manager, connection);
+ result = empathy_contact_manager_get_flags_for_connection (contact_manager, connection) & EMPATHY_CONTACT_LIST_CAN_ADD;
g_object_unref (contact_manager);
return result;
@@ -366,6 +368,13 @@ new_contact_response_cb (GtkDialog *dialog,
void
empathy_new_contact_dialog_show (GtkWindow *parent)
{
+ empathy_new_contact_dialog_show_with_contact (parent, NULL);
+}
+
+void
+empathy_new_contact_dialog_show_with_contact (GtkWindow *parent,
+ EmpathyContact *contact)
+{
GtkWidget *dialog;
GtkWidget *button;
GtkWidget *contact_widget;
@@ -398,12 +407,12 @@ empathy_new_contact_dialog_show (GtkWindow *parent)
gtk_widget_show (button);
/* Contact info widget */
- contact_widget = empathy_contact_widget_new (NULL,
+ contact_widget = empathy_contact_widget_new (contact,
EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT |
EMPATHY_CONTACT_WIDGET_EDIT_ID |
EMPATHY_CONTACT_WIDGET_EDIT_GROUPS);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
contact_widget,
TRUE, TRUE, 0);
empathy_contact_widget_set_account_filter (contact_widget,
diff --git a/libempathy-gtk/empathy-contact-dialogs.h b/libempathy-gtk/empathy-contact-dialogs.h
index c714c6b96..21aa5ce73 100644
--- a/libempathy-gtk/empathy-contact-dialogs.h
+++ b/libempathy-gtk/empathy-contact-dialogs.h
@@ -35,7 +35,9 @@ void empathy_contact_information_dialog_show (EmpathyContact *contact,
void empathy_contact_edit_dialog_show (EmpathyContact *contact,
GtkWindow *parent);
void empathy_contact_personal_dialog_show (GtkWindow *parent);
-void empathy_new_contact_dialog_show (GtkWindow *parent);
+void empathy_new_contact_dialog_show (GtkWindow *parent);
+void empathy_new_contact_dialog_show_with_contact (GtkWindow *parent,
+ EmpathyContact *contact);
G_END_DECLS
diff --git a/libempathy-gtk/empathy-contact-list-store.c b/libempathy-gtk/empathy-contact-list-store.c
index 0e9372be1..a4c1d7ab9 100644
--- a/libempathy-gtk/empathy-contact-list-store.c
+++ b/libempathy-gtk/empathy-contact-list-store.c
@@ -33,6 +33,9 @@
#include <telepathy-glib/util.h>
#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-enum-types.h>
+#include <libempathy/empathy-contact-manager.h>
+
#include "empathy-contact-list-store.h"
#include "empathy-ui-utils.h"
#include "empathy-gtk-enum-types.h"
@@ -725,19 +728,22 @@ static void
contact_list_store_setup (EmpathyContactListStore *store)
{
EmpathyContactListStorePriv *priv;
- GType types[] = {G_TYPE_STRING, /* Status icon-name */
- GDK_TYPE_PIXBUF, /* Avatar pixbuf */
- G_TYPE_BOOLEAN, /* Avatar pixbuf visible */
- G_TYPE_STRING, /* Name */
- G_TYPE_STRING, /* Status string */
- G_TYPE_BOOLEAN, /* Show status */
- EMPATHY_TYPE_CONTACT, /* Contact type */
- G_TYPE_BOOLEAN, /* Is group */
- G_TYPE_BOOLEAN, /* Is active */
- G_TYPE_BOOLEAN, /* Is online */
- G_TYPE_BOOLEAN, /* Is separator */
- G_TYPE_BOOLEAN, /* Can make audio calls */
- G_TYPE_BOOLEAN}; /* Can make video calls */
+ GType types[] = {
+ G_TYPE_STRING, /* Status icon-name */
+ GDK_TYPE_PIXBUF, /* Avatar pixbuf */
+ G_TYPE_BOOLEAN, /* Avatar pixbuf visible */
+ G_TYPE_STRING, /* Name */
+ G_TYPE_STRING, /* Status string */
+ G_TYPE_BOOLEAN, /* Show status */
+ EMPATHY_TYPE_CONTACT, /* Contact type */
+ G_TYPE_BOOLEAN, /* Is group */
+ G_TYPE_BOOLEAN, /* Is active */
+ G_TYPE_BOOLEAN, /* Is online */
+ G_TYPE_BOOLEAN, /* Is separator */
+ G_TYPE_BOOLEAN, /* Can make audio calls */
+ G_TYPE_BOOLEAN, /* Can make video calls */
+ EMPATHY_TYPE_CONTACT_LIST_FLAGS, /* Flags */
+ };
priv = GET_PRIV (store);
@@ -851,6 +857,8 @@ contact_list_store_add_contact (EmpathyContactListStore *store,
EmpathyContactListStorePriv *priv;
GtkTreeIter iter;
GList *groups = NULL, *l;
+ TpConnection *connection;
+ EmpathyContactListFlags flags;
priv = GET_PRIV (store);
@@ -863,6 +871,14 @@ contact_list_store_add_contact (EmpathyContactListStore *store,
groups = empathy_contact_list_get_groups (priv->list, contact);
}
+ connection = empathy_contact_get_connection (contact);
+ if (EMPATHY_IS_CONTACT_MANAGER (priv->list)) {
+ flags = empathy_contact_manager_get_flags_for_connection (
+ EMPATHY_CONTACT_MANAGER (priv->list), connection);
+ } else {
+ flags = 0;
+ }
+
/* If no groups just add it at the top level. */
if (!groups) {
gtk_tree_store_append (GTK_TREE_STORE (store), &iter, NULL);
@@ -877,6 +893,7 @@ contact_list_store_add_contact (EmpathyContactListStore *store,
EMPATHY_CONTACT_LIST_STORE_COL_CAN_VIDEO_CALL,
empathy_contact_get_capabilities (contact) &
EMPATHY_CAPABILITIES_VIDEO,
+ EMPATHY_CONTACT_LIST_STORE_COL_FLAGS, flags,
-1);
}
@@ -899,6 +916,7 @@ contact_list_store_add_contact (EmpathyContactListStore *store,
EMPATHY_CONTACT_LIST_STORE_COL_CAN_VIDEO_CALL,
empathy_contact_get_capabilities (contact) &
EMPATHY_CAPABILITIES_VIDEO,
+ EMPATHY_CONTACT_LIST_STORE_COL_FLAGS, flags,
-1);
g_free (l->data);
}
diff --git a/libempathy-gtk/empathy-contact-list-store.h b/libempathy-gtk/empathy-contact-list-store.h
index 007a6b069..f97853991 100644
--- a/libempathy-gtk/empathy-contact-list-store.h
+++ b/libempathy-gtk/empathy-contact-list-store.h
@@ -62,6 +62,7 @@ typedef enum {
EMPATHY_CONTACT_LIST_STORE_COL_IS_SEPARATOR,
EMPATHY_CONTACT_LIST_STORE_COL_CAN_AUDIO_CALL,
EMPATHY_CONTACT_LIST_STORE_COL_CAN_VIDEO_CALL,
+ EMPATHY_CONTACT_LIST_STORE_COL_FLAGS,
EMPATHY_CONTACT_LIST_STORE_COL_COUNT
} EmpathyContactListStoreCol;
diff --git a/libempathy-gtk/empathy-contact-list-view.c b/libempathy-gtk/empathy-contact-list-view.c
index f7b506e7c..783d986d0 100644
--- a/libempathy-gtk/empathy-contact-list-view.c
+++ b/libempathy-gtk/empathy-contact-list-view.c
@@ -292,7 +292,7 @@ contact_list_view_drag_data_received (GtkWidget *view,
goto OUT;
}
- id = (const gchar*) selection->data;
+ id = (const gchar*) gtk_selection_data_get_data (selection);
DEBUG ("Received %s%s drag & drop contact from roster with id:'%s'",
context->action == GDK_ACTION_MOVE ? "move" : "",
context->action == GDK_ACTION_COPY ? "copy" : "",
@@ -817,16 +817,20 @@ contact_list_view_text_cell_data_func (GtkTreeViewColumn *tree_column,
gboolean is_group;
gboolean is_active;
gboolean show_status;
+ gchar *name;
gtk_tree_model_get (model, iter,
EMPATHY_CONTACT_LIST_STORE_COL_IS_GROUP, &is_group,
EMPATHY_CONTACT_LIST_STORE_COL_IS_ACTIVE, &is_active,
EMPATHY_CONTACT_LIST_STORE_COL_STATUS_VISIBLE, &show_status,
+ EMPATHY_CONTACT_LIST_STORE_COL_NAME, &name,
-1);
g_object_set (cell,
"show-status", show_status,
+ "text", name,
NULL);
+ g_free (name);
contact_list_view_cell_set_background (view, cell, is_group, is_active);
}
@@ -851,7 +855,7 @@ contact_list_view_expander_cell_data_func (GtkTreeViewColumn *column,
gboolean row_expanded;
path = gtk_tree_model_get_path (model, iter);
- row_expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (column->tree_view), path);
+ row_expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (gtk_tree_view_column_get_tree_view (column)), path);
gtk_tree_path_free (path);
g_object_set (cell,
@@ -1302,6 +1306,31 @@ empathy_contact_list_view_dup_selected (EmpathyContactListView *view)
return contact;
}
+EmpathyContactListFlags
+empathy_contact_list_view_get_flags (EmpathyContactListView *view)
+{
+ EmpathyContactListViewPriv *priv;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ EmpathyContactListFlags flags;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view), 0);
+
+ priv = GET_PRIV (view);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ return 0;
+ }
+
+ gtk_tree_model_get (model, &iter,
+ EMPATHY_CONTACT_LIST_STORE_COL_FLAGS, &flags,
+ -1);
+
+ return flags;
+}
+
gchar *
empathy_contact_list_view_get_selected_group (EmpathyContactListView *view)
{
@@ -1473,6 +1502,7 @@ empathy_contact_list_view_get_contact_menu (EmpathyContactListView *view)
GtkWidget *menu;
GtkWidget *item;
GtkWidget *image;
+ EmpathyContactListFlags flags;
g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view), NULL);
@@ -1480,25 +1510,23 @@ empathy_contact_list_view_get_contact_menu (EmpathyContactListView *view)
if (!contact) {
return NULL;
}
+ flags = empathy_contact_list_view_get_flags (view);
menu = empathy_contact_menu_new (contact, priv->contact_features);
- if (!(priv->list_features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_REMOVE)) {
- g_object_unref (contact);
- return menu;
- }
-
- if (menu) {
- /* Separator */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
- } else {
- menu = gtk_menu_new ();
- }
-
/* Remove contact */
- if (priv->list_features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_REMOVE) {
+ if (priv->list_features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_REMOVE &&
+ flags & EMPATHY_CONTACT_LIST_CAN_REMOVE) {
+ /* create the menu if required, or just add a separator */
+ if (!menu) {
+ menu = gtk_menu_new ();
+ } else {
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+
+ /* Remove */
item = gtk_image_menu_item_new_with_mnemonic (_("_Remove"));
image = gtk_image_new_from_icon_name (GTK_STOCK_REMOVE,
GTK_ICON_SIZE_MENU);
diff --git a/libempathy-gtk/empathy-contact-list-view.h b/libempathy-gtk/empathy-contact-list-view.h
index e9c3457d8..6666cfbb7 100644
--- a/libempathy-gtk/empathy-contact-list-view.h
+++ b/libempathy-gtk/empathy-contact-list-view.h
@@ -71,6 +71,7 @@ EmpathyContactListView * empathy_contact_list_view_new (Empathy
EmpathyContactListFeatureFlags list_features,
EmpathyContactFeatureFlags contact_features);
EmpathyContact * empathy_contact_list_view_dup_selected (EmpathyContactListView *view);
+EmpathyContactListFlags empathy_contact_list_view_get_flags (EmpathyContactListView *view);
gchar * empathy_contact_list_view_get_selected_group (EmpathyContactListView *view);
GtkWidget * empathy_contact_list_view_get_contact_menu (EmpathyContactListView *view);
GtkWidget * empathy_contact_list_view_get_group_menu (EmpathyContactListView *view);
diff --git a/libempathy-gtk/empathy-contact-menu.c b/libempathy-gtk/empathy-contact-menu.c
index 2bad5c9fe..070d91267 100644
--- a/libempathy-gtk/empathy-contact-menu.c
+++ b/libempathy-gtk/empathy-contact-menu.c
@@ -28,15 +28,18 @@
#include <libempathy/empathy-call-factory.h>
#include <libempathy/empathy-log-manager.h>
+#include <libempathy/empathy-contact-manager.h>
#include <libempathy/empathy-dispatcher.h>
#include <libempathy/empathy-utils.h>
#include <libempathy/empathy-chatroom-manager.h>
+#include <libempathy/empathy-contact-manager.h>
#include "empathy-contact-menu.h"
#include "empathy-images.h"
#include "empathy-log-window.h"
#include "empathy-contact-dialogs.h"
#include "empathy-ui-utils.h"
+#include "empathy-share-my-desktop.h"
GtkWidget *
empathy_contact_menu_new (EmpathyContact *contact,
@@ -55,6 +58,13 @@ empathy_contact_menu_new (EmpathyContact *contact,
menu = gtk_menu_new ();
shell = GTK_MENU_SHELL (menu);
+ /* Add Contact */
+ item = empathy_contact_add_menu_item_new (contact);
+ if (item) {
+ gtk_menu_shell_append (shell, item);
+ gtk_widget_show (item);
+ }
+
/* Chat */
if (features & EMPATHY_CONTACT_FEATURE_CHAT) {
item = empathy_contact_chat_menu_item_new (contact);
@@ -91,6 +101,13 @@ empathy_contact_menu_new (EmpathyContact *contact,
gtk_menu_shell_append (shell, item);
gtk_widget_show (item);
+ /* Share my desktop */
+ /* FIXME we should add the "Share my desktop" menu item if Vino is
+ a registered handler in MC5 */
+ item = empathy_contact_share_my_desktop_menu_item_new (contact);
+ gtk_menu_shell_append (shell, item);
+ gtk_widget_show (item);
+
/* Separator */
if (features & (EMPATHY_CONTACT_FEATURE_EDIT |
EMPATHY_CONTACT_FEATURE_INFO)) {
@@ -117,13 +134,83 @@ empathy_contact_menu_new (EmpathyContact *contact,
}
static void
+empathy_contact_add_menu_item_activated (GtkMenuItem *item,
+ EmpathyContact *contact)
+{
+ GtkWidget *toplevel;
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item));
+ if (!GTK_WIDGET_TOPLEVEL (toplevel) || !GTK_IS_WINDOW (toplevel)) {
+ toplevel = NULL;
+ }
+
+ empathy_new_contact_dialog_show_with_contact (GTK_WINDOW (toplevel),
+ contact);
+}
+
+GtkWidget *
+empathy_contact_add_menu_item_new (EmpathyContact *contact)
+{
+ GtkWidget *item;
+ GtkWidget *image;
+ EmpathyContactManager *manager;
+ TpConnection *connection;
+ GList *l, *members;
+ gboolean found = FALSE;
+ EmpathyContactListFlags flags;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+ if (!empathy_contact_manager_initialized ()) {
+ return NULL;
+ }
+
+ manager = empathy_contact_manager_dup_singleton ();
+ connection = empathy_contact_get_connection (contact);
+
+ flags = empathy_contact_manager_get_flags_for_connection (manager,
+ connection);
+
+ if (!(flags & EMPATHY_CONTACT_LIST_CAN_ADD)) {
+ return NULL;
+ }
+
+ members = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST (manager));
+ for (l = members; l; l = l->next) {
+ if (!found && empathy_contact_equal (l->data, contact)) {
+ found = TRUE;
+ /* we keep iterating so that we don't leak contact
+ * refs */
+ }
+
+ g_object_unref (l->data);
+ }
+ g_list_free (members);
+ g_object_unref (manager);
+
+ if (found) {
+ return NULL;
+ }
+
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Add Contact..."));
+ image = gtk_image_new_from_icon_name (GTK_STOCK_ADD,
+ GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+
+ g_signal_connect (item, "activate",
+ G_CALLBACK (empathy_contact_add_menu_item_activated),
+ contact);
+
+ return item;
+}
+
+static void
empathy_contact_chat_menu_item_activated (GtkMenuItem *item,
EmpathyContact *contact)
{
empathy_dispatcher_chat_with_contact (contact, NULL, NULL);
}
-
GtkWidget *
empathy_contact_chat_menu_item_new (EmpathyContact *contact)
{
@@ -167,7 +254,7 @@ empathy_contact_audio_call_menu_item_new (EmpathyContact *contact)
image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_VOIP,
GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- gtk_widget_set_sensitive (item, empathy_contact_can_voip (contact));
+ gtk_widget_set_sensitive (item, empathy_contact_can_voip_audio (contact));
gtk_widget_show (image);
g_signal_connect (item, "activate",
@@ -199,7 +286,7 @@ empathy_contact_video_call_menu_item_new (EmpathyContact *contact)
image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_VIDEO_CALL,
GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- gtk_widget_set_sensitive (item, empathy_contact_can_voip (contact));
+ gtk_widget_set_sensitive (item, empathy_contact_can_voip_video (contact));
gtk_widget_show (image);
g_signal_connect (item, "activate",
@@ -270,6 +357,29 @@ empathy_contact_file_transfer_menu_item_new (EmpathyContact *contact)
return item;
}
+/* FIXME we should check if the contact supports vnc stream tube */
+GtkWidget *
+empathy_contact_share_my_desktop_menu_item_new (EmpathyContact *contact)
+{
+ GtkWidget *item;
+ GtkWidget *image;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+ item = gtk_image_menu_item_new_with_mnemonic (_("Share my desktop"));
+ image = gtk_image_new_from_icon_name (GTK_STOCK_NETWORK,
+ GTK_ICON_SIZE_MENU);
+ gtk_widget_set_sensitive (item, empathy_contact_can_use_stream_tube (contact));
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+ gtk_widget_show (image);
+
+ g_signal_connect_swapped (item, "activate",
+ G_CALLBACK (empathy_share_my_desktop_share_with_contact),
+ contact);
+
+ return item;
+}
+
static void
contact_info_menu_item_activate_cb (EmpathyContact *contact)
{
@@ -306,17 +416,36 @@ contact_edit_menu_item_activate_cb (EmpathyContact *contact)
GtkWidget *
empathy_contact_edit_menu_item_new (EmpathyContact *contact)
{
+ EmpathyContactManager *manager;
GtkWidget *item;
GtkWidget *image;
+ gboolean enable = FALSE;
g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+ if (empathy_contact_manager_initialized ()) {
+ TpConnection *connection;
+ EmpathyContactListFlags flags;
+
+ manager = empathy_contact_manager_dup_singleton ();
+ connection = empathy_contact_get_connection (contact);
+ flags = empathy_contact_manager_get_flags_for_connection (
+ manager, connection);
+
+ enable = (flags & EMPATHY_CONTACT_LIST_CAN_ALIAS ||
+ flags & EMPATHY_CONTACT_LIST_CAN_GROUP);
+
+ g_object_unref (manager);
+ }
+
item = gtk_image_menu_item_new_with_mnemonic (_("_Edit"));
image = gtk_image_new_from_icon_name (GTK_STOCK_EDIT,
GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
gtk_widget_show (image);
+ gtk_widget_set_sensitive (item, enable);
+
g_signal_connect_swapped (item, "activate",
G_CALLBACK (contact_edit_menu_item_activate_cb),
contact);
diff --git a/libempathy-gtk/empathy-contact-menu.h b/libempathy-gtk/empathy-contact-menu.h
index 262ec9650..2c623e6ba 100644
--- a/libempathy-gtk/empathy-contact-menu.h
+++ b/libempathy-gtk/empathy-contact-menu.h
@@ -40,6 +40,7 @@ typedef enum {
GtkWidget * empathy_contact_menu_new (EmpathyContact *contact,
EmpathyContactFeatureFlags features);
+GtkWidget * empathy_contact_add_menu_item_new (EmpathyContact *contact);
GtkWidget * empathy_contact_chat_menu_item_new (EmpathyContact *contact);
GtkWidget * empathy_contact_audio_call_menu_item_new (EmpathyContact *contact);
GtkWidget * empathy_contact_video_call_menu_item_new (EmpathyContact *contact);
@@ -48,6 +49,7 @@ GtkWidget * empathy_contact_info_menu_item_new (EmpathyContact *cont
GtkWidget * empathy_contact_edit_menu_item_new (EmpathyContact *contact);
GtkWidget * empathy_contact_invite_menu_item_new (EmpathyContact *contact);
GtkWidget * empathy_contact_file_transfer_menu_item_new (EmpathyContact *contact);
+GtkWidget * empathy_contact_share_my_desktop_menu_item_new (EmpathyContact *contact);
G_END_DECLS
diff --git a/libempathy-gtk/empathy-contact-widget.c b/libempathy-gtk/empathy-contact-widget.c
index 7e80d0d65..a9a673c43 100644
--- a/libempathy-gtk/empathy-contact-widget.c
+++ b/libempathy-gtk/empathy-contact-widget.c
@@ -47,6 +47,7 @@
#include "empathy-avatar-chooser.h"
#include "empathy-avatar-image.h"
#include "empathy-ui-utils.h"
+#include "empathy-kludge-label.h"
#define DEBUG_FLAG EMPATHY_DEBUG_CONTACT
#include <libempathy/empathy-debug.h>
@@ -219,7 +220,6 @@ empathy_contact_widget_new (EmpathyContact *contact,
"hbox_presence", &information->hbox_presence,
"label_alias", &information->label_alias,
"image_state", &information->image_state,
- "label_status", &information->label_status,
"table_contact", &information->table_contact,
"vbox_avatar", &information->vbox_avatar,
"vbox_location", &information->vbox_location,
@@ -400,6 +400,13 @@ contact_widget_set_contact (EmpathyContactWidget *information,
information->factory = empathy_tp_contact_factory_dup_singleton (connection);
}
+ /* set the selected account to be the account this contact came from */
+ if (contact && EMPATHY_IS_ACCOUNT_CHOOSER (information->widget_account)) {
+ empathy_account_chooser_set_account (
+ EMPATHY_ACCOUNT_CHOOSER (information->widget_account),
+ empathy_contact_get_account (contact));
+ }
+
/* Update information for widgets */
contact_widget_contact_update (information);
contact_widget_groups_update (information);
@@ -587,6 +594,12 @@ update_avatar_chooser_account_cb (EmpathyAccountChooser *account_chooser,
static void
contact_widget_contact_setup (EmpathyContactWidget *information)
{
+ /* Setup label_status as a KludgeLabel */
+ information->label_status = empathy_kludge_label_new ("");
+ gtk_box_pack_start (GTK_BOX (information->hbox_presence),
+ information->label_status, TRUE, TRUE, 0);
+ gtk_widget_show (information->label_status);
+
/* Setup account label/chooser */
if (information->flags & EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT)
{
diff --git a/libempathy-gtk/empathy-contact-widget.ui b/libempathy-gtk/empathy-contact-widget.ui
index c5bbd5bbe..5737b7d71 100644
--- a/libempathy-gtk/empathy-contact-widget.ui
+++ b/libempathy-gtk/empathy-contact-widget.ui
@@ -112,17 +112,7 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="label_status">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="xalign">0</property>
- <property name="use_markup">True</property>
- <property name="wrap">True</property>
- <property name="selectable">True</property>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
+ <placeholder/>
</child>
</object>
<packing>
diff --git a/libempathy-gtk/empathy-geometry.c b/libempathy-gtk/empathy-geometry.c
index 882e15aa9..14e794c44 100644
--- a/libempathy-gtk/empathy-geometry.c
+++ b/libempathy-gtk/empathy-geometry.c
@@ -49,7 +49,7 @@ geometry_get_filename (void)
gchar *dir;
gchar *filename;
- dir = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, NULL);
+ dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
if (!g_file_test (dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
DEBUG ("Creating directory:'%s'", dir);
g_mkdir_with_parents (dir, GEOMETRY_DIR_CREATE_MODE);
@@ -77,9 +77,13 @@ empathy_geometry_save (const gchar *name,
gchar *content;
gsize length;
gchar *str;
+ gchar *escaped_name;
- DEBUG ("Saving window geometry: x:%d, y:%d, w:%d, h:%d\n",
- x, y, w, h);
+ /* escape the name so that unwanted characters such as # are removed */
+ escaped_name = g_uri_escape_string (name, NULL, TRUE);
+
+ DEBUG ("Saving window geometry: name:%s x:%d, y:%d, w:%d, h:%d\n",
+ escaped_name, x, y, w, h);
screen = gdk_screen_get_default ();
max_width = gdk_screen_get_width (screen);
@@ -98,7 +102,7 @@ empathy_geometry_save (const gchar *name,
filename = geometry_get_filename ();
g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL);
- g_key_file_set_string (key_file, GEOMETRY_GROUP_NAME, name, str);
+ g_key_file_set_string (key_file, GEOMETRY_GROUP_NAME, escaped_name, str);
g_free (str);
@@ -111,6 +115,7 @@ empathy_geometry_save (const gchar *name,
g_free (content);
g_free (filename);
+ g_free (escaped_name);
g_key_file_free (key_file);
}
@@ -124,6 +129,10 @@ empathy_geometry_load (const gchar *name,
GKeyFile *key_file;
gchar *filename;
gchar *str = NULL;
+ gchar *escaped_name;
+
+ /* escape the name so that unwanted characters such as # are removed */
+ escaped_name = g_uri_escape_string (name, NULL, TRUE);
if (x) {
*x = -1;
@@ -146,7 +155,7 @@ empathy_geometry_load (const gchar *name,
filename = geometry_get_filename ();
if (g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL)) {
- str = g_key_file_get_string (key_file, GEOMETRY_GROUP_NAME, name, NULL);
+ str = g_key_file_get_string (key_file, GEOMETRY_GROUP_NAME, escaped_name, NULL);
}
if (str) {
@@ -177,6 +186,7 @@ empathy_geometry_load (const gchar *name,
x ? *x : -1, y ? *y : -1, w ? *w : -1, h ? *h : -1);
g_free (filename);
+ g_free (escaped_name);
g_key_file_free (key_file);
}
diff --git a/libempathy-gtk/empathy-kludge-label.c b/libempathy-gtk/empathy-kludge-label.c
new file mode 100644
index 000000000..f4a29dec2
--- /dev/null
+++ b/libempathy-gtk/empathy-kludge-label.c
@@ -0,0 +1,89 @@
+/* vim: set ts=4 sts=4 sw=4 et: */
+/*
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Davyd Madeley <davyd.madeley@collabora.co.uk>
+ */
+
+#include "empathy-kludge-label.h"
+
+G_DEFINE_TYPE (EmpathyKludgeLabel, empathy_kludge_label, GTK_TYPE_LABEL);
+
+static void
+empathy_kludge_label_size_allocate (GtkWidget *self,
+ GtkAllocation *allocation)
+{
+ PangoLayout *layout;
+
+ GTK_WIDGET_CLASS (empathy_kludge_label_parent_class)->size_allocate (
+ self, allocation);
+
+ /* force the width of the PangoLayout to be the width of the allocation */
+ layout = gtk_label_get_layout (GTK_LABEL (self));
+ pango_layout_set_width (layout, allocation->width * PANGO_SCALE);
+}
+
+static gboolean
+empathy_kludge_label_expose_event (GtkWidget *self,
+ GdkEventExpose *event)
+{
+ PangoLayout *layout;
+ PangoRectangle rect;
+ GtkAllocation real_allocation;
+ gboolean r;
+
+ layout = gtk_label_get_layout (GTK_LABEL (self));
+ pango_layout_get_pixel_extents (layout, NULL, &rect);
+
+ /* this is mind-bendingly evil:
+ * get_layout_location() is going to remove rect.x from the position of the
+ * layout when painting it. This really sucks. We're going to compensate by
+ * adding this value to the allocation.
+ */
+ real_allocation = self->allocation;
+ self->allocation.x += rect.x;
+
+ r = GTK_WIDGET_CLASS (empathy_kludge_label_parent_class)->expose_event (
+ self, event);
+
+ self->allocation = real_allocation;
+
+ return r;
+}
+
+static void
+empathy_kludge_label_class_init (EmpathyKludgeLabelClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ widget_class->size_allocate = empathy_kludge_label_size_allocate;
+ widget_class->expose_event = empathy_kludge_label_expose_event;
+}
+
+static void
+empathy_kludge_label_init (EmpathyKludgeLabel *self)
+{
+}
+
+GtkWidget *
+empathy_kludge_label_new (const char *str)
+{
+ return g_object_new (EMPATHY_TYPE_KLUDGE_LABEL,
+ "label", str,
+ "xalign", 0.,
+ NULL);
+}
diff --git a/libempathy-gtk/empathy-kludge-label.h b/libempathy-gtk/empathy-kludge-label.h
new file mode 100644
index 000000000..f2ea1e938
--- /dev/null
+++ b/libempathy-gtk/empathy-kludge-label.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Davyd Madeley <davyd.madeley@collabora.co.uk>
+ */
+
+#ifndef __EMPATHY_KLUDGE_LABEL_H__
+#define __EMPATHY_KLUDGE_LABEL_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_KLUDGE_LABEL (empathy_kludge_label_get_type ())
+#define EMPATHY_KLUDGE_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMPATHY_TYPE_KLUDGE_LABEL, EmpathyKludgeLabel))
+#define EMPATHY_KLUDGE_LABEL_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), EMPATHY_TYPE_KLUDGE_LABEL, EmpathyKludgeLabelClass))
+#define EMPATHY_IS_KLUDGE_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMPATHY_TYPE_KLUDGE_LABEL))
+#define EMPATHY_IS_KLUDGE_LABEL_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), EMPATHY_TYPE_KLUDGE_LABEL))
+#define EMPATHY_KLUDGE_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_KLUDGE_LABEL, EmpathyKludgeLabelClass))
+
+typedef struct _EmpathyKludgeLabel EmpathyKludgeLabel;
+typedef struct _EmpathyKludgeLabelClass EmpathyKludgeLabelClass;
+
+struct _EmpathyKludgeLabel
+{
+ GtkLabel parent;
+};
+
+struct _EmpathyKludgeLabelClass
+{
+ GtkLabelClass parent_class;
+};
+
+GType empathy_kludge_label_get_type (void);
+GtkWidget *empathy_kludge_label_new (const char *str);
+
+G_END_DECLS
+
+#endif
diff --git a/libempathy-gtk/empathy-new-message-dialog.ui b/libempathy-gtk/empathy-new-message-dialog.ui
index e24095fba..a7b43818c 100644
--- a/libempathy-gtk/empathy-new-message-dialog.ui
+++ b/libempathy-gtk/empathy-new-message-dialog.ui
@@ -1,6 +1,14 @@
<?xml version="1.0"?>
<!--*- mode: xml -*-->
<interface>
+ <object class="GtkImage" id="call_image">
+ <property name="icon_name">audio-input-microphone</property>
+ <property name="icon-size">4</property>
+ </object>
+ <object class="GtkImage" id="chat_image">
+ <property name="icon_name">im-message-new</property>
+ <property name="icon-size">4</property>
+ </object>
<object class="GtkDialog" id="new_message_dialog">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">5</property>
@@ -82,41 +90,9 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
- <child>
- <object class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="spacing">2</property>
- <child>
- <object class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="icon_name">audio-input-microphone</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes">C_all</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
+ <property name="image">call_image</property>
+ <property name="label" translatable="yes">C_all</property>
+ <property name="use_underline">True</property>
</object>
<packing>
<property name="position">1</property>
@@ -128,41 +104,9 @@
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
- <child>
- <object class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkHBox" id="hbox2">
- <property name="visible">True</property>
- <property name="spacing">2</property>
- <child>
- <object class="GtkImage" id="image2">
- <property name="visible">True</property>
- <property name="icon_name">im-message-new</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="label" translatable="yes">C_hat</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
+ <property name="image">chat_image</property>
+ <property name="label" translatable="yes">C_hat</property>
+ <property name="use_underline">True</property>
</object>
<packing>
<property name="position">2</property>
diff --git a/libempathy-gtk/empathy-presence-chooser.c b/libempathy-gtk/empathy-presence-chooser.c
index 8fba26ff7..69b031c05 100644
--- a/libempathy-gtk/empathy-presence-chooser.c
+++ b/libempathy-gtk/empathy-presence-chooser.c
@@ -79,9 +79,9 @@ enum {
/* For combobox's model */
enum {
+ COL_STATUS_TEXT,
COL_STATE_ICON_NAME,
COL_STATE,
- COL_STATUS_TEXT,
COL_DISPLAY_MARKUP,
COL_STATUS_CUSTOMISABLE,
COL_TYPE,
@@ -162,9 +162,9 @@ presence_chooser_create_model (EmpathyPresenceChooser *self)
int i;
store = gtk_list_store_new (N_COLUMNS,
+ G_TYPE_STRING, /* COL_STATUS_TEXT */
G_TYPE_STRING, /* COL_STATE_ICON_NAME */
G_TYPE_UINT, /* COL_STATE */
- G_TYPE_STRING, /* COL_STATUS_TEXT */
G_TYPE_STRING, /* COL_DISPLAY_MARKUP */
G_TYPE_BOOLEAN, /* COL_STATUS_CUSTOMISABLE */
G_TYPE_INT); /* COL_TYPE */
@@ -179,9 +179,9 @@ presence_chooser_create_model (EmpathyPresenceChooser *self)
icon_name = empathy_icon_name_for_presence (states[i].state);
gtk_list_store_insert_with_values (store, NULL, -1,
+ COL_STATUS_TEXT, status,
COL_STATE_ICON_NAME, icon_name,
COL_STATE, states[i].state,
- COL_STATUS_TEXT, status,
COL_DISPLAY_MARKUP, status,
COL_STATUS_CUSTOMISABLE, states[i].customisable,
COL_TYPE, ENTRY_TYPE_BUILTIN,
@@ -194,9 +194,9 @@ presence_chooser_create_model (EmpathyPresenceChooser *self)
for (l = list; l; l = l->next) {
gtk_list_store_insert_with_values (store,
NULL, -1,
+ COL_STATUS_TEXT, l->data,
COL_STATE_ICON_NAME, icon_name,
COL_STATE, states[i].state,
- COL_STATUS_TEXT, l->data,
COL_DISPLAY_MARKUP, l->data,
COL_STATUS_CUSTOMISABLE, TRUE,
COL_TYPE, ENTRY_TYPE_SAVED,
@@ -205,9 +205,9 @@ presence_chooser_create_model (EmpathyPresenceChooser *self)
g_list_free (list);
gtk_list_store_insert_with_values (store, NULL, -1,
+ COL_STATUS_TEXT, _("Custom Message..."),
COL_STATE_ICON_NAME, icon_name,
COL_STATE, states[i].state,
- COL_STATUS_TEXT, "",
COL_DISPLAY_MARKUP, custom_message,
COL_STATUS_CUSTOMISABLE, TRUE,
COL_TYPE, ENTRY_TYPE_CUSTOM,
@@ -222,8 +222,8 @@ presence_chooser_create_model (EmpathyPresenceChooser *self)
-1);
gtk_list_store_insert_with_values (store, NULL, -1,
+ COL_STATUS_TEXT, _("Edit Custom Messages..."),
COL_STATE_ICON_NAME, GTK_STOCK_EDIT,
- COL_STATUS_TEXT, "",
COL_DISPLAY_MARKUP, _("Edit Custom Messages..."),
COL_TYPE, ENTRY_TYPE_EDIT_CUSTOM,
-1);
diff --git a/libempathy-gtk/empathy-share-my-desktop.c b/libempathy-gtk/empathy-share-my-desktop.c
new file mode 100644
index 000000000..4a5fce916
--- /dev/null
+++ b/libempathy-gtk/empathy-share-my-desktop.c
@@ -0,0 +1,245 @@
+/*
+ * © 2009, Collabora Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Arnaud Maillet <arnaud.maillet@collabora.co.uk>
+ */
+
+#include <gtk/gtk.h>
+
+#include <dbus/dbus-glib.h>
+#include <telepathy-glib/util.h>
+#include <telepathy-glib/contact.h>
+#define DEBUG_FLAG EMPATHY_DEBUG_SHARE_DESKTOP
+#include <libempathy/empathy-debug.h>
+
+#include "empathy-share-my-desktop.h"
+
+#define DBUS_SERVICE "org.gnome.Vino"
+#define DBUS_INTERFACE "org.gnome.VinoScreen"
+
+typedef struct {
+ TpContact *contact;
+ TpChannel *channel;
+ gulong signal_invalidated_id;
+} EmpathyShareMyDesktopPrivate;
+
+
+static void
+empathy_share_my_desktop_tube_invalidated (TpProxy *channel,
+ guint domain,
+ gint code,
+ gchar *message,
+ gpointer object)
+{
+ EmpathyShareMyDesktopPrivate *data = (EmpathyShareMyDesktopPrivate *) object;
+
+ DEBUG ("Tube is invalidated");
+
+ g_signal_handler_disconnect (G_OBJECT (data->channel),
+ data->signal_invalidated_id);
+
+ if (data->channel != NULL)
+ {
+ g_object_unref (data->channel);
+ data->channel = NULL;
+ }
+
+ g_slice_free (EmpathyShareMyDesktopPrivate, data);
+}
+
+static void
+empathy_share_my_desktop_channel_ready (TpChannel *channel,
+ const GError *error_failed,
+ gpointer object)
+{
+ EmpathyShareMyDesktopPrivate *data = (EmpathyShareMyDesktopPrivate *) object;
+ TpConnection *connection;
+ gchar * connection_path;
+ gchar * tube_path;
+ DBusGConnection *dbus_g_connection;
+ GHashTable *channel_properties;
+ DBusGProxy *proxy;
+ GError *error = NULL;
+ GdkScreen *screen;
+ gchar *obj_path;
+ GtkWidget *window;
+
+ if (channel == NULL)
+ {
+ DEBUG ("The channel is not ready: %s", error_failed->message);
+ return;
+ }
+
+ data->channel = channel;
+
+ data->signal_invalidated_id = g_signal_connect (G_OBJECT (channel),
+ "invalidated", G_CALLBACK (empathy_share_my_desktop_tube_invalidated),
+ data);
+
+ dbus_g_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+ if (dbus_g_connection == NULL)
+ {
+ DEBUG ("Failed to open connection to bus: %s", error->message);
+ g_clear_error (&error);
+ return;
+ }
+
+ screen = gdk_screen_get_default ();
+ obj_path = g_strdup_printf ("/org/gnome/vino/screens/%d",
+ gdk_screen_get_number (screen));
+
+ proxy = dbus_g_proxy_new_for_name (dbus_g_connection, DBUS_SERVICE,
+ obj_path, DBUS_INTERFACE);
+
+ connection = tp_channel_borrow_connection (channel);
+
+ g_object_get (connection, "object-path", &connection_path, NULL);
+
+ DEBUG ("connection path : %s", connection_path);
+
+ g_object_get (channel, "object-path", &tube_path, "channel-properties",
+ &channel_properties, NULL);
+
+ DEBUG ("tube path : %s", tube_path);
+
+ if (!dbus_g_proxy_call (proxy, "ShareWithTube", &error,
+ DBUS_TYPE_G_OBJECT_PATH, connection_path,
+ DBUS_TYPE_G_OBJECT_PATH, tube_path,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ channel_properties,
+ G_TYPE_INVALID, G_TYPE_INVALID))
+ {
+ window = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+ "Vino doesn't support telepathy");
+ gtk_dialog_run (GTK_DIALOG (window));
+ gtk_widget_destroy (window);
+ DEBUG ("Failed to request name: %s",
+ error ? error->message : "No error given");
+ g_clear_error (&error);
+ }
+
+ g_hash_table_unref (channel_properties);
+ g_free (connection_path);
+ g_free (tube_path);
+ g_free (obj_path);
+ g_object_unref (proxy);
+}
+
+static void
+empathy_share_my_desktop_create_channel_cb (TpConnection *connection,
+ const gchar *object_path,
+ GHashTable *channel_properties,
+ const GError *error_failed,
+ gpointer user_data,
+ GObject *object)
+{
+ EmpathyShareMyDesktopPrivate *data = (EmpathyShareMyDesktopPrivate *)
+ user_data;
+
+ TpChannel *channel;
+ GError *error = NULL;
+
+ if (object_path == NULL)
+ {
+ DEBUG ("CreateChannel failed: %s", error_failed->message);
+ return;
+ }
+
+ DEBUG ("Offering a new stream tube");
+
+ channel = tp_channel_new_from_properties (connection, object_path,
+ channel_properties, &error);
+
+ if (channel == NULL)
+ {
+ DEBUG ("Error requesting channel: %s", error->message);
+ g_clear_error (&error);
+ return;
+ }
+
+ tp_channel_call_when_ready (channel,
+ empathy_share_my_desktop_channel_ready, data);
+}
+
+static void
+empathy_share_my_desktop_connection_ready (TpConnection *connection,
+ const GError *error,
+ gpointer object)
+{
+ EmpathyShareMyDesktopPrivate *data = (EmpathyShareMyDesktopPrivate *) object;
+ GHashTable *request;
+ GValue *value;
+
+ if (connection == NULL)
+ {
+ DEBUG ("The connection is not ready: %s", error->message);
+ return;
+ }
+
+ request = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) tp_g_value_slice_free);
+
+ /* org.freedesktop.Telepathy.Channel.ChannelType */
+ value = tp_g_value_slice_new_static_string
+ (TP_IFACE_CHANNEL_TYPE_STREAM_TUBE);
+ g_hash_table_insert (request, TP_IFACE_CHANNEL ".ChannelType", value);
+
+ /* org.freedesktop.Telepathy.Channel.TargetHandleType */
+ value = tp_g_value_slice_new_uint (TP_HANDLE_TYPE_CONTACT);
+ g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandleType", value);
+
+ /* org.freedesktop.Telepathy.Channel.TargetHandleType */
+ value = tp_g_value_slice_new_uint (tp_contact_get_handle
+ (data->contact));
+ g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandle", value);
+
+ /* org.freedesktop.Telepathy.Channel.Type.StreamTube.Service */
+ value = tp_g_value_slice_new_static_string ("x_vnc");
+ g_hash_table_insert (request,
+ TP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service",
+ value);
+
+ tp_cli_connection_interface_requests_call_create_channel
+ (connection, -1, request, empathy_share_my_desktop_create_channel_cb,
+ data, NULL, NULL);
+
+ g_hash_table_destroy (request);
+}
+
+void
+empathy_share_my_desktop_share_with_contact (EmpathyContact *contact)
+{
+ TpConnection *connection;
+ EmpathyShareMyDesktopPrivate *data;
+ data = g_slice_new (EmpathyShareMyDesktopPrivate);
+ data->contact = empathy_contact_get_tp_contact (contact);
+
+ DEBUG ("Creation of ShareMyDesktop");
+
+ if (!TP_IS_CONTACT (data->contact))
+ {
+ DEBUG ("It's not a tp contact");
+ return;
+ }
+
+ connection = tp_contact_get_connection (data->contact);
+
+ tp_connection_call_when_ready (connection,
+ empathy_share_my_desktop_connection_ready, data);
+}
diff --git a/libempathy-gtk/empathy-share-my-desktop.h b/libempathy-gtk/empathy-share-my-desktop.h
new file mode 100644
index 000000000..3efeecc14
--- /dev/null
+++ b/libempathy-gtk/empathy-share-my-desktop.h
@@ -0,0 +1,28 @@
+/*
+ * © 2009, Collabora Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Arnaud Maillet <arnaud.maillet@collabora.co.uk>
+ */
+
+#ifndef __EMPATHY_SHARE_MY_DESKTOP_H__
+#define __EMPATHY_SHARE_MY_DESKTOP_H__
+
+#include <libempathy/empathy-contact.h>
+
+void empathy_share_my_desktop_share_with_contact (EmpathyContact *contact);
+
+#endif \ No newline at end of file
diff --git a/libempathy-gtk/empathy-status-preset-dialog.c b/libempathy-gtk/empathy-status-preset-dialog.c
index 7ac13ad38..802d116e7 100644
--- a/libempathy-gtk/empathy-status-preset-dialog.c
+++ b/libempathy-gtk/empathy-status-preset-dialog.c
@@ -559,8 +559,8 @@ empathy_status_preset_dialog_init (EmpathyStatusPresetDialog *self)
status_preset_dialog_setup_presets_treeview (self);
status_preset_dialog_setup_add_combobox (self);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (self)->vbox), toplevel_vbox,
- TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))),
+ toplevel_vbox, TRUE, TRUE, 0);
g_object_unref (gui);
}
diff --git a/libempathy-gtk/empathy-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c
index 0cc2c034d..e04771597 100644
--- a/libempathy-gtk/empathy-theme-adium.c
+++ b/libempathy-gtk/empathy-theme-adium.c
@@ -51,8 +51,12 @@ typedef struct {
EmpathySmileyManager *smiley_manager;
EmpathyContact *last_contact;
time_t last_timestamp;
+ gboolean last_is_backlog;
gboolean page_loaded;
GList *message_queue;
+ gchar *hovered_uri;
+ guint notify_enable_webkit_developer_tools_id;
+ GtkWidget *inspector_window;
} EmpathyThemeAdiumPriv;
struct _EmpathyAdiumData {
@@ -65,12 +69,20 @@ struct _EmpathyAdiumData {
gchar *template_html;
gchar *in_content_html;
gsize in_content_len;
+ gchar *in_context_html;
+ gsize in_context_len;
gchar *in_nextcontent_html;
gsize in_nextcontent_len;
+ gchar *in_nextcontext_html;
+ gsize in_nextcontext_len;
gchar *out_content_html;
gsize out_content_len;
+ gchar *out_context_html;
+ gsize out_context_len;
gchar *out_nextcontent_html;
gsize out_nextcontent_len;
+ gchar *out_nextcontext_html;
+ gsize out_nextcontext_len;
gchar *status_html;
gsize status_len;
GHashTable *info;
@@ -88,6 +100,31 @@ G_DEFINE_TYPE_WITH_CODE (EmpathyThemeAdium, empathy_theme_adium,
G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CHAT_VIEW,
theme_adium_iface_init));
+static void
+theme_adium_update_enable_webkit_developer_tools (EmpathyThemeAdium *theme)
+{
+ WebKitWebView *web_view = WEBKIT_WEB_VIEW (theme);
+ gboolean enable_webkit_developer_tools;
+
+ if (empathy_conf_get_bool (empathy_conf_get (), "/apps/empathy/conversation/enable_webkit_developer_tools", &enable_webkit_developer_tools) == FALSE)
+ return;
+
+ g_object_set (G_OBJECT (webkit_web_view_get_settings (web_view)),
+ "enable-developer-extras",
+ enable_webkit_developer_tools,
+ NULL);
+}
+
+static void
+theme_adium_notify_enable_webkit_developer_tools_cb (EmpathyConf *conf,
+ const gchar *key,
+ gpointer user_data)
+{
+ EmpathyThemeAdium *theme = user_data;
+
+ theme_adium_update_enable_webkit_developer_tools (theme);
+}
+
static WebKitNavigationResponse
theme_adium_navigation_requested_cb (WebKitWebView *view,
WebKitWebFrame *frame,
@@ -103,15 +140,81 @@ theme_adium_navigation_requested_cb (WebKitWebView *view,
}
static void
+theme_adium_hovering_over_link_cb (EmpathyThemeAdium *theme,
+ gchar *title,
+ gchar *uri,
+ gpointer user_data)
+{
+ EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+
+ if (tp_strdiff (uri, priv->hovered_uri)) {
+ g_free (priv->hovered_uri);
+ priv->hovered_uri = g_strdup (uri);
+ }
+}
+
+static void
+theme_adium_copy_address_cb (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (user_data);
+ EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+ GtkClipboard *clipboard;
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, priv->hovered_uri, -1);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+ gtk_clipboard_set_text (clipboard, priv->hovered_uri, -1);
+}
+
+static void
+theme_adium_open_address_cb (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (user_data);
+ EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+
+ empathy_url_show (GTK_WIDGET (menuitem), priv->hovered_uri);
+}
+
+static void
theme_adium_populate_popup_cb (WebKitWebView *view,
GtkMenu *menu,
gpointer user_data)
{
- GtkWidget *item;
+ EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (view);
+ EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+ GtkWidget *item;
+ GList *items;
+ GtkWidget *icon;
+ gchar *stock_id;
+ gboolean is_link = FALSE;
+ gboolean developer_tools_enabled;
+
+ /* FIXME: WebKitGTK+'s context menu API clearly needs an
+ * overhaul. There is currently no way to know what is being
+ * clicked, to decide what features to provide. You either
+ * take what it gives you as a menu, or use hacks to figure
+ * out what to display. */
+ items = gtk_container_get_children (GTK_CONTAINER (menu));
+ item = GTK_WIDGET (g_list_nth_data (items, 0));
+ g_list_free (items);
+
+ if (GTK_IS_IMAGE_MENU_ITEM (item)) {
+ icon = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (item));
+ gtk_image_get_stock (GTK_IMAGE (icon), &stock_id, NULL);
+
+ if ((!strcmp (stock_id, GTK_STOCK_OPEN)) && priv->hovered_uri)
+ is_link = TRUE;
+ }
/* Remove default menu items */
- gtk_container_foreach (GTK_CONTAINER (menu),
- (GtkCallback) gtk_widget_destroy, NULL);
+ g_object_get (G_OBJECT (webkit_web_view_get_settings (view)),
+ "enable-developer-extras", &developer_tools_enabled, NULL);
+ if (!developer_tools_enabled)
+ gtk_container_foreach (GTK_CONTAINER (menu),
+ (GtkCallback) gtk_widget_destroy, NULL);
/* Select all item */
item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SELECT_ALL, NULL);
@@ -146,10 +249,31 @@ theme_adium_populate_popup_cb (WebKitWebView *view,
G_CALLBACK (empathy_chat_view_clear),
view);
- /* FIXME: Add open_link and copy_link when those bugs are fixed:
- * https://bugs.webkit.org/show_bug.cgi?id=16092
- * https://bugs.webkit.org/show_bug.cgi?id=16562
- */
+ /* We will only add the following menu items if we are
+ * right-clicking a link */
+ if (!is_link)
+ return;
+
+ /* Separator */
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* Copy Link Address menu item */
+ item = gtk_menu_item_new_with_mnemonic (_("_Copy Link Address"));
+ g_signal_connect (item, "activate",
+ G_CALLBACK (theme_adium_copy_address_cb),
+ view);
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* Open Link menu item */
+ item = gtk_menu_item_new_with_mnemonic (_("_Open Link"));
+ g_signal_connect (item, "activate",
+ G_CALLBACK (theme_adium_open_address_cb),
+ view);
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
}
static gchar *
@@ -402,7 +526,8 @@ theme_adium_append_message (EmpathyChatView *view,
gsize len = 0;
const gchar *func;
const gchar *service_name;
- const gchar *message_classes = NULL;
+ GString *message_classes = NULL;
+ gboolean is_backlog;
if (!priv->page_loaded) {
priv->message_queue = g_list_prepend (priv->message_queue,
@@ -455,45 +580,102 @@ theme_adium_append_message (EmpathyChatView *view,
}
}
+ is_backlog = empathy_message_is_backlog (msg);
+
/* Get the right html/func to add the message */
func = "appendMessage";
+
+ message_classes = g_string_new ("message");
+
+ /* eventually append the "history" class */
+ if (is_backlog) {
+ g_string_append (message_classes, " history");
+ }
+
+ /* check the sender of the message and append the appropriate class */
+ if (empathy_contact_is_user (sender)) {
+ g_string_append (message_classes, " outgoing");
+ }
+ else {
+ g_string_append (message_classes, " incoming");
+ }
+
/*
* To mimick Adium's behavior, we only want to join messages
- * sent within a 5 minute time frame.
+ * sent by the same contact within a 5 minute time frame.
*/
if (empathy_contact_equal (priv->last_contact, sender) &&
- (timestamp - priv->last_timestamp < MESSAGE_JOIN_PERIOD)) {
+ (timestamp - priv->last_timestamp < MESSAGE_JOIN_PERIOD) &&
+ (is_backlog == priv->last_is_backlog)) {
+ /* the messages can be appended */
func = "appendNextMessage";
+ g_string_append (message_classes, " consecutive");
+
+ /* check who is the sender of the message to use the correct html file */
if (empathy_contact_is_user (sender)) {
- message_classes = "consecutive incoming message";
- html = priv->data->out_nextcontent_html;
- len = priv->data->out_nextcontent_len;
+ /* check if this is a backlog message and use NextContext.html */
+ if (is_backlog) {
+ html = priv->data->out_nextcontext_html;
+ len = priv->data->out_nextcontext_len;
+ }
+
+ /*
+ * html is null if this is not a backlog message or
+ * if we have to fallback (NextContext.html missing).
+ * use NextContent.html
+ */
+ if (html == NULL) {
+ html = priv->data->out_nextcontent_html;
+ len = priv->data->out_nextcontent_len;
+ }
}
- if (!html) {
- message_classes = "consecutive message outgoing";
- html = priv->data->in_nextcontent_html;
- len = priv->data->in_nextcontent_len;
+ else {
+ if (is_backlog) {
+ html = priv->data->in_nextcontext_html;
+ len = priv->data->in_nextcontext_len;
+ }
+
+ if (html == NULL) {
+ html = priv->data->in_nextcontent_html;
+ len = priv->data->in_nextcontent_len;
+ }
}
}
- if (!html) {
+
+ /*
+ * we have html == NULL here if:
+ * 1. the message didn't have to be appended because
+ * the sender was different or the timestamp was too far
+ * 2. NextContent.html file does not exist, so we must
+ * not forget to fallback to the correct Content.html
+ */
+ if (html == NULL) {
if (empathy_contact_is_user (sender)) {
- if (!message_classes) {
- message_classes = "incoming message";
+ if (is_backlog) {
+ html = priv->data->out_context_html;
+ len = priv->data->out_context_len;
+ }
+
+ if (html == NULL) {
+ html = priv->data->out_content_html;
+ len = priv->data->out_content_len;
}
- html = priv->data->out_content_html;
- len = priv->data->out_content_len;
}
- if (!html) {
- if (!message_classes) {
- message_classes = "message outgoing";
+ else {
+ if (is_backlog) {
+ html = priv->data->in_context_html;
+ len = priv->data->in_context_len;
+ }
+
+ if (html == NULL) {
+ html = priv->data->in_content_html;
+ len = priv->data->in_content_len;
}
- html = priv->data->in_content_html;
- len = priv->data->in_content_len;
}
}
theme_adium_append_html (theme, func, html, len, body, avatar_filename,
- name, contact_id, service_name, message_classes,
+ name, contact_id, service_name, message_classes->str,
timestamp);
/* Keep the sender of the last displayed message */
@@ -502,8 +684,10 @@ theme_adium_append_message (EmpathyChatView *view,
}
priv->last_contact = g_object_ref (sender);
priv->last_timestamp = timestamp;
+ priv->last_is_backlog = is_backlog;
g_free (dup_body);
+ g_string_free (message_classes, TRUE);
}
static void
@@ -560,6 +744,13 @@ theme_adium_clear (EmpathyChatView *view)
priv->data->template_html,
basedir_uri);
g_free (basedir_uri);
+
+ /* Clear last contact to avoid trying to add a 'joined'
+ * message when we don't have an insertion point. */
+ if (priv->last_contact) {
+ g_object_unref (priv->last_contact);
+ priv->last_contact = NULL;
+ }
}
static gboolean
@@ -657,6 +848,10 @@ theme_adium_finalize (GObject *object)
EmpathyThemeAdiumPriv *priv = GET_PRIV (object);
empathy_adium_data_unref (priv->data);
+ g_free (priv->hovered_uri);
+
+ empathy_conf_notify_remove (empathy_conf_get (),
+ priv->notify_enable_webkit_developer_tools_id);
G_OBJECT_CLASS (empathy_theme_adium_parent_class)->finalize (object);
}
@@ -676,9 +871,77 @@ theme_adium_dispose (GObject *object)
priv->last_contact = NULL;
}
+ if (priv->inspector_window) {
+ gtk_widget_destroy (priv->inspector_window);
+ priv->inspector_window = NULL;
+ }
+
G_OBJECT_CLASS (empathy_theme_adium_parent_class)->dispose (object);
}
+static gboolean
+theme_adium_inspector_show_window_cb (WebKitWebInspector *inspector,
+ gpointer user_data)
+{
+ EmpathyThemeAdium *theme = user_data;
+ EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+
+ gtk_widget_show_all (priv->inspector_window);
+
+ return TRUE;
+}
+
+static gboolean
+theme_adium_inspector_close_window_cb (WebKitWebInspector *inspector,
+ gpointer user_data)
+{
+ EmpathyThemeAdium *theme = user_data;
+ EmpathyThemeAdiumPriv *priv;
+
+ /* We may be called too late - when the theme has already been
+ * destroyed */
+ if (!theme)
+ return FALSE;
+
+ priv = GET_PRIV (theme);
+
+ if (priv->inspector_window) {
+ gtk_widget_hide (priv->inspector_window);
+ }
+
+ return TRUE;
+}
+
+static WebKitWebView *
+theme_adium_inspect_web_view_cb (WebKitWebInspector *inspector,
+ WebKitWebView *web_view,
+ gpointer data)
+{
+ EmpathyThemeAdiumPriv *priv = GET_PRIV (EMPATHY_THEME_ADIUM (web_view));
+ GtkWidget *scrolled_window;
+ GtkWidget *inspector_web_view;
+
+ if (!priv->inspector_window) {
+ priv->inspector_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size (GTK_WINDOW (priv->inspector_window),
+ 800, 600);
+
+ g_signal_connect (priv->inspector_window, "delete-event",
+ G_CALLBACK (gtk_widget_hide_on_delete), NULL);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (priv->inspector_window), scrolled_window);
+
+ inspector_web_view = webkit_web_view_new ();
+ gtk_container_add (GTK_CONTAINER (scrolled_window), inspector_web_view);
+
+ return WEBKIT_WEB_VIEW (inspector_web_view);
+ }
+
+ return NULL;
+}
+
static void
theme_adium_constructed (GObject *object)
{
@@ -698,7 +961,15 @@ theme_adium_constructed (GObject *object)
if (font_size) {
g_object_set (G_OBJECT (webkit_settings), "default-font-size", font_size, NULL);
}
- webkit_web_view_set_settings (WEBKIT_WEB_VIEW (object), webkit_settings);
+
+ g_signal_connect (webkit_web_view_get_inspector (WEBKIT_WEB_VIEW (object)), "inspect-web-view",
+ G_CALLBACK (theme_adium_inspect_web_view_cb), NULL);
+
+ g_signal_connect (webkit_web_view_get_inspector (WEBKIT_WEB_VIEW (object)), "show-window",
+ G_CALLBACK (theme_adium_inspector_show_window_cb), object);
+
+ g_signal_connect (webkit_web_view_get_inspector (WEBKIT_WEB_VIEW (object)), "close-window",
+ G_CALLBACK (theme_adium_inspector_close_window_cb), NULL);
/* Load template */
basedir_uri = g_strconcat ("file://", priv->data->basedir, NULL);
@@ -768,7 +1039,6 @@ empathy_theme_adium_class_init (EmpathyThemeAdiumClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
-
g_type_class_add_private (object_class, sizeof (EmpathyThemeAdiumPriv));
}
@@ -791,6 +1061,17 @@ empathy_theme_adium_init (EmpathyThemeAdium *theme)
g_signal_connect (theme, "populate-popup",
G_CALLBACK (theme_adium_populate_popup_cb),
NULL);
+ g_signal_connect (theme, "hovering-over-link",
+ G_CALLBACK (theme_adium_hovering_over_link_cb),
+ NULL);
+
+ priv->notify_enable_webkit_developer_tools_id =
+ empathy_conf_notify_add (empathy_conf_get (),
+ "/apps/empathy/conversation/enable_webkit_developer_tools",
+ theme_adium_notify_enable_webkit_developer_tools_cb,
+ theme);
+
+ theme_adium_update_enable_webkit_developer_tools (theme);
}
EmpathyThemeAdium *
@@ -809,6 +1090,15 @@ empathy_adium_path_is_valid (const gchar *path)
gboolean ret;
gchar *file;
+ /* The theme is not valid if there is no Info.plist */
+ file = g_build_filename (path, "Contents", "Info.plist",
+ NULL);
+ ret = g_file_test (file, G_FILE_TEST_EXISTS);
+ g_free (file);
+
+ if (ret == FALSE)
+ return ret;
+
/* We ship a default Template.html as fallback if there is any problem
* with the one inside the theme. The only other required file is
* Content.html for incoming messages (outgoing fallback to use
@@ -834,10 +1124,15 @@ empathy_adium_info_new (const gchar *path)
value = empathy_plist_parse_from_file (file);
g_free (file);
- if (value) {
- info = g_value_dup_boxed (value);
- tp_g_value_slice_free (value);
- }
+ if (value == NULL)
+ return NULL;
+
+ info = g_value_dup_boxed (value);
+ tp_g_value_slice_free (value);
+
+ /* Insert the theme's path into the hash table,
+ * keys have to be dupped */
+ tp_asv_set_string (info, g_strdup ("path"), path);
return info;
}
@@ -890,6 +1185,14 @@ empathy_adium_data_new_with_info (const gchar *path, GHashTable *info)
g_file_get_contents (file, &data->in_nextcontent_html, &data->in_nextcontent_len, NULL);
g_free (file);
+ file = g_build_filename (data->basedir, "Incoming", "Context.html", NULL);
+ g_file_get_contents (file, &data->in_context_html, &data->in_context_len, NULL);
+ g_free (file);
+
+ file = g_build_filename (data->basedir, "Incoming", "NextContext.html", NULL);
+ g_file_get_contents (file, &data->in_nextcontext_html, &data->in_nextcontext_len, NULL);
+ g_free (file);
+
file = g_build_filename (data->basedir, "Outgoing", "Content.html", NULL);
g_file_get_contents (file, &data->out_content_html, &data->out_content_len, NULL);
g_free (file);
@@ -898,6 +1201,14 @@ empathy_adium_data_new_with_info (const gchar *path, GHashTable *info)
g_file_get_contents (file, &data->out_nextcontent_html, &data->out_nextcontent_len, NULL);
g_free (file);
+ file = g_build_filename (data->basedir, "Outgoing", "Context.html", NULL);
+ g_file_get_contents (file, &data->out_context_html, &data->out_context_len, NULL);
+ g_free (file);
+
+ file = g_build_filename (data->basedir, "Outgoing", "NextContext.html", NULL);
+ g_file_get_contents (file, &data->out_nextcontext_html, &data->out_nextcontext_len, NULL);
+ g_free (file);
+
file = g_build_filename (data->basedir, "Status.html", NULL);
g_file_get_contents (file, &data->status_html, &data->status_len, NULL);
g_free (file);
@@ -1001,7 +1312,7 @@ empathy_adium_data_ref (EmpathyAdiumData *data)
{
g_return_val_if_fail (data != NULL, NULL);
- data->ref_count++;
+ g_atomic_int_inc (&data->ref_count);
return data;
}
@@ -1011,15 +1322,18 @@ empathy_adium_data_unref (EmpathyAdiumData *data)
{
g_return_if_fail (data != NULL);
- data->ref_count--;
- if (data->ref_count == 0) {
+ if (g_atomic_int_dec_and_test (&data->ref_count)) {
g_free (data->path);
g_free (data->basedir);
g_free (data->template_html);
g_free (data->in_content_html);
g_free (data->in_nextcontent_html);
+ g_free (data->in_context_html);
+ g_free (data->in_nextcontext_html);
g_free (data->out_content_html);
g_free (data->out_nextcontent_html);
+ g_free (data->out_context_html);
+ g_free (data->out_nextcontext_html);
g_free (data->default_avatar_filename);
g_free (data->default_incoming_avatar_filename);
g_free (data->default_outgoing_avatar_filename);
diff --git a/libempathy-gtk/empathy-theme-manager.c b/libempathy-gtk/empathy-theme-manager.c
index ba3d48e68..fea2eca51 100644
--- a/libempathy-gtk/empathy-theme-manager.c
+++ b/libempathy-gtk/empathy-theme-manager.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <glib/gi18n-lib.h>
+#include <telepathy-glib/dbus.h>
#include <gtk/gtk.h>
#include <telepathy-glib/util.h>
@@ -67,9 +68,6 @@ static const gchar *themes[] = {
"simple", N_("Simple"),
"clean", N_("Clean"),
"blue", N_("Blue"),
-#ifdef HAVE_WEBKIT
- "adium", N_("Adium"),
-#endif
NULL
};
@@ -378,6 +376,10 @@ theme_manager_ensure_theme_exists (const gchar *name)
return FALSE;
}
+ if (strcmp ("adium", name) == 0) {
+ return TRUE;
+ }
+
for (i = 0; themes[i]; i += 2) {
if (strcmp (themes[i], name) == 0) {
return TRUE;
@@ -534,3 +536,62 @@ empathy_theme_manager_get_themes (void)
return themes;
}
+#ifdef HAVE_WEBKIT
+static void
+find_themes (GList **list, const gchar *dirpath)
+{
+ GDir *dir;
+ GError *error = NULL;
+ const gchar *name = NULL;
+ GHashTable *info = NULL;
+
+ dir = g_dir_open (dirpath, 0, &error);
+ if (dir != NULL) {
+ name = g_dir_read_name (dir);
+ while (name != NULL) {
+ gchar *path;
+
+ path = g_build_path (G_DIR_SEPARATOR_S, dirpath, name, NULL);
+ if (empathy_adium_path_is_valid (path)) {
+ info = empathy_adium_info_new (path);
+ if (info != NULL) {
+ *list = g_list_prepend (*list, info);
+ }
+ }
+ g_free (path);
+ name = g_dir_read_name (dir);
+ }
+ g_dir_close (dir);
+ } else {
+ DEBUG ("Error opening %s: %s\n", dirpath, error->message);
+ g_error_free (error);
+ }
+}
+#endif /* HAVE_WEBKIT */
+
+GList *
+empathy_theme_manager_get_adium_themes (void)
+{
+#ifdef HAVE_WEBKIT
+ GList *themes = NULL;
+ gchar *userpath = NULL;
+ const gchar *const *paths = NULL;
+ gint i = 0;
+
+ userpath = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (), "adium/message-styles", NULL);
+ find_themes (&themes, userpath);
+ g_free (userpath);
+
+ paths = g_get_system_data_dirs ();
+ for (i = 0; paths[i] != NULL; i++) {
+ userpath = g_build_path (G_DIR_SEPARATOR_S, paths[i],
+ "adium/message-styles", NULL);
+ find_themes (&themes, userpath);
+ g_free (userpath);
+ }
+
+ return themes;
+#else
+ return NULL;
+#endif /* HAVE_WEBKIT */
+}
diff --git a/libempathy-gtk/empathy-theme-manager.h b/libempathy-gtk/empathy-theme-manager.h
index 99c96d784..a459b43cb 100644
--- a/libempathy-gtk/empathy-theme-manager.h
+++ b/libempathy-gtk/empathy-theme-manager.h
@@ -51,6 +51,7 @@ struct _EmpathyThemeManagerClass {
GType empathy_theme_manager_get_type (void) G_GNUC_CONST;
EmpathyThemeManager * empathy_theme_manager_get (void);
const gchar ** empathy_theme_manager_get_themes (void);
+GList * empathy_theme_manager_get_adium_themes (void);
EmpathyChatView * empathy_theme_manager_create_view (EmpathyThemeManager *manager);
G_END_DECLS
diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c
index 7b4cc1d43..b697b4d0b 100644
--- a/libempathy-gtk/empathy-ui-utils.c
+++ b/libempathy-gtk/empathy-ui-utils.c
@@ -1238,7 +1238,7 @@ empathy_window_get_is_visible (GtkWindow *window)
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
- gdk_window = GTK_WIDGET (window)->window;
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
if (!gdk_window) {
return FALSE;
}
@@ -1260,7 +1260,7 @@ empathy_window_iconify (GtkWindow *window, GtkStatusIcon *status_icon)
GdkWindow *gdk_window;
gtk_status_icon_get_geometry (status_icon, NULL, &icon_location, NULL);
- gdk_window = GTK_WIDGET (window)->window;
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
dpy = gdk_x11_drawable_get_xdisplay (gdk_window);
data[0] = icon_location.x;
@@ -1329,6 +1329,8 @@ empathy_get_toplevel_window (GtkWidget *widget)
static gchar *
fixup_url (const gchar *url)
{
+ g_return_val_if_fail (url != NULL, NULL);
+
if (g_str_has_prefix (url, "ghelp:") ||
g_str_has_prefix (url, "mailto:") ||
strstr (url, ":/")) {
@@ -1349,6 +1351,9 @@ empathy_url_show (GtkWidget *parent,
gchar *real_url;
GError *error = NULL;
+ g_return_if_fail (GTK_IS_WIDGET (parent));
+ g_return_if_fail (url != NULL);
+
real_url = fixup_url (url);
if (real_url) {
url = real_url;
diff --git a/libempathy-gtk/empathy-video-widget.c b/libempathy-gtk/empathy-video-widget.c
index 79f27814f..0f62496de 100644
--- a/libempathy-gtk/empathy-video-widget.c
+++ b/libempathy-gtk/empathy-video-widget.c
@@ -403,7 +403,7 @@ empathy_video_widget_sync_message_cb (GstBus *bus, GstMessage *message,
{
g_assert (GTK_WIDGET_REALIZED (GTK_WIDGET (self)));
gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (priv->overlay),
- GDK_WINDOW_XID (GTK_WIDGET (self)->window));
+ GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (self))));
}
}
@@ -418,13 +418,13 @@ empathy_video_widget_expose_event (GtkWidget *widget, GdkEventExpose *event)
if (priv->overlay == NULL)
{
- gdk_window_clear_area (widget->window, 0, 0,
+ gdk_window_clear_area (gtk_widget_get_window (widget), 0, 0,
widget->allocation.width, widget->allocation.height);
return TRUE;
}
gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (priv->overlay),
- GDK_WINDOW_XID (widget->window));
+ GDK_WINDOW_XID (gtk_widget_get_window (widget)));
gst_x_overlay_expose (GST_X_OVERLAY (priv->overlay));