[pan2] https://bugzilla.gnome.org/show_bug.cgi?id=412890
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2] https://bugzilla.gnome.org/show_bug.cgi?id=412890
- Date: Sun, 18 Dec 2011 12:34:11 +0000 (UTC)
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]