Skip to content
This repository has been archived by the owner on Oct 18, 2020. It is now read-only.

Commit

Permalink
Newline issue has been solved
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] authored and [email protected] committed Nov 10, 2009
1 parent dd31aba commit f23fc80
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 17 deletions.
39 changes: 24 additions & 15 deletions src/embeddedvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
#include <debug.h>

static GHashTable *ht_buttons = NULL; /* <button, imhtml> */
static GHashTable *ht_signal_handlers = NULL; /* <text_buffer, handler_id> */
static GHashTable *ht_signal_handlers_it = NULL; /* <text_buffer, "insert-text"> */
static GHashTable *ht_signal_handlers_eua = NULL; /* <text_buffer, "end-user-action"> */

static void
insert_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *location,
Expand All @@ -37,9 +38,6 @@ insert_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *location,
GtkWidget *button = videoframes_insert_new_button(imhtml, location, info, text, len);
g_hash_table_insert(ht_buttons, button, imhtml);

if (purple_prefs_get_bool("/plugins/gtk/embeddedvideo/show-video"))
videoframes_toggle_button(button);

gtk_text_buffer_get_end_iter(imhtml->text_buffer, location);

}
Expand All @@ -54,9 +52,13 @@ attach_to_conversation(gpointer data, gpointer user_data)
GtkIMHtml *imhtml = GTK_IMHTML(gtkconv->imhtml);
g_assert(GTK_IS_IMHTML(imhtml));

gulong handler_id = g_signal_connect_after(G_OBJECT(imhtml->text_buffer),
gulong it_handler_id = g_signal_connect_after(G_OBJECT(imhtml->text_buffer),
"insert-text", G_CALLBACK(insert_text_cb), imhtml);
g_hash_table_insert(ht_signal_handlers, imhtml->text_buffer, (gpointer) handler_id);
g_hash_table_insert(ht_signal_handlers_it, imhtml->text_buffer, (gpointer) it_handler_id);

gulong eua_handler_id = g_signal_connect(G_OBJECT(imhtml->text_buffer),
"end-user-action", G_CALLBACK(videoframes_text_buffer_end_user_action_cb), NULL);
g_hash_table_insert(ht_signal_handlers_eua, imhtml->text_buffer, (gpointer) eua_handler_id);
}

static void
Expand All @@ -68,10 +70,15 @@ detach_from_conversation(gpointer data, gpointer user_data)
GtkIMHtml *imhtml = GTK_IMHTML(gtkconv->imhtml);
g_assert(GTK_IS_IMHTML(imhtml));

gulong handler_id = (gulong) g_hash_table_lookup(ht_signal_handlers,
gulong it_handler_id = (gulong) g_hash_table_lookup(ht_signal_handlers_it,
imhtml->text_buffer);
g_signal_handler_disconnect(imhtml->text_buffer, it_handler_id);
g_hash_table_remove(ht_signal_handlers_it, imhtml->text_buffer);

gulong eua_handler_id = (gulong) g_hash_table_lookup(ht_signal_handlers_eua,
imhtml->text_buffer);
g_signal_handler_disconnect(imhtml->text_buffer, handler_id);
g_hash_table_remove(ht_signal_handlers, imhtml->text_buffer);
g_signal_handler_disconnect(imhtml->text_buffer, eua_handler_id);
g_hash_table_remove(ht_signal_handlers_eua, imhtml->text_buffer);
}

static void
Expand Down Expand Up @@ -109,8 +116,9 @@ plugin_load(PurplePlugin *plugin)
ht_buttons = g_hash_table_new_full(g_direct_hash, g_direct_equal,
(GDestroyNotify) videoframes_remove_button, NULL);

/* Create the hash table for signal handlers. */
ht_signal_handlers = g_hash_table_new(g_direct_hash, g_direct_equal);
/* Create hash tables for signal handlers. */
ht_signal_handlers_it = g_hash_table_new(g_direct_hash, g_direct_equal);
ht_signal_handlers_eua = g_hash_table_new(g_direct_hash, g_direct_equal);

