2 * Purple - iChat-style timestamps
4 * Copyright (C) 2002-2003, Sean Egan
5 * Copyright (C) 2003, Chris J. Friesen <Darth_Sebulba04@yahoo.com>
6 * Copyright (C) 2007, Andrew Gaul <andrew@gaul.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 #include "conversation.h"
32 #include "gtkimhtml.h"
33 #include "gtkplugin.h"
37 #define TIMESTAMP_PLUGIN_ID "gtk-timestamp"
39 /* minutes externally, seconds internally, and milliseconds in preferences */
40 static int interval
= 5 * 60;
43 timestamp_display(PurpleConversation
*conv
, time_t then
, time_t now
)
45 PidginConversation
*gtk_conv
= PIDGIN_CONVERSATION(conv
);
46 GtkWidget
*imhtml
= gtk_conv
->imhtml
;
47 GtkTextBuffer
*buffer
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(imhtml
));
52 gboolean scrolled
= FALSE
;
55 /* display timestamp */
56 mdate
= purple_utf8_strftime(then
== 0 ? "%H:%M" : "\n%H:%M",
58 gtk_text_buffer_get_end_iter(buffer
, &iter
);
60 /* is the view already scrolled? */
61 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml
), &rect
);
62 gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml
), &iter
, &y
, &height
);
63 if (((y
+ height
) - (rect
.y
+ rect
.height
)) > height
)
66 if ((tag
= gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer
), "TIMESTAMP")) == NULL
)
67 tag
= gtk_text_buffer_create_tag(buffer
, "TIMESTAMP",
68 "foreground", "#888888", "justification", GTK_JUSTIFY_CENTER
,
69 "weight", PANGO_WEIGHT_BOLD
, NULL
);
71 gtk_text_buffer_insert_with_tags(buffer
, &iter
, mdate
,
72 strlen(mdate
), tag
, NULL
);
74 /* scroll view if necessary */
75 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml
), &rect
);
76 gtk_text_view_get_line_yrange(
77 GTK_TEXT_VIEW(imhtml
), &iter
, &y
, &height
);
78 if (!scrolled
&& ((y
+ height
) - (rect
.y
+ rect
.height
)) > height
&&
79 gtk_text_buffer_get_char_count(buffer
)) {
80 gboolean smooth
= purple_prefs_get_bool(
81 PIDGIN_PREFS_ROOT
"/conversations/use_smooth_scrolling");
82 gtk_imhtml_scroll_to_end(GTK_IMHTML(imhtml
), smooth
);
87 timestamp_displaying_conv_msg(PurpleAccount
*account
, const char *who
,
88 char **buffer
, PurpleConversation
*conv
,
89 PurpleMessageFlags flags
, void *data
)
91 time_t now
= time(NULL
) / interval
* interval
;
94 if (!g_list_find(purple_get_conversations(), conv
))
97 then
= GPOINTER_TO_INT(purple_conversation_get_data(
98 conv
, "timestamp-last"));
100 if (now
- then
>= interval
) {
101 timestamp_display(conv
, then
, now
);
102 purple_conversation_set_data(
103 conv
, "timestamp-last", GINT_TO_POINTER(now
));
110 timestamp_new_convo(PurpleConversation
*conv
)
112 if (!g_list_find(purple_get_conversations(), conv
))
115 purple_conversation_set_data(conv
, "timestamp-last", GINT_TO_POINTER(0));
119 set_timestamp(GtkWidget
*spinner
, void *null
)
123 tm
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner
));
124 purple_debug(PURPLE_DEBUG_MISC
, "timestamp",
125 "setting interval to %d minutes\n", tm
);
128 purple_prefs_set_int("/plugins/gtk/timestamp/interval", interval
* 1000);
132 get_config_frame(PurplePlugin
*plugin
)
135 GtkWidget
*frame
, *label
;
136 GtkWidget
*vbox
, *hbox
;
140 ret
= gtk_vbox_new(FALSE
, 18);
141 gtk_container_set_border_width (GTK_CONTAINER (ret
), 12);
143 frame
= pidgin_make_frame(ret
, _("Display Timestamps Every"));
144 vbox
= gtk_vbox_new(FALSE
, 5);
145 gtk_container_add(GTK_CONTAINER(frame
), vbox
);
147 hbox
= gtk_hbox_new(FALSE
, 5);
148 gtk_box_pack_start(GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 5);
150 /* XXX limit to divisors of 60? */
151 adj
= gtk_adjustment_new(interval
/ 60, 1, 60, 1, 0, 0);
152 spinner
= gtk_spin_button_new(GTK_ADJUSTMENT(adj
), 0, 0);
153 gtk_box_pack_start(GTK_BOX(hbox
), spinner
, TRUE
, TRUE
, 0);
154 g_signal_connect(G_OBJECT(spinner
), "value-changed",
155 G_CALLBACK(set_timestamp
), NULL
);
156 label
= gtk_label_new(_("minutes"));
157 gtk_box_pack_start(GTK_BOX(hbox
), label
, FALSE
, FALSE
, 5);
159 gtk_widget_show_all(ret
);
164 plugin_load(PurplePlugin
*plugin
)
166 void *conv_handle
= purple_conversations_get_handle();
167 void *gtkconv_handle
= pidgin_conversations_get_handle();
169 /* lower priority to display initial timestamp after logged messages */
170 purple_signal_connect_priority(conv_handle
, "conversation-created",
171 plugin
, PURPLE_CALLBACK(timestamp_new_convo
), NULL
,
172 PURPLE_SIGNAL_PRIORITY_DEFAULT
+ 1);
174 purple_signal_connect(gtkconv_handle
, "displaying-chat-msg",
175 plugin
, PURPLE_CALLBACK(timestamp_displaying_conv_msg
), NULL
);
176 purple_signal_connect(gtkconv_handle
, "displaying-im-msg",
177 plugin
, PURPLE_CALLBACK(timestamp_displaying_conv_msg
), NULL
);
179 interval
= purple_prefs_get_int("/plugins/gtk/timestamp/interval") / 1000;
184 static PidginPluginUiInfo ui_info
=
187 0, /* page_num (Reserved) */
196 static PurplePluginInfo info
=
199 PURPLE_MAJOR_VERSION
,
200 PURPLE_MINOR_VERSION
,
201 PURPLE_PLUGIN_STANDARD
, /**< type */
202 PIDGIN_PLUGIN_TYPE
, /**< ui_requirement */
204 NULL
, /**< dependencies */
205 PURPLE_PRIORITY_DEFAULT
, /**< priority */
207 TIMESTAMP_PLUGIN_ID
, /**< id */
208 N_("Timestamp"), /**< name */
209 DISPLAY_VERSION
, /**< version */
211 N_("Display iChat-style timestamps"),
213 N_("Display iChat-style timestamps every N minutes."),
214 "Sean Egan <seanegan@gmail.com>", /**< author */
215 PURPLE_WEBSITE
, /**< homepage */
217 plugin_load
, /**< load */
219 NULL
, /**< destroy */
221 &ui_info
, /**< ui_info */
222 NULL
, /**< extra_info */
234 init_plugin(PurplePlugin
*plugin
)
236 purple_prefs_add_none("/plugins/gtk/timestamp");
237 purple_prefs_add_int("/plugins/gtk/timestamp/interval", interval
* 1000);
240 PURPLE_INIT_PLUGIN(timestamp
, init_plugin
, info
)