313
320
struct rfc822_header *rfc822 = rfc822_parse_stanza(f);
315
322
char *cmd = rfc822_header_lookup(rfc822, "Command");
316
char *term = g_strstrip(rfc822_header_lookup(rfc822, "Terminal"));
317
g_object_set_data(G_OBJECT(button_run),"cmd", g_strdup(cmd));
318
g_object_set_data(G_OBJECT(button_run),"term", g_strdup(term));
319
g_object_set_data(G_OBJECT(button_run),"hook_file", hf);
323
char *term = rfc822_header_lookup(rfc822, "Terminal");
325
term = g_strstrip(term);
326
g_object_set_data(G_OBJECT(priv->button_run),"cmd", g_strdup(cmd));
327
g_object_set_data(G_OBJECT(priv->button_run),"term", g_strdup(term));
328
g_object_set_data(G_OBJECT(priv->button_run),"hook_file", hf);
320
329
if(cmd != NULL) {
321
gtk_widget_show(button_run);
330
gtk_widget_show(priv->button_run);
323
gtk_widget_hide(button_run);
332
gtk_widget_hide(priv->button_run);
325
334
char *title_str = hook_file_lookup_i18n(rfc822, "Title");
326
335
if(title_str != NULL) {
327
336
gchar *s = g_strdup_printf("<span weight=\"bold\" size=\"larger\">%s</span>", title_str);
328
gtk_label_set_markup(GTK_LABEL(title), s);
337
gtk_label_set_markup(GTK_LABEL(priv->label_title), s);
331
340
char *summary = hook_description_get_summary(rfc822);
404
413
hf = (HookFile*)g_object_get_data(G_OBJECT(self),"HookFile");
406
g_warning("button_next called without HookFile\n");
415
g_warning("button_next called without HookFile");
411
420
hook_file_mark_as_seen(priv, hf);
412
check_update_hooks(ta);
414
422
if(priv->hook_files != NULL)
415
423
show_next_hook(ta, priv->hook_files);
418
void show_hooks(TrayApplet *ta, gboolean focus_on_map)
427
on_insert_text(GtkTextBuffer *buffer,
428
GtkTextIter *iter_end,
433
GtkTextIter iter, match_start, match_end, match_tmp;
435
// get where we start
436
gtk_text_buffer_get_iter_at_offset(buffer, &iter,
437
gtk_text_iter_get_offset(iter_end) - g_utf8_strlen(text,-1));
438
// search for http:// uris
439
while(gtk_text_iter_forward_search(&iter,
440
"http://", GTK_TEXT_SEARCH_VISIBLE_ONLY,
441
&match_start, &match_end, iter_end)) {
442
match_tmp = match_end;
443
// we found a uri, iterate it until the end is found
444
while(gtk_text_iter_forward_char(&match_tmp)) {
445
gchar *s = gtk_text_iter_get_text(&match_end,&match_tmp);
448
char c = s[strlen(s)-1];
449
if(c == ' ' || c == ')' || c == ']' || c == '\n' || c == '\t' || c == '>')
451
match_end = match_tmp;
453
gchar *url = gtk_text_iter_get_text(&match_start, &match_end);
454
//g_print("url: '%s'\n",url);
456
tag = gtk_text_buffer_create_tag(buffer, NULL,
458
"underline", PANGO_UNDERLINE_SINGLE,
460
g_object_set_data(G_OBJECT(tag), "url", url);
461
gtk_text_buffer_apply_tag(buffer, tag, &match_start, &match_end);
467
on_event_after(GtkWidget *widget,
468
GdkEventButton *event,
471
if(event->type != GDK_BUTTON_RELEASE)
473
if(event->button != 1)
476
gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget),
477
GTK_TEXT_WINDOW_WIDGET,
481
gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &iter, x, y);
482
GSList *tags = gtk_text_iter_get_tags(&iter);
483
for( ; tags != NULL ; tags = tags->next) {
484
gchar *url = g_object_get_data(G_OBJECT(tags->data), "url");
486
//g_print("click: '%s'\n",url);
487
char *argv[] = { "/usr/bin/gnome-open", url, NULL };
488
g_spawn_async(NULL, argv, NULL, 0, NULL, NULL, NULL, NULL);
495
show_hooks(TrayApplet *ta, gboolean focus_on_map)
497
HookTrayAppletPrivate *priv = (HookTrayAppletPrivate *)ta->user_data;
499
GError *error = NULL;
420
501
g_debug_hooks("show_hooks()");
421
HookTrayAppletPrivate* priv = (HookTrayAppletPrivate *)ta->user_data;
423
GtkBuilder *builder = priv->gtk_builder;
424
GtkWidget *dia = GTK_WIDGET (gtk_builder_get_object(builder, "dialog_hooks"));
425
gtk_window_set_title(GTK_WINDOW(dia), _("Information available"));
427
GtkWidget *button_run = GTK_WIDGET (gtk_builder_get_object(builder, "button_run"));
429
GtkWidget *button_next = GTK_WIDGET (gtk_builder_get_object(builder, "button_next"));
432
gtk_window_set_focus_on_map(GTK_WINDOW(dia), focus_on_map);
503
builder = gtk_builder_new ();
506
if (!gtk_builder_add_from_file (builder, UIDIR"hooks-dialog.ui", &error)) {
507
g_warning ("Couldn't load builder file: %s", error->message);
508
g_error_free (error);
511
gtk_builder_connect_signals (builder, (gpointer)ta);
513
priv->dialog_hooks = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_hooks"));
514
gtk_window_set_title (GTK_WINDOW (priv->dialog_hooks), _("Information available"));
515
assert (priv->dialog_hooks);
516
priv->label_title = GTK_WIDGET (gtk_builder_get_object (builder, "label_title"));
517
assert (priv->label_title);
518
priv->textview_hook = GTK_WIDGET (gtk_builder_get_object (builder, "textview_hook"));
519
assert (priv->textview_hook);
520
priv->button_run = GTK_WIDGET (gtk_builder_get_object (builder, "button_run"));
521
assert (priv->button_run);
522
priv->button_next = GTK_WIDGET (gtk_builder_get_object (builder, "button_next"));
523
assert (priv->button_next);
525
g_object_unref (G_OBJECT (builder));
528
GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->textview_hook));
529
gtk_text_buffer_create_tag (buf, "bold_tag",
530
"scale", PANGO_SCALE_LARGE,
531
"weight", PANGO_WEIGHT_BOLD,
533
g_signal_connect_after (G_OBJECT (buf), "insert-text",
534
G_CALLBACK (on_insert_text), NULL);
535
g_signal_connect_after (G_OBJECT (priv->textview_hook), "event-after",
536
G_CALLBACK (on_event_after), NULL);
538
gtk_window_set_focus_on_map (GTK_WINDOW (priv->dialog_hooks), focus_on_map);
434
540
// if show_next_hook() fails for some reason don't do anything
435
541
if(!show_next_hook(ta, priv->hook_files))
438
int res = gtk_dialog_run(GTK_DIALOG(dia));
544
int res = gtk_dialog_run (GTK_DIALOG (priv->dialog_hooks));
439
545
if(res == GTK_RESPONSE_CLOSE) {
440
546
// mark the currently current hookfile as seen
442
hf = (HookFile*)g_object_get_data(G_OBJECT(button_next),"HookFile");
548
hf = (HookFile*)g_object_get_data (G_OBJECT (priv->button_next), "HookFile");
444
g_warning("show_hooks called without HookFile\n");
550
g_warning("show_hooks called without HookFile");
539
651
TrayApplet *ta = (TrayApplet*)data;
540
652
HookTrayAppletPrivate *priv = (HookTrayAppletPrivate*)ta->user_data;
542
if(!gtk_status_icon_get_visible(ta->tray_icon))
545
GtkWidget *d = GTK_WIDGET (gtk_builder_get_object(priv->gtk_builder,"dialog_hooks"));
546
if((d && GTK_WIDGET_VISIBLE(d)) || priv->active_notification != NULL)
550
gtk_status_icon_get_geometry(ta->tray_icon, NULL, &area, NULL);
551
// no usefull coordiante yet, do another timeout
552
if(area.x <= 0 || area.y <= 0 || area.width <= 0 || area.height <= 0)
654
if(!tray_applet_ui_get_visible(ta))
657
if((priv->dialog_hooks && gtk_widget_get_visible(priv->dialog_hooks)) ||
658
priv->active_notification != NULL)
555
661
NotifyNotification *n;
557
n = notify_notification_new_with_status_icon(
663
n = notify_notification_new(
558
664
_("Information available"),
559
665
_("Click on the notification icon"
560
666
" to show the available information.\n"),
564
669
pix = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
565
670
GTK_STOCK_DIALOG_INFO, 48,0,NULL);
669
776
//g_debug_hooks("hooks: %i (new: %i)", g_list_length(hook_files), unseen_count);
671
GtkBuilder *builder = priv->gtk_builder;
672
GtkWidget *button_next = GTK_WIDGET (gtk_builder_get_object(builder, "button_next"));
675
// check if we do a notification or a dialog
676
GConfClient *gconf = gconf_client_get_default();
677
if(gconf_client_get_bool(gconf, GCONF_KEY_AUTO_LAUNCH, NULL)) {
778
if (unseen_count > 0) {
779
// we only do a dialog
678
780
g_debug_hooks("showing hooks with focus on map == FALSE");
679
if (unseen_count < 2)
680
gtk_widget_hide(button_next);
682
gtk_widget_show(button_next);
683
781
show_hooks(ta, FALSE);
687
// no dialog, do the notification
688
if((unseen_count > 0) && !gtk_status_icon_get_visible (ta->tray_icon))
689
g_timeout_add(5000, show_notification, ta);
691
switch(unseen_count) {
693
gtk_status_icon_set_visible (ta->tray_icon, FALSE);
694
gtk_widget_hide(button_next);
697
gtk_status_icon_set_visible (ta->tray_icon, TRUE);
698
gtk_widget_hide(button_next);
701
gtk_status_icon_set_visible (ta->tray_icon, TRUE);
702
gtk_widget_show(button_next);
705
hooks_trayicon_update_tooltip (ta, unseen_count);
784
tray_applet_ui_destroy (ta);
710
void hook_read_seen_file(HookTrayAppletPrivate *priv, const char* filename)
790
hook_read_seen_file(HookTrayAppletPrivate *priv, const char* filename)
772
852
init_already_seen_hooks(TrayApplet *ta)
774
854
g_debug_hooks("init_already_seen_hooks");
776
856
HookTrayAppletPrivate* priv = (HookTrayAppletPrivate*)ta->user_data;
857
char *filename, *old_filename;
779
859
// init with default value
780
860
priv->hook_files = NULL;
782
862
// read global hook file
783
hook_read_seen_file(priv,GLOBAL_HOOKS_SEEN);
863
hook_read_seen_file(priv, GLOBAL_HOOKS_SEEN);
865
filename = g_strdup_printf("%s/%s",
866
g_get_user_config_dir(),
868
// compat with the previous version
869
old_filename = g_strdup_printf("%s/%s",
871
HOOKS_SEEN_DEPRECATED);
872
if (g_file_test(old_filename, G_FILE_TEST_IS_REGULAR)) {
873
g_rename(old_filename, filename);
785
875
// read user hook file
786
filename = g_strdup_printf("%s/%s", g_get_home_dir(),HOOKS_SEEN);
787
876
hook_read_seen_file(priv,filename);
788
877
g_free(filename);
878
g_free(old_filename);
794
on_insert_text(GtkTextBuffer *buffer,
795
GtkTextIter *iter_end,
800
GtkTextIter iter, match_start, match_end, match_tmp;
802
// get where we start
803
gtk_text_buffer_get_iter_at_offset(buffer, &iter,
804
gtk_text_iter_get_offset(iter_end) - g_utf8_strlen(text,-1));
805
// search for http:// uris
806
while(gtk_text_iter_forward_search(&iter,
807
"http://", GTK_TEXT_SEARCH_VISIBLE_ONLY,
808
&match_start, &match_end, iter_end)) {
809
match_tmp = match_end;
810
// we found a uri, iterate it until the end is found
811
while(gtk_text_iter_forward_char(&match_tmp)) {
812
gchar *s = gtk_text_iter_get_text(&match_end,&match_tmp);
815
char c = s[strlen(s)-1];
816
if(c == ' ' || c == ')' || c == ']' || c == '\n' || c == '\t' || c == '>')
818
match_end = match_tmp;
820
gchar *url = gtk_text_iter_get_text(&match_start, &match_end);
821
//g_print("url: '%s'\n",url);
823
tag = gtk_text_buffer_create_tag(buffer, NULL,
825
"underline", PANGO_UNDERLINE_SINGLE,
827
g_object_set_data(G_OBJECT(tag), "url", url);
828
gtk_text_buffer_apply_tag(buffer, tag, &match_start, &match_end);
834
on_event_after(GtkWidget *widget,
835
GdkEventButton *event,
838
if(event->type != GDK_BUTTON_RELEASE)
840
if(event->button != 1)
843
gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget),
844
GTK_TEXT_WINDOW_WIDGET,
848
gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &iter, x, y);
849
GSList *tags = gtk_text_iter_get_tags(&iter);
850
for( ; tags != NULL ; tags = tags->next) {
851
gchar *url = g_object_get_data(G_OBJECT(tags->data), "url");
853
//g_print("click: '%s'\n",url);
854
char *argv[] = { "/usr/bin/gnome-open", url, NULL };
855
g_spawn_async(NULL, argv, NULL, 0, NULL, NULL, NULL, NULL);
861
883
void hook_tray_icon_init(TrayApplet *ta)
863
GError* error = NULL;
864
GtkBuilder* builder = gtk_builder_new ();
866
885
HookTrayAppletPrivate *priv = g_new0(HookTrayAppletPrivate, 1);
867
886
ta->user_data = priv;
869
if (!gtk_builder_add_from_file (builder, UIDIR"hooks-dialog.ui", &error)) {
870
g_warning ("Couldn't load builder file: %s", error->message);
871
g_error_free (error);
875
priv->gtk_builder = builder;
876
gtk_builder_connect_signals (builder, (gpointer)ta);
878
/* show dialog on click */
879
g_signal_connect (G_OBJECT(ta->tray_icon),
881
G_CALLBACK (button_release_cb),
885
GtkWidget *text = GTK_WIDGET (gtk_builder_get_object(builder, "textview_hook"));
886
GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
887
gtk_text_buffer_create_tag (buf, "bold_tag",
888
"scale", PANGO_SCALE_LARGE,
889
"weight", PANGO_WEIGHT_BOLD,
891
g_signal_connect_after(G_OBJECT(buf), "insert-text",
892
G_CALLBACK(on_insert_text), NULL);
893
g_signal_connect_after(G_OBJECT(text), "event-after",
894
G_CALLBACK(on_event_after), NULL);
897
888
/* read already seen hooks */
898
889
init_already_seen_hooks(ta);