10 #include "gtkplugin.h"
11 #include "gtkimhtml.h"
15 static const char *format_12hour_hour(const struct tm
*tm
)
18 int hour
= tm
->tm_hour
% 12;
22 g_snprintf(hr
, sizeof(hr
), "%d", hour
);
26 static PurplePluginPrefFrame
*
27 get_plugin_pref_frame(PurplePlugin
*plugin
)
29 PurplePluginPrefFrame
*frame
;
30 PurplePluginPref
*ppref
;
33 frame
= purple_plugin_pref_frame_new();
35 ppref
= purple_plugin_pref_new_with_label(_("Timestamp Format Options"));
36 purple_plugin_pref_frame_add(frame
, ppref
);
38 tmp
= g_strdup(_("_Force timestamp format:"));
39 ppref
= purple_plugin_pref_new_with_name_and_label(
40 "/plugins/gtk/timestamp_format/force",
42 purple_plugin_pref_set_type(ppref
, PURPLE_PLUGIN_PREF_CHOICE
);
43 purple_plugin_pref_add_choice(ppref
, _("Use system default"), "default");
44 purple_plugin_pref_add_choice(ppref
, _("12 hour time format"), "force12");
45 purple_plugin_pref_add_choice(ppref
, _("24 hour time format"), "force24");
46 purple_plugin_pref_frame_add(frame
, ppref
);
49 ppref
= purple_plugin_pref_new_with_label(_("Show dates in..."));
50 purple_plugin_pref_frame_add(frame
, ppref
);
52 ppref
= purple_plugin_pref_new_with_name_and_label(
53 "/plugins/gtk/timestamp_format/use_dates/conversation",
54 _("Co_nversations:"));
55 purple_plugin_pref_set_type(ppref
, PURPLE_PLUGIN_PREF_CHOICE
);
56 purple_plugin_pref_add_choice(ppref
, _("For delayed messages"), "automatic");
57 purple_plugin_pref_add_choice(ppref
, _("For delayed messages and in chats"), "chats");
58 purple_plugin_pref_add_choice(ppref
, _("Always"), "always");
59 purple_plugin_pref_frame_add(frame
, ppref
);
61 ppref
= purple_plugin_pref_new_with_name_and_label(
62 "/plugins/gtk/timestamp_format/use_dates/log",
64 purple_plugin_pref_set_type(ppref
, PURPLE_PLUGIN_PREF_CHOICE
);
65 purple_plugin_pref_add_choice(ppref
, _("For delayed messages"), "automatic");
66 purple_plugin_pref_add_choice(ppref
, _("For delayed messages and in chats"), "chats");
67 purple_plugin_pref_add_choice(ppref
, _("Always"), "always");
68 purple_plugin_pref_frame_add(frame
, ppref
);
73 static char *timestamp_cb_common(PurpleConversation
*conv
,
82 g_return_val_if_fail(dates
!= NULL
, NULL
);
87 purple_strequal(dates
, "always") ||
88 (conv
!= NULL
&& purple_conversation_get_type(conv
) == PURPLE_CONV_TYPE_CHAT
&& purple_strequal(dates
, "chats")))
90 if (purple_strequal(force
, "force24"))
91 return g_strdup_printf("%s%s%s", parens
? "(" : "", purple_utf8_strftime("%Y-%m-%d %H:%M:%S", tm
), parens
? ")" : "");
92 else if (purple_strequal(force
, "force12")) {
93 char *date
= g_strdup_printf("%s", purple_utf8_strftime("%Y-%m-%d ", tm
));
94 char *remtime
= g_strdup_printf("%s", purple_utf8_strftime(":%M:%S %p", tm
));
95 const char *hour
= format_12hour_hour(tm
);
98 output
= g_strdup_printf("%s%s%s%s%s",
99 parens
? "(" : "", date
,
100 hour
, remtime
, parens
? ")" : "");
107 return g_strdup_printf("%s%s%s", parens
? "(" : "", purple_date_format_long(tm
), parens
? ")" : "");
110 if (purple_strequal(force
, "force24"))
111 return g_strdup_printf("%s%s%s", parens
? "(" : "", purple_utf8_strftime("%H:%M:%S", tm
), parens
? ")" : "");
112 else if (purple_strequal(force
, "force12")) {
113 const char *hour
= format_12hour_hour(tm
);
114 char *remtime
= g_strdup_printf("%s", purple_utf8_strftime(":%M:%S %p", tm
));
115 char *output
= g_strdup_printf("%s%s%s%s", parens
? "(" : "", hour
, remtime
, parens
? ")" : "");
125 static char *conversation_timestamp_cb(PurpleConversation
*conv
,
126 time_t t
, gboolean show_date
, gpointer data
)
128 const char *force
= purple_prefs_get_string(
129 "/plugins/gtk/timestamp_format/force");
130 const char *dates
= purple_prefs_get_string(
131 "/plugins/gtk/timestamp_format/use_dates/conversation");
133 g_return_val_if_fail(conv
!= NULL
, NULL
);
135 return timestamp_cb_common(conv
, t
, show_date
, force
, dates
, TRUE
);
138 static char *log_timestamp_cb(PurpleLog
*log
, time_t t
, gboolean show_date
, gpointer data
)
140 const char *force
= purple_prefs_get_string(
141 "/plugins/gtk/timestamp_format/force");
142 const char *dates
= purple_prefs_get_string(
143 "/plugins/gtk/timestamp_format/use_dates/log");
145 g_return_val_if_fail(log
!= NULL
, NULL
);
147 return timestamp_cb_common(log
->conv
, t
, show_date
, force
, dates
, FALSE
);
151 menu_cb(GtkWidget
*item
, gpointer data
)
153 PurplePlugin
*plugin
= data
;
154 GtkWidget
*frame
= pidgin_plugin_get_config_frame(plugin
), *dialog
;
158 dialog
= gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE
, NULL
,
159 GTK_DIALOG_NO_SEPARATOR
| GTK_DIALOG_DESTROY_WITH_PARENT
,
160 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
,
162 g_signal_connect_after(G_OBJECT(dialog
), "response", G_CALLBACK(gtk_widget_destroy
), dialog
);
163 #if GTK_CHECK_VERSION(2,14,0)
164 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog
))), frame
);
166 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog
)->vbox
), frame
);
168 gtk_window_set_role(GTK_WINDOW(dialog
), "plugin_config");
169 gtk_window_set_title(GTK_WINDOW(dialog
), _(purple_plugin_get_name(plugin
)));
170 gtk_widget_show_all(dialog
);
174 textview_emission_hook(GSignalInvocationHint
*hint
, guint n_params
,
175 const GValue
*pvalues
, gpointer data
)
177 GtkTextView
*view
= GTK_TEXT_VIEW(g_value_get_object(pvalues
));
178 GtkWidget
*menu
, *item
;
179 GtkTextBuffer
*buffer
;
183 if (!GTK_IS_IMHTML(view
))
186 #if GTK_CHECK_VERSION(2,14,0)
187 if (!gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(view
)), &cx
, &cy
, NULL
))
190 if (!gdk_window_get_pointer(GTK_WIDGET(view
)->window
, &cx
, &cy
, NULL
))
194 buffer
= gtk_text_view_get_buffer(view
);
196 gtk_text_view_window_to_buffer_coords(view
, GTK_TEXT_WINDOW_TEXT
, cx
, cy
, &bx
, &by
);
197 gtk_text_view_get_iter_at_location(view
, &cursor
, bx
, by
);
198 if (!gtk_text_iter_has_tag(&cursor
,
199 gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer
), "comment")))
202 menu
= g_value_get_object(&pvalues
[1]);
204 item
= gtk_menu_item_new_with_label(_("Timestamp Format Options"));
205 gtk_widget_show_all(item
);
206 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(menu_cb
), data
);
207 gtk_menu_shell_insert(GTK_MENU_SHELL(menu
), item
, 0);
209 item
= gtk_separator_menu_item_new();
210 gtk_widget_show(item
);
211 gtk_menu_shell_insert(GTK_MENU_SHELL(menu
), item
, 1);
216 static guint signal_id
;
217 static gulong hook_id
;
220 plugin_load(PurplePlugin
*plugin
)
222 gpointer klass
= NULL
;
224 purple_signal_connect(pidgin_conversations_get_handle(), "conversation-timestamp",
225 plugin
, PURPLE_CALLBACK(conversation_timestamp_cb
), NULL
);
226 purple_signal_connect(purple_log_get_handle(), "log-timestamp",
227 plugin
, PURPLE_CALLBACK(log_timestamp_cb
), NULL
);
229 klass
= g_type_class_ref(GTK_TYPE_TEXT_VIEW
);
231 /* In 3.0.0, use purple_g_signal_connect_flags */
232 g_signal_parse_name("populate_popup", GTK_TYPE_TEXT_VIEW
, &signal_id
, NULL
, FALSE
);
233 hook_id
= g_signal_add_emission_hook(signal_id
, 0, textview_emission_hook
,
236 g_type_class_unref(klass
);
242 plugin_unload(PurplePlugin
*plugin
)
244 g_signal_remove_emission_hook(signal_id
, hook_id
);
248 static PurplePluginUiInfo prefs_info
= {
249 get_plugin_pref_frame
,
250 0, /* page num (Reserved) */
251 NULL
,/* frame (Reserved) */
260 static PurplePluginInfo info
=
263 PURPLE_MAJOR_VERSION
,
264 PURPLE_MINOR_VERSION
,
265 PURPLE_PLUGIN_STANDARD
, /**< type */
266 PIDGIN_PLUGIN_TYPE
, /**< ui_requirement */
268 NULL
, /**< dependencies */
269 PURPLE_PRIORITY_DEFAULT
, /**< priority */
271 "core-timestamp_format", /**< id */
272 N_("Message Timestamp Formats"), /**< name */
273 DISPLAY_VERSION
, /**< version */
275 N_("Customizes the message timestamp formats."),
277 N_("This plugin allows the user to customize "
278 "conversation and logging message timestamp "
280 "Richard Laager <rlaager@pidgin.im>", /**< author */
281 PURPLE_WEBSITE
, /**< homepage */
283 plugin_load
, /**< load */
284 plugin_unload
, /**< unload */
285 NULL
, /**< destroy */
287 NULL
, /**< ui_info */
288 NULL
, /**< extra_info */
289 &prefs_info
, /**< prefs_info */
290 NULL
, /**< actions */
300 init_plugin(PurplePlugin
*plugin
)
302 purple_prefs_add_none("/plugins/gtk");
303 purple_prefs_add_none("/plugins/gtk/timestamp_format");
305 if (!purple_prefs_exists("/plugins/gtk/timestamp_format/force") &&
306 purple_prefs_exists("/plugins/gtk/timestamp_format/force_24hr"))
308 if (purple_prefs_get_bool(
309 "/plugins/gtk/timestamp_format/force_24hr"))
310 purple_prefs_add_string("/plugins/gtk/timestamp_format/force", "force24");
312 purple_prefs_add_string("/plugins/gtk/timestamp_format/force", "default");
315 purple_prefs_add_string("/plugins/gtk/timestamp_format/force", "default");
317 purple_prefs_add_none("/plugins/gtk/timestamp_format/use_dates");
318 purple_prefs_add_string("/plugins/gtk/timestamp_format/use_dates/conversation", "automatic");
319 purple_prefs_add_string("/plugins/gtk/timestamp_format/use_dates/log", "automatic");
322 PURPLE_INIT_PLUGIN(timestamp_format
, init_plugin
, info
)