[pan2] https://bugzilla.gnome.org/show_bug.cgi?id=412890



commit 81d9e4ee78cfe5f35d001b76ebb714738264e00e
Author: Heinrich MÃller <henmull src gnome org>
Date:   Sun Dec 18 13:04:12 2011 +0100

    https://bugzilla.gnome.org/show_bug.cgi?id=412890

 pan/general/utf8-utils.cc      |    2 +-
 pan/gui/body-pane.cc           |    2 +
 pan/gui/gui.cc                 |   30 ++++++++++--
 pan/gui/header-pane.cc         |   38 ++++++++++++++--
 pan/gui/header-pane.h          |    1 +
 pan/usenet-utils/mime-utils.cc |   97 +++++++++++++++++++++++++++++++++++++++-
 pan/usenet-utils/mime-utils.h  |   16 ++++++-
 7 files changed, 172 insertions(+), 14 deletions(-)
---
diff --git a/pan/general/utf8-utils.cc b/pan/general/utf8-utils.cc
index 854c7ca..0c2fe18 100644
--- a/pan/general/utf8-utils.cc
+++ b/pan/general/utf8-utils.cc
@@ -196,7 +196,7 @@ pan :: content_to_utf8 (const StringView  & content,
 
       // try each charset in turn
       for (size_t i=0; i!=n; ++i) {
-        char * tmp = g_convert (content.str, content.len, "UTF-8", encodings[i], 0, 0, 0);
+        char * tmp = g_convert (content.str, content.len, "UTF-8", encodings[i], 0, 0, NULL);
         if (tmp) {
           ret = tmp;
           g_free (tmp);
diff --git a/pan/gui/body-pane.cc b/pan/gui/body-pane.cc
index d0c5013..94b405e 100644
--- a/pan/gui/body-pane.cc
+++ b/pan/gui/body-pane.cc
@@ -1026,6 +1026,7 @@ namespace
     s += e;
     const size_t retval (g_utf8_strlen(key,-1) + g_utf8_strlen(utf8_val.c_str(),-1) + 2);
     g_free (e);
+
     return retval;
   }
 
@@ -1754,6 +1755,7 @@ BodyPane :: on_prefs_flag_changed (const StringView& key, bool value G_GNUC_UNUS
     refresh_fonts ();
 
   if ((key=="wrap-article-body") || (key=="mute-quoted-text") ||
+      (key=="mute-signature") ||
       (key=="show-smilies-as-graphics") || (key=="show-all-headers") ||
       (key=="size-pictures-to-fit") || (key=="show-text-markup") ||
       (key=="highlight-urls") )
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index c02ed0b..91bd55d 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -26,6 +26,7 @@ extern "C" {
   #include <sys/types.h> // for chmod
   #include <sys/stat.h> // for chmod
   #include <glib/gi18n.h>
+  #include <iconv.h>
 }
 #include <pan/general/debug.h>
 #include <pan/general/e-util.h>
@@ -915,6 +916,8 @@ void GUI :: do_clear_header_pane ()
 {
   gtk_window_set_title (get_window(_root), _("Pan"));
   _header_pane->set_group (Quark());
+  // close iconv handler
+  iconv_close(conv);
 }
 void GUI :: do_clear_body_pane ()
 {
@@ -1348,7 +1351,13 @@ void GUI :: do_tip_jar ()
 }
 void GUI :: do_about_pan ()
 {
-  const gchar * authors [] = { "Charles Kerr <charles rebelbase com> - Pan Author", "Calin Culianu <calin ajvar org> - Threaded Decoding", "K. Haley <haleykd users sf net> - Contributor", "Petr Kovar <pknbe volny cz> - Contributor", "Heinrich Mueller <eddie_v gmx de> - Contributor", "Christophe Lambin <chris rebelbase com> - Original Pan Development", "Matt Eagleson <matt rebelbase com> - Original Pan Development", 0 };
+  const gchar * authors [] = { "Charles Kerr <charles rebelbase com> - Pan Author",
+                               "Calin Culianu <calin ajvar org> - Threaded Decoding",
+                               "K. Haley <haleykd users sf net> - Contributor",
+                               "Petr Kovar <pknbe volny cz> - Contributor",
+                               "Heinrich M\u00fceller <eddie_v gmx de> - Contributor",
+                               "Christophe Lambin <chris rebelbase com> - Original Pan Development",
+                               "Matt Eagleson <matt rebelbase com> - Original Pan Development", 0 };
   GdkPixbuf * logo = gdk_pixbuf_new_from_inline(-1, icon_pan_about_logo, 0, 0);
   GtkAboutDialog * w (GTK_ABOUT_DIALOG (gtk_about_dialog_new ()));
   gtk_about_dialog_set_program_name (w, _("Pan"));
@@ -1622,10 +1631,21 @@ void GUI :: do_read_selected_group ()
   {
     std::string local (_group_prefs.get_string (group, "character-encoding", ""));
     if (local.empty())
-      set_charset (_prefs.get_string("default-charset", "UTF-8"));
-    else
-      set_charset (local);
-
+    {
+      local = _prefs.get_string("default-charset", "UTF-8");
+    }
+    set_charset (local);
+
+    // update iconv handler
+    const char * from = g_mime_charset_iconv_name(local.c_str());
+    char buf[256];
+    g_snprintf(buf, sizeof(buf), "%s//IGNORE", _prefs.get_string("default-charset", "UTF-8").c_str());
+    const char * to  = g_mime_charset_iconv_name(buf);
+    conv = iconv_open (to, from);
+    if (conv == (iconv_t)-1)
+    {
+      Log::add_err(_("Error loading iconv library. Some Charsets in GUI will not be able to be encoded."));
+    }
   }
 
 
diff --git a/pan/gui/header-pane.cc b/pan/gui/header-pane.cc
index 9e6a388..95781bf 100644
--- a/pan/gui/header-pane.cc
+++ b/pan/gui/header-pane.cc
@@ -22,16 +22,19 @@ extern "C" {
   #include <glib/gi18n.h>
   #include <gtk/gtk.h>
   #include <gdk/gdkkeysyms.h>
+  #include <iconv.h>
 }
 #include <cctype>
 #include <cmath>
 #include <algorithm>
 #include <pan/general/debug.h>
 #include <pan/general/e-util.h>
+#include <pan/general/utf8-utils.h>
 #include <pan/general/log.h>
 #include <pan/general/macros.h>
 #include <pan/general/quark.h>
 #include <pan/usenet-utils/filter-info.h>
+#include <pan/usenet-utils/mime-utils.h>
 #include <pan/data/article.h>
 #include <pan/data/data.h>
 #include <pan/icons/pan-pixbufs.h>
@@ -244,6 +247,24 @@ HeaderPane :: render_score (GtkTreeViewColumn * ,
 }
 
 void
+HeaderPane :: render_author (GtkTreeViewColumn * ,
+                            GtkCellRenderer   * renderer,
+                            GtkTreeModel      * model,
+                            GtkTreeIter       * iter,
+                            gpointer            user_data)
+{
+
+  const HeaderPane * self (static_cast<HeaderPane*>(user_data));
+  const Row * row (dynamic_cast<Row*>(self->_tree_store->get_row (iter)));
+
+  const Article * a (self->get_article (model, iter));
+
+  char* ret = __g_mime_iconv_strdup(conv, a->author.c_str());
+  if (ret) g_object_set (renderer, "text", ret, NULL);
+  g_free(ret);
+}
+
+void
 HeaderPane :: render_bytes (GtkTreeViewColumn * ,
                             GtkCellRenderer   * renderer,
                             GtkTreeModel      * model,
@@ -255,6 +276,7 @@ HeaderPane :: render_bytes (GtkTreeViewColumn * ,
   g_object_set (renderer, "text", pan::render_bytes(bytes), NULL);
 }
 
+
 struct HeaderPane::CountUnread: public PanTreeStore::WalkFunctor
 {
   const Row * top_row;
@@ -289,7 +311,12 @@ HeaderPane :: render_subject (GtkTreeViewColumn * ,
   const bool bold (!row->is_read);
 
   const Article * a (self->get_article (model, iter));
-  const char * text (a->subject.c_str());
+
+  char* ret = __g_mime_iconv_strdup(conv, a->subject.c_str());
+  std::string res;
+  if (ret) res = ret;
+  g_free(ret);
+
   char buf[512];
 
   bool underlined (false);
@@ -304,13 +331,13 @@ HeaderPane :: render_subject (GtkTreeViewColumn * ,
 
     if (!expanded) {
       underlined = row->is_read;
-      snprintf (buf, sizeof(buf), "%s (%lu)", text, counter.unread_children);
-      text = buf;
+      snprintf (buf, sizeof(buf), "%s (%lu)", res.c_str(), counter.unread_children);
+      res = buf;
     }
   }
 
   g_object_set (renderer,
-    "text", text,
+    "text", res.c_str(),
     "weight", (bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL),
     "underline", (underlined ? PANGO_UNDERLINE_SINGLE : PANGO_UNDERLINE_NONE),
     NULL);
@@ -1499,11 +1526,12 @@ HeaderPane :: build_tree_columns ()
         "ypad", 0,
         NULL));
       ellipsize_if_supported (G_OBJECT(r));
-      col = gtk_tree_view_column_new_with_attributes (_("Author"), r, "text", COL_SHORT_AUTHOR, NULL);
+      col = gtk_tree_view_column_new_with_attributes (_("Author"), r, NULL);
       gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
       gtk_tree_view_column_set_fixed_width (col, _prefs.get_int (width_key, 133));
       gtk_tree_view_column_set_resizable (col, true);
       gtk_tree_view_column_set_sort_column_id (col, COL_SHORT_AUTHOR);
+      gtk_tree_view_column_set_cell_data_func (col, r, render_author, this, 0);
       gtk_tree_view_append_column (tree_view, col);
     }
     else if (name == "lines")
diff --git a/pan/gui/header-pane.h b/pan/gui/header-pane.h
index 7144c84..702c032 100644
--- a/pan/gui/header-pane.h
+++ b/pan/gui/header-pane.h
@@ -348,6 +348,7 @@ namespace pan
       static RenderFunc render_score;
       static RenderFunc render_bytes;
       static RenderFunc render_subject;
+      static RenderFunc render_author;
 
     private:
       Row* get_row (const Quark& message_id);
diff --git a/pan/usenet-utils/mime-utils.cc b/pan/usenet-utils/mime-utils.cc
index 52de825..5152fc2 100644
--- a/pan/usenet-utils/mime-utils.cc
+++ b/pan/usenet-utils/mime-utils.cc
@@ -66,6 +66,99 @@ using namespace pan;
 #define YENC_SHIFT             42
 #define YENC_QUOTE_SHIFT       64
 
+namespace pan
+{
+
+  iconv_t conv;
+
+  char *
+  __g_mime_iconv_strndup (iconv_t cd, const char *str, size_t n)
+  {
+    size_t inleft, outleft, converted = 0;
+    char *out, *outbuf;
+    const char *inbuf;
+    size_t outlen;
+    int errnosav;
+
+    if (cd == (iconv_t) -1)
+      return g_strndup (str, n);
+
+    outlen = n * 2 + 16;
+    out = (char*)g_malloc (outlen + 4);
+
+    inbuf = str;
+    inleft = n;
+
+    do {
+      errno = 0;
+      outbuf = out + converted;
+      outleft = outlen - converted;
+
+      converted = iconv (cd, (char **) &inbuf, &inleft, &outbuf, &outleft);
+
+      if (converted != (size_t) -1 || errno == EINVAL) {
+        /*
+         * EINVAL  An  incomplete  multibyte sequence has been encoun­
+         *         tered in the input.
+         *
+         * We'll just have to ignore it...
+         */
+        break;
+      }
+
+      if (errno != E2BIG && errno != EILSEQ) {
+        errnosav = errno;
+        g_free (out);
+
+        /* reset the cd */
+        iconv (cd, NULL, NULL, NULL, NULL);
+
+        errno = errnosav;
+
+        return NULL;
+      }
+
+      /*
+		 * E2BIG   There is not sufficient room at *outbuf.
+		 *
+		 * We just need to grow our outbuffer and try again.
+		 */
+      {
+        converted = outbuf - out;
+        outlen += inleft * 2 + 16;
+        out = (char*)g_realloc (out, outlen + 4);
+        outbuf = out + converted;
+      }
+
+    } while (TRUE);
+
+    /* flush the iconv conversion */
+    while (iconv (cd, NULL, NULL, &outbuf, &outleft) == (size_t) -1) {
+      if (errno != E2BIG)
+        break;
+
+      outlen += 16;
+      converted = outbuf - out;
+      out = (char*)g_realloc (out, outlen + 4);
+      outleft = outlen - converted;
+      outbuf = out + converted;
+    }
+
+    /* Note: not all charsets can be nul-terminated with a single
+             nul byte. UCS2, for example, needs 2 nul bytes and UCS4
+             needs 4. I hope that 4 nul bytes is enough to terminate all
+             multibyte charsets? */
+
+    /* nul-terminate the string */
+    memset (outbuf, 0, 4);
+
+    /* reset the cd */
+    iconv (cd, NULL, NULL, NULL, NULL);
+
+    return out;
+  }
+}
+
 namespace
 {
    const char*
@@ -171,10 +264,10 @@ namespace
 
       // part is optional
       int part_num = __yenc_extract_tag_val_int (b, YENC_TAG_PART);
-	
+
       int a_sz = __yenc_extract_tag_val_int( b, YENC_TAG_SIZE );
       pan_return_val_if_fail( a_sz != 0, -1 );
-	
+
       const char * fname = __yenc_extract_tag_val_char (b, YENC_TAG_NAME);
       pan_return_val_if_fail( fname, -1 );
 
diff --git a/pan/usenet-utils/mime-utils.h b/pan/usenet-utils/mime-utils.h
index d2aa101..bcd17a9 100644
--- a/pan/usenet-utils/mime-utils.h
+++ b/pan/usenet-utils/mime-utils.h
@@ -27,11 +27,16 @@
 #include <gmime/gmime-message.h>
 #include <pan/general/string-view.h>
 
+extern "C"
+{
+  #include <iconv.h>
+}
+
 namespace pan
 {
   /**
    * Utilities to build and parse GMimeMesasges.
-   * 
+   *
    * Most of nastiness this is to handle Usenet's use of chainging together
    * multiple articles as parts of a whole.  This code tries to build
    * a multipart GMimeMessage from multiple posts when necessary, and to
@@ -66,6 +71,15 @@ namespace pan
   char *pan_g_mime_message_get_body (GMimeMessage *message, gboolean *is_html);
   void pan_g_mime_message_add_recipients_from_string (GMimeMessage *message, GMimeRecipientType type, const char *string);
 
+  extern iconv_t conv;
+
+  char * __g_mime_iconv_strndup (iconv_t cd, const char *str, size_t n);
+
+  static char * __g_mime_iconv_strdup (iconv_t cd, const char *str)
+  {
+    return __g_mime_iconv_strndup(cd, str, strlen(str));
+  }
+
 }
 
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]