/* Attach to current conversations. */
g_list_foreach(purple_get_conversations(), attach_to_conversation, NULL);
Expand All @@ -130,16 +138,17 @@ plugin_unload(PurplePlugin *plugin)
{
/* Disconnect signals for future conversations. */
void *conv_handle = purple_conversations_get_handle();
purple_signal_disconnect(conv_handle, "conversation-created", plugin,
PURPLE_CALLBACK(conversation_created_cb));
purple_signal_disconnect(conv_handle, "deleting-conversation", plugin,
PURPLE_CALLBACK(deleting_conversation_cb));
purple_signal_disconnect(conv_handle, "conversation-created", plugin,
PURPLE_CALLBACK(conversation_created_cb));

/* Detach from current conversations. */
g_list_foreach(purple_get_conversations(), detach_from_conversation, NULL);

/* Destroy the hash table for signal handlers. */
g_hash_table_destroy(ht_signal_handlers);
/* Destroy hash tables for signal handlers. */
g_hash_table_destroy(ht_signal_handlers_eua);
g_hash_table_destroy(ht_signal_handlers_it);

/* Remove all the inserted buttons and destroy the hash table.
Every button will automatically remove its video frame if it has one. */
Expand Down
48 changes: 46 additions & 2 deletions src/videoframes.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ button_info_new(GtkIMHtml *imhtml, GtkTextIter *location,
location, TRUE);
info->website = website;
info->url = g_string_new_len(text, len);
info->iter = location;
info->insert_newline = -1;

return info;
}
Expand All @@ -60,6 +62,44 @@ videoframes_destroy()
g_hash_table_destroy(ht_button_info);
}

void
videoframes_text_buffer_check_newline(gpointer key, gpointer values, gpointer user_data)
{
GtkWidget *button = (GtkWidget *) key;
ButtonInfo *button_info = (ButtonInfo *) values;

if (button_info->insert_newline != -1)
return ;

GtkTextIter iter;

gtk_text_buffer_get_iter_at_mark(button_info->imhtml->text_buffer,
&iter, button_info->mark);
button_info->insert_newline = 0;

while (gtk_text_iter_forward_char(&iter)) {
gunichar crt_unichar = gtk_text_iter_get_char(&iter);

if (crt_unichar == G_UNICODE_BREAK_LINE_FEED)
break ;
if (g_unichar_isgraph(crt_unichar)) {
button_info->insert_newline = 1;
break ;
}
}

if (purple_prefs_get_bool("/plugins/gtk/embeddedvideo/show-video")) {
videoframes_toggle_button(button);
gtk_text_buffer_get_end_iter(button_info->imhtml->text_buffer, button_info->iter);
}
}

void
videoframes_text_buffer_end_user_action_cb(GtkTextBuffer* text_buffer, gpointer user_data)
{
g_hash_table_foreach(ht_button_info, videoframes_text_buffer_check_newline, NULL);
}

GtkWidget *
videoframes_insert_new_button(GtkIMHtml *imhtml, GtkTextIter *location,
WebsiteInfo *website, gchar *text, gint len)
Expand Down Expand Up @@ -155,11 +195,15 @@ videoframes_toggle_button_cb(GtkWidget *button)
gtk_widget_show_all(web_view);

/* Insert the web view into the conversation. */
/* FIXME: Is this "\n" enough? What about those who use unicode chars?
What could happen on Windows without "\r"?
*/
gtk_text_buffer_insert(info->imhtml->text_buffer, &iter, "\n", 1);
GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(
info->imhtml->text_buffer, &iter);
gtk_text_view_add_child_at_anchor(&info->imhtml->text_view, web_view, anchor);
gtk_text_buffer_insert(info->imhtml->text_buffer, &iter, "\n", 1);
if (info->insert_newline == 1)
gtk_text_buffer_insert(info->imhtml->text_buffer, &iter, "\n", 1);

} else {

Expand All @@ -169,7 +213,7 @@ videoframes_toggle_button_cb(GtkWidget *button)
/* Remove the video from the conversation.
The web view is implicitly destroyed. */
GtkTextIter next_iter = iter;
gtk_text_iter_forward_chars(&next_iter, 3);
gtk_text_iter_forward_chars(&next_iter, 2 + (info->insert_newline));
gtk_text_buffer_delete(info->imhtml->text_buffer, &iter, &next_iter);

}
Expand Down
4 changes: 4 additions & 0 deletions src/videoframes.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ struct _ButtonInfo
GtkTextMark *mark;
WebsiteInfo *website;
GString *url;
GtkTextIter *iter;
gint insert_newline;
};

ButtonInfo * button_info_new(GtkIMHtml *, GtkTextIter *,
Expand All @@ -25,6 +27,8 @@ void button_info_free(ButtonInfo *);

void videoframes_init();
void videoframes_destroy();
void videoframes_text_buffer_check_new_line(gpointer, gpointer, gpointer);
void videoframes_text_buffer_end_user_action_cb(GtkTextBuffer *, gpointer);
GtkWidget * videoframes_insert_new_button(GtkIMHtml *, GtkTextIter *,
WebsiteInfo *, gchar *, gint);
void videoframes_remove_button(GtkWidget *);
Expand Down

0 comments on commit f23fc80

Please sign in to comment.