| Summary: | Umlaute are not displayed corretly for folder names | ||
|---|---|---|---|
| Product: | [Unmaintained] mailody | Reporter: | Ferdinand Gassauer <gassauer> |
| Component: | general | Assignee: | Tom Albers <toma> |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | ||
| Priority: | NOR | ||
| Version First Reported In: | 0.4.0 | ||
| Target Milestone: | --- | ||
| Platform: | unspecified | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
|
Description
Ferdinand Gassauer
2007-02-04 16:46:57 UTC
SVN commit 630300 by toma:
Make it possible to use international characters in foldernames read and write. Resync mailbox list to see it. Thanks for reporting.
BUG:141181
M +267 -8 imap.cpp
M +5 -0 imap.h
--- trunk/playground/pim/mailody/src/imap.cpp #630299:630300
@@ -321,6 +321,8 @@
if (y.startsWith("\"") && y.endsWith("\""))
y=y.mid(1, y.length()-2);
+ y = decodeIMAPFolderName(y);
+
// kdDebug() << "Mailbox found.. " << y << endl;
newList[y] = true;
@@ -831,20 +833,23 @@
emit messageCount( box, 0);
emit unseenCount( box, 0);
emit allUidsKnown( box ); // clear the view
- m_queue.prepend(Queue(Queue::SyncMailBox, box, "SELECT \""+box+"\""));
+ const QString box2 = encodeIMAPFolderName(box);
+ m_queue.prepend(Queue(Queue::SyncMailBox, box, "SELECT \""+box2+"\""));
}
void Imap::selectMailBox(const QString& box)
{
// kdDebug() << k_funcinfo << box << endl;
- m_queue.prepend(Queue(Queue::SelectMailBox, box, "SELECT \""+box+"\""));
+ const QString box2 = encodeIMAPFolderName(box);
+ m_queue.prepend(Queue(Queue::SelectMailBox, box, "SELECT \""+box2+"\""));
}
void Imap::checkMail(const QString& box)
{
// kdDebug() << k_funcinfo << box << endl;
+ const QString box2 = encodeIMAPFolderName(box);
m_queue.append(Queue(Queue::CheckMail, box,
- "STATUS \""+box+"\" (MESSAGES UNSEEN)"));
+ "STATUS \""+box2+"\" (MESSAGES UNSEEN)"));
}
void Imap::slotSendNoop()
@@ -856,26 +861,31 @@
void Imap::expungeMailBox(const QString& box)
{
// kdDebug() << k_funcinfo << box << endl;
+ const QString box2 = encodeIMAPFolderName(box);
m_queue.append(Queue(Queue::Expunge, box, "EXPUNGE"));
}
void Imap::createMailBox(const QString& box)
{
// kdDebug() << k_funcinfo << box << endl;
- m_queue.append(Queue(Queue::CreateMailBox, box, "CREATE \"" + box + "\""));
+ const QString box2 = encodeIMAPFolderName(box);
+ m_queue.append(Queue(Queue::CreateMailBox, box, "CREATE \"" + box2 + "\""));
}
void Imap::deleteMailBox(const QString& box)
{
// kdDebug() << k_funcinfo << box << endl;
- m_queue.append(Queue(Queue::DeleteMailBox, box, "DELETE \"" + box + "\""));
+ const QString box2 = encodeIMAPFolderName(box);
+ m_queue.append(Queue(Queue::DeleteMailBox, box, "DELETE \"" + box2 + "\""));
}
void Imap::renameMailBox(const QString& oldbox, const QString& newbox)
{
// kdDebug() << k_funcinfo << oldbox << "->" << newbox << endl;
+ const QString oldbox2 = encodeIMAPFolderName(oldbox);
+ const QString newbox2 = encodeIMAPFolderName(newbox);
m_queue.append(Queue(Queue::RenameMailBox, oldbox + "~" + newbox,
- "RENAME \"" + oldbox + "\" \"" + newbox + "\""));
+ "RENAME \"" + oldbox2 + "\" \"" + newbox2 + "\""));
}
//---------------- Messages -----------------------------//
@@ -885,8 +895,9 @@
{
// kdDebug() << k_funcinfo << origbox
// << " - " << uid << " -> " << destbox << endl;
+ const QString destbox2 = encodeIMAPFolderName(destbox);
m_queue.append(Queue(Queue::Move, origbox,
- "UID COPY " + QString::number(uid) + " \"" + destbox+ "\""));
+ "UID COPY " + QString::number(uid) + " \"" + destbox2+ "\""));
addFlag(uid, origbox, "\\Deleted");
}
@@ -935,8 +946,9 @@
void Imap::saveMessage(const QString& mb, const QString& message)
{
// kdDebug() << k_funcinfo << message << endl;
+ const QString mb2 = encodeIMAPFolderName(mb);
m_queue.append( Queue(Queue::SaveMessage, mb,
- "APPEND \"" + mb + "\" (\\Seen) {"
+ "APPEND \"" + mb2 + "\" (\\Seen) {"
+ QString::number(message.length())
+ "}"));
m_queue.append( Queue(Queue::SaveMessageData, mb, message));
@@ -1211,6 +1223,8 @@
return true;
}
+//---------------------------------- ----------------------------------//
+
/* Copy from KDE/3.5/kdepim/kioslaves/imap4/rfcdecoder.cc */
/* Copyright (C) 2000 s.carstens@gmx.de */
/* replace " with \" and \ with \\ " and \ characters */
@@ -1229,6 +1243,251 @@
return result;
}
+//---------------------------------------------------------------------------
+
+/* Copy from KDE/3.5/kdepim/kioslaves/imap4/rfcdecoder.cc */
+// This part taken from rfc 2192 IMAP URL Scheme. C. Newman. September 1997.
+// adapted to QT-Toolkit by Sven Carstens <s.carstens@gmx.de> 2000
+
+static unsigned char base64chars[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
+#define UNDEFINED 64
+#define MAXLINE 76
+
+/* UTF16 definitions */
+#define UTF16MASK 0x03FFUL
+#define UTF16SHIFT 10
+#define UTF16BASE 0x10000UL
+#define UTF16HIGHSTART 0xD800UL
+#define UTF16HIGHEND 0xDBFFUL
+#define UTF16LOSTART 0xDC00UL
+#define UTF16LOEND 0xDFFFUL
+
+/* Convert an IMAP mailbox to a Unicode path
+ */
+QString Imap::decodeIMAPFolderName(const QString & inSrc)
+{
+ unsigned char c, i, bitcount;
+ unsigned long ucs4, utf16, bitbuf;
+ unsigned char base64[256], utf8[6];
+ unsigned long srcPtr = 0;
+ QCString dst;
+ QCString src = inSrc.ascii ();
+ uint srcLen = inSrc.length();
+
+ /* initialize modified base64 decoding table */
+ memset (base64, UNDEFINED, sizeof (base64));
+ for (i = 0; i < sizeof (base64chars); ++i)
+ {
+ base64[(int)base64chars[i]] = i;
+ }
+
+ /* loop until end of string */
+ while (srcPtr < srcLen)
+ {
+ c = src[srcPtr++];
+ /* deal with literal characters and &- */
+ if (c != '&' || src[srcPtr] == '-')
+ {
+ /* encode literally */
+ dst += c;
+ /* skip over the '-' if this is an &- sequence */
+ if (c == '&')
+ srcPtr++;
+ }
+ else
+ {
+ /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
+ bitbuf = 0;
+ bitcount = 0;
+ ucs4 = 0;
+ while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED)
+ {
+ ++srcPtr;
+ bitbuf = (bitbuf << 6) | c;
+ bitcount += 6;
+ /* enough bits for a UTF-16 character? */
+ if (bitcount >= 16)
+ {
+ bitcount -= 16;
+ utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
+ /* convert UTF16 to UCS4 */
+ if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND)
+ {
+ ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
+ continue;
+ }
+ else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND)
+ {
+ ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
+ }
+ else
+ {
+ ucs4 = utf16;
+ }
+ /* convert UTF-16 range of UCS4 to UTF-8 */
+ if (ucs4 <= 0x7fUL)
+ {
+ utf8[0] = ucs4;
+ i = 1;
+ }
+ else if (ucs4 <= 0x7ffUL)
+ {
+ utf8[0] = 0xc0 | (ucs4 >> 6);
+ utf8[1] = 0x80 | (ucs4 & 0x3f);
+ i = 2;
+ }
+ else if (ucs4 <= 0xffffUL)
+ {
+ utf8[0] = 0xe0 | (ucs4 >> 12);
+ utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
+ utf8[2] = 0x80 | (ucs4 & 0x3f);
+ i = 3;
+ }
+ else
+ {
+ utf8[0] = 0xf0 | (ucs4 >> 18);
+ utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
+ utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
+ utf8[3] = 0x80 | (ucs4 & 0x3f);
+ i = 4;
+ }
+ /* copy it */
+ for (c = 0; c < i; ++c)
+ {
+ dst += utf8[c];
+ }
+ }
+ }
+ /* skip over trailing '-' in modified UTF-7 encoding */
+ if (src[srcPtr] == '-')
+ ++srcPtr;
+ }
+ }
+ return QString::fromUtf8 (dst.data ());
}
+/* Convert Unicode path to modified UTF-7 IMAP mailbox
+ */
+QString Imap::encodeIMAPFolderName (const QString & inSrc)
+{
+ unsigned int utf8pos, utf8total, c, utf7mode, bitstogo, utf16flag;
+ unsigned long ucs4, bitbuf;
+ QCString src = inSrc.utf8 ();
+ QString dst;
+
+ ulong srcPtr = 0;
+ utf7mode = 0;
+ utf8total = 0;
+ bitstogo = 0;
+ utf8pos = 0;
+ bitbuf = 0;
+ ucs4 = 0;
+ while (srcPtr < src.length ())
+ {
+ c = (unsigned char) src[srcPtr++];
+ /* normal character? */
+ if (c >= ' ' && c <= '~')
+ {
+ /* switch out of UTF-7 mode */
+ if (utf7mode)
+ {
+ if (bitstogo)
+ {
+ dst += base64chars[(bitbuf << (6 - bitstogo)) & 0x3F];
+ bitstogo = 0;
+ }
+ dst += '-';
+ utf7mode = 0;
+ }
+ dst += c;
+ /* encode '&' as '&-' */
+ if (c == '&')
+ {
+ dst += '-';
+ }
+ continue;
+ }
+ /* switch to UTF-7 mode */
+ if (!utf7mode)
+ {
+ dst += '&';
+ utf7mode = 1;
+ }
+ /* Encode US-ASCII characters as themselves */
+ if (c < 0x80)
+ {
+ ucs4 = c;
+ utf8total = 1;
+ }
+ else if (utf8total)
+ {
+ /* save UTF8 bits into UCS4 */
+ ucs4 = (ucs4 << 6) | (c & 0x3FUL);
+ if (++utf8pos < utf8total)
+ {
+ continue;
+ }
+ }
+ else
+ {
+ utf8pos = 1;
+ if (c < 0xE0)
+ {
+ utf8total = 2;
+ ucs4 = c & 0x1F;
+ }
+ else if (c < 0xF0)
+ {
+ utf8total = 3;
+ ucs4 = c & 0x0F;
+ }
+ else
+ {
+ /* NOTE: can't convert UTF8 sequences longer than 4 */
+ utf8total = 4;
+ ucs4 = c & 0x03;
+ }
+ continue;
+ }
+ /* loop to split ucs4 into two utf16 chars if necessary */
+ utf8total = 0;
+ do
+ {
+ if (ucs4 >= UTF16BASE)
+ {
+ ucs4 -= UTF16BASE;
+ bitbuf = (bitbuf << 16) | ((ucs4 >> UTF16SHIFT) + UTF16HIGHSTART);
+ ucs4 = (ucs4 & UTF16MASK) + UTF16LOSTART;
+ utf16flag = 1;
+ }
+ else
+ {
+ bitbuf = (bitbuf << 16) | ucs4;
+ utf16flag = 0;
+ }
+ bitstogo += 16;
+ /* spew out base64 */
+ while (bitstogo >= 6)
+ {
+ bitstogo -= 6;
+ dst += base64chars[(bitstogo ? (bitbuf >> bitstogo) : bitbuf) & 0x3F];
+ }
+ }
+ while (utf16flag);
+ }
+ /* if in UTF-7 mode, finish in ASCII */
+ if (utf7mode)
+ {
+ if (bitstogo)
+ {
+ dst += base64chars[(bitbuf << (6 - bitstogo)) & 0x3F];
+ }
+ dst += '-';
+ }
+ return quoteIMAP(dst);
+}
+
+}
+
#include "imap.moc"
--- trunk/playground/pim/mailody/src/imap.h #630299:630300
@@ -238,8 +238,13 @@
void integrity(const QString& mb, int);
void timerEvent( QTimerEvent * );
void getCapabilities();
+
+ /* taken from rfcencoder */
QString quoteIMAP(const QString &src);
+ QString decodeIMAPFolderName(const QString & inSrc);
+ QString encodeIMAPFolderName(const QString & inSrc);
+
signals:
/**
* Emitted when the mailbox list is updated
|