2 * Markerline - Draw a line to indicate new messages in a conversation.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 #define PLUGIN_ID "gtk-plugin_pack-markerline"
23 #define PLUGIN_NAME N_("Markerline")
24 #define PLUGIN_CATEGORY N_("User interface")
25 #define PLUGIN_STATIC_NAME Markerline
26 #define PLUGIN_SUMMARY N_("Draw a line to indicate new messages in a conversation.")
27 #define PLUGIN_DESCRIPTION N_("Draw a line to indicate new messages in a conversation.")
28 #define PLUGIN_AUTHORS {"Sadrul H Chowdhury <sadrul@users.sourceforge.net>", NULL}
37 #include <gtkplugin.h>
38 #include <gtkwebview.h>
41 #define PREF_PREFIX "/plugins/gtk/" PLUGIN_ID
42 #define PREF_IMS PREF_PREFIX "/ims"
43 #define PREF_CHATS PREF_PREFIX "/chats"
46 update_marker_for_gtkconv(PidginConversation
*gtkconv
)
48 PurpleConversation
*conv
;
50 g_return_if_fail(gtkconv
!= NULL
);
52 conv
= gtkconv
->active_conv
;
54 if ((PURPLE_IS_CHAT_CONVERSATION(conv
) && !purple_prefs_get_bool(PREF_CHATS
)) ||
55 (PURPLE_IS_IM_CONVERSATION(conv
) && !purple_prefs_get_bool(PREF_IMS
)))
58 pidgin_webview_safe_execute_script(PIDGIN_WEBVIEW(gtkconv
->webview
),
59 "var mhr = document.getElementById(\"markerhr\");"
61 "mhr = document.createElement(\"hr\");"
62 "mhr.setAttribute(\"id\", \"markerhr\");"
63 "mhr.setAttribute(\"color\", \"#ff0000\");"
64 "mhr.setAttribute(\"size\", \"1\");"
66 "document.getElementById(\"Chat\").appendChild(mhr);");
70 focus_removed(GtkWidget
*widget
, GdkEventVisibility
*event
, PidginConvWindow
*win
)
72 PurpleConversation
*conv
;
73 PidginConversation
*gtkconv
;
75 conv
= pidgin_conv_window_get_active_conversation(win
);
76 g_return_val_if_fail(conv
!= NULL
, FALSE
);
78 gtkconv
= PIDGIN_CONVERSATION(conv
);
79 update_marker_for_gtkconv(gtkconv
);
85 page_switched(GtkWidget
*widget
, GtkWidget
*page
, gint num
, PidginConvWindow
*win
)
87 focus_removed(NULL
, NULL
, win
);
91 detach_from_gtkconv(PidginConversation
*gtkconv
, gpointer null
)
93 pidgin_webview_safe_execute_script(PIDGIN_WEBVIEW(gtkconv
->webview
),
94 "var mhr = document.getElementById(\"markerhr\");"
95 "if (mhr) mhr.parentNode.removeChild(mhr);");
99 detach_from_pidgin_window(PidginConvWindow
*win
, gpointer null
)
101 g_list_foreach(pidgin_conv_window_get_gtkconvs(win
), (GFunc
)detach_from_gtkconv
, NULL
);
102 g_signal_handlers_disconnect_by_func(G_OBJECT(win
->notebook
), page_switched
, win
);
103 g_signal_handlers_disconnect_by_func(G_OBJECT(win
->window
), focus_removed
, win
);
107 attach_to_gtkconv(PidginConversation
*gtkconv
, gpointer null
)
109 detach_from_gtkconv(gtkconv
, NULL
);
110 update_marker_for_gtkconv(gtkconv
);
114 attach_to_pidgin_window(PidginConvWindow
*win
, gpointer null
)
116 g_list_foreach(pidgin_conv_window_get_gtkconvs(win
), (GFunc
)attach_to_gtkconv
, NULL
);
118 g_signal_connect(G_OBJECT(win
->window
), "focus_out_event",
119 G_CALLBACK(focus_removed
), win
);
121 g_signal_connect(G_OBJECT(win
->notebook
), "switch_page",
122 G_CALLBACK(page_switched
), win
);
126 detach_from_all_windows(void)
128 g_list_foreach(pidgin_conv_windows_get_list(), (GFunc
)detach_from_pidgin_window
, NULL
);
132 attach_to_all_windows(void)
134 g_list_foreach(pidgin_conv_windows_get_list(), (GFunc
)attach_to_pidgin_window
, NULL
);
138 conv_created(PidginConversation
*gtkconv
, gpointer null
)
140 PidginConvWindow
*win
;
142 win
= pidgin_conv_get_window(gtkconv
);
146 detach_from_pidgin_window(win
, NULL
);
147 attach_to_pidgin_window(win
, NULL
);
151 jump_to_markerline(PurpleConversation
*conv
, gpointer null
)
153 PidginConversation
*gtkconv
= PIDGIN_CONVERSATION(conv
);
158 pidgin_webview_safe_execute_script(PIDGIN_WEBVIEW(gtkconv
->webview
),
159 "var mhr = document.getElementById(\"markerhr\");"
161 "window.scroll(0, mhr.offsetTop);"
166 conv_menu_cb(PurpleConversation
*conv
, GList
**list
)
168 gboolean enabled
= ((PURPLE_IS_IM_CONVERSATION(conv
) && purple_prefs_get_bool(PREF_IMS
)) ||
169 (PURPLE_IS_CHAT_CONVERSATION(conv
) && purple_prefs_get_bool(PREF_CHATS
)));
170 PurpleMenuAction
*action
= purple_menu_action_new(_("Jump to markerline"),
171 enabled
? PURPLE_CALLBACK(jump_to_markerline
) : NULL
, NULL
, NULL
);
172 *list
= g_list_append(*list
, action
);
175 static PurplePluginPrefFrame
*
176 get_plugin_pref_frame(PurplePlugin
*plugin
)
178 PurplePluginPrefFrame
*frame
;
179 PurplePluginPref
*pref
;
181 frame
= purple_plugin_pref_frame_new();
183 pref
= purple_plugin_pref_new_with_label(_("Draw Markerline in "));
184 purple_plugin_pref_frame_add(frame
, pref
);
186 pref
= purple_plugin_pref_new_with_name_and_label(PREF_IMS
,
188 purple_plugin_pref_frame_add(frame
, pref
);
190 pref
= purple_plugin_pref_new_with_name_and_label(PREF_CHATS
,
192 purple_plugin_pref_frame_add(frame
, pref
);
197 static PidginPluginInfo
*
198 plugin_query(GError
**error
)
200 const gchar
* const authors
[] = PLUGIN_AUTHORS
;
202 return pidgin_plugin_info_new(
205 "version", DISPLAY_VERSION
,
206 "category", PLUGIN_CATEGORY
,
207 "summary", PLUGIN_SUMMARY
,
208 "description", PLUGIN_DESCRIPTION
,
210 "website", PURPLE_WEBSITE
,
211 "abi-version", PURPLE_ABI_VERSION
,
212 "pref-frame-cb", get_plugin_pref_frame
,
218 plugin_load(PurplePlugin
*plugin
, GError
**error
)
220 purple_prefs_add_none(PREF_PREFIX
);
221 purple_prefs_add_bool(PREF_IMS
, FALSE
);
222 purple_prefs_add_bool(PREF_CHATS
, TRUE
);
224 attach_to_all_windows();
226 purple_signal_connect(pidgin_conversations_get_handle(), "conversation-displayed",
227 plugin
, PURPLE_CALLBACK(conv_created
), NULL
);
229 purple_signal_connect(purple_conversations_get_handle(), "conversation-extended-menu",
230 plugin
, PURPLE_CALLBACK(conv_menu_cb
), NULL
);
235 plugin_unload(PurplePlugin
*plugin
, GError
**error
)
237 detach_from_all_windows();
242 PURPLE_PLUGIN_INIT(PLUGIN_STATIC_NAME
, plugin_query
, plugin_load
, plugin_unload
);