317
320
struct rfc822_header *rfc822 = rfc822_parse_stanza(f);
319
322
char *cmd = rfc822_header_lookup(rfc822, "Command");
320
char *term = g_strstrip(rfc822_header_lookup(rfc822, "Terminal"));
321
g_object_set_data(G_OBJECT(button_run),"cmd", g_strdup(cmd));
322
g_object_set_data(G_OBJECT(button_run),"term", g_strdup(term));
323
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);
324
329
if(cmd != NULL) {
325
gtk_widget_show(button_run);
330
gtk_widget_show(priv->button_run);
327
gtk_widget_hide(button_run);
332
gtk_widget_hide(priv->button_run);
329
334
char *title_str = hook_file_lookup_i18n(rfc822, "Title");
330
335
if(title_str != NULL) {
331
336
gchar *s = g_strdup_printf("<span weight=\"bold\" size=\"larger\">%s</span>", title_str);
332
gtk_label_set_markup(GTK_LABEL(title), s);
337
gtk_label_set_markup(GTK_LABEL(priv->label_title), s);
335
340
char *summary = hook_description_get_summary(rfc822);
408
413
hf = (HookFile*)g_object_get_data(G_OBJECT(self),"HookFile");
410
g_warning("button_next called without HookFile\n");
415
g_warning("button_next called without HookFile");
415
420
hook_file_mark_as_seen(priv, hf);
416
check_update_hooks(ta);
418
422
if(priv->hook_files != NULL)
419
423
show_next_hook(ta, priv->hook_files);
422
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;
424
501
g_debug_hooks("show_hooks()");
425
HookTrayAppletPrivate* priv = (HookTrayAppletPrivate *)ta->user_data;
427
GtkBuilder *builder = priv->gtk_builder;
428
GtkWidget *dia = GTK_WIDGET (gtk_builder_get_object(builder, "dialog_hooks"));
429
gtk_window_set_title(GTK_WINDOW(dia), _("Information available"));
431
GtkWidget *button_run = GTK_WIDGET (gtk_builder_get_object(builder, "button_run"));
433
GtkWidget *button_next = GTK_WIDGET (gtk_builder_get_object(builder, "button_next"));
436
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);
438
540
// if show_next_hook() fails for some reason don't do anything
439
541
if(!show_next_hook(ta, priv->hook_files))
442
int res = gtk_dialog_run(GTK_DIALOG(dia));
544
int res = gtk_dialog_run (GTK_DIALOG (priv->dialog_hooks));
443
545
if(res == GTK_RESPONSE_CLOSE) {
444
546
// mark the currently current hookfile as seen
446
hf = (HookFile*)g_object_get_data(G_OBJECT(button_next),"HookFile");
548
hf = (HookFile*)g_object_get_data (G_OBJECT (priv->button_next), "HookFile");
448
g_warning("show_hooks called without HookFile\n");
550
g_warning("show_hooks called without HookFile");
543
651
TrayApplet *ta = (TrayApplet*)data;
544
652
HookTrayAppletPrivate *priv = (HookTrayAppletPrivate*)ta->user_data;
546
if(!gtk_status_icon_get_visible(ta->tray_icon))
549
GtkWidget *d = GTK_WIDGET (gtk_builder_get_object(priv->gtk_builder,"dialog_hooks"));
550
if((d && gtk_widget_get_visible(d)) || priv->active_notification != NULL)
554
gtk_status_icon_get_geometry(ta->tray_icon, NULL, &area, NULL);
555
// no usefull coordiante yet, do another timeout
556
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)
559
661
NotifyNotification *n;
561
n = notify_notification_new_with_status_icon(
663
n = notify_notification_new(
562
664
_("Information available"),
563
665
_("Click on the notification icon"
564
666
" to show the available information.\n"),
568
669
pix = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
569
670
GTK_STOCK_DIALOG_INFO, 48,0,NULL);
673
776
//g_debug_hooks("hooks: %i (new: %i)", g_list_length(hook_files), unseen_count);
675
GtkBuilder *builder = priv->gtk_builder;
676
GtkWidget *button_next = GTK_WIDGET (gtk_builder_get_object(builder, "button_next"));
679
// check if we do a notification or a dialog
680
GConfClient *gconf = gconf_client_get_default();
681
if(gconf_client_get_bool(gconf, GCONF_KEY_AUTO_LAUNCH, NULL)) {
778
if (unseen_count > 0) {
779
// we only do a dialog
682
780
g_debug_hooks("showing hooks with focus on map == FALSE");
683
if (unseen_count < 2)
684
gtk_widget_hide(button_next);
686
gtk_widget_show(button_next);
687
781
show_hooks(ta, FALSE);
691
// no dialog, do the notification
692
if((unseen_count > 0) && !gtk_status_icon_get_visible (ta->tray_icon))
693
g_timeout_add(5000, show_notification, ta);
695
switch(unseen_count) {
697
gtk_status_icon_set_visible (ta->tray_icon, FALSE);
698
gtk_widget_hide(button_next);
701
gtk_status_icon_set_visible (ta->tray_icon, TRUE);
702
gtk_widget_hide(button_next);
705
gtk_status_icon_set_visible (ta->tray_icon, TRUE);
706
gtk_widget_show(button_next);
709
hooks_trayicon_update_tooltip (ta, unseen_count);
784
tray_applet_ui_destroy (ta);
714
void hook_read_seen_file(HookTrayAppletPrivate *priv, const char* filename)
790
hook_read_seen_file(HookTrayAppletPrivate *priv, const char* filename)
799
875
// read user hook file
800
876
hook_read_seen_file(priv,filename);
801
877
g_free(filename);
878
g_free(old_filename);
807
on_insert_text(GtkTextBuffer *buffer,
808
GtkTextIter *iter_end,
813
GtkTextIter iter, match_start, match_end, match_tmp;
815
// get where we start
816
gtk_text_buffer_get_iter_at_offset(buffer, &iter,
817
gtk_text_iter_get_offset(iter_end) - g_utf8_strlen(text,-1));
818
// search for http:// uris
819
while(gtk_text_iter_forward_search(&iter,
820
"http://", GTK_TEXT_SEARCH_VISIBLE_ONLY,
821
&match_start, &match_end, iter_end)) {
822
match_tmp = match_end;
823
// we found a uri, iterate it until the end is found
824
while(gtk_text_iter_forward_char(&match_tmp)) {
825
gchar *s = gtk_text_iter_get_text(&match_end,&match_tmp);
828
char c = s[strlen(s)-1];
829
if(c == ' ' || c == ')' || c == ']' || c == '\n' || c == '\t' || c == '>')
831
match_end = match_tmp;
833
gchar *url = gtk_text_iter_get_text(&match_start, &match_end);
834
//g_print("url: '%s'\n",url);
836
tag = gtk_text_buffer_create_tag(buffer, NULL,
838
"underline", PANGO_UNDERLINE_SINGLE,
840
g_object_set_data(G_OBJECT(tag), "url", url);
841
gtk_text_buffer_apply_tag(buffer, tag, &match_start, &match_end);
847
on_event_after(GtkWidget *widget,
848
GdkEventButton *event,
851
if(event->type != GDK_BUTTON_RELEASE)
853
if(event->button != 1)
856
gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget),
857
GTK_TEXT_WINDOW_WIDGET,
861
gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &iter, x, y);
862
GSList *tags = gtk_text_iter_get_tags(&iter);
863
for( ; tags != NULL ; tags = tags->next) {
864
gchar *url = g_object_get_data(G_OBJECT(tags->data), "url");
866
//g_print("click: '%s'\n",url);
867
char *argv[] = { "/usr/bin/gnome-open", url, NULL };
868
g_spawn_async(NULL, argv, NULL, 0, NULL, NULL, NULL, NULL);
874
883
void hook_tray_icon_init(TrayApplet *ta)
876
GError* error = NULL;
877
GtkBuilder* builder = gtk_builder_new ();
879
885
HookTrayAppletPrivate *priv = g_new0(HookTrayAppletPrivate, 1);
880
886
ta->user_data = priv;
882
if (!gtk_builder_add_from_file (builder, UIDIR"hooks-dialog.ui", &error)) {
883
g_warning ("Couldn't load builder file: %s", error->message);
884
g_error_free (error);
888
priv->gtk_builder = builder;
889
gtk_builder_connect_signals (builder, (gpointer)ta);
891
/* show dialog on click */
892
g_signal_connect (G_OBJECT(ta->tray_icon),
894
G_CALLBACK (button_release_cb),
898
GtkWidget *text = GTK_WIDGET (gtk_builder_get_object(builder, "textview_hook"));
899
GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
900
gtk_text_buffer_create_tag (buf, "bold_tag",
901
"scale", PANGO_SCALE_LARGE,
902
"weight", PANGO_WEIGHT_BOLD,
904
g_signal_connect_after(G_OBJECT(buf), "insert-text",
905
G_CALLBACK(on_insert_text), NULL);
906
g_signal_connect_after(G_OBJECT(text), "event-after",
907
G_CALLBACK(on_event_after), NULL);
910
888
/* read already seen hooks */
911
889
init_already_seen_hooks(ta);