Author: kelnos Date: 2009-07-16 17:31:39 +0000 (Thu, 16 Jul 2009) New Revision: 30321
Modified: xfce4-session/trunk/NEWS xfce4-session/trunk/xfce4-tips/data/Makefile.am xfce4-session/trunk/xfce4-tips/main.c Log: allow xfce4-tips to work properly without 'fortune' installed (bug 2871) patch from Enrico Troeger <enrico.troe...@uvena.de> Modified: xfce4-session/trunk/NEWS =================================================================== --- xfce4-session/trunk/NEWS 2009-07-16 07:19:38 UTC (rev 30320) +++ xfce4-session/trunk/NEWS 2009-07-16 17:31:39 UTC (rev 30321) @@ -3,6 +3,7 @@ - Query HAL to be sure suspend and hibernate are supported. If not, don't even show the buttons (bug 4952). +- Allow xfce4-tips to work when 'fortune' is not installed (bug 2871). 4.6.1 ===== Modified: xfce4-session/trunk/xfce4-tips/data/Makefile.am =================================================================== --- xfce4-session/trunk/xfce4-tips/data/Makefile.am 2009-07-16 07:19:38 UTC (rev 30320) +++ xfce4-session/trunk/xfce4-tips/data/Makefile.am 2009-07-16 17:31:39 UTC (rev 30321) @@ -1,10 +1,5 @@ tipsdir = $(datadir)/xfce4/tips -tips_DATA = \ - tips \ - tips.dat +tips_DATA = tips -tips.dat: $(srcdir)/tips - strfile $(srcdir)/tips tips.dat - EXTRA_DIST = $(tips_DATA) Modified: xfce4-session/trunk/xfce4-tips/main.c =================================================================== --- xfce4-session/trunk/xfce4-tips/main.c 2009-07-16 07:19:38 UTC (rev 30320) +++ xfce4-session/trunk/xfce4-tips/main.c 2009-07-16 17:31:39 UTC (rev 30321) @@ -52,9 +52,66 @@ static GtkWidget *dlg = NULL; static guint option = OPTION_TIPS; +static gchar *fortune_cmd = NULL; +static GPtrArray *tips = NULL; +static void +read_tips_from_file (void) +{ + gchar *data; + gchar *entry; + gsize len; + guint i, j; + GError *error = NULL; + /* read the whole file */ + g_file_get_contents (TIPSDIR "/tips", &data, &len, &error); + + tips = g_ptr_array_new (); + if (error != NULL) + { + g_ptr_array_add (tips, g_strdup_printf (_("Could not load tips database (%s)."), + error->message)); + g_free (data); + g_error_free (error); + return; + } + + entry = g_malloc (len + 1); + i = j = 0; + while (data[i]) + { + if (data[i] == '%') + { + /* add a new tip */ + entry[j] = '\0'; + j = 0; + if (entry[0]) + g_ptr_array_add (tips, g_strdup(entry)); + /* skip the following line break character(s) */ + if (data[i] == '\r' && (i + 1) < len && data[i + 1] == '\n') + i += 2; + else + i += 1; + } + else + entry[j++] = data[i]; + + i++; + } + g_free (data); + g_free (entry); +} + + +static void +free_tip (gpointer data, gpointer user_data) +{ + g_free (data); +} + + static gboolean autostart_enabled (void) { @@ -95,45 +152,91 @@ item_cb (GtkWidget *btn, gpointer data) { - option = GPOINTER_TO_UINT(data); + option = GPOINTER_TO_UINT (data); gtk_window_set_title (GTK_WINDOW (dlg), _(titles[option])); } +static gchar* +run_fortune (void) +{ + GError *error = NULL; + gchar *out = NULL; + gchar *err = NULL; + gchar *buffer = NULL; + + if (fortune_cmd != NULL && g_spawn_command_line_sync (fortune_cmd, &out, &err, NULL, &error)) + { + if (out != NULL && *out != '\0') + { + /* check output for valid UTF-8 */ + if (g_utf8_validate (out, -1, NULL)) + buffer = out; + else + { + /* we got something else than UTF-8, try to convert it from the user's locale */ + buffer = g_locale_to_utf8 (out, -1, NULL, NULL, NULL); + if (buffer == NULL) + { + /* converting it from the user's locale failed too, we give up */ + buffer = g_strdup_printf (_("Invalid output of fortune.")); + } + } + } + else + buffer = g_strdup_printf (_("Executing fortune failed (%s)"), err); + + if (buffer != out) + g_free (out); + g_free(err); + } + else + { + buffer = g_strdup_printf (_("Executing fortune failed (%s)"), error->message); + g_error_free (error); + } + + return buffer; +} + + + static void next_cb(GtkWidget *btn, GtkTextBuffer *textbuf) { - gchar buffer[1024]; + gchar *buffer = NULL; GtkTextIter start; GtkTextIter end; - FILE *fp; /* clear the text buffer */ - gtk_text_buffer_get_bounds(textbuf, &start, &end); - gtk_text_buffer_delete(textbuf, &start, &end); + gtk_text_buffer_get_bounds (textbuf, &start, &end); + gtk_text_buffer_delete (textbuf, &start, &end); - switch (option) { - case OPTION_TIPS: - strcpy(buffer, "fortune " TIPSDIR "/tips"); - break; + switch (option) + { + case OPTION_TIPS: + { + if (! tips || tips->len == 0) + buffer = _("Error while loading tips."); + else + /* no need to check or convert the encoding of our own tips file as it is already UTF-8 */ + buffer = g_ptr_array_index (tips, g_random_int_range(0, tips->len)); + break; + } + case OPTION_FORTUNES: + { + buffer = run_fortune (); + break; + } + } - case OPTION_FORTUNES: - strcpy(buffer, "fortune"); - break; - } + /* add the text to the buffer */ + gtk_text_buffer_get_end_iter (textbuf, &end); + gtk_text_buffer_insert (textbuf, &end, buffer, -1); - if ((fp = popen(buffer, "r")) == NULL) { - perror("Unable to execute fortune"); - return; - } - - while (fgets(buffer, sizeof(buffer), fp) != NULL) { - gtk_text_buffer_get_end_iter(textbuf, &end); - gtk_text_buffer_insert(textbuf, &end, buffer, -1); - } - - pclose (fp); + if (option == OPTION_FORTUNES) + g_free (buffer); } @@ -155,6 +258,11 @@ gtk_init (&argc, &argv); + /* test for fortune */ + fortune_cmd = g_find_program_in_path ("fortune"); + + read_tips_from_file (); + /* fake a SM client id, so the session manager does not restart us */ gdk_set_sm_client_id ("FAKED CLIENTID"); @@ -193,26 +301,29 @@ gtk_box_pack_start (GTK_BOX (vbox2), check, FALSE, FALSE, 0); gtk_widget_show (check); - menu = gtk_menu_new (); - gtk_widget_show (menu); - - item = gtk_menu_item_new_with_label (_("Tips and tricks")); - g_signal_connect (item, "activate", G_CALLBACK (item_cb), GUINT_TO_POINTER (OPTION_TIPS)); - g_signal_connect (item, "activate", G_CALLBACK (next_cb), gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); + if (fortune_cmd != NULL) + { + menu = gtk_menu_new (); + gtk_widget_show (menu); - item = gtk_menu_item_new_with_label (_("Fortunes")); - g_signal_connect (item, "activate", G_CALLBACK (item_cb), GUINT_TO_POINTER (OPTION_FORTUNES)); - g_signal_connect (item, "activate", G_CALLBACK (next_cb), gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); + item = gtk_menu_item_new_with_label (_(titles[OPTION_TIPS])); + g_signal_connect (item, "activate", G_CALLBACK (item_cb), GUINT_TO_POINTER (OPTION_TIPS)); + g_signal_connect (item, "activate", G_CALLBACK (next_cb), gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); - opt = gtk_option_menu_new(); - gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); - gtk_dialog_add_action_widget (GTK_DIALOG (dlg), opt, GTK_RESPONSE_NONE); - gtk_widget_show(opt); + item = gtk_menu_item_new_with_label (_(titles[OPTION_FORTUNES])); + g_signal_connect (item, "activate", G_CALLBACK (item_cb), GUINT_TO_POINTER (OPTION_FORTUNES)); + g_signal_connect (item, "activate", G_CALLBACK (next_cb), gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); + opt = gtk_option_menu_new(); + gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); + gtk_dialog_add_action_widget (GTK_DIALOG (dlg), opt, GTK_RESPONSE_NONE); + gtk_widget_show(opt); + } + next = gtk_button_new_with_label (_("Next")); gtk_dialog_add_action_widget (GTK_DIALOG (dlg), next, GTK_RESPONSE_NONE); gtk_widget_show (next); @@ -232,5 +343,14 @@ gtk_main (); + + /* cleanup */ + g_free (fortune_cmd); + if (tips != NULL) + { + g_ptr_array_foreach (tips, free_tip, NULL); + g_ptr_array_free (tips, TRUE); + } + return EXIT_SUCCESS; } _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits