From c283449d04e9c38f4970beaf2d25638c681b5a6d Mon Sep 17 00:00:00 2001 From: Sander Bogaert Date: Tue, 12 Apr 2011 14:32:42 +0200 Subject: [PATCH 001/121] Added another badDateTimeFormat to ImapResponseParser. Some IMAP servers generate timestamps without timezones. :/ Fixes gcode issue 3179 --- src/com/fsck/k9/mail/store/ImapResponseParser.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/com/fsck/k9/mail/store/ImapResponseParser.java b/src/com/fsck/k9/mail/store/ImapResponseParser.java index f52653da0..090dd85ad 100644 --- a/src/com/fsck/k9/mail/store/ImapResponseParser.java +++ b/src/com/fsck/k9/mail/store/ImapResponseParser.java @@ -15,6 +15,7 @@ public class ImapResponseParser { private static final SimpleDateFormat mDateTimeFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss Z", Locale.US); private static final SimpleDateFormat badDateTimeFormat = new SimpleDateFormat("dd MMM yyyy HH:mm:ss Z", Locale.US); private static final SimpleDateFormat badDateTimeFormat2 = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z", Locale.US); + private static final SimpleDateFormat badDateTimeFormat3 = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.US); private PeekableInputStream mIn; private ImapResponse mResponse; @@ -426,8 +427,14 @@ public class ImapResponseParser { return badDateTimeFormat.parse(value); } } catch (Exception e2) { - synchronized (badDateTimeFormat2) { - return badDateTimeFormat2.parse(value); + try { + synchronized (badDateTimeFormat2) { + return badDateTimeFormat2.parse(value); + } + } catch (Exception e3) { + synchronized (badDateTimeFormat3) { + return badDateTimeFormat3.parse(value); + } } } } From 17cb5106f69f478c555d33573027bb8b71837a43 Mon Sep 17 00:00:00 2001 From: Sander Bogaert Date: Tue, 12 Apr 2011 13:23:19 +0200 Subject: [PATCH 002/121] The date format preference is now refreshed each time the messages get listed. Previously, changes to the date format preference weren't noticed until the app restarted. --- src/com/fsck/k9/activity/MessageList.java | 5 ++++- src/com/fsck/k9/helper/MessageHelper.java | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 4965cd478..19c4b213b 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -698,7 +698,7 @@ public class MessageList @Override public void onResume() { super.onResume(); - + if (mAccount != null && !mAccount.isAvailable(this)) { onAccountUnavailable(); return; @@ -726,6 +726,9 @@ public class MessageList } } else { + // reread the selected date format preference in case it has changed + mMessageHelper.refresh(); + new Thread() { @Override public void run() { diff --git a/src/com/fsck/k9/helper/MessageHelper.java b/src/com/fsck/k9/helper/MessageHelper.java index 412796336..3eba0a5eb 100644 --- a/src/com/fsck/k9/helper/MessageHelper.java +++ b/src/com/fsck/k9/helper/MessageHelper.java @@ -99,4 +99,9 @@ public class MessageHelper { return mDateFormat.format(date); } } + + public void refresh() { + mDateFormat = DateFormatter.getDateFormat(mContext); + mTodayDateFormat = android.text.format.DateFormat.getTimeFormat(mContext); + } } From c891a5f00b77ec7765df2c2cd5e91bb3a877ff50 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 12 Apr 2011 21:49:31 +1000 Subject: [PATCH 003/121] Bumped manifest to 3.710 --- AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b76404dbc..c74641d35 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ Date: Tue, 12 Apr 2011 22:16:22 +1000 Subject: [PATCH 004/121] astyle --- src/com/fsck/k9/K9.java | 4 +- src/com/fsck/k9/activity/Accounts.java | 106 ++++++++-------- .../fsck/k9/activity/ConfirmationDialog.java | 36 +++--- src/com/fsck/k9/activity/FolderList.java | 28 +++-- src/com/fsck/k9/activity/MessageCompose.java | 2 +- src/com/fsck/k9/activity/MessageList.java | 56 ++++----- src/com/fsck/k9/activity/MessageView.java | 42 +++---- .../activity/setup/AccountSetupIncoming.java | 4 +- src/com/fsck/k9/activity/setup/Prefs.java | 16 +-- src/com/fsck/k9/helper/Contacts.java | 2 +- src/com/fsck/k9/helper/ContactsSdk3_4.java | 10 +- src/com/fsck/k9/helper/MessageHelper.java | 6 +- src/com/fsck/k9/mail/Authentication.java | 116 +++++++++--------- src/com/fsck/k9/mail/filter/Hex.java | 19 ++- .../fsck/k9/mail/internet/MimeUtility.java | 14 +-- .../k9/mail/store/ImapResponseParser.java | 4 +- src/com/fsck/k9/mail/store/ImapStore.java | 2 +- src/com/fsck/k9/mail/store/LocalStore.java | 2 +- src/com/fsck/k9/mail/store/Pop3Store.java | 16 +-- .../fsck/k9/mail/transport/SmtpTransport.java | 4 +- 20 files changed, 243 insertions(+), 246 deletions(-) diff --git a/src/com/fsck/k9/K9.java b/src/com/fsck/k9/K9.java index c193737da..f408544f2 100644 --- a/src/com/fsck/k9/K9.java +++ b/src/com/fsck/k9/K9.java @@ -942,11 +942,11 @@ public class K9 extends Application { } public static boolean confirmSpam() { - return mConfirmSpam; + return mConfirmSpam; } public static void setConfirmSpam(final boolean confirm) { - mConfirmSpam = confirm; + mConfirmSpam = confirm; } public static boolean confirmMarkAllAsRead() { diff --git a/src/com/fsck/k9/activity/Accounts.java b/src/com/fsck/k9/activity/Accounts.java index b18470208..37f5a41c8 100644 --- a/src/com/fsck/k9/activity/Accounts.java +++ b/src/com/fsck/k9/activity/Accounts.java @@ -457,66 +457,66 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC switch (id) { case DIALOG_REMOVE_ACCOUNT: return ConfirmationDialog.create(this, id, - R.string.account_delete_dlg_title, - getString(R.string.account_delete_dlg_instructions_fmt, - mSelectedContextAccount.getDescription()), - R.string.okay_action, - R.string.cancel_action, - new Runnable() { - @Override - public void run() { - if (mSelectedContextAccount instanceof Account) { - Account realAccount = (Account)mSelectedContextAccount; - try { - realAccount.getLocalStore().delete(); - } catch (Exception e) { - // Ignore, this may lead to localStores on sd-cards that are - // currently not inserted to be left - } - MessagingController.getInstance(getApplication()) - .notifyAccountCancel(Accounts.this, realAccount); - Preferences.getPreferences(Accounts.this).deleteAccount(realAccount); - K9.setServicesEnabled(Accounts.this); - refresh(); - } + R.string.account_delete_dlg_title, + getString(R.string.account_delete_dlg_instructions_fmt, + mSelectedContextAccount.getDescription()), + R.string.okay_action, + R.string.cancel_action, + new Runnable() { + @Override + public void run() { + if (mSelectedContextAccount instanceof Account) { + Account realAccount = (Account)mSelectedContextAccount; + try { + realAccount.getLocalStore().delete(); + } catch (Exception e) { + // Ignore, this may lead to localStores on sd-cards that are + // currently not inserted to be left } - }); + MessagingController.getInstance(getApplication()) + .notifyAccountCancel(Accounts.this, realAccount); + Preferences.getPreferences(Accounts.this).deleteAccount(realAccount); + K9.setServicesEnabled(Accounts.this); + refresh(); + } + } + }); case DIALOG_CLEAR_ACCOUNT: return ConfirmationDialog.create(this, id, - R.string.account_clear_dlg_title, - getString(R.string.account_clear_dlg_instructions_fmt, - mSelectedContextAccount.getDescription()), - R.string.okay_action, - R.string.cancel_action, - new Runnable() { - @Override - public void run() { - if (mSelectedContextAccount instanceof Account) { - Account realAccount = (Account)mSelectedContextAccount; - mHandler.workingAccount(realAccount, R.string.clearing_account); - MessagingController.getInstance(getApplication()).clear(realAccount, null); - } - } - }); + R.string.account_clear_dlg_title, + getString(R.string.account_clear_dlg_instructions_fmt, + mSelectedContextAccount.getDescription()), + R.string.okay_action, + R.string.cancel_action, + new Runnable() { + @Override + public void run() { + if (mSelectedContextAccount instanceof Account) { + Account realAccount = (Account)mSelectedContextAccount; + mHandler.workingAccount(realAccount, R.string.clearing_account); + MessagingController.getInstance(getApplication()).clear(realAccount, null); + } + } + }); case DIALOG_RECREATE_ACCOUNT: return ConfirmationDialog.create(this, id, - R.string.account_recreate_dlg_title, - getString(R.string.account_recreate_dlg_instructions_fmt, - mSelectedContextAccount.getDescription()), - R.string.okay_action, - R.string.cancel_action, - new Runnable() { - @Override - public void run() { - if (mSelectedContextAccount instanceof Account) { - Account realAccount = (Account)mSelectedContextAccount; - mHandler.workingAccount(realAccount, R.string.recreating_account); - MessagingController.getInstance(getApplication()).recreate(realAccount, null); - } - } - }); + R.string.account_recreate_dlg_title, + getString(R.string.account_recreate_dlg_instructions_fmt, + mSelectedContextAccount.getDescription()), + R.string.okay_action, + R.string.cancel_action, + new Runnable() { + @Override + public void run() { + if (mSelectedContextAccount instanceof Account) { + Account realAccount = (Account)mSelectedContextAccount; + mHandler.workingAccount(realAccount, R.string.recreating_account); + MessagingController.getInstance(getApplication()).recreate(realAccount, null); + } + } + }); } return super.onCreateDialog(id); } diff --git a/src/com/fsck/k9/activity/ConfirmationDialog.java b/src/com/fsck/k9/activity/ConfirmationDialog.java index e61039cd4..73e9bf81c 100644 --- a/src/com/fsck/k9/activity/ConfirmationDialog.java +++ b/src/com/fsck/k9/activity/ConfirmationDialog.java @@ -20,27 +20,27 @@ public class ConfirmationDialog { * @return A confirmation dialog with the supplied arguments */ public static Dialog create(final Activity activity, final int dialogId, final int title, - final String message, final int confirmButton, final int cancelButton, - final Runnable action) { + final String message, final int confirmButton, final int cancelButton, + final Runnable action) { final AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(title); builder.setMessage(message); builder.setPositiveButton(confirmButton, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - activity.dismissDialog(dialogId); - action.run(); - } - }); + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + activity.dismissDialog(dialogId); + action.run(); + } + }); builder.setNegativeButton(cancelButton, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - activity.dismissDialog(dialogId); - } - }); + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + activity.dismissDialog(dialogId); + } + }); return builder.create(); } @@ -58,10 +58,10 @@ public class ConfirmationDialog { * @see #create(Activity,int,int,String,int,int,Runnable) */ public static Dialog create(final Activity activity, final int dialogId, final int title, - final int message, final int confirmButton, final int cancelButton, - final Runnable action) { + final int message, final int confirmButton, final int cancelButton, + final Runnable action) { return create(activity, dialogId, title, activity.getString(message), confirmButton, - cancelButton, action); + cancelButton, action); } } diff --git a/src/com/fsck/k9/activity/FolderList.java b/src/com/fsck/k9/activity/FolderList.java index 62982cba5..09c55a976 100644 --- a/src/com/fsck/k9/activity/FolderList.java +++ b/src/com/fsck/k9/activity/FolderList.java @@ -641,10 +641,12 @@ public class FolderList extends K9ListActivity { private void markAllAsRead() { try { MessagingController.getInstance(getApplication()) - .markAllMessagesRead(mAccount, mSelectedContextFolder.name); + .markAllMessagesRead(mAccount, mSelectedContextFolder.name); mSelectedContextFolder.unreadMessageCount = 0; mHandler.dataChanged(); - } catch (Exception e) { /* Ignore */ } + } catch (Exception e) { + /* Ignore */ + } } @Override @@ -652,17 +654,17 @@ public class FolderList extends K9ListActivity { switch (id) { case DIALOG_MARK_ALL_AS_READ: return ConfirmationDialog.create(this, id, - R.string.mark_all_as_read_dlg_title, - getString(R.string.mark_all_as_read_dlg_instructions_fmt, - mSelectedContextFolder.displayName), - R.string.okay_action, - R.string.cancel_action, - new Runnable() { - @Override - public void run() { - markAllAsRead(); - } - }); + R.string.mark_all_as_read_dlg_title, + getString(R.string.mark_all_as_read_dlg_instructions_fmt, + mSelectedContextFolder.displayName), + R.string.okay_action, + R.string.cancel_action, + new Runnable() { + @Override + public void run() { + markAllAsRead(); + } + }); } return super.onCreateDialog(id); diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index ee5422c8e..0b6b39374 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -1121,7 +1121,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc */ bp.addHeader(MimeHeader.HEADER_CONTENT_DISPOSITION, String.format( "attachment;\n filename=\"%s\";\n size=%d", - EncoderUtil.encodeIfNecessary(attachment.name, + EncoderUtil.encodeIfNecessary(attachment.name, EncoderUtil.Usage.WORD_ENTITY, 7), attachment.size)); diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 19c4b213b..23ac75e79 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -698,7 +698,7 @@ public class MessageList @Override public void onResume() { super.onResume(); - + if (mAccount != null && !mAccount.isAvailable(this)) { onAccountUnavailable(); return; @@ -726,9 +726,9 @@ public class MessageList } } else { - // reread the selected date format preference in case it has changed - mMessageHelper.refresh(); - + // reread the selected date format preference in case it has changed + mMessageHelper.refresh(); + new Thread() { @Override public void run() { @@ -1142,7 +1142,7 @@ public class MessageList } } - private void moveToSpamFolder(MessageInfoHolder holder){ + private void moveToSpamFolder(MessageInfoHolder holder) { if (!mController.isMoveCapable(holder.message)) { Toast toast = Toast.makeText(this, R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG); toast.show(); @@ -1286,31 +1286,31 @@ public class MessageList switch (id) { case DIALOG_MARK_ALL_AS_READ: return ConfirmationDialog.create(this, id, - R.string.mark_all_as_read_dlg_title, - getString(R.string.mark_all_as_read_dlg_instructions_fmt, - mCurrentFolder.displayName), - R.string.okay_action, - R.string.cancel_action, - new Runnable() { - @Override - public void run() { - markAllAsRead(); - } - }); + R.string.mark_all_as_read_dlg_title, + getString(R.string.mark_all_as_read_dlg_instructions_fmt, + mCurrentFolder.displayName), + R.string.okay_action, + R.string.cancel_action, + new Runnable() { + @Override + public void run() { + markAllAsRead(); + } + }); case R.id.dialog_confirm_spam: return ConfirmationDialog.create(this, id, - R.string.dialog_confirm_spam_title, - R.string.dialog_confirm_spam_message, - R.string.dialog_confirm_spam_confirm_button, - R.string.dialog_confirm_spam_cancel_button, - new Runnable() { - @Override - public void run() { - moveToSpamFolder(mSelectedMessage); - // No further need for this reference - mSelectedMessage = null; - } - }); + R.string.dialog_confirm_spam_title, + R.string.dialog_confirm_spam_message, + R.string.dialog_confirm_spam_confirm_button, + R.string.dialog_confirm_spam_cancel_button, + new Runnable() { + @Override + public void run() { + moveToSpamFolder(mSelectedMessage); + // No further need for this reference + mSelectedMessage = null; + } + }); } return super.onCreateDialog(id); diff --git a/src/com/fsck/k9/activity/MessageView.java b/src/com/fsck/k9/activity/MessageView.java index 49d6243b0..91e9c7f4a 100644 --- a/src/com/fsck/k9/activity/MessageView.java +++ b/src/com/fsck/k9/activity/MessageView.java @@ -932,29 +932,29 @@ public class MessageView extends K9Activity implements OnClickListener { switch (id) { case R.id.dialog_confirm_delete: return ConfirmationDialog.create(this, id, - R.string.dialog_confirm_delete_title, - R.string.dialog_confirm_delete_message, - R.string.dialog_confirm_delete_confirm_button, - R.string.dialog_confirm_delete_cancel_button, - new Runnable() { - @Override - public void run() { - delete(); - } - }); + R.string.dialog_confirm_delete_title, + R.string.dialog_confirm_delete_message, + R.string.dialog_confirm_delete_confirm_button, + R.string.dialog_confirm_delete_cancel_button, + new Runnable() { + @Override + public void run() { + delete(); + } + }); case R.id.dialog_confirm_spam: return ConfirmationDialog.create(this, id, - R.string.dialog_confirm_spam_title, - R.string.dialog_confirm_spam_message, - R.string.dialog_confirm_spam_confirm_button, - R.string.dialog_confirm_spam_cancel_button, - new Runnable() { - @Override - public void run() { - refileMessage(mDstFolder); - mDstFolder = null; - } - }); + R.string.dialog_confirm_spam_title, + R.string.dialog_confirm_spam_message, + R.string.dialog_confirm_spam_confirm_button, + R.string.dialog_confirm_spam_cancel_button, + new Runnable() { + @Override + public void run() { + refileMessage(mDstFolder); + mDstFolder = null; + } + }); case R.id.dialog_attachment_progress: ProgressDialog d = new ProgressDialog(this); d.setIndeterminate(true); diff --git a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java index 7d94e919f..db0bbca33 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java @@ -409,9 +409,9 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener } else { String authType = ((SpinnerOption)mAuthTypeView.getSelectedItem()).label; if (!authType.equalsIgnoreCase("plain")) { - userInfo = authType + ":" + userEnc + ":" + passwordEnc; + userInfo = authType + ":" + userEnc + ":" + passwordEnc; } else { - userInfo = userEnc + ":" + passwordEnc; + userInfo = userEnc + ":" + passwordEnc; } } URI uri = new URI( diff --git a/src/com/fsck/k9/activity/setup/Prefs.java b/src/com/fsck/k9/activity/setup/Prefs.java index 2a2c51b93..905344041 100644 --- a/src/com/fsck/k9/activity/setup/Prefs.java +++ b/src/com/fsck/k9/activity/setup/Prefs.java @@ -182,15 +182,15 @@ public class Prefs extends K9PreferenceActivity { mConfirmActions = (CheckBoxListPreference) findPreference(PREFERENCE_CONFIRM_ACTIONS); mConfirmActions.setItems(new CharSequence[] { - getString(R.string.global_settings_confirm_action_delete), - getString(R.string.global_settings_confirm_action_spam), - getString(R.string.global_settings_confirm_action_mark_all_as_read) - }); + getString(R.string.global_settings_confirm_action_delete), + getString(R.string.global_settings_confirm_action_spam), + getString(R.string.global_settings_confirm_action_mark_all_as_read) + }); mConfirmActions.setCheckedItems(new boolean[] { - K9.confirmDelete(), - K9.confirmSpam(), - K9.confirmMarkAllAsRead() - }); + K9.confirmDelete(), + K9.confirmSpam(), + K9.confirmMarkAllAsRead() + }); mPrivacyMode = (CheckBoxPreference) findPreference(PREFERENCE_PRIVACY_MODE); mPrivacyMode.setChecked(K9.keyguardPrivacy()); diff --git a/src/com/fsck/k9/helper/Contacts.java b/src/com/fsck/k9/helper/Contacts.java index 7f3e6e441..c42b2d43d 100644 --- a/src/com/fsck/k9/helper/Contacts.java +++ b/src/com/fsck/k9/helper/Contacts.java @@ -195,7 +195,7 @@ public abstract class Contacts { public boolean hasContactPicker() { if (mHasContactPicker == null) { mHasContactPicker = (mContext.getPackageManager(). - queryIntentActivities(contactPickerIntent(), 0).size() > 0); + queryIntentActivities(contactPickerIntent(), 0).size() > 0); } return mHasContactPicker; } diff --git a/src/com/fsck/k9/helper/ContactsSdk3_4.java b/src/com/fsck/k9/helper/ContactsSdk3_4.java index 0b2433417..5d0fbdcd2 100644 --- a/src/com/fsck/k9/helper/ContactsSdk3_4.java +++ b/src/com/fsck/k9/helper/ContactsSdk3_4.java @@ -239,11 +239,11 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts { if (cursor.moveToFirst()) { String emailId = cursor.getString(cursor.getColumnIndex(Contacts.People.PRIMARY_EMAIL_ID)); cursor2 = mContext.getContentResolver().query( - ContactMethods.CONTENT_EMAIL_URI, - new String[] { ContactMethods.DATA }, - "contact_methods._id=?", - new String[] { emailId }, - null); + ContactMethods.CONTENT_EMAIL_URI, + new String[] { ContactMethods.DATA }, + "contact_methods._id=?", + new String[] { emailId }, + null); if (cursor2.moveToFirst()) { email = cursor2.getString(0); diff --git a/src/com/fsck/k9/helper/MessageHelper.java b/src/com/fsck/k9/helper/MessageHelper.java index 3eba0a5eb..43b208a77 100644 --- a/src/com/fsck/k9/helper/MessageHelper.java +++ b/src/com/fsck/k9/helper/MessageHelper.java @@ -100,8 +100,8 @@ public class MessageHelper { } } - public void refresh() { + public void refresh() { mDateFormat = DateFormatter.getDateFormat(mContext); - mTodayDateFormat = android.text.format.DateFormat.getTimeFormat(mContext); - } + mTodayDateFormat = android.text.format.DateFormat.getTimeFormat(mContext); + } } diff --git a/src/com/fsck/k9/mail/Authentication.java b/src/com/fsck/k9/mail/Authentication.java index f80b5f82d..4b9ae90ae 100644 --- a/src/com/fsck/k9/mail/Authentication.java +++ b/src/com/fsck/k9/mail/Authentication.java @@ -6,80 +6,80 @@ import com.fsck.k9.mail.filter.Base64; import com.fsck.k9.mail.filter.Hex; public class Authentication { - private static final String US_ASCII = "US-ASCII"; + private static final String US_ASCII = "US-ASCII"; - /** - * Computes the response for CRAM-MD5 authentication mechanism given the user credentials and - * the server-provided nonce. - * - * @param username The username. - * @param password The password. - * @param b64Nonce The nonce as base64-encoded string. - * @return The CRAM-MD5 response. - * - * @throws AuthenticationFailedException If something went wrong. - * - * @see Authentication#computeCramMd5Bytes(String, String, byte[]) - */ - public static String computeCramMd5(String username, String password, String b64Nonce) - throws AuthenticationFailedException { + /** + * Computes the response for CRAM-MD5 authentication mechanism given the user credentials and + * the server-provided nonce. + * + * @param username The username. + * @param password The password. + * @param b64Nonce The nonce as base64-encoded string. + * @return The CRAM-MD5 response. + * + * @throws AuthenticationFailedException If something went wrong. + * + * @see Authentication#computeCramMd5Bytes(String, String, byte[]) + */ + public static String computeCramMd5(String username, String password, String b64Nonce) + throws AuthenticationFailedException { try { - byte[] b64NonceBytes = b64Nonce.getBytes(US_ASCII); - byte[] b64CRAM = computeCramMd5Bytes(username, password, b64NonceBytes); - return new String(b64CRAM, US_ASCII); + byte[] b64NonceBytes = b64Nonce.getBytes(US_ASCII); + byte[] b64CRAM = computeCramMd5Bytes(username, password, b64NonceBytes); + return new String(b64CRAM, US_ASCII); } catch (AuthenticationFailedException e) { - throw e; + throw e; } catch (Exception e) { - throw new AuthenticationFailedException("This shouldn't happen", e); + throw new AuthenticationFailedException("This shouldn't happen", e); } - } + } - /** - * Computes the response for CRAM-MD5 authentication mechanism given the user credentials and - * the server-provided nonce. - * - * @param username The username. - * @param password The password. - * @param b64Nonce The nonce as base64-encoded byte array. - * @return The CRAM-MD5 response as byte array. - * - * @throws AuthenticationFailedException If something went wrong. - * - * @see RFC 2195 - */ - public static byte[] computeCramMd5Bytes(String username, String password, byte[] b64Nonce) - throws AuthenticationFailedException { + /** + * Computes the response for CRAM-MD5 authentication mechanism given the user credentials and + * the server-provided nonce. + * + * @param username The username. + * @param password The password. + * @param b64Nonce The nonce as base64-encoded byte array. + * @return The CRAM-MD5 response as byte array. + * + * @throws AuthenticationFailedException If something went wrong. + * + * @see RFC 2195 + */ + public static byte[] computeCramMd5Bytes(String username, String password, byte[] b64Nonce) + throws AuthenticationFailedException { try { - byte[] nonce = Base64.decodeBase64(b64Nonce); + byte[] nonce = Base64.decodeBase64(b64Nonce); - byte[] secretBytes = password.getBytes(US_ASCII); - MessageDigest md = MessageDigest.getInstance("MD5"); - if (secretBytes.length > 64) { - secretBytes = md.digest(secretBytes); - } + byte[] secretBytes = password.getBytes(US_ASCII); + MessageDigest md = MessageDigest.getInstance("MD5"); + if (secretBytes.length > 64) { + secretBytes = md.digest(secretBytes); + } - byte[] ipad = new byte[64]; - byte[] opad = new byte[64]; - System.arraycopy(secretBytes, 0, ipad, 0, secretBytes.length); - System.arraycopy(secretBytes, 0, opad, 0, secretBytes.length); - for (int i = 0; i < ipad.length; i++) ipad[i] ^= 0x36; - for (int i = 0; i < opad.length; i++) opad[i] ^= 0x5c; + byte[] ipad = new byte[64]; + byte[] opad = new byte[64]; + System.arraycopy(secretBytes, 0, ipad, 0, secretBytes.length); + System.arraycopy(secretBytes, 0, opad, 0, secretBytes.length); + for (int i = 0; i < ipad.length; i++) ipad[i] ^= 0x36; + for (int i = 0; i < opad.length; i++) opad[i] ^= 0x5c; - md.update(ipad); - byte[] firstPass = md.digest(nonce); + md.update(ipad); + byte[] firstPass = md.digest(nonce); - md.update(opad); - byte[] result = md.digest(firstPass); + md.update(opad); + byte[] result = md.digest(firstPass); - String plainCRAM = username + " " + new String(Hex.encodeHex(result)); - byte[] b64CRAM = Base64.encodeBase64(plainCRAM.getBytes(US_ASCII)); + String plainCRAM = username + " " + new String(Hex.encodeHex(result)); + byte[] b64CRAM = Base64.encodeBase64(plainCRAM.getBytes(US_ASCII)); - return b64CRAM; + return b64CRAM; } catch (Exception e) { - throw new AuthenticationFailedException("Something went wrong during CRAM-MD5 computation", e); + throw new AuthenticationFailedException("Something went wrong during CRAM-MD5 computation", e); } - } + } } diff --git a/src/com/fsck/k9/mail/filter/Hex.java b/src/com/fsck/k9/mail/filter/Hex.java index 5bbcf7b05..92022203b 100644 --- a/src/com/fsck/k9/mail/filter/Hex.java +++ b/src/com/fsck/k9/mail/filter/Hex.java @@ -20,14 +20,13 @@ package com.fsck.k9.mail.filter; * This code was copied from the Apache Commons project. * The unnecessary parts have been left out. */ -public class Hex -{ +public class Hex { /** * Used building output as Hex */ private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; /** @@ -43,15 +42,15 @@ public class Hex int l = data.length; - char[] out = new char[l << 1]; + char[] out = new char[l << 1]; - // two characters form the hex value. - for (int i = 0, j = 0; i < l; i++) { - out[j++] = DIGITS[(0xF0 & data[i]) >>> 4 ]; - out[j++] = DIGITS[ 0x0F & data[i] ]; - } + // two characters form the hex value. + for (int i = 0, j = 0; i < l; i++) { + out[j++] = DIGITS[(0xF0 & data[i]) >>> 4 ]; + out[j++] = DIGITS[ 0x0F & data[i] ]; + } - return out; + return out; } } diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java index 24f9da2da..84ce1e063 100644 --- a/src/com/fsck/k9/mail/internet/MimeUtility.java +++ b/src/com/fsck/k9/mail/internet/MimeUtility.java @@ -1212,13 +1212,13 @@ public class MimeUtility { * @see #MIME_TYPE_REPLACEMENT_MAP */ public static String canonicalizeMimeType(String mimeType) { - for (String[] mimeTypeMapEntry : MIME_TYPE_REPLACEMENT_MAP) { - if (mimeTypeMapEntry[0].equals(mimeType)) { - return mimeTypeMapEntry[1]; - } - } - return mimeType; - } + for (String[] mimeTypeMapEntry : MIME_TYPE_REPLACEMENT_MAP) { + if (mimeTypeMapEntry[0].equals(mimeType)) { + return mimeTypeMapEntry[1]; + } + } + return mimeType; + } /** * When viewing the attachment we want the MIME type to be as sensible as diff --git a/src/com/fsck/k9/mail/store/ImapResponseParser.java b/src/com/fsck/k9/mail/store/ImapResponseParser.java index 090dd85ad..8e93ea65e 100644 --- a/src/com/fsck/k9/mail/store/ImapResponseParser.java +++ b/src/com/fsck/k9/mail/store/ImapResponseParser.java @@ -362,7 +362,7 @@ public class ImapResponseParser { } return parseDate(value); } catch (ParseException pe) { - throw new MessagingException("Unable to parse IMAP datetime '"+value+"' ", pe); + throw new MessagingException("Unable to parse IMAP datetime '" + value + "' ", pe); } } @@ -428,7 +428,7 @@ public class ImapResponseParser { } } catch (Exception e2) { try { - synchronized (badDateTimeFormat2) { + synchronized (badDateTimeFormat2) { return badDateTimeFormat2.parse(value); } } catch (Exception e3) { diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index 13e626a5d..339a74124 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -2098,7 +2098,7 @@ public class ImapStore extends Store { System.arraycopy(buf, 1, b64NonceTrim, 0, b64NonceLen - 2); byte[] b64CRAM = Authentication.computeCramMd5Bytes(mSettings.getUsername(), - mSettings.getPassword(), b64NonceTrim); + mSettings.getPassword(), b64NonceTrim); mOut.write(b64CRAM); mOut.write(new byte[] { 0x0d, 0x0a }); diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java index 252f804ec..50b224d64 100644 --- a/src/com/fsck/k9/mail/store/LocalStore.java +++ b/src/com/fsck/k9/mail/store/LocalStore.java @@ -1675,7 +1675,7 @@ public class LocalStore extends Store implements Serializable { } String encoded_name = EncoderUtil.encodeIfNecessary(name, - EncoderUtil.Usage.WORD_ENTITY, 7); + EncoderUtil.Usage.WORD_ENTITY, 7); MimeBodyPart bp = new LocalAttachmentBodyPart(body, id); bp.setHeader(MimeHeader.HEADER_CONTENT_TYPE, diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java index a5df595cf..188b5476b 100644 --- a/src/com/fsck/k9/mail/store/Pop3Store.java +++ b/src/com/fsck/k9/mail/store/Pop3Store.java @@ -91,11 +91,10 @@ public class Pop3Store extends Store { try { int userIndex = 0, passwordIndex = 1; String[] userInfoParts = uri.getUserInfo().split(":"); - if (userInfoParts.length > 2) - { - userIndex++; - passwordIndex++; - useCramMd5 = true; + if (userInfoParts.length > 2) { + userIndex++; + passwordIndex++; + useCramMd5 = true; } mUsername = URLDecoder.decode(userInfoParts[userIndex], "UTF-8"); if (userInfoParts.length > passwordIndex) { @@ -224,8 +223,7 @@ public class Pop3Store extends Store { } } - if (useCramMd5) - { + if (useCramMd5) { try { String b64Nonce = executeSimpleCommand("AUTH CRAM-MD5").replace("+ ", ""); @@ -235,9 +233,7 @@ public class Pop3Store extends Store { } catch (MessagingException me) { throw new AuthenticationFailedException(null, me); } - } - else - { + } else { try { executeSimpleCommand("USER " + mUsername); executeSimpleCommand("PASS " + mPassword, true); diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java index 9ae26e79a..142c8ac9f 100644 --- a/src/com/fsck/k9/mail/transport/SmtpTransport.java +++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java @@ -520,9 +520,9 @@ public class SmtpTransport extends Transport { private void saslAuthCramMD5(String username, String password) throws MessagingException, AuthenticationFailedException, IOException { - List respList = executeSimpleCommand("AUTH CRAM-MD5"); + List respList = executeSimpleCommand("AUTH CRAM-MD5"); if (respList.size() != 1) { - throw new AuthenticationFailedException("Unable to negotiate CRAM-MD5"); + throw new AuthenticationFailedException("Unable to negotiate CRAM-MD5"); } String b64Nonce = respList.get(0); From 50b906aef7e87f4bf5ba8d4b778480fc559c7eb5 Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:08:10 -0700 Subject: [PATCH 005/121] Added mInboxFolderName and mOutboxFolderName fields --- src/com/fsck/k9/Account.java | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java index 719e4b15a..5aefe10c2 100644 --- a/src/com/fsck/k9/Account.java +++ b/src/com/fsck/k9/Account.java @@ -80,11 +80,13 @@ public class Account implements BaseAccount { private long mLatestOldMessageSeenTime; private boolean mNotifyNewMail; private boolean mNotifySelfNewMail; + private String mInboxFolderName; private String mDraftsFolderName; private String mSentFolderName; private String mTrashFolderName; private String mArchiveFolderName; private String mSpamFolderName; + private String mOutboxFolderName; private String mAutoExpandFolderName; private FolderMode mFolderDisplayMode; private FolderMode mFolderSyncMode; @@ -180,7 +182,8 @@ public class Account implements BaseAccount { mEnableMoveButtons = false; mIsSignatureBeforeQuotedText = false; mExpungePolicy = EXPUNGE_IMMEDIATELY; - mAutoExpandFolderName = "INBOX"; + mAutoExpandFolderName = K9.INBOX; + mInboxFolderName = K9.INBOX; mMaxPushFolders = 10; mChipColor = (new Random()).nextInt(0xffffff) + 0xff000000; goToUnreadMessageSearch = false; @@ -246,11 +249,13 @@ public class Account implements BaseAccount { mNotifySelfNewMail = prefs.getBoolean(mUuid + ".notifySelfNewMail", true); mNotifySync = prefs.getBoolean(mUuid + ".notifyMailCheck", false); mDeletePolicy = prefs.getInt(mUuid + ".deletePolicy", 0); + mInboxFolderName = prefs.getString(mUuid + ".inboxFolderName", K9.INBOX); mDraftsFolderName = prefs.getString(mUuid + ".draftsFolderName", "Drafts"); mSentFolderName = prefs.getString(mUuid + ".sentFolderName", "Sent"); mTrashFolderName = prefs.getString(mUuid + ".trashFolderName", "Trash"); mArchiveFolderName = prefs.getString(mUuid + ".archiveFolderName", "Archive"); mSpamFolderName = prefs.getString(mUuid + ".spamFolderName", "Spam"); + mOutboxFolderName = prefs.getString(mUuid + ".outboxFolderName", "Outbox"); mExpungePolicy = prefs.getString(mUuid + ".expungePolicy", EXPUNGE_IMMEDIATELY); mSyncRemoteDeletions = prefs.getBoolean(mUuid + ".syncRemoteDeletions", true); @@ -270,8 +275,7 @@ public class Account implements BaseAccount { compressionMap.put(type, useCompression); } - mAutoExpandFolderName = prefs.getString(mUuid + ".autoExpandFolderName", - "INBOX"); + mAutoExpandFolderName = prefs.getString(mUuid + ".autoExpandFolderName", K9.INBOX); mAccountNumber = prefs.getInt(mUuid + ".accountNumber", 0); @@ -394,6 +398,7 @@ public class Account implements BaseAccount { editor.remove(mUuid + ".trashFolderName"); editor.remove(mUuid + ".archiveFolderName"); editor.remove(mUuid + ".spamFolderName"); + editor.remove(mUuid + ".outboxFolderName"); editor.remove(mUuid + ".autoExpandFolderName"); editor.remove(mUuid + ".accountNumber"); editor.remove(mUuid + ".vibrate"); @@ -485,11 +490,13 @@ public class Account implements BaseAccount { editor.putBoolean(mUuid + ".notifySelfNewMail", mNotifySelfNewMail); editor.putBoolean(mUuid + ".notifyMailCheck", mNotifySync); editor.putInt(mUuid + ".deletePolicy", mDeletePolicy); + editor.putString(mUuid + ".inboxFolderName", mInboxFolderName); editor.putString(mUuid + ".draftsFolderName", mDraftsFolderName); editor.putString(mUuid + ".sentFolderName", mSentFolderName); editor.putString(mUuid + ".trashFolderName", mTrashFolderName); editor.putString(mUuid + ".archiveFolderName", mArchiveFolderName); editor.putString(mUuid + ".spamFolderName", mSpamFolderName); + editor.putString(mUuid + ".outboxFolderName", mOutboxFolderName); editor.putString(mUuid + ".autoExpandFolderName", mAutoExpandFolderName); editor.putInt(mUuid + ".accountNumber", mAccountNumber); editor.putString(mUuid + ".hideButtonsEnum", mScrollMessageViewButtons.name()); @@ -762,7 +769,7 @@ public class Account implements BaseAccount { public boolean isSpecialFolder(String folderName) { - if (folderName != null && (folderName.equalsIgnoreCase(K9.INBOX) || + if (folderName != null && (folderName.equalsIgnoreCase(getInboxFolderName()) || folderName.equals(getTrashFolderName()) || folderName.equals(getDraftsFolderName()) || folderName.equals(getArchiveFolderName()) || @@ -824,7 +831,11 @@ public class Account implements BaseAccount { } public synchronized String getOutboxFolderName() { - return K9.OUTBOX; + return mOutboxFolderName; + } + + public synchronized void setOutboxFolderName(String outboxFolderName) { + mOutboxFolderName = outboxFolderName; } public synchronized String getAutoExpandFolderName() { @@ -1303,6 +1314,15 @@ public class Account implements BaseAccount { public void setCryptoAutoSignature(boolean cryptoAutoSignature) { mCryptoAutoSignature = cryptoAutoSignature; } + + public String getInboxFolderName() { + return mInboxFolderName; + } + + public void setInboxFolderName(String mInboxFolderName) { + this.mInboxFolderName = mInboxFolderName; + } + public synchronized boolean syncRemoteDeletions() { return mSyncRemoteDeletions; } From 680e2e419163df030a26cfca2a2682c743ffe422 Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:10:11 -0700 Subject: [PATCH 006/121] Replaced references to K9.INBOX with account.getInboxFolderName() --- src/com/fsck/k9/activity/ChooseFolder.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/com/fsck/k9/activity/ChooseFolder.java b/src/com/fsck/k9/activity/ChooseFolder.java index 01513196f..5d0ff100f 100644 --- a/src/com/fsck/k9/activity/ChooseFolder.java +++ b/src/com/fsck/k9/activity/ChooseFolder.java @@ -248,7 +248,8 @@ public class ChooseFolder extends K9ListActivity { String name = folder.getName(); // Inbox needs to be compared case-insensitively - if (hideCurrentFolder && (name.equals(mFolder) || (K9.INBOX.equalsIgnoreCase(mFolder) && K9.INBOX.equalsIgnoreCase(name)))) { + if (hideCurrentFolder && (name.equals(mFolder) || + (mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name)))) { continue; } try { @@ -282,10 +283,10 @@ public class ChooseFolder extends K9ListActivity { if (K9.FOLDER_NONE.equalsIgnoreCase(bName)) { return 1; } - if (K9.INBOX.equalsIgnoreCase(aName)) { + if (mAccount.getInboxFolderName().equalsIgnoreCase(aName)) { return -1; } - if (K9.INBOX.equalsIgnoreCase(bName)) { + if (mAccount.getInboxFolderName().equalsIgnoreCase(bName)) { return 1; } @@ -298,7 +299,7 @@ public class ChooseFolder extends K9ListActivity { mAdapter.clear(); int position = 0; for (String name : localFolders) { - if (K9.INBOX.equalsIgnoreCase(name)) { + if (mAccount.getInboxFolderName().equalsIgnoreCase(name)) { mAdapter.add(getString(R.string.special_mailbox_name_inbox)); heldInbox = name; } else if (!K9.ERROR_FOLDER_NAME.equals(name) && !account.getOutboxFolderName().equals(name)) { @@ -315,7 +316,7 @@ public class ChooseFolder extends K9ListActivity { selectedFolder = position; } } else if (name.equals(mFolder) || - (K9.INBOX.equalsIgnoreCase(mFolder) && K9.INBOX.equalsIgnoreCase(name))) { + (mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name))) { selectedFolder = position; } position++; From 236226858ca0681761ef3982d17e01100d48c597 Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:11:21 -0700 Subject: [PATCH 007/121] Replaced references to K9.INBOX with account.getInboxFolderName() --- src/com/fsck/k9/activity/FolderInfoHolder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/fsck/k9/activity/FolderInfoHolder.java b/src/com/fsck/k9/activity/FolderInfoHolder.java index 30023b343..4f9eca5f0 100644 --- a/src/com/fsck/k9/activity/FolderInfoHolder.java +++ b/src/com/fsck/k9/activity/FolderInfoHolder.java @@ -97,7 +97,7 @@ public class FolderInfoHolder implements Comparable { this.status = truncateStatus(folder.getStatus()); - if (this.name.equalsIgnoreCase(K9.INBOX)) { + if (this.name.equalsIgnoreCase(account.getInboxFolderName())) { this.displayName = context.getString(R.string.special_mailbox_name_inbox); } else { this.displayName = folder.getName(); From ccc79f62b92a1095c04ebe6633d01aeda7383f26 Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:12:06 -0700 Subject: [PATCH 008/121] Replaced references to K9.INBOX with account.getInboxFolderName() --- src/com/fsck/k9/activity/MessageList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 23ac75e79..915e9ef00 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -491,7 +491,7 @@ public class MessageList if (mFolderName != null) { displayName = mFolderName; - if (K9.INBOX.equalsIgnoreCase(displayName)) { + if (mAccount.getInboxFolderName().equalsIgnoreCase(displayName)) { displayName = getString(R.string.special_mailbox_name_inbox); } else if (mAccount.getOutboxFolderName().equals(displayName)) { displayName = getString(R.string.special_mailbox_name_outbox); From 32901667496a84cec9c78d9d1613fbb44b0ce88f Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:14:56 -0700 Subject: [PATCH 009/121] Replaced references to K9.INBOX with account.getInboxFolderName() and disabled the call to reverseTranslateFolder in case of WebDav account --- src/com/fsck/k9/activity/setup/AccountSettings.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/com/fsck/k9/activity/setup/AccountSettings.java b/src/com/fsck/k9/activity/setup/AccountSettings.java index b5c4a54b4..c54f82cc4 100644 --- a/src/com/fsck/k9/activity/setup/AccountSettings.java +++ b/src/com/fsck/k9/activity/setup/AccountSettings.java @@ -700,7 +700,13 @@ public class AccountSettings extends K9PreferenceActivity { mAccount.setCryptoAutoSignature(mCryptoAutoSignature.isChecked()); mAccount.setLocalStorageProviderId(mLocalStorageProvider.getValue()); - mAccount.setAutoExpandFolderName(reverseTranslateFolder(mAutoExpandFolder.getValue())); + // In webdav account we use the exact folder name also for inbox, + // since it varies because of internationalization + if(mAccount.getStoreUri().startsWith("webdav")) + mAccount.setAutoExpandFolderName(mAutoExpandFolder.getValue()); + else + mAccount.setAutoExpandFolderName(reverseTranslateFolder(mAutoExpandFolder.getValue())); + mAccount.setArchiveFolderName(mArchiveFolder.getValue()); mAccount.setDraftsFolderName(mDraftsFolder.getValue()); mAccount.setSentFolderName(mSentFolder.getValue()); @@ -826,7 +832,7 @@ public class AccountSettings extends K9PreferenceActivity { } private String translateFolder(String in) { - if (K9.INBOX.equalsIgnoreCase(in)) { + if (mAccount.getInboxFolderName().equalsIgnoreCase(in)) { return getString(R.string.special_mailbox_name_inbox); } else { return in; @@ -835,7 +841,7 @@ public class AccountSettings extends K9PreferenceActivity { private String reverseTranslateFolder(String in) { if (getString(R.string.special_mailbox_name_inbox).equals(in)) { - return K9.INBOX; + return mAccount.getInboxFolderName(); } else { return in; } From 879d8726169eb637ef51517217055449c893fd2e Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:19:27 -0700 Subject: [PATCH 010/121] Replaced references to K9.INBOX with account.getInboxFolderName() --- src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java index 2aaac3fd5..bfc8e3520 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java @@ -116,7 +116,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList setMessage(R.string.account_setup_check_settings_fetch); } MessagingController.getInstance(getApplication()).listFoldersSynchronous(mAccount, true, null); - MessagingController.getInstance(getApplication()).synchronizeMailbox(mAccount, K9.INBOX , null, null); + MessagingController.getInstance(getApplication()).synchronizeMailbox(mAccount, mAccount.getInboxFolderName(), null, null); } if (mDestroyed) { return; From 461b57747c1209ab451275828b94c2f21f88a1d1 Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:23:57 -0700 Subject: [PATCH 011/121] Replaced references to K9.INBOX with account.getInboxFolderName() --- src/com/fsck/k9/controller/MessagingController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index 7acc65882..de04e2d1c 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -719,7 +719,7 @@ public class MessagingController implements Runnable { } } // Never exclude the INBOX (see issue 1817) - else if (noSpecialFolders && !localFolderName.equalsIgnoreCase(K9.INBOX) && + else if (noSpecialFolders && !localFolderName.equalsIgnoreCase(account.getInboxFolderName()) && !localFolderName.equals(account.getArchiveFolderName()) && account.isSpecialFolder(localFolderName)) { include = false; } else if (displayableOnly && modeMismatch(account.getFolderDisplayMode(), folder.getDisplayClass())) { @@ -2880,7 +2880,7 @@ public class MessagingController implements Runnable { (NotificationManager)mApplication.getSystemService(Context.NOTIFICATION_SERVICE); Notification notif = new Notification(R.drawable.ic_menu_refresh, mApplication.getString(R.string.notification_bg_send_ticker, account.getDescription()), System.currentTimeMillis()); - Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, K9.INBOX); + Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, account.getInboxFolderName()); PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0); notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.notification_bg_send_title), account.getDescription() , pi); @@ -2922,7 +2922,7 @@ public class MessagingController implements Runnable { Notification notif = new Notification(R.drawable.ic_menu_refresh, mApplication.getString(R.string.notification_bg_sync_ticker, account.getDescription(), folder.getName()), System.currentTimeMillis()); - Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, K9.INBOX); + Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, account.getInboxFolderName()); PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0); notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.notification_bg_sync_title), account.getDescription() + mApplication.getString(R.string.notification_bg_title_separator) + folder.getName(), pi); @@ -3867,7 +3867,7 @@ public class MessagingController implements Runnable { // No notification for new messages in Trash, Drafts, Spam or Sent folder. // But do notify if it's the INBOX (see issue 1817). String folderName = folder.getName(); - if (!K9.INBOX.equals(folderName) && + if (!account.getInboxFolderName().equals(folderName) && (account.getTrashFolderName().equals(folderName) || account.getDraftsFolderName().equals(folderName) || account.getSpamFolderName().equals(folderName) From 20a9043a135c29d3d1da8c31ee8d24e8a96c1152 Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:27:04 -0700 Subject: [PATCH 012/121] Replaced references to K9.INBOX with account.getInboxFolderName() --- src/com/fsck/k9/mail/store/ImapStore.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index 339a74124..bbd7fc148 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -380,7 +380,7 @@ public class ImapStore extends Store { mCombinedPrefix = null; } - if (folder.equalsIgnoreCase(K9.INBOX)) { + if (folder.equalsIgnoreCase(mAccount.getInboxFolderName())) { continue; } else if (folder.equalsIgnoreCase(K9.OUTBOX)) { /* @@ -413,7 +413,7 @@ public class ImapStore extends Store { } } } - folders.add(getFolder("INBOX")); + folders.add(getFolder(mAccount.getInboxFolderName())); return folders; } @@ -548,7 +548,7 @@ public class ImapStore extends Store { public String getPrefixedName() throws MessagingException { String prefixedName = ""; - if (!K9.INBOX.equalsIgnoreCase(mName)) { + if (!mAccount.getInboxFolderName().equalsIgnoreCase(mName)) { ImapConnection connection = null; synchronized (this) { if (mConnection == null) { From 59b1d57658d982609fbb48e8cdd108201a636980 Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:27:39 -0700 Subject: [PATCH 013/121] Replaced references to K9.INBOX with account.getInboxFolderName() --- src/com/fsck/k9/mail/store/LocalStore.java | 23 +++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java index 50b224d64..4c010924b 100644 --- a/src/com/fsck/k9/mail/store/LocalStore.java +++ b/src/com/fsck/k9/mail/store/LocalStore.java @@ -366,7 +366,7 @@ public class LocalStore extends Store implements Serializable { Folder.FolderClass pushClass = Folder.FolderClass.SECOND_CLASS; boolean inTopGroup = false; boolean integrate = false; - if (K9.INBOX.equals(name)) { + if (mAccount.getInboxFolderName().equals(name)) { displayClass = Folder.FolderClass.FIRST_CLASS; syncClass = Folder.FolderClass.FIRST_CLASS; pushClass = Folder.FolderClass.FIRST_CLASS; @@ -515,7 +515,7 @@ public class LocalStore extends Store implements Serializable { mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "", mAccount.getOutboxFolderName() != null ? mAccount.getOutboxFolderName() : "", mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "", - K9.INBOX + mAccount.getInboxFolderName() } ); @@ -526,7 +526,7 @@ public class LocalStore extends Store implements Serializable { mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "", mAccount.getOutboxFolderName() != null ? mAccount.getOutboxFolderName() : "", mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "", - K9.INBOX, Folder.FolderClass.FIRST_CLASS.name() + mAccount.getInboxFolderName(), Folder.FolderClass.FIRST_CLASS.name() }); @@ -537,7 +537,7 @@ public class LocalStore extends Store implements Serializable { mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "", mAccount.getOutboxFolderName() != null ? mAccount.getOutboxFolderName() : "", mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "", - K9.INBOX, Folder.FolderClass.FIRST_CLASS.name(), Folder.FolderClass.SECOND_CLASS.name() + mAccount.getInboxFolderName(), Folder.FolderClass.FIRST_CLASS.name(), Folder.FolderClass.SECOND_CLASS.name() }); } else if (displayMode == Account.FolderMode.NOT_SECOND_CLASS) { cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class != ?)", new String[] { @@ -547,7 +547,7 @@ public class LocalStore extends Store implements Serializable { mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "", mAccount.getOutboxFolderName() != null ? mAccount.getOutboxFolderName() : "", mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "", - K9.INBOX, Folder.FolderClass.SECOND_CLASS.name() + mAccount.getInboxFolderName(), Folder.FolderClass.SECOND_CLASS.name() }); } else if (displayMode == Account.FolderMode.ALL) { cursor = db.rawQuery(baseQuery, new String[] { @@ -1047,14 +1047,14 @@ public class LocalStore extends Store implements Serializable { if (mAccount.isSpecialFolder(name)) { prefHolder.inTopGroup = true; prefHolder.displayClass = LocalFolder.FolderClass.FIRST_CLASS; - if (name.equalsIgnoreCase(K9.INBOX)) { + if (name.equalsIgnoreCase(mAccount.getInboxFolderName())) { prefHolder.integrate = true; prefHolder.pushClass = LocalFolder.FolderClass.FIRST_CLASS; } else { prefHolder.pushClass = LocalFolder.FolderClass.INHERITED; } - if (name.equalsIgnoreCase(K9.INBOX) || + if (name.equalsIgnoreCase(mAccount.getInboxFolderName()) || name.equalsIgnoreCase(mAccount.getDraftsFolderName())) { prefHolder.syncClass = LocalFolder.FolderClass.FIRST_CLASS; } else { @@ -1104,7 +1104,8 @@ public class LocalStore extends Store implements Serializable { super(LocalStore.this.mAccount); this.mName = name; - if (K9.INBOX.equals(getName())) { + if (LocalStore.this.mAccount.getInboxFolderName().equals(getName())) { + mSyncClass = FolderClass.FIRST_CLASS; mPushClass = FolderClass.FIRST_CLASS; mInTopGroup = true; @@ -1484,19 +1485,19 @@ public class LocalStore extends Store implements Serializable { String id = getPrefId(); // there can be a lot of folders. For the defaults, let's not save prefs, saving space, except for INBOX - if (mDisplayClass == FolderClass.NO_CLASS && !K9.INBOX.equals(getName())) { + if (mDisplayClass == FolderClass.NO_CLASS && !mAccount.getInboxFolderName().equals(getName())) { editor.remove(id + ".displayMode"); } else { editor.putString(id + ".displayMode", mDisplayClass.name()); } - if (mSyncClass == FolderClass.INHERITED && !K9.INBOX.equals(getName())) { + if (mSyncClass == FolderClass.INHERITED && !mAccount.getInboxFolderName().equals(getName())) { editor.remove(id + ".syncMode"); } else { editor.putString(id + ".syncMode", mSyncClass.name()); } - if (mPushClass == FolderClass.SECOND_CLASS && !K9.INBOX.equals(getName())) { + if (mPushClass == FolderClass.SECOND_CLASS && !mAccount.getInboxFolderName().equals(getName())) { editor.remove(id + ".pushMode"); } else { editor.putString(id + ".pushMode", mPushClass.name()); From c46372b58cd0c3b64648610b388579092d860e62 Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:28:04 -0700 Subject: [PATCH 014/121] Replaced references to K9.INBOX with account.getInboxFolderName() --- src/com/fsck/k9/mail/store/Pop3Store.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java index 188b5476b..b9d3eae8b 100644 --- a/src/com/fsck/k9/mail/store/Pop3Store.java +++ b/src/com/fsck/k9/mail/store/Pop3Store.java @@ -120,13 +120,13 @@ public class Pop3Store extends Store { @Override public List getPersonalNamespaces(boolean forceListAll) throws MessagingException { List folders = new LinkedList(); - folders.add(getFolder("INBOX")); + folders.add(getFolder(mAccount.getInboxFolderName())); return folders; } @Override public void checkSettings() throws MessagingException { - Pop3Folder folder = new Pop3Folder("INBOX"); + Pop3Folder folder = new Pop3Folder(mAccount.getInboxFolderName()); folder.open(OpenMode.READ_WRITE); if (!mCapabilities.uidl) { /* @@ -157,8 +157,9 @@ public class Pop3Store extends Store { public Pop3Folder(String name) { super(Pop3Store.this.mAccount); this.mName = name; - if (mName.equalsIgnoreCase("INBOX")) { - mName = "INBOX"; + + if (mName.equalsIgnoreCase(mAccount.getInboxFolderName())) { + mName = mAccount.getInboxFolderName(); } } @@ -168,7 +169,7 @@ public class Pop3Store extends Store { return; } - if (!mName.equalsIgnoreCase("INBOX")) { + if (!mName.equalsIgnoreCase(mAccount.getInboxFolderName())) { throw new MessagingException("Folder does not exist"); } @@ -325,7 +326,7 @@ public class Pop3Store extends Store { @Override public boolean exists() throws MessagingException { - return mName.equalsIgnoreCase("INBOX"); + return mName.equalsIgnoreCase(mAccount.getInboxFolderName()); } @Override From 0a5d7ba953980c7dc989bcf1a1fb62345254dff7 Mon Sep 17 00:00:00 2001 From: bitblaster Date: Tue, 5 Apr 2011 02:31:17 -0700 Subject: [PATCH 015/121] In getPersonalNameSpaces now we ask the server for the real folder names corresponding to the special folders ids (for which we have constants), so we can map the account folders using the real names. --- src/com/fsck/k9/mail/store/WebDavStore.java | 319 ++++++++++++-------- 1 file changed, 195 insertions(+), 124 deletions(-) diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java index efedebf7b..297811357 100644 --- a/src/com/fsck/k9/mail/store/WebDavStore.java +++ b/src/com/fsck/k9/mail/store/WebDavStore.java @@ -1,58 +1,38 @@ package com.fsck.k9.mail.store; -import android.util.Log; +import java.io.*; +import java.net.*; +import java.security.*; +import java.text.*; +import java.util.*; +import java.util.zip.*; -import com.fsck.k9.Account; -import com.fsck.k9.K9; -import com.fsck.k9.R; -import com.fsck.k9.controller.MessageRetrievalListener; -import com.fsck.k9.helper.Utility; +import javax.net.ssl.*; +import javax.xml.parsers.*; + +import org.apache.http.*; +import org.apache.http.client.*; +import org.apache.http.client.entity.*; +import org.apache.http.client.methods.*; +import org.apache.http.client.protocol.*; +import org.apache.http.conn.scheme.*; +import org.apache.http.entity.*; +import org.apache.http.impl.client.*; +import org.apache.http.message.*; +import org.apache.http.protocol.*; +import org.xml.sax.*; +import org.xml.sax.helpers.*; + +import android.util.*; + +import com.fsck.k9.*; +import com.fsck.k9.controller.*; +import com.fsck.k9.helper.*; import com.fsck.k9.mail.*; import com.fsck.k9.mail.Folder.OpenMode; -import com.fsck.k9.mail.filter.EOLConvertingOutputStream; -import com.fsck.k9.mail.internet.MimeMessage; -import com.fsck.k9.mail.transport.TrustedSocketFactory; -import org.apache.http.*; -import org.apache.http.client.CookieStore; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.protocol.ClientContext; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.protocol.BasicHttpContext; -import org.apache.http.protocol.HttpContext; -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; - -import javax.net.ssl.SSLException; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import java.io.*; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Stack; -import java.util.zip.GZIPInputStream; +import com.fsck.k9.mail.filter.*; +import com.fsck.k9.mail.internet.*; +import com.fsck.k9.mail.transport.*; /** *
@@ -79,8 +59,13 @@ public class WebDavStore extends Store {
 
     private static final Message[] EMPTY_MESSAGE_ARRAY = new Message[0];
 
+    private static final Object DAV_MAIL_INBOX_FOLDER = "inbox";
+    private static final Object DAV_MAIL_DRAFTS_FOLDER = "drafts";
+    private static final String DAV_MAIL_SPAM_FOLDER = "spam";
     private static final String DAV_MAIL_SEND_FOLDER = "##DavMailSubmissionURI##";
-    private static final String DAV_MAIL_TMP_FOLDER = "drafts";
+	private static final Object DAV_MAIL_TRASH_FOLDER = "deleteditems";
+	private static final Object DAV_MAIL_OUTBOX_FOLDER = "outbox";
+	private static final Object DAV_MAIL_SENT_FOLDER = "sentitems";
 
     private short mConnectionSecurity;
     private String mUsername; /* Stores the username for authentications */
@@ -101,6 +86,7 @@ public class WebDavStore extends Store {
     private short mAuthentication = AUTH_TYPE_NONE;
     private String mCachedLoginUrl;
 
+    private Folder mSendFolder = null;
     private HashMap mFolderList = new HashMap();
 
     /**
@@ -231,63 +217,120 @@ public class WebDavStore extends Store {
     @Override
     public List  getPersonalNamespaces(boolean forceListAll) throws MessagingException {
         LinkedList folderList = new LinkedList();
-        HashMap headers = new HashMap();
-        DataSet dataset = new DataSet();
-        String messageBody;
-        String[] folderUrls;
-        int urlLength;
-
-        String translatedInbox = K9.app.getString(R.string.special_mailbox_name_inbox);
-
         /**
          * We have to check authentication here so we have the proper URL stored
          */
         getHttpClient();
-        messageBody = getFolderListXml();
+
+        /**
+         *  Firstly we get the "special" folders list (inbox, outbox, etc)
+         *  and setup the account accordingly
+         */
+        HashMap headers = new HashMap();
+        DataSet dataset = new DataSet();
+        headers.put("Depth", "0");
         headers.put("Brief", "t");
-        dataset = processRequest(this.mUrl, "SEARCH", messageBody, headers);
+        dataset = processRequest(this.mUrl, "PROPFIND", getSpecialFoldersList(), headers);
 
-        folderUrls = dataset.getHrefs();
-        urlLength = folderUrls.length;
+        HashMap specialFoldersMap = dataset.getSpecialFolderToUrl();
+        String folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_INBOX_FOLDER));
+        if(folderName != null) {
+		mAccount.setAutoExpandFolderName(folderName);
+		mAccount.setInboxFolderName(folderName);
+        }
 
-        for (int i = 0; i < urlLength; i++) {
-            String[] urlParts = folderUrls[i].split("/");
-            String folderName = urlParts[urlParts.length - 1];
-            String fullPathName = "";
-            WebDavFolder wdFolder;
+        folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_DRAFTS_FOLDER));
+        if(folderName != null)
+		mAccount.setDraftsFolderName(folderName);
 
-            // Check each Exchange folder name to see if it is the user's inbox.
-            // We will check for the default English inbox ("Inbox"), and the user's
-            // translation for "Inbox", in case the user is using a non-English
-            // version of Exchange.
-            if (folderName.equalsIgnoreCase("Inbox") ||
-                    folderName.equalsIgnoreCase(translatedInbox)) {
-                folderName = K9.INBOX;
-            } else {
-                for (int j = 5, count = urlParts.length; j < count; j++) {
-                    if (j != 5) {
-                        fullPathName = fullPathName + "/" + urlParts[j];
-                    } else {
-                        fullPathName = urlParts[j];
-                    }
-                }
-                try {
-                    folderName = java.net.URLDecoder.decode(fullPathName, "UTF-8");
-                } catch (UnsupportedEncodingException uee) {
-                    /** If we don't support UTF-8 there's a problem, don't decode it then */
-                    folderName = fullPathName;
-                }
-            }
+        folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_TRASH_FOLDER));
+        if(folderName != null)
+		mAccount.setTrashFolderName(folderName);
 
-            wdFolder = new WebDavFolder(this, folderName);
-            wdFolder.setUrl(folderUrls[i]);
-            folderList.add(wdFolder);
-            this.mFolderList.put(folderName, wdFolder);
+        folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SPAM_FOLDER));
+        if(folderName != null)
+		mAccount.setSpamFolderName(folderName);
+
+        folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_OUTBOX_FOLDER));
+        if(folderName != null)
+		mAccount.setOutboxFolderName(folderName);
+
+        folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SENT_FOLDER));
+        if(folderName != null)
+		mAccount.setSentFolderName(folderName);
+
+        /**
+         * Next we get all the folders (including "special" ones)
+         */
+        headers = new HashMap();
+        dataset = new DataSet();
+        headers.put("Brief", "t");
+        dataset = processRequest(this.mUrl, "SEARCH", getFolderListXml(), headers);
+        String[] folderUrls = dataset.getHrefs();
+
+        for (int i = 0; i < folderUrls.length; i++) {
+            String tempUrl = folderUrls[i];
+            createFolder(tempUrl, folderList);
         }
 
         return folderList;
     }
 
+    private WebDavFolder createFolder(String folderUrl, LinkedList folderList) {
+	if(folderUrl == null || folderList == null)
+		return null;
+
+	WebDavFolder wdFolder=null;
+	String folderName = getFolderName(folderUrl);
+	if(folderName != null) {
+			if(!this.mFolderList.containsKey(folderName)) {
+                wdFolder = new WebDavFolder(this, folderName);
+                wdFolder.setUrl(folderUrl);
+		folderList.add(wdFolder);
+		mFolderList.put(folderName, wdFolder);
+			}
+        }
+	// else: Unknown URL format => NO Folder created
+
+	return wdFolder;
+	}
+
+    private String getFolderName(String folderUrl) {
+	if(folderUrl == null)
+		return null;
+
+        int folderSlash=-1;
+        for(int j=0; j < 5; j++) {
+		folderSlash=folderUrl.indexOf('/', folderSlash+1);
+		if(folderSlash < 0)
+			break;
+        }
+
+        if(folderSlash > 0) {
+		String folderName;
+		String fullPathName;
+
+		if(folderUrl.charAt(folderUrl.length()-1) == '/')
+			fullPathName = folderUrl.substring(folderSlash+1, folderUrl.length()-1);
+		else
+			fullPathName = folderUrl.substring(folderSlash+1);
+
+			try {
+				folderName = java.net.URLDecoder.decode(fullPathName, "UTF-8");
+			} catch (UnsupportedEncodingException uee) {
+				/**
+				 * If we don't support UTF-8 there's a problem, don't decode
+				 * it then
+				 */
+				folderName = fullPathName;
+			}
+
+			return folderName;
+		}
+
+        return null;
+    }
+
     @Override
     public Folder getFolder(String name) {
         WebDavFolder folder;
@@ -300,7 +343,10 @@ public class WebDavStore extends Store {
     }
 
     public Folder getSendSpoolFolder() throws MessagingException {
-        return getFolder(DAV_MAIL_SEND_FOLDER);
+		if (mSendFolder == null)
+			mSendFolder = getFolder(DAV_MAIL_SEND_FOLDER);
+
+		return mSendFolder;
     }
 
     @Override
@@ -313,6 +359,27 @@ public class WebDavStore extends Store {
         return true;
     }
 
+	private String getSpecialFoldersList() {
+		StringBuffer buffer = new StringBuffer(200);
+		buffer.append("");
+		buffer.append("");
+		buffer.append("");
+		buffer.append("<").append(DAV_MAIL_INBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		buffer.append("<").append(DAV_MAIL_DRAFTS_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		buffer.append("<").append(DAV_MAIL_OUTBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		buffer.append("<").append(DAV_MAIL_SENT_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		buffer.append("<").append(DAV_MAIL_TRASH_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		// This should always be ##DavMailSubmissionURI## for which we already have a constant
+		// buffer.append("");
+
+		//TODO: What is the id of the spam folder???
+		//buffer.append("<").append(DAV_MAIL_SPAM_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+
+		buffer.append("");
+		buffer.append("");
+		return buffer.toString();
+	}
+
     /***************************************************************
      * WebDAV XML Request body retrieval functions
      */
@@ -980,7 +1047,7 @@ public class WebDavStore extends Store {
 
     @Override
     public void sendMessages(Message[] messages) throws MessagingException {
-        WebDavFolder tmpFolder = (WebDavStore.WebDavFolder) getFolder(DAV_MAIL_TMP_FOLDER);
+		WebDavFolder tmpFolder = (WebDavStore.WebDavFolder) getFolder(mAccount.getDraftsFolderName());
         try {
             tmpFolder.open(OpenMode.READ_WRITE);
             Message[] retMessages = tmpFolder.appendWebDavMessages(messages);
@@ -1017,37 +1084,30 @@ public class WebDavStore extends Store {
             store = nStore;
             this.mName = name;
 
-            if (DAV_MAIL_SEND_FOLDER.equals(name)) {
-                this.mFolderUrl = getUrl() + "/" + name + "/";
-            } else {
-                String encodedName = "";
-                try {
-                    String[] urlParts = name.split("/");
-                    String url = "";
-                    for (int i = 0, count = urlParts.length; i < count; i++) {
-                        if (i != 0) {
-                            url = url + "/" + java.net.URLEncoder.encode(urlParts[i], "UTF-8");
-                        } else {
-                            url = java.net.URLEncoder.encode(urlParts[i], "UTF-8");
-                        }
+            String encodedName = "";
+            try {
+                String[] urlParts = name.split("/");
+                String url = "";
+                for (int i = 0, count = urlParts.length; i < count; i++) {
+                    if (i != 0) {
+                        url = url + "/" + java.net.URLEncoder.encode(urlParts[i], "UTF-8");
+                    } else {
+                        url = java.net.URLEncoder.encode(urlParts[i], "UTF-8");
                     }
-                    encodedName = url;
-                } catch (UnsupportedEncodingException uee) {
-                    Log.e(K9.LOG_TAG, "UnsupportedEncodingException URLEncoding folder name, skipping encoded");
-                    encodedName = name;
                 }
-
-                encodedName = encodedName.replaceAll("\\+", "%20");
-
-                if (encodedName.equals(K9.INBOX)) {
-                    encodedName = "Inbox";
-                }
-                this.mFolderUrl = WebDavStore.this.mUrl;
-                if (!WebDavStore.this.mUrl.endsWith("/")) {
-                    this.mFolderUrl += "/";
-                }
-                this.mFolderUrl += encodedName;
+                encodedName = url;
+            } catch (UnsupportedEncodingException uee) {
+                Log.e(K9.LOG_TAG, "UnsupportedEncodingException URLEncoding folder name, skipping encoded");
+                encodedName = name;
             }
+
+            encodedName = encodedName.replaceAll("\\+", "%20");
+
+            this.mFolderUrl = WebDavStore.this.mUrl;
+            if (!WebDavStore.this.mUrl.endsWith("/")) {
+                this.mFolderUrl += "/";
+            }
+            this.mFolderUrl += encodedName;
         }
 
         public void setUrl(String url) {
@@ -1978,6 +2038,17 @@ public class WebDavStore extends Store {
         }
 
         /**
+		 * Returns a hashmap of special folder name => special folder url
+		 */
+		public HashMap getSpecialFolderToUrl() {
+			// We return the first (and only) map
+			for (HashMap folderMap : mData.values()) {
+				return folderMap;
+			}
+			return new HashMap();
+		}
+
+		/**
          * Returns a hashmap of Message UID => Message Url
          */
         public HashMap getUidToUrl() {

From d2c56edbd246e79e565a4c0967b4d09dfbfcc8c5 Mon Sep 17 00:00:00 2001
From: bitblaster 
Date: Fri, 8 Apr 2011 04:10:20 -0700
Subject: [PATCH 016/121] Restored original imports, added comments, changed
 method createFolder

---
 src/com/fsck/k9/mail/store/WebDavStore.java | 118 +++++++++++++-------
 1 file changed, 76 insertions(+), 42 deletions(-)

diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
index 297811357..6f626bba9 100644
--- a/src/com/fsck/k9/mail/store/WebDavStore.java
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -1,38 +1,58 @@
 package com.fsck.k9.mail.store;
 
-import java.io.*;
-import java.net.*;
-import java.security.*;
-import java.text.*;
-import java.util.*;
-import java.util.zip.*;
+import android.util.Log;
 
-import javax.net.ssl.*;
-import javax.xml.parsers.*;
-
-import org.apache.http.*;
-import org.apache.http.client.*;
-import org.apache.http.client.entity.*;
-import org.apache.http.client.methods.*;
-import org.apache.http.client.protocol.*;
-import org.apache.http.conn.scheme.*;
-import org.apache.http.entity.*;
-import org.apache.http.impl.client.*;
-import org.apache.http.message.*;
-import org.apache.http.protocol.*;
-import org.xml.sax.*;
-import org.xml.sax.helpers.*;
-
-import android.util.*;
-
-import com.fsck.k9.*;
-import com.fsck.k9.controller.*;
-import com.fsck.k9.helper.*;
+import com.fsck.k9.Account;
+import com.fsck.k9.K9;
+import com.fsck.k9.R;
+import com.fsck.k9.controller.MessageRetrievalListener;
+import com.fsck.k9.helper.Utility;
 import com.fsck.k9.mail.*;
 import com.fsck.k9.mail.Folder.OpenMode;
-import com.fsck.k9.mail.filter.*;
-import com.fsck.k9.mail.internet.*;
-import com.fsck.k9.mail.transport.*;
+import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
+import com.fsck.k9.mail.internet.MimeMessage;
+import com.fsck.k9.mail.transport.TrustedSocketFactory;
+import org.apache.http.*;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+import javax.net.ssl.SSLException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.io.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Stack;
+import java.util.zip.GZIPInputStream;
 
 /**
  * 
@@ -59,13 +79,15 @@ public class WebDavStore extends Store {
 
     private static final Message[] EMPTY_MESSAGE_ARRAY = new Message[0];
 
-    private static final Object DAV_MAIL_INBOX_FOLDER = "inbox";
-    private static final Object DAV_MAIL_DRAFTS_FOLDER = "drafts";
-    private static final String DAV_MAIL_SPAM_FOLDER = "spam";
+    // These are the ids used from Exchange server to identify the special folders
+    // http://social.technet.microsoft.com/Forums/en/exchangesvrdevelopment/thread/1cd2e98c-8a12-44bd-a3e3-9c5ee9e4e14d
+    private static final String DAV_MAIL_INBOX_FOLDER = "inbox";
+    private static final String DAV_MAIL_DRAFTS_FOLDER = "drafts";
+    private static final String DAV_MAIL_SPAM_FOLDER = "junkemail";
     private static final String DAV_MAIL_SEND_FOLDER = "##DavMailSubmissionURI##";
-	private static final Object DAV_MAIL_TRASH_FOLDER = "deleteditems";
-	private static final Object DAV_MAIL_OUTBOX_FOLDER = "outbox";
-	private static final Object DAV_MAIL_SENT_FOLDER = "sentitems";
+	private static final String DAV_MAIL_TRASH_FOLDER = "deleteditems";
+	private static final String DAV_MAIL_OUTBOX_FOLDER = "outbox";
+	private static final String DAV_MAIL_SENT_FOLDER = "sentitems";
 
     private short mConnectionSecurity;
     private String mUsername; /* Stores the username for authentications */
@@ -270,14 +292,23 @@ public class WebDavStore extends Store {
 
         for (int i = 0; i < folderUrls.length; i++) {
             String tempUrl = folderUrls[i];
-            createFolder(tempUrl, folderList);
+            WebDavFolder folder = createFolder(tempUrl);
+            if(folder != null)
+		folderList.add(folder);
         }
 
         return folderList;
     }
 
-    private WebDavFolder createFolder(String folderUrl, LinkedList folderList) {
-	if(folderUrl == null || folderList == null)
+    /**
+     * Creates a folder using the URL passed as parameter (only if it has not been
+     * already created) and adds this to our store folder map.
+     *
+     * @param folderUrl
+     * @return
+     */
+    private WebDavFolder createFolder(String folderUrl) {
+	if(folderUrl == null)
 		return null;
 
 	WebDavFolder wdFolder=null;
@@ -286,7 +317,6 @@ public class WebDavStore extends Store {
 			if(!this.mFolderList.containsKey(folderName)) {
                 wdFolder = new WebDavFolder(this, folderName);
                 wdFolder.setUrl(folderUrl);
-		folderList.add(wdFolder);
 		mFolderList.put(folderName, wdFolder);
 			}
         }
@@ -299,6 +329,9 @@ public class WebDavStore extends Store {
 	if(folderUrl == null)
 		return null;
 
+	// Here we extract the folder name starting from the complete url.
+	// folderUrl is in the form http://mail.domain.com/exchange/username/foldername
+	// so we need "foldername" which is the string after the fifth slash
         int folderSlash=-1;
         for(int j=0; j < 5; j++) {
 		folderSlash=folderUrl.indexOf('/', folderSlash+1);
@@ -310,11 +343,13 @@ public class WebDavStore extends Store {
 		String folderName;
 		String fullPathName;
 
+		// Removes the final slash if present
 		if(folderUrl.charAt(folderUrl.length()-1) == '/')
 			fullPathName = folderUrl.substring(folderSlash+1, folderUrl.length()-1);
 		else
 			fullPathName = folderUrl.substring(folderSlash+1);
 
+		// Decodes the url-encoded folder name (i.e. "My%20folder" => "My Folder"
 			try {
 				folderName = java.net.URLDecoder.decode(fullPathName, "UTF-8");
 			} catch (UnsupportedEncodingException uee) {
@@ -372,8 +407,7 @@ public class WebDavStore extends Store {
 		// This should always be ##DavMailSubmissionURI## for which we already have a constant
 		// buffer.append("");
 
-		//TODO: What is the id of the spam folder???
-		//buffer.append("<").append(DAV_MAIL_SPAM_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+		buffer.append("<").append(DAV_MAIL_SPAM_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
 
 		buffer.append("");
 		buffer.append("");

From d3848d352d7a06322f845a24a912f0b4abf69359 Mon Sep 17 00:00:00 2001
From: Jesse Vincent 
Date: Tue, 12 Apr 2011 22:17:22 +1000
Subject: [PATCH 017/121] astyle

---
 src/com/fsck/k9/Account.java                  |  18 +-
 src/com/fsck/k9/activity/ChooseFolder.java    |   4 +-
 .../k9/activity/setup/AccountSettings.java    |   6 +-
 src/com/fsck/k9/mail/store/WebDavStore.java   | 180 +++++++++---------
 4 files changed, 104 insertions(+), 104 deletions(-)

diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java
index 5aefe10c2..9dd61ba9d 100644
--- a/src/com/fsck/k9/Account.java
+++ b/src/com/fsck/k9/Account.java
@@ -86,7 +86,7 @@ public class Account implements BaseAccount {
     private String mTrashFolderName;
     private String mArchiveFolderName;
     private String mSpamFolderName;
-	private String mOutboxFolderName;
+    private String mOutboxFolderName;
     private String mAutoExpandFolderName;
     private FolderMode mFolderDisplayMode;
     private FolderMode mFolderSyncMode;
@@ -255,7 +255,7 @@ public class Account implements BaseAccount {
         mTrashFolderName = prefs.getString(mUuid  + ".trashFolderName", "Trash");
         mArchiveFolderName = prefs.getString(mUuid  + ".archiveFolderName", "Archive");
         mSpamFolderName = prefs.getString(mUuid  + ".spamFolderName", "Spam");
-		mOutboxFolderName = prefs.getString(mUuid + ".outboxFolderName", "Outbox");
+        mOutboxFolderName = prefs.getString(mUuid + ".outboxFolderName", "Outbox");
         mExpungePolicy = prefs.getString(mUuid  + ".expungePolicy", EXPUNGE_IMMEDIATELY);
         mSyncRemoteDeletions = prefs.getBoolean(mUuid  + ".syncRemoteDeletions", true);
 
@@ -398,7 +398,7 @@ public class Account implements BaseAccount {
         editor.remove(mUuid + ".trashFolderName");
         editor.remove(mUuid + ".archiveFolderName");
         editor.remove(mUuid + ".spamFolderName");
-		editor.remove(mUuid + ".outboxFolderName");
+        editor.remove(mUuid + ".outboxFolderName");
         editor.remove(mUuid + ".autoExpandFolderName");
         editor.remove(mUuid + ".accountNumber");
         editor.remove(mUuid + ".vibrate");
@@ -496,7 +496,7 @@ public class Account implements BaseAccount {
         editor.putString(mUuid + ".trashFolderName", mTrashFolderName);
         editor.putString(mUuid + ".archiveFolderName", mArchiveFolderName);
         editor.putString(mUuid + ".spamFolderName", mSpamFolderName);
-		editor.putString(mUuid + ".outboxFolderName", mOutboxFolderName);
+        editor.putString(mUuid + ".outboxFolderName", mOutboxFolderName);
         editor.putString(mUuid + ".autoExpandFolderName", mAutoExpandFolderName);
         editor.putInt(mUuid + ".accountNumber", mAccountNumber);
         editor.putString(mUuid + ".hideButtonsEnum", mScrollMessageViewButtons.name());
@@ -1316,12 +1316,12 @@ public class Account implements BaseAccount {
     }
 
     public String getInboxFolderName() {
-		return mInboxFolderName;
-	}
+        return mInboxFolderName;
+    }
 
-	public void setInboxFolderName(String mInboxFolderName) {
-		this.mInboxFolderName = mInboxFolderName;
-	}
+    public void setInboxFolderName(String mInboxFolderName) {
+        this.mInboxFolderName = mInboxFolderName;
+    }
 
     public synchronized boolean syncRemoteDeletions() {
         return mSyncRemoteDeletions;
diff --git a/src/com/fsck/k9/activity/ChooseFolder.java b/src/com/fsck/k9/activity/ChooseFolder.java
index 5d0ff100f..32e7fba22 100644
--- a/src/com/fsck/k9/activity/ChooseFolder.java
+++ b/src/com/fsck/k9/activity/ChooseFolder.java
@@ -249,7 +249,7 @@ public class ChooseFolder extends K9ListActivity {
 
                 // Inbox needs to be compared case-insensitively
                 if (hideCurrentFolder && (name.equals(mFolder) ||
-			(mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name)))) {
+                (mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name)))) {
                     continue;
                 }
                 try {
@@ -316,7 +316,7 @@ public class ChooseFolder extends K9ListActivity {
                             selectedFolder = position;
                         }
                     } else if (name.equals(mFolder) ||
-                        (mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name))) {
+                    (mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name))) {
                         selectedFolder = position;
                     }
                     position++;
diff --git a/src/com/fsck/k9/activity/setup/AccountSettings.java b/src/com/fsck/k9/activity/setup/AccountSettings.java
index c54f82cc4..2944ace9b 100644
--- a/src/com/fsck/k9/activity/setup/AccountSettings.java
+++ b/src/com/fsck/k9/activity/setup/AccountSettings.java
@@ -702,10 +702,10 @@ public class AccountSettings extends K9PreferenceActivity {
 
         // In webdav account we use the exact folder name also for inbox,
         // since it varies because of internationalization
-        if(mAccount.getStoreUri().startsWith("webdav"))
-		mAccount.setAutoExpandFolderName(mAutoExpandFolder.getValue());
+        if (mAccount.getStoreUri().startsWith("webdav"))
+            mAccount.setAutoExpandFolderName(mAutoExpandFolder.getValue());
         else
-		mAccount.setAutoExpandFolderName(reverseTranslateFolder(mAutoExpandFolder.getValue()));
+            mAccount.setAutoExpandFolderName(reverseTranslateFolder(mAutoExpandFolder.getValue()));
 
         mAccount.setArchiveFolderName(mArchiveFolder.getValue());
         mAccount.setDraftsFolderName(mDraftsFolder.getValue());
diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
index 6f626bba9..ef3b837f6 100644
--- a/src/com/fsck/k9/mail/store/WebDavStore.java
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -85,9 +85,9 @@ public class WebDavStore extends Store {
     private static final String DAV_MAIL_DRAFTS_FOLDER = "drafts";
     private static final String DAV_MAIL_SPAM_FOLDER = "junkemail";
     private static final String DAV_MAIL_SEND_FOLDER = "##DavMailSubmissionURI##";
-	private static final String DAV_MAIL_TRASH_FOLDER = "deleteditems";
-	private static final String DAV_MAIL_OUTBOX_FOLDER = "outbox";
-	private static final String DAV_MAIL_SENT_FOLDER = "sentitems";
+    private static final String DAV_MAIL_TRASH_FOLDER = "deleteditems";
+    private static final String DAV_MAIL_OUTBOX_FOLDER = "outbox";
+    private static final String DAV_MAIL_SENT_FOLDER = "sentitems";
 
     private short mConnectionSecurity;
     private String mUsername; /* Stores the username for authentications */
@@ -256,30 +256,30 @@ public class WebDavStore extends Store {
 
         HashMap specialFoldersMap = dataset.getSpecialFolderToUrl();
         String folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_INBOX_FOLDER));
-        if(folderName != null) {
-		mAccount.setAutoExpandFolderName(folderName);
-		mAccount.setInboxFolderName(folderName);
+        if (folderName != null) {
+            mAccount.setAutoExpandFolderName(folderName);
+            mAccount.setInboxFolderName(folderName);
         }
 
         folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_DRAFTS_FOLDER));
-        if(folderName != null)
-		mAccount.setDraftsFolderName(folderName);
+        if (folderName != null)
+            mAccount.setDraftsFolderName(folderName);
 
         folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_TRASH_FOLDER));
-        if(folderName != null)
-		mAccount.setTrashFolderName(folderName);
+        if (folderName != null)
+            mAccount.setTrashFolderName(folderName);
 
         folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SPAM_FOLDER));
-        if(folderName != null)
-		mAccount.setSpamFolderName(folderName);
+        if (folderName != null)
+            mAccount.setSpamFolderName(folderName);
 
         folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_OUTBOX_FOLDER));
-        if(folderName != null)
-		mAccount.setOutboxFolderName(folderName);
+        if (folderName != null)
+            mAccount.setOutboxFolderName(folderName);
 
         folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SENT_FOLDER));
-        if(folderName != null)
-		mAccount.setSentFolderName(folderName);
+        if (folderName != null)
+            mAccount.setSentFolderName(folderName);
 
         /**
          * Next we get all the folders (including "special" ones)
@@ -293,8 +293,8 @@ public class WebDavStore extends Store {
         for (int i = 0; i < folderUrls.length; i++) {
             String tempUrl = folderUrls[i];
             WebDavFolder folder = createFolder(tempUrl);
-            if(folder != null)
-		folderList.add(folder);
+            if (folder != null)
+                folderList.add(folder);
         }
 
         return folderList;
@@ -308,60 +308,60 @@ public class WebDavStore extends Store {
      * @return
      */
     private WebDavFolder createFolder(String folderUrl) {
-	if(folderUrl == null)
-		return null;
+        if (folderUrl == null)
+            return null;
 
-	WebDavFolder wdFolder=null;
-	String folderName = getFolderName(folderUrl);
-	if(folderName != null) {
-			if(!this.mFolderList.containsKey(folderName)) {
+        WebDavFolder wdFolder = null;
+        String folderName = getFolderName(folderUrl);
+        if (folderName != null) {
+            if (!this.mFolderList.containsKey(folderName)) {
                 wdFolder = new WebDavFolder(this, folderName);
                 wdFolder.setUrl(folderUrl);
-		mFolderList.put(folderName, wdFolder);
-			}
+                mFolderList.put(folderName, wdFolder);
+            }
         }
-	// else: Unknown URL format => NO Folder created
+        // else: Unknown URL format => NO Folder created
 
-	return wdFolder;
-	}
+        return wdFolder;
+    }
 
     private String getFolderName(String folderUrl) {
-	if(folderUrl == null)
-		return null;
+        if (folderUrl == null)
+            return null;
 
-	// Here we extract the folder name starting from the complete url.
-	// folderUrl is in the form http://mail.domain.com/exchange/username/foldername
-	// so we need "foldername" which is the string after the fifth slash
-        int folderSlash=-1;
-        for(int j=0; j < 5; j++) {
-		folderSlash=folderUrl.indexOf('/', folderSlash+1);
-		if(folderSlash < 0)
-			break;
+        // Here we extract the folder name starting from the complete url.
+        // folderUrl is in the form http://mail.domain.com/exchange/username/foldername
+        // so we need "foldername" which is the string after the fifth slash
+        int folderSlash = -1;
+        for (int j = 0; j < 5; j++) {
+            folderSlash = folderUrl.indexOf('/', folderSlash + 1);
+            if (folderSlash < 0)
+                break;
         }
 
-        if(folderSlash > 0) {
-		String folderName;
-		String fullPathName;
+        if (folderSlash > 0) {
+            String folderName;
+            String fullPathName;
 
-		// Removes the final slash if present
-		if(folderUrl.charAt(folderUrl.length()-1) == '/')
-			fullPathName = folderUrl.substring(folderSlash+1, folderUrl.length()-1);
-		else
-			fullPathName = folderUrl.substring(folderSlash+1);
+            // Removes the final slash if present
+            if (folderUrl.charAt(folderUrl.length() - 1) == '/')
+                fullPathName = folderUrl.substring(folderSlash + 1, folderUrl.length() - 1);
+            else
+                fullPathName = folderUrl.substring(folderSlash + 1);
 
-		// Decodes the url-encoded folder name (i.e. "My%20folder" => "My Folder"
-			try {
-				folderName = java.net.URLDecoder.decode(fullPathName, "UTF-8");
-			} catch (UnsupportedEncodingException uee) {
-				/**
-				 * If we don't support UTF-8 there's a problem, don't decode
-				 * it then
-				 */
-				folderName = fullPathName;
-			}
+            // Decodes the url-encoded folder name (i.e. "My%20folder" => "My Folder"
+            try {
+                folderName = java.net.URLDecoder.decode(fullPathName, "UTF-8");
+            } catch (UnsupportedEncodingException uee) {
+                /**
+                 * If we don't support UTF-8 there's a problem, don't decode
+                 * it then
+                 */
+                folderName = fullPathName;
+            }
 
-			return folderName;
-		}
+            return folderName;
+        }
 
         return null;
     }
@@ -378,10 +378,10 @@ public class WebDavStore extends Store {
     }
 
     public Folder getSendSpoolFolder() throws MessagingException {
-		if (mSendFolder == null)
-			mSendFolder = getFolder(DAV_MAIL_SEND_FOLDER);
+        if (mSendFolder == null)
+            mSendFolder = getFolder(DAV_MAIL_SEND_FOLDER);
 
-		return mSendFolder;
+        return mSendFolder;
     }
 
     @Override
@@ -394,25 +394,25 @@ public class WebDavStore extends Store {
         return true;
     }
 
-	private String getSpecialFoldersList() {
-		StringBuffer buffer = new StringBuffer(200);
-		buffer.append("");
-		buffer.append("");
-		buffer.append("");
-		buffer.append("<").append(DAV_MAIL_INBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
-		buffer.append("<").append(DAV_MAIL_DRAFTS_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
-		buffer.append("<").append(DAV_MAIL_OUTBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
-		buffer.append("<").append(DAV_MAIL_SENT_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
-		buffer.append("<").append(DAV_MAIL_TRASH_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
-		// This should always be ##DavMailSubmissionURI## for which we already have a constant
-		// buffer.append("");
+    private String getSpecialFoldersList() {
+        StringBuffer buffer = new StringBuffer(200);
+        buffer.append("");
+        buffer.append("");
+        buffer.append("");
+        buffer.append("<").append(DAV_MAIL_INBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+        buffer.append("<").append(DAV_MAIL_DRAFTS_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+        buffer.append("<").append(DAV_MAIL_OUTBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+        buffer.append("<").append(DAV_MAIL_SENT_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+        buffer.append("<").append(DAV_MAIL_TRASH_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+        // This should always be ##DavMailSubmissionURI## for which we already have a constant
+        // buffer.append("");
 
-		buffer.append("<").append(DAV_MAIL_SPAM_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
+        buffer.append("<").append(DAV_MAIL_SPAM_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
 
-		buffer.append("");
-		buffer.append("");
-		return buffer.toString();
-	}
+        buffer.append("");
+        buffer.append("");
+        return buffer.toString();
+    }
 
     /***************************************************************
      * WebDAV XML Request body retrieval functions
@@ -1081,7 +1081,7 @@ public class WebDavStore extends Store {
 
     @Override
     public void sendMessages(Message[] messages) throws MessagingException {
-		WebDavFolder tmpFolder = (WebDavStore.WebDavFolder) getFolder(mAccount.getDraftsFolderName());
+        WebDavFolder tmpFolder = (WebDavStore.WebDavFolder) getFolder(mAccount.getDraftsFolderName());
         try {
             tmpFolder.open(OpenMode.READ_WRITE);
             Message[] retMessages = tmpFolder.appendWebDavMessages(messages);
@@ -2072,17 +2072,17 @@ public class WebDavStore extends Store {
         }
 
         /**
-		 * Returns a hashmap of special folder name => special folder url
-		 */
-		public HashMap getSpecialFolderToUrl() {
-			// We return the first (and only) map
-			for (HashMap folderMap : mData.values()) {
-				return folderMap;
-			}
-			return new HashMap();
-		}
+         * Returns a hashmap of special folder name => special folder url
+         */
+        public HashMap getSpecialFolderToUrl() {
+            // We return the first (and only) map
+            for (HashMap folderMap : mData.values()) {
+                return folderMap;
+            }
+            return new HashMap();
+        }
 
-		/**
+        /**
          * Returns a hashmap of Message UID => Message Url
          */
         public HashMap getUidToUrl() {

From d68d3c1ea3ec9c4a61e7eaca31baddc683943e46 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Wed, 13 Apr 2011 02:27:37 +0900
Subject: [PATCH 018/121] Renamed package name corresponding to the directory

---
 tests/src/com/fsck/k9/activity/AccountsTest.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/src/com/fsck/k9/activity/AccountsTest.java b/tests/src/com/fsck/k9/activity/AccountsTest.java
index 54a5d3670..81ef1c5f8 100644
--- a/tests/src/com/fsck/k9/activity/AccountsTest.java
+++ b/tests/src/com/fsck/k9/activity/AccountsTest.java
@@ -1,4 +1,4 @@
-package com.fsck.k9;
+package com.fsck.k9.activity;
 
 import android.test.ActivityInstrumentationTestCase2;
 import com.fsck.k9.activity.Accounts;

From 9bdfb0d023c8916588a67648564c4a6e94b60409 Mon Sep 17 00:00:00 2001
From: mwolschon 
Date: Wed, 13 Apr 2011 12:18:07 +0200
Subject: [PATCH 019/121] BUGFIX: time changes are still honored even if the
 user choose the [abort] button of the DialogPreference.

---
 .../k9/preferences/TimePickerPreference.java  | 35 +++++++++++++++----
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/com/fsck/k9/preferences/TimePickerPreference.java b/src/com/fsck/k9/preferences/TimePickerPreference.java
index b8824bac1..b8944bd6c 100644
--- a/src/com/fsck/k9/preferences/TimePickerPreference.java
+++ b/src/com/fsck/k9/preferences/TimePickerPreference.java
@@ -25,7 +25,18 @@ public class TimePickerPreference extends DialogPreference implements
      * The default value for this preference
      */
     private String defaultValue;
-
+    /**
+     * Store the original value, in case the user
+     * chooses to abort the {@link DialogPreference}
+     * after making a change.
+     */
+    private int originalHour = 0;
+    /**
+     * Store the original value, in case the user
+     * chooses to abort the {@link DialogPreference}
+     * after making a change.
+     */
+    private int originalMinute = 0;
     /**
      * @param context
      * @param attrs
@@ -64,11 +75,12 @@ public class TimePickerPreference extends DialogPreference implements
         TimePicker tp = new TimePicker(getContext());
         tp.setOnTimeChangedListener(this);
 
-        int h = getHour();
-        int m = getMinute();
-        if (h >= 0 && m >= 0) {
-            tp.setCurrentHour(h);
-            tp.setCurrentMinute(m);
+        originalHour = getHour();
+        originalMinute = getMinute();
+        if (originalHour >= 0 && originalMinute >= 0)
+        {
+            tp.setCurrentHour(originalHour);
+            tp.setCurrentMinute(originalMinute);
         }
 
         return tp;
@@ -88,6 +100,17 @@ public class TimePickerPreference extends DialogPreference implements
         callChangeListener(String.format("%02d:%02d", hour, minute));
     }
 
+    @Override
+	protected void onDialogClosed(boolean positiveResult) {
+    	// Bug #1185 "[SE-QS] GMX: Nach Abbruch der Einstellungen der Ruhezeiten werden diese trotzdem uebernommen"
+
+		if (!positiveResult) {
+			persistString(String.format("%02d:%02d", originalHour, originalMinute));
+	        callChangeListener(String.format("%02d:%02d", originalHour, originalMinute));
+		}
+		super.onDialogClosed(positiveResult);
+	}
+
     /*
      * (non-Javadoc)
      *

From 3b4fcbe6028dc33695ac4c105086b1271b7764cf Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Wed, 13 Apr 2011 23:30:21 +0900
Subject: [PATCH 020/121] Updated Japanese translation. catch up with 4aec4b0.

---
 res/values-ja/strings.xml | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 645c50736..7336ce75e 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -259,14 +259,14 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     本文
     -------- 元メール --------
     件名:
-    
+    送信日:
     送信者:
     宛先:
     CC:
     %s wrote:\n\n
     テキスト引用
     少なくとも1つの受信者を追加する必要があります
-    
+    メールアドレスが登録されていません
     一部の添付ファイルをダウンロードしていません.このメールが送信される前に自動的にダウンロードされます.
     ダウンロードしていないため、一部の添付ファイルを転送することはできません.
 
@@ -342,7 +342,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     アーカイブ
     削除(メッセージ表示画面のみ)
     迷惑メール
-    
+    すべて既読にする
     送信
 
     スクリーンロック時の通知
@@ -910,13 +910,13 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     起動後に統合フォルダを表示する
 
     アカウントのサイズ表示
-    表示を早くしたい場合はチェックをはずしてください
+    表示を速くしたい場合はチェックをはずしてください
 
     検索結果の件数表示
-    表示を早くしたい場合はチェックをはずしてください
+    表示を速くしたい場合はチェックをはずしてください
 
-    
-    
+    特殊なアカウントを隠す
+    統合フォルダと全メッセージを隠す
 
     %s %s
      - スター
@@ -1018,12 +1018,12 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     削除する
     削除しない
 
-    
-    
-    
-    
+    迷惑メールフォルダへの移動の確認
+    本当にこのメッセージを迷惑メールフォルダに移動しますか?
+    はい
+    いいえ
 
-    
+    添付ファイルをダウンロードしています
 
     Android のログにデバッグ用のログを出力するように設定しました。
 
@@ -1031,6 +1031,6 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     \u203a
     接続できません
 
-    
+    アカウント \"%s\" は利用できません。ストレージを確認してください。
 
 

From 7f5c18bd2b1505b4556def7f8ad2bfe963dd4ffb Mon Sep 17 00:00:00 2001
From: mwolschon 
Date: Thu, 14 Apr 2011 10:07:33 +0200
Subject: [PATCH 021/121] updated comments

---
 .../k9/preferences/TimePickerPreference.java  | 37 +++++++++++--------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/src/com/fsck/k9/preferences/TimePickerPreference.java b/src/com/fsck/k9/preferences/TimePickerPreference.java
index b8944bd6c..16685efe9 100644
--- a/src/com/fsck/k9/preferences/TimePickerPreference.java
+++ b/src/com/fsck/k9/preferences/TimePickerPreference.java
@@ -41,7 +41,7 @@ public class TimePickerPreference extends DialogPreference implements
      * @param context
      * @param attrs
      */
-    public TimePickerPreference(Context context, AttributeSet attrs) {
+    public TimePickerPreference(final Context context, final AttributeSet attrs) {
         super(context, attrs);
         initialize();
     }
@@ -51,8 +51,8 @@ public class TimePickerPreference extends DialogPreference implements
      * @param attrs
      * @param defStyle
      */
-    public TimePickerPreference(Context context, AttributeSet attrs,
-                                int defStyle) {
+    public TimePickerPreference(final Context context, final AttributeSet attrs,
+    		final int defStyle) {
         super(context, attrs, defStyle);
         initialize();
     }
@@ -86,23 +86,24 @@ public class TimePickerPreference extends DialogPreference implements
         return tp;
     }
 
-    /*
-     * (non-Javadoc)
-     *
+    /**
      * @see
      * android.widget.TimePicker.OnTimeChangedListener#onTimeChanged(android
      * .widget.TimePicker, int, int)
      */
     @Override
-    public void onTimeChanged(TimePicker view, int hour, int minute) {
+    public void onTimeChanged(final TimePicker view, final int hour, final int minute) {
 
         persistString(String.format("%02d:%02d", hour, minute));
         callChangeListener(String.format("%02d:%02d", hour, minute));
     }
 
+    /**
+     * If not a positive result, restore the original value
+     * before going to super.onDialogClosed(positiveResult).
+     */
     @Override
 	protected void onDialogClosed(boolean positiveResult) {
-    	// Bug #1185 "[SE-QS] GMX: Nach Abbruch der Einstellungen der Ruhezeiten werden diese trotzdem uebernommen"
 
 		if (!positiveResult) {
 			persistString(String.format("%02d:%02d", originalHour, originalMinute));
@@ -111,13 +112,11 @@ public class TimePickerPreference extends DialogPreference implements
 		super.onDialogClosed(positiveResult);
 	}
 
-    /*
-     * (non-Javadoc)
-     *
+    /**
      * @see android.preference.Preference#setDefaultValue(java.lang.Object)
      */
     @Override
-    public void setDefaultValue(Object defaultValue) {
+    public void setDefaultValue(final Object defaultValue) {
         // BUG this method is never called if you use the 'android:defaultValue' attribute in your XML preference file, not sure why it isn't
 
         super.setDefaultValue(defaultValue);
@@ -136,10 +135,10 @@ public class TimePickerPreference extends DialogPreference implements
     /**
      * Get the hour value (in 24 hour time)
      *
-     * @return The hour value, will be 0 to 23 (inclusive)
+     * @return The hour value, will be 0 to 23 (inclusive) or -1 if illegal
      */
     private int getHour() {
-        String time = getPersistedString(this.defaultValue);
+        String time = getTime();
         if (time == null || !time.matches(VALIDATION_EXPRESSION)) {
             return -1;
         }
@@ -150,10 +149,10 @@ public class TimePickerPreference extends DialogPreference implements
     /**
      * Get the minute value
      *
-     * @return the minute value, will be 0 to 59 (inclusive)
+     * @return the minute value, will be 0 to 59 (inclusive) or -1 if illegal
      */
     private int getMinute() {
-        String time = getPersistedString(this.defaultValue);
+        String time = getTime();
         if (time == null || !time.matches(VALIDATION_EXPRESSION)) {
             return -1;
         }
@@ -161,6 +160,12 @@ public class TimePickerPreference extends DialogPreference implements
         return Integer.valueOf(time.split(":")[1]);
     }
 
+    /**
+     * Get the time. It is only legal, if it matches
+     * {@link #VALIDATION_EXPRESSION}.
+     *
+     * @return the time as hh:mm
+     */
     public String getTime() {
         return getPersistedString(this.defaultValue);
     }

From 659a5d36b2d02f6aea61eaee29da236343adc3b1 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Sat, 16 Apr 2011 18:13:54 +0900
Subject: [PATCH 022/121] Fixed issue 2991: Should display colorized name in
 the message list.

---
 src/com/fsck/k9/activity/MessageList.java | 26 ++++++++++++-----------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java
index 915e9ef00..e48b7cf00 100644
--- a/src/com/fsck/k9/activity/MessageList.java
+++ b/src/com/fsck/k9/activity/MessageList.java
@@ -12,13 +12,13 @@ import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.Intent;
-import android.content.res.ColorStateList;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
-import android.text.style.TextAppearanceSpan;
+import android.text.style.AbsoluteSizeSpan;
+import android.text.style.StyleSpan;
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.animation.Animation;
@@ -2159,13 +2159,14 @@ public class MessageList
                     holder.preview.setText(noSender, TextView.BufferType.SPANNABLE);
                     Spannable str = (Spannable) holder.preview.getText();
 
-                    ColorStateList color = holder.subject.getTextColors();
-                    ColorStateList linkColor = holder.subject.getLinkTextColors();
-                    str.setSpan(new TextAppearanceSpan(null, Typeface.NORMAL, mFontSizes.getMessageListSender(), color, linkColor),
+                    str.setSpan(new StyleSpan(Typeface.NORMAL),
                                 0,
                                 noSender.length(),
-                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
-                               );
+                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+                    str.setSpan(new AbsoluteSizeSpan(mFontSizes.getMessageListSender(), true),
+                                0,
+                                noSender.length(),
+                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                 } else {
                     holder.from.setText(noSender);
                     holder.from.setTypeface(null, Typeface.NORMAL);
@@ -2247,13 +2248,14 @@ public class MessageList
                 Spannable str = (Spannable)holder.preview.getText();
 
                 // Create a span section for the sender, and assign the correct font size and weight.
-                ColorStateList color = holder.subject.getTextColors();
-                ColorStateList linkColor = holder.subject.getLinkTextColors();
-                str.setSpan(new TextAppearanceSpan(null, senderTypeface, mFontSizes.getMessageListSender(), color, linkColor),
+                str.setSpan(new StyleSpan(senderTypeface),
                             0,
                             message.sender.length() + 1,
-                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
-                           );
+                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+                str.setSpan(new AbsoluteSizeSpan(mFontSizes.getMessageListSender(), true),
+                            0,
+                            message.sender.length() + 1,
+                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
             } else {
                 holder.from.setText(new SpannableStringBuilder(recipientSigil(message)).append(message.sender));
 

From 724b6eaaa5595bede25ddce80cc48659b1ce7a82 Mon Sep 17 00:00:00 2001
From: Jesse Vincent 
Date: Sun, 17 Apr 2011 21:07:13 +1000
Subject: [PATCH 023/121] For a while, it was possible for users to conifgure
 their outbox and drafts folders to be the same folder. This could result in
 drafts being sent over and over.  This change uses the K-9 Identity header as
 a shibboleth for drafts, as it's not actually set when a message is sent.

---
 src/com/fsck/k9/controller/MessagingController.java | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index de04e2d1c..f37b89318 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -3025,6 +3025,16 @@ public class MessagingController implements Runnable {
 
                     localFolder.fetch(new Message[] { message }, fp, null);
                     try {
+
+
+                        if (message.getHeader(K9.IDENTITY_HEADER) != null) {
+                            Log.v(K9.LOG_TAG, "The user has set the Outbox and Drafts folder to the same thing. " +
+                                  "This message appears to be a draft, so K-9 will not send it");
+                            continue;
+
+                        }
+
+
                         message.setFlag(Flag.X_SEND_IN_PROGRESS, true);
                         if (K9.DEBUG)
                             Log.i(K9.LOG_TAG, "Sending message with UID " + message.getUid());

From 59399506dfdddb01996a07165218634c00e12993 Mon Sep 17 00:00:00 2001
From: Marcus Wolschon 
Date: Tue, 19 Apr 2011 09:01:01 +0200
Subject: [PATCH 024/121] fixed very rare NullPointerException

---
 src/com/fsck/k9/provider/AttachmentProvider.java | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/com/fsck/k9/provider/AttachmentProvider.java b/src/com/fsck/k9/provider/AttachmentProvider.java
index 126223d72..8b234113b 100644
--- a/src/com/fsck/k9/provider/AttachmentProvider.java
+++ b/src/com/fsck/k9/provider/AttachmentProvider.java
@@ -72,7 +72,14 @@ public class AttachmentProvider extends ContentProvider {
          * We use the cache dir as a temporary directory (since Android doesn't give us one) so
          * on startup we'll clean up any .tmp files from the last run.
          */
-        File[] files = getContext().getCacheDir().listFiles();
+        final File cacheDir = getContext().getCacheDir();
+        if (cacheDir == null) {
+        	return true;
+        }
+		File[] files = cacheDir.listFiles();
+		if (files == null) {
+			return true;
+		}
         for (File file : files) {
             if (file.getName().endsWith(".tmp")) {
                 file.delete();

From 6f4bef3530e615361a9edee50f692b1efa6b63d9 Mon Sep 17 00:00:00 2001
From: Marcus Wolschon 
Date: Tue, 19 Apr 2011 10:46:17 +0200
Subject: [PATCH 025/121]  Issue 3259:  	 Show SubjectAltNames in
 acceptKeyDialog

---
 .../setup/AccountSetupCheckSettings.java      | 74 +++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
index bfc8e3520..4e21619d9 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
@@ -5,6 +5,7 @@ import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Process;
@@ -27,9 +28,12 @@ import com.fsck.k9.mail.filter.Hex;
 
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
 import java.security.cert.X509Certificate;
 import java.security.NoSuchAlgorithmException;
 import java.security.MessageDigest;
+import java.util.Collection;
+import java.util.List;
 
 /**
  * Checks the given settings to make sure that they can be used to send and
@@ -249,8 +253,78 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
                 }
                 for (int i = 0; i < chain.length; i++) {
                     // display certificate chain information
+                	//TODO: localize this strings
                     chainInfo.append("Certificate chain[" + i + "]:\n");
                     chainInfo.append("Subject: " + chain[i].getSubjectDN().toString() + "\n");
+
+                    // display SubjectAltNames too
+                    // (the user may be mislead into mistrusting a certificate
+                    //  by a subjectDN not matching the server even though a
+                    //  SubjectAltName matches)
+                    try {
+						final Collection> subjectAlternativeNames = chain[i].getSubjectAlternativeNames();
+						if (subjectAlternativeNames != null) {
+							// The list of SubjectAltNames may be very long
+		                	//TODO: localize this string
+							StringBuffer altNamesText = new StringBuffer("Subject has " + subjectAlternativeNames.size() + " alternative names\n");
+
+							// we need these for matching
+							String storeURIHost = (Uri.parse(mAccount.getStoreUri())).getHost();
+							String transportURIHost = (Uri.parse(mAccount.getTransportUri())).getHost();
+
+							for (List subjectAlternativeName : subjectAlternativeNames) {
+								Integer type = (Integer)subjectAlternativeName.get(0);
+							    Object value = subjectAlternativeName.get(1);
+							    String name = "";
+							    switch (type.intValue()) {
+							      case 0:
+							    	  Log.w(K9.LOG_TAG, "SubjectAltName of type OtherName not supported.");
+							    	  continue;
+							      case 1: // RFC822Name 
+							    	  name = (String)value;
+							        break;
+							      case 2:  // DNSName 
+							    	  name = (String)value;
+							        break;
+							      case 3:
+							    	  Log.w(K9.LOG_TAG, "unsupported SubjectAltName of type x400Address");
+							    	  continue;
+							      case 4:
+							    	  Log.w(K9.LOG_TAG, "unsupported SubjectAltName of type directoryName");
+							    	  continue;
+							      case 5:
+							    	  Log.w(K9.LOG_TAG, "unsupported SubjectAltName of type ediPartyName");
+							    	  continue;
+							      case 6:  // Uri
+							    	  name = (String)value;
+							        break;
+							      case 7: // ip-address
+							    	  name = (String)value;
+							        break;
+							      default:
+							    	  Log.w(K9.LOG_TAG, "unsupported SubjectAltName of unknown type");
+							    	  continue;
+							   }
+
+							    // if some of the SubjectAltNames match the store or transport -host,
+							    // display them
+							    if (name.equalsIgnoreCase(storeURIHost) || name.equalsIgnoreCase(transportURIHost)) {
+				                	//TODO: localize this string
+        	                        altNamesText.append("Subject(alt): " + name + ",...\n");
+							    } else if (name.startsWith("*.")) {
+							    	if (storeURIHost.endsWith(name.substring(2)) || transportURIHost.endsWith(name.substring(2))) {
+					                	//TODO: localize this string
+							    		altNamesText.append("Subject(alt): " + name + ",...\n");
+							    	}
+							    }
+							}
+							chainInfo.append(altNamesText);
+						}
+					} catch (Exception e1) {
+						// don't fail just because of subjectAltNames
+						Log.w(K9.LOG_TAG, "cannot display SubjectAltNames in dialog", e1);
+					}
+
                     chainInfo.append("Issuer: " + chain[i].getIssuerDN().toString() + "\n");
                     if (sha1 != null) {
                         sha1.reset();

From 120a39d5d6b5603169e6622103be9fa8294512c8 Mon Sep 17 00:00:00 2001
From: Bernhard Redl 
Date: Wed, 20 Apr 2011 10:01:23 +0800
Subject: [PATCH 026/121] * Fix Bug
 https://code.google.com/p/k9mail/issues/detail?id=3224   12/24 timesetting is
 no based on the android system settings

---
 src/com/fsck/k9/preferences/TimePickerPreference.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/com/fsck/k9/preferences/TimePickerPreference.java b/src/com/fsck/k9/preferences/TimePickerPreference.java
index 16685efe9..cc021f8d8 100644
--- a/src/com/fsck/k9/preferences/TimePickerPreference.java
+++ b/src/com/fsck/k9/preferences/TimePickerPreference.java
@@ -6,6 +6,7 @@ package com.fsck.k9.preferences;
 
 import android.content.Context;
 import android.preference.DialogPreference;
+import android.text.format.DateFormat;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.TimePicker;
@@ -73,8 +74,8 @@ public class TimePickerPreference extends DialogPreference implements
     protected View onCreateDialogView() {
 
         TimePicker tp = new TimePicker(getContext());
+        tp.setIs24HourView(DateFormat.is24HourFormat(getContext()));
         tp.setOnTimeChangedListener(this);
-
         originalHour = getHour();
         originalMinute = getMinute();
         if (originalHour >= 0 && originalMinute >= 0)

From 415c11d7123c8681e5fb38d837b036de173e2d47 Mon Sep 17 00:00:00 2001
From: Bernhard Redl 
Date: Wed, 20 Apr 2011 14:55:55 +0200
Subject: [PATCH 027/121] "When calculating the number of unread messages shown
 in the account list, INBOX now is always counted, even if a "special" folder
 has been set to INBOX (issue 3074)

---
 src/com/fsck/k9/mail/store/LocalStore.java | 66 +++++++---------------
 1 file changed, 21 insertions(+), 45 deletions(-)

diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index 4c010924b..a484b3855 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -507,57 +507,33 @@ public class LocalStore extends Store implements Serializable {
                 Cursor cursor = null;
                 try {
                     String baseQuery = "SELECT SUM(unread_count), SUM(flagged_count) FROM folders WHERE ( name != ? AND name != ? AND name != ? AND name != ? AND name != ? ) ";
+                    List queryParam = new ArrayList();
+                    queryParam.add((mAccount.getTrashFolderName() != null && !mAccount.getTrashFolderName().equals(mAccount.getInboxFolderName())) ? mAccount.getTrashFolderName() : "");
+                    queryParam.add((mAccount.getDraftsFolderName() != null && !mAccount.getTrashFolderName().equals(mAccount.getInboxFolderName())) ? mAccount.getDraftsFolderName() : "");
+                    queryParam.add((mAccount.getSpamFolderName() != null && !mAccount.getSpamFolderName().equals(mAccount.getInboxFolderName())) ? mAccount.getSpamFolderName() : "");
+                    queryParam.add((mAccount.getOutboxFolderName() != null && !mAccount.getOutboxFolderName().equals(mAccount.getInboxFolderName())) ?  mAccount.getOutboxFolderName() : "");
+                    queryParam.add((mAccount.getSentFolderName() != null && !mAccount.getSentFolderName().equals(mAccount.getInboxFolderName())) ? mAccount.getSentFolderName() : "");
+
                     if (displayMode == Account.FolderMode.NONE) {
-                        cursor = db.rawQuery(baseQuery + "AND (name = ? )", new String[] {
-
-                                                 mAccount.getTrashFolderName() != null ? mAccount.getTrashFolderName() : "" ,
-                                                 mAccount.getDraftsFolderName() != null ? mAccount.getDraftsFolderName() : "",
-                                                 mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "",
-                                                 mAccount.getOutboxFolderName() != null ?  mAccount.getOutboxFolderName() : "",
-                                                 mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "",
-                                                 mAccount.getInboxFolderName()
-                                             }
-
-                                            );
+                        queryParam.add(mAccount.getInboxFolderName());
+                        cursor = db.rawQuery(baseQuery + "AND (name = ? )", queryParam.toArray(new String[queryParam.size()]));
                     } else if (displayMode == Account.FolderMode.FIRST_CLASS) {
-                        cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class = ?)", new String[] {
-                                                 mAccount.getTrashFolderName() != null ? mAccount.getTrashFolderName() : "" ,
-                                                 mAccount.getDraftsFolderName() != null ? mAccount.getDraftsFolderName() : "",
-                                                 mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "",
-                                                 mAccount.getOutboxFolderName() != null ?  mAccount.getOutboxFolderName() : "",
-                                                 mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "",
-                                                 mAccount.getInboxFolderName(), Folder.FolderClass.FIRST_CLASS.name()
-                                             });
-
+                        queryParam.add(mAccount.getInboxFolderName());
+                        queryParam.add(Folder.FolderClass.FIRST_CLASS.name());
+                        cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class = ?)", queryParam.toArray(new String[queryParam.size()]));
 
                     } else if (displayMode == Account.FolderMode.FIRST_AND_SECOND_CLASS) {
-                        cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class = ? OR display_class = ? )", new String[] {
-                                                 mAccount.getTrashFolderName() != null ? mAccount.getTrashFolderName() : "" ,
-                                                 mAccount.getDraftsFolderName() != null ? mAccount.getDraftsFolderName() : "",
-                                                 mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "",
-                                                 mAccount.getOutboxFolderName() != null ?  mAccount.getOutboxFolderName() : "",
-                                                 mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "",
-                                                 mAccount.getInboxFolderName(), Folder.FolderClass.FIRST_CLASS.name(), Folder.FolderClass.SECOND_CLASS.name()
-                                             });
+                        queryParam.add(mAccount.getInboxFolderName());
+                        queryParam.add(Folder.FolderClass.FIRST_CLASS.name());
+                        queryParam.add(Folder.FolderClass.SECOND_CLASS.name());
+                        cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class = ? OR display_class = ? )", queryParam.toArray(new String[queryParam.size()]));
+
                     } else if (displayMode == Account.FolderMode.NOT_SECOND_CLASS) {
-                        cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class != ?)", new String[] {
-
-                                                 mAccount.getTrashFolderName() != null ? mAccount.getTrashFolderName() : "" ,
-                                                 mAccount.getDraftsFolderName() != null ? mAccount.getDraftsFolderName() : "",
-                                                 mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "",
-                                                 mAccount.getOutboxFolderName() != null ?  mAccount.getOutboxFolderName() : "",
-                                                 mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "",
-                                                 mAccount.getInboxFolderName(), Folder.FolderClass.SECOND_CLASS.name()
-                                             });
+                        queryParam.add(mAccount.getInboxFolderName());
+                        queryParam.add(Folder.FolderClass.SECOND_CLASS.name());
+                        cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class != ?)", queryParam.toArray(new String[queryParam.size()]));
                     } else if (displayMode == Account.FolderMode.ALL) {
-                        cursor = db.rawQuery(baseQuery,  new String[] {
-
-                                                 mAccount.getTrashFolderName() != null ? mAccount.getTrashFolderName() : "" ,
-                                                 mAccount.getDraftsFolderName() != null ? mAccount.getDraftsFolderName() : "",
-                                                 mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "",
-                                                 mAccount.getOutboxFolderName() != null ?  mAccount.getOutboxFolderName() : "",
-                                                 mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "",
-                                             });
+                        cursor = db.rawQuery(baseQuery, (String [])queryParam.toArray());
                     } else {
                         Log.e(K9.LOG_TAG, "asked to compute account statistics for an impossible folder mode " + displayMode);
                         stats.unreadMessageCount = 0;

From 92f7c3a19fd40323b6218ab5099dc62b21a10273 Mon Sep 17 00:00:00 2001
From: Bernhard Redl 
Date: Wed, 20 Apr 2011 15:30:08 +0200
Subject: [PATCH 028/121] Refactored the code to calculate the number of unread
 messages in an account

---
 src/com/fsck/k9/mail/store/LocalStore.java | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index a484b3855..7cbb94e8e 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -506,13 +506,14 @@ public class LocalStore extends Store implements Serializable {
             public Integer doDbWork(final SQLiteDatabase db) {
                 Cursor cursor = null;
                 try {
-                    String baseQuery = "SELECT SUM(unread_count), SUM(flagged_count) FROM folders WHERE ( name != ? AND name != ? AND name != ? AND name != ? AND name != ? ) ";
+                    String baseQuery = "SELECT SUM(unread_count), SUM(flagged_count) FROM folders WHERE ((name = ?) or ( name != ? AND name != ? AND name != ? AND name != ? AND name != ? )) ";
                     List queryParam = new ArrayList();
-                    queryParam.add((mAccount.getTrashFolderName() != null && !mAccount.getTrashFolderName().equals(mAccount.getInboxFolderName())) ? mAccount.getTrashFolderName() : "");
-                    queryParam.add((mAccount.getDraftsFolderName() != null && !mAccount.getTrashFolderName().equals(mAccount.getInboxFolderName())) ? mAccount.getDraftsFolderName() : "");
-                    queryParam.add((mAccount.getSpamFolderName() != null && !mAccount.getSpamFolderName().equals(mAccount.getInboxFolderName())) ? mAccount.getSpamFolderName() : "");
-                    queryParam.add((mAccount.getOutboxFolderName() != null && !mAccount.getOutboxFolderName().equals(mAccount.getInboxFolderName())) ?  mAccount.getOutboxFolderName() : "");
-                    queryParam.add((mAccount.getSentFolderName() != null && !mAccount.getSentFolderName().equals(mAccount.getInboxFolderName())) ? mAccount.getSentFolderName() : "");
+                    queryParam.add(mAccount.getInboxFolderName());
+                    queryParam.add((mAccount.getTrashFolderName() != null) ? mAccount.getTrashFolderName() : "");
+                    queryParam.add((mAccount.getDraftsFolderName() != null) ? mAccount.getDraftsFolderName() : "");
+                    queryParam.add((mAccount.getSpamFolderName() != null) ? mAccount.getSpamFolderName() : "");
+                    queryParam.add((mAccount.getOutboxFolderName() != null) ?  mAccount.getOutboxFolderName() : "");
+                    queryParam.add((mAccount.getSentFolderName() != null) ? mAccount.getSentFolderName() : "");
 
                     if (displayMode == Account.FolderMode.NONE) {
                         queryParam.add(mAccount.getInboxFolderName());

From 49308922d99d622ca62bbaf0594184abe83efd5e Mon Sep 17 00:00:00 2001
From: cketti 
Date: Wed, 20 Apr 2011 23:58:10 +0200
Subject: [PATCH 029/121] Refactored code to calculate number of unread
 messages some more

---
 src/com/fsck/k9/mail/store/LocalStore.java | 80 ++++++++++++++--------
 1 file changed, 50 insertions(+), 30 deletions(-)

diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index 7cbb94e8e..31d6c8987 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -10,6 +10,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
@@ -506,42 +507,61 @@ public class LocalStore extends Store implements Serializable {
             public Integer doDbWork(final SQLiteDatabase db) {
                 Cursor cursor = null;
                 try {
-                    String baseQuery = "SELECT SUM(unread_count), SUM(flagged_count) FROM folders WHERE ((name = ?) or ( name != ? AND name != ? AND name != ? AND name != ? AND name != ? )) ";
+                    // Always count messages in the INBOX but exclude special folders and possibly
+                    // more (depending on the folder display mode)
+                    String baseQuery = "SELECT SUM(unread_count), SUM(flagged_count) " +
+                            "FROM folders " +
+                            "WHERE (name = ?)" +  /* INBOX */
+                            " OR (" +
+                            "name NOT IN (?, ?, ?, ?, ?)" +  /* special folders */
+                            "%s)";  /* placeholder for additional constraints */
+
                     List queryParam = new ArrayList();
                     queryParam.add(mAccount.getInboxFolderName());
-                    queryParam.add((mAccount.getTrashFolderName() != null) ? mAccount.getTrashFolderName() : "");
-                    queryParam.add((mAccount.getDraftsFolderName() != null) ? mAccount.getDraftsFolderName() : "");
-                    queryParam.add((mAccount.getSpamFolderName() != null) ? mAccount.getSpamFolderName() : "");
-                    queryParam.add((mAccount.getOutboxFolderName() != null) ?  mAccount.getOutboxFolderName() : "");
-                    queryParam.add((mAccount.getSentFolderName() != null) ? mAccount.getSentFolderName() : "");
 
-                    if (displayMode == Account.FolderMode.NONE) {
-                        queryParam.add(mAccount.getInboxFolderName());
-                        cursor = db.rawQuery(baseQuery + "AND (name = ? )", queryParam.toArray(new String[queryParam.size()]));
-                    } else if (displayMode == Account.FolderMode.FIRST_CLASS) {
-                        queryParam.add(mAccount.getInboxFolderName());
-                        queryParam.add(Folder.FolderClass.FIRST_CLASS.name());
-                        cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class = ?)", queryParam.toArray(new String[queryParam.size()]));
+                    queryParam.add((mAccount.getTrashFolderName() != null) ?
+                            mAccount.getTrashFolderName() : "");
+                    queryParam.add((mAccount.getDraftsFolderName() != null) ?
+                            mAccount.getDraftsFolderName() : "");
+                    queryParam.add((mAccount.getSpamFolderName() != null) ?
+                            mAccount.getSpamFolderName() : "");
+                    queryParam.add((mAccount.getOutboxFolderName() != null) ?
+                            mAccount.getOutboxFolderName() : "");
+                    queryParam.add((mAccount.getSentFolderName() != null) ?
+                            mAccount.getSentFolderName() : "");
 
-                    } else if (displayMode == Account.FolderMode.FIRST_AND_SECOND_CLASS) {
-                        queryParam.add(mAccount.getInboxFolderName());
-                        queryParam.add(Folder.FolderClass.FIRST_CLASS.name());
-                        queryParam.add(Folder.FolderClass.SECOND_CLASS.name());
-                        cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class = ? OR display_class = ? )", queryParam.toArray(new String[queryParam.size()]));
-
-                    } else if (displayMode == Account.FolderMode.NOT_SECOND_CLASS) {
-                        queryParam.add(mAccount.getInboxFolderName());
-                        queryParam.add(Folder.FolderClass.SECOND_CLASS.name());
-                        cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class != ?)", queryParam.toArray(new String[queryParam.size()]));
-                    } else if (displayMode == Account.FolderMode.ALL) {
-                        cursor = db.rawQuery(baseQuery, (String [])queryParam.toArray());
-                    } else {
-                        Log.e(K9.LOG_TAG, "asked to compute account statistics for an impossible folder mode " + displayMode);
-                        stats.unreadMessageCount = 0;
-                        stats.flaggedMessageCount = 0;
-                        return null;
+                    final String extraWhere;
+                    switch (displayMode) {
+                        case FIRST_CLASS:
+                            // Count messages in the INBOX and non-special first class folders
+                            extraWhere = " AND (display_class = ?)";
+                            queryParam.add(Folder.FolderClass.FIRST_CLASS.name());
+                            break;
+                        case FIRST_AND_SECOND_CLASS:
+                            // Count messages in the INBOX and non-special first and second class folders
+                            extraWhere = " AND (display_class IN (?, ?))";
+                            queryParam.add(Folder.FolderClass.FIRST_CLASS.name());
+                            queryParam.add(Folder.FolderClass.SECOND_CLASS.name());
+                            break;
+                        case NOT_SECOND_CLASS:
+                            // Count messages in the INBOX and non-special non-second-class folders
+                            extraWhere = " AND (display_class != ?)";
+                            queryParam.add(Folder.FolderClass.SECOND_CLASS.name());
+                            break;
+                        case ALL:
+                            // Count messages in the INBOX and non-special folders
+                            extraWhere = "";
+                            break;
+                        default:
+                            Log.e(K9.LOG_TAG, "asked to compute account statistics for an impossible folder mode " + displayMode);
+                            stats.unreadMessageCount = 0;
+                            stats.flaggedMessageCount = 0;
+                            return null;
                     }
 
+                    String query = String.format(Locale.US, baseQuery, extraWhere);
+                    cursor = db.rawQuery(query, queryParam.toArray(EMPTY_STRING_ARRAY));
+
                     cursor.moveToFirst();
                     stats.unreadMessageCount = cursor.getInt(0);
                     stats.flaggedMessageCount = cursor.getInt(1);

From 4b2fe6efab49899076a41d4f3089c0b27eaf94e5 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Thu, 21 Apr 2011 00:00:16 +0200
Subject: [PATCH 030/121] Removed unused imports

---
 .../fsck/k9/activity/setup/AccountSetupCheckSettings.java    | 5 ++---
 src/com/fsck/k9/mail/store/WebDavStore.java                  | 1 -
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
index 4e21619d9..eda175696 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
@@ -28,7 +28,6 @@ import com.fsck.k9.mail.filter.Hex;
 
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateParsingException;
 import java.security.cert.X509Certificate;
 import java.security.NoSuchAlgorithmException;
 import java.security.MessageDigest;
@@ -280,10 +279,10 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
 							      case 0:
 							    	  Log.w(K9.LOG_TAG, "SubjectAltName of type OtherName not supported.");
 							    	  continue;
-							      case 1: // RFC822Name 
+							      case 1: // RFC822Name
 							    	  name = (String)value;
 							        break;
-							      case 2:  // DNSName 
+							      case 2:  // DNSName
 							    	  name = (String)value;
 							        break;
 							      case 3:
diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
index ef3b837f6..69d788c89 100644
--- a/src/com/fsck/k9/mail/store/WebDavStore.java
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -4,7 +4,6 @@ import android.util.Log;
 
 import com.fsck.k9.Account;
 import com.fsck.k9.K9;
-import com.fsck.k9.R;
 import com.fsck.k9.controller.MessageRetrievalListener;
 import com.fsck.k9.helper.Utility;
 import com.fsck.k9.mail.*;

From 9954d96c10a3c26075bf30f967d51633ee482677 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Thu, 21 Apr 2011 00:02:11 +0200
Subject: [PATCH 031/121] Fixed HTML to get rid of some warnings

---
 assets/downloading.html | 2 +-
 assets/empty.html       | 2 +-
 assets/loading.html     | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/assets/downloading.html b/assets/downloading.html
index 403950b57..d77026c14 100644
--- a/assets/downloading.html
+++ b/assets/downloading.html
@@ -2,7 +2,7 @@
 	
 		
-				
+ Downloading...

diff --git a/assets/empty.html b/assets/empty.html index f2f3af345..ae837b940 100644 --- a/assets/empty.html +++ b/assets/empty.html @@ -2,7 +2,7 @@ - diff --git a/assets/loading.html b/assets/loading.html index 0cc9cecc3..fc8c14ac8 100644 --- a/assets/loading.html +++ b/assets/loading.html @@ -2,7 +2,7 @@
+ No text
-
+ Loading...

From 44feb1563b11942ce3d8d675a7a7d2001d2db7a0 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 21 Apr 2011 00:05:03 +0200 Subject: [PATCH 032/121] Updated german translation (nagel.patrick) --- res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index ca6028d5f..06c0bd1e3 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -56,7 +56,7 @@ Antworten Allen antworten Löschen - Sichern + Archivieren Spam Ordner leeren Weiterleiten From e278ea23e9588a0cd7d0f913df8fa3eb2ed1d306 Mon Sep 17 00:00:00 2001 From: Bernhard Redl Date: Sun, 24 Apr 2011 13:54:28 +1000 Subject: [PATCH 033/121] Add a preference for selecting a default folder in which to save attachments --- res/values/strings.xml | 3 ++ res/xml/global_preferences.xml | 6 ++- src/com/fsck/k9/K9.java | 15 ++++-- src/com/fsck/k9/activity/setup/Prefs.java | 62 ++++++++++++++++++++++- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 8737904e7..425682fce 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1041,4 +1041,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin Account \"%s\" is unavailable; check storage + Attachments Default Path + Save to + No filebrowser installed. Please enter destination foldername diff --git a/res/xml/global_preferences.xml b/res/xml/global_preferences.xml index aee7235e2..a65450f83 100644 --- a/res/xml/global_preferences.xml +++ b/res/xml/global_preferences.xml @@ -231,7 +231,11 @@ android:dialogTitle="@string/global_settings_confirm_actions_title" android:positiveButtonText="@android:string/ok" android:negativeButtonText="@android:string/cancel" /> - + Date: Sun, 24 Apr 2011 13:56:34 +1000 Subject: [PATCH 034/121] Unroll import statements in AttachmentView.java --- src/com/fsck/k9/view/AttachmentView.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/com/fsck/k9/view/AttachmentView.java b/src/com/fsck/k9/view/AttachmentView.java index 1fff23319..0ebfa228e 100644 --- a/src/com/fsck/k9/view/AttachmentView.java +++ b/src/com/fsck/k9/view/AttachmentView.java @@ -1,7 +1,16 @@ package com.fsck.k9.view; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.commons.io.IOUtils; + import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; @@ -9,7 +18,12 @@ import android.os.Environment; import android.util.AttributeSet; import android.util.Log; import android.view.View; -import android.widget.*; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + import com.fsck.k9.Account; import com.fsck.k9.K9; import com.fsck.k9.R; @@ -23,9 +37,6 @@ import com.fsck.k9.mail.Part; import com.fsck.k9.mail.internet.MimeUtility; import com.fsck.k9.mail.store.LocalStore.LocalAttachmentBodyPart; import com.fsck.k9.provider.AttachmentProvider; -import org.apache.commons.io.IOUtils; - -import java.io.*; public class AttachmentView extends FrameLayout { From ab4bae214f3b6d5bdf13fed317a5eba4a2e350e8 Mon Sep 17 00:00:00 2001 From: Bernhard Redl Date: Sun, 24 Apr 2011 14:00:10 +1000 Subject: [PATCH 035/121] Make attachment saving respect the new preference. Allow long-press to choose a folder. (new constant renamed from CHOOSE_FOLDER to CHOOSE directory for clarity) --- src/com/fsck/k9/activity/MessageView.java | 51 ++++++++++++++++++++- src/com/fsck/k9/view/AttachmentView.java | 48 +++++++++++++++++-- src/com/fsck/k9/view/SingleMessageView.java | 13 +++++- 3 files changed, 106 insertions(+), 6 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageView.java b/src/com/fsck/k9/activity/MessageView.java index 91e9c7f4a..da64d2acf 100644 --- a/src/com/fsck/k9/activity/MessageView.java +++ b/src/com/fsck/k9/activity/MessageView.java @@ -17,12 +17,16 @@ import com.fsck.k9.*; import com.fsck.k9.controller.MessagingController; import com.fsck.k9.controller.MessagingListener; import com.fsck.k9.crypto.PgpData; +import com.fsck.k9.helper.FileBrowserHelper; +import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback; import com.fsck.k9.mail.*; import com.fsck.k9.mail.store.StorageManager; import com.fsck.k9.view.AttachmentView; import com.fsck.k9.view.ToggleScrollView; import com.fsck.k9.view.SingleMessageView; +import com.fsck.k9.view.AttachmentView.AttachmentFileDownloadCallback; +import java.io.File; import java.util.*; public class MessageView extends K9Activity implements OnClickListener { @@ -33,7 +37,7 @@ public class MessageView extends K9Activity implements OnClickListener { private static final String STATE_PGP_DATA = "pgpData"; private static final int ACTIVITY_CHOOSE_FOLDER_MOVE = 1; private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2; - + private static final int ACTIVITY_CHOOSE_DIRECTORY = 3; private SingleMessageView mMessageView; @@ -61,6 +65,12 @@ public class MessageView extends K9Activity implements OnClickListener { private MessageViewHandler mHandler = new MessageViewHandler(); private StorageManager.StorageListener mStorageListener = new StorageListenerImplementation(); + /** this variable is used to save the calling AttachmentView + * until the onActivityResult is called. + * => with this reference we can identity the caller + */ + private AttachmentView attachmentTmpStore; + /** * Used to temporarily store the destination folder for refile operations if a confirmation * dialog is shown. @@ -295,6 +305,32 @@ public class MessageView extends K9Activity implements OnClickListener { mTopView = mToggleScrollView = (ToggleScrollView) findViewById(R.id.top_view); mMessageView = (SingleMessageView) findViewById(R.id.message_view); + //set a callback for the attachment view. With this callback the attachmentview + //request the start of a filebrowser activity. + mMessageView.setAttachmentCallback(new AttachmentFileDownloadCallback() { + + @Override + public void showFileBrowser(final AttachmentView caller) { + FileBrowserHelper.getInstance() + .showFileBrowserActivity(MessageView.this, + null, + MessageView.ACTIVITY_CHOOSE_DIRECTORY, + callback); + attachmentTmpStore = caller; + } + FileBrowserFailOverCallback callback = new FileBrowserFailOverCallback() { + + @Override + public void onPathEntered(String path) { + attachmentTmpStore.writeFile(new File(path)); + } + + @Override + public void onCancel() { + // canceled, do nothing + } + }; + }); mMessageView.initialize(this); setTitle(""); @@ -712,6 +748,19 @@ public class MessageView extends K9Activity implements OnClickListener { if (resultCode != RESULT_OK) return; switch (requestCode) { + case ACTIVITY_CHOOSE_DIRECTORY: + if (resultCode == RESULT_OK && data != null) { + // obtain the filename + Uri fileUri = data.getData(); + if (fileUri != null) { + String filePath = fileUri.getPath(); + if (filePath != null) { + attachmentTmpStore.writeFile(new File(filePath)); + } + } + } + + break; case ACTIVITY_CHOOSE_FOLDER_MOVE: case ACTIVITY_CHOOSE_FOLDER_COPY: if (data == null) diff --git a/src/com/fsck/k9/view/AttachmentView.java b/src/com/fsck/k9/view/AttachmentView.java index 0ebfa228e..cf24aa322 100644 --- a/src/com/fsck/k9/view/AttachmentView.java +++ b/src/com/fsck/k9/view/AttachmentView.java @@ -53,6 +53,8 @@ public class AttachmentView extends FrameLayout { public long size; public ImageView iconView; + private AttachmentFileDownloadCallback callback; + public AttachmentView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mContext = context; @@ -67,7 +69,18 @@ public class AttachmentView extends FrameLayout { } - + public interface AttachmentFileDownloadCallback { + /** + * this method i called by the attachmentview when + * he wants to show a filebrowser + * the provider should show the filebrowser activity + * and save the reference to the attachment view for later. + * in his onActivityResult he can get the saved reference and + * call the saveFile method of AttachmentView + * @param view + */ + public void showFileBrowser(AttachmentView caller); + } public boolean populateFromPart(Part inputPart, Message message, Account account, MessagingController controller, MessagingListener listener) { try { part = (LocalAttachmentBodyPart) inputPart; @@ -124,6 +137,14 @@ public class AttachmentView extends FrameLayout { return; } }); + downloadButton.setOnLongClickListener(new OnLongClickListener() { + + @Override + public boolean onLongClick(View v) { + callback.showFileBrowser(AttachmentView.this); + return true; + } + }); attachmentName.setText(name); attachmentInfo.setText(SizeFormatter.formatSize(mContext, size)); @@ -169,9 +190,13 @@ public class AttachmentView extends FrameLayout { saveFile(); } - public void writeFile() { + /** + * Writes the attachment onto the given path + * @param directory: the base dir where the file should be saved. + */ + public void writeFile(File directory) { try { - File file = Utility.createUniqueFile(Environment.getExternalStorageDirectory(), name); + File file = Utility.createUniqueFile(directory, name); Uri uri = AttachmentProvider.getAttachmentUri(mAccount, part.getAttachmentId()); InputStream in = mContext.getContentResolver().openInputStream(uri); OutputStream out = new FileOutputStream(file); @@ -179,14 +204,22 @@ public class AttachmentView extends FrameLayout { out.flush(); out.close(); in.close(); - attachmentSaved(file.getName()); + attachmentSaved(file.toString()); new MediaScannerNotifier(mContext, file); } catch (IOException ioe) { attachmentNotSaved(); } } + /** + * saves the file to the defaultpath setting in the config, or if the config + * is not set => to the Environment + */ + public void writeFile() { + writeFile(new File(K9.getAttachmentDefaultPath())); + } public void saveFile() { + //TODO: Can the user save attachments on the internal filesystem or sd card only? if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { /* * Abort early if there's no place to save the attachment. We don't want to spend @@ -259,4 +292,11 @@ public class AttachmentView extends FrameLayout { mContext.getString(R.string.message_view_status_attachment_not_saved), Toast.LENGTH_LONG).show(); } + public AttachmentFileDownloadCallback getCallback() { + return callback; + } + public void setCallback(AttachmentFileDownloadCallback callback) { + this.callback = callback; + } + } diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java index 3f0ceb146..5b84fc57f 100644 --- a/src/com/fsck/k9/view/SingleMessageView.java +++ b/src/com/fsck/k9/view/SingleMessageView.java @@ -44,7 +44,7 @@ public class SingleMessageView extends LinearLayout { private Button mDownloadRemainder; private LayoutInflater mInflater; private Contacts mContacts; - + private AttachmentView.AttachmentFileDownloadCallback attachmentCallback; public void initialize(Activity activity) { mMessageContentView = (MessageWebView) findViewById(R.id.message_content); @@ -265,6 +265,7 @@ public class SingleMessageView extends LinearLayout { return; } AttachmentView view = (AttachmentView)mInflater.inflate(R.layout.message_view_attachment, null); + view.setCallback(attachmentCallback); if (view.populateFromPart(part, message, account, controller, listener)) { addAttachment(view); } @@ -299,4 +300,14 @@ public class SingleMessageView extends LinearLayout { mMessageContentView.clearView(); mAttachments.removeAllViews(); } + + public AttachmentView.AttachmentFileDownloadCallback getAttachmentCallback() { + return attachmentCallback; + } + + public void setAttachmentCallback( + AttachmentView.AttachmentFileDownloadCallback attachmentCallback) { + this.attachmentCallback = attachmentCallback; + } + } From 0b2a9b5912dc11f0d893b478262a47754deb552f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 24 Apr 2011 14:11:43 +1000 Subject: [PATCH 036/121] Phrasing improvements for "where to save attachments" preference --- res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 425682fce..01150c8eb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1041,7 +1041,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin Account \"%s\" is unavailable; check storage - Attachments Default Path - Save to - No filebrowser installed. Please enter destination foldername + Save attachments to... + Save attachment + No file browser found. Where would you like to save this attachment? From a4db299289906d8cff7f4e733137cba8913e2964 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 24 Apr 2011 14:12:32 +1000 Subject: [PATCH 037/121] we don't use def_ to mean default --- res/values/strings.xml | 2 +- res/xml/global_preferences.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 01150c8eb..8458b0b1c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1041,7 +1041,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin Account \"%s\" is unavailable; check storage - Save attachments to... + Save attachments to... Save attachment No file browser found. Where would you like to save this attachment? diff --git a/res/xml/global_preferences.xml b/res/xml/global_preferences.xml index a65450f83..bf26c2eeb 100644 --- a/res/xml/global_preferences.xml +++ b/res/xml/global_preferences.xml @@ -233,7 +233,7 @@ android:negativeButtonText="@android:string/cancel" /> From ad46c5a22e897cdd665b1880a7cd773f608f500f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 24 Apr 2011 14:13:13 +1000 Subject: [PATCH 038/121] default path to save attachments isn't an interaction preference. until we have a "storage" toplevel preferences section, move it to misc --- res/xml/global_preferences.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/res/xml/global_preferences.xml b/res/xml/global_preferences.xml index bf26c2eeb..d3297c942 100644 --- a/res/xml/global_preferences.xml +++ b/res/xml/global_preferences.xml @@ -231,11 +231,6 @@ android:dialogTitle="@string/global_settings_confirm_actions_title" android:positiveButtonText="@android:string/ok" android:negativeButtonText="@android:string/cancel" /> - + Date: Sat, 23 Apr 2011 08:24:13 +0800 Subject: [PATCH 039/121] fix NullPtr Exception when there is no Sent Mail folder on the imap server --- src/com/fsck/k9/activity/setup/AccountSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/fsck/k9/activity/setup/AccountSettings.java b/src/com/fsck/k9/activity/setup/AccountSettings.java index 2944ace9b..69f35cb6e 100644 --- a/src/com/fsck/k9/activity/setup/AccountSettings.java +++ b/src/com/fsck/k9/activity/setup/AccountSettings.java @@ -873,7 +873,7 @@ public class AccountSettings extends K9PreferenceActivity { Iterator iter = folders.iterator(); while (iter.hasNext()) { Folder folder = iter.next(); - if (mAccount.getOutboxFolderName().equalsIgnoreCase(folder.getName())) { + if (mAccount.getOutboxFolderName() != null && mAccount.getOutboxFolderName().equalsIgnoreCase(folder.getName())) { iter.remove(); } } From c3480db129a55e2ea41f14c9d70b76a176c8b64a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 25 Apr 2011 13:17:18 +1000 Subject: [PATCH 040/121] Add missing file from the file chooser work --- src/com/fsck/k9/helper/FileBrowserHelper.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/com/fsck/k9/helper/FileBrowserHelper.java diff --git a/src/com/fsck/k9/helper/FileBrowserHelper.java b/src/com/fsck/k9/helper/FileBrowserHelper.java new file mode 100644 index 000000000..caf7f55cc --- /dev/null +++ b/src/com/fsck/k9/helper/FileBrowserHelper.java @@ -0,0 +1,116 @@ +package com.fsck.k9.helper; + +import java.io.File; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.ActivityNotFoundException; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.text.InputType; +import android.widget.EditText; + +import com.fsck.k9.K9; +import com.fsck.k9.R; + +public class FileBrowserHelper { + private static FileBrowserHelper sInstance; + + /** + * callback class to provide the result of the fallback textedit path dialog + */ + public interface FileBrowserFailOverCallback { + /** + * the user has entered a path + * @param path the path as String + */ + public void onPathEntered(String path); + /** + * the user has cancel the inputtext dialog + */ + public void onCancel(); + } + /** + * factory method + * + */ + private FileBrowserHelper() { + } + public synchronized static FileBrowserHelper getInstance() { + if (sInstance == null) { + sInstance = new FileBrowserHelper(); + } + return sInstance; + } + + + /** + * tries to open known filebrowsers. + * If no filebrowser is found and fallback textdialog is shown + * @param c the context as activty + * @param startPath: the default value, where the filebrowser will start. + * if startPath = null => the default path is used + * @param requestcode: the int you will get as requestcode in onActivityResult + * (only used if there is a filebrowser installed) + * @param callback: the callback (only used when no filebrowser is installed. + * if a filebrowser is installed => override the onActivtyResult Method + * + * @return true: if a filebrowser has been found (the result will be in the onActivityResult + * false: a fallback textinput has been shown. The Result will be sent with the callback method + * + * + */ + public boolean showFileBrowserActivity(Activity c, File startPath, int requestcode, FileBrowserFailOverCallback callback) { + boolean success = false; + Intent intent = new Intent("org.openintents.action.PICK_DIRECTORY"); + if (startPath == null) + startPath = new File(K9.getAttachmentDefaultPath()); + if (startPath != null) + intent.setData(Uri.fromFile(startPath)); + + try { + c.startActivityForResult(intent, requestcode); + success = true; + } catch (ActivityNotFoundException e) { + try { + intent = new Intent("com.androidworkz.action.PICK_DIRECTORY"); + c.startActivityForResult(intent, requestcode); + success = true; + } catch (ActivityNotFoundException ee) { + //No Filebrowser is installed => show an fallback textdialog + showPathTextInput(c, startPath, callback); + return false; + } + } + return success; + } + + private void showPathTextInput(final Activity c, final File startPath, final FileBrowserFailOverCallback callback) { + AlertDialog.Builder alert = new AlertDialog.Builder(c); + + alert.setTitle(c.getString(R.string.attachment_save_title)); + alert.setMessage(c.getString(R.string.attachment_save_desc)); + final EditText input = new EditText(c); + input.setInputType(InputType.TYPE_CLASS_TEXT); + if (startPath != null) + input.setText(startPath.toString()); + alert.setView(input); + + alert.setPositiveButton(c.getString(R.string.okay_action), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + String path = input.getText().toString(); + callback.onPathEntered(path); + } + }); + + alert.setNegativeButton(c.getString(R.string.cancel_action), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + callback.onCancel(); + } + }); + + alert.show(); + } +} From da38149091cd8793ee74f25e1f16a09ca9b8beef Mon Sep 17 00:00:00 2001 From: Jonas Hurrelmann Date: Mon, 25 Apr 2011 22:32:48 +0200 Subject: [PATCH 041/121] Support for SMTP authentication methods that are not announced by the server. - Added AUTOMATIC as a new authentication method that will automatically choose the best authentication method (basically old behavior with CRAM_MD5). All other options will now enforce the selected authentication method. - Added LOGIN as selectable option. - Cleaned up code so strings to the different authentication methods are only defined once. --- .../activity/setup/AccountSetupOutgoing.java | 21 +++++---- .../fsck/k9/mail/transport/SmtpTransport.java | 47 ++++++++++++------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java b/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java index 770f6e909..3a3938d09 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java @@ -16,6 +16,8 @@ import android.widget.CompoundButton.OnCheckedChangeListener; import com.fsck.k9.*; import com.fsck.k9.activity.K9Activity; import com.fsck.k9.helper.Utility; +import com.fsck.k9.mail.transport.SmtpTransport; + import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; @@ -45,10 +47,13 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener, "webdav", "webdav+ssl", "webdav+ssl+", "webdav+tls", "webdav+tls+" }; */ - private static final String authTypes[] = { - "PLAIN", "CRAM_MD5" + SmtpTransport.AUTH_AUTOMATIC, + SmtpTransport.AUTH_LOGIN, + SmtpTransport.AUTH_PLAIN, + SmtpTransport.AUTH_CRAM_MD5, }; + private EditText mUsernameView; private EditText mPasswordView; private EditText mServerView; @@ -117,14 +122,10 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener, new SpinnerOption(4, getString(R.string.account_setup_incoming_security_tls_label)), }; - // This needs to be kept in sync with the list at the top of the file. - // that makes me somewhat unhappy - SpinnerOption authTypeSpinnerOptions[] = { - new SpinnerOption(0, "PLAIN"), - new SpinnerOption(1, "CRAM_MD5") - }; - - + SpinnerOption authTypeSpinnerOptions[] = new SpinnerOption[authTypes.length]; + for (int i = 0; i < authTypes.length; i++) { + authTypeSpinnerOptions[i] = new SpinnerOption(i, authTypes[i]); + } ArrayAdapter securityTypesAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, securityTypes); diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java index 142c8ac9f..0666ce62d 100644 --- a/src/com/fsck/k9/mail/transport/SmtpTransport.java +++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java @@ -39,6 +39,14 @@ public class SmtpTransport extends Transport { public static final int CONNECTION_SECURITY_SSL_OPTIONAL = 4; + public static final String AUTH_PLAIN = "PLAIN"; + + public static final String AUTH_CRAM_MD5 = "CRAM_MD5"; + + public static final String AUTH_LOGIN = "LOGIN"; + + public static final String AUTH_AUTOMATIC = "AUTOMATIC"; + String mHost; int mPort; @@ -227,22 +235,29 @@ public class SmtpTransport extends Transport { boolean authLoginSupported = false; boolean authPlainSupported = false; boolean authCramMD5Supported = false; - for (String result : results) { - if (result.matches(".*AUTH.*LOGIN.*$")) { - authLoginSupported = true; - } - if (result.matches(".*AUTH.*PLAIN.*$")) { - authPlainSupported = true; - } - if (result.matches(".*AUTH.*CRAM-MD5.*$") && mAuthType != null && mAuthType.equals("CRAM_MD5")) { - authCramMD5Supported = true; - } - if (result.matches(".*SIZE \\d*$")) { - try { - mLargestAcceptableMessage = Integer.parseInt(result.substring(result.lastIndexOf(' ') + 1)); - } catch (Exception e) { - if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { - Log.d(K9.LOG_TAG, "Tried to parse " + result + " and get an int out of the last word: " + e); + if (mAuthType != null) { + authLoginSupported = mAuthType.equals(AUTH_LOGIN); + authPlainSupported = mAuthType.equals(AUTH_PLAIN); + authCramMD5Supported = mAuthType.equals(AUTH_CRAM_MD5); + } + if (mAuthType == null || mAuthType.equals(AUTH_AUTOMATIC)) { + for (String result : results) { + if (result.matches(".*AUTH.*LOGIN.*$")) { + authLoginSupported = true; + } + if (result.matches(".*AUTH.*PLAIN.*$")) { + authPlainSupported = true; + } + if (result.matches(".*AUTH.*CRAM-MD5.*$")) { + authCramMD5Supported = true; + } + if (result.matches(".*SIZE \\d*$")) { + try { + mLargestAcceptableMessage = Integer.parseInt(result.substring(result.lastIndexOf(' ') + 1)); + } catch (Exception e) { + if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { + Log.d(K9.LOG_TAG, "Tried to parse " + result + " and get an int out of the last word: " + e); + } } } } From 9b2e4c43a9d8da8f131aad0e827e2a28f533d003 Mon Sep 17 00:00:00 2001 From: Koji Arai Date: Tue, 26 Apr 2011 23:49:25 +0900 Subject: [PATCH 042/121] Fixed default sender color in the MessageList --- res/layout/message_list_item_touchable.xml | 2 +- src/com/fsck/k9/activity/MessageList.java | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/res/layout/message_list_item_touchable.xml b/res/layout/message_list_item_touchable.xml index 0cf1ad978..32d27ca07 100644 --- a/res/layout/message_list_item_touchable.xml +++ b/res/layout/message_list_item_touchable.xml @@ -83,7 +83,7 @@ android:layout_marginRight="0dip" android:singleLine="false" android:bufferType="spannable" - android:textColor="?android:attr/textColorTertiary" + android:textColor="?android:attr/textColorPrimary" android:textAppearance="?android:attr/textAppearanceSmall" /> diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index e48b7cf00..c99253795 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -12,12 +12,14 @@ import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.Intent; +import android.graphics.Color; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.AbsoluteSizeSpan; +import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.util.Log; import android.util.TypedValue; @@ -2256,6 +2258,12 @@ public class MessageList 0, message.sender.length() + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + + // set span for preview message. + str.setSpan(new ForegroundColorSpan(Color.rgb(128, 128, 128)), // How do I can specify the android.R.attr.textColorTertiary + message.sender.length() + 1, + str.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } else { holder.from.setText(new SpannableStringBuilder(recipientSigil(message)).append(message.sender)); From e8a1a9a4661e9b5aa0ed4dd819e0b680bed7f0b8 Mon Sep 17 00:00:00 2001 From: cketti Date: Tue, 26 Apr 2011 17:49:40 +0200 Subject: [PATCH 043/121] Restored semantics of auth*Supported in SMTP authentication code Also, display a debug message if a certain authentication method was selected by the user but the server didn't advertise support for it in the EHLO response. --- .../fsck/k9/mail/transport/SmtpTransport.java | 68 ++++++++++--------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java index 0666ce62d..aa4f64383 100644 --- a/src/com/fsck/k9/mail/transport/SmtpTransport.java +++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java @@ -229,47 +229,53 @@ public class SmtpTransport extends Transport { } } - /* - * result contains the results of the EHLO in concatenated form - */ + boolean useAuthLogin = AUTH_LOGIN.equals(mAuthType); + boolean useAuthPlain = AUTH_PLAIN.equals(mAuthType); + boolean useAuthCramMD5 = AUTH_CRAM_MD5.equals(mAuthType); + boolean authLoginSupported = false; boolean authPlainSupported = false; boolean authCramMD5Supported = false; - if (mAuthType != null) { - authLoginSupported = mAuthType.equals(AUTH_LOGIN); - authPlainSupported = mAuthType.equals(AUTH_PLAIN); - authCramMD5Supported = mAuthType.equals(AUTH_CRAM_MD5); - } - if (mAuthType == null || mAuthType.equals(AUTH_AUTOMATIC)) { - for (String result : results) { - if (result.matches(".*AUTH.*LOGIN.*$")) { - authLoginSupported = true; - } - if (result.matches(".*AUTH.*PLAIN.*$")) { - authPlainSupported = true; - } - if (result.matches(".*AUTH.*CRAM-MD5.*$")) { - authCramMD5Supported = true; - } - if (result.matches(".*SIZE \\d*$")) { - try { - mLargestAcceptableMessage = Integer.parseInt(result.substring(result.lastIndexOf(' ') + 1)); - } catch (Exception e) { - if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { - Log.d(K9.LOG_TAG, "Tried to parse " + result + " and get an int out of the last word: " + e); - } + for (String result : results) { + if (result.matches(".*AUTH.*LOGIN.*$")) { + authLoginSupported = true; + } + if (result.matches(".*AUTH.*PLAIN.*$")) { + authPlainSupported = true; + } + if (result.matches(".*AUTH.*CRAM-MD5.*$")) { + authCramMD5Supported = true; + } + if (result.matches(".*SIZE \\d*$")) { + try { + mLargestAcceptableMessage = Integer.parseInt(result.substring(result.lastIndexOf(' ') + 1)); + } catch (Exception e) { + if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { + Log.d(K9.LOG_TAG, "Tried to parse " + result + " and get an int out of the last word: " + e); } } } } - if (mUsername != null && mUsername.length() > 0 && mPassword != null - && mPassword.length() > 0) { - if (authCramMD5Supported) { + if (mUsername != null && mUsername.length() > 0 && + mPassword != null && mPassword.length() > 0) { + if (useAuthCramMD5 || authCramMD5Supported) { + if (!authCramMD5Supported && K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { + Log.d(K9.LOG_TAG, "Using CRAM_MD5 as authentication method although the " + + "server didn't advertise support for it in EHLO response."); + } saslAuthCramMD5(mUsername, mPassword); - } else if (authPlainSupported) { + } else if (useAuthPlain || authPlainSupported) { + if (!authPlainSupported && K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { + Log.d(K9.LOG_TAG, "Using PLAIN as authentication method although the " + + "server didn't advertise support for it in EHLO response."); + } saslAuthPlain(mUsername, mPassword); - } else if (authLoginSupported) { + } else if (useAuthLogin || authLoginSupported) { + if (!authPlainSupported && K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { + Log.d(K9.LOG_TAG, "Using LOGIN as authentication method although the " + + "server didn't advertise support for it in EHLO response."); + } saslAuthLogin(mUsername, mPassword); } else { throw new MessagingException("No valid authentication mechanism found."); From 037b0ff64de7f8461920a21445595e4a160e1381 Mon Sep 17 00:00:00 2001 From: cketti Date: Tue, 26 Apr 2011 18:23:41 +0200 Subject: [PATCH 044/121] Fix automatic authentication method selection for SMTP Only use automatic authentication method selection if none was explicitly selected in outgoing server settings. --- src/com/fsck/k9/mail/transport/SmtpTransport.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java index aa4f64383..bb31409be 100644 --- a/src/com/fsck/k9/mail/transport/SmtpTransport.java +++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java @@ -233,6 +233,9 @@ public class SmtpTransport extends Transport { boolean useAuthPlain = AUTH_PLAIN.equals(mAuthType); boolean useAuthCramMD5 = AUTH_CRAM_MD5.equals(mAuthType); + // Automatically choose best authentication method if none was explicitly selected + boolean useAutomaticAuth = !(useAuthLogin || useAuthPlain || useAuthCramMD5); + boolean authLoginSupported = false; boolean authPlainSupported = false; boolean authCramMD5Supported = false; @@ -259,19 +262,19 @@ public class SmtpTransport extends Transport { if (mUsername != null && mUsername.length() > 0 && mPassword != null && mPassword.length() > 0) { - if (useAuthCramMD5 || authCramMD5Supported) { + if (useAuthCramMD5 || (useAutomaticAuth && authCramMD5Supported)) { if (!authCramMD5Supported && K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { Log.d(K9.LOG_TAG, "Using CRAM_MD5 as authentication method although the " + "server didn't advertise support for it in EHLO response."); } saslAuthCramMD5(mUsername, mPassword); - } else if (useAuthPlain || authPlainSupported) { + } else if (useAuthPlain || (useAutomaticAuth && authPlainSupported)) { if (!authPlainSupported && K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { Log.d(K9.LOG_TAG, "Using PLAIN as authentication method although the " + "server didn't advertise support for it in EHLO response."); } saslAuthPlain(mUsername, mPassword); - } else if (useAuthLogin || authLoginSupported) { + } else if (useAuthLogin || (useAutomaticAuth && authLoginSupported)) { if (!authPlainSupported && K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { Log.d(K9.LOG_TAG, "Using LOGIN as authentication method although the " + "server didn't advertise support for it in EHLO response."); From b7a6dbd9734700e3eacdaf1477fed14c03106e00 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 28 Apr 2011 04:46:01 +0200 Subject: [PATCH 045/121] Skip IMAP folders with names that are not correctly encoded. Configure the CharsetDecoder to throw an exception if malformed input is encountered. Not doing this can cause an endless loop that allocates memory until the application dies with an OutOfMemory error. Until we have support for both a folder display name and a raw folder name we simply ignore folders with names that aren't correctly encoded with the modified UTF-7 variant. Fixes issue 3268 Credits: Bernhard Redl (aatdark) analysed the problem and wrote the initial version of the fix. --- src/com/fsck/k9/mail/store/ImapStore.java | 27 ++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index bbd7fc148..4eeb3bea0 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -18,7 +18,10 @@ import java.net.URISyntaxException; import java.net.URLDecoder; import java.nio.ByteBuffer; import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; import java.security.GeneralSecurityException; import java.security.SecureRandom; import java.security.Security; @@ -373,7 +376,20 @@ public class ImapStore extends Store { for (ImapResponse response : responses) { if (ImapResponseParser.equalsIgnoreCase(response.get(0), commandResponse)) { boolean includeFolder = true; - String folder = decodeFolderName(response.getString(3)); + + String folder; + try { + folder = decodeFolderName(response.getString(3)); + } catch (CharacterCodingException e) { + Log.w(K9.LOG_TAG, "Folder name not correctly encoded with the UTF-7 variant " + + "as defined by RFC 3501: " + response.getString(3), e); + + //TODO: Use the raw name returned by the server for all commands that require + // a folder name. Use the decoded name only for showing it to the user. + + // We currently just skip folders with malformed names. + continue; + } if (mPathDelimeter == null) { mPathDelimeter = response.getString(2); @@ -395,7 +411,7 @@ public class ImapStore extends Store { if (folder.length() >= getCombinedPrefix().length()) { folder = folder.substring(getCombinedPrefix().length()); } - if (!decodeFolderName(response.getString(3)).equalsIgnoreCase(getCombinedPrefix() + folder)) { + if (!folder.equalsIgnoreCase(getCombinedPrefix() + folder)) { includeFolder = false; } } @@ -492,14 +508,15 @@ public class ImapStore extends Store { } } - private String decodeFolderName(String name) { + private String decodeFolderName(String name) throws CharacterCodingException { /* * Convert the encoded name to US-ASCII, then pass it through the modified UTF-7 * decoder and return the Unicode String. */ try { - byte[] encoded = name.getBytes("US-ASCII"); - CharBuffer cb = mModifiedUtf7Charset.decode(ByteBuffer.wrap(encoded)); + // Make sure the decoder throws an exception if it encounters an invalid encoding. + CharsetDecoder decoder = mModifiedUtf7Charset.newDecoder().onMalformedInput(CodingErrorAction.REPORT); + CharBuffer cb = decoder.decode(ByteBuffer.wrap(name.getBytes("US-ASCII"))); return cb.toString(); } catch (UnsupportedEncodingException uee) { /* From d745df753d2ea6b7531c1a575aee63db5bf7c408 Mon Sep 17 00:00:00 2001 From: Koji Arai Date: Thu, 28 Apr 2011 00:22:13 +0900 Subject: [PATCH 046/121] Improved Japanese translation --- res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 7336ce75e..52108d795 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -133,7 +133,7 @@ (取込中 %s%s) メール取込中\u2026 接続エラー - 新着メールなし + メッセージが見つかりません エラー 送信\u2026 From d5ca4f107a4d78e9d0ba985b9c4ca39fe907855f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 30 Apr 2011 08:17:25 +0800 Subject: [PATCH 047/121] Bumped manifest to 3.711 --- AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c74641d35..4285bdcba 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ Date: Sun, 1 May 2011 01:32:34 +0900 Subject: [PATCH 048/121] Updated Japanese translation. catch up with a4db299. --- res/values-ja/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 52108d795..ebf53b638 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -1033,4 +1033,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール アカウント \"%s\" は利用できません。ストレージを確認してください。 + 添付ファイルの保存先 + 添付ファイルの保存先 + ファイルブラウザがインストールされていません。添付ファイルの保存場所を直接入力してください。 From 785fd397c5125ed94e4b2bc0d94e99766dd6c354 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 30 Apr 2011 23:22:47 +0200 Subject: [PATCH 049/121] Updated catalan translation (dvbotet) --- res/values-ca/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 7284788f1..5aea00067 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -344,7 +344,7 @@ Benvingut a la configuració del K-9. El K-9 és un client de codi obert per An Arxiva Esborra (només la vista del missatge) Brossa - + Maca\'ls tots com a llegits Envia Bloca notificacions @@ -1025,10 +1025,10 @@ Benvingut a la configuració del K-9. El K-9 és un client de codi obert per An Esborra No esborris - - - - + Confirma moure\'l carpeta brossa + Realment vols moure aquest missatge a la carpeta brossa? + + No S\'està descarregant adjunt @@ -1038,6 +1038,6 @@ Benvingut a la configuració del K-9. El K-9 és un client de codi obert per An No es pot connectar. - + Compte \"%s\" no és disponible; comprova emmagatzematge From f2283aa91efeac1947cb6539652b0b71ad52a540 Mon Sep 17 00:00:00 2001 From: Bernhard Redl Date: Sun, 1 May 2011 00:42:15 +0200 Subject: [PATCH 050/121] Catch IllegalCharsetNameException causing force-close on unsupported japanese charsets (issue 3272) --- src/com/fsck/k9/mail/internet/MimeUtility.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java index 84ce1e063..0fd320c0a 100644 --- a/src/com/fsck/k9/mail/internet/MimeUtility.java +++ b/src/com/fsck/k9/mail/internet/MimeUtility.java @@ -14,6 +14,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.regex.Pattern; import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; public class MimeUtility { @@ -1381,13 +1382,19 @@ public class MimeUtility { /* * See if there is conversion from the MIME charset to the Java one. + * this function may also throw an exception if the charset name is not known */ - if (!Charset.isSupported(charset)) { + boolean supported; + try { + supported = Charset.isSupported(charset); + } catch (IllegalCharsetNameException e) { + supported = false; + } + if (!supported) { Log.e(K9.LOG_TAG, "I don't know how to deal with the charset " + charset + ". Falling back to US-ASCII"); charset = "US-ASCII"; } - /* * Convert and return as new String */ From 01937d4ab83e89195124488de7c52686ea492645 Mon Sep 17 00:00:00 2001 From: cketti Date: Sun, 1 May 2011 05:34:17 +0200 Subject: [PATCH 051/121] Don't crash if "footer view" is clicked in search results Fixes issue 3071 --- src/com/fsck/k9/activity/MessageList.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index c99253795..c7069df0e 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -567,9 +567,10 @@ public class MessageList @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - // Use mListView.getAdapter() to get the WrapperListAdapter that includes the footer view. - if (mCurrentFolder != null && ((position + 1) == mListView.getAdapter().getCount())) { - mController.loadMoreMessages(mAccount, mFolderName, mAdapter.mListener); + if (view == mFooterView) { + if (mCurrentFolder != null) { + mController.loadMoreMessages(mAccount, mFolderName, mAdapter.mListener); + } return; } From 37ae2e41f536a360cf86a4d0083393b540dd73ba Mon Sep 17 00:00:00 2001 From: Vitaly Polonetsky Date: Thu, 5 May 2011 04:25:58 +0800 Subject: [PATCH 052/121] fixed displaying of "(null)" account description in notification at account setup wizard --- src/com/fsck/k9/controller/MessagingController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index f37b89318..e05654b1c 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -3982,7 +3982,8 @@ public class MessagingController implements Runnable { Intent i = FolderList.actionHandleNotification(context, account, message.getFolder().getName()); PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0); - String accountNotice = context.getString(R.string.notification_new_one_account_fmt, unreadCount, account.getDescription()); + String accountDescr = (account.getDescription() != null) ? account.getDescription() : account.getEmail(); + String accountNotice = context.getString(R.string.notification_new_one_account_fmt, unreadCount, accountDescr); notif.setLatestEventInfo(context, accountNotice, messageNotice, pi); // Only ring or vibrate if we have not done so already on this From 870791958f707a3df7a672ea382f84e47c0db081 Mon Sep 17 00:00:00 2001 From: Koji Arai Date: Thu, 5 May 2011 07:06:29 +0900 Subject: [PATCH 053/121] Refresh folder list when folder is cleared --- src/com/fsck/k9/activity/FolderList.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/com/fsck/k9/activity/FolderList.java b/src/com/fsck/k9/activity/FolderList.java index 09c55a976..30b0ed706 100644 --- a/src/com/fsck/k9/activity/FolderList.java +++ b/src/com/fsck/k9/activity/FolderList.java @@ -487,6 +487,7 @@ public class FolderList extends K9ListActivity { } } + onRefresh(!REFRESH_REMOTE); } From 67b2921bcf58a80c7e32e14a5d82469561a09e37 Mon Sep 17 00:00:00 2001 From: cketti Date: Wed, 4 May 2011 23:45:54 +0200 Subject: [PATCH 054/121] Replaced tabs with spaces --- res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 8458b0b1c..4f496e6b0 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1041,7 +1041,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin Account \"%s\" is unavailable; check storage - Save attachments to... - Save attachment - No file browser found. Where would you like to save this attachment? + Save attachments to... + Save attachment + No file browser found. Where would you like to save this attachment? From bb4da9a8bad22099fc87305a98ce7512a6a59f59 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 5 May 2011 00:08:09 +0200 Subject: [PATCH 055/121] Added placeholders for newly added string to translations --- res/values-ca/strings.xml | 3 +++ res/values-cs/strings.xml | 3 +++ res/values-de/strings.xml | 3 +++ res/values-es/strings.xml | 3 +++ res/values-fi/strings.xml | 3 +++ res/values-gl/strings.xml | 3 +++ res/values-it/strings.xml | 3 +++ res/values-nl/strings.xml | 3 +++ res/values-pl/strings.xml | 3 +++ res/values-pt-rBR/strings.xml | 3 +++ res/values-ru/strings.xml | 3 +++ res/values-sv/strings.xml | 3 +++ res/values-zh-rCN/strings.xml | 3 +++ 13 files changed, 39 insertions(+) diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 5aea00067..46b74b95e 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -1040,4 +1040,7 @@ Benvingut a la configuració del K-9. El K-9 és un client de codi obert per An Compte \"%s\" no és disponible; comprova emmagatzematge + + + diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index beeb45308..feeb968e2 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -1047,4 +1047,7 @@ Vítejte v nastavení pošty K-9 Mail. K-9 je open source poštovní klient pro + + + diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 06c0bd1e3..7003a790f 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -1037,4 +1037,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü Konto \"%s\" ist nicht verfügbar; Bitte SD-Karte prüfen. + + + diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 08c5a51d7..267874dc2 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -1037,4 +1037,7 @@ Bienvenido a la Configuración de K-9. K-9 es un cliente de correo OpenSource pa + + + diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index bf46e58ea..1417f417b 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -1034,4 +1034,7 @@ Tervetuloa K-9 Mail asennukseen.  K-9 on avoimen lähdekoodin sähköpostiasiak + + + diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index ddafeafcb..111a5ab19 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -1037,4 +1037,7 @@ Benvido á Configuración de K-9. K-9 é un cliente de correo OpenSource para An A conta \"%s\" non está dispoñible; verifica o almacenamento + + + diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index e4b8dbb9a..f6ed42781 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -1041,4 +1041,7 @@ Benvenuto nella configurazione della posta di K-9. K-9 è un client di posta ope + + + diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index fbbd28747..32aed4154 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -1037,4 +1037,7 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge + + + diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 330e0ad55..6cd8251f9 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -1049,4 +1049,7 @@ Witaj w K-9 Mail, darmowym programie pocztowym dla systemu Android. Najistotniej Konto \"%s\" jest niedostępne; sprawdź pamięc + + + diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 985402e68..f14f57657 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -1034,4 +1034,7 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código + + + diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 385ba22fe..ced8e0123 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -1031,4 +1031,7 @@ + + + diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index fe28f9f1c..afbcbd5d4 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -1040,4 +1040,7 @@ Välkommen till installationen av K-9 E-post. K-9 är en e-postklient med öppen + + + diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index c431f76dd..645aa8ff7 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -1021,4 +1021,7 @@ + + + From 50b6d621699265f450c638989e00fe4501186962 Mon Sep 17 00:00:00 2001 From: jmccabe Date: Thu, 5 May 2011 00:10:50 +0800 Subject: [PATCH 056/121] Refactor of showFileBrowserActivity to add a couple of extra options to the list of possible file browser intents (ES File Explorer and Blackmoon File Browser) and simplify possible future updates. --- src/com/fsck/k9/helper/FileBrowserHelper.java | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/com/fsck/k9/helper/FileBrowserHelper.java b/src/com/fsck/k9/helper/FileBrowserHelper.java index caf7f55cc..3293a80d0 100644 --- a/src/com/fsck/k9/helper/FileBrowserHelper.java +++ b/src/com/fsck/k9/helper/FileBrowserHelper.java @@ -48,7 +48,7 @@ public class FileBrowserHelper { /** * tries to open known filebrowsers. * If no filebrowser is found and fallback textdialog is shown - * @param c the context as activty + * @param c the context as activity * @param startPath: the default value, where the filebrowser will start. * if startPath = null => the default path is used * @param requestcode: the int you will get as requestcode in onActivityResult @@ -62,27 +62,41 @@ public class FileBrowserHelper { * */ public boolean showFileBrowserActivity(Activity c, File startPath, int requestcode, FileBrowserFailOverCallback callback) { - boolean success = false; - Intent intent = new Intent("org.openintents.action.PICK_DIRECTORY"); - if (startPath == null) - startPath = new File(K9.getAttachmentDefaultPath()); - if (startPath != null) - intent.setData(Uri.fromFile(startPath)); + // A string array that specifies the name of the intent to use, and + // the scheme to use with it when setting the data for the intent. + String[][] intentDetails = + { { "org.openintents.action.PICK_DIRECTORY", "file://" }, // OI File Manager (maybe others) + { "com.androidworkz.action.PICK_DIRECTORY", "file://" }, // SystemExplorer + { "com.estrongs.action.PICK_DIRECTORY", "file://" }, // ES File Explorer + { Intent.ACTION_PICK, "folder://" } }; // Blackmoon File Browser (maybe others) - try { - c.startActivityForResult(intent, requestcode); - success = true; - } catch (ActivityNotFoundException e) { - try { - intent = new Intent("com.androidworkz.action.PICK_DIRECTORY"); + boolean success = false; + + if (startPath == null) { + startPath = new File(K9.getAttachmentDefaultPath()); + } + + int listIndex = 0; + do { + Intent intent = new Intent(intentDetails[listIndex][0]); + if (startPath != null) { + intent.setData(Uri.parse(intentDetails[listIndex][1] + startPath.getPath())); + } + try { c.startActivityForResult(intent, requestcode); success = true; - } catch (ActivityNotFoundException ee) { - //No Filebrowser is installed => show an fallback textdialog - showPathTextInput(c, startPath, callback); - return false; - } + } catch (ActivityNotFoundException e) { + // Try the next intent in the list + listIndex++; + }; + } while (!success && (listIndex < intentDetails.length)); + + if (listIndex == intentDetails.length) { + //No Filebrowser is installed => show a fallback textdialog + showPathTextInput(c, startPath, callback); + success = false; } + return success; } From 837b7da2067720519b9813017a62b5a0b85a5817 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 5 May 2011 02:36:15 +0200 Subject: [PATCH 057/121] Changed order of pick directory intents --- src/com/fsck/k9/helper/FileBrowserHelper.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/com/fsck/k9/helper/FileBrowserHelper.java b/src/com/fsck/k9/helper/FileBrowserHelper.java index 3293a80d0..f5ea6c4f8 100644 --- a/src/com/fsck/k9/helper/FileBrowserHelper.java +++ b/src/com/fsck/k9/helper/FileBrowserHelper.java @@ -62,13 +62,13 @@ public class FileBrowserHelper { * */ public boolean showFileBrowserActivity(Activity c, File startPath, int requestcode, FileBrowserFailOverCallback callback) { - // A string array that specifies the name of the intent to use, and - // the scheme to use with it when setting the data for the intent. - String[][] intentDetails = - { { "org.openintents.action.PICK_DIRECTORY", "file://" }, // OI File Manager (maybe others) - { "com.androidworkz.action.PICK_DIRECTORY", "file://" }, // SystemExplorer - { "com.estrongs.action.PICK_DIRECTORY", "file://" }, // ES File Explorer - { Intent.ACTION_PICK, "folder://" } }; // Blackmoon File Browser (maybe others) + // A string array that specifies the name of the intent to use, and + // the scheme to use with it when setting the data for the intent. + String[][] intentDetails = + { { "org.openintents.action.PICK_DIRECTORY", "file://" }, // OI File Manager (maybe others) + { "com.estrongs.action.PICK_DIRECTORY", "file://" }, // ES File Explorer + { Intent.ACTION_PICK, "folder://" }, // Blackmoon File Browser (maybe others) + { "com.androidworkz.action.PICK_DIRECTORY", "file://" }}; // SystemExplorer boolean success = false; From 141e2d2ad91c89ecad67c45dd587bca9ac96ae77 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 5 May 2011 02:52:47 +0200 Subject: [PATCH 058/121] Make the "pick directory intent" array a constant --- src/com/fsck/k9/helper/FileBrowserHelper.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/com/fsck/k9/helper/FileBrowserHelper.java b/src/com/fsck/k9/helper/FileBrowserHelper.java index f5ea6c4f8..2ef2c78e9 100644 --- a/src/com/fsck/k9/helper/FileBrowserHelper.java +++ b/src/com/fsck/k9/helper/FileBrowserHelper.java @@ -15,6 +15,16 @@ import com.fsck.k9.K9; import com.fsck.k9.R; public class FileBrowserHelper { + /** + * A string array that specifies the name of the intent to use, and the scheme to use with it + * when setting the data for the intent. + */ + private static final String[][] PICK_DIRECTORY_INTENTS = + { { "org.openintents.action.PICK_DIRECTORY", "file://" }, // OI File Manager (maybe others) + { "com.estrongs.action.PICK_DIRECTORY", "file://" }, // ES File Explorer + { Intent.ACTION_PICK, "folder://" }, // Blackmoon File Browser (maybe others) + { "com.androidworkz.action.PICK_DIRECTORY", "file://" }}; // SystemExplorer + private static FileBrowserHelper sInstance; /** @@ -62,14 +72,6 @@ public class FileBrowserHelper { * */ public boolean showFileBrowserActivity(Activity c, File startPath, int requestcode, FileBrowserFailOverCallback callback) { - // A string array that specifies the name of the intent to use, and - // the scheme to use with it when setting the data for the intent. - String[][] intentDetails = - { { "org.openintents.action.PICK_DIRECTORY", "file://" }, // OI File Manager (maybe others) - { "com.estrongs.action.PICK_DIRECTORY", "file://" }, // ES File Explorer - { Intent.ACTION_PICK, "folder://" }, // Blackmoon File Browser (maybe others) - { "com.androidworkz.action.PICK_DIRECTORY", "file://" }}; // SystemExplorer - boolean success = false; if (startPath == null) { @@ -78,9 +80,11 @@ public class FileBrowserHelper { int listIndex = 0; do { - Intent intent = new Intent(intentDetails[listIndex][0]); + String intentAction = PICK_DIRECTORY_INTENTS[listIndex][0]; + String uriPrefix = PICK_DIRECTORY_INTENTS[listIndex][1]; + Intent intent = new Intent(intentAction); if (startPath != null) { - intent.setData(Uri.parse(intentDetails[listIndex][1] + startPath.getPath())); + intent.setData(Uri.parse(uriPrefix + startPath.getPath())); } try { c.startActivityForResult(intent, requestcode); @@ -89,9 +93,9 @@ public class FileBrowserHelper { // Try the next intent in the list listIndex++; }; - } while (!success && (listIndex < intentDetails.length)); + } while (!success && (listIndex < PICK_DIRECTORY_INTENTS.length)); - if (listIndex == intentDetails.length) { + if (listIndex == PICK_DIRECTORY_INTENTS.length) { //No Filebrowser is installed => show a fallback textdialog showPathTextInput(c, startPath, callback); success = false; From 71c5e3c611cc9482e5dcea61790bcd9183eab88c Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 5 May 2011 02:54:20 +0200 Subject: [PATCH 059/121] Remove unnecessary null pointer check --- src/com/fsck/k9/helper/FileBrowserHelper.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/com/fsck/k9/helper/FileBrowserHelper.java b/src/com/fsck/k9/helper/FileBrowserHelper.java index 2ef2c78e9..3c8634c57 100644 --- a/src/com/fsck/k9/helper/FileBrowserHelper.java +++ b/src/com/fsck/k9/helper/FileBrowserHelper.java @@ -83,9 +83,8 @@ public class FileBrowserHelper { String intentAction = PICK_DIRECTORY_INTENTS[listIndex][0]; String uriPrefix = PICK_DIRECTORY_INTENTS[listIndex][1]; Intent intent = new Intent(intentAction); - if (startPath != null) { - intent.setData(Uri.parse(uriPrefix + startPath.getPath())); - } + intent.setData(Uri.parse(uriPrefix + startPath.getPath())); + try { c.startActivityForResult(intent, requestcode); success = true; From 3fcca67ae504ee43e59492593fa9ece16fa5e415 Mon Sep 17 00:00:00 2001 From: Andrew Chen Date: Wed, 4 May 2011 23:33:22 -0700 Subject: [PATCH 060/121] Preserve legacy SMTP authentication behavior for PLAIN by trying LOGIN if supported. --- .../fsck/k9/mail/transport/SmtpTransport.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java index bb31409be..45f218191 100644 --- a/src/com/fsck/k9/mail/transport/SmtpTransport.java +++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java @@ -273,7 +273,22 @@ public class SmtpTransport extends Transport { Log.d(K9.LOG_TAG, "Using PLAIN as authentication method although the " + "server didn't advertise support for it in EHLO response."); } - saslAuthPlain(mUsername, mPassword); + try { + saslAuthPlain(mUsername, mPassword); + } catch(MessagingException ex) { + // PLAIN is a special case. Historically, PLAIN has represented both PLAIN and LOGIN; only the + // protocol being advertised by the server would be used, with PLAIN taking precedence. Instead + // of using only the requested protocol, we'll try PLAIN and then try LOGIN. + if (useAuthPlain && authLoginSupported) { + if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { + Log.d(K9.LOG_TAG, "Using legacy PLAIN authentication behavior and trying LOGIN."); + } + saslAuthLogin(mUsername, mPassword); + } else { + // If it was auto detected and failed, continue throwing the exception back up. + throw ex; + } + } } else if (useAuthLogin || (useAutomaticAuth && authLoginSupported)) { if (!authPlainSupported && K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { Log.d(K9.LOG_TAG, "Using LOGIN as authentication method although the " + From 1ea27d7020ab4f4338e52f838111cbe53fd7924e Mon Sep 17 00:00:00 2001 From: Andrew Chen Date: Thu, 5 May 2011 00:17:34 -0700 Subject: [PATCH 061/121] Issue 3105: Generate proper HTML-ified versions of text messages so that textification of the HTMLified text message preserves the original newlines. --- src/com/fsck/k9/helper/HtmlConverter.java | 48 ++++++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/com/fsck/k9/helper/HtmlConverter.java b/src/com/fsck/k9/helper/HtmlConverter.java index f4135138d..1282bd985 100644 --- a/src/com/fsck/k9/helper/HtmlConverter.java +++ b/src/com/fsck/k9/helper/HtmlConverter.java @@ -123,6 +123,43 @@ public class HtmlConverter { private static final int MAX_SMART_HTMLIFY_MESSAGE_LENGTH = 1024 * 256 ; + /** + * Naively convert a text string into an HTML document. This method avoids using regular expressions on the entire + * message body to save memory. + * @param text Plain text string. + * @return HTML string. + */ + private static String simpleTextToHtml(String text) { + // Encode HTML entities to make sure we don't display something evil. + text = TextUtils.htmlEncode(text); + + StringReader reader = new StringReader(text); + StringBuilder buff = new StringBuilder(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH); + buff.append(""); + + int c; + try { + while ((c = reader.read()) != -1) { + switch (c) { + case '\n': + buff.append("
\n"); + break; + case '\r': + break; + default: + buff.append((char)c); + }//switch + } + } catch (IOException e) { + //Should never happen + Log.e(K9.LOG_TAG, "Could not read string to convert text to HTML:", e); + } + + buff.append(""); + + return buff.toString(); + } + /** * Convert a text string into an HTML document. Attempts to do smart replacement for large * documents to prevent OOM errors. This method adds headers and footers to create a proper HTML @@ -136,11 +173,7 @@ public class HtmlConverter { // if the message is big and plain text, just do // a trivial htmlification if (text.length() > MAX_SMART_HTMLIFY_MESSAGE_LENGTH) { - return "" + - htmlifyMessageHeader() + - text + - htmlifyMessageFooter() + - ""; + return simpleTextToHtml(text); } StringReader reader = new StringReader(text); StringBuilder buff = new StringBuilder(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH); @@ -148,6 +181,9 @@ public class HtmlConverter { try { while ((c = reader.read()) != -1) { switch (c) { + case '\n': + buff.append("
\n"); + break; case '&': buff.append("&"); break; @@ -1076,7 +1112,7 @@ public class HtmlConverter { final String font = K9.messageViewFixedWidthFont() ? "monospace" : "sans-serif"; - return "
";
+        return "
";
     }
 
     private static String htmlifyMessageFooter() {

From 196a9c167de165c9d34471e8caed7120b603074d Mon Sep 17 00:00:00 2001
From: Jesse Vincent 
Date: Thu, 5 May 2011 12:47:39 -0400
Subject: [PATCH 062/121] comment some preview regexes

---
 src/com/fsck/k9/mail/store/LocalStore.java | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index 31d6c8987..7e85bae70 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -2705,13 +2705,21 @@ public class LocalStore extends Store implements Serializable {
                 text = text.substring(0, 8192);
             }
 
-
+            // try to remove lines of dashes in the preview
             text = text.replaceAll("(?m)^----.*?$", "");
+            // remove quoted text from the preview
             text = text.replaceAll("(?m)^[#>].*$", "");
+            // Remove a common quote header from the preview
             text = text.replaceAll("(?m)^On .*wrote.?$", "");
+            // Remove a more generic quote header from the preview
             text = text.replaceAll("(?m)^.*\\w+:$", "");
+
+            // URLs in the preview should just be shown as "..." - They're not
+            // clickable and they usually overwhelm the preview
             text = text.replaceAll("https?://\\S+", "...");
+            // Don't show newlines in the preview
             text = text.replaceAll("(\\r|\\n)+", " ");
+            // Collapse whitespace in the preview
             text = text.replaceAll("\\s+", " ");
             if (text.length() <= 512) {
                 return text;

From 8a907f9be74143b99b0976d041f53273f66260ec Mon Sep 17 00:00:00 2001
From: Jesse Vincent 
Date: Thu, 5 May 2011 12:47:57 -0400
Subject: [PATCH 063/121] remove a pointless extra assignment

---
 src/com/fsck/k9/mail/store/LocalStore.java | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index 7e85bae70..b2ed1069f 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -2724,8 +2724,7 @@ public class LocalStore extends Store implements Serializable {
             if (text.length() <= 512) {
                 return text;
             } else {
-                text = text.substring(0, 512);
-                return text;
+                return text.substring(0, 512);
             }
 
         }

From cfd1ad7cdbb4133566b1089261bd78f769763de9 Mon Sep 17 00:00:00 2001
From: Jesse Vincent 
Date: Thu, 5 May 2011 12:50:45 -0400
Subject: [PATCH 064/121] comment some htmlifciation regexes

---
 src/com/fsck/k9/helper/HtmlConverter.java | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/com/fsck/k9/helper/HtmlConverter.java b/src/com/fsck/k9/helper/HtmlConverter.java
index 1282bd985..5ea30e59c 100644
--- a/src/com/fsck/k9/helper/HtmlConverter.java
+++ b/src/com/fsck/k9/helper/HtmlConverter.java
@@ -204,8 +204,14 @@ public class HtmlConverter {
             Log.e(K9.LOG_TAG, "Could not read string to convert text to HTML:", e);
         }
         text = buff.toString();
+
+        // Replace lines of -,= or _ with horizontal rules
         text = text.replaceAll("\\s*([-=_]{30,}+)\\s*", "
"); + + // TODO: reverse engineer (or troll history) and document text = text.replaceAll("(?m)^([^\r\n]{4,}[\\s\\w,:;+/])(?:\r\n|\n|\r)(?=[a-z]\\S{0,10}[\\s\\n\\r])", "$1 "); + + // Compress four or more newlines down to two newlines text = text.replaceAll("(?m)(\r\n|\n|\r){4,}", "\n\n"); StringBuffer sb = new StringBuffer(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH); From 723b20a7f670f065ba1e7bede6867923a75b7c88 Mon Sep 17 00:00:00 2001 From: kris kechagia Date: Thu, 5 May 2011 21:24:11 +0200 Subject: [PATCH 065/121] removed empty, non-localized strings --- res/layout/message_compose.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml index 7d9120cde..66f0de097 100644 --- a/res/layout/message_compose.xml +++ b/res/layout/message_compose.xml @@ -152,7 +152,6 @@ Date: Thu, 5 May 2011 21:24:39 +0200 Subject: [PATCH 066/121] added libraries to Android.mk --- Android.mk | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Android.mk b/Android.mk index 5fbfacca1..a17c75e68 100644 --- a/Android.mk +++ b/Android.mk @@ -1,10 +1,33 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_STATIC_JAVA_LIBRARIES += libcore +LOCAL_STATIC_JAVA_LIBRARIES += libdom +LOCAL_STATIC_JAVA_LIBRARIES += libio +LOCAL_STATIC_JAVA_LIBRARIES += libjutf +LOCAL_STATIC_JAVA_LIBRARIES += libjzlib + LOCAL_MODULE_TAGS := eng LOCAL_SRC_FILES := $(call all-subdir-java-files) +LOCAL_SDK_VERSION := current + LOCAL_PACKAGE_NAME := Email include $(BUILD_PACKAGE) +################################################## +include $(CLEAR_VARS) + +LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += libcore:libs/apache-mime4j-core-0.7-SNAPSHOT.jar +LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += libdom:libs/apache-mime4j-dom-0.7-SNAPSHOT.jar +LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += libio:libs/commons-io-2.0.1.jar +LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += libjutf:libs/jutf7-1.0.1-SNAPSHOT.jar +LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += libjzlib:libs/jzlib-1.0.7.jar + +include $(BUILD_MULTI_PREBUILT) + + +# Use the folloing include to make our test apk. +include $(call all-makefiles-under,$(LOCAL_PATH)) + From e12dd323f8e56a0af75534919507e3860405ec7c Mon Sep 17 00:00:00 2001 From: Andrew Chen Date: Thu, 5 May 2011 13:52:28 -0700 Subject: [PATCH 067/121] Issue 3105: Drop newlines in favor of preserving multiple spaces in htmlified text bodies. --- src/com/fsck/k9/helper/HtmlConverter.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/com/fsck/k9/helper/HtmlConverter.java b/src/com/fsck/k9/helper/HtmlConverter.java index 5ea30e59c..fefa22d2c 100644 --- a/src/com/fsck/k9/helper/HtmlConverter.java +++ b/src/com/fsck/k9/helper/HtmlConverter.java @@ -142,7 +142,9 @@ public class HtmlConverter { while ((c = reader.read()) != -1) { switch (c) { case '\n': - buff.append("
\n"); + // pine treats
as two newlines, but
as one newline. Use
so our messages aren't + // doublespaced. + buff.append("
"); break; case '\r': break; @@ -182,7 +184,9 @@ public class HtmlConverter { while ((c = reader.read()) != -1) { switch (c) { case '\n': - buff.append("
\n"); + // pine treats
as two newlines, but
as one newline. Use
so our messages aren't + // doublespaced. + buff.append("
"); break; case '&': buff.append("&"); @@ -1118,7 +1122,7 @@ public class HtmlConverter { final String font = K9.messageViewFixedWidthFont() ? "monospace" : "sans-serif"; - return "
";
+        return "
";
     }
 
     private static String htmlifyMessageFooter() {

From 824c8c89bb272fd2c5733e145c84d7dc02cf9781 Mon Sep 17 00:00:00 2001
From: Jesse Vincent 
Date: Thu, 5 May 2011 23:10:33 -0400
Subject: [PATCH 068/121] 3.900 version bumping

---
 AndroidManifest.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4285bdcba..6a425013d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,8 +1,8 @@
 
 
     
Date: Thu, 5 May 2011 23:12:18 -0400
Subject: [PATCH 069/121] Bumped manifest to 3.900

---
 AndroidManifest.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6a425013d..241f78786 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,7 +1,7 @@
 
 
     
Date: Fri, 6 May 2011 20:02:55 +0200
Subject: [PATCH 070/121] Avoid NullPointerException for messages with
 html_content = NULL in DB

Fixes issue 3302
---
 src/com/fsck/k9/mail/store/LocalStore.java | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index b2ed1069f..ad487af06 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -2425,16 +2425,18 @@ public class LocalStore extends Store implements Serializable {
                                                          { Long.toString(messageId) }, null, null, null);
                                 try {
                                     if (cursor.moveToNext()) {
-                                        String new_html;
+                                        String htmlContent = cursor.getString(0);
 
-                                        new_html = cursor.getString(0);
-                                        new_html = new_html.replaceAll(Pattern.quote("cid:" + contentId),
-                                                                       contentUri.toString());
+                                        if (htmlContent != null) {
+                                            String newHtmlContent = htmlContent.replaceAll(
+                                                    Pattern.quote("cid:" + contentId),
+                                                    contentUri.toString());
 
-                                        ContentValues cv = new ContentValues();
-                                        cv.put("html_content", new_html);
-                                        db.update("messages", cv, "id = ?", new String[]
-                                                  { Long.toString(messageId) });
+                                            ContentValues cv = new ContentValues();
+                                            cv.put("html_content", newHtmlContent);
+                                            db.update("messages", cv, "id = ?", new String[]
+                                                      { Long.toString(messageId) });
+                                        }
                                     }
                                 } finally {
                                     if (cursor != null) {

From 92ea452163551a4a7bfc8a8e6316271b2f359657 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 7 May 2011 23:57:47 +0200
Subject: [PATCH 071/121] Restore hardcoded Outbox

---
 src/com/fsck/k9/Account.java                        | 10 +---------
 src/com/fsck/k9/K9.java                             | 10 +++++-----
 src/com/fsck/k9/activity/setup/AccountSettings.java |  2 +-
 src/com/fsck/k9/mail/store/WebDavStore.java         |  3 +++
 4 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java
index 9dd61ba9d..67d2b4f2f 100644
--- a/src/com/fsck/k9/Account.java
+++ b/src/com/fsck/k9/Account.java
@@ -86,7 +86,6 @@ public class Account implements BaseAccount {
     private String mTrashFolderName;
     private String mArchiveFolderName;
     private String mSpamFolderName;
-    private String mOutboxFolderName;
     private String mAutoExpandFolderName;
     private FolderMode mFolderDisplayMode;
     private FolderMode mFolderSyncMode;
@@ -255,7 +254,6 @@ public class Account implements BaseAccount {
         mTrashFolderName = prefs.getString(mUuid  + ".trashFolderName", "Trash");
         mArchiveFolderName = prefs.getString(mUuid  + ".archiveFolderName", "Archive");
         mSpamFolderName = prefs.getString(mUuid  + ".spamFolderName", "Spam");
-        mOutboxFolderName = prefs.getString(mUuid + ".outboxFolderName", "Outbox");
         mExpungePolicy = prefs.getString(mUuid  + ".expungePolicy", EXPUNGE_IMMEDIATELY);
         mSyncRemoteDeletions = prefs.getBoolean(mUuid  + ".syncRemoteDeletions", true);
 
@@ -398,7 +396,6 @@ public class Account implements BaseAccount {
         editor.remove(mUuid + ".trashFolderName");
         editor.remove(mUuid + ".archiveFolderName");
         editor.remove(mUuid + ".spamFolderName");
-        editor.remove(mUuid + ".outboxFolderName");
         editor.remove(mUuid + ".autoExpandFolderName");
         editor.remove(mUuid + ".accountNumber");
         editor.remove(mUuid + ".vibrate");
@@ -496,7 +493,6 @@ public class Account implements BaseAccount {
         editor.putString(mUuid + ".trashFolderName", mTrashFolderName);
         editor.putString(mUuid + ".archiveFolderName", mArchiveFolderName);
         editor.putString(mUuid + ".spamFolderName", mSpamFolderName);
-        editor.putString(mUuid + ".outboxFolderName", mOutboxFolderName);
         editor.putString(mUuid + ".autoExpandFolderName", mAutoExpandFolderName);
         editor.putInt(mUuid + ".accountNumber", mAccountNumber);
         editor.putString(mUuid + ".hideButtonsEnum", mScrollMessageViewButtons.name());
@@ -831,11 +827,7 @@ public class Account implements BaseAccount {
     }
 
     public synchronized String getOutboxFolderName() {
-        return mOutboxFolderName;
-    }
-
-    public synchronized void setOutboxFolderName(String outboxFolderName) {
-        mOutboxFolderName = outboxFolderName;
+        return K9.OUTBOX;
     }
 
     public synchronized String getAutoExpandFolderName() {
diff --git a/src/com/fsck/k9/K9.java b/src/com/fsck/k9/K9.java
index 8f8892522..364c5188c 100644
--- a/src/com/fsck/k9/K9.java
+++ b/src/com/fsck/k9/K9.java
@@ -144,6 +144,11 @@ public class K9 extends Application {
     public static boolean ENABLE_ERROR_FOLDER = true;
     public static String ERROR_FOLDER_NAME = "K9mail-errors";
 
+    /**
+     * This local folder is used to store messages to be sent.
+     */
+    public static final String OUTBOX = "OUTBOX";
+
 
     private static boolean mAnimations = true;
 
@@ -217,11 +222,6 @@ public class K9 extends Application {
      */
     public static final String INBOX = "INBOX";
 
-    /**
-     * This local folder is used to store messages to be sent.
-     */
-    public static final String OUTBOX = "OUTBOX";
-
     /**
      * For use when displaying that no folder is selected
      */
diff --git a/src/com/fsck/k9/activity/setup/AccountSettings.java b/src/com/fsck/k9/activity/setup/AccountSettings.java
index 69f35cb6e..3a67198fb 100644
--- a/src/com/fsck/k9/activity/setup/AccountSettings.java
+++ b/src/com/fsck/k9/activity/setup/AccountSettings.java
@@ -873,7 +873,7 @@ public class AccountSettings extends K9PreferenceActivity {
             Iterator  iter = folders.iterator();
             while (iter.hasNext()) {
                 Folder folder = iter.next();
-                if (mAccount.getOutboxFolderName() != null && mAccount.getOutboxFolderName().equalsIgnoreCase(folder.getName())) {
+                if (mAccount.getOutboxFolderName().equals(folder.getName())) {
                     iter.remove();
                 }
             }
diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
index 69d788c89..0f8714a36 100644
--- a/src/com/fsck/k9/mail/store/WebDavStore.java
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -272,9 +272,12 @@ public class WebDavStore extends Store {
         if (folderName != null)
             mAccount.setSpamFolderName(folderName);
 
+        // K-9 Mail's outbox is a special local folder and different from Exchange/WebDAV's outbox.
+        /*
         folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_OUTBOX_FOLDER));
         if (folderName != null)
             mAccount.setOutboxFolderName(folderName);
+        */
 
         folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SENT_FOLDER));
         if (folderName != null)

From f4931a3167268bafef6fdd43e62bf4a190fde5f7 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sun, 8 May 2011 02:17:23 +0200
Subject: [PATCH 072/121] Get rid of constant K9.INBOX

Use Account.getInboxFolderName() instead
---
 src/com/fsck/k9/Account.java                   | 13 +++++++++----
 src/com/fsck/k9/K9.java                        |  6 ------
 src/com/fsck/k9/activity/ActivityListener.java |  3 +--
 3 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java
index 67d2b4f2f..256a31793 100644
--- a/src/com/fsck/k9/Account.java
+++ b/src/com/fsck/k9/Account.java
@@ -33,6 +33,11 @@ import java.util.concurrent.ConcurrentHashMap;
  * and delete itself given a Preferences to work with. Each account is defined by a UUID.
  */
 public class Account implements BaseAccount {
+    /**
+     * Default value for the inbox folder (never changes for POP3 and IMAP)
+     */
+    public static final String INBOX = "INBOX";
+
     public static final String EXPUNGE_IMMEDIATELY = "EXPUNGE_IMMEDIATELY";
     public static final String EXPUNGE_MANUALLY = "EXPUNGE_MANUALLY";
     public static final String EXPUNGE_ON_POLL = "EXPUNGE_ON_POLL";
@@ -181,8 +186,8 @@ public class Account implements BaseAccount {
         mEnableMoveButtons = false;
         mIsSignatureBeforeQuotedText = false;
         mExpungePolicy = EXPUNGE_IMMEDIATELY;
-        mAutoExpandFolderName = K9.INBOX;
-        mInboxFolderName = K9.INBOX;
+        mAutoExpandFolderName = INBOX;
+        mInboxFolderName = INBOX;
         mMaxPushFolders = 10;
         mChipColor = (new Random()).nextInt(0xffffff) + 0xff000000;
         goToUnreadMessageSearch = false;
@@ -248,7 +253,7 @@ public class Account implements BaseAccount {
         mNotifySelfNewMail = prefs.getBoolean(mUuid + ".notifySelfNewMail", true);
         mNotifySync = prefs.getBoolean(mUuid + ".notifyMailCheck", false);
         mDeletePolicy = prefs.getInt(mUuid + ".deletePolicy", 0);
-        mInboxFolderName = prefs.getString(mUuid  + ".inboxFolderName", K9.INBOX);
+        mInboxFolderName = prefs.getString(mUuid  + ".inboxFolderName", INBOX);
         mDraftsFolderName = prefs.getString(mUuid  + ".draftsFolderName", "Drafts");
         mSentFolderName = prefs.getString(mUuid  + ".sentFolderName", "Sent");
         mTrashFolderName = prefs.getString(mUuid  + ".trashFolderName", "Trash");
@@ -273,7 +278,7 @@ public class Account implements BaseAccount {
             compressionMap.put(type, useCompression);
         }
 
-        mAutoExpandFolderName = prefs.getString(mUuid  + ".autoExpandFolderName", K9.INBOX);
+        mAutoExpandFolderName = prefs.getString(mUuid  + ".autoExpandFolderName", INBOX);
 
         mAccountNumber = prefs.getInt(mUuid + ".accountNumber", 0);
 
diff --git a/src/com/fsck/k9/K9.java b/src/com/fsck/k9/K9.java
index 364c5188c..84f62a054 100644
--- a/src/com/fsck/k9/K9.java
+++ b/src/com/fsck/k9/K9.java
@@ -216,12 +216,6 @@ public class K9 extends Application {
     public static final String[] UNACCEPTABLE_ATTACHMENT_DOWNLOAD_TYPES = new String[] {
     };
 
-    /**
-     * The special name "INBOX" is used throughout the application to mean "Whatever folder
-     * the server refers to as the user's Inbox. Placed here to ease use.
-     */
-    public static final String INBOX = "INBOX";
-
     /**
      * For use when displaying that no folder is selected
      */
diff --git a/src/com/fsck/k9/activity/ActivityListener.java b/src/com/fsck/k9/activity/ActivityListener.java
index 6fbfaec16..58c6eed77 100644
--- a/src/com/fsck/k9/activity/ActivityListener.java
+++ b/src/com/fsck/k9/activity/ActivityListener.java
@@ -6,7 +6,6 @@ import android.content.Context;
 
 import com.fsck.k9.Account;
 import com.fsck.k9.AccountStats;
-import com.fsck.k9.K9;
 import com.fsck.k9.R;
 import com.fsck.k9.controller.MessagingListener;
 import com.fsck.k9.service.MailService;
@@ -35,7 +34,7 @@ public class ActivityListener extends MessagingListener {
 
             if (mLoadingFolderName != null || mLoadingHeaderFolderName != null) {
                 String displayName = mLoadingFolderName;
-                if (K9.INBOX.equalsIgnoreCase(displayName)) {
+                if (mAccount.getInboxFolderName().equalsIgnoreCase(displayName)) {
                     displayName = context.getString(R.string.special_mailbox_name_inbox);
                 } else if ((mAccount != null) && mAccount.getOutboxFolderName().equals(displayName)) {
                     displayName = context.getString(R.string.special_mailbox_name_outbox);

From 8e1c4acef943efe52e24c38c9a1e8586e5f53312 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sun, 8 May 2011 02:22:38 +0200
Subject: [PATCH 073/121] Get rid of constant K9.OUTBOX

Use Account.getOutboxFolderName() instead (still hardcoded, though)
---
 src/com/fsck/k9/Account.java              | 7 ++++++-
 src/com/fsck/k9/K9.java                   | 6 ------
 src/com/fsck/k9/mail/store/ImapStore.java | 2 +-
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java
index 256a31793..7508e87cb 100644
--- a/src/com/fsck/k9/Account.java
+++ b/src/com/fsck/k9/Account.java
@@ -38,6 +38,11 @@ public class Account implements BaseAccount {
      */
     public static final String INBOX = "INBOX";
 
+    /**
+     * This local folder is used to store messages to be sent.
+     */
+    public static final String OUTBOX = "OUTBOX";
+
     public static final String EXPUNGE_IMMEDIATELY = "EXPUNGE_IMMEDIATELY";
     public static final String EXPUNGE_MANUALLY = "EXPUNGE_MANUALLY";
     public static final String EXPUNGE_ON_POLL = "EXPUNGE_ON_POLL";
@@ -832,7 +837,7 @@ public class Account implements BaseAccount {
     }
 
     public synchronized String getOutboxFolderName() {
-        return K9.OUTBOX;
+        return OUTBOX;
     }
 
     public synchronized String getAutoExpandFolderName() {
diff --git a/src/com/fsck/k9/K9.java b/src/com/fsck/k9/K9.java
index 84f62a054..0c5da2007 100644
--- a/src/com/fsck/k9/K9.java
+++ b/src/com/fsck/k9/K9.java
@@ -144,12 +144,6 @@ public class K9 extends Application {
     public static boolean ENABLE_ERROR_FOLDER = true;
     public static String ERROR_FOLDER_NAME = "K9mail-errors";
 
-    /**
-     * This local folder is used to store messages to be sent.
-     */
-    public static final String OUTBOX = "OUTBOX";
-
-
     private static boolean mAnimations = true;
 
     private static boolean mConfirmDelete = false;
diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index 4eeb3bea0..56e0f8a52 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -398,7 +398,7 @@ public class ImapStore extends Store {
 
                 if (folder.equalsIgnoreCase(mAccount.getInboxFolderName())) {
                     continue;
-                } else if (folder.equalsIgnoreCase(K9.OUTBOX)) {
+                } else if (folder.equals(mAccount.getOutboxFolderName())) {
                     /*
                      * There is a folder on the server with the same name as our local
                      * outbox. Until we have a good plan to deal with this situation

From 806e2094bcbde3525125f403087f0c340d8ae804 Mon Sep 17 00:00:00 2001
From: sunglim 
Date: Sun, 8 May 2011 12:56:40 +0900
Subject: [PATCH 074/121] strings.xml

---
 res/values-ko/strings.xml | 1038 +++++++++++++++++++++++++++++++++++++
 1 file changed, 1038 insertions(+)
 create mode 100644 res/values-ko/strings.xml

diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
new file mode 100644
index 000000000..d820e7a3f
--- /dev/null
+++ b/res/values-ko/strings.xml
@@ -0,0 +1,1038 @@
+
+
+    K-9 메일
+    K-9 메일 베타
+    Authors: %s
+    http://code.google.com/p/k9mail/wiki/ReleaseNotes
+    수정 정보: %s
+    http://code.google.com/p/k9mail/
+    K-9 메일은 아래의 서드파티 라이브러리를 이용합니다 : %s
+    Emoji 아이콘: %s
+    
+    첨부 읽기
+    K-9이 이메일의 첨부를 읽도록 합니다
+    이메일 읽기
+    K-9이 이메일을 읽도록 합니다.
+    이메일 삭제
+    K-9이 이메일을 삭제하도록 합니다
+    
+     정보 %s
+    계정
+    고급
+    %s 
+    K-9 계정
+    
+      %s:%s 
+
+    쓰기
+    디버그
+    폴더 선택
+    색 선택
+
+    %s%s%s
+
+    \u0020[%d]
+    \u0020(수신 %s:%s%s)
+    \u0020(헤더정보를 가져오는 중 %s:%s%s)
+    \u0020(보내는 중 %s%s)
+    \u0020(Proc %s:%s%s)
+    \u0020%s/%s
+
+    \u0020(다음 수신 @ %s)
+    \u0020(동기화 불가능)
+
+    
+    다음 
+    이전 
+    OK 
+    취소
+    전송
+    재전송
+    선택
+    선택 해제
+    회신
+    전체회신
+    지우기
+    보관
+    스팸
+    폴더 비우기
+    전달
+    이동
+    계속
+    완료 
+    삭제
+    버리기
+    임시 보관함에 저장
+    재시도
+    새로 읽기
+    새로고침
+    메시지 보내기
+    폴더 목록
+    폴더 다시읽기
+    모든 편지를 읽음으로 표시
+    계정 추가
+    작성
+    검색
+    검색 결과
+    설정
+    열기
+    계정 설정
+    폴더 설정
+    환경 설정
+    계정 삭제
+    예정된 작업 없애기(위험!)
+    
+    계정
+    
+    
+    읽기
+    읽은 메일로 표시
+    공유
+    발신자 선택
+
+    모든 편지를 읽음으로 표시
+    \'%s\' 폴더의 모든 메시지를 읽음으로 표시하시겠습니까?  (K-9에서 보여지지 않은 폴더의 메시지포함)
+
+    별표 붙이기
+    별표 삭제
+    복사
+    헤더 보기
+    헤더 숨기기
+    텍스트 선택
+
+    읽지 않은 메일로 표시
+    다음으로 이동
+    폴더
+    세부내용 보기/숨기기 
+    참조/숨은참조 추가
+    제목 수정
+    첨부 추가
+    첨부 추가 (이미지)
+    첨부 추가 (비디오)
+    Dump settings
+    휴지통 비우기
+    삭제(expunge)
+    로컬 메시지 삭제
+    정렬방식 선택
+    반대로 정렬
+    About
+
+    설정
+    계정 옵션
+    폴더 옵션
+
+    (제목 없음) 
+    날짜 없음
+    보낸이 없음
+    수신중
+    (수신 %s%s)
+    로딩중..\u2026
+    연결 오류
+    메시지를 찾을 수 없습니다
+    오류 
+    보내는 중 
+
+    메시지 로딩 실패
+
+    %d개 더 읽기
+
+    GB
+    MB
+    KB
+    B
+
+    
+    \"%s\" 계정이 차지하는 용량이
+    %s
+    에서
+    %s 로 줄었습니다
+    
+
+    계정 최적화(compact) \"%s\"
+    계정 비우기(clearing) \"%s\"
+    계정 재생성 \"%s\"
+
+    새 이메일
+    새 이메일 %s
+    %d 개 읽지 않음 (%s) 
+    %d 개 새 이메일 (%s) 
+    in %d accounts
+    메시지가 전송되지 않았습니다
+
+    메일 체크중: %s:%s
+    메일 체크중
+    메일 전송중: %s
+    메일 전송중
+    :
+
+    받은 메일함
+    보낸 메일함
+    
+    임시 메일함
+    휴지통
+    보낸 메일함
+    보관
+    스팸메일함
+    
+
+    %s (임시보관함)
+    %s (Trash)
+    %s (Sent)
+    %s (Archive)
+    %s (Spam)
+
+    일부 메시지를 보내는데 실패하였습니다
+    %s 폴더 자세히 보기
+    K-9에서 메시지를 보내는데 문제가 발생하였습니다.
+    하지만 문제의 특성상 K-9은 메시지가 확실히 보내졌는지 여부를 확인할 수 없습니다. 
+	수신자는 이미 메시지를 받았을 수도 있습니다.
+    \u000a\u000a발생된 문제 유형의 메시지는 보낸편지함에 별표(started) 표시되었습니다.
+    이 별표를 없애면 K-9은 메시지를 재전송을 시도할것입니다.
+	다른 발신 작업을 하기위해서는 보낸편지함을 길게 눌러 메시지 보내기를 찾으십시오.\u000A\u000a
+	%s 폴더에 실패에 대한 에러메시지가 있습니다.
+
+    K-9 알람
+    네트워크 문제로 동기화, 메일보내기가 지연되고있습니다.
+
+    더 이상 없음
+
+    
+K-9 메일 설치를 환영합니다.  K-9은 안드로이드용 오픈소스 메일 클라이언트로 표준 안드로이드 메일 클라이언트를 기반으로 하였습니다.
+\n
+\n\nK-9\'s 향상된 기능:
+\n * IMAP IDLE를 이용한 메일 푸시(PUSH)기능
+\n * 더 나은 성능
+\n * 메시지 재정리
+\n * 이메일 서명
+\n * Bcc-to-self
+\n * 폴더 구독
+\n * 모든 폴더 동기화
+\n * 회신주소 수정
+\n * 키보드 단축
+\n * 더 나은 IMAP 지원
+\n * SD 카드에 첨부파일 저장
+\n * 휴지통 비우기
+\n * 메시지 정렬
+\n * ...그리고 그 밖에
+\n
+\nK-9 메일은 다른 메일 클라이언트와 마찬가지로 대부분의 무료 hotmail 계정을 Microsoft Exchange와 연결할때 발생되는 문제로 인해 지원하지 않습니다. 
+\n
+\n 버그 리포트, 새로운 기능 그리고 질문에 대한 문의는 http://k9mail.googlecode.com/ 로 남겨주시기바랍니다.
+
+
+
+    Version: %s
+    버그 정보 기록
+    추가적인 정보를 기록합니다.
+    중요 정보 기록
+    로그에 비밀번호를 남길수도 있습니다.
+
+    안드로이드용 K-9 메일 
+
+    모든 메일
+    모든 계정의 모든 메시지
+    받은 편지함의 모든 메일 
+
+    %s:%s
+                       %s
+                       %s
+                       %s
+                       %s
+    메시지 추가 로드
+    To:%s
+    지우기
+    읽음으로 표시
+    읽지 않음으료 표시
+    별표 더하기
+    별표 지우기
+
+    받는 사람
+    참조
+    숨은 참조
+    제목
+    내용
+    -------- 원본 메시지 --------
+    제목:
+    보낸날짜:
+    보낸 사람:
+    받는 사람:
+    참조:
+    %s wrote:\n\n
+    Quoted text
+    한명 이상의 받는 사람을 입력하십시오.
+    이메일 주소를 찾을 수 없습니다.
+    일부 첨부파일을 다운로드 할 수 없습니다. 이 메시지가 보내지기 이전에 자동적으로 다운로드 됩니다.
+    다운로드 완료되지않은 일부 첨부파일을 보낼수 없습니다.
+
+
+
+    발신자: %s <%s>
+    수신자:
+    참조:
+    열기
+    저장
+    \u25BC
+    \u25B2
+    보관
+    이동
+    스팸
+    MMM dd yyyy hh:mm a
+    첨부파일이 SD카드에 %s 로 저장되었습니다.
+    첨부파일을 SD카드에 저장할 수 없습니다.
+    포함된 그림을 보기위해서는  \"그림 보기\" 버튼을 누르십시오.
+    그림 보기
+    첨부파일 가져오는 중.
+    %s에 대한 뷰어를 찾을 수 없습니다.
+
+
+    다운로드 완료 메시지
+
+    
+    모든 헤더의 다운로드 혹은 저장이 완료 되지않았습니다. Select \"Save all headers locally\" in the account\'s incoming server settings to enable this for the future.
+    모든 헤더의 다운로드 완료되었습니다. 더이상 보여줄 추가적인 헤더정보가 없습니다.
+    이 데이터베이스 혹은 메일서버에서 추가적인 헤더 정보를 가져오는데 실패.
+
+    폴더
+    새 폴더
+
+    새 폴더 이름
+
+    (Push)
+
+    이 발신자에 대한 추가작업
+
+    복사됨
+    이동됨
+    삭제됨
+    버려짐
+    임시보관함에 저장되었습니다
+    삭제 실패
+
+    About %s
+    버전: %s
+
+
+    별표 보기
+    체크된 메시지 별표하기
+    체크박스 여러게 선택하기
+    여러게 선택하기를 항상보여줍니다.
+    메시지 미리보기
+    메시지 미리보기 목록의 각 항목을 더 넓게
+    미리보기 라인
+    발신자 이름을 보여줌
+    이메일 주소를 보여주지않고 발신자 이름을 보여줌
+    주소록(Contact) 이름 보기
+    받는사람 이름을 주소록(Contact)에서 가져옵니다.
+    주소록 색표시
+    주소록(Contact) 목록에 있는 이름에 색표시 하지않음
+    주소록(Contact) 목록에 있는 이름에 색표시
+
+    고정 넓이 폰트
+    일반텍스트(Plain) 메시지를 보여줄때 고정 넓이 폰트사용
+    삭제후 목록으로
+    메시지 삭제후에 메시지 목록으로 되돌아갑니다.
+
+    동작시 행동
+    설정한 행동을 할 경우 확인창을 보여줍니다.
+    보관
+    삭제 (message view only)
+    스팸
+    모든 편지를 읽음으로 표시
+    보내기
+
+    잠긴화면에서 알림
+    화면이 잠겨있을경우 메시지 수신시 제목을 화면에 보여주지 않습니다.
+
+
+    무음 시간
+    벨소리, 부져, 플래쉬를 밤시간에 사용하지않습니다
+    무음 시작 시간
+    무음 끝나는 시간
+
+
+    계정 추가
+    이메일 계정을 입력하시오:
+    (%d개의 계정을 추가하였습니다.)
+    이메일 주소
+    %s 유효하지 않은 이메일 주소입니다.
+    %s는 이미 등록되있습니다.
+    비밀번호
+    기본 이메일로 설정
+    수동 설정
+
+    
+    계정 정보 복구\u2026
+    받기 서버 설정 확인중\u2026
+    보내기 서버 설정 확인중\u2026
+    인증중\u2026
+    계정설정 가져오기\u2026
+    완료중\u2026
+    취소중\u2026
+
+    거의 완료되었습니다!
+    계정이 설정되었습니다. 순조롭게 진행중입니다!
+    이 계정의 이름을 입력 (옵션):
+    이름 입력 (보내는 메시지에 표시 될 이름):
+
+    계정 설정완료!\n\메일을 가져오는중\u2026
+
+    계정 종류
+    계정 유형을 선택하시오.
+    POP3
+    IMAP
+    Exchange (WebDAV)
+
+    받기 서버 설정
+    아이디
+    비밀번호
+    POP3 서버
+    IMAP 서버
+    Exchange 서버
+    포트 번호
+    보안 연결
+    인증 방식
+    없음
+    SSL (유효할경우)
+    SSL (항상)
+    TLS (유효할경우)
+    TLS (항상)
+
+    메시지 삭제시
+    서버에는 메일을 삭제하지않음
+    7일 이후
+    서버에도 메일 삭제
+    서버에 읽은 메일로 표시
+
+    네트워크상에서 압축 사용:
+    Mobile
+    Wi-Fi
+    Other
+
+    헤더정보 다운로드
+    모든 메시지의 헤더정보를 로컬에 저장
+
+    외부 저장장치(SD card)
+    일반적인 내부 저장장치
+    %1$s 추가적인 내부 저장장치
+    저장 위치
+
+    삭제된 메시지를 없앰(Expunge)
+    즉시
+    수신시(poll)
+    항상 수동적으로
+
+    IMAP path prefix
+    (NAMESPACE가 이용가능할경우 자동으로 이용)
+
+    임시보관함 폴더
+    보낸 편지함 폴더
+    휴지통 폴더
+    보관 폴더
+    스팸 폴더
+
+    설정한 폴더만 보기
+    폴더 자동 펼치기
+
+    OWA 경로
+    옵션
+
+    인증 경로
+    옵션
+    Mailbox alias
+    옵션
+
+    보내기 서버 설정
+    SMTP 서버
+    포트번호
+    보안 유형
+    없음
+    SSL
+    TLS (유효할 경우)
+    TLS (항상)
+    sign-in 필요.
+    이름
+    비밀번호
+    인증 유형
+    
+    아이디 & 비밀번호
+    아이디
+    비밀번호
+    POP before SMTP
+    IMAP before SMTP
+    WebDAV (Exchange) before SMTP
+
+    잘못된 설정: %s
+
+    계정 옵션
+
+    최적화
+    편지 비우기 (위험!)
+    데이터 재생성 (Last Resort!)
+
+    폴더 수신(poll) 빈도
+    
+    하지않음
+    매 1분 마다
+    매 5분 마다
+    매 10분 마다
+    매 15분 마다
+    매 30분 마다
+    매 시간 마다
+    2시간 마다
+    3시간 마다
+    6시간 마다
+    12시간 마다
+    24시간 마다
+
+    push접속시 수신
+    이 계정의 메일에 대해 push 하도록함
+    만약 해당 계정서버가 push를 지원할경우 새로운 메시지가 있을경우 바로 보여질것입니다. 이  기능은 성능을 매우 향상시킬수 있습니다.
+    IDLE 연결을 재생(refresh)
+    매 1분 마다
+    매 2분 마다
+    매 3분 마다
+    매 6분 마다
+    매 12분 마다
+    매 24분 마다
+    매 36분 마다
+    매 48분 마다
+    매 60분 마다
+
+    보내기 기본 계정으로 사용합니다.
+    메일 도착시 알림
+    메일 확인시 알림
+
+    
+    화면에 보여질 메시지 수
+    10 메시지
+    25 메시지
+    50 메시지
+    100 메시지
+    250 메시지
+    500 메시지
+    1000 메시지
+    모든 메시지
+
+
+    서버와 동기화 되지않은 메시지를 복사하거나 이동할 수 없습니다.
+
+    설정이 완료되지 않았습니다
+    아이디 혹은 비밀번호가 틀림.\n(%s) 
+    서버에 안전하게 연결할 수 없습니다.\n(%s) 
+    서버에 연결할 수 없습니다.\n(%s) 
+    내용 수정
+    계속
+
+    고급
+    계정 설정
+    기본 계정
+    기본 계정
+    보내기 기본 계정으로 사용합니다.
+    새 메일 알림
+    동기화 알림
+    당신의 이메일 주소
+    메일 도착시 상태바에 표시
+    동기화 확인중일때 상태바에 표시
+    Show combined Inbox
+    보낸편지함 포함
+    내가 보낸 메시지에대해 알림 보기
+    읽지 않은 메일에 대해 알림
+    알림표시 가능상태일 때 읽지 않은 메일에 대해 찾습니다
+    읽지 않은 메일 수 세기
+    읽지 않은 메시지의 수를 상태바에 보여줍니다.
+
+    네비게이션 버튼을 스크롤
+    하지않음
+    키보드를 이용가능할 경우
+    항상
+
+    재정리(refile) 버튼 활성화
+    보관, 이동, 스팸 버튼을 보이기
+    재정리(refile) 보튼을 스크롤
+
+    항상 그림 보기
+    아니오
+    주소록에 등록된 경우
+    항상
+
+    메일 보내기
+
+    Reply after quoted text
+    메시지 회신시 원본 메시지를 회신메시지에 포함시킵니다.
+
+    메시지 형식
+    일반 텍스트(Plain) (이미지와 꾸밈format은 없어집니다)
+    HTML (이미지와 꾸밈format이 보존됩니다)
+
+    회신시 인용문 위치
+    Prefix (Gmail, Pine 처럼)
+    Header (Outlook, Yahoo!, Hotmail 처럼)
+
+    일반 설정
+    화면
+    메일 가져오기
+    폴더
+    메시지 목록
+    메시지 보기
+    본문 앞에
+    암호화 방법
+    OpenPGP Provider
+    없음
+    이용 불가
+    Auto-sign
+    계정의 이메일 주소를 서명키를 추측할 수 있도록 사용.
+
+    폴더 수신(poll) 빈도
+    2nd class check frequency
+
+    저장장치
+
+
+    계정 색깔
+    계정 목록과 폴더내에서 사용될 계정 색깔을 선택하시오.
+
+    알림 LED 색깔
+    이 계정에 대해 깜빡일 LED 색을 선택하시오.
+
+    로컬 폴더 용량
+
+    가져올 메시지 최대용량
+    1Kb
+    2Kb
+    4Kb
+    8Kb
+    16Kb
+    32Kb
+    64Kb
+    128Kb
+    256Kb
+    512Kb
+    1Mb
+    2Mb
+    any size (제한없음)
+
+    메시지 동기화 기간
+    모두 (제한없음)
+    오늘
+    최근 2일
+    최근 3일
+    최근 1주
+    최근 2주
+    최근 3주
+    최근 1달
+    최근 2달
+    최근 3달
+    최근 6달
+    최근 1년
+
+
+    보여질 폴더
+    모든 폴더
+    Only 1st Class folders
+    1st and 2nd Class folders
+    All except 2nd Class folders
+
+    폴링(Poll)할 폴더Poll
+    모든 폴더
+    Only 1st Class folders
+    1st and 2nd Class folders
+    All except 2nd Class folders
+    없음
+
+    푸시(Push)할 폴더
+    모든 폴더
+    Only 1st Class folders
+    1st and 2nd Class folders
+    All except 2nd Class folders
+    없음
+
+    이동/복사 메시지가 저장될 폴더
+    모든 폴더
+    Only 1st Class folders
+    1st and 2nd Class folders
+    All except 2nd Class folders
+
+    서버에서의 삭제 동기화
+    서버에서 메시지가 삭제되있을 경우 메시지를 삭제합니다
+
+    폴더 설정
+
+    첫번째 그룹에 보여짐
+    폴더 목록의 가장 위에 보여짐
+
+    폴더 디스플레이 클래스(Class)
+    없음
+    1st Class
+    2nd Class
+
+    폴더 동기화 클래스(Class)
+    없음
+    1st Class
+    2nd Class
+    Same as display class
+
+    폴더 푸시(Push) 클래스(Class)
+    없음
+    1st Class
+    2nd Class
+    동기화 클래스와 같음
+
+    받기 서버
+    메일 받기 서버 수정
+    보내기 서버
+    메일 보내기서버(SMTP) 수정
+    Add another account
+    계정 이름
+    당신의 이름
+    통지
+    메일 도착시 벨울림
+    진동
+    메일 도착시 진동
+    진동 패턴
+    기본
+    패턴 1
+    패턴 2
+    패턴 3
+    패턴 4
+    패턴 5
+    진동 반복
+    새로운 메일 벨울림
+    LED 깜빡임
+    메일 도착시 LED를 깜빡입니다.
+
+
+    서버 설정
+
+    메시지 작성 옵션
+    메시지 작성 기본값
+     기본 발신자, 숨은참조, 서명을 설정
+
+    내 정보 관리
+    Set up alternate \'From\' addresses and signatures
+
+    신원(Identities) 관리
+
+    신원(Identity) 관리
+
+    신원(Identity) 수정
+    새로운 신원(Identity)
+
+    모든 메시지를 비밀첨부 보냄
+    이 주소로 보내는 모든 메시지의 복사본을 전달합니다
+
+    수정
+    위로 이동
+    아래로 이동
+    맨위로 이동 / 기본값으로 함
+    제거
+
+    이 항목(Identity) 설명
+    (Optional)
+    이름
+    (옵션)
+    이메일 주소
+    (필수)
+    회신(reply-to) 주소
+    (옵션)
+    서명
+    (옵션)
+
+    서명 사용
+    서명
+    모든 보내는 메시지에 서명을 사용합니다
+
+    -- \nSent from my Android phone with K-9 Mail. Please excuse my brevity.
+    초기 발신자
+    발신자 선택
+    발신자 선택
+    계정을 선택하시오
+    다른 계정으로 보내기
+
+
+    신원 설정 가기 -> 새로운 신원(Identity) 생성을 위한 신원(Identity) 관리
+    신원(Identity)를 제거할 수 없습니다.
+    이메일 주소없이 신원(Identity)을 사용할 수 없습니다
+    신원(Identity) 선택과 서명 변경은 임시 저장에서 제외됩니다
+
+    오래된 메시지를 순서
+    최근 메시지 순서
+    알파벳 순서
+    알파벳 순서의 역순
+    제목의 알파벳 순서
+    제목의 알파벳 순서의 역순
+    별표(stared) 메시지를 첫번째로
+    별표아닌(unstarted) 메시지를 첫번째로
+    읽지않은 메시지를 첫번째로
+    읽은 메시지를 첫번째로
+    첨부파일이 있는 메시지를 첫번째로
+    첨부파일이 있는 메시지를 첫번째로
+
+    정렬
+    날짜
+    보낸이
+    제목
+    즐겨찾기
+    읽음/읽지않음
+    첨부
+    %s
+
+    계정 삭제
+    \"%s\" 계정이 K-9에서 삭제됩니다.
+
+    계정 재생성
+    \"%s\"의 모든 데이타가 K-9에서 삭제됩니다. 하지만 계정 설정은 보존됩니다.
+
+    계정 비우기
+    \"%s\"의 모든 메일이 K-9에서 삭제될것입니다. 하지만 계정 설정은 보존됩니다.
+
+	\"Plus\" 계정만이 이 프로그램을 POP 접근 하도록 허락합니다. 
+	올바른 이메일 주소와 비밀번호로 로그인 실패할 경우 \"Plus\" 계정을 위해 유료전환 해야 할 것입니다. 
+	웹브라우저를 통해 접근을 얻도록 하십시오	
+		
+    POP3를 이용하기위해서는 야휴 메일 설정페이지에서 POP3 이용을 설정하여야합니다.
+
+    잘못된 인증정보
+    Accept Key
+    Reject Key
+
+    Del (or D) - 삭제\u000AR -
+    회신\u000AA - 전체 회신\u000AF - 전달\u000AJ or P - Previous
+    메시지\u000AK, N - 다음 메시지\u000AM - 이동\u000AY - 복사\u000AZ - Zoom Out\u000AShift-Z -
+    Zoom In\u000aG - Star
+    Del (or D) - 삭제\u000AR -
+    회신\u000AA - 전체 회신\u000AC - 작성\u000AF - 전달\u000aM -
+    이동\u000AY - 복사\u000AG - Star\u000AO - Sort type\u000AI - 정렬 순서\u000AQ
+    - 폴더로 돌아가기\u000AS - 선택/선택해제
+
+    
+    1 - 첫 번째 클래스 폴더만 보기\u000A
+    2 - 첫 번째, 두 번째 클레스(Class)를 제외하고 모두 보기\u000A
+    3 - 두 번째 클레스(Class)를 제외하고 모두 보기\u000A
+    4 - 모든 폴더 보기\u000A
+    Q - 계정 변경\u000A
+    S - 계정 설정 변경
+
+    폴더
+    모든 폴더 표시
+    Display only 1st Class folders
+    Display 1st and 2nd Class folders
+    Display all except 2nd Class folders
+
+
+
+    서명 위치
+    본문 앞에
+    본문 뒤에
+    어두운 테마
+    밝은 테마
+    화면
+    Global
+    디버깅
+    개인정보
+    네트워크
+    상호 작용(Interaction)
+    계정 항목
+    메시지 리스트
+    메시지
+    테마
+    언어
+
+    Single-column layout
+    작은 스크린에서 HTML 메시지를 다시만듬(reformat)
+    시스템 줌 컨트롤
+    Enable zoom widgets or pinch-zoom if your device supports it
+
+
+
+    시스템 기본값
+
+    벡그라운드 동기화
+    절대 하지않음
+    항상
+    \'백그라운드 데이타\'가 선택된 경우
+    \'백그라운드 데이타\'와 \'Auto-sync\'가 선택된 경우
+
+    아무 메시지도 선택되지않음
+
+    날짜 형식
+    
+    SHORT
+    MEDIUM
+    dd-MMM-yyyy
+    yyyy-MM-dd
+
+    선택항목 일괄처리
+    삭제
+    읽음으로 표시
+    읽지 않음으로 표시
+    별표 추기
+    별표 없애기
+    보관(Archive)으로 이동
+    스팸으로 이동
+    이동(Move)
+    복사
+    별표(Star) 모드
+    선택(Select) 모드
+    일반(Plain)모드
+    모두 선택
+    선택 취소
+
+    Push 체크할 최대 폴더 수
+    10개 폴더
+    25개 폴더
+    50개 폴더
+    100개 폴더
+    250개 폴더
+    500개 폴더
+    1000개 폴더
+
+    Animation
+    Use gaudy visual effects
+    제스쳐
+    제스쳐를 이용합니다
+
+    레이아웃 최적화(Compact)
+    각 페이지에 더 많은 내용을 보여주기위해 레이아웃을 조절
+
+    볼륨키 네비게이션
+    볼륨키를 이용하여 메시지 목록의 각 항목을 넘김
+    메시지 뷰
+    다양한 리스트 뷰
+
+     \"뒤로\" 버튼 관리
+    \"뒤로\" 버튼이 항상 위로
+
+    통합 메일함으로 시작
+    통합 메일함을 시작시 보여줍니다
+
+    계정 용량을 보여줍니다
+    빠른 처리를 위해 비활성화
+
+    검색 결과 카운트
+    빠른 처리를 위해 비활성화
+
+    특정 계정 숨기기
+    통합 이메일함과 모든 편지함 숨기기
+
+    %s %s
+     - 별표 메일수
+     - 읽지않은 메일수
+
+    모든 편지
+    검색가능한 모든 편지
+
+    통합 이메일함
+    통합된 폴더의 모든 이메일
+
+    Tap envelope or star for unread or starred messages
+
+    통합
+    모든 메시지는 통합 이메일함에 보여집니다
+
+    찾을 폴더
+    모두
+    보여지는 폴더
+    없음
+
+    K-9 메일 리모콘
+    이 어플리케이션이 K-9 메일을 제어하고 설정하도록 함.
+
+    글씨 크기
+    글씨 크기 수정
+
+    계정 리스트
+    계정 이름
+    계정 정보
+
+    폴더 리스트
+    폴더 이름
+    폴더 순위(status)
+
+    메시지 목록
+    제목
+    보낸이
+    날짜
+    미리보기
+
+    메시지
+    보낸이
+    받는이
+    참조
+    추가 헤더정보
+    제목
+    시간
+    날짜
+    내용
+
+    가장 작음
+    매우 작음
+    더 작게
+    작게
+    중간
+    크게
+    더 크게
+
+    가장 작음
+    더 작게
+    보통
+    더 크게
+    가장 크게
+
+    
+    \"설정\" 확인 -> \"갤러리 버그 회피\" 갤러리 3D버그를 피해 이미지 혹은 비디오를 사용하기위함.
+
+    
+    \"첨부 추가 (이미지)\" 혹은 \"첨부 추가 (비디오)\"를 Gallery 3D를 이용해서 이미지나 비디오를 보낼수 있습니다.
+
+    기타 설정
+    갤러리 버그 회피
+    이미지/비디오 첨부를 위한 버튼을 보여줍니다.(갤러리의 3D 버그를 회피하기위함)
+
+    
+    이 작동에 대해 적절한 어플리케이션을 찾을 수 없습니다.
+    설치된 APG 버전을 지원하지 않습니다.
+    Sign
+    암호화
+    복호화
+    인증(Verify)
+    <알수없음>
+    id: %s
+    K-9 는 APG를 완벽하게 접근할 권한이 없습니다. K-9 재설치를 통해 고쳐질 수 있습니다.
+    PGP/MIME 메시지는 아직 지원하지 않습니다.
+    경고: 첨부파일이 아직 암호화 안 되었습니다
+    보내기 실패.
+
+    임시보관함에 저장하시겠습니까?
+    메시지를 저장하거나 버리하시겠습니까?
+
+    이 메시지를 보여드릴수 없습니다. charset \"%s\" 을 찾을 수 없습니다.
+
+    복사할 텍스트 선택.
+
+    삭제 확인
+    이 메시지를 삭제하시겠습니까?
+    삭제함
+    삭제하지 않음
+
+    스팸폴더로 이동 확인
+    정말 이 메시지를 스팸폴더로 옮기시겠습니까?
+    
+    아니오
+
+    첨부파일 다운로드중
+
+    디버그 로깅정보를 바탕으로 안드로이드 디버그 로깅 시스템 사용
+
+    »
+    
+    연결실패
+
+    \"%s\" 계정을 이용할 수 없습니다.; 저장장치를 확인하십시오.
+
+	첨부파일 저장위치
+	첨부파일 저장
+	파일 브라우져를 찾을 수 없습니다. 첨부파일을 저장할 경로를 입력하시오
+

From e0ef94f64b221a75643ff7436b4ce40b6dab050d Mon Sep 17 00:00:00 2001
From: Marcus Wolschon 
Date: Mon, 9 May 2011 11:21:24 +0200
Subject: [PATCH 075/121] Issue 3319:  	 unseen message count can add up to
 infinity

---
 src/com/fsck/k9/activity/MessageView.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/com/fsck/k9/activity/MessageView.java b/src/com/fsck/k9/activity/MessageView.java
index da64d2acf..eee9a9485 100644
--- a/src/com/fsck/k9/activity/MessageView.java
+++ b/src/com/fsck/k9/activity/MessageView.java
@@ -823,7 +823,7 @@ public class MessageView extends K9Activity implements OnClickListener {
 
     private void onMarkAsUnread() {
         if (mMessage != null) {
-            mController.setFlag(mAccount, mMessageReference.folderName, new String[] { mMessage.getUid() }, Flag.SEEN, false);
+// (Issue 3319)            mController.setFlag(mAccount, mMessageReference.folderName, new String[] { mMessage.getUid() }, Flag.SEEN, false);
             try {
                 mMessage.setFlag(Flag.SEEN, false);
                 mMessageView.setHeaders(mMessage, mAccount);

From 1f62b8d945105c5fab7025a8337c4131a845b8f3 Mon Sep 17 00:00:00 2001
From: sunglim 
Date: Tue, 10 May 2011 15:09:11 +0900
Subject: [PATCH 076/121] ko option

---
 res/values/arrays.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 645747228..97e8df20f 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -501,6 +501,7 @@
         zh_CN
         fi
         sv
+		ko
     
 
     

From dfa1b290e748556dd040650e8fe294ef943c2d88 Mon Sep 17 00:00:00 2001
From: sunglim 
Date: Tue, 10 May 2011 15:13:04 +0900
Subject: [PATCH 077/121] Korean Language Option

---
 res/values/arrays.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 97e8df20f..68b88c018 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -501,7 +501,7 @@
         zh_CN
         fi
         sv
-		ko
+        ko
     
 
     

From e5d952bff4e5494145914eb60b48eee081f0bb33 Mon Sep 17 00:00:00 2001
From: Andrew Chen 
Date: Tue, 10 May 2011 15:23:25 -0700
Subject: [PATCH 078/121] Save and restore the cursor position when saving or
 loading a draft.  This is the first step in making "resume composition on
 context switch" a reality.

---
 src/com/fsck/k9/activity/MessageCompose.java | 21 +++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index 0b6b39374..4b985e719 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -1139,7 +1139,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
         NAME("n"),
         EMAIL("e"),
         // TODO - store a reference to the message being replied so we can mark it at the time of send.
-        ORIGINAL_MESSAGE("m");
+        ORIGINAL_MESSAGE("m"),
+        CURSOR_POSITION("p");   // Where in the message your cursor was when you saved.
 
         private final String value;
 
@@ -1202,6 +1203,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
             uri.appendQueryParameter(IdentityField.ORIGINAL_MESSAGE.value(), mMessageReference.toIdentityString());
         }
 
+        uri.appendQueryParameter(IdentityField.CURSOR_POSITION.value(), Integer.toString(mMessageContentView.getSelectionStart()));
+
         String k9identity = IDENTITY_VERSION_1 + uri.build().getEncodedQuery();
 
         if (K9.DEBUG) {
@@ -2047,6 +2050,15 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
                     }
                 }
 
+                int cursorPosition = 0;
+                if(k9identity.containsKey(IdentityField.CURSOR_POSITION)) {
+                    try {
+                        cursorPosition = Integer.valueOf(k9identity.get(IdentityField.CURSOR_POSITION)).intValue();
+                    } catch(Exception e) {
+                        Log.e(K9.LOG_TAG, "Could not parse cursor position for MessageCompose; continuing.", e);
+                    }
+                }
+
                 mIdentity = newIdentity;
 
                 updateSignature();
@@ -2151,6 +2163,13 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
                         Log.e(K9.LOG_TAG, "Unhandled message format.");
                     }
                 }
+
+                // Set the cursor position if we have it.
+                try {
+                    mMessageContentView.setSelection(cursorPosition);
+                } catch(Exception e) {
+                    Log.e(K9.LOG_TAG, "Could not set cursor position in MessageCompose; ignoring.", e);
+                }
             }
         } catch (MessagingException me) {
             /**

From eb83cfe1b5f5155793276c6b6be1d070c354fc94 Mon Sep 17 00:00:00 2001
From: sunglim 
Date: Thu, 12 May 2011 02:57:43 +0900
Subject: [PATCH 079/121] add some Korean providers

---
 res/values-ko/strings.xml |  7 ++++++-
 res/values/strings.xml    |  5 +++++
 res/xml/providers.xml     | 27 +++++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index d820e7a3f..5ed4d832f 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -790,7 +790,12 @@ K-9 메일 설치를 환영합니다.  K-9은 안드로이드용 오픈소스 
 	웹브라우저를 통해 접근을 얻도록 하십시오	
 		
     POP3를 이용하기위해서는 야휴 메일 설정페이지에서 POP3 이용을 설정하여야합니다.
-
+   
+    IMAP/POP3를 이용하기위해서는 네이버 메일 설정페이지에서 IMAP/POP3 이용을 설정하여야합니다.
+    IMAP/POP3을 이용하기위해서는 한메일 환경설정 페이지에서 IMAP/POP3 이용을 설정하여야합니다.
+    IMAP/POP3을 이용하기위해서는 파란 메일 환경설정 페이지에서 IMAP/POP3 이용을 설정하여야합니다.
+    IMAP/POP3을 이용하기위해서는 네이트 메일 환경설정 페이지에서 IMAP/POP3 이용을 설정하여야합니다.
+    
     잘못된 인증정보
     Accept Key
     Reject Key
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4f496e6b0..fcdf3539a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -800,6 +800,11 @@ Welcome to K-9 Mail setup.  K-9 is an open source mail client for Android origin
 
     If you would like to use POP3 for this provider, You should permit to use POP3 on Yahoo mail settings page.
 
+    If you would like to use IMAP or POP3 for this provider, You should permit to use IMAP or POP3 on Naver mail settings page.
+    If you would like to use IMAP or POP3 for this provider, You should permit to use IMAP or POP3 on Hanmail(Daum) mail settings page.
+    If you would like to use IMAP or POP3 for this provider, You should permit to use IMAP or POP3 on Paran mail settings page.
+    If you would like to use IMAP or POP3 for this provider, You should permit to use IMAP or POP3 on Nate mail settings page.
+    
     Unrecognized Certificate
     Accept Key
     Reject Key
diff --git a/res/xml/providers.xml b/res/xml/providers.xml
index aed1477a0..9a7ecc794 100644
--- a/res/xml/providers.xml
+++ b/res/xml/providers.xml
@@ -276,6 +276,33 @@
         
     
 
+   
+    
+        
+        
+    
+    
+        
+        
+    
+    
+        
+        
+    
+    
+        
+        
+    
+    
+        
+        
+    
+    
     
     
         

From 969e2d93fdc771a85fbf34b754eb179e303e442d Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 14 May 2011 04:53:17 +0200
Subject: [PATCH 080/121] Don't use the "owner name" as default value for the
 email name

Get rid of Contacts.getOwnerName() and associated permissions.

Fixes issue 3331
---
 AndroidManifest.xml                           | 10 +++------
 .../k9/activity/setup/AccountSetupBasics.java | 13 +++---------
 src/com/fsck/k9/helper/Contacts.java          |  7 -------
 src/com/fsck/k9/helper/ContactsSdk3_4.java    | 21 -------------------
 src/com/fsck/k9/helper/ContactsSdk5.java      | 18 ----------------
 5 files changed, 6 insertions(+), 63 deletions(-)

diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 241f78786..faf568c95 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -18,10 +18,6 @@
     
     
 
-    
-    
-    
-
     
     
 
@@ -319,7 +315,7 @@
               android:enabled="true"
               >
             
-
                 
-
diff --git a/src/com/fsck/k9/activity/setup/AccountSetupBasics.java b/src/com/fsck/k9/activity/setup/AccountSetupBasics.java
index 0bde132a1..2c31e1920 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupBasics.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupBasics.java
@@ -18,7 +18,6 @@ import android.widget.CheckBox;
 import android.widget.EditText;
 import com.fsck.k9.*;
 import com.fsck.k9.activity.K9Activity;
-import com.fsck.k9.helper.Contacts;
 import com.fsck.k9.helper.Utility;
 import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
@@ -134,17 +133,11 @@ public class AccountSetupBasics extends K9Activity
     private String getOwnerName() {
         String name = null;
         try {
-            name = Contacts.getInstance(this).getOwnerName();
+            name = getDefaultAccountName();
         } catch (Exception e) {
-            Log.e(K9.LOG_TAG, "Could not get owner name, using default account name", e);
-        }
-        if (name == null || name.length() == 0) {
-            try {
-                name = getDefaultAccountName();
-            } catch (Exception e) {
-                Log.e(K9.LOG_TAG, "Could not get default account name", e);
-            }
+            Log.e(K9.LOG_TAG, "Could not get default account name", e);
         }
+
         if (name == null) {
             name = "";
         }
diff --git a/src/com/fsck/k9/helper/Contacts.java b/src/com/fsck/k9/helper/Contacts.java
index c42b2d43d..acf97d174 100644
--- a/src/com/fsck/k9/helper/Contacts.java
+++ b/src/com/fsck/k9/helper/Contacts.java
@@ -97,13 +97,6 @@ public abstract class Contacts {
         mContentResolver = context.getContentResolver();
     }
 
-    /**
-     * Get the name of the device's owner.
-     *
-     * @return The name of the owner if available. null, otherwise.
-     */
-    public abstract String getOwnerName();
-
     /**
      * Start the activity to add information to an existing contact or add a
      * new one.
diff --git a/src/com/fsck/k9/helper/ContactsSdk3_4.java b/src/com/fsck/k9/helper/ContactsSdk3_4.java
index 5d0fbdcd2..c7addc83f 100644
--- a/src/com/fsck/k9/helper/ContactsSdk3_4.java
+++ b/src/com/fsck/k9/helper/ContactsSdk3_4.java
@@ -85,27 +85,6 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts {
         mContext.startActivity(contactIntent);
     }
 
-    @Override
-    public String getOwnerName() {
-        String name = null;
-        final Cursor c = mContentResolver.query(
-                             Uri.withAppendedPath(Contacts.People.CONTENT_URI, "owner"),
-                             new String[] {Contacts.ContactMethods.DISPLAY_NAME},
-                             null,
-                             null,
-                             null);
-
-        if (c != null) {
-            if (c.getCount() > 0) {
-                c.moveToFirst();
-                name = c.getString(0);  // owner's display name
-            }
-            c.close();
-        }
-
-        return name;
-    }
-
     @Override
     public boolean isInContacts(final String emailAddress) {
         boolean result = false;
diff --git a/src/com/fsck/k9/helper/ContactsSdk5.java b/src/com/fsck/k9/helper/ContactsSdk5.java
index 40ae2768b..b77539c88 100644
--- a/src/com/fsck/k9/helper/ContactsSdk5.java
+++ b/src/com/fsck/k9/helper/ContactsSdk5.java
@@ -1,7 +1,5 @@
 package com.fsck.k9.helper;
 
-import android.accounts.Account;
-import android.accounts.AccountManager;
 import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
@@ -87,22 +85,6 @@ public class ContactsSdk5 extends com.fsck.k9.helper.Contacts {
         mContext.startActivity(contactIntent);
     }
 
-    @Override
-    public String getOwnerName() {
-        String name = null;
-
-        // Get the name of the first account that has one.
-        Account[] accounts = AccountManager.get(mContext).getAccounts();
-        for (final Account account : accounts) {
-            if (account.name != null) {
-                name = account.name;
-                break;
-            }
-        }
-
-        return name;
-    }
-
     @Override
     public boolean isInContacts(final String emailAddress) {
         boolean result = false;

From 86fca9c1f2c9477469ffd1f753d6a70421cda59a Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 14 May 2011 21:40:21 +0200
Subject: [PATCH 081/121] POP3: Check for support of the TOP command (if CAPA
 isn't supported)

This will allow to download partial messages if the server doesn't
support the CAPA command but supports the TOP command (e.g. Hotmail).

Fixes issue 2042
---
 src/com/fsck/k9/mail/store/Pop3Store.java | 108 ++++++++++++++++------
 1 file changed, 79 insertions(+), 29 deletions(-)

diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index b9d3eae8b..e3843c568 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -43,6 +43,13 @@ public class Pop3Store extends Store {
     private HashMap mFolders = new HashMap();
     private Pop3Capabilities mCapabilities;
 
+    /**
+     * This value is {@code true} if the server supports the CAPA command but doesn't advertise
+     * support for the TOP command OR if the server doesn't support the CAPA command and we
+     * already unsuccessfully tried to use the TOP command.
+     */
+    private boolean mTopNotSupported;
+
     /**
      * pop3://user:password@server:port CONNECTION_SECURITY_NONE
      * pop3+tls://user:password@server:port CONNECTION_SECURITY_TLS_OPTIONAL
@@ -656,41 +663,67 @@ public class Pop3Store extends Store {
         }
 
         /**
-         * Fetches the body of the given message, limiting the stored data
-         * to the specified number of lines. If lines is -1 the entire message
-         * is fetched. This is implemented with RETR for lines = -1 or TOP
-         * for any other value. If the server does not support TOP it is
-         * emulated with RETR and extra lines are thrown away.
-         * @param message
-         * @param lines
+         * Fetches the body of the given message, limiting the downloaded data to the specified
+         * number of lines if possible.
+         *
+         * If lines is -1 the entire message is fetched. This is implemented with RETR for
+         * lines = -1 or TOP for any other value. If the server does not support TOP, RETR is used
+         * instead.
          */
         private void fetchBody(Pop3Message message, int lines)
         throws IOException, MessagingException {
             String response = null;
-            if (lines == -1 || !mCapabilities.top) {
+
+            // Try hard to use the TOP command if we're not asked to download the whole message.
+            if (lines != -1 && (!mTopNotSupported || mCapabilities.top)) {
+                try {
+                    if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3 && !mCapabilities.top) {
+                        Log.d(K9.LOG_TAG, "This server doesn't support the CAPA command. " +
+                                "Checking to see if the TOP command is supported nevertheless.");
+                    }
+
+                    response = executeSimpleCommand(String.format("TOP %d %d",
+                            mUidToMsgNumMap.get(message.getUid()), lines));
+
+                    // TOP command is supported. Remember this for the next time.
+                    mCapabilities.top = true;
+                } catch (Pop3ErrorResponse e) {
+                    if (mCapabilities.top) {
+                        // The TOP command should be supported but something went wrong.
+                        throw e;
+                    } else {
+                        if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3) {
+                            Log.d(K9.LOG_TAG, "The server really doesn't support the TOP " +
+                                    "command. Using RETR instead.");
+                        }
+
+                        // Don't try to use the TOP command again.
+                        mTopNotSupported = true;
+                    }
+                }
+            }
+
+            if (response == null) {
                 response = executeSimpleCommand(String.format("RETR %d",
                                                 mUidToMsgNumMap.get(message.getUid())));
-            } else {
-                response = executeSimpleCommand(String.format("TOP %d %d",
-                                                mUidToMsgNumMap.get(message.getUid()),
-                                                lines));
             }
-            if (response != null) {
-                try {
-                    message.parse(new Pop3ResponseInputStream(mIn));
-                    if (lines == -1 || !mCapabilities.top) {
-                        message.setFlag(Flag.X_DOWNLOADED_FULL, true);
-                    }
-                } catch (MessagingException me) {
-                    /*
-                     * If we're only downloading headers it's possible
-                     * we'll get a broken MIME message which we're not
-                     * real worried about. If we've downloaded the body
-                     * and can't parse it we need to let the user know.
-                     */
-                    if (lines == -1) {
-                        throw me;
-                    }
+
+            try {
+                message.parse(new Pop3ResponseInputStream(mIn));
+
+                // TODO: if we've received fewer lines than requested we also have the complete message.
+                if (lines == -1 || !mCapabilities.top) {
+                    message.setFlag(Flag.X_DOWNLOADED_FULL, true);
+                }
+            } catch (MessagingException me) {
+                /*
+                 * If we're only downloading headers it's possible
+                 * we'll get a broken MIME message which we're not
+                 * real worried about. If we've downloaded the body
+                 * and can't parse it we need to let the user know.
+                 */
+                if (lines == -1) {
+                    throw me;
                 }
             }
         }
@@ -806,6 +839,14 @@ public class Pop3Store extends Store {
                         capabilities.top = true;
                     }
                 }
+
+                if (!capabilities.top) {
+                    /*
+                     * If the CAPA command is supported but it doesn't advertise support for the
+                     * TOP command, we won't check for it manually.
+                     */
+                    mTopNotSupported = true;
+                }
             } catch (MessagingException me) {
                 /*
                  * The server may not support the CAPA command, so we just eat this Exception
@@ -838,7 +879,7 @@ public class Pop3Store extends Store {
 
                 String response = readLine();
                 if (response.length() > 1 && response.charAt(0) == '-') {
-                    throw new MessagingException(response);
+                    throw new Pop3ErrorResponse(response);
                 }
 
                 return response;
@@ -953,4 +994,13 @@ public class Pop3Store extends Store {
             return d;
         }
     }
+
+    /**
+     * Exception that is thrown if the server returns an error response.
+     */
+    static class Pop3ErrorResponse extends MessagingException {
+        public Pop3ErrorResponse(String message) {
+            super(message, true);
+        }
+    }
 }

From 92b17ec2e2dbf46d4ca6a7046096b116c887a8a7 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 14 May 2011 22:15:39 +0200
Subject: [PATCH 082/121] Hide "Show only subscribed folders" checkbox for POP3
 accounts

---
 src/com/fsck/k9/activity/setup/AccountSetupIncoming.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
index db0bbca33..520ac6f82 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
@@ -236,6 +236,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
                 findViewById(R.id.webdav_auth_path_section).setVisibility(View.GONE);
                 findViewById(R.id.compression_section).setVisibility(View.GONE);
                 findViewById(R.id.compression_label).setVisibility(View.GONE);
+                subscribedFoldersOnly.setVisibility(View.GONE);
                 mAccount.setDeletePolicy(Account.DELETE_POLICY_NEVER);
             } else if (uri.getScheme().startsWith("imap")) {
                 serverLabelView.setText(R.string.account_setup_incoming_imap_server_label);

From e90a47938484e35217cce5413c0dbec8659feffd Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 14 May 2011 22:17:15 +0200
Subject: [PATCH 083/121] Renamed member variables to match code style
 guidelines

---
 .../activity/setup/AccountSetupIncoming.java  | 36 +++++++++----------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
index 520ac6f82..1cbd7410a 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
@@ -65,10 +65,10 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
     private Button mNextButton;
     private Account mAccount;
     private boolean mMakeDefault;
-    private CheckBox compressionMobile;
-    private CheckBox compressionWifi;
-    private CheckBox compressionOther;
-    private CheckBox subscribedFoldersOnly;
+    private CheckBox mCompressionMobile;
+    private CheckBox mCompressionWifi;
+    private CheckBox mCompressionOther;
+    private CheckBox mSubscribedFoldersOnly;
 
     public static void actionIncomingSettings(Activity context, Account account, boolean makeDefault) {
         Intent i = new Intent(context, AccountSetupIncoming.class);
@@ -101,10 +101,10 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
         mWebdavAuthPathView = (EditText)findViewById(R.id.webdav_auth_path);
         mWebdavMailboxPathView = (EditText)findViewById(R.id.webdav_mailbox_path);
         mNextButton = (Button)findViewById(R.id.next);
-        compressionMobile = (CheckBox)findViewById(R.id.compression_mobile);
-        compressionWifi = (CheckBox)findViewById(R.id.compression_wifi);
-        compressionOther = (CheckBox)findViewById(R.id.compression_other);
-        subscribedFoldersOnly = (CheckBox)findViewById(R.id.subscribed_folders_only);
+        mCompressionMobile = (CheckBox)findViewById(R.id.compression_mobile);
+        mCompressionWifi = (CheckBox)findViewById(R.id.compression_wifi);
+        mCompressionOther = (CheckBox)findViewById(R.id.compression_other);
+        mSubscribedFoldersOnly = (CheckBox)findViewById(R.id.subscribed_folders_only);
 
         mNextButton.setOnClickListener(this);
 
@@ -236,7 +236,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
                 findViewById(R.id.webdav_auth_path_section).setVisibility(View.GONE);
                 findViewById(R.id.compression_section).setVisibility(View.GONE);
                 findViewById(R.id.compression_label).setVisibility(View.GONE);
-                subscribedFoldersOnly.setVisibility(View.GONE);
+                mSubscribedFoldersOnly.setVisibility(View.GONE);
                 mAccount.setDeletePolicy(Account.DELETE_POLICY_NEVER);
             } else if (uri.getScheme().startsWith("imap")) {
                 serverLabelView.setText(R.string.account_setup_incoming_imap_server_label);
@@ -267,7 +267,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
                 findViewById(R.id.account_auth_type).setVisibility(View.GONE);
                 findViewById(R.id.compression_section).setVisibility(View.GONE);
                 findViewById(R.id.compression_label).setVisibility(View.GONE);
-                subscribedFoldersOnly.setVisibility(View.GONE);
+                mSubscribedFoldersOnly.setVisibility(View.GONE);
                 if (uri.getPath() != null && uri.getPath().length() > 0) {
                     String[] pathParts = uri.getPath().split("\\|");
 
@@ -300,9 +300,9 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
                     SpinnerOption.setSpinnerOptionValue(mSecurityTypeView, i);
                 }
             }
-            compressionMobile.setChecked(mAccount.useCompression(Account.TYPE_MOBILE));
-            compressionWifi.setChecked(mAccount.useCompression(Account.TYPE_WIFI));
-            compressionOther.setChecked(mAccount.useCompression(Account.TYPE_OTHER));
+            mCompressionMobile.setChecked(mAccount.useCompression(Account.TYPE_MOBILE));
+            mCompressionWifi.setChecked(mAccount.useCompression(Account.TYPE_WIFI));
+            mCompressionOther.setChecked(mAccount.useCompression(Account.TYPE_OTHER));
 
             if (uri.getHost() != null) {
                 mServerView.setText(uri.getHost());
@@ -314,7 +314,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
                 updatePortFromSecurityType();
             }
 
-            subscribedFoldersOnly.setChecked(mAccount.subscribedFoldersOnly());
+            mSubscribedFoldersOnly.setChecked(mAccount.subscribedFoldersOnly());
 
             validateFields();
         } catch (Exception e) {
@@ -426,10 +426,10 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
             mAccount.setStoreUri(uri.toString());
 
 
-            mAccount.setCompression(Account.TYPE_MOBILE, compressionMobile.isChecked());
-            mAccount.setCompression(Account.TYPE_WIFI, compressionWifi.isChecked());
-            mAccount.setCompression(Account.TYPE_OTHER, compressionOther.isChecked());
-            mAccount.setSubscribedFoldersOnly(subscribedFoldersOnly.isChecked());
+            mAccount.setCompression(Account.TYPE_MOBILE, mCompressionMobile.isChecked());
+            mAccount.setCompression(Account.TYPE_WIFI, mCompressionWifi.isChecked());
+            mAccount.setCompression(Account.TYPE_OTHER, mCompressionOther.isChecked());
+            mAccount.setSubscribedFoldersOnly(mSubscribedFoldersOnly.isChecked());
 
             AccountSetupCheckSettings.actionCheckSettings(this, mAccount, true, false);
         } catch (Exception e) {

From ba9bc2f8e92ee143504e993e965da020dea2f492 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 14 May 2011 23:19:24 +0200
Subject: [PATCH 084/121] Added method Folder.isFlagSupported(Flag)

---
 src/com/fsck/k9/controller/MessagingController.java | 11 ++---------
 src/com/fsck/k9/mail/Folder.java                    |  6 +++++-
 src/com/fsck/k9/mail/store/Pop3Store.java           |  5 +++++
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index e05654b1c..cc408d051 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -2174,14 +2174,7 @@ public class MessagingController implements Runnable {
 
         Store remoteStore = account.getRemoteStore();
         Folder remoteFolder = remoteStore.getFolder(folder);
-        if (!remoteFolder.exists() ||
-                /*
-                 * Don't proceed if the remote folder doesn't support flags and
-                 * the flag to be changed isn't the deleted flag. This avoids
-                 * unnecessary connections to POP3 servers.
-                 */
-                // TODO: This should actually call a supportsSettingFlag(flag) method.
-                (!remoteFolder.supportsFetchingFlags() && !Flag.DELETED.equals(flag))) {
+        if (!remoteFolder.exists() || !remoteFolder.isFlagSupported(flag)) {
             return;
         }
 
@@ -3982,7 +3975,7 @@ public class MessagingController implements Runnable {
         Intent i = FolderList.actionHandleNotification(context, account, message.getFolder().getName());
         PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
 
-        String accountDescr = (account.getDescription() != null) ? account.getDescription() : account.getEmail(); 
+        String accountDescr = (account.getDescription() != null) ? account.getDescription() : account.getEmail();
         String accountNotice = context.getString(R.string.notification_new_one_account_fmt, unreadCount, accountDescr);
         notif.setLatestEventInfo(context, accountNotice, messageNotice, pi);
 
diff --git a/src/com/fsck/k9/mail/Folder.java b/src/com/fsck/k9/mail/Folder.java
index 7e338400b..0f5b96060 100644
--- a/src/com/fsck/k9/mail/Folder.java
+++ b/src/com/fsck/k9/mail/Folder.java
@@ -153,9 +153,13 @@ public abstract class Folder {
         return null;
     }
 
+    public boolean isFlagSupported(Flag flag) {
+        return true;
+    }
+
     public boolean supportsFetchingFlags() {
         return true;
-    }//isFlagSupported
+    }
 
     @Override
     public String toString() {
diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index e3843c568..cb5b64b01 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -891,6 +891,11 @@ public class Pop3Store extends Store {
             }
         }
 
+        @Override
+        public boolean isFlagSupported(Flag flag) {
+            return (flag == Flag.DELETED);
+        }
+
         @Override
         public boolean supportsFetchingFlags() {
             return false;

From dc96bf318635ad860c4e2595b3c68f52098ea954 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 14 May 2011 23:30:47 +0200
Subject: [PATCH 085/121] Only mark all messages as read on the server if
 that's supported

This change prevents K-9 Mail from establishing a connection to the
server when all messages are marked as read on a POP3 account.
---
 src/com/fsck/k9/controller/MessagingController.java | 2 +-
 src/com/fsck/k9/mail/store/Pop3Store.java           | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index cc408d051..da325a287 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -2378,7 +2378,7 @@ public class MessagingController implements Runnable {
             Store remoteStore = account.getRemoteStore();
             remoteFolder = remoteStore.getFolder(folder);
 
-            if (!remoteFolder.exists()) {
+            if (!remoteFolder.exists() || !remoteFolder.isFlagSupported(Flag.SEEN)) {
                 return;
             }
             remoteFolder.open(OpenMode.READ_WRITE);
diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index cb5b64b01..de40edea1 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -283,7 +283,9 @@ public class Pop3Store extends Store {
         @Override
         public void close() {
             try {
-                executeSimpleCommand("QUIT");
+                if (isOpen()) {
+                    executeSimpleCommand("QUIT");
+                }
             } catch (Exception e) {
                 /*
                  * QUIT may fail if the connection is already closed. We don't care. It's just

From 95288b37d7b060173db89b7b171eb648ff482400 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 14 May 2011 23:46:26 +0200
Subject: [PATCH 086/121] Removed unnecessary method implementation

Make Pop3Folder.setFlags(Flag[],boolean) throw an
UnsupportedOperationException instead of calling a method that does
just that.
---
 src/com/fsck/k9/mail/store/Pop3Store.java | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index de40edea1..ee04f15d8 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -754,10 +754,8 @@ public class Pop3Store extends Store {
         }
 
         @Override
-        public void setFlags(Flag[] flags, boolean value)
-        throws MessagingException {
-            Message[] messages = getMessages(null);
-            setFlags(messages, flags, value);
+        public void setFlags(Flag[] flags, boolean value) throws MessagingException {
+            throw new UnsupportedOperationException("POP3: No setFlags(Flag[],boolean)");
         }
 
         @Override

From 41b039b691ff45b81b91fa694eb2164f5bc0abb0 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sun, 15 May 2011 16:23:53 +0200
Subject: [PATCH 087/121] Fix bug introduced with commit
 b7a6dbd9734700e3eacdaf1477fed14c03106e00

Fixes issue 3297
---
 src/com/fsck/k9/mail/store/ImapStore.java | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index 56e0f8a52..92d0cb778 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -377,9 +377,9 @@ public class ImapStore extends Store {
             if (ImapResponseParser.equalsIgnoreCase(response.get(0), commandResponse)) {
                 boolean includeFolder = true;
 
-                String folder;
+                String decodedFolderName;
                 try {
-                    folder = decodeFolderName(response.getString(3));
+                    decodedFolderName = decodeFolderName(response.getString(3));
                 } catch (CharacterCodingException e) {
                     Log.w(K9.LOG_TAG, "Folder name not correctly encoded with the UTF-7 variant " +
                             "as defined by RFC 3501: " + response.getString(3), e);
@@ -391,6 +391,8 @@ public class ImapStore extends Store {
                     continue;
                 }
 
+                String folder = decodedFolderName;
+
                 if (mPathDelimeter == null) {
                     mPathDelimeter = response.getString(2);
                     mCombinedPrefix = null;
@@ -406,12 +408,13 @@ public class ImapStore extends Store {
                      */
                     continue;
                 } else {
-
-                    if (getCombinedPrefix().length() > 0) {
-                        if (folder.length() >= getCombinedPrefix().length()) {
-                            folder = folder.substring(getCombinedPrefix().length());
+                    int prefixLength = getCombinedPrefix().length();
+                    if (prefixLength > 0) {
+                        // Strip prefix from the folder name
+                        if (folder.length() >= prefixLength) {
+                            folder = folder.substring(prefixLength);
                         }
-                        if (!folder.equalsIgnoreCase(getCombinedPrefix() + folder)) {
+                        if (!decodedFolderName.equalsIgnoreCase(getCombinedPrefix() + folder)) {
                             includeFolder = false;
                         }
                     }

From 8fc714ac4ae5203298bc88ded6112d8ddf686b22 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Mon, 16 May 2011 00:36:46 +0200
Subject: [PATCH 088/121] Don't show "null" for partially downloaded messages
 with empty text body

---
 src/com/fsck/k9/mail/store/LocalStore.java | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index ad487af06..c0607cd39 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -2074,6 +2074,15 @@ public class LocalStore extends Store implements Serializable {
                                 for (Part viewable : viewables) {
                                     try {
                                         String text = MimeUtility.getTextFromPart(viewable);
+
+                                        /*
+                                         * Small hack to make sure the string "null" doesn't end up
+                                         * in one of the StringBuffers.
+                                         */
+                                        if (text == null) {
+                                            text = "";
+                                        }
+
                                         /*
                                          * Anything with MIME type text/html will be stored as such. Anything
                                          * else will be stored as text/plain.
@@ -2179,6 +2188,15 @@ public class LocalStore extends Store implements Serializable {
                                 Part viewable = viewables.get(i);
                                 try {
                                     String text = MimeUtility.getTextFromPart(viewable);
+
+                                    /*
+                                     * Small hack to make sure the string "null" doesn't end up
+                                     * in one of the StringBuffers.
+                                     */
+                                    if (text == null) {
+                                        text = "";
+                                    }
+
                                     /*
                                      * Anything with MIME type text/html will be stored as such. Anything
                                      * else will be stored as text/plain.

From 2311e688f09793dccab208cc561135495e5c7726 Mon Sep 17 00:00:00 2001
From: Marcus Wolschon 
Date: Tue, 17 May 2011 09:16:42 +0200
Subject: [PATCH 089/121] changed German translation for batch-ops. *
 "Mehrfachauswahl" was confusing and suggesting some kind of selection-mode *
 menu-texts for the individual batch-ops didn't even fit the screen.

---
 res/values-de/strings.xml | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 7003a790f..822e172ab 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -869,16 +869,16 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
     dd.MMM yyyy
     yyyy-MM-dd
 
-    Mehrfachauswahl
-    Ausgewählte löschen
-    Ausgewählte als gelesen markieren
-    Ausgewählte als ungelesen markieren
-    Ausgewählte als wichtig markieren
-    Markierung bei Ausgewählten entfernen
-    Ausgewählte sichern
-    Ausgewählte als Spam markieren
-    Ausgewählte verschieben
-    Ausgewählte kopieren
+    Gruppenoperationen
+    Gewählte löschen
+    Gewählte als gelesen markieren
+    Gewählte als ungelesen markieren
+    Gewählte als wichtig markieren
+    Markierung bei Gewählten entfernen
+    Gewählte sichern
+    Gewählte als Spam markieren
+    Gewählte verschieben
+    Gewählte kopieren
     Stern-Modus
     Auswahl-Modus
     Normaler Modus

From 2d7fad1fa9e2fa8a2faebf51b1bff2c906c2ac0e Mon Sep 17 00:00:00 2001
From: cketti 
Date: Thu, 19 May 2011 00:55:34 +0200
Subject: [PATCH 090/121] Use InetAddress.getCanonicalHostName() instead of
 getHostName()

This should always return a FQDN.
---
 src/com/fsck/k9/mail/transport/SmtpTransport.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java
index 45f218191..7906ca5db 100644
--- a/src/com/fsck/k9/mail/transport/SmtpTransport.java
+++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java
@@ -171,7 +171,7 @@ public class SmtpTransport extends Transport {
             executeSimpleCommand(null);
 
             InetAddress localAddress = mSocket.getLocalAddress();
-            String localHost = localAddress.getHostName();
+            String localHost = localAddress.getCanonicalHostName();
             String ipAddr = localAddress.getHostAddress();
 
             if (localHost.equals("") || localHost.equals(ipAddr) || localHost.contains("_")) {

From e6d4299c238a80081a591025b0ba663c0682fb75 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Fri, 20 May 2011 00:19:12 +0900
Subject: [PATCH 091/121] Improved Japanese translation

---
 res/values-ja/strings.xml | 44 +++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index ebf53b638..bdce1340b 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -188,13 +188,13 @@
 
     メール送信に失敗しました
     %s フォルダ詳細を確認してください
-    K-9 はメール送信中にトラブルが発生しました.
-     メッセージが送信されたかどうかについては、トラブルに応じるため不明です.
-      送信宛先は、メールを既に受信している場合があります.
-    \u000a\u000a送信済みトレイにトラブルで発生したメールを格納します.
-    フラグ解除されたメールを再送信することができます.
-    送信済みトレイを長く押下することで「メール送信」メニューを表示させて送信することができます.\u000A\u000a
-    %s フォルダには失敗したエラーメッセージが含まれています.
+    メール送信中に問題が発生しました。
+    問題の性質により、メッセージが送信されたかどうかがわかりません。
+    受信者は、そのメッセージを既に受信しているかもしれません。
+    \u000a\u000a問題が発生したメールには送信トレイにスターが付いています。
+    スターを取ることで、メールを再送することができます。
+    他のメッセージを送信するには、「メール送信」メニューを表示させるために送信トレイを長押ししてください。\u000A\u000a
+    %s フォルダにはその問題に関するエラーメッセージが含まれています。
 
     K-9 警告
     送信ネットワークのリソース不足のため同期処理中断
@@ -231,7 +231,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     拡張デバッグログ
     追加診断情報ログ
     詳細情報ログ
-    ログにパスワードが表示されるかもしれません
+    ログにパスワードが表示される
 
     K-9 for Android 
 
@@ -267,8 +267,8 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     テキスト引用
     少なくとも1つの受信者を追加する必要があります
     メールアドレスが登録されていません
-    一部の添付ファイルをダウンロードしていません.このメールが送信される前に自動的にダウンロードされます.
-    ダウンロードしていないため、一部の添付ファイルを転送することはできません.
+    一部の添付ファイルをダウンロードしていません。このメールが送信される前に自動的にダウンロードされます。
+    ダウンロードしていないため、一部の添付ファイルを転送することはできません。
 
 
 
@@ -293,9 +293,9 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     すべてダウンロード
 
     
-    一部のヘッダしか保存されていません.ヘッダをすべて保存するためには、アカウント設定の受信メールサーバ設定で「すべてのヘッダを端末に保存」をチェックしてください.
-    すべてのヘッダをダウンロードしましたが、表示すべき追加ヘッダはありませんでした.
-    追加ヘッダをデータベースまたはメールサーバから取得できませんでした.
+    一部のヘッダしか保存されていません。ヘッダをすべて保存するためには、アカウント設定の受信メールサーバ設定で「すべてのヘッダを端末に保存」をチェックしてください。
+    すべてのヘッダをダウンロードしましたが、表示すべき追加ヘッダはありませんでした。
+    追加ヘッダをデータベースまたはメールサーバから取得できませんでした。
 
     フォルダ
     新しいフォルダ
@@ -318,7 +318,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
 
 
     スターを表示
-    スターは印を付けたメッセージを示します
+    スターは印の付いたメッセージを示す
     複数選択チェックボックス
     複数選択チェックボックス常時表示
     メッセージプレビュー
@@ -333,7 +333,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     連絡先の名前の場合は色を付ける
 
     固定幅フォント
-    プレーンテキストメッセージを表示する際、固定幅フォントを利用します.
+    プレーンテキストメッセージの表示に固定幅フォントを利用
     削除後メッセージ一覧へ戻る
     メッセージの削除後、メッセージ一覧に戻る
 
@@ -350,7 +350,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
 
 
     夜間時間帯
-    夜間での各種通知や表示を抑制する時間帯を設定します.
+    夜間での各種通知や表示を抑制する時間帯を設定
     開始時刻
     終了時刻
 
@@ -491,7 +491,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
 
     プッシュ接続時の同期
     このアカウントにプッシュメールを有効化
-    メールサーバがサポートしていれば新しいメッセージは即座に表示されます.当オプションはパフォーマンスが改善もしくは低下します.
+    メールサーバがサポートしていれば新しいメッセージは即座に表示されます。当オプションはパフォーマンスが改善もしくは低下します。
     IMAP IDLE(プッシュ)接続のリフレッシュ
     1分毎
     2分毎
@@ -584,7 +584,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     なし
     利用不可
     自動署名
-    このアカウントのE-Mailアドレスから署名の鍵を自動的に決定する.
+    このアカウントのE-Mailアドレスから署名の鍵を自動的に決定する
 
     同期フォルダの同期間隔
     2nd クラス自動受信間隔
@@ -600,7 +600,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
 
     一度に表示するメール数
 
-    ダウンロードするメッセージの上限
+    ダウンロードするメッセージサイズの上限
     1Kb
     2Kb
     4Kb
@@ -841,7 +841,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     1列レイアウト
     小さい画面用にHTMLメッセージを再構成
     ズーム制御
-    デバイスが対応するならば、ズームウィジェットやピンチズームを有効にします
+    デバイスが対応するならば、ズームウィジェットやピンチズームを有効にする
 
 
 
@@ -910,10 +910,10 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     起動後に統合フォルダを表示する
 
     アカウントのサイズ表示
-    表示を速くしたい場合はチェックをはずしてください
+    表示を速くしたい場合はチェックをはずす
 
     検索結果の件数表示
-    表示を速くしたい場合はチェックをはずしてください
+    表示を速くしたい場合はチェックをはずす
 
     特殊なアカウントを隠す
     統合フォルダと全メッセージを隠す

From 6c1b1ebf322d9936901a3a8ac53d980aa88b374f Mon Sep 17 00:00:00 2001
From: cketti 
Date: Fri, 20 May 2011 23:00:48 +0200
Subject: [PATCH 092/121] Moved checks from notifyAccount() to
 shouldNotifyForMessage()

This should fix the "notification count" for cases where messages
passed the shouldNotifyForMessage() checks but not the ones in
notifyAccount().
---
 .../k9/controller/MessagingController.java    | 64 +++++++++----------
 1 file changed, 31 insertions(+), 33 deletions(-)

diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index da325a287..c18579b32 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -3859,16 +3859,29 @@ public class MessagingController implements Runnable {
 
 
     private boolean shouldNotifyForMessage(Account account, LocalFolder localFolder, Message message) {
-        // Do not notify if the user does not have notifications
-        // enabled or if the message has been read
-        if (!account.isNotifyNewMail() || message.isSet(Flag.SEEN) || (account.getName() == null)) {
+        // If we don't even have an account name, don't show the notification.
+        // (This happens during initial account setup)
+        if (account.getName() == null) {
             return false;
         }
 
+        // Do not notify if the user does not have notifications enabled or if the message has
+        // been read.
+        if (!account.isNotifyNewMail() || message.isSet(Flag.SEEN)) {
+            return false;
+        }
+
+        // If the account is a POP3 account and the message is older than the oldest message we've
+        // previously seen, then don't notify about it.
+        if (account.getStoreUri().startsWith("pop3") &&
+                message.olderThan(new Date(account.getLatestOldMessageSeenTime()))) {
+            return false;
+        }
+
+        // No notification for new messages in Trash, Drafts, Spam or Sent folder.
+        // But do notify if it's the INBOX (see issue 1817).
         Folder folder = message.getFolder();
         if (folder != null) {
-            // No notification for new messages in Trash, Drafts, Spam or Sent folder.
-            // But do notify if it's the INBOX (see issue 1817).
             String folderName = folder.getName();
             if (!account.getInboxFolderName().equals(folderName) &&
                     (account.getTrashFolderName().equals(folderName)
@@ -3884,7 +3897,8 @@ public class MessagingController implements Runnable {
                 Integer messageUid = Integer.parseInt(message.getUid());
                 if (messageUid <= localFolder.getLastUid()) {
                     if (K9.DEBUG)
-                        Log.d(K9.LOG_TAG, "Message uid is " + messageUid + ", max message uid is " + localFolder.getLastUid() + ".  Skipping notification.");
+                        Log.d(K9.LOG_TAG, "Message uid is " + messageUid + ", max message uid is " +
+                                localFolder.getLastUid() + ".  Skipping notification.");
                     return false;
                 }
             } catch (NumberFormatException e) {
@@ -3892,31 +3906,22 @@ public class MessagingController implements Runnable {
             }
         }
 
-        return true;
+        // Don't notify if the sender address matches one of our identities and the user chose not
+        // to be notified for such messages.
+        if (account.isAnIdentity(message.getFrom()) && !account.isNotifySelfNewMail()) {
+            return false;
+        }
 
+        return true;
     }
 
 
 
-    /** Creates a notification of new email messages
-      * ringtone, lights, and vibration to be played
-    */
-    private boolean notifyAccount(Context context, Account account, Message message, int previousUnreadMessageCount, AtomicInteger newMessageCount) {
-        // If we don't even have an account name, don't show the notification
-        // (This happens during initial account setup)
-        //
-        if (account.getName() == null) {
-            return false;
-        }
-
-        // If the account us a POP3 account and the message is older than
-        // the oldest message we've previously seen then don't notify about it
-        if (account.getStoreUri().startsWith("pop3")) {
-            if (message.olderThan(new Date(account.getLatestOldMessageSeenTime()))) {
-                return false;
-            }
-        }
-
+    /**
+     * Creates a notification of a newly received message.
+     */
+    private void notifyAccount(Context context, Account account, Message message,
+            int previousUnreadMessageCount, AtomicInteger newMessageCount) {
 
         // If we have a message, set the notification to ": "
         StringBuilder messageNotice = new StringBuilder();
@@ -3937,19 +3942,13 @@ public class MessagingController implements Runnable {
                     }
                     // show To: if the message was sent from me
                     else {
-                        if (!account.isNotifySelfNewMail()) {
-                            return false;
-                        }
-
                         Address[] rcpts = message.getRecipients(Message.RecipientType.TO);
                         String to = rcpts.length > 0 ? rcpts[0].toFriendly().toString() : null;
                         if (to != null) {
                             messageNotice.append(String.format(context.getString(R.string.message_to_fmt), to)).append(": ").append(subject);
                         } else {
                             messageNotice.append(context.getString(R.string.general_no_sender)).append(": ").append(subject);
-
                         }
-
                     }
                 }
             }
@@ -3992,7 +3991,6 @@ public class MessagingController implements Runnable {
         configureNotification(notif, (n.shouldRing() ?  n.getRingtone() : null), (n.shouldVibrate() ? n.getVibration() : null), (n.isLed() ?  n.getLedColor()  : null), K9.NOTIFICATION_LED_BLINK_SLOW, ringAndVibrate);
 
         notifMgr.notify(account.getAccountNumber(), notif);
-        return true;
     }
 
     /**

From 4f67a6be245ef33aa52e45cdda538c611d70d5c1 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 21 May 2011 00:33:43 +0200
Subject: [PATCH 093/121] Fixed counting of new unread messages

---
 .../k9/controller/MessagingController.java    | 42 ++++++++++++++++---
 1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index c18579b32..fd4e0f7f1 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -1161,12 +1161,32 @@ public class MessagingController implements Runnable {
         }
     }
 
+    /**
+     * Fetches the messages described by inputMessages from the remote store and writes them to
+     * local storage.
+     *
+     * @param account
+     *            The account the remote store belongs to.
+     * @param remoteFolder
+     *            The remote folder to download messages from.
+     * @param localFolder
+     *            The {@link LocalFolder} instance corresponding to the remote folder.
+     * @param inputMessages
+     *            A list of messages objects that store the UIDs of which messages to download.
+     * @param flagSyncOnly
+     *            Only flags will be fetched from the remote store if this is {@code true}.
+     *
+     * @return The number of downloaded messages that are not flagged as {@link Flag#SEEN}.
+     *
+     * @throws MessagingException
+     */
     private int downloadMessages(final Account account, final Folder remoteFolder,
-                                 final LocalFolder localFolder, List inputMessages, boolean flagSyncOnly) throws MessagingException {
+                                 final LocalFolder localFolder, List inputMessages,
+                                 boolean flagSyncOnly) throws MessagingException {
+
         final Date earliestDate = account.getEarliestPollDate();
         Date downloadStarted = new Date(); // now
 
-
         if (earliestDate != null) {
             if (K9.DEBUG) {
                 Log.d(K9.LOG_TAG, "Only syncing messages after " + earliestDate);
@@ -1541,7 +1561,7 @@ public class MessagingController implements Runnable {
         remoteFolder.fetch(smallMessages.toArray(new Message[smallMessages.size()]),
         fp, new MessageRetrievalListener() {
             @Override
-            public void messageFinished(Message message, int number, int ofTotal) {
+            public void messageFinished(final Message message, int number, int ofTotal) {
                 try {
 
                     if (!shouldImportMessage(account, folder, message, progress, earliestDate)) {
@@ -1557,6 +1577,13 @@ public class MessagingController implements Runnable {
                             progress.incrementAndGet();
                         }
                     });
+
+                    // Increment the number of "new messages" if the newly downloaded message is
+                    // not marked as read.
+                    if (!localMessage.isSet(Flag.SEEN)) {
+                        newMessages.incrementAndGet();
+                    }
+
                     if (K9.DEBUG)
                         Log.v(K9.LOG_TAG, "About to notify listeners that we got a new small message "
                               + account + ":" + folder + ":" + message.getUid());
@@ -1572,7 +1599,6 @@ public class MessagingController implements Runnable {
                     // Send a notification of this message
 
                     if (shouldNotifyForMessage(account, localFolder, message)) {
-                        newMessages.incrementAndGet();
                         notifyAccount(mApplication, account, message, unreadBeforeStart, newMessages);
                     }
 
@@ -1691,6 +1717,13 @@ public class MessagingController implements Runnable {
             // Update the listener with what we've found
             progress.incrementAndGet();
             Message localMessage = localFolder.getMessage(message.getUid());
+
+            // Increment the number of "new messages" if the newly downloaded message is
+            // not marked as read.
+            if (!localMessage.isSet(Flag.SEEN)) {
+                newMessages.incrementAndGet();
+            }
+
             for (MessagingListener l : getListeners()) {
                 l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage);
                 l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
@@ -1701,7 +1734,6 @@ public class MessagingController implements Runnable {
 
             // Send a notification of this message
             if (shouldNotifyForMessage(account, localFolder, message)) {
-                newMessages.incrementAndGet();
                 notifyAccount(mApplication, account, message, unreadBeforeStart, newMessages);
             }
 

From 91a8bb78d9c7ca546b207437fb179956c09d24d0 Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 21 May 2011 05:55:21 +0200
Subject: [PATCH 094/121] Updated catalan translation (dvbotet)

---
 res/values-ca/strings.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 46b74b95e..4c8e01188 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -1001,7 +1001,7 @@ Benvingut a la configuració del K-9.  El K-9 és un client de codi obert per An
 
     
     No s’ha trobat cap aplicació idònia per a aquesta acció.
-    Versió APG instal lada no suportada.
+    Versió APG instal·lada no suportada.
     Inicia
     Encripta
     Desencripta
@@ -1040,7 +1040,7 @@ Benvingut a la configuració del K-9.  El K-9 és un client de codi obert per An
 
     Compte \"%s\" no és disponible; comprova emmagatzematge
 
-    
-    
-    
+    Desa adjunts a...
+    Desa adjunt
+    No s\'ha trobat l\'arxiu al navegador. On vols desar l\'adjunt?
 

From a97d7ff31146f1e552b22ae011f5f65beb83b026 Mon Sep 17 00:00:00 2001
From: Bernhard Redl 
Date: Sat, 21 May 2011 17:13:26 +0200
Subject: [PATCH 095/121] added new translated strings (german)

---
 res/values-de/strings.xml | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 822e172ab..ab10542f7 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -341,7 +341,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
     Archivieren
     Löschen (nur in Nachrichtenansicht)
     Spam
-    
+    Alle als gelesen markieren
     Senden
 
     Vertrauliche Benachrichtigung
@@ -1022,12 +1022,12 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
     Löschen
     Nicht löschen
 
-    
-    
-    
-    
+    als Spam markieren
+    Wollen sie die Nachricht in den Spam Ordner verschieben?
+    Ja
+    Nein
 
-    
+    Anhänge werden heruntergeladen
 
     Debug-Meldungen werden mit Hilfe des Android-Logging-Systems aufgezeichnet.
 
@@ -1037,7 +1037,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
 
     Konto \"%s\" ist nicht verfügbar; Bitte SD-Karte prüfen.
 
-    
-    
-    
+    Anhang speichern unter...
+    Anhang abspeichern
+    Keine Filebrowser App installiert, wo soll der Anhang abgelegt werden?
 

From 072620e4fac804f670d30b37194bf3698b22f5ba Mon Sep 17 00:00:00 2001
From: cketti 
Date: Sat, 21 May 2011 18:04:23 +0200
Subject: [PATCH 096/121] Modified german translation

---
 res/values-de/strings.xml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index ab10542f7..16f6b4c40 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -688,7 +688,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
     Eine weiteres Konto hinzufügen
     Kontoname
     Ihr Name
-    Benachrichtigungseinstellungen
+    Benachrichtigungen
     Klingeln bei neuer Nachricht
     Vibration
     Vibration bei neuer Nachricht
@@ -1022,12 +1022,12 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
     Löschen
     Nicht löschen
 
-    als Spam markieren
-    Wollen sie die Nachricht in den Spam Ordner verschieben?
+    Als Spam markieren
+    Wollen Sie diese Nachricht in den Spam-Ordner verschieben?
     Ja
     Nein
 
-    Anhänge werden heruntergeladen
+    Anhang wird heruntergeladen
 
     Debug-Meldungen werden mit Hilfe des Android-Logging-Systems aufgezeichnet.
 
@@ -1038,6 +1038,6 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
     Konto \"%s\" ist nicht verfügbar; Bitte SD-Karte prüfen.
 
     Anhang speichern unter...
-    Anhang abspeichern
-    Keine Filebrowser App installiert, wo soll der Anhang abgelegt werden?
+    Anhang speichern
+    Es wurde kein Dateimanager gefunden. Wo soll der Anhang abgelegt werden?
 

From 5d6df85aac5a9ded0579f4bfd7dfee56dde8ec95 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Wed, 11 May 2011 00:54:17 +0900
Subject: [PATCH 097/121] possible to toggle to display the quoted message to
 send.

---
 res/layout/message_compose.xml               |  10 +
 src/com/fsck/k9/activity/MessageCompose.java | 277 ++++++++++---------
 2 files changed, 160 insertions(+), 127 deletions(-)

diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml
index 66f0de097..bc8d89d39 100644
--- a/res/layout/message_compose.xml
+++ b/res/layout/message_compose.xml
@@ -237,6 +237,16 @@
                 android:textColor="@android:color/primary_text_light"
                 android:textAppearance="?android:attr/textAppearanceMedium" />
 
+            
+
             
              0) {
-                                mQuotedHtmlContent = new InsertableHtmlContent();
-                                mQuotedHtmlContent.setQuotedContent(quotedHTML);
-                                mQuotedHtmlContent.setHeaderInsertionPoint(bodyOffset);
-                                mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
-                                mQuotedHTML.setVisibility(View.VISIBLE);
-                                mQuotedTextBar.setVisibility(View.VISIBLE);
-                                mQuotedTextEdit.setVisibility(View.VISIBLE);
-                            }
+                        // Regenerate the quoted html without our user content in it.
+                        StringBuilder quotedHTML = new StringBuilder();
+                        quotedHTML.append(text.substring(0, bodyOffset));   // stuff before the reply
+                        quotedHTML.append(text.substring(bodyOffset + bodyLength));
+                        if (quotedHTML.length() > 0) {
+                            mQuotedHtmlContent = new InsertableHtmlContent();
+                            mQuotedHtmlContent.setQuotedContent(quotedHTML);
+                            mQuotedHtmlContent.setHeaderInsertionPoint(bodyOffset);
+                            mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
                         }
                     }
                 } else if (mMessageFormat == MessageFormat.TEXT) {
-                    MessageFormat format = k9identity.get(IdentityField.MESSAGE_FORMAT) != null
-                                           ? MessageFormat.valueOf(k9identity.get(IdentityField.MESSAGE_FORMAT))
-                                           : null;
-                    if (format == null) {
-                        mMessageContentView.setText(getBodyTextFromMessage(message, MessageFormat.TEXT));
-                    } else if (format.equals(MessageFormat.HTML)) {
-                        // We are in text mode, but have an HTML message.
-                        Part htmlPart = MimeUtility.findFirstPartByMimeType(message, "text/html");
-                        if (htmlPart != null) { // Shouldn't happen if we were the one who saved it.
-                            String text = MimeUtility.getTextFromPart(htmlPart);
-                            if (K9.DEBUG) {
-                                Log.d(K9.LOG_TAG, "Loading message with offset " + bodyOffset + ", length " + bodyLength + ". Text length is " + text.length() + ".");
-                            }
+                    Part textPart = MimeUtility.findFirstPartByMimeType(message, "text/plain");
+                    if (textPart != null) {
+                        String text = MimeUtility.getTextFromPart(textPart);
+                        // If we had a body length (and it was valid), separate the composition from the quoted text
+                        // and put them in their respective places in the UI.
+                        if (bodyLength != null && bodyLength + 1 < text.length()) { // + 1 to get rid of the newline we added when saving the draft
+                            String bodyText = text.substring(0, bodyLength);
+                            String quotedText = text.substring(bodyLength + 1, text.length());
 
-                            // Grab our reply text.
-                            String bodyText = text.substring(bodyOffset, bodyOffset + bodyLength);
-                            mMessageContentView.setText(Html.fromHtml(bodyText).toString());
-
-                            // Regenerate the quoted html without out content in it.
-                            StringBuilder quotedHTML = new StringBuilder();
-                            quotedHTML.append(text.substring(0, bodyOffset));   // stuff before the reply
-                            quotedHTML.append(text.substring(bodyOffset + bodyLength));
-                            // Convert it to text.
-                            mQuotedText.setText(HtmlConverter.htmlToText(quotedHTML.toString()));
-
-                            mQuotedTextBar.setVisibility(View.VISIBLE);
-                            mQuotedText.setVisibility(View.VISIBLE);
+                            mMessageContentView.setText(bodyText);
+                            mQuotedText.setText(quotedText);
                         } else {
-                            Log.e(K9.LOG_TAG, "Found an HTML draft but couldn't find the HTML part!  Something's wrong.");
+                            mMessageContentView.setText(text);
                         }
-                    } else if (format.equals(MessageFormat.TEXT)) {
-                        Part textPart = MimeUtility.findFirstPartByMimeType(message, "text/plain");
-                        if (textPart != null) {
-                            String text = MimeUtility.getTextFromPart(textPart);
-                            // If we had a body length (and it was valid), separate the composition from the quoted text
-                            // and put them in their respective places in the UI.
-                            if (bodyLength != null && bodyLength + 1 < text.length()) { // + 1 to get rid of the newline we added when saving the draft
-                                String bodyText = text.substring(0, bodyLength);
-                                String quotedText = text.substring(bodyLength + 1, text.length());
-
-                                mMessageContentView.setText(bodyText);
-                                mQuotedText.setText(quotedText);
-
-                                mQuotedTextBar.setVisibility(View.VISIBLE);
-                                mQuotedText.setVisibility(View.VISIBLE);
-                                mQuotedHTML.setVisibility(View.VISIBLE);
-                            } else {
-                                mMessageContentView.setText(text);
-                            }
-                        }
-                    } else {
-                        Log.e(K9.LOG_TAG, "Unhandled message format.");
                     }
+                } else {
+                    Log.e(K9.LOG_TAG, "Unhandled message format.");
                 }
 
                 // Set the cursor position if we have it.
@@ -2170,6 +2198,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
                 } catch(Exception e) {
                     Log.e(K9.LOG_TAG, "Could not set cursor position in MessageCompose; ignoring.", e);
                 }
+
+                showOrHideQuotedText(QuotedTextMode.valueOf(showQuotedTextMode));
             }
         } catch (MessagingException me) {
             /**
@@ -2178,8 +2208,10 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
              */
             Log.e(K9.LOG_TAG, "Error while processing source message: ", me);
         }
-        mSourceMessageProcessed = true;
-        mDraftNeedsSaving = false;
+        finally {
+            mSourceMessageProcessed = true;
+            mDraftNeedsSaving = false;
+        }
     }
 
     /**
@@ -2200,20 +2232,11 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
             // Load the message with the reply header.
             mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
 
-            mQuotedTextBar.setVisibility(View.VISIBLE);
-            mQuotedHTML.setVisibility(View.VISIBLE);
-            mQuotedTextEdit.setVisibility(View.VISIBLE);
-
-            mQuotedText.setVisibility(View.GONE);
+            showOrHideQuotedText(QuotedTextMode.SHOW);
         } else if (mMessageFormat == MessageFormat.TEXT) {
             mQuotedText.setText(quoteOriginalTextMessage(mSourceMessage, content, mAccount.getQuoteStyle()));
 
-            mQuotedTextBar.setVisibility(View.VISIBLE);
-            mQuotedText.setVisibility(View.VISIBLE);
-
-            mQuotedHtmlContent = null;
-            mQuotedTextEdit.setVisibility(View.GONE);
-            mQuotedHTML.setVisibility(View.GONE);
+            showOrHideQuotedText(QuotedTextMode.SHOW);
         }
     }
 
@@ -2428,7 +2451,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
                             populateUIWithQuotedMessage();
                         } catch (MessagingException e) {
                             // Hm, if we couldn't populate the UI after source reprocessing, let's just delete it?
-                            deleteQuotedText();
+                            showOrHideQuotedText(QuotedTextMode.HIDE);
                             Log.e(K9.LOG_TAG, "Could not re-process source message; deleting quoted text to be safe.", e);
                         }
                     } else {

From ce9b280746728e69a0d28f4fba240464f60b12b3 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Sun, 15 May 2011 00:15:01 +0900
Subject: [PATCH 098/121] Added account preference to display quoted text.

---
 res/values/strings.xml                             |  3 +++
 res/xml/account_settings_preferences.xml           |  7 +++++++
 src/com/fsck/k9/Account.java                       | 13 +++++++++++++
 src/com/fsck/k9/activity/MessageCompose.java       | 14 +++++++++-----
 .../fsck/k9/activity/setup/AccountSettings.java    |  6 ++++++
 5 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/res/values/strings.xml b/res/values/strings.xml
index fcdf3539a..0239bcadc 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -564,6 +564,9 @@ Welcome to K-9 Mail setup.  K-9 is an open source mail client for Android origin
 
     Sending mail
 
+    Show quoted text by default
+    When replying to messages, the original message is in your reply.
+
     Reply after quoted text
     When replying to messages, the original message will appear above your reply.
 
diff --git a/res/xml/account_settings_preferences.xml b/res/xml/account_settings_preferences.xml
index 33a29ed60..942eee150 100644
--- a/res/xml/account_settings_preferences.xml
+++ b/res/xml/account_settings_preferences.xml
@@ -239,6 +239,13 @@
             android:entries="@array/account_settings_quote_style_entries"
             android:entryValues="@array/account_settings_quote_style_values" />
 
+        
+
         
Date: Wed, 18 May 2011 00:00:16 +0900
Subject: [PATCH 099/121] Use the Button instead of the ImageButton.

---
 res/layout/message_compose.xml               | 11 ++++++-----
 res/values/strings.xml                       |  3 ++-
 src/com/fsck/k9/activity/MessageCompose.java |  5 +++--
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml
index bc8d89d39..2cafb2428 100644
--- a/res/layout/message_compose.xml
+++ b/res/layout/message_compose.xml
@@ -237,15 +237,16 @@
                 android:textColor="@android:color/primary_text_light"
                 android:textAppearance="?android:attr/textAppearanceMedium" />
 
-            
+                android:layout_alignParentRight="true" />
 
             
             No email address could be found.
     Some attachments were not downloaded. They will be downloaded automatically before this message is sent.
     Some attachments cannot be forwarded because they have not been downloaded.
-
+    Quote message
 
 
     From: %s <%s>
@@ -1052,4 +1052,5 @@ Welcome to K-9 Mail setup.  K-9 is an open source mail client for Android origin
     Save attachments to...
     Save attachment
     No file browser found. Where would you like to save this attachment?
+
 
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index ac94139db..d9ed28141 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -38,6 +38,7 @@ import android.view.View.OnFocusChangeListener;
 import android.view.Window;
 import android.webkit.WebView;
 import android.widget.AutoCompleteTextView.Validator;
+import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.EditText;
 import android.widget.ImageButton;
@@ -179,7 +180,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
     private EditText mSignatureView;
     private EditText mMessageContentView;
     private LinearLayout mAttachments;
-    private ImageButton mQuotedTextShow;
+    private Button mQuotedTextShow;
     private View mQuotedTextBar;
     private ImageButton mQuotedTextEdit;
     private ImageButton mQuotedTextDelete;
@@ -399,7 +400,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
         mMessageContentView = (EditText)findViewById(R.id.message_content);
         mMessageContentView.getInputExtras(true).putBoolean("allowEmoji", true);
         mAttachments = (LinearLayout)findViewById(R.id.attachments);
-        mQuotedTextShow = (ImageButton)findViewById(R.id.quoted_text_show);
+        mQuotedTextShow = (Button)findViewById(R.id.quoted_text_show);
         mQuotedTextBar = findViewById(R.id.quoted_text_bar);
         mQuotedTextEdit = (ImageButton)findViewById(R.id.quoted_text_edit);
         mQuotedTextDelete = (ImageButton)findViewById(R.id.quoted_text_delete);

From 54030547dba3e484392efffc6e866601a5a21965 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Sun, 22 May 2011 08:45:37 +0900
Subject: [PATCH 100/121] Improved Japanese translation

---
 res/values-ja/strings.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index bdce1340b..1547aa213 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -910,10 +910,10 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     起動後に統合フォルダを表示する
 
     アカウントのサイズ表示
-    表示を速くしたい場合はチェックをはずす
+    表示を速くしたい場合はチェックしない
 
     検索結果の件数表示
-    表示を速くしたい場合はチェックをはずす
+    表示を速くしたい場合はチェックしない
 
     特殊なアカウントを隠す
     統合フォルダと全メッセージを隠す

From dc72efdb0be709f171e9dc8fbc1fd47bdaeb1ba4 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Sun, 22 May 2011 08:49:02 +0900
Subject: [PATCH 101/121] Improved Japanese translation

---
 res/values-ja/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 1547aa213..82ee33b03 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -23,7 +23,7 @@
     アカウント一覧
     拡張機能
     %s 
-    K-9 Accounts
+    K-9 アカウント
 
     %s:%s 
 

From abb288ee078108c78ebd3fdc533e6f09d146d173 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Sun, 22 May 2011 08:54:51 +0900
Subject: [PATCH 102/121] Improved Japanese translation

---
 res/values-ja/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 82ee33b03..b660fcc9b 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -293,7 +293,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
     すべてダウンロード
 
     
-    一部のヘッダしか保存されていません。ヘッダをすべて保存するためには、アカウント設定の受信メールサーバ設定で「すべてのヘッダを端末に保存」をチェックしてください。
+    一部のヘッダしか保存されていません。ヘッダをすべて保存するためには、アカウント設定の受信メールサーバ設定で「ヘッダのダウンロード」をチェックしてください。
     すべてのヘッダをダウンロードしましたが、表示すべき追加ヘッダはありませんでした。
     追加ヘッダをデータベースまたはメールサーバから取得できませんでした。
 

From e894d30d54d265ed7d19cc3458735f901d278e09 Mon Sep 17 00:00:00 2001
From: Frank071 
Date: Tue, 24 May 2011 05:32:04 -0700
Subject: [PATCH 103/121] As requested by Jesse - all NEW: are translated.

---
 res/values-nl/strings.xml | 134 +++++++++++++++++++-------------------
 1 file changed, 67 insertions(+), 67 deletions(-)

diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 32aed4154..8dec642c0 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -3,14 +3,14 @@
     K-9 Mail
     K-9 Mail BETA
     Google, The K-9 Dog Walkers.
-    
-    
+    Copyright 2008-%s The K-9 Dog Walkers. Portions Copyright 2006-%s the Android Open Source Project.
+    Licensed under the Apache License, Version 2.0.
     Auteurs: %s
     http://code.google.com/p/k9mail/wiki/ReleaseNotes
     Revisie Informatie: %s
     http://code.google.com/p/k9mail/
-    
-    
+    De volgende externe bibliotheken worden gebruikt: %s
+    Emoji icons: %s
 
     Lees Email bijlage
     Sta deze applicatie toe de bijlage van emails te lezen.
@@ -42,15 +42,15 @@
     \u0020%s/%s
 
     \u0020(Volgende poll @ %s)
-    
+    \u0020(Synchroniseren uitgeschakeld)
 
     
     Volgende 
-     
+    Vorige 
     OK 
     Annuleer
     Verzenden
-    
+    Opnieuw Verzenden
     Selecteren
     Annuleer selectie
     Antwoorden
@@ -117,7 +117,7 @@
     Gooi instellingen weg
     Prullenbak legen
     Wissen
-    
+    Lokale berichten wissen
     Kies sortering
     Omgekeerd sorteren
     Over
@@ -127,7 +127,7 @@
     Map opties
 
     (Geen onderwerp) 
-    
+    Geen datum
     Geen afzender
     Polling
     (Poll %s%s)
@@ -259,14 +259,14 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Bericht tekst
     -------- Origineel bericht --------
     Subject:
-    
+    Verzonden:
     From:
     To:
     CC:
     %s wrote:\n\n
     Ge-quote tekst
     Minimaal 1 ontvanger kiezen.
-    
+    Geen email adres gevonden.
     Sommige bijlage zijn niet gedownload. Deze worden automatisch gedownload voor dat dit bericht is verzonden.
     Sommige bijlagen kunnen niet worden doorgestuurd, omdat ze niet zijn gedownload.
 
@@ -324,11 +324,11 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Laat altijd multi-selecteer selectieboxen zien
     Berichten voorbeelden
     Ruimere lijst items met bericht voorbeelden
-    
-    
-    
-    
-    
+    Preview regels
+    Toon naam bij bericht
+    Geef bij voorkeur naam van afzender/geadresseerde weer i.p.v. email adres
+    Toon naam uit contactenlijst
+    Geef de naam weer uit het adresboek
     Kleuren contacten
     Niet kleuren van namen in uw lijst met contactpersonen
     Kleuren van namen in uw lijst met contactpersonen
@@ -343,17 +343,17 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Archief
     Verwijder (alleen berichten bekijken)
     Spam
-    
+    Markeer alles als gelezen
     Verzonden
 
     Lock-screen meldingen
     Niet weergegeven onderwerp van het bericht in de notificatie bar als het systeem is vergrendeld
 
 
-    
-    
-    
-    
+    Stilteperiode
+    Schakel beltoon, vibratie en leds uit gedurende de nacht
+    Stilteperiode start
+    Stilteperiode eindigt
 
 
     Een nieuwe account instellen
@@ -370,8 +370,8 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Ophalen account informatie\u2026
     Controleren van inkomende serverinstellingen\u2026
     Controleren van uitgaande serverinstellingen\u2026
-    
-    
+    Authenticatie\u2026
+    Accountinstellingen worden opgehaald\u2026
     Afronden\u2026
     Annuleren\u2026
 
@@ -417,10 +417,10 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Downloaden van email headers
     Sla alle headers lokaal op
 
-    
-    
-    
-    
+    Externe opslag (SD kaart)
+    Reguliere interne opslag
+    %1$s extra interne opslag
+    Opslag locatie
 
     Wissen berichten
     Onmiddellijk na verwijderen of verplaatsen
@@ -517,7 +517,7 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     250 berichten
     500 berichten
     1000 berichten
-    
+    alle berichten
 
 
     Kan bericht niet kopiëren of verplaatsen omdat deze niet gesynchroniseerd is met de server
@@ -529,7 +529,7 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Aanpassen details
     Doorgaan
 
-    
+    Geavanceerd
     Algemene instellingen
     Standaard account
     Standaard account
@@ -544,8 +544,8 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Notificatie ook voor mail verzonden vanaf een identiteit
     Notificatie opent ongelezen berichten
     Zoekt voor ongelezen berichten wanneer Notificatie is geopend
-    
-    
+    Toon aantal ongelezen
+    Toon het aantal ongelezen berichten in de \'notification bar\'.
 
     Scroll navigatie knoppen
     Nooit
@@ -566,16 +566,16 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Antwoorden na quote
     Wanneer u antwoord op berichten, zal het originele bericht boven uw antwoord staan.
 
-    
-    
-    
+    Berichtopmaak
+    Platte Tekst (plaatjes en formattering worden verwijderd)
+    HTML (plaatjes en formattering blijven behouden)
 
-    
-    
-    
+    Quotestijl bij antwoorden
+    Prefix (zoals Gmail, Pine)
+    Header (zoals Outlook, Yahoo!, Hotmail)
 
-    
-    
+    Algemeen
+    Scherm
     Synchroniseren van mappen
     Mappen
     Lijst berichten
@@ -591,7 +591,7 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Mappen poll controleer frequentie
     2e klasse controleer frequentie
 
-    
+    Opslag
 
 
     Account kleur
@@ -752,7 +752,7 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Kies identiteit
     Kies identiteit
     Kies account/identiteit
-    
+    Verzenden als
 
 
     Ga naar Account Instellingen -> Beheer identiteiten om identiteiten aan te maken
@@ -794,7 +794,7 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Alleen sommige \"Plus\" accounts staan POP access
  toe om verbinding te krijgen met dit programma. Als het niet mogelijk is om in te loggen met de juiste gebruikersnaam en wachtwoord, heb je misschien geen betaalde \"Plus\" account.  Start de webbrowser om de toegang tot deze e-mailaccount te krijgen.
 
-    
+    Als je POP3 wilt gebruiken, moet je het geebruik van POP3 activeren op de Yahoo mail settings pagina.
 
     Onbekend Certificaat
     Accepteer Sleutel
@@ -831,21 +831,21 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Donker
     Licht
     Algemene instellingen
-    
+    Globaal
     Verwijderen van fouten
-    
-    
-    
+    Privacy
+    Netwerk
+    Interactie
     Account Lijst
     Berichten Lijst
     Berichten
     Thema
     Taal
 
-    
-    
-    
-    
+    1-kolom layout
+    Herschik HTML berichten voor kleinere schermen
+    Apparaat zoom
+    Gebruik zoom widgets of pinch-zoom als het apparaat dat ondersteunt
 
 
 
@@ -899,8 +899,8 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Gebaren
     Accepteer gebaren sturing
 
-    
-    
+    Compacte layout-
+    Pas layout aan zodat er meer op een pagina past
 
     Volume op/neer navigatie
     Spring tussen items door gebruik van de volumeknoppen
@@ -919,8 +919,8 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Tel zoek resultaten
     Zet uit voor sneller beeldscherm
 
-    
-    
+    Verberg speciale accounts
+    Verberg de gecombineerde inbox and alle berichtaccounts
 
     %s %s
      - Starred
@@ -960,7 +960,7 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Bericht onderwerp
     bericht afzender
     Bericht datum
-    
+    Preview
 
     Beeld berichten
     bericht afzender
@@ -1022,22 +1022,22 @@ Welkom bij K-9 Mail setup.  K-9 is een open source mail cliënt voor Android, ge
     Verwijder
     Niet verwijderen
 
-    
-    
-    
-    
+    Bevestig verplaatsing naar spam map
+    Wil je dit bericht echt verplaatsen naar de spam map?
+    Ja
+    Nee
 
-    
+    Bijlage wordt opgehaald
 
     Debug logging van Android logging systeem ingeschakeld
 
-    
-    
-    
+    » 
+    
+    Kan geen verbinding maken.
 
-    
+    Account \"%s\" is niet beschikbaar; controleer opslag
 
-    
-    
-    
+    Sla bijlagen op naar...
+    Sla bijlage op
+    Geen bestandsverkenner gevonden. Waar wil je deze bijlage opslaan?
 

From e6a8dff0d5d9397b4c41e6bcb6c39f65cda5d797 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Wed, 25 May 2011 00:15:13 +0900
Subject: [PATCH 104/121] Correct resources.

---
 res/values/strings.xml                   | 2 +-
 res/xml/account_settings_preferences.xml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/res/values/strings.xml b/res/values/strings.xml
index f5e795baa..bdcd6ddd6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -564,7 +564,7 @@ Welcome to K-9 Mail setup.  K-9 is an open source mail client for Android origin
 
     Sending mail
 
-    Show quoted text by default
+    Quote original message when replying
     When replying to messages, the original message is in your reply.
 
     Reply after quoted text
diff --git a/res/xml/account_settings_preferences.xml b/res/xml/account_settings_preferences.xml
index 942eee150..f30ed0065 100644
--- a/res/xml/account_settings_preferences.xml
+++ b/res/xml/account_settings_preferences.xml
@@ -243,7 +243,7 @@
             android:persistent="false"
             android:key="default_quoted_text_shown"
             android:title="@string/account_settings_default_quoted_text_shown_label"
-            android:defaultValue="false"
+            android:defaultValue="true"
             android:summary="@string/account_settings_default_quoted_text_shown_summary" />
 
         
Date: Wed, 25 May 2011 00:25:23 +0900
Subject: [PATCH 105/121] Refactoring

---
 src/com/fsck/k9/activity/MessageCompose.java | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index d9ed28141..0230c632a 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -840,13 +840,10 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
                                   .getBoolean(STATE_KEY_BCC_SHOWN) ? View.VISIBLE : View.GONE);
         showOrHideQuotedText((QuotedTextMode)savedInstanceState.getSerializable(STATE_KEY_QUOTED_TEXT_MODE));
 
-        if (mQuotedTextMode != QuotedTextMode.NONE) {
-            if (mMessageFormat == MessageFormat.HTML) {
-                mQuotedHtmlContent = (InsertableHtmlContent) savedInstanceState.getSerializable(STATE_KEY_HTML_QUOTE);
-                if (mQuotedHtmlContent != null && mQuotedHtmlContent.getQuotedContent() != null) {
-                    mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
-                    mQuotedTextEdit.setVisibility(View.VISIBLE);
-                }
+        if (mQuotedTextMode != QuotedTextMode.NONE && mMessageFormat == MessageFormat.HTML) {
+            mQuotedHtmlContent = (InsertableHtmlContent) savedInstanceState.getSerializable(STATE_KEY_HTML_QUOTE);
+            if (mQuotedHtmlContent != null && mQuotedHtmlContent.getQuotedContent() != null) {
+                mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
             }
         }
         mDraftUid = savedInstanceState.getString(STATE_KEY_DRAFT_UID);

From a4f7288d3749b8ed5c89ee82b59e52bee979b2f2 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Thu, 28 Apr 2011 00:23:16 +0900
Subject: [PATCH 106/121] Avoid NullPointerException. The name parameter in
 Content-Type may be not set.

---
 src/com/fsck/k9/mail/store/LocalStore.java | 26 ++++++++++++----------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index c0607cd39..55b630d66 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -1672,20 +1672,22 @@ public class LocalStore extends Store implements Serializable {
                                                 body = new LocalAttachmentBody(Uri.parse(contentUri), mApplication);
                                             }
 
-                                            String encoded_name = EncoderUtil.encodeIfNecessary(name,
-                                                                  EncoderUtil.Usage.WORD_ENTITY, 7);
-
                                             MimeBodyPart bp = new LocalAttachmentBodyPart(body, id);
-                                            bp.setHeader(MimeHeader.HEADER_CONTENT_TYPE,
-                                                         String.format("%s;\n name=\"%s\"",
-                                                                       type,
-                                                                       encoded_name));
                                             bp.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
-                                            bp.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
-                                                         String.format("%s;\n filename=\"%s\";\n size=%d",
-                                                                       contentDisposition,
-                                                                       encoded_name, // TODO: Should use encoded word defined in RFC 2231.
-                                                                       size));
+                                            if (name != null) {
+                                                String encoded_name = EncoderUtil.encodeIfNecessary(name,
+                                                                                                    EncoderUtil.Usage.WORD_ENTITY, 7);
+
+                                                bp.setHeader(MimeHeader.HEADER_CONTENT_TYPE,
+                                                             String.format("%s;\n name=\"%s\"",
+                                                                           type,
+                                                                           encoded_name));
+                                                bp.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
+                                                             String.format("%s;\n filename=\"%s\";\n size=%d",
+                                                                           contentDisposition,
+                                                                           encoded_name, // TODO: Should use encoded word defined in RFC 2231.
+                                                                           size));
+                                            }
 
                                             bp.setHeader(MimeHeader.HEADER_CONTENT_ID, contentId);
                                             /*

From cb46f170cdc93b9341413a1cf59c1d5a5d946e68 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Wed, 29 Dec 2010 16:42:11 +0900
Subject: [PATCH 107/121] Should reset visibleLimit on clear messages.

---
 src/com/fsck/k9/mail/store/LocalStore.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index 55b630d66..2fb64dd07 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -2572,6 +2572,7 @@ public class LocalStore extends Store implements Serializable {
             setPushState(null);
             setLastPush(0);
             setLastChecked(0);
+            setVisibleLimit(mAccount.getDisplayCount());
         }
 
         private void resetUnreadAndFlaggedCounts() {

From b4f37122463eb916d874ded2c99271844fd850e2 Mon Sep 17 00:00:00 2001
From: Koji Arai 
Date: Sat, 19 Feb 2011 23:10:51 +0900
Subject: [PATCH 108/121] Should retrieve just visibleLimit messages when the
 local folder is cleared.

---
 src/com/fsck/k9/controller/MessagingController.java | 2 +-
 src/com/fsck/k9/mail/store/LocalStore.java          | 7 +------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index fd4e0f7f1..f8cd2167f 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -793,7 +793,7 @@ public class MessagingController implements Runnable {
             LocalStore localStore = account.getLocalStore();
             LocalFolder localFolder = localStore.getFolder(folder);
             if (localFolder.getVisibleLimit() > 0) {
-                localFolder.setVisibleLimit(localFolder.getVisibleLimit() + account.getDisplayCount());
+                localFolder.setVisibleLimit(localFolder.getVisibleLimit() + localFolder.getMessageCount());
             }
             synchronizeMailbox(account, folder, listener, null);
         } catch (MessagingException me) {
diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index 2fb64dd07..52d28b8d7 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -485,9 +485,6 @@ public class LocalStore extends Store implements Serializable {
                     cursor = db.rawQuery("SELECT COUNT(*) FROM messages", null);
                     cursor.moveToFirst();
                     return cursor.getInt(0);   // message count
-
-
-
                 } finally {
                     if (cursor != null) {
                         cursor.close();
@@ -497,8 +494,6 @@ public class LocalStore extends Store implements Serializable {
         });
     }
 
-
-
     public void getMessageCounts(final AccountStats stats) throws MessagingException {
         final Account.FolderMode displayMode = mAccount.getFolderDisplayMode();
 
@@ -1269,7 +1264,7 @@ public class LocalStore extends Store implements Serializable {
                         }
                         Cursor cursor = null;
                         try {
-                            cursor = db.rawQuery("SELECT COUNT(*) FROM messages WHERE folder_id = ?",
+                            cursor = db.rawQuery("SELECT COUNT(*) FROM messages WHERE deleted = 0 and folder_id = ?",
                                                  new String[] {
                                                      Long.toString(mFolderId)
                                                  });

From b05af904efa1fff37eedd98cd2f0df91129bc36a Mon Sep 17 00:00:00 2001
From: Andrew Chen 
Date: Tue, 24 May 2011 12:43:32 -0700
Subject: [PATCH 109/121] Update .iml for IntelliJ IDEA 10.5 (Android SDK is
 now the platform SDK); remove unused compile only libs.

---
 k9mail.iml | 29 -----------------------------
 1 file changed, 29 deletions(-)

diff --git a/k9mail.iml b/k9mail.iml
index b5267d68f..1f9d13dd0 100644
--- a/k9mail.iml
+++ b/k9mail.iml
@@ -3,7 +3,6 @@
   
     
       
-