diff -u pidgin-2.2.2.orig/pidgin/plugins/Makefile.am pidgin-2.2.2/pidgin/plugins/Makefile.am --- pidgin-2.2.2.orig/pidgin/plugins/Makefile.am Tue Oct 30 22:01:48 2007 +++ pidgin-2.2.2/pidgin/plugins/Makefile.am Tue Oct 30 22:03:27 2007 @@ -31,6 +31,7 @@ plugindir = $(libdir)/pidgin convcolors_la_LDFLAGS = -module -avoid-version +convcharcount_la_LDFLAGS = -module -avoid-version contact_priority_la_LDFLAGS = -module -avoid-version extplacement_la_LDFLAGS = -module -avoid-version gtk_signals_test_la_LDFLAGS = -module -avoid-version @@ -50,6 +51,7 @@ plugin_LTLIBRARIES = \ convcolors.la \ + convcharcount.la \ extplacement.la \ gtkbuddynote.la \ history.la \ @@ -68,6 +70,7 @@ gtk_signals_test.la convcolors_la_SOURCES = convcolors.c +convcharcount_la_SOURCES = convcharcount.c contact_priority_la_SOURCES = contact_priority.c extplacement_la_SOURCES = extplacement.c gtk_signals_test_la_SOURCES = gtk-signals-test.c @@ -84,6 +87,7 @@ xmppconsole_la_SOURCES = xmppconsole.c convcolors_la_LIBADD = $(GTK_LIBS) +convcharcount_la_LIBADD = $(GTK_LIBS) contact_priority_la_LIBADD = $(GTK_LIBS) extplacement_la_LIBADD = $(GTK_LIBS) gtk_signals_test_la_LIBADD = $(GTK_LIBS) diff -u pidgin-2.2.2.orig/pidgin/plugins/Makefile.mingw pidgin-2.2.2/pidgin/plugins/Makefile.mingw --- pidgin-2.2.2.orig/pidgin/plugins/Makefile.mingw Tue Oct 30 22:01:14 2007 +++ pidgin-2.2.2/pidgin/plugins/Makefile.mingw Tue Oct 30 16:39:21 2007 @@ -76,6 +76,7 @@ plugins: \ convcolors.dll \ + convcharcount.dll \ extplacement.dll \ gtkbuddynote.dll \ history.dll \ --- /dev/null Tue Oct 30 22:38:52 2007 +++ pidgin-2.2.2/pidgin/plugins/convcharcount.c Tue Oct 30 22:38:25 2007 @@ -0,0 +1,223 @@ +/* + * Conversation input characters count plugin. + * Based on the Markerline plugin. + * + * Copyright (C) 2007 Dossy Shiobara + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02111-1301, USA. + */ + +#include "internal.h" + +#define PLUGIN_ID "gtk-convcharcount" +#define PLUGIN_NAME N_("Conv. input chars count") +#define PLUGIN_STATIC_NAME "Conv. input chars count" +#define PLUGIN_SUMMARY N_("Display current number of characters in a conversation's input widget.") +#define PLUGIN_DESCRIPTION N_("Display current number of characters in a conversation's input widget.") +#define PLUGIN_AUTHOR "Dossy Shiobara " + +#include +#include +#include + +#include +#include +#include +#include + +static void +insert_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *position, gchar *new_text, gint new_text_length, gpointer user_data) +{ + PidginConversation *gtkconv = (PidginConversation *)user_data; + GtkWidget *box, *counter = NULL; + gchar count[20]; + + g_return_if_fail(gtkconv != NULL); + + g_snprintf(count, sizeof(count) - 1, "%u", + gtk_text_buffer_get_char_count(textbuffer) + + new_text_length); + + box = gtkconv->toolbar; + counter = g_object_get_data(G_OBJECT(box), PLUGIN_ID "-counter"); + if (counter) + gtk_label_set_text(GTK_LABEL(counter), count); +} + +static void +delete_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *start_pos, GtkTextIter *end_pos, gpointer user_data) +{ + PidginConversation *gtkconv = (PidginConversation *)user_data; + GtkWidget *box, *counter = NULL; + gchar count[20]; + + g_return_if_fail(gtkconv != NULL); + + g_snprintf(count, sizeof(count) - 1, "%u", + gtk_text_buffer_get_char_count(textbuffer) - + (gtk_text_iter_get_offset(end_pos) - gtk_text_iter_get_offset(start_pos))); + + box = gtkconv->toolbar; + counter = g_object_get_data(G_OBJECT(box), PLUGIN_ID "-counter"); + if (counter) + gtk_label_set_text(GTK_LABEL(counter), count); +} + +static void +detach_from_gtkconv(PidginConversation *gtkconv, gpointer null) +{ + GtkWidget *box, *counter = NULL, *sep = NULL; + + g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->entry_buffer), + (GFunc)insert_text_cb, gtkconv); + g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->entry_buffer), + (GFunc)delete_text_cb, gtkconv); + + box = gtkconv->toolbar; + counter = g_object_get_data(G_OBJECT(box), PLUGIN_ID "-counter"); + if (counter) + gtk_container_remove(GTK_CONTAINER(box), counter); + sep = g_object_get_data(G_OBJECT(box), PLUGIN_ID "-sep"); + if (sep) + gtk_container_remove(GTK_CONTAINER(box), sep); + + gtk_widget_queue_draw(pidgin_conv_get_window(gtkconv)->window); +} + +static void +attach_to_gtkconv(PidginConversation *gtkconv, gpointer null) +{ + GtkWidget *box, *sep, *counter; + + box = gtkconv->toolbar; + counter = g_object_get_data(G_OBJECT(box), PLUGIN_ID "-counter"); + g_return_if_fail(counter == NULL); + + counter = gtk_label_new(NULL); + gtk_widget_set_name(counter, "convcharcount_label"); + gtk_label_set_text(GTK_LABEL(counter), "0"); + gtk_box_pack_end(GTK_BOX(box), counter, FALSE, FALSE, 0); + gtk_widget_show_all(counter); + + g_object_set_data(G_OBJECT(box), PLUGIN_ID "-counter", counter); + + sep = gtk_vseparator_new(); + gtk_box_pack_end(GTK_BOX(box), sep, FALSE, FALSE, 0); + gtk_widget_show_all(sep); + + g_object_set_data(G_OBJECT(box), PLUGIN_ID "-sep", sep); + + /* connect signals, etc. */ + g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", + G_CALLBACK(insert_text_cb), gtkconv); + g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range", + G_CALLBACK(delete_text_cb), gtkconv); + + gtk_widget_queue_draw(pidgin_conv_get_window(gtkconv)->window); +} + +static void +detach_from_pidgin_window(PidginWindow *win, gpointer null) +{ + g_list_foreach(pidgin_conv_window_get_gtkconvs(win), (GFunc)detach_from_gtkconv, NULL); +} + +static void +attach_to_pidgin_window(PidginWindow *win, gpointer null) +{ + g_list_foreach(pidgin_conv_window_get_gtkconvs(win), (GFunc)attach_to_gtkconv, NULL); +} + +static void +detach_from_all_windows() +{ + g_list_foreach(pidgin_conv_windows_get_list(), (GFunc)detach_from_pidgin_window, NULL); +} + +static void +attach_to_all_windows() +{ + g_list_foreach(pidgin_conv_windows_get_list(), (GFunc)attach_to_pidgin_window, NULL); +} + +static void +conv_created_cb(PurpleConversation *conv, gpointer null) +{ + PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); + + g_return_if_fail(gtkconv != NULL); + + attach_to_gtkconv(gtkconv, NULL); +} + +static gboolean +plugin_load(PurplePlugin *plugin) +{ + attach_to_all_windows(); + + purple_signal_connect(purple_conversations_get_handle(), + "conversation-created", + plugin, PURPLE_CALLBACK(conv_created_cb), NULL); + + return TRUE; +} + +static gboolean +plugin_unload(PurplePlugin *plugin) +{ + detach_from_all_windows(); + + return TRUE; +} + +static PurplePluginInfo info = +{ + PURPLE_PLUGIN_MAGIC, + PURPLE_MAJOR_VERSION, + PURPLE_MINOR_VERSION, + PURPLE_PLUGIN_STANDARD, + PIDGIN_PLUGIN_TYPE, + 0, + NULL, + PURPLE_PRIORITY_DEFAULT, + PLUGIN_ID, + PLUGIN_NAME, + VERSION, + PLUGIN_SUMMARY, + PLUGIN_DESCRIPTION, + PLUGIN_AUTHOR, + PURPLE_WEBSITE, + plugin_load, + plugin_unload, + NULL, + NULL, + NULL, + NULL, + NULL, + + /* padding */ + NULL, + NULL, + NULL, + NULL +}; + +static void +init_plugin(PurplePlugin *plugin) +{ +} + +PURPLE_INIT_PLUGIN(PLUGIN_STATIC_NAME, init_plugin, info)