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

Reply via email to