# HG changeset patch # User Tomasz Wasilczyk # Date 1398730867 -7200 # Node ID 98e92d543d73032f2a4f6948bc8660781b147560 # Parent 1c082451371dc7541300cee5b167bccf88e0e82d Initial implementation fot the screencap plugin diff -r 1c082451371d -r 98e92d543d73 pidgin/gtkwebview.c --- a/pidgin/gtkwebview.c Mon Apr 28 10:57:31 2014 +0200 +++ b/pidgin/gtkwebview.c Tue Apr 29 02:21:07 2014 +0200 @@ -2243,6 +2243,17 @@ priv->toolbar = PIDGIN_WEBVIEWTOOLBAR(toolbar); } +GtkWidget * +pidgin_webview_get_toolbar(PidginWebView *webview) +{ + PidginWebViewPriv *priv; + + g_return_val_if_fail(webview != NULL, NULL); + + priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); + return GTK_WIDGET(priv->toolbar); +} + void pidgin_webview_show_toolbar(PidginWebView *webview) { diff -r 1c082451371d -r 98e92d543d73 pidgin/gtkwebview.h --- a/pidgin/gtkwebview.h Mon Apr 28 10:57:31 2014 +0200 +++ b/pidgin/gtkwebview.h Tue Apr 29 02:21:07 2014 +0200 @@ -628,10 +628,21 @@ pidgin_webview_switch_active_conversation(PidginWebView *webview, PurpleConversation *conv); -/* Do not use. */ +/* Do not use. TODO: rename to _pidgin and move to gtkinternal.h */ void pidgin_webview_set_toolbar(PidginWebView *webview, GtkWidget *toolbar); +/** + * pidgin_webview_get_toolbar: + * @webview: The PidginWebView + * + * Returns the toolbar associated with the webview. + * + * Returns: the toolbar. + */ +GtkWidget * +pidgin_webview_get_toolbar(PidginWebView *webview); + G_END_DECLS #endif /* _PIDGIN_WEBVIEW_H_ */ diff -r 1c082451371d -r 98e92d543d73 pidgin/gtkwebviewtoolbar.c --- a/pidgin/gtkwebviewtoolbar.c Mon Apr 28 10:57:31 2014 +0200 +++ b/pidgin/gtkwebviewtoolbar.c Tue Apr 29 02:21:07 2014 +0200 @@ -1504,20 +1504,32 @@ gtk_toolbar_set_style(GTK_TOOLBAR(priv->wide_view), GTK_TOOLBAR_ICONS); for (i = 0; i < G_N_ELEMENTS(layout); i++) { - if (layout[i]) + if (layout[i]) { item = GTK_TOOL_ITEM(gtk_action_create_tool_item(layout[i])); - else + g_object_set_data_full(G_OBJECT(item), "action-name", + g_strdup(gtk_action_get_name(layout[i])), g_free); + } else item = gtk_separator_tool_item_new(); gtk_toolbar_insert(GTK_TOOLBAR(priv->wide_view), item, -1); } } +static inline void +lean_view_add_menu_item(GtkWidget *menu, GtkAction *action) +{ + GtkWidget *menuitem; + + menuitem = gtk_action_create_menu_item(action); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + g_object_set_data_full(G_OBJECT(menuitem), "action-name", + g_strdup(gtk_action_get_name(action)), g_free); +} + static void pidgin_webviewtoolbar_create_lean_view(PidginWebViewToolbar *toolbar) { PidginWebViewToolbarPriv *priv = PIDGIN_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar); GtkWidget *label; - GtkWidget *menuitem; GtkToolItem *sep; GtkToolItem *font_button; GtkWidget *font_menu; @@ -1531,12 +1543,10 @@ gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); gtk_toolbar_set_style(GTK_TOOLBAR(priv->lean_view), GTK_TOOLBAR_BOTH_HORIZ); -#define ADD_MENU_ITEM(menu, item) \ - menuitem = gtk_action_create_menu_item((item)); \ - gtk_menu_shell_append(GTK_MENU_SHELL((menu)), menuitem); - /* Fonts */ font_button = gtk_toggle_tool_button_new(); + g_object_set_data_full(G_OBJECT(font_button), "action-name", + g_strdup("font"), g_free); gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view), font_button, -1); gtk_tool_item_set_is_important(font_button, TRUE); gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(font_button), GTK_STOCK_BOLD); @@ -1545,20 +1555,21 @@ gtk_tool_button_set_label_widget(GTK_TOOL_BUTTON(font_button), label); priv->font_menu = font_menu = gtk_menu_new(); + g_object_set_data(G_OBJECT(font_button), "menu", font_menu); - ADD_MENU_ITEM(font_menu, priv->bold); - ADD_MENU_ITEM(font_menu, priv->italic); - ADD_MENU_ITEM(font_menu, priv->underline); - ADD_MENU_ITEM(font_menu, priv->strike); - ADD_MENU_ITEM(font_menu, priv->larger_size); + lean_view_add_menu_item(font_menu, priv->bold); + lean_view_add_menu_item(font_menu, priv->italic); + lean_view_add_menu_item(font_menu, priv->underline); + lean_view_add_menu_item(font_menu, priv->strike); + lean_view_add_menu_item(font_menu, priv->larger_size); #if 0 - ADD_MENU_ITEM(font_menu, priv->normal_size); + lean_view_add_menu_item(font_menu, priv->normal_size); #endif - ADD_MENU_ITEM(font_menu, priv->smaller_size); - ADD_MENU_ITEM(font_menu, priv->font); - ADD_MENU_ITEM(font_menu, priv->fgcolor); - ADD_MENU_ITEM(font_menu, priv->bgcolor); - ADD_MENU_ITEM(font_menu, priv->clear); + lean_view_add_menu_item(font_menu, priv->smaller_size); + lean_view_add_menu_item(font_menu, priv->font); + lean_view_add_menu_item(font_menu, priv->fgcolor); + lean_view_add_menu_item(font_menu, priv->bgcolor); + lean_view_add_menu_item(font_menu, priv->clear); g_signal_connect(G_OBJECT(font_button), "toggled", G_CALLBACK(pidgin_menu_clicked), font_menu); @@ -1573,6 +1584,8 @@ /* Insert */ insert_button = gtk_toggle_tool_button_new(); + g_object_set_data_full(G_OBJECT(insert_button), "action-name", + g_strdup("insert"), g_free); gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view), insert_button, -1); gtk_tool_item_set_is_important(insert_button, TRUE); gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(insert_button), @@ -1581,10 +1594,11 @@ gtk_tool_button_set_label_widget(GTK_TOOL_BUTTON(insert_button), label); priv->insert_menu = insert_menu = gtk_menu_new(); + g_object_set_data(G_OBJECT(insert_button), "menu", insert_menu); - ADD_MENU_ITEM(insert_menu, priv->image); - ADD_MENU_ITEM(insert_menu, priv->link); - ADD_MENU_ITEM(insert_menu, priv->hr); + lean_view_add_menu_item(insert_menu, priv->image); + lean_view_add_menu_item(insert_menu, priv->link); + lean_view_add_menu_item(insert_menu, priv->hr); g_signal_connect(G_OBJECT(insert_button), "toggled", G_CALLBACK(pidgin_menu_clicked), insert_menu); @@ -1597,6 +1611,8 @@ /* Smiley */ smiley_button = gtk_action_create_tool_item(priv->smiley); + g_object_set_data_full(G_OBJECT(smiley_button), "action-name", + g_strdup("smiley"), g_free); gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view), GTK_TOOL_ITEM(smiley_button), -1); @@ -1606,10 +1622,10 @@ /* Attention */ attention_button = gtk_action_create_tool_item(priv->attention); + g_object_set_data_full(G_OBJECT(attention_button), "action-name", + g_strdup("attention"), g_free); gtk_toolbar_insert(GTK_TOOLBAR(priv->lean_view), GTK_TOOL_ITEM(attention_button), -1); - -#undef ADD_MENU_ITEM } static void @@ -1815,3 +1831,23 @@ gtk_action_activate(act); } + +GtkWidget * +pidgin_webviewtoolbar_get_wide_view(PidginWebViewToolbar *toolbar) +{ + PidginWebViewToolbarPriv *priv = PIDGIN_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar); + + g_return_val_if_fail(toolbar != NULL, NULL); + + return priv->wide_view; +} + +GtkWidget * +pidgin_webviewtoolbar_get_lean_view(PidginWebViewToolbar *toolbar) +{ + PidginWebViewToolbarPriv *priv = PIDGIN_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar); + + g_return_val_if_fail(toolbar != NULL, NULL); + + return priv->lean_view; +} diff -r 1c082451371d -r 98e92d543d73 pidgin/gtkwebviewtoolbar.h --- a/pidgin/gtkwebviewtoolbar.h Mon Apr 28 10:57:31 2014 +0200 +++ b/pidgin/gtkwebviewtoolbar.h Tue Apr 29 02:21:07 2014 +0200 @@ -104,6 +104,28 @@ void pidgin_webviewtoolbar_activate(PidginWebViewToolbar *toolbar, PidginWebViewAction action); +/** + * pidgin_webviewtoolbar_get_wide_view: + * @toolbar: The PidginWebViewToolbar object + * + * Returns the wide toolbar variant widget for the given @toolbar. + * + * Returns: the wide toolbar variant. + */ +GtkWidget * +pidgin_webviewtoolbar_get_wide_view(PidginWebViewToolbar *toolbar); + +/** + * pidgin_webviewtoolbar_get_lean_view: + * @toolbar: The PidginWebViewToolbar object + * + * Returns the lean toolbar variant widget for the given @toolbar. + * + * Returns: the lean toolbar variant. + */ +GtkWidget * +pidgin_webviewtoolbar_get_lean_view(PidginWebViewToolbar *toolbar); + G_END_DECLS #endif /* _PIDGINWEBVIEWTOOLBAR_H_ */ diff -r 1c082451371d -r 98e92d543d73 pidgin/pidginstock.c --- a/pidgin/pidginstock.c Mon Apr 28 10:57:31 2014 +0200 +++ b/pidgin/pidginstock.c Tue Apr 29 02:21:07 2014 +0200 @@ -168,6 +168,7 @@ { PIDGIN_STOCK_TOOLBAR_TEXT_LARGER, "toolbar", "font-size-up.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_INSERT, "toolbar", "insert.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, "toolbar", "insert-image.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_INSERT_SCREENSHOT, "toolbar", "insert-screenshot.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_INSERT_LINK, "toolbar", "insert-link.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, "toolbar", "message-new.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TOOLBAR_PENDING, "toolbar", "message-new.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, diff -r 1c082451371d -r 98e92d543d73 pidgin/pidginstock.h --- a/pidgin/pidginstock.h Mon Apr 28 10:57:31 2014 +0200 +++ b/pidgin/pidginstock.h Tue Apr 29 02:21:07 2014 +0200 @@ -147,6 +147,7 @@ #define PIDGIN_STOCK_TOOLBAR_TEXT_LARGER "pidgin-text-larger" #define PIDGIN_STOCK_TOOLBAR_INSERT "pidgin-insert" #define PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE "pidgin-insert-image" +#define PIDGIN_STOCK_TOOLBAR_INSERT_SCREENSHOT "pidgin-insert-screenshot" #define PIDGIN_STOCK_TOOLBAR_INSERT_LINK "pidgin-insert-link" #define PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW "pidgin-message-new" #define PIDGIN_STOCK_TOOLBAR_PENDING "pidgin-pending" diff -r 1c082451371d -r 98e92d543d73 pidgin/pixmaps/Makefile.am --- a/pidgin/pixmaps/Makefile.am Mon Apr 28 10:57:31 2014 +0200 +++ b/pidgin/pixmaps/Makefile.am Tue Apr 29 02:21:07 2014 +0200 @@ -436,6 +436,7 @@ toolbar/16/insert.png \ toolbar/16/insert-image.png \ toolbar/16/insert-link.png \ + toolbar/16/insert-screenshot.png \ toolbar/16/message-new.png \ toolbar/16/plugins.png \ toolbar/16/send-file.png \ diff -r 1c082451371d -r 98e92d543d73 pidgin/pixmaps/toolbar/16/insert-screenshot.png Binary file pidgin/pixmaps/toolbar/16/insert-screenshot.png has changed diff -r 1c082451371d -r 98e92d543d73 pidgin/plugins/Makefile.am --- a/pidgin/plugins/Makefile.am Mon Apr 28 10:57:31 2014 +0200 +++ b/pidgin/plugins/Makefile.am Tue Apr 29 02:21:07 2014 +0200 @@ -46,6 +46,7 @@ markerline_la_LDFLAGS = -module @PLUGIN_LDFLAGS@ notify_la_LDFLAGS = -module @PLUGIN_LDFLAGS@ relnot_la_LDFLAGS = -module @PLUGIN_LDFLAGS@ +screencap_la_LDFLAGS = -module @PLUGIN_LDFLAGS@ sendbutton_la_LDFLAGS = -module @PLUGIN_LDFLAGS@ spellchk_la_LDFLAGS = -module @PLUGIN_LDFLAGS@ themeedit_la_LDFLAGS = -module @PLUGIN_LDFLAGS@ @@ -63,6 +64,7 @@ markerline.la \ notify.la \ relnot.la \ + screencap.la \ sendbutton.la \ spellchk.la \ themeedit.la \ @@ -86,6 +88,7 @@ markerline_la_SOURCES = markerline.c notify_la_SOURCES = notify.c relnot_la_SOURCES = relnot.c +screencap_la_SOURCES = screencap.c sendbutton_la_SOURCES = sendbutton.c spellchk_la_SOURCES = spellchk.c themeedit_la_SOURCES = themeedit.c themeedit-icon.c themeedit-icon.h @@ -102,6 +105,7 @@ markerline_la_LIBADD = @PIDGIN_LIBS@ $(WEBKIT_LIBS) notify_la_LIBADD = @PIDGIN_LIBS@ relnot_la_LIBADD = @PIDGIN_LIBS@ +screencap_la_LIBADD = @PIDGIN_LIBS@ sendbutton_la_LIBADD = @PIDGIN_LIBS@ spellchk_la_LIBADD = @PIDGIN_LIBS@ themeedit_la_LIBADD = @PIDGIN_LIBS@ diff -r 1c082451371d -r 98e92d543d73 pidgin/plugins/screencap.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/plugins/screencap.c Tue Apr 29 02:21:07 2014 +0200 @@ -0,0 +1,234 @@ +/* + * Screenshots as outgoing images plugin. + * + * 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 + */ + +/* TODO: disable, when prpl doesn't support inline images */ +/* TODO: add "Insert screenshot" to the Conversation window menu */ + +#include "internal.h" + +#include "version.h" + +#include "gtkconv.h" +#include "gtkplugin.h" +#include "gtkwebviewtoolbar.h" +#include "pidginstock.h" + +static inline void +scrncap_conv_set_data(PidginConversation *gtkconv, const gchar *key, + gpointer value) +{ + g_return_if_fail(gtkconv != NULL); + + g_object_set_data(G_OBJECT(gtkconv->tab_cont), key, value); +} + +static inline gpointer +scrncap_conv_get_data(PidginConversation *gtkconv, const gchar *key) +{ + g_return_val_if_fail(gtkconv != NULL, NULL); + + return g_object_get_data(G_OBJECT(gtkconv->tab_cont), key); +} + +static void +scrncap_conversation_init(PidginConversation *gtkconv) +{ + PidginWebViewToolbar *toolbar; + GtkAction *action; + GtkToolItem *scrncap_btn_wide; + GtkWidget *scrncap_btn_lean; + gint pos = -1, i; + GtkToolbar *wide_view, *lean_view; + GtkMenu *wide_menu = NULL; + GList *wide_children, *it; + + if (scrncap_conv_get_data(gtkconv, "scrncap-btn-wide") != NULL) + return; + + toolbar = PIDGIN_WEBVIEWTOOLBAR(pidgin_webview_get_toolbar( + PIDGIN_WEBVIEW(gtkconv->entry))); + g_return_if_fail(toolbar != NULL); + wide_view = GTK_TOOLBAR(pidgin_webviewtoolbar_get_wide_view(toolbar)); + g_return_if_fail(wide_view != NULL); + lean_view = GTK_TOOLBAR(pidgin_webviewtoolbar_get_lean_view(toolbar)); + g_return_if_fail(lean_view != NULL); + + action = gtk_action_new("InsertScreenshot", _("_Screenshot"), + _("Insert screenshot"), PIDGIN_STOCK_TOOLBAR_INSERT_SCREENSHOT); + gtk_action_set_is_important(action, TRUE); + /*g_signal_connect(G_OBJECT(action), "activate", actions[i].cb, toolbar);*/ + + scrncap_btn_wide = GTK_TOOL_ITEM(gtk_action_create_tool_item(action)); + scrncap_conv_set_data(gtkconv, "scrncap-btn-wide", scrncap_btn_wide); + for (i = 0; i < gtk_toolbar_get_n_items(wide_view); i++) { + GtkToolItem *ref_item = gtk_toolbar_get_nth_item(wide_view, i); + const gchar *action_name; + + action_name = g_object_get_data(G_OBJECT(ref_item), + "action-name"); + if (g_strcmp0(action_name, "InsertImage") == 0) { + pos = i + 1; + break; + } + } + gtk_toolbar_insert(wide_view, scrncap_btn_wide, pos); + gtk_widget_show(GTK_WIDGET(scrncap_btn_wide)); + + for (i = 0; i < gtk_toolbar_get_n_items(lean_view); i++) { + GtkToolItem *ref_item = gtk_toolbar_get_nth_item(lean_view, i); + const gchar *action_name; + + action_name = g_object_get_data(G_OBJECT(ref_item), "action-name"); + if (g_strcmp0(action_name, "insert") == 0) { + wide_menu = g_object_get_data(G_OBJECT(ref_item), "menu"); + break; + } + } + g_return_if_fail(wide_menu); + + pos = -1; + wide_children = gtk_container_get_children(GTK_CONTAINER(wide_menu)); + for (it = wide_children, i = 0; it; it = g_list_next(it), i++) { + GtkWidget *child = it->data; + const gchar *action_name; + + action_name = g_object_get_data(G_OBJECT(child), "action-name"); + if (g_strcmp0(action_name, "InsertImage") == 0) { + pos = i + 1; + break; + } + } + g_list_free(wide_children); + if (pos < 0) { + g_warn_if_fail(pos >= 0); + pos = 0; + } + + scrncap_btn_lean = gtk_action_create_menu_item(action); + scrncap_conv_set_data(gtkconv, "scrncap-btn-lean", scrncap_btn_lean); + gtk_menu_shell_insert(GTK_MENU_SHELL(wide_menu), + GTK_WIDGET(scrncap_btn_lean), pos); + gtk_widget_show(GTK_WIDGET(scrncap_btn_lean)); +} + +static void +scrncap_conversation_uninit(PidginConversation *gtkconv) +{ + GtkWidget *scrncap_btn_wide, *scrncap_btn_lean; + + scrncap_btn_wide = scrncap_conv_get_data(gtkconv, "scrncap-btn-wide"); + if (scrncap_btn_wide == NULL) + return; + + scrncap_btn_lean = scrncap_conv_get_data(gtkconv, "scrncap-btn-lean"); + + gtk_widget_destroy(scrncap_btn_wide); + if (scrncap_btn_lean) + gtk_widget_destroy(scrncap_btn_lean); + + scrncap_conv_set_data(gtkconv, "scrncap-btn-wide", NULL); + scrncap_conv_set_data(gtkconv, "scrncap-btn-lean", NULL); +} + +static gboolean +scrncap_plugin_load(PurplePlugin *plugin) +{ + GList *it; + + purple_signal_connect(pidgin_conversations_get_handle(), + "conversation-displayed", plugin, + PURPLE_CALLBACK(scrncap_conversation_init), NULL); + + it = purple_conversations_get_all(); + for (; it; it = g_list_next(it)) { + PurpleConversation *conv = it->data; + + if (!PIDGIN_IS_PIDGIN_CONVERSATION(conv)) + continue; + scrncap_conversation_init(PIDGIN_CONVERSATION(conv)); + } + + return TRUE; +} + +static gboolean +scrncap_plugin_unload(PurplePlugin *plugin) +{ + GList *it; + + it = purple_conversations_get_all(); + for (; it; it = g_list_next(it)) { + PurpleConversation *conv = it->data; + + if (!PIDGIN_IS_PIDGIN_CONVERSATION(conv)) + continue; + scrncap_conversation_uninit(PIDGIN_CONVERSATION(conv)); + } + + return TRUE; +} + +static PidginPluginUiInfo scrncap_ui_info = +{ + NULL, /* config */ + + /* padding */ + NULL, NULL, NULL, NULL +}; + +static PurplePluginInfo scrncap_info = +{ + PURPLE_PLUGIN_MAGIC, + PURPLE_MAJOR_VERSION, + PURPLE_MINOR_VERSION, + PURPLE_PLUGIN_STANDARD, + PIDGIN_PLUGIN_TYPE, + 0, + NULL, + PURPLE_PRIORITY_DEFAULT, + "gtk-screencap", + N_("Screen Capture"), + DISPLAY_VERSION, + N_("Send screenshots to your buddies."), + N_("Adds an option to send a screenshot as an inline image. " + "It works only with protocols that supports inline images."), + "Tomasz Wasilczyk ", + PURPLE_WEBSITE, + scrncap_plugin_load, + scrncap_plugin_unload, + NULL, + &scrncap_ui_info, + NULL, + NULL, + NULL, + + /* padding */ + NULL, NULL, NULL, NULL +}; + +static void +scrncap_init_plugin(PurplePlugin *plugin) +{ +#if 0 + purple_prefs_add_none("/plugins"); + purple_prefs_add_none("/plugins/gtk"); + purple_prefs_add_none("/plugins/gtk/screencap"); +#endif +} + +PURPLE_INIT_PLUGIN(screencap, scrncap_init_plugin, scrncap_info)