From f1baa8f461c92b4d489e7ac52e0c91cef16eed0f Mon Sep 17 00:00:00 2001
From: m0viefreak
Date: Fri, 2 Mar 2012 05:16:58 +0100
Subject: [PATCH 01/63] invalidate message content WebView when the message
header changes
This fixes redraw issues where text appears doubled or is cut off
---
src/com/fsck/k9/view/MessageHeader.java | 17 +++++++++++++++++
src/com/fsck/k9/view/SingleMessageView.java | 10 +++++++++-
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/src/com/fsck/k9/view/MessageHeader.java b/src/com/fsck/k9/view/MessageHeader.java
index a3f10afad..ed51d70d4 100644
--- a/src/com/fsck/k9/view/MessageHeader.java
+++ b/src/com/fsck/k9/view/MessageHeader.java
@@ -63,6 +63,8 @@ public class MessageHeader extends ScrollView implements OnClickListener {
private ImageView mShowAdditionalHeadersIcon;
private SavedState mSavedState;
+ private OnLayoutChangedListener mOnLayoutChangedListener;
+
/**
* Pair class is only available since API Level 5, so we need
* this helper class unfortunately
@@ -272,6 +274,7 @@ public class MessageHeader extends ScrollView implements OnClickListener {
} else {
showAdditionalHeaders();
}
+ layoutChanged();
}
private List getAdditionalHeaders(final Message message)
@@ -378,4 +381,18 @@ public class MessageHeader extends ScrollView implements OnClickListener {
out.writeInt((this.additionalHeadersVisible) ? 1 : 0);
}
}
+
+ public interface OnLayoutChangedListener {
+ void onLayoutChanged();
+ }
+
+ public void setOnLayoutChangedListener(OnLayoutChangedListener listener) {
+ mOnLayoutChangedListener = listener;
+ }
+
+ private void layoutChanged() {
+ if (mOnLayoutChangedListener != null) {
+ mOnLayoutChangedListener.onLayoutChanged();
+ }
+ }
}
diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java
index b1e0980e9..a19796d8c 100644
--- a/src/com/fsck/k9/view/SingleMessageView.java
+++ b/src/com/fsck/k9/view/SingleMessageView.java
@@ -33,7 +33,8 @@ import com.fsck.k9.mail.store.LocalStore.LocalMessage;
import java.util.List;
-public class SingleMessageView extends LinearLayout implements OnClickListener {
+public class SingleMessageView extends LinearLayout implements OnClickListener,
+ MessageHeader.OnLayoutChangedListener {
private boolean mScreenReaderEnabled;
private MessageCryptoView mCryptoView;
private MessageWebView mMessageContentView;
@@ -65,6 +66,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
mHeaderPlaceHolder = (LinearLayout) findViewById(R.id.message_view_header_container);
mHeaderContainer = (MessageHeader) findViewById(R.id.header_container);
+ mHeaderContainer.setOnLayoutChangedListener(this);
mAttachmentsContainer = findViewById(R.id.attachments_container);
mInsideAttachmentsContainer = (LinearLayout) findViewById(R.id.inside_attachments_container);
@@ -508,6 +510,12 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
mSavedState = savedState;
}
+ public void onLayoutChanged() {
+ if (mMessageContentView != null) {
+ mMessageContentView.invalidate();
+ }
+ }
+
static class SavedState extends BaseSavedState {
boolean attachmentViewVisible;
boolean hiddenAttachmentsVisible;
From 8d12244a9c23da0b5146afa418f75a4b7e49747d Mon Sep 17 00:00:00 2001
From: m0viefreak
Date: Fri, 2 Mar 2012 05:41:01 +0100
Subject: [PATCH 02/63] Message header changes
* remove expand/collapse arrows, instead use the background area of the header to toggle
* allow expanding of To: and Cc: texts when too long and cut off by clicking on them
---
...xml => message_view_header_background.xml} | 0
res/layout/message_view_header.xml | 50 ++-----------------
src/com/fsck/k9/view/MessageHeader.java | 37 ++++++++++----
3 files changed, 31 insertions(+), 56 deletions(-)
rename res/drawable/{separator_area_background.xml => message_view_header_background.xml} (100%)
diff --git a/res/drawable/separator_area_background.xml b/res/drawable/message_view_header_background.xml
similarity index 100%
rename from res/drawable/separator_area_background.xml
rename to res/drawable/message_view_header_background.xml
diff --git a/res/layout/message_view_header.xml b/res/layout/message_view_header.xml
index fe5c486a0..5b4d0d591 100644
--- a/res/layout/message_view_header.xml
+++ b/res/layout/message_view_header.xml
@@ -17,7 +17,7 @@
android:layout_height="wrap_content"
android:stretchColumns="1"
android:shrinkColumns="1"
- android:background="@color/message_view_header_background">
+ android:background="@drawable/message_view_header_background">
@@ -194,51 +194,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_height="1.5dp"
+ android:background="#59000000"/>
getAdditionalHeaders(final Message message)
throws MessagingException {
List additionalHeaders = new LinkedList();
From 78615f878d4ea28201e79652bd2c8694a09980a4 Mon Sep 17 00:00:00 2001
From: ashley willis
Date: Mon, 5 Mar 2012 15:17:31 -0600
Subject: [PATCH 03/63] added From: addresses on reply all when Reply-To: is
set. don't repeat address in To: field if it's already included in
replyToAddresses.
---
src/com/fsck/k9/activity/MessageCompose.java | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index 927078cf2..8ecc78a08 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -2289,8 +2289,15 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
}
if (ACTION_REPLY_ALL.equals(action)) {
+ if (message.getReplyTo().length > 0) {
+ for (Address address : message.getFrom()) {
+ if (!mAccount.isAnIdentity(address)) {
+ addAddress(mToView, address);
+ }
+ }
+ }
for (Address address : message.getRecipients(RecipientType.TO)) {
- if (!mAccount.isAnIdentity(address)) {
+ if (!mAccount.isAnIdentity(address) && !Utility.arrayContains(replyToAddresses, address)) {
addAddress(mToView, address);
}
From faf9dc6e0263e7cb3df1d09ebdeea6fb85777df8 Mon Sep 17 00:00:00 2001
From: cketti
Date: Tue, 6 Mar 2012 04:26:18 +0100
Subject: [PATCH 04/63] Restored show/more less indicator in the message header
---
res/layout/message_view_header.xml | 62 ++++++++++++++++++++++++-
src/com/fsck/k9/view/MessageHeader.java | 11 ++++-
2 files changed, 69 insertions(+), 4 deletions(-)
diff --git a/res/layout/message_view_header.xml b/res/layout/message_view_header.xml
index 5b4d0d591..19bd2a52d 100644
--- a/res/layout/message_view_header.xml
+++ b/res/layout/message_view_header.xml
@@ -30,6 +30,7 @@
@@ -134,14 +135,56 @@
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -188,6 +231,21 @@
android:textColor="?android:attr/textColorPrimary"
android:textAppearance="?android:attr/textAppearanceSmall"/>
+
+
+
+
+
diff --git a/src/com/fsck/k9/view/MessageHeader.java b/src/com/fsck/k9/view/MessageHeader.java
index f3f3b9a32..277885b95 100644
--- a/src/com/fsck/k9/view/MessageHeader.java
+++ b/src/com/fsck/k9/view/MessageHeader.java
@@ -59,6 +59,7 @@ public class MessageHeader extends ScrollView implements OnClickListener {
private Account mAccount;
private FontSizes mFontSizes = K9.getFontSizes();
private Contacts mContacts;
+ private ImageView mShowAdditionalHeadersIcon;
private SavedState mSavedState;
private OnLayoutChangedListener mOnLayoutChangedListener;
@@ -98,6 +99,7 @@ public class MessageHeader extends ScrollView implements OnClickListener {
mDateView = (TextView) findViewById(R.id.date);
mTimeView = (TextView) findViewById(R.id.time);
mFlagged = (CheckBox) findViewById(R.id.flagged);
+ mShowAdditionalHeadersIcon = (ImageView) findViewById(R.id.show_additional_headers_icon);
defaultSubjectColor = mSubjectView.getCurrentTextColor();
mSubjectView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewSubject());
@@ -113,10 +115,13 @@ public class MessageHeader extends ScrollView implements OnClickListener {
((TextView) findViewById(R.id.to_label)).setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewTo());
((TextView) findViewById(R.id.cc_label)).setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewCC());
- mToView.setOnClickListener(this);
- mCcView.setOnClickListener(this);
mFromView.setOnClickListener(this);
findViewById(R.id.top_container).setOnClickListener(this);
+
+ TextView dummyDateView = (TextView) findViewById(R.id.dummy_date);
+ TextView dummyTimeView = (TextView) findViewById(R.id.dummy_time);
+ dummyTimeView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewTime());
+ dummyDateView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewDate());
}
@Override
@@ -168,6 +173,7 @@ public class MessageHeader extends ScrollView implements OnClickListener {
private void hideAdditionalHeaders() {
mAdditionalHeadersView.setVisibility(View.GONE);
mAdditionalHeadersView.setText("");
+ mShowAdditionalHeadersIcon.setImageResource(R.drawable.show_more);
}
@@ -186,6 +192,7 @@ public class MessageHeader extends ScrollView implements OnClickListener {
// Show the additional headers that we have got.
populateAdditionalHeadersView(additionalHeaders);
mAdditionalHeadersView.setVisibility(View.VISIBLE);
+ mShowAdditionalHeadersIcon.setImageResource(R.drawable.show_less);
}
if (!allHeadersDownloaded) {
/*
From 4721d92e7909fd00619a02571916c438ec5b395b Mon Sep 17 00:00:00 2001
From: cketti
Date: Wed, 7 Mar 2012 21:40:41 +0100
Subject: [PATCH 05/63] Avoid some instances of autoboxing
This will hopefully allow us to compile with "Android Java IDE".
---
src/com/fsck/k9/activity/MessageCompose.java | 10 +++++-----
src/com/fsck/k9/controller/MessagingController.java | 10 ++++++++--
2 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index 8ecc78a08..e14c34c8e 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -2427,19 +2427,19 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
updateFrom();
Integer bodyLength = k9identity.get(IdentityField.LENGTH) != null
- ? Integer.parseInt(k9identity.get(IdentityField.LENGTH))
+ ? Integer.valueOf(k9identity.get(IdentityField.LENGTH))
: 0;
Integer bodyOffset = k9identity.get(IdentityField.OFFSET) != null
- ? Integer.parseInt(k9identity.get(IdentityField.OFFSET))
+ ? Integer.valueOf(k9identity.get(IdentityField.OFFSET))
: 0;
Integer bodyFooterOffset = k9identity.get(IdentityField.FOOTER_OFFSET) != null
- ? Integer.parseInt(k9identity.get(IdentityField.FOOTER_OFFSET))
+ ? Integer.valueOf(k9identity.get(IdentityField.FOOTER_OFFSET))
: null;
Integer bodyPlainLength = k9identity.get(IdentityField.PLAIN_LENGTH) != null
- ? Integer.parseInt(k9identity.get(IdentityField.PLAIN_LENGTH))
+ ? Integer.valueOf(k9identity.get(IdentityField.PLAIN_LENGTH))
: null;
Integer bodyPlainOffset = k9identity.get(IdentityField.PLAIN_OFFSET) != null
- ? Integer.parseInt(k9identity.get(IdentityField.PLAIN_OFFSET))
+ ? Integer.valueOf(k9identity.get(IdentityField.PLAIN_OFFSET))
: null;
mQuoteStyle = k9identity.get(IdentityField.QUOTE_STYLE) != null
? QuoteStyle.valueOf(k9identity.get(IdentityField.QUOTE_STYLE))
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index 023d19f60..250e3fb3d 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -629,7 +629,7 @@ public class MessagingController implements Runnable {
Log.i(K9.LOG_TAG, "searchLocalMessages ("
+ "accountUuids=" + Utility.combine(accountUuids, ',')
+ ", folderNames = " + Utility.combine(folderNames, ',')
- + ", messages.size() = " + (messages != null ? messages.length : null)
+ + ", messages.size() = " + (messages != null ? messages.length : -1)
+ ", query = " + query
+ ", integrate = " + integrate
+ ", requiredFlags = " + Utility.combine(requiredFlags, ',')
@@ -4182,7 +4182,13 @@ public class MessagingController implements Runnable {
NotificationSetting n = account.getNotificationSetting();
- configureNotification(notif, (n.shouldRing() ? n.getRingtone() : null), (n.shouldVibrate() ? n.getVibration() : null), (n.isLed() ? n.getLedColor() : null), K9.NOTIFICATION_LED_BLINK_SLOW, ringAndVibrate);
+ configureNotification(
+ notif,
+ (n.shouldRing()) ? n.getRingtone() : null,
+ (n.shouldVibrate()) ? n.getVibration() : null,
+ (n.isLed()) ? Integer.valueOf(n.getLedColor()) : null,
+ K9.NOTIFICATION_LED_BLINK_SLOW,
+ ringAndVibrate);
notifMgr.notify(account.getAccountNumber(), notif);
}
From ee34344d30fded0c3cba2b489a3462b271ff97a8 Mon Sep 17 00:00:00 2001
From: cketti
Date: Wed, 7 Mar 2012 21:52:47 +0100
Subject: [PATCH 06/63] Upgrade to SDK 15
---
project.properties | 2 +-
src/com/fsck/k9/preferences/Editor.java | 6 ++++
src/com/fsck/k9/preferences/Storage.java | 7 ++++
src/com/fsck/k9/provider/MessageProvider.java | 32 +++++++++++--------
4 files changed, 33 insertions(+), 14 deletions(-)
diff --git a/project.properties b/project.properties
index 213821e1f..46fb34716 100644
--- a/project.properties
+++ b/project.properties
@@ -11,5 +11,5 @@
split.density=false
java.encoding=utf8
# Project target.
-target=android-9
+target=android-15
extensible.libs.classpath=compile-only-libs
diff --git a/src/com/fsck/k9/preferences/Editor.java b/src/com/fsck/k9/preferences/Editor.java
index 412d14ff8..88479d0e2 100644
--- a/src/com/fsck/k9/preferences/Editor.java
+++ b/src/com/fsck/k9/preferences/Editor.java
@@ -7,6 +7,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
public class Editor implements android.content.SharedPreferences.Editor {
private Storage storage;
@@ -138,4 +139,9 @@ public class Editor implements android.content.SharedPreferences.Editor {
return this;
}
+ @Override
+ public android.content.SharedPreferences.Editor putStringSet(String arg0, Set arg1) {
+ throw new RuntimeException("Not implemented");
+ }
+
}
diff --git a/src/com/fsck/k9/preferences/Storage.java b/src/com/fsck/k9/preferences/Storage.java
index 34c978754..b9041c8f6 100644
--- a/src/com/fsck/k9/preferences/Storage.java
+++ b/src/com/fsck/k9/preferences/Storage.java
@@ -15,6 +15,7 @@ import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -399,4 +400,10 @@ public class Storage implements SharedPreferences {
Log.e(K9.LOG_TAG, "Error writing key '" + key + "', value = '" + value + "'");
}
}
+
+
+ @Override
+ public Set getStringSet(String arg0, Set arg1) {
+ throw new RuntimeException("Not implemented");
+ }
}
diff --git a/src/com/fsck/k9/provider/MessageProvider.java b/src/com/fsck/k9/provider/MessageProvider.java
index 50220c31c..0557575af 100644
--- a/src/com/fsck/k9/provider/MessageProvider.java
+++ b/src/com/fsck/k9/provider/MessageProvider.java
@@ -1,18 +1,5 @@
package com.fsck.k9.provider;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -46,6 +33,19 @@ import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.store.LocalStore;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
public class MessageProvider extends ContentProvider {
public static interface MessageColumns extends BaseColumns {
@@ -714,6 +714,12 @@ public class MessageProvider extends ContentProvider {
checkClosed();
mCursor.unregisterDataSetObserver(observer);
}
+
+ @Override
+ public int getType(int columnIndex) {
+ checkClosed();
+ return mCursor.getType(columnIndex);
+ }
}
protected class ThrottlingQueryHandler implements QueryHandler {
From 7163d39091b2a32724d9767b5ebf92dcb786a90b Mon Sep 17 00:00:00 2001
From: cketti
Date: Fri, 9 Mar 2012 21:50:26 +0100
Subject: [PATCH 07/63] Change ImapException to always be a permanent error
This way IMAP commands that get anything but an "OK" response are never
tried again (pending actions).
---
src/com/fsck/k9/mail/store/ImapStore.java | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index 6a77db634..008d8d45a 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -2735,13 +2735,8 @@ public class ImapStore extends Store {
private static final long serialVersionUID = 3725007182205882394L;
String mAlertText;
- public ImapException(String message, String alertText, Throwable throwable) {
- super(message, throwable);
- this.mAlertText = alertText;
- }
-
public ImapException(String message, String alertText) {
- super(message);
+ super(message, true);
this.mAlertText = alertText;
}
From 0cb4207ef73027e86feee4400647ad8f10f777d9 Mon Sep 17 00:00:00 2001
From: cketti
Date: Fri, 9 Mar 2012 21:51:48 +0100
Subject: [PATCH 08/63] IMAP: don't create the destination folder when copying
messages
---
src/com/fsck/k9/mail/store/ImapStore.java | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index 008d8d45a..043920aa6 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -1101,15 +1101,6 @@ public class ImapStore extends Store {
try {
String remoteDestName = encodeString(encodeFolderName(iFolder.getPrefixedName()));
- if (!exists(remoteDestName)) {
- // If the remote trash folder doesn't exist we try to create it.
- if (K9.DEBUG) {
- Log.i(K9.LOG_TAG, "Attempting to create remote folder '" + remoteDestName +
- "' for " + getLogId());
- }
- iFolder.create(FolderType.HOLDS_MESSAGES);
- }
-
//TODO: Split this into multiple commands if the command exceeds a certain length.
mConnection.sendCommand(String.format("UID COPY %s %s",
Utility.combine(uids, ','),
From dda072eff65c135a59da78b8b04482471e9ad199 Mon Sep 17 00:00:00 2001
From: ashley willis
Date: Sun, 11 Mar 2012 14:31:35 -0500
Subject: [PATCH 09/63] Upgrade to SDK 15
---
ant.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ant.properties b/ant.properties
index cfc6e1ad4..6be7f3220 100644
--- a/ant.properties
+++ b/ant.properties
@@ -19,5 +19,5 @@
split.density=false
java.encoding=utf8
# Project target.
-target=android-9
+target=android-15
extensible.libs.classpath=compile-only-libs
From f9a30d1822b0de034bab4d08b1e9392b7d7e69e4 Mon Sep 17 00:00:00 2001
From: ashley willis
Date: Sun, 11 Mar 2012 17:48:56 -0500
Subject: [PATCH 10/63] added sort by arrival option.
---
res/menu/message_list_option.xml | 4 ++++
res/values/strings.xml | 1 +
src/com/fsck/k9/activity/MessageInfoHolder.java | 1 +
src/com/fsck/k9/activity/MessageList.java | 16 +++++++++++++++-
.../fsck/k9/controller/MessagingController.java | 1 +
src/com/fsck/k9/helper/MessageHelper.java | 1 +
6 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/res/menu/message_list_option.xml b/res/menu/message_list_option.xml
index 2aa550a0f..b8bbf03a7 100644
--- a/res/menu/message_list_option.xml
+++ b/res/menu/message_list_option.xml
@@ -15,6 +15,10 @@
android:id="@+id/set_sort_date"
android:title="@string/sort_by_date"
/>
+ Sort by...Date
+ ArrivalSenderSubjectStar
diff --git a/src/com/fsck/k9/activity/MessageInfoHolder.java b/src/com/fsck/k9/activity/MessageInfoHolder.java
index e19fb953a..baee99b9a 100644
--- a/src/com/fsck/k9/activity/MessageInfoHolder.java
+++ b/src/com/fsck/k9/activity/MessageInfoHolder.java
@@ -7,6 +7,7 @@ import com.fsck.k9.mail.store.LocalStore.LocalMessage;
public class MessageInfoHolder {
public String date;
public Date compareDate;
+ public Date compareArrival;
public String compareSubject;
public CharSequence sender;
public String senderAddress;
diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java
index f874267f9..aec709cfe 100644
--- a/src/com/fsck/k9/activity/MessageList.java
+++ b/src/com/fsck/k9/activity/MessageList.java
@@ -185,6 +185,15 @@ public class MessageList
}
+ public static class ArrivalComparator implements Comparator {
+
+ @Override
+ public int compare(MessageInfoHolder object1, MessageInfoHolder object2) {
+ return object1.compareArrival.compareTo(object2.compareArrival);
+ }
+
+ }
+
public static class SubjectComparator implements Comparator {
@Override
@@ -234,6 +243,7 @@ public class MessageList
final Map> map = new EnumMap>(SORT_TYPE.class);
map.put(SORT_TYPE.SORT_ATTACHMENT, new AttachmentComparator());
map.put(SORT_TYPE.SORT_DATE, new DateComparator());
+ map.put(SORT_TYPE.SORT_ARRIVAL, new ArrivalComparator());
map.put(SORT_TYPE.SORT_FLAGGED, new FlaggedComparator());
map.put(SORT_TYPE.SORT_SENDER, new SenderComparator());
map.put(SORT_TYPE.SORT_SUBJECT, new SubjectComparator());
@@ -460,7 +470,7 @@ public class MessageList
{
// add the date comparator if not already specified
- if (sortType != SORT_TYPE.SORT_DATE) {
+ if (sortType != SORT_TYPE.SORT_DATE && sortType != SORT_TYPE.SORT_ARRIVAL) {
final Comparator comparator = SORT_COMPARATORS.get(SORT_TYPE.SORT_DATE);
if (sortDateAscending) {
chain.add(comparator);
@@ -1439,6 +1449,10 @@ public class MessageList
changeSort(SORT_TYPE.SORT_DATE);
return true;
}
+ case R.id.set_sort_arrival: {
+ changeSort(SORT_TYPE.SORT_ARRIVAL);
+ return true;
+ }
case R.id.set_sort_subject: {
changeSort(SORT_TYPE.SORT_SUBJECT);
return true;
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index 250e3fb3d..33acd96f1 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -146,6 +146,7 @@ public class MessagingController implements Runnable {
public enum SORT_TYPE {
SORT_DATE(R.string.sort_earliest_first, R.string.sort_latest_first, false),
+ SORT_ARRIVAL(R.string.sort_earliest_first, R.string.sort_latest_first, false),
SORT_SUBJECT(R.string.sort_subject_alpha, R.string.sort_subject_re_alpha, true),
SORT_SENDER(R.string.sort_sender_alpha, R.string.sort_sender_re_alpha, true),
SORT_UNREAD(R.string.sort_unread_first, R.string.sort_unread_last, true),
diff --git a/src/com/fsck/k9/helper/MessageHelper.java b/src/com/fsck/k9/helper/MessageHelper.java
index 43b208a77..018b481e2 100644
--- a/src/com/fsck/k9/helper/MessageHelper.java
+++ b/src/com/fsck/k9/helper/MessageHelper.java
@@ -49,6 +49,7 @@ public class MessageHelper {
try {
LocalMessage message = (LocalMessage) m;
target.message = message;
+ target.compareArrival = message.getInternalDate();
target.compareDate = message.getSentDate();
if (target.compareDate == null) {
target.compareDate = message.getInternalDate();
From 561d2a1a44ae6e9615b9a9c04d8a040b4a724690 Mon Sep 17 00:00:00 2001
From: cketti
Date: Mon, 12 Mar 2012 17:44:53 +0100
Subject: [PATCH 11/63] Added unit test for MimeUtility.getHeaderParameter()
---
.../k9/mail/internet/MimeUtilityTest.java | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 tests/src/com/fsck/k9/mail/internet/MimeUtilityTest.java
diff --git a/tests/src/com/fsck/k9/mail/internet/MimeUtilityTest.java b/tests/src/com/fsck/k9/mail/internet/MimeUtilityTest.java
new file mode 100644
index 000000000..8bf122395
--- /dev/null
+++ b/tests/src/com/fsck/k9/mail/internet/MimeUtilityTest.java
@@ -0,0 +1,39 @@
+package com.fsck.k9.mail.internet;
+
+import android.test.AndroidTestCase;
+
+public class MimeUtilityTest extends AndroidTestCase {
+
+ public void testGetHeaderParameter() {
+ String result;
+
+ /* Test edge cases */
+ result = MimeUtility.getHeaderParameter(";", null);
+ assertEquals(null, result);
+
+ result = MimeUtility.getHeaderParameter("name", "name");
+ assertEquals(null, result);
+
+ result = MimeUtility.getHeaderParameter("name=", "name");
+ assertEquals("", result);
+
+ result = MimeUtility.getHeaderParameter("name=\"", "name");
+ assertEquals("\"", result);
+
+ /* Test expected cases */
+ result = MimeUtility.getHeaderParameter("name=value", "name");
+ assertEquals("value", result);
+
+ result = MimeUtility.getHeaderParameter("name = value", "name");
+ assertEquals("value", result);
+
+ result = MimeUtility.getHeaderParameter("name=\"value\"", "name");
+ assertEquals("value", result);
+
+ result = MimeUtility.getHeaderParameter("name = \"value\"" , "name");
+ assertEquals("value", result);
+
+ result = MimeUtility.getHeaderParameter("name=\"\"", "name");
+ assertEquals("", result);
+ }
+}
From aeb0220e56b4717e4af262097f391d42fd3a3a4b Mon Sep 17 00:00:00 2001
From: cketti
Date: Mon, 12 Mar 2012 17:45:34 +0100
Subject: [PATCH 12/63] Fixed MimeUtility.getHeaderParameter() to not crash on
unexpected input
---
src/com/fsck/k9/mail/internet/MimeUtility.java | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index 405243d4b..0b8caf71f 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -953,16 +953,20 @@ public class MimeUtility {
}
header = header.replaceAll("\r|\n", "");
String[] parts = header.split(";");
- if (name == null) {
+ if (name == null && parts.length > 0) {
return parts[0];
}
for (String part : parts) {
if (part.trim().toLowerCase(Locale.US).startsWith(name.toLowerCase(Locale.US))) {
- String parameter = part.split("=", 2)[1].trim();
- if (parameter.startsWith("\"") && parameter.endsWith("\"")) {
- return parameter.substring(1, parameter.length() - 1);
- } else {
- return parameter;
+ String[] partParts = part.split("=", 2);
+ if (partParts.length == 2) {
+ String parameter = partParts[1].trim();
+ int len = parameter.length();
+ if (len >= 2 && parameter.startsWith("\"") && parameter.endsWith("\"")) {
+ return parameter.substring(1, len - 1);
+ } else {
+ return parameter;
+ }
}
}
}
From f181e923ca8bb4f75f250f6f56f8b4409e0a4ae3 Mon Sep 17 00:00:00 2001
From: cketti
Date: Thu, 15 Mar 2012 21:21:00 +0100
Subject: [PATCH 13/63] Don't modify draft messages when storing them in the
database
---
.../fsck/k9/mail/internet/MimeUtility.java | 57 +++++++++++++++++++
src/com/fsck/k9/mail/store/LocalStore.java | 27 +++++++--
2 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index 0b8caf71f..0405fd567 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -3260,4 +3260,61 @@ public class MimeUtility {
return charset;
}
+
+ public static ViewableContainer extractPartsFromDraft(Message message)
+ throws MessagingException {
+
+ Body body = message.getBody();
+ if (message.isMimeType("multipart/mixed") && body instanceof MimeMultipart) {
+ MimeMultipart multipart = (MimeMultipart) body;
+
+ ViewableContainer container;
+ int count = multipart.getCount();
+ if (count >= 1) {
+ // The first part is either a text/plain or a multipart/alternative
+ BodyPart firstPart = multipart.getBodyPart(0);
+ container = extractTextual(firstPart);
+
+ // The rest should be attachments
+ for (int i = 1; i < count; i++) {
+ BodyPart bodyPart = multipart.getBodyPart(i);
+ container.attachments.add(bodyPart);
+ }
+ } else {
+ container = new ViewableContainer(null, null, new ArrayList());
+ }
+
+ return container;
+ }
+
+ return extractTextual(message);
+ }
+
+ private static ViewableContainer extractTextual(Part part) throws MessagingException {
+ String text = null;
+ String html = null;
+ List attachments = new ArrayList();
+
+ Body firstBody = part.getBody();
+ if (part.isMimeType("text/plain") &&
+ firstBody instanceof TextBody) {
+ text = ((TextBody) firstBody).getText();
+ } else if (part.isMimeType("multipart/alternative") &&
+ firstBody instanceof MimeMultipart) {
+ MimeMultipart multipart = (MimeMultipart) firstBody;
+ for (int i = 0, count = multipart.getCount(); i < count; i++) {
+ BodyPart bodyPart = multipart.getBodyPart(i);
+ if (bodyPart.getBody() instanceof TextBody) {
+ TextBody textBody = (TextBody) bodyPart.getBody();
+ if (text == null && bodyPart.isMimeType("text/plain")) {
+ text = textBody.getText();
+ } else if (html == null && bodyPart.isMimeType("text/html")) {
+ html = textBody.getText();
+ }
+ }
+ }
+ }
+
+ return new ViewableContainer(text, html, attachments);
+ }
}
diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java
index f9d769511..64d89610c 100644
--- a/src/com/fsck/k9/mail/store/LocalStore.java
+++ b/src/com/fsck/k9/mail/store/LocalStore.java
@@ -2134,12 +2134,29 @@ public class LocalStore extends Store implements Serializable {
deleteAttachments(message.getUid());
}
- ViewableContainer container =
- MimeUtility.extractTextAndAttachments(mApplication, message);
+ boolean isDraft = (message.getHeader(K9.IDENTITY_HEADER) != null);
- List attachments = container.attachments;
- String text = container.text;
- String html = HtmlConverter.convertEmoji2Img(container.html);
+ List attachments;
+ String text;
+ String html;
+ if (isDraft) {
+ // Don't modify the text/plain or text/html part of our own
+ // draft messages because this will cause the values stored in
+ // the identity header to be wrong.
+ ViewableContainer container =
+ MimeUtility.extractPartsFromDraft(message);
+
+ text = container.text;
+ html = container.html;
+ attachments = container.attachments;
+ } else {
+ ViewableContainer container =
+ MimeUtility.extractTextAndAttachments(mApplication, message);
+
+ attachments = container.attachments;
+ text = container.text;
+ html = HtmlConverter.convertEmoji2Img(container.html);
+ }
String preview = calculateContentPreview(text);
From a48adafbbc99ce2b0ad275060f2045d1f8199328 Mon Sep 17 00:00:00 2001
From: cketti
Date: Fri, 16 Mar 2012 22:56:09 +0100
Subject: [PATCH 14/63] Don't use null for 'text' and 'html' in
ViewableContainer
---
src/com/fsck/k9/mail/internet/MimeUtility.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index 0405fd567..1c43d3b58 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -3281,7 +3281,7 @@ public class MimeUtility {
container.attachments.add(bodyPart);
}
} else {
- container = new ViewableContainer(null, null, new ArrayList());
+ container = new ViewableContainer("", "", new ArrayList());
}
return container;
@@ -3291,8 +3291,8 @@ public class MimeUtility {
}
private static ViewableContainer extractTextual(Part part) throws MessagingException {
- String text = null;
- String html = null;
+ String text = "";
+ String html = "";
List attachments = new ArrayList();
Body firstBody = part.getBody();
From dbf38dae653aa2fdfe2372cec2ab2e19bea5f5c7 Mon Sep 17 00:00:00 2001
From: cketti
Date: Sat, 17 Mar 2012 00:30:40 +0100
Subject: [PATCH 15/63] Fixed the change of the previous commit
---
src/com/fsck/k9/mail/internet/MimeUtility.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index 1c43d3b58..20486232c 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -3306,9 +3306,9 @@ public class MimeUtility {
BodyPart bodyPart = multipart.getBodyPart(i);
if (bodyPart.getBody() instanceof TextBody) {
TextBody textBody = (TextBody) bodyPart.getBody();
- if (text == null && bodyPart.isMimeType("text/plain")) {
+ if ("".equals(text) && bodyPart.isMimeType("text/plain")) {
text = textBody.getText();
- } else if (html == null && bodyPart.isMimeType("text/html")) {
+ } else if ("".equals(html) && bodyPart.isMimeType("text/html")) {
html = textBody.getText();
}
}
From 3fa8081e88e0b035377c721fd21676a735d82baf Mon Sep 17 00:00:00 2001
From: cketti
Date: Sat, 17 Mar 2012 03:19:09 +0100
Subject: [PATCH 16/63] Fixed MimeUtility.extractTextual() when loading
messages from the server
---
src/com/fsck/k9/mail/internet/MimeUtility.java | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index 20486232c..eb6948c11 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -3304,12 +3304,12 @@ public class MimeUtility {
MimeMultipart multipart = (MimeMultipart) firstBody;
for (int i = 0, count = multipart.getCount(); i < count; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
- if (bodyPart.getBody() instanceof TextBody) {
- TextBody textBody = (TextBody) bodyPart.getBody();
- if ("".equals(text) && bodyPart.isMimeType("text/plain")) {
- text = textBody.getText();
- } else if ("".equals(html) && bodyPart.isMimeType("text/html")) {
- html = textBody.getText();
+ String bodyText = getTextFromPart(bodyPart);
+ if (bodyText != null) {
+ if (text.length() == 0 && bodyPart.isMimeType("text/plain")) {
+ text = bodyText;
+ } else if (html.length() == 0 && bodyPart.isMimeType("text/html")) {
+ html = bodyText;
}
}
}
From f9a35aeaeeae67bd88c3b253c25d06832ca7da73 Mon Sep 17 00:00:00 2001
From: cketti
Date: Sat, 17 Mar 2012 04:15:30 +0100
Subject: [PATCH 17/63] Replace CRLF with LF when loading drafts
This is necessary because we save the offset and length of the user-
supplied text in the identity header. These values are then later used
to split the draft in user text and quoted message.
When calculating these values we operate on a string with LF line
endings. Ideally we want to do the reverse operation on the same
string, but when saving the message to the server LF is converted to
CRLF to create RFC-conforming messages.
This is only a hack and will probably be the cause of more trouble in
the future. A better solution would be to make the identity header more
robust or get rid of it entirely.
---
.../fsck/k9/mail/internet/MimeUtility.java | 29 +++++++++++++++----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index eb6948c11..842a7cc8d 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -3296,9 +3296,11 @@ public class MimeUtility {
List attachments = new ArrayList();
Body firstBody = part.getBody();
- if (part.isMimeType("text/plain") &&
- firstBody instanceof TextBody) {
- text = ((TextBody) firstBody).getText();
+ if (part.isMimeType("text/plain")) {
+ String bodyText = getTextFromPart(part);
+ if (bodyText != null) {
+ text = fixDraftTextBody(bodyText);
+ }
} else if (part.isMimeType("multipart/alternative") &&
firstBody instanceof MimeMultipart) {
MimeMultipart multipart = (MimeMultipart) firstBody;
@@ -3307,9 +3309,9 @@ public class MimeUtility {
String bodyText = getTextFromPart(bodyPart);
if (bodyText != null) {
if (text.length() == 0 && bodyPart.isMimeType("text/plain")) {
- text = bodyText;
+ text = fixDraftTextBody(bodyText);
} else if (html.length() == 0 && bodyPart.isMimeType("text/html")) {
- html = bodyText;
+ html = fixDraftTextBody(bodyText);
}
}
}
@@ -3317,4 +3319,21 @@ public class MimeUtility {
return new ViewableContainer(text, html, attachments);
}
+
+ /**
+ * Fix line endings of text bodies in draft messages.
+ *
+ *
+ * We create drafts with LF line endings. The values in the identity header are based on that.
+ * So we replace CRLF with LF when loading messages (from the server).
+ *
+ *
+ * @param text
+ * The body text with CRLF line endings
+ *
+ * @return The text with LF line endings
+ */
+ private static String fixDraftTextBody(String text) {
+ return text.replace("\r\n", "\n");
+ }
}
From 8192d54cce6d5f0796ad9a806627dd9b11249238 Mon Sep 17 00:00:00 2001
From: Koji Arai
Date: Sat, 17 Mar 2012 23:08:14 +0900
Subject: [PATCH 18/63] Updated Japanese translation. catch up with f9a30d1.
---
res/values-ja/strings.xml | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 55815636e..794a17cf2 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -287,8 +287,11 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
SDカードに添付ファイルを保存できません\"画像表示\"ボタンを押下すると描画します画像表示
- 添付取込中
- 添付ファイルのビューワー見つけられません .%s
+ メッセージ表示
+ 添付ファイル表示
+ 他…
+ 添付ファイル取得中
+ %sのビューワーが見つかりませんすべてダウンロード
@@ -777,6 +780,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
並べ替え...日付
+ 受信順送信者件名フラグ
From 39f2138292225c1b904c5bfbeec41e58c20d100b Mon Sep 17 00:00:00 2001
From: Koji Arai
Date: Sun, 4 Mar 2012 09:47:29 +0900
Subject: [PATCH 19/63] added a Japanese provider "auone.jp"
---
res/values-ja/strings.xml | 4 +++-
res/values/strings.xml | 1 +
res/xml/providers.xml | 5 +++++
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 794a17cf2..4c678800b 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -799,7 +799,9 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
このプログラムでPOPアクセスが許可されているのは一部の「Plus」アカウントだけです。有料の「Plus」アカウントがなければ、正しいメールアドレスとパスワードを入力してもログインできません。これらのアカウントにはブラウザからアクセスしてください。
- Yahoo! JapanでPOP3アクセスを使う場合は、Yahoo!メールサイトの「メールの設定」にてPOPアクセスが許可されていることを確認してください。
+ Yahoo! JapanでPOP3アクセスを行う場合は、Yahoo!メールサイトの「メールの設定」にてPOPアクセスが許可されていることを確認してください。
+
+ au oneでIMAPアクセスを行う場合は、au oneポータルサイトの「メール」→「設定」ページにて「IMAPを有効にする」をチェックしてください。証明書が無効です許可
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d7ad77b8d..820960b66 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -805,6 +805,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
\"Plus\" account. Please launch the Web browser to gain access to
these mail accounts.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 au one 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.
diff --git a/res/xml/providers.xml b/res/xml/providers.xml
index a00108996..d94d929a7 100644
--- a/res/xml/providers.xml
+++ b/res/xml/providers.xml
@@ -283,6 +283,11 @@
+
+
+
+
Date: Wed, 29 Feb 2012 00:51:02 +0900
Subject: [PATCH 20/63] avoid NPE. address may be null when the parser is
failed.
---
src/com/fsck/k9/mail/internet/MimeUtility.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index 842a7cc8d..13ebc9304 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -2182,6 +2182,8 @@ public class MimeUtility {
}
private static String getJisVariantFromAddress(String address) {
+ if (address == null)
+ return null;
if (isInDomain(address, "docomo.ne.jp") || isInDomain(address, "dwmail.jp") ||
isInDomain(address, "pdx.ne.jp") || isInDomain(address, "willcom.com"))
return "docomo";
From 10c37942a632dc1a05cbf7624e0739a7e624ae02 Mon Sep 17 00:00:00 2001
From: Koji Arai
Date: Wed, 7 Mar 2012 00:56:33 +0900
Subject: [PATCH 21/63] Added two domains handle docomo emoji
---
src/com/fsck/k9/mail/internet/MimeUtility.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/com/fsck/k9/mail/internet/MimeUtility.java b/src/com/fsck/k9/mail/internet/MimeUtility.java
index 13ebc9304..e1908670d 100644
--- a/src/com/fsck/k9/mail/internet/MimeUtility.java
+++ b/src/com/fsck/k9/mail/internet/MimeUtility.java
@@ -2185,7 +2185,8 @@ public class MimeUtility {
if (address == null)
return null;
if (isInDomain(address, "docomo.ne.jp") || isInDomain(address, "dwmail.jp") ||
- isInDomain(address, "pdx.ne.jp") || isInDomain(address, "willcom.com"))
+ isInDomain(address, "pdx.ne.jp") || isInDomain(address, "willcom.com") ||
+ isInDomain(address, "emnet.ne.jp") || isInDomain(address, "emobile.ne.jp"))
return "docomo";
else if (isInDomain(address, "softbank.ne.jp") || isInDomain(address, "vodafone.ne.jp") ||
isInDomain(address, "disney.ne.jp") || isInDomain(address, "vertuclub.ne.jp"))
From ef01dc906b1b006a0bab045ebd426281407c2558 Mon Sep 17 00:00:00 2001
From: cketti
Date: Sat, 17 Mar 2012 18:27:17 +0100
Subject: [PATCH 22/63] Use AlertDialog's ListView on import instead of
creating our own
This fixes a display problem when using the dark theme.
---
src/com/fsck/k9/activity/Accounts.java | 52 +++++++++++---------------
1 file changed, 22 insertions(+), 30 deletions(-)
diff --git a/src/com/fsck/k9/activity/Accounts.java b/src/com/fsck/k9/activity/Accounts.java
index 339494044..d31bced32 100644
--- a/src/com/fsck/k9/activity/Accounts.java
+++ b/src/com/fsck/k9/activity/Accounts.java
@@ -21,6 +21,7 @@ import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -45,12 +46,10 @@ import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
-import android.widget.CheckedTextView;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
-import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
@@ -58,7 +57,6 @@ import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.CompoundButton.OnCheckedChangeListener;
import com.fsck.k9.Account;
@@ -1464,8 +1462,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
private static class ImportSelectionDialog implements NonConfigurationInstance {
private ImportContents mImportContents;
private Uri mUri;
- private Dialog mDialog;
- private ListView mImportSelectionView;
+ private AlertDialog mDialog;
private SparseBooleanArray mSelection;
@@ -1483,8 +1480,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
public boolean retain() {
if (mDialog != null) {
// Save the selection state of each list item
- mSelection = mImportSelectionView.getCheckedItemPositions();
- mImportSelectionView = null;
+ mSelection = mDialog.getListView().getCheckedItemPositions();
mDialog.dismiss();
mDialog = null;
@@ -1498,8 +1494,6 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
}
public void show(final Accounts activity, SparseBooleanArray selection) {
- final ListView importSelectionView = new ListView(activity);
- mImportSelectionView = importSelectionView;
List contents = new ArrayList();
if (mImportContents.globalSettings) {
@@ -1510,23 +1504,15 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
contents.add(account.name);
}
- importSelectionView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
- importSelectionView.setAdapter(new ArrayAdapter(activity,
- android.R.layout.simple_list_item_checked, contents));
- importSelectionView.setOnItemSelectedListener(new OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parent, View view, int pos, long id) {
- CheckedTextView ctv = (CheckedTextView)view;
- ctv.setChecked(!ctv.isChecked());
- }
-
- @Override
- public void onNothingSelected(AdapterView> arg0) { /* Do nothing */ }
- });
-
+ int count = contents.size();
+ boolean[] checkedItems = new boolean[count];
if (selection != null) {
- for (int i = 0, end = contents.size(); i < end; i++) {
- importSelectionView.setItemChecked(i, selection.get(i));
+ for (int i = 0; i < count; i++) {
+ checkedItems[i] = selection.get(i);
+ }
+ } else {
+ for (int i = 0; i < count; i++) {
+ checkedItems[i] = true;
}
}
@@ -1534,23 +1520,29 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
//TODO: listview footer: "Select all" / "Select none" buttons?
//TODO: listview footer: "Overwrite existing accounts?" checkbox
+ OnMultiChoiceClickListener listener = new OnMultiChoiceClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+ ((AlertDialog) dialog).getListView().setItemChecked(which, isChecked);
+ }
+ };
+
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ builder.setMultiChoiceItems(contents.toArray(new String[0]), checkedItems, listener);
builder.setTitle(activity.getString(R.string.settings_import_selection));
- builder.setView(importSelectionView);
builder.setInverseBackgroundForced(true);
builder.setPositiveButton(R.string.okay_action,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- ListAdapter adapter = importSelectionView.getAdapter();
- int count = adapter.getCount();
- SparseBooleanArray pos = importSelectionView.getCheckedItemPositions();
+ ListView listView = ((AlertDialog) dialog).getListView();
+ SparseBooleanArray pos = listView.getCheckedItemPositions();
boolean includeGlobals = mImportContents.globalSettings ? pos.get(0) : false;
List accountUuids = new ArrayList();
int start = mImportContents.globalSettings ? 1 : 0;
- for (int i = start; i < count; i++) {
+ for (int i = start, end = listView.getCount(); i < end; i++) {
if (pos.get(i)) {
accountUuids.add(mImportContents.accounts.get(i-start).uuid);
}
From 69ee6a48187d7c1cde3bc3cdb292f4858d7c5c56 Mon Sep 17 00:00:00 2001
From: cketti
Date: Sat, 17 Mar 2012 20:12:33 +0100
Subject: [PATCH 23/63] Avoid NullPointerException in Accounts.onCreateDialog()
Also cleaned up code formatting of onCreateDialog() and
onPrepareDialog().
---
src/com/fsck/k9/activity/Accounts.java | 195 ++++++++++++++-----------
1 file changed, 108 insertions(+), 87 deletions(-)
diff --git a/src/com/fsck/k9/activity/Accounts.java b/src/com/fsck/k9/activity/Accounts.java
index d31bced32..bb8d9a96a 100644
--- a/src/com/fsck/k9/activity/Accounts.java
+++ b/src/com/fsck/k9/activity/Accounts.java
@@ -918,107 +918,128 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
@Override
public Dialog onCreateDialog(int id) {
+ // Android recreates our dialogs on configuration changes even when they have been
+ // dismissed. Make sure we have all information necessary before creating a new dialog.
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();
- }
+ case DIALOG_REMOVE_ACCOUNT: {
+ if (mSelectedContextAccount == null) {
+ return null;
}
- });
- 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);
- }
+ 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();
+ }
+ }
+ });
+ }
+ case DIALOG_CLEAR_ACCOUNT: {
+ if (mSelectedContextAccount == null) {
+ return 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);
- }
+ 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);
+ }
+ }
+ });
+ }
+ case DIALOG_RECREATE_ACCOUNT: {
+ if (mSelectedContextAccount == null) {
+ return null;
}
- });
- case DIALOG_NO_FILE_MANAGER:
- return ConfirmationDialog.create(this, id,
- R.string.import_dialog_error_title,
- getString(R.string.import_dialog_error_message),
- R.string.open_market,
- R.string.close,
- new Runnable() {
- @Override
- public void run() {
- Uri uri = Uri.parse(ANDROID_MARKET_URL);
- Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- startActivity(intent);
- }
- });
+
+ 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);
+ }
+ }
+ });
+ }
+ case DIALOG_NO_FILE_MANAGER: {
+ return ConfirmationDialog.create(this, id,
+ R.string.import_dialog_error_title,
+ getString(R.string.import_dialog_error_message),
+ R.string.open_market,
+ R.string.close,
+ new Runnable() {
+ @Override
+ public void run() {
+ Uri uri = Uri.parse(ANDROID_MARKET_URL);
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ startActivity(intent);
+ }
+ });
+ }
}
+
return super.onCreateDialog(id);
}
@Override
public void onPrepareDialog(int id, Dialog d) {
-
AlertDialog alert = (AlertDialog) d;
switch (id) {
- case DIALOG_REMOVE_ACCOUNT:
- alert.setMessage(getString(R.string.account_delete_dlg_instructions_fmt,
- mSelectedContextAccount.getDescription()));
- break;
- case DIALOG_CLEAR_ACCOUNT:
- alert.setMessage(getString(R.string.account_clear_dlg_instructions_fmt,
- mSelectedContextAccount.getDescription()));
- break;
- case DIALOG_RECREATE_ACCOUNT:
- alert.setMessage(getString(R.string.account_recreate_dlg_instructions_fmt,
- mSelectedContextAccount.getDescription()));
- break;
- case DIALOG_NO_FILE_MANAGER:
- alert.setMessage(getString(R.string.import_dialog_error_message));
- break;
+ case DIALOG_REMOVE_ACCOUNT: {
+ alert.setMessage(getString(R.string.account_delete_dlg_instructions_fmt,
+ mSelectedContextAccount.getDescription()));
+ break;
+ }
+ case DIALOG_CLEAR_ACCOUNT: {
+ alert.setMessage(getString(R.string.account_clear_dlg_instructions_fmt,
+ mSelectedContextAccount.getDescription()));
+ break;
+ }
+ case DIALOG_RECREATE_ACCOUNT: {
+ alert.setMessage(getString(R.string.account_recreate_dlg_instructions_fmt,
+ mSelectedContextAccount.getDescription()));
+ break;
+ }
}
super.onPrepareDialog(id, d);
From 482ae352c158d75eb3db820305d020b809715a32 Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 18 Mar 2012 04:51:29 +0100
Subject: [PATCH 24/63] Reverted most of the recent message header changes
Clicking the additional headers area still allows to hide that view
again.
---
res/layout/message_view_header.xml | 147 ++++++++++++------------
src/com/fsck/k9/view/MessageHeader.java | 21 ++--
2 files changed, 86 insertions(+), 82 deletions(-)
diff --git a/res/layout/message_view_header.xml b/res/layout/message_view_header.xml
index 19bd2a52d..67f8fe010 100644
--- a/res/layout/message_view_header.xml
+++ b/res/layout/message_view_header.xml
@@ -17,7 +17,7 @@
android:layout_height="wrap_content"
android:stretchColumns="1"
android:shrinkColumns="1"
- android:background="@drawable/message_view_header_background">
+ android:background="@color/message_view_header_background">
@@ -30,7 +30,6 @@
@@ -123,68 +122,16 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -231,32 +178,82 @@
android:textColor="?android:attr/textColorPrimary"
android:textAppearance="?android:attr/textAppearanceSmall"/>
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+ android:layout_height="21.5dp"
+ android:focusable="true"
+ android:clickable="true"
+ android:background="@drawable/message_view_header_background">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Date: Sun, 18 Mar 2012 18:28:03 +0100
Subject: [PATCH 25/63] Fix for Issue 4164: Force close when moving an email to
another folder
---
src/com/fsck/k9/activity/ChooseFolder.java | 34 +++++++++++++++-------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/src/com/fsck/k9/activity/ChooseFolder.java b/src/com/fsck/k9/activity/ChooseFolder.java
index dc4a88115..2525c5763 100644
--- a/src/com/fsck/k9/activity/ChooseFolder.java
+++ b/src/com/fsck/k9/activity/ChooseFolder.java
@@ -1,6 +1,11 @@
package com.fsck.k9.activity;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
@@ -19,15 +24,16 @@ import android.widget.EditText;
import android.widget.Filter;
import android.widget.ListView;
import android.widget.TextView;
-import com.fsck.k9.*;
+
+import com.fsck.k9.Account;
import com.fsck.k9.Account.FolderMode;
+import com.fsck.k9.K9;
+import com.fsck.k9.Preferences;
+import com.fsck.k9.R;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.controller.MessagingListener;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
public class ChooseFolder extends K9ListActivity {
String mFolder;
@@ -40,6 +46,8 @@ public class ChooseFolder extends K9ListActivity {
boolean hideCurrentFolder = true;
boolean showOptionNone = false;
boolean showDisplayableOnly = false;
+
+ private List folderList;
/**
* What folders to display.
@@ -361,17 +369,19 @@ public class ChooseFolder extends K9ListActivity {
return aName.compareToIgnoreCase(bName);
}
});
- mAdapter.setNotifyOnChange(false);
int selectedFolder = -1;
+ // We're not allowed to change the adapter from a background thread, so we use
+ // a java.util.List to build a list of the folder names.
+ // We'll add the folder names to the adapter from the UI-thread (see the 'finally' block).
+ folderList = new ArrayList();
try {
- mAdapter.clear();
int position = 0;
for (String name : localFolders) {
if (mAccount.getInboxFolderName().equalsIgnoreCase(name)) {
- mAdapter.add(getString(R.string.special_mailbox_name_inbox));
+ folderList.add(getString(R.string.special_mailbox_name_inbox));
heldInbox = name;
} else if (!K9.ERROR_FOLDER_NAME.equals(name) && !account.getOutboxFolderName().equals(name)) {
- mAdapter.add(name);
+ folderList.add(name);
}
if (mSelectFolder != null) {
@@ -390,11 +400,13 @@ public class ChooseFolder extends K9ListActivity {
position++;
}
} finally {
- mAdapter.setNotifyOnChange(true);
runOnUiThread(new Runnable() {
public void run() {
- // runOnUiThread(
- mAdapter.notifyDataSetChanged();
+ // Now we're in the UI-thread, we can safely change the contents of the adapter.
+ mAdapter.clear();
+ for (String folderName: folderList) {
+ mAdapter.add(folderName);
+ }
}
});
}
From 6bdaac4353cfcb7bc61674cefd6b2fff5741016b Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 18 Mar 2012 21:46:32 +0100
Subject: [PATCH 26/63] Fixed whitespace (tabs vs. spaces)
---
src/com/fsck/k9/activity/ChooseFolder.java | 88 +++++++++++-----------
1 file changed, 44 insertions(+), 44 deletions(-)
diff --git a/src/com/fsck/k9/activity/ChooseFolder.java b/src/com/fsck/k9/activity/ChooseFolder.java
index 2525c5763..98210bc7c 100644
--- a/src/com/fsck/k9/activity/ChooseFolder.java
+++ b/src/com/fsck/k9/activity/ChooseFolder.java
@@ -46,7 +46,7 @@ public class ChooseFolder extends K9ListActivity {
boolean hideCurrentFolder = true;
boolean showOptionNone = false;
boolean showDisplayableOnly = false;
-
+
private List folderList;
/**
@@ -216,7 +216,7 @@ public class ChooseFolder extends K9ListActivity {
return true;
}
case R.id.filter_folders: {
- onEnterFilter();
+ onEnterFilter();
}
return true;
default:
@@ -236,43 +236,43 @@ public class ChooseFolder extends K9ListActivity {
* Filter {@link #mAdapter} with the user-input.
*/
private void onEnterFilter() {
- final AlertDialog.Builder filterAlert = new AlertDialog.Builder(this);
+ final AlertDialog.Builder filterAlert = new AlertDialog.Builder(this);
- final EditText input = new EditText(this);
- input.addTextChangedListener(new TextWatcher() {
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- mAdapter.getFilter().filter(input.getText().toString());
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- }
- });
- input.setHint(R.string.folder_list_filter_hint);
- filterAlert.setView(input);
+ final EditText input = new EditText(this);
+ input.addTextChangedListener(new TextWatcher() {
- filterAlert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- String value = input.getText().toString().trim();
- mAdapter.getFilter().filter(value);
- }
- });
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ mAdapter.getFilter().filter(input.getText().toString());
+ }
- filterAlert.setNegativeButton("Cancel",
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- mAdapter.getFilter().filter("");
- }
- });
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {
+ }
- filterAlert.show();
+ @Override
+ public void afterTextChanged(Editable s) {
+ }
+ });
+ input.setHint(R.string.folder_list_filter_hint);
+ filterAlert.setView(input);
+
+ filterAlert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ String value = input.getText().toString().trim();
+ mAdapter.getFilter().filter(value);
+ }
+ });
+
+ filterAlert.setNegativeButton("Cancel",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ mAdapter.getFilter().filter("");
+ }
+ });
+
+ filterAlert.show();
}
@@ -370,18 +370,18 @@ public class ChooseFolder extends K9ListActivity {
}
});
int selectedFolder = -1;
- // We're not allowed to change the adapter from a background thread, so we use
+ // We're not allowed to change the adapter from a background thread, so we use
// a java.util.List to build a list of the folder names.
- // We'll add the folder names to the adapter from the UI-thread (see the 'finally' block).
+ // We'll add the folder names to the adapter from the UI-thread (see the 'finally' block).
folderList = new ArrayList();
try {
int position = 0;
for (String name : localFolders) {
if (mAccount.getInboxFolderName().equalsIgnoreCase(name)) {
- folderList.add(getString(R.string.special_mailbox_name_inbox));
+ folderList.add(getString(R.string.special_mailbox_name_inbox));
heldInbox = name;
} else if (!K9.ERROR_FOLDER_NAME.equals(name) && !account.getOutboxFolderName().equals(name)) {
- folderList.add(name);
+ folderList.add(name);
}
if (mSelectFolder != null) {
@@ -402,11 +402,11 @@ public class ChooseFolder extends K9ListActivity {
} finally {
runOnUiThread(new Runnable() {
public void run() {
- // Now we're in the UI-thread, we can safely change the contents of the adapter.
- mAdapter.clear();
- for (String folderName: folderList) {
- mAdapter.add(folderName);
- }
+ // Now we're in the UI-thread, we can safely change the contents of the adapter.
+ mAdapter.clear();
+ for (String folderName: folderList) {
+ mAdapter.add(folderName);
+ }
}
});
}
From 09bc07596ec7bff27ae9a912a86fc5804277fc7d Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 18 Mar 2012 21:48:22 +0100
Subject: [PATCH 27/63] Got rid of unnecessary instance variable
---
src/com/fsck/k9/activity/ChooseFolder.java | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/com/fsck/k9/activity/ChooseFolder.java b/src/com/fsck/k9/activity/ChooseFolder.java
index 98210bc7c..7e7a9e2a4 100644
--- a/src/com/fsck/k9/activity/ChooseFolder.java
+++ b/src/com/fsck/k9/activity/ChooseFolder.java
@@ -47,8 +47,6 @@ public class ChooseFolder extends K9ListActivity {
boolean showOptionNone = false;
boolean showDisplayableOnly = false;
- private List folderList;
-
/**
* What folders to display.
* Initialized to whatever is configured
@@ -370,10 +368,12 @@ public class ChooseFolder extends K9ListActivity {
}
});
int selectedFolder = -1;
- // We're not allowed to change the adapter from a background thread, so we use
- // a java.util.List to build a list of the folder names.
- // We'll add the folder names to the adapter from the UI-thread (see the 'finally' block).
- folderList = new ArrayList();
+
+ /*
+ * We're not allowed to change the adapter from a background thread, so we collect the
+ * folder names and update the adapter in the UI thread (see finally block).
+ */
+ final List folderList = new ArrayList();
try {
int position = 0;
for (String name : localFolders) {
From b7c1f8ab2fb1a2be01ffa783e7491417a7bfd9c5 Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 18 Mar 2012 21:51:01 +0100
Subject: [PATCH 28/63] Prefixed instance variables with "m" to comply with K-9
code style
---
src/com/fsck/k9/activity/ChooseFolder.java | 30 +++++++++++-----------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/com/fsck/k9/activity/ChooseFolder.java b/src/com/fsck/k9/activity/ChooseFolder.java
index 7e7a9e2a4..746d2a17f 100644
--- a/src/com/fsck/k9/activity/ChooseFolder.java
+++ b/src/com/fsck/k9/activity/ChooseFolder.java
@@ -42,10 +42,10 @@ public class ChooseFolder extends K9ListActivity {
MessageReference mMessageReference;
ArrayAdapter mAdapter;
private ChooseFolderHandler mHandler = new ChooseFolderHandler();
- String heldInbox = null;
- boolean hideCurrentFolder = true;
- boolean showOptionNone = false;
- boolean showDisplayableOnly = false;
+ String mHeldInbox = null;
+ boolean mHideCurrentFolder = true;
+ boolean mShowOptionNone = false;
+ boolean mShowDisplayableOnly = false;
/**
* What folders to display.
@@ -59,7 +59,7 @@ public class ChooseFolder extends K9ListActivity {
* Created on the fly and invalidated if a new
* set of folders is chosen via {@link #onOptionsItemSelected(MenuItem)}
*/
- private FolderListFilter myFilter = null;
+ private FolderListFilter mMyFilter = null;
public static final String EXTRA_ACCOUNT = "com.fsck.k9.ChooseFolder_account";
public static final String EXTRA_CUR_FOLDER = "com.fsck.k9.ChooseFolder_curfolder";
@@ -85,13 +85,13 @@ public class ChooseFolder extends K9ListActivity {
mFolder = intent.getStringExtra(EXTRA_CUR_FOLDER);
mSelectFolder = intent.getStringExtra(EXTRA_SEL_FOLDER);
if (intent.getStringExtra(EXTRA_SHOW_CURRENT) != null) {
- hideCurrentFolder = false;
+ mHideCurrentFolder = false;
}
if (intent.getStringExtra(EXTRA_SHOW_FOLDER_NONE) != null) {
- showOptionNone = true;
+ mShowOptionNone = true;
}
if (intent.getStringExtra(EXTRA_SHOW_DISPLAYABLE_ONLY) != null) {
- showDisplayableOnly = true;
+ mShowDisplayableOnly = true;
}
if (mFolder == null)
mFolder = "";
@@ -121,8 +121,8 @@ public class ChooseFolder extends K9ListActivity {
intent.putExtra(EXTRA_ACCOUNT, mAccount.getUuid());
intent.putExtra(EXTRA_CUR_FOLDER, mFolder);
String destFolderName = (String)((TextView)view).getText();
- if (heldInbox != null && getString(R.string.special_mailbox_name_inbox).equals(destFolderName)) {
- destFolderName = heldInbox;
+ if (mHeldInbox != null && getString(R.string.special_mailbox_name_inbox).equals(destFolderName)) {
+ destFolderName = mHeldInbox;
}
intent.putExtra(EXTRA_NEW_FOLDER, destFolderName);
intent.putExtra(EXTRA_MESSAGE, mMessageReference);
@@ -277,8 +277,8 @@ public class ChooseFolder extends K9ListActivity {
private void setDisplayMode(FolderMode aMode) {
mMode = aMode;
// invalidate the current filter as it is working on an inval
- if (myFilter != null) {
- myFilter.invalidate();
+ if (mMyFilter != null) {
+ mMyFilter.invalidate();
}
//re-populate the list
MessagingController.getInstance(getApplication()).listFolders(mAccount,
@@ -322,7 +322,7 @@ public class ChooseFolder extends K9ListActivity {
String name = folder.getName();
// Inbox needs to be compared case-insensitively
- if (hideCurrentFolder && (name.equals(mFolder) ||
+ if (mHideCurrentFolder && (name.equals(mFolder) ||
(mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name)))) {
continue;
}
@@ -345,7 +345,7 @@ public class ChooseFolder extends K9ListActivity {
}
- if (showOptionNone) {
+ if (mShowOptionNone) {
localFolders.add(K9.FOLDER_NONE);
}
@@ -379,7 +379,7 @@ public class ChooseFolder extends K9ListActivity {
for (String name : localFolders) {
if (mAccount.getInboxFolderName().equalsIgnoreCase(name)) {
folderList.add(getString(R.string.special_mailbox_name_inbox));
- heldInbox = name;
+ mHeldInbox = name;
} else if (!K9.ERROR_FOLDER_NAME.equals(name) && !account.getOutboxFolderName().equals(name)) {
folderList.add(name);
}
From 4f2412eacda3daae3181bbaaede6eaaaf4e200b2 Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 18 Mar 2012 22:06:44 +0100
Subject: [PATCH 29/63] Changed code formatting. No functional changes
---
src/com/fsck/k9/activity/ChooseFolder.java | 182 +++++++++++----------
1 file changed, 92 insertions(+), 90 deletions(-)
diff --git a/src/com/fsck/k9/activity/ChooseFolder.java b/src/com/fsck/k9/activity/ChooseFolder.java
index 746d2a17f..170f64358 100644
--- a/src/com/fsck/k9/activity/ChooseFolder.java
+++ b/src/com/fsck/k9/activity/ChooseFolder.java
@@ -36,6 +36,16 @@ import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
public class ChooseFolder extends K9ListActivity {
+ public static final String EXTRA_ACCOUNT = "com.fsck.k9.ChooseFolder_account";
+ public static final String EXTRA_CUR_FOLDER = "com.fsck.k9.ChooseFolder_curfolder";
+ public static final String EXTRA_SEL_FOLDER = "com.fsck.k9.ChooseFolder_selfolder";
+ public static final String EXTRA_NEW_FOLDER = "com.fsck.k9.ChooseFolder_newfolder";
+ public static final String EXTRA_MESSAGE = "com.fsck.k9.ChooseFolder_message";
+ public static final String EXTRA_SHOW_CURRENT = "com.fsck.k9.ChooseFolder_showcurrent";
+ public static final String EXTRA_SHOW_FOLDER_NONE = "com.fsck.k9.ChooseFolder_showOptionNone";
+ public static final String EXTRA_SHOW_DISPLAYABLE_ONLY = "com.fsck.k9.ChooseFolder_showDisplayableOnly";
+
+
String mFolder;
String mSelectFolder;
Account mAccount;
@@ -54,6 +64,7 @@ public class ChooseFolder extends K9ListActivity {
* while this activity is showing.
*/
private Account.FolderMode mMode;
+
/**
* Current filter used by our ArrayAdapter.
* Created on the fly and invalidated if a new
@@ -61,14 +72,6 @@ public class ChooseFolder extends K9ListActivity {
*/
private FolderListFilter mMyFilter = null;
- public static final String EXTRA_ACCOUNT = "com.fsck.k9.ChooseFolder_account";
- public static final String EXTRA_CUR_FOLDER = "com.fsck.k9.ChooseFolder_curfolder";
- public static final String EXTRA_SEL_FOLDER = "com.fsck.k9.ChooseFolder_selfolder";
- public static final String EXTRA_NEW_FOLDER = "com.fsck.k9.ChooseFolder_newfolder";
- public static final String EXTRA_MESSAGE = "com.fsck.k9.ChooseFolder_message";
- public static final String EXTRA_SHOW_CURRENT = "com.fsck.k9.ChooseFolder_showcurrent";
- public static final String EXTRA_SHOW_FOLDER_NONE = "com.fsck.k9.ChooseFolder_showOptionNone";
- public static final String EXTRA_SHOW_DISPLAYABLE_ONLY = "com.fsck.k9.ChooseFolder_showDisplayableOnly";
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -110,55 +113,54 @@ public class ChooseFolder extends K9ListActivity {
setListAdapter(mAdapter);
-
mMode = mAccount.getFolderTargetMode();
MessagingController.getInstance(getApplication()).listFolders(mAccount, false, mListener);
-
this.getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
- Intent intent = new Intent();
- intent.putExtra(EXTRA_ACCOUNT, mAccount.getUuid());
- intent.putExtra(EXTRA_CUR_FOLDER, mFolder);
+ Intent result = new Intent();
+ result.putExtra(EXTRA_ACCOUNT, mAccount.getUuid());
+ result.putExtra(EXTRA_CUR_FOLDER, mFolder);
String destFolderName = (String)((TextView)view).getText();
if (mHeldInbox != null && getString(R.string.special_mailbox_name_inbox).equals(destFolderName)) {
destFolderName = mHeldInbox;
}
- intent.putExtra(EXTRA_NEW_FOLDER, destFolderName);
- intent.putExtra(EXTRA_MESSAGE, mMessageReference);
- setResult(RESULT_OK, intent);
+ result.putExtra(EXTRA_NEW_FOLDER, destFolderName);
+ result.putExtra(EXTRA_MESSAGE, mMessageReference);
+ setResult(RESULT_OK, result);
finish();
}
});
-
}
class ChooseFolderHandler extends Handler {
-
private static final int MSG_PROGRESS = 2;
-
private static final int MSG_DATA_CHANGED = 3;
private static final int MSG_SET_SELECTED_FOLDER = 4;
@Override
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
- case MSG_PROGRESS:
- setProgressBarIndeterminateVisibility(msg.arg1 != 0);
- break;
- case MSG_DATA_CHANGED:
- mAdapter.notifyDataSetChanged();
+ case MSG_PROGRESS: {
+ setProgressBarIndeterminateVisibility(msg.arg1 != 0);
+ break;
+ }
+ case MSG_DATA_CHANGED: {
+ mAdapter.notifyDataSetChanged();
- /*
- * Only enable the text filter after the list has been
- * populated to avoid possible race conditions because our
- * FolderListFilter isn't really thread-safe.
- */
- getListView().setTextFilterEnabled(true);
- break;
- case MSG_SET_SELECTED_FOLDER:
- getListView().setSelection(msg.arg1);
- break;
+ /*
+ * Only enable the text filter after the list has been
+ * populated to avoid possible race conditions because our
+ * FolderListFilter isn't really thread-safe.
+ */
+ getListView().setTextFilterEnabled(true);
+ break;
+ }
+ case MSG_SET_SELECTED_FOLDER: {
+ getListView().setSelection(msg.arg1);
+ break;
+ }
}
}
@@ -181,52 +183,48 @@ public class ChooseFolder extends K9ListActivity {
}
}
- @Override public boolean onCreateOptionsMenu(Menu menu) {
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.folder_select_option, menu);
return true;
}
- @Override public boolean onOptionsItemSelected(MenuItem item) {
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
-
-
- case R.id.display_1st_class: {
- setDisplayMode(FolderMode.FIRST_CLASS);
- return true;
- }
- case R.id.display_1st_and_2nd_class: {
- setDisplayMode(FolderMode.FIRST_AND_SECOND_CLASS);
- return true;
- }
- case R.id.display_not_second_class: {
- setDisplayMode(FolderMode.NOT_SECOND_CLASS);
- return true;
- }
- case R.id.display_all: {
- setDisplayMode(FolderMode.ALL);
- return true;
- }
-
- case R.id.list_folders: {
- onRefresh();
-
- return true;
- }
- case R.id.filter_folders: {
- onEnterFilter();
- }
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ case R.id.display_1st_class: {
+ setDisplayMode(FolderMode.FIRST_CLASS);
+ return true;
+ }
+ case R.id.display_1st_and_2nd_class: {
+ setDisplayMode(FolderMode.FIRST_AND_SECOND_CLASS);
+ return true;
+ }
+ case R.id.display_not_second_class: {
+ setDisplayMode(FolderMode.NOT_SECOND_CLASS);
+ return true;
+ }
+ case R.id.display_all: {
+ setDisplayMode(FolderMode.ALL);
+ return true;
+ }
+ case R.id.list_folders: {
+ onRefresh();
+ return true;
+ }
+ case R.id.filter_folders: {
+ onEnterFilter();
+ return true;
+ }
+ default: {
+ return super.onOptionsItemSelected(item);
+ }
}
}
-
private void onRefresh() {
-
MessagingController.getInstance(getApplication()).listFolders(mAccount, true, mListener);
-
}
/**
@@ -238,40 +236,37 @@ public class ChooseFolder extends K9ListActivity {
final EditText input = new EditText(this);
input.addTextChangedListener(new TextWatcher() {
-
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mAdapter.getFilter().filter(input.getText().toString());
}
@Override
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ /* not used */ }
@Override
- public void afterTextChanged(Editable s) {
- }
+ public void afterTextChanged(Editable s) { /* not used */ }
});
input.setHint(R.string.folder_list_filter_hint);
filterAlert.setView(input);
filterAlert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
+ @Override
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString().trim();
mAdapter.getFilter().filter(value);
}
});
- filterAlert.setNegativeButton("Cancel",
- new DialogInterface.OnClickListener() {
+ filterAlert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
public void onClick(DialogInterface dialog, int whichButton) {
mAdapter.getFilter().filter("");
}
});
filterAlert.show();
-
}
private void setDisplayMode(FolderMode aMode) {
@@ -281,8 +276,7 @@ public class ChooseFolder extends K9ListActivity {
mMyFilter.invalidate();
}
//re-populate the list
- MessagingController.getInstance(getApplication()).listFolders(mAccount,
- false, mListener);
+ MessagingController.getInstance(getApplication()).listFolders(mAccount, false, mListener);
}
private MessagingListener mListener = new MessagingListener() {
@@ -322,23 +316,27 @@ public class ChooseFolder extends K9ListActivity {
String name = folder.getName();
// Inbox needs to be compared case-insensitively
- if (mHideCurrentFolder && (name.equals(mFolder) ||
- (mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name)))) {
+ if (mHideCurrentFolder && (name.equals(mFolder) || (
+ mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) &&
+ mAccount.getInboxFolderName().equalsIgnoreCase(name)))) {
continue;
}
try {
folder.refresh(prefs);
Folder.FolderClass fMode = folder.getDisplayClass();
- if ((aMode == Account.FolderMode.FIRST_CLASS && fMode != Folder.FolderClass.FIRST_CLASS)
- || (aMode == Account.FolderMode.FIRST_AND_SECOND_CLASS &&
+ if ((aMode == Account.FolderMode.FIRST_CLASS &&
+ fMode != Folder.FolderClass.FIRST_CLASS) || (
+ aMode == Account.FolderMode.FIRST_AND_SECOND_CLASS &&
fMode != Folder.FolderClass.FIRST_CLASS &&
- fMode != Folder.FolderClass.SECOND_CLASS)
- || (aMode == Account.FolderMode.NOT_SECOND_CLASS && fMode == Folder.FolderClass.SECOND_CLASS)) {
+ fMode != Folder.FolderClass.SECOND_CLASS) || (
+ aMode == Account.FolderMode.NOT_SECOND_CLASS &&
+ fMode == Folder.FolderClass.SECOND_CLASS)) {
continue;
}
} catch (MessagingException me) {
- Log.e(K9.LOG_TAG, "Couldn't get prefs to check for displayability of folder " + folder.getName(), me);
+ Log.e(K9.LOG_TAG, "Couldn't get prefs to check for displayability of folder " +
+ folder.getName(), me);
}
localFolders.add(folder.getName());
@@ -350,6 +348,7 @@ public class ChooseFolder extends K9ListActivity {
}
Collections.sort(localFolders, new Comparator() {
+ @Override
public int compare(String aName, String bName) {
if (K9.FOLDER_NONE.equalsIgnoreCase(aName)) {
return -1;
@@ -380,7 +379,8 @@ public class ChooseFolder extends K9ListActivity {
if (mAccount.getInboxFolderName().equalsIgnoreCase(name)) {
folderList.add(getString(R.string.special_mailbox_name_inbox));
mHeldInbox = name;
- } else if (!K9.ERROR_FOLDER_NAME.equals(name) && !account.getOutboxFolderName().equals(name)) {
+ } else if (!K9.ERROR_FOLDER_NAME.equals(name) &&
+ !account.getOutboxFolderName().equals(name)) {
folderList.add(name);
}
@@ -393,14 +393,16 @@ public class ChooseFolder extends K9ListActivity {
if (name.equals(mSelectFolder)) {
selectedFolder = position;
}
- } else if (name.equals(mFolder) ||
- (mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name))) {
+ } else if (name.equals(mFolder) || (
+ mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) &&
+ mAccount.getInboxFolderName().equalsIgnoreCase(name))) {
selectedFolder = position;
}
position++;
}
} finally {
runOnUiThread(new Runnable() {
+ @Override
public void run() {
// Now we're in the UI-thread, we can safely change the contents of the adapter.
mAdapter.clear();
From 16afff4dfcb6adcedb021d6753feb660a1540e5c Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 18 Mar 2012 22:09:52 +0100
Subject: [PATCH 30/63] Notify the adapter from runOnUiThread() instead of
using Handler
---
src/com/fsck/k9/activity/ChooseFolder.java | 31 ++++++++--------------
1 file changed, 11 insertions(+), 20 deletions(-)
diff --git a/src/com/fsck/k9/activity/ChooseFolder.java b/src/com/fsck/k9/activity/ChooseFolder.java
index 170f64358..1cfdfa976 100644
--- a/src/com/fsck/k9/activity/ChooseFolder.java
+++ b/src/com/fsck/k9/activity/ChooseFolder.java
@@ -135,9 +135,8 @@ public class ChooseFolder extends K9ListActivity {
}
class ChooseFolderHandler extends Handler {
- private static final int MSG_PROGRESS = 2;
- private static final int MSG_DATA_CHANGED = 3;
- private static final int MSG_SET_SELECTED_FOLDER = 4;
+ private static final int MSG_PROGRESS = 1;
+ private static final int MSG_SET_SELECTED_FOLDER = 2;
@Override
public void handleMessage(android.os.Message msg) {
@@ -146,17 +145,6 @@ public class ChooseFolder extends K9ListActivity {
setProgressBarIndeterminateVisibility(msg.arg1 != 0);
break;
}
- case MSG_DATA_CHANGED: {
- mAdapter.notifyDataSetChanged();
-
- /*
- * Only enable the text filter after the list has been
- * populated to avoid possible race conditions because our
- * FolderListFilter isn't really thread-safe.
- */
- getListView().setTextFilterEnabled(true);
- break;
- }
case MSG_SET_SELECTED_FOLDER: {
getListView().setSelection(msg.arg1);
break;
@@ -177,10 +165,6 @@ public class ChooseFolder extends K9ListActivity {
msg.arg1 = position;
sendMessage(msg);
}
-
- public void dataChanged() {
- sendEmptyMessage(MSG_DATA_CHANGED);
- }
}
@Override
@@ -409,12 +393,19 @@ public class ChooseFolder extends K9ListActivity {
for (String folderName: folderList) {
mAdapter.add(folderName);
}
+
+ mAdapter.notifyDataSetChanged();
+
+ /*
+ * Only enable the text filter after the list has been
+ * populated to avoid possible race conditions because our
+ * FolderListFilter isn't really thread-safe.
+ */
+ getListView().setTextFilterEnabled(true);
}
});
}
- mHandler.dataChanged();
-
if (selectedFolder != -1) {
mHandler.setSelectedFolder(selectedFolder);
}
From 8c66a2f835b76f323682862a6f4bc4619a86907c Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 18 Mar 2012 22:13:27 +0100
Subject: [PATCH 31/63] Replaced hardcoded strings with references to string
resources
---
src/com/fsck/k9/activity/ChooseFolder.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/com/fsck/k9/activity/ChooseFolder.java b/src/com/fsck/k9/activity/ChooseFolder.java
index 1cfdfa976..a5b8568fe 100644
--- a/src/com/fsck/k9/activity/ChooseFolder.java
+++ b/src/com/fsck/k9/activity/ChooseFolder.java
@@ -235,7 +235,8 @@ public class ChooseFolder extends K9ListActivity {
input.setHint(R.string.folder_list_filter_hint);
filterAlert.setView(input);
- filterAlert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
+ String okay = getString(R.string.okay_action);
+ filterAlert.setPositiveButton(okay, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString().trim();
@@ -243,7 +244,8 @@ public class ChooseFolder extends K9ListActivity {
}
});
- filterAlert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ String cancel = getString(R.string.cancel_action);
+ filterAlert.setNegativeButton(cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
mAdapter.getFilter().filter("");
From 5245191900f4568a068a1f35160d3d122c325886 Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 18 Mar 2012 22:43:47 +0100
Subject: [PATCH 32/63] Notify the listener provided as argument to
doRefreshRemote()
With this change pressing "Refresh folders" in ChooseFolder actually
refreshes the folder list.
---
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 33acd96f1..290679e86 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -449,7 +449,7 @@ public class MessagingController implements Runnable {
}
}
- private void doRefreshRemote(final Account account, MessagingListener listener) {
+ private void doRefreshRemote(final Account account, final MessagingListener listener) {
put("doRefreshRemote", listener, new Runnable() {
@Override
public void run() {
@@ -492,14 +492,14 @@ public class MessagingController implements Runnable {
localFolders = localStore.getPersonalNamespaces(false);
Folder[] folderArray = localFolders.toArray(EMPTY_FOLDER_ARRAY);
- for (MessagingListener l : getListeners()) {
+ for (MessagingListener l : getListeners(listener)) {
l.listFolders(account, folderArray);
}
- for (MessagingListener l : getListeners()) {
+ for (MessagingListener l : getListeners(listener)) {
l.listFoldersFinished(account);
}
} catch (Exception e) {
- for (MessagingListener l : getListeners()) {
+ for (MessagingListener l : getListeners(listener)) {
l.listFoldersFailed(account, "");
}
addErrorMessage(account, null, e);
From 1d28eb003df376a9ba186fece011d499ef1da96a Mon Sep 17 00:00:00 2001
From: cketti
Date: Mon, 19 Mar 2012 04:44:41 +0100
Subject: [PATCH 33/63] Added a setting to disable marking messages as read on
viewing
---
res/values/strings.xml | 2 ++
res/xml/account_settings_preferences.xml | 11 +++++++++++
src/com/fsck/k9/Account.java | 13 +++++++++++++
src/com/fsck/k9/activity/MessageView.java | 13 +++++++++----
src/com/fsck/k9/activity/setup/AccountSettings.java | 11 ++++++-----
src/com/fsck/k9/controller/MessagingController.java | 2 +-
src/com/fsck/k9/preferences/AccountSettings.java | 3 +++
src/com/fsck/k9/preferences/Settings.java | 2 +-
8 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 820960b66..8d66d64ea 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -549,6 +549,8 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
Searches for unread messages when Notification is openedShow unread countShow the number of unread messages in the notification bar.
+ Mark message as read when opening
+ Mark a message as read when it is opened for viewingEnable refile buttonsShow the Archive, Move, and Spam buttons.
diff --git a/res/xml/account_settings_preferences.xml b/res/xml/account_settings_preferences.xml
index 9fa5a11a6..683827258 100644
--- a/res/xml/account_settings_preferences.xml
+++ b/res/xml/account_settings_preferences.xml
@@ -81,6 +81,17 @@
+
+
+
+
+
+
diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java
index c04e89c06..98c3ddafb 100644
--- a/src/com/fsck/k9/Account.java
+++ b/src/com/fsck/k9/Account.java
@@ -149,6 +149,7 @@ public class Account implements BaseAccount {
private String mCryptoApp;
private boolean mCryptoAutoSignature;
private boolean mCryptoAutoEncrypt;
+ private boolean mMarkMessageAsReadOnView;
private CryptoProvider mCryptoProvider = null;
@@ -236,6 +237,7 @@ public class Account implements BaseAccount {
mCryptoAutoSignature = false;
mCryptoAutoEncrypt = false;
mEnabled = true;
+ mMarkMessageAsReadOnView = true;
searchableFolders = Searchable.ALL;
@@ -391,6 +393,7 @@ public class Account implements BaseAccount {
mCryptoAutoSignature = prefs.getBoolean(mUuid + ".cryptoAutoSignature", false);
mCryptoAutoEncrypt = prefs.getBoolean(mUuid + ".cryptoAutoEncrypt", false);
mEnabled = prefs.getBoolean(mUuid + ".enabled", true);
+ mMarkMessageAsReadOnView = prefs.getBoolean(mUuid + ".markMessageAsReadOnView", true);
}
protected synchronized void delete(Preferences preferences) {
@@ -472,6 +475,7 @@ public class Account implements BaseAccount {
editor.remove(mUuid + ".enabled");
editor.remove(mUuid + ".enableMoveButtons");
editor.remove(mUuid + ".hideMoveButtonsEnum");
+ editor.remove(mUuid + ".markMessageAsReadOnView");
for (String type : networkTypes) {
editor.remove(mUuid + ".useCompression." + type);
}
@@ -632,6 +636,7 @@ public class Account implements BaseAccount {
editor.putBoolean(mUuid + ".cryptoAutoSignature", mCryptoAutoSignature);
editor.putBoolean(mUuid + ".cryptoAutoEncrypt", mCryptoAutoEncrypt);
editor.putBoolean(mUuid + ".enabled", mEnabled);
+ editor.putBoolean(mUuid + ".markMessageAsReadOnView", mMarkMessageAsReadOnView);
editor.putBoolean(mUuid + ".vibrate", mNotificationSetting.shouldVibrate());
editor.putInt(mUuid + ".vibratePattern", mNotificationSetting.getVibratePattern());
@@ -1500,4 +1505,12 @@ public class Account implements BaseAccount {
public synchronized void setEnabled(boolean enabled) {
mEnabled = enabled;
}
+
+ public synchronized boolean isMarkMessageAsReadOnView() {
+ return mMarkMessageAsReadOnView;
+ }
+
+ public synchronized void setMarkMessageAsReadOnView(boolean value) {
+ mMarkMessageAsReadOnView = value;
+ }
}
diff --git a/src/com/fsck/k9/activity/MessageView.java b/src/com/fsck/k9/activity/MessageView.java
index 1ffb9586e..87d968681 100644
--- a/src/com/fsck/k9/activity/MessageView.java
+++ b/src/com/fsck/k9/activity/MessageView.java
@@ -756,17 +756,16 @@ public class MessageView extends K9Activity implements OnClickListener {
mPrevious.requestFocus();
}
- private void onMarkAsUnread() {
+ private void onToggleRead() {
if (mMessage != null) {
mController.setFlag(mAccount, mMessage.getFolder().getName(),
- new Message[] { mMessage }, Flag.SEEN, false);
+ new Message[] { mMessage }, Flag.SEEN, !mMessage.isSet(Flag.SEEN));
mMessageView.setHeaders(mMessage, mAccount);
String subject = mMessage.getSubject();
setTitle(subject);
}
}
-
private void onDownloadRemainder() {
if (mMessage.isSet(Flag.X_DOWNLOADED_FULL)) {
return;
@@ -833,7 +832,7 @@ public class MessageView extends K9Activity implements OnClickListener {
onSendAlternate();
break;
case R.id.mark_as_unread:
- onMarkAsUnread();
+ onToggleRead();
break;
case R.id.flag:
onFlag();
@@ -944,6 +943,12 @@ public class MessageView extends K9Activity implements OnClickListener {
additionalHeadersItem.setTitle(mMessageView.additionalHeadersVisible() ?
R.string.hide_full_header_action : R.string.show_full_header_action);
}
+
+ if (mMessage != null) {
+ int actionTitle = mMessage.isSet(Flag.SEEN) ?
+ R.string.mark_as_unread_action : R.string.mark_as_read_action;
+ menu.findItem(R.id.mark_as_unread).setTitle(actionTitle);
+ }
}
return super.onPrepareOptionsMenu(menu);
}
diff --git a/src/com/fsck/k9/activity/setup/AccountSettings.java b/src/com/fsck/k9/activity/setup/AccountSettings.java
index 9ac8f7058..f38cfa20f 100644
--- a/src/com/fsck/k9/activity/setup/AccountSettings.java
+++ b/src/com/fsck/k9/activity/setup/AccountSettings.java
@@ -48,6 +48,7 @@ public class AccountSettings extends K9PreferenceActivity {
private static final String PREFERENCE_SCREEN_PUSH_ADVANCED = "push_advanced";
private static final String PREFERENCE_DESCRIPTION = "account_description";
+ private static final String PREFERENCE_MARK_MESSAGE_AS_READ_ON_VIEW = "mark_message_as_read_on_view";
private static final String PREFERENCE_COMPOSITION = "composition";
private static final String PREFERENCE_MANAGE_IDENTITIES = "manage_identities";
private static final String PREFERENCE_FREQUENCY = "account_check_frequency";
@@ -94,9 +95,7 @@ public class AccountSettings extends K9PreferenceActivity {
private static final String PREFERENCE_CRYPTO_APP = "crypto_app";
private static final String PREFERENCE_CRYPTO_AUTO_SIGNATURE = "crypto_auto_signature";
private static final String PREFERENCE_CRYPTO_AUTO_ENCRYPT = "crypto_auto_encrypt";
-
private static final String PREFERENCE_LOCAL_STORAGE_PROVIDER = "local_storage_provider";
-
private static final String PREFERENCE_CATEGORY_FOLDERS = "folders";
private static final String PREFERENCE_ARCHIVE_FOLDER = "archive_folder";
private static final String PREFERENCE_DRAFTS_FOLDER = "drafts_folder";
@@ -114,6 +113,7 @@ public class AccountSettings extends K9PreferenceActivity {
private PreferenceScreen mComposingScreen;
private EditTextPreference mAccountDescription;
+ private CheckBoxPreference mMarkMessageAsReadOnView;
private ListPreference mCheckFrequency;
private ListPreference mDisplayCount;
private ListPreference mMessageAge;
@@ -157,10 +157,7 @@ public class AccountSettings extends K9PreferenceActivity {
private ListPreference mCryptoApp;
private CheckBoxPreference mCryptoAutoSignature;
private CheckBoxPreference mCryptoAutoEncrypt;
-
private ListPreference mLocalStorageProvider;
-
-
private ListPreference mArchiveFolder;
private ListPreference mDraftsFolder;
private ListPreference mSentFolder;
@@ -204,6 +201,9 @@ public class AccountSettings extends K9PreferenceActivity {
}
});
+ mMarkMessageAsReadOnView = (CheckBoxPreference) findPreference(PREFERENCE_MARK_MESSAGE_AS_READ_ON_VIEW);
+ mMarkMessageAsReadOnView.setChecked(mAccount.isMarkMessageAsReadOnView());
+
mMessageFormat = (ListPreference) findPreference(PREFERENCE_MESSAGE_FORMAT);
mMessageFormat.setValue(mAccount.getMessageFormat().name());
mMessageFormat.setSummary(mMessageFormat.getEntry());
@@ -672,6 +672,7 @@ public class AccountSettings extends K9PreferenceActivity {
}
mAccount.setDescription(mAccountDescription.getText());
+ mAccount.setMarkMessageAsReadOnView(mMarkMessageAsReadOnView.isChecked());
mAccount.setNotifyNewMail(mAccountNotify.isChecked());
mAccount.setNotifySelfNewMail(mAccountNotifySelf.isChecked());
mAccount.setShowOngoing(mAccountNotifySync.isChecked());
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index 290679e86..9a7065cbd 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -2846,7 +2846,7 @@ public class MessagingController implements Runnable {
|| message.getId() == 0) {
throw new IllegalArgumentException("Message not found: folder=" + folder + ", uid=" + uid);
}
- if (!message.isSet(Flag.SEEN)) {
+ if (account.isMarkMessageAsReadOnView() && !message.isSet(Flag.SEEN)) {
message.setFlag(Flag.SEEN, true);
setFlag(new Message[] { message }, Flag.SEEN, true);
}
diff --git a/src/com/fsck/k9/preferences/AccountSettings.java b/src/com/fsck/k9/preferences/AccountSettings.java
index fdc311820..f2dcf3669 100644
--- a/src/com/fsck/k9/preferences/AccountSettings.java
+++ b/src/com/fsck/k9/preferences/AccountSettings.java
@@ -96,6 +96,9 @@ public class AccountSettings {
s.put("localStorageProvider", Settings.versions(
new V(1, new StorageProviderSetting())
));
+ s.put("markMessageAsReadOnView", Settings.versions(
+ new V(7, new BooleanSetting(true))
+ ));
s.put("maxPushFolders", Settings.versions(
new V(1, new IntegerRangeSetting(0, 100, 10))
));
diff --git a/src/com/fsck/k9/preferences/Settings.java b/src/com/fsck/k9/preferences/Settings.java
index 3b2bbb979..637d6d74d 100644
--- a/src/com/fsck/k9/preferences/Settings.java
+++ b/src/com/fsck/k9/preferences/Settings.java
@@ -35,7 +35,7 @@ public class Settings {
*
* @see SettingsExporter
*/
- public static final int VERSION = 6;
+ public static final int VERSION = 7;
public static Map validate(int version, Map> settings,
From 8180fd9ad2113c5c92a9ea7de2d19b396ffa10f8 Mon Sep 17 00:00:00 2001
From: cketti
Date: Thu, 22 Mar 2012 22:17:10 +0100
Subject: [PATCH 34/63] Added a button to switch the identity in MessageCompose
Originally I wanted to use a Spinner, but it doesn't support multiple
view types (see [1]). Those are necessary because we use different
layouts for accounts (section headers) and identities (selectable list
items).
Removed the ChooseAccount activity because it's now unused.
---
res/layout/choose_account.xml | 9 -
res/layout/choose_account_item.xml | 42 +--
res/layout/choose_identity_item.xml | 17 +-
res/layout/message_compose.xml | 33 ++-
res/menu/message_compose_option.xml | 6 -
src/com/fsck/k9/activity/ChooseAccount.java | 243 ------------------
.../k9/activity/K9ExpandableListActivity.java | 18 --
src/com/fsck/k9/activity/MessageCompose.java | 227 ++++++++++++----
8 files changed, 215 insertions(+), 380 deletions(-)
delete mode 100644 res/layout/choose_account.xml
delete mode 100644 src/com/fsck/k9/activity/ChooseAccount.java
delete mode 100644 src/com/fsck/k9/activity/K9ExpandableListActivity.java
diff --git a/res/layout/choose_account.xml b/res/layout/choose_account.xml
deleted file mode 100644
index 09c8fe2d8..000000000
--- a/res/layout/choose_account.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
diff --git a/res/layout/choose_account_item.xml b/res/layout/choose_account_item.xml
index d212594f0..361db3d61 100644
--- a/res/layout/choose_account_item.xml
+++ b/res/layout/choose_account_item.xml
@@ -3,37 +3,21 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
- android:paddingRight="6dip"
- android:paddingBottom="2dip"
- android:descendantFocusability="blocksDescendants"
- android:gravity="center_vertical" >
+ android:background="#cccccc"
+ android:gravity="left|center_vertical">
-
-
-
-
-
-
-
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:paddingTop="2dp"
+ android:paddingLeft="18dp"
+ android:paddingRight="4dp"
+ android:paddingBottom="2dp"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
diff --git a/res/layout/choose_identity_item.xml b/res/layout/choose_identity_item.xml
index 0f1999003..600bb8b75 100644
--- a/res/layout/choose_identity_item.xml
+++ b/res/layout/choose_identity_item.xml
@@ -5,25 +5,20 @@
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
- android:paddingRight="6dip"
- android:paddingBottom="2dip"
- android:descendantFocusability="blocksDescendants"
- android:gravity="center_vertical" >
+ android:gravity="center_vertical">
+ android:layout_width="6dp"/>
+ android:paddingLeft="12dp"
+ android:paddingRight="4dp">
+ android:textAppearance="?android:attr/textAppearanceMedium"/>
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml
index 2cafb2428..70d3be985 100644
--- a/res/layout/message_compose.xml
+++ b/res/layout/message_compose.xml
@@ -20,17 +20,34 @@
-
+ android:orientation="horizontal">
+
+
+
+
+
+
+
- identities = account.getIdentities();
- final Identity identity = (Identity) extras.getSerializable(EXTRA_IDENTITY);
- if (identity == null) {
- expandableListView.setSelectedChild(i, 0, true);
- break;
- }
- for (int j = 0; j < identities.size(); j++) {
- final Identity loopIdentity = identities.get(j);
- if (identity.equals(loopIdentity)) {
- expandableListView.setSelectedChild(i, j, true);
- break;
- }
- }
- break;
- }
- }
- }
- }
-
- private IdentitiesAdapter createAdapter() {
- return new IdentitiesAdapter(this, getLayoutInflater());
- }
-
- /**
- * Dynamically provides accounts/identities data for
- * {@link ExpandableListView#setAdapter(ExpandableListAdapter)}:
- *
- *
- *
Groups represent {@link Account accounts}
- *
Children represent {@link Identity identities} of the parent account
- *
- */
- public static class IdentitiesAdapter extends BaseExpandableListAdapter {
-
- private Context mContext;
- private LayoutInflater mLayoutInflater;
- private Account[] mAccounts;
-
- public IdentitiesAdapter(final Context context, final LayoutInflater layoutInflater) {
- mContext = context;
- mLayoutInflater = layoutInflater;
- Preferences prefs = Preferences.getPreferences(mContext);
- mAccounts = prefs.getAvailableAccounts().toArray(EMPTY_ACCOUNT_ARRAY);
- }
-
- @Override
- public Object getChild(int groupPosition, int childPosition) {
- return getAccounts()[groupPosition].getIdentity(childPosition);
- }
-
- @Override
- public long getChildId(int groupPosition, int childPosition) {
- return Integer.valueOf(childPosition).longValue();
- }
-
- @Override
- public int getChildrenCount(int groupPosition) {
- return getAccounts()[groupPosition].getIdentities().size();
- }
-
- @Override
- public Object getGroup(int groupPosition) {
- return getAccounts()[groupPosition];
- }
-
- @Override
- public int getGroupCount() {
- return getAccounts().length;
- }
-
- @Override
- public long getGroupId(int groupPosition) {
- return Integer.valueOf(groupPosition).longValue();
- }
-
- @Override
- public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
- ViewGroup parent) {
- final View v;
- if (convertView == null) {
- v = mLayoutInflater.inflate(R.layout.choose_account_item, parent, false);
- } else {
- v = convertView;
- }
-
- final TextView description = (TextView) v.findViewById(R.id.description);
- final Account account = getAccounts()[groupPosition];
- description.setText(account.getDescription());
- description.setTextSize(TypedValue.COMPLEX_UNIT_SP, K9.getFontSizes().getAccountName());
-
- // display unavailable accounts translucent
- /*
- * 20101030/fiouzy: NullPointerException on null getBackground()
- *
- if (account.isAvailable(parent.getContext()))
- {
- description.getBackground().setAlpha(255);
- description.getBackground().setAlpha(255);
- }
- else
- {
- description.getBackground().setAlpha(127);
- description.getBackground().setAlpha(127);
- }
- */
-
- v.findViewById(R.id.chip).setBackgroundColor(account.getChipColor());
-
- return v;
- }
-
- @Override
- public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
- View convertView, ViewGroup parent) {
- final Account account = getAccounts()[groupPosition];
- final Identity identity = account.getIdentity(childPosition);
-
- final View v;
- if (convertView == null) {
- v = mLayoutInflater.inflate(R.layout.choose_identity_item, parent, false);
- } else {
- v = convertView;
- }
-
- final TextView name = (TextView) v.findViewById(R.id.name);
- final TextView description = (TextView) v.findViewById(R.id.description);
- name.setTextSize(TypedValue.COMPLEX_UNIT_SP, K9.getFontSizes().getAccountName());
- description.setTextSize(TypedValue.COMPLEX_UNIT_SP, K9.getFontSizes().getAccountDescription());
-
- name.setText(identity.getDescription());
- description.setText(String.format("%s <%s>", identity.getName(), identity.getEmail()));
-
- v.findViewById(R.id.chip).setBackgroundColor(account.getChipColor());
-
- return v;
- }
-
- @Override
- public boolean hasStableIds() {
- // returning false since accounts/identities are mutable
- return false;
- }
-
- @Override
- public boolean isChildSelectable(int groupPosition, int childPosition) {
- return true;
- }
-
- private Account[] getAccounts() {
- return mAccounts;
- }
- }
-}
diff --git a/src/com/fsck/k9/activity/K9ExpandableListActivity.java b/src/com/fsck/k9/activity/K9ExpandableListActivity.java
deleted file mode 100644
index 3e1b509a7..000000000
--- a/src/com/fsck/k9/activity/K9ExpandableListActivity.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.fsck.k9.activity;
-
-import android.app.ExpandableListActivity;
-import android.os.Bundle;
-
-import com.fsck.k9.K9;
-
-/**
- * @see ExpandableListActivity
- */
-public class K9ExpandableListActivity extends ExpandableListActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setTheme(K9.getK9Theme());
- super.onCreate(savedInstanceState);
- }
-}
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index e14c34c8e..01df80ebb 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -15,6 +15,7 @@ import com.fsck.k9.mail.*;
import com.fsck.k9.view.MessageWebView;
import org.apache.james.mime4j.codec.EncoderUtil;
import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.ContentResolver;
import android.content.Context;
@@ -31,14 +32,17 @@ import android.provider.OpenableColumns;
import android.text.util.Rfc822Tokenizer;
import android.util.Log;
import android.util.TypedValue;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
+import android.view.ViewGroup;
import android.view.Window;
import android.webkit.WebView;
import android.widget.AutoCompleteTextView.Validator;
+import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
@@ -84,6 +88,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
private static final int DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED = 2;
private static final int DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY = 3;
private static final int DIALOG_CONFIRM_DISCARD_ON_BACK = 4;
+ private static final int DIALOG_CHOOSE_IDENTITY = 5;
private static final long INVALID_DRAFT_ID = MessagingController.INVALID_MESSAGE_ID;
@@ -128,12 +133,11 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
private static final int MSG_DISCARDED_DRAFT = 6;
private static final int ACTIVITY_REQUEST_PICK_ATTACHMENT = 1;
- private static final int ACTIVITY_CHOOSE_IDENTITY = 2;
- private static final int ACTIVITY_CHOOSE_ACCOUNT = 3;
- private static final int CONTACT_PICKER_TO = 4;
- private static final int CONTACT_PICKER_CC = 5;
- private static final int CONTACT_PICKER_BCC = 6;
+ private static final int CONTACT_PICKER_TO = 2;
+ private static final int CONTACT_PICKER_CC = 3;
+ private static final int CONTACT_PICKER_BCC = 4;
+ private static final Account[] EMPTY_ACCOUNT_ARRAY = new Account[0];
/**
* Regular expression to remove the first localized "Re:" prefix in subjects.
@@ -186,7 +190,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
private QuotedTextMode mQuotedTextMode = QuotedTextMode.NONE;
- private TextView mFromView;
+ private Button mChooseIdentityButton;
private LinearLayout mCcWrapper;
private LinearLayout mBccWrapper;
private MultiAutoCompleteTextView mToView;
@@ -410,7 +414,14 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
mAddressAdapter = EmailAddressAdapter.getInstance(this);
mAddressValidator = new EmailAddressValidator();
- mFromView = (TextView) findViewById(R.id.from);
+ mChooseIdentityButton = (Button) findViewById(R.id.identity);
+ mChooseIdentityButton.setOnClickListener(this);
+
+ if (mAccount.getIdentities().size() == 1 &&
+ Preferences.getPreferences(this).getAvailableAccounts().size() == 1) {
+ findViewById(R.id.identity_container).setVisibility(View.GONE);
+ }
+
mToView = (MultiAutoCompleteTextView) findViewById(R.id.to);
mCcView = (MultiAutoCompleteTextView) findViewById(R.id.cc);
mBccView = (MultiAutoCompleteTextView) findViewById(R.id.bcc);
@@ -548,8 +559,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
mQuotedTextEdit.setOnClickListener(this);
mQuotedTextDelete.setOnClickListener(this);
- mFromView.setVisibility(View.GONE);
-
mToView.setAdapter(mAddressAdapter);
mToView.setTokenizer(new Rfc822Tokenizer());
mToView.setValidator(mAddressValidator);
@@ -607,8 +616,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
mReadReceipt = mAccount.isMessageReadReceiptAlways();
mQuoteStyle = mAccount.getQuoteStyle();
+ updateFrom();
+
if (!mSourceMessageProcessed) {
- updateFrom();
updateSignature();
if (ACTION_REPLY.equals(action) ||
@@ -1776,12 +1786,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
addAttachment(data.getData());
mDraftNeedsSaving = true;
break;
- case ACTIVITY_CHOOSE_IDENTITY:
- onIdentityChosen(data);
- break;
- case ACTIVITY_CHOOSE_ACCOUNT:
- onAccountChosen(data);
- break;
case CONTACT_PICKER_TO:
case CONTACT_PICKER_CC:
case CONTACT_PICKER_BCC:
@@ -1811,15 +1815,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
startActivityForResult(mContacts.contactPickerIntent(), resultId);
}
-
-
- private void onAccountChosen(final Intent intent) {
- final Bundle extras = intent.getExtras();
- final String uuid = extras.getString(ChooseAccount.EXTRA_ACCOUNT);
- final Identity identity = (Identity) extras.getSerializable(ChooseAccount.EXTRA_IDENTITY);
-
- final Account account = Preferences.getPreferences(this).getAccount(uuid);
-
+ private void onAccountChosen(Account account, Identity identity) {
if (!mAccount.equals(account)) {
if (K9.DEBUG) {
Log.v(K9.LOG_TAG, "Switching account from " + mAccount + " to " + account);
@@ -1863,11 +1859,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
switchToIdentity(identity);
}
- private void onIdentityChosen(Intent intent) {
- Bundle bundle = intent.getExtras();
- switchToIdentity((Identity) bundle.getSerializable(ChooseIdentity.EXTRA_IDENTITY));
- }
-
private void switchToIdentity(Identity identity) {
mIdentity = identity;
mIdentityChanged = true;
@@ -1877,10 +1868,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
}
private void updateFrom() {
- if (mIdentityChanged) {
- mFromView.setVisibility(View.VISIBLE);
- }
- mFromView.setText(getString(R.string.message_view_from_format, mIdentity.getName(), mIdentity.getEmail()));
+ mChooseIdentityButton.setText(getIdentityDescription(mIdentity));
}
private void updateSignature() {
@@ -1923,6 +1911,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
MessagingController.getInstance(getApplication()).loadMessageForView(account, folderName, sourceMessageUid, null);
}
break;
+ case R.id.identity:
+ showDialog(DIALOG_CHOOSE_IDENTITY);
+ break;
}
}
@@ -1989,9 +1980,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
case R.id.add_attachment_video:
onAddAttachment2("video/*");
break;
- case R.id.choose_identity:
- onChooseIdentity();
- break;
case R.id.read_receipt:
onReadReceipt();
default:
@@ -2000,25 +1988,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
return true;
}
- private void onChooseIdentity() {
- // keep things simple: trigger account choice only if there are more
- // than 1 account
- mIgnoreOnPause = true;
- if (Preferences.getPreferences(this).getAvailableAccounts().size() > 1) {
- final Intent intent = new Intent(this, ChooseAccount.class);
- intent.putExtra(ChooseAccount.EXTRA_ACCOUNT, mAccount.getUuid());
- intent.putExtra(ChooseAccount.EXTRA_IDENTITY, mIdentity);
- startActivityForResult(intent, ACTIVITY_CHOOSE_ACCOUNT);
- } else if (mAccount.getIdentities().size() > 1) {
- Intent intent = new Intent(this, ChooseIdentity.class);
- intent.putExtra(ChooseIdentity.EXTRA_ACCOUNT, mAccount.getUuid());
- startActivityForResult(intent, ACTIVITY_CHOOSE_IDENTITY);
- } else {
- Toast.makeText(this, getString(R.string.no_identities),
- Toast.LENGTH_LONG).show();
- }
- }
-
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
@@ -2148,6 +2117,19 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
}
})
.create();
+ case DIALOG_CHOOSE_IDENTITY:
+ Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.send_as);
+ final IdentityAdapter adapter = new IdentityAdapter(this, getLayoutInflater());
+ builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ IdentityContainer container = (IdentityContainer) adapter.getItem(which);
+ onAccountChosen(container.account, container.identity);
+ }
+ });
+
+ return builder.create();
}
return super.onCreateDialog(id);
}
@@ -3184,4 +3166,137 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
return insertable;
}
+
+ /**
+ * Used to store an {@link Identity} instance together with the {@link Account} it belongs to.
+ *
+ * @see IdentityAdapter
+ */
+ static class IdentityContainer {
+ public final Identity identity;
+ public final Account account;
+
+ IdentityContainer(Identity identity, Account account) {
+ this.identity = identity;
+ this.account = account;
+ }
+ }
+
+ /**
+ * Adapter for the Choose identity list view.
+ *
+ *
+ * Account names are displayed as section headers, identities as selectable list items.
+ *
+ */
+ static class IdentityAdapter extends BaseAdapter {
+ private LayoutInflater mLayoutInflater;
+ private List
+
-
-
-
+
+
-
-
+
-
+
Date: Thu, 22 Mar 2012 21:25:57 +0100
Subject: [PATCH 36/63] Fixed indentation
---
res/layout/message_compose.xml | 46 ++++++++++++++++++----------------
1 file changed, 25 insertions(+), 21 deletions(-)
diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml
index a033df2cf..4e5149a9c 100644
--- a/res/layout/message_compose.xml
+++ b/res/layout/message_compose.xml
@@ -55,6 +55,7 @@
android:layout_marginLeft="6dip"
android:layout_marginRight="6dip"
android:layout_width="fill_parent">
+
+ android:layout_weight="5"/>
+
-
+ android:layout_marginTop="1dip"/>
+
+
+
+
-
-
+ android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+
+
+
+
+ android:textAppearance="?android:attr/textAppearanceMedium"/>
+
-
+ android:src="@drawable/ic_button_contacts"/>
+
+
Date: Thu, 22 Mar 2012 23:37:03 +0100
Subject: [PATCH 37/63] Tweaked MessageCompose layout
---
res/layout/message_compose.xml | 53 +++++++++++++++++-----------------
res/values/strings.xml | 6 ++++
2 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml
index 4e5149a9c..b6ac2da71 100644
--- a/res/layout/message_compose.xml
+++ b/res/layout/message_compose.xml
@@ -9,8 +9,8 @@
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
- android:scrollbarStyle="outsideInset"
- android:fillViewport="true" >
+ android:scrollbarStyle="insideOverlay"
+ android:fillViewport="true">
+ android:layout_weight="1"/>
@@ -89,9 +89,9 @@
@@ -120,10 +120,10 @@
@@ -228,6 +228,7 @@
@@ -235,8 +236,8 @@
@@ -265,9 +267,7 @@
android:padding="0dip"
android:layout_gravity="right"
android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true" />
+ android:layout_width="match_parent"/>
@@ -301,19 +301,17 @@
@@ -324,12 +322,13 @@
android:id="@+id/lower_signature"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_weight="1.0"
android:gravity="left|top"
android:editable="false"
android:minLines="0"
android:autoText="true"
android:capitalize="sentences"
+ android:hint="@string/message_compose_signature_hint"
+ android:inputType="textMultiLine|textAutoCorrect|textCapSentences"
android:textColor="@android:color/primary_text_light"
android:textAppearance="?android:attr/textAppearanceMedium" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8d66d64ea..c1cfb2b26 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -260,6 +260,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
BccSubjectMessage text
+ Signature-------- Original Message --------Subject:Sent:
@@ -273,6 +274,11 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
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
+ Add recipient (To)
+ Add recipient (CC)
+ Add recipient (BCC)
+ Remove quoted text
+ Edit quoted textFrom: %s <%s>To:
From 365f8e71e049f411c363ebeade991c8073bfd3a9 Mon Sep 17 00:00:00 2001
From: cketti
Date: Fri, 23 Mar 2012 04:20:29 +0100
Subject: [PATCH 38/63] Fixed array length calculation
---
src/com/fsck/k9/controller/MessagingController.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index 9a7065cbd..bf7a3233b 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -2085,7 +2085,7 @@ public class MessagingController implements Runnable {
PendingCommand command = new PendingCommand();
command.command = PENDING_COMMAND_MOVE_OR_COPY_BULK_NEW;
- int length = 3 + uids.length;
+ int length = 4 + uids.length;
command.arguments = new String[length];
command.arguments[0] = srcFolder;
command.arguments[1] = destFolder;
From 580f1639c39b10adea67cf6248141cfb9a919f20 Mon Sep 17 00:00:00 2001
From: Jesse Vincent
Date: Fri, 23 Mar 2012 21:34:29 -0400
Subject: [PATCH 39/63] UI improvements to the "select identity" button
---
res/layout/message_compose.xml | 11 +----------
src/com/fsck/k9/activity/MessageCompose.java | 2 +-
2 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml
index b6ac2da71..18b775573 100644
--- a/res/layout/message_compose.xml
+++ b/res/layout/message_compose.xml
@@ -29,20 +29,11 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
-
-
-
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index 01df80ebb..73d367409 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -1868,7 +1868,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
}
private void updateFrom() {
- mChooseIdentityButton.setText(getIdentityDescription(mIdentity));
+ mChooseIdentityButton.setText(mIdentity.getEmail());
}
private void updateSignature() {
From ea90e24785a3d2d1e74a3acea37183c927cde80d Mon Sep 17 00:00:00 2001
From: Jesse Vincent
Date: Fri, 23 Mar 2012 22:00:53 -0400
Subject: [PATCH 40/63] move the chips, change the sizes
---
res/layout/choose_account_item.xml | 10 +++++++---
res/layout/choose_identity_item.xml | 6 +-----
src/com/fsck/k9/activity/MessageCompose.java | 6 +-----
3 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/res/layout/choose_account_item.xml b/res/layout/choose_account_item.xml
index 361db3d61..910312441 100644
--- a/res/layout/choose_account_item.xml
+++ b/res/layout/choose_account_item.xml
@@ -6,6 +6,10 @@
android:orientation="horizontal"
android:background="#cccccc"
android:gravity="left|center_vertical">
+
+ android:textAppearance="?android:attr/textAppearanceMedium"/>
diff --git a/res/layout/choose_identity_item.xml b/res/layout/choose_identity_item.xml
index 600bb8b75..cec5d632b 100644
--- a/res/layout/choose_identity_item.xml
+++ b/res/layout/choose_identity_item.xml
@@ -7,10 +7,6 @@
android:orientation="horizontal"
android:gravity="center_vertical">
-
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
Date: Sat, 24 Mar 2012 20:43:17 +0100
Subject: [PATCH 41/63] Added AccountHolder
---
src/com/fsck/k9/activity/MessageCompose.java | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index 31d22f0a5..03417e620 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -3252,18 +3252,20 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
View view = null;
if (item instanceof Account) {
- if (convertView != null && convertView.getTag() instanceof TextView) {
+ if (convertView != null && convertView.getTag() instanceof AccountHolder) {
view = convertView;
} else {
view = mLayoutInflater.inflate(R.layout.choose_account_item, parent, false);
- TextView name = (TextView) view.findViewById(R.id.name);
- view.setTag(name);
+ AccountHolder holder = new AccountHolder();
+ holder.name = (TextView) view.findViewById(R.id.name);
+ holder.chip = view.findViewById(R.id.chip);
+ view.setTag(holder);
}
Account account = (Account) item;
- TextView name = (TextView) view.getTag();
- name.setText(account.getDescription());
- view.findViewById(R.id.chip).setBackgroundColor(account.getChipColor());
+ AccountHolder holder = (AccountHolder) view.getTag();
+ holder.name.setText(account.getDescription());
+ holder.chip.setBackgroundColor(account.getChipColor());
} else if (item instanceof IdentityContainer) {
if (convertView != null && convertView.getTag() instanceof IdentityHolder) {
view = convertView;
@@ -3277,7 +3279,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
IdentityContainer identityContainer = (IdentityContainer) item;
Identity identity = identityContainer.identity;
- Account account = identityContainer.account;
IdentityHolder holder = (IdentityHolder) view.getTag();
holder.name.setText(identity.getDescription());
holder.description.setText(getIdentityDescription(identity));
@@ -3286,6 +3287,11 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
return view;
}
+ static class AccountHolder {
+ public TextView name;
+ public View chip;
+ }
+
static class IdentityHolder {
public TextView name;
public TextView description;
From 661ed080616188aea1e61484052bd9ff91eb467a Mon Sep 17 00:00:00 2001
From: cketti
Date: Sat, 24 Mar 2012 22:51:33 +0100
Subject: [PATCH 42/63] Removed unnecessary layout containers
---
res/layout/choose_identity_item.xml | 47 ++++++++------------
res/layout/message_compose.xml | 17 +++----
src/com/fsck/k9/activity/MessageCompose.java | 2 +-
3 files changed, 25 insertions(+), 41 deletions(-)
diff --git a/res/layout/choose_identity_item.xml b/res/layout/choose_identity_item.xml
index cec5d632b..e641a4025 100644
--- a/res/layout/choose_identity_item.xml
+++ b/res/layout/choose_identity_item.xml
@@ -4,36 +4,27 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
- android:orientation="horizontal"
- android:gravity="center_vertical">
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ android:paddingLeft="12dp"
+ android:paddingRight="4dp">
-
-
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
-
-
-
-
-
+
diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml
index 18b775573..d29c574db 100644
--- a/res/layout/message_compose.xml
+++ b/res/layout/message_compose.xml
@@ -24,20 +24,13 @@
android:orientation="vertical"
android:background="#ededed" >
-
-
-
-
+ android:gravity="left|center"
+ android:layout_marginLeft="6dip"
+ android:layout_marginRight="6dip"/>
Date: Sat, 24 Mar 2012 22:56:51 +0100
Subject: [PATCH 43/63] Fixed a small display issue in MessageCompose
---
res/layout/message_compose.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml
index d29c574db..e84a3e2bd 100644
--- a/res/layout/message_compose.xml
+++ b/res/layout/message_compose.xml
@@ -20,6 +20,7 @@
@@ -212,7 +213,6 @@
From acffe973eb41d27801dec1128d147aa3bc52904f Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 25 Mar 2012 00:28:40 +0100
Subject: [PATCH 44/63] ADT 17 changes
---
.classpath | 1 +
1 file changed, 1 insertion(+)
diff --git a/.classpath b/.classpath
index 323d9666c..7c3f645a0 100644
--- a/.classpath
+++ b/.classpath
@@ -9,5 +9,6 @@
+
From 43cb78d2de6ad01cba5de33a428eb179b545078e Mon Sep 17 00:00:00 2001
From: cketti
Date: Mon, 26 Mar 2012 07:29:10 +0200
Subject: [PATCH 45/63] Fixed display issue in MessageCompose
---
res/layout/message_compose.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml
index e84a3e2bd..f22928a56 100644
--- a/res/layout/message_compose.xml
+++ b/res/layout/message_compose.xml
@@ -217,10 +217,12 @@
+
Date: Mon, 26 Mar 2012 19:41:21 +0200
Subject: [PATCH 46/63] Fixed potential NullPointerException
---
src/com/fsck/k9/controller/MessagingController.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index bf7a3233b..090db17ac 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -2265,10 +2265,12 @@ public class MessagingController implements Runnable {
String newUid = remoteUidMap.get(remoteSrcUid);
Message localDestMessage = localDestFolder.getMessage(localDestUid);
- localDestMessage.setUid(newUid);
- localDestFolder.changeUid((LocalMessage)localDestMessage);
- for (MessagingListener l : getListeners()) {
- l.messageUidChanged(account, destFolder, localDestUid, newUid);
+ if (localDestMessage != null) {
+ localDestMessage.setUid(newUid);
+ localDestFolder.changeUid((LocalMessage)localDestMessage);
+ for (MessagingListener l : getListeners()) {
+ l.messageUidChanged(account, destFolder, localDestUid, newUid);
+ }
}
}
}
From 4e21f049d304c21a8caf6bdf655d0f0925365f0a Mon Sep 17 00:00:00 2001
From: cketti
Date: Mon, 26 Mar 2012 21:36:26 +0200
Subject: [PATCH 47/63] Validate "original message" field of identity header
when loading drafts
---
src/com/fsck/k9/activity/MessageCompose.java | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index de47e2ce7..c85f98a12 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -2384,7 +2384,15 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
if (k9identity.containsKey(IdentityField.ORIGINAL_MESSAGE)) {
mMessageReference = null;
try {
- mMessageReference = new MessageReference(k9identity.get(IdentityField.ORIGINAL_MESSAGE));
+ String originalMessage = k9identity.get(IdentityField.ORIGINAL_MESSAGE);
+ MessageReference messageReference = new MessageReference(originalMessage);
+
+ // Check if this is a valid account in our database
+ Preferences prefs = Preferences.getPreferences(getApplicationContext());
+ Account account = prefs.getAccount(messageReference.accountUuid);
+ if (account != null) {
+ mMessageReference = messageReference;
+ }
} catch (MessagingException e) {
Log.e(K9.LOG_TAG, "Could not decode message reference in identity.", e);
}
From 1266c3c73ec332071e1d72017338bb06dccef82a Mon Sep 17 00:00:00 2001
From: cketti
Date: Tue, 27 Mar 2012 20:41:43 +0200
Subject: [PATCH 48/63] Don't allow invalid values for header/footer insertion
point
---
src/com/fsck/k9/activity/InsertableHtmlContent.java | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/com/fsck/k9/activity/InsertableHtmlContent.java b/src/com/fsck/k9/activity/InsertableHtmlContent.java
index ab413e19d..851f0ca9a 100644
--- a/src/com/fsck/k9/activity/InsertableHtmlContent.java
+++ b/src/com/fsck/k9/activity/InsertableHtmlContent.java
@@ -32,11 +32,20 @@ class InsertableHtmlContent implements Serializable {
}
public void setHeaderInsertionPoint(int headerInsertionPoint) {
- this.headerInsertionPoint = headerInsertionPoint;
+ if (headerInsertionPoint < 0 || headerInsertionPoint > quotedContent.length()) {
+ this.headerInsertionPoint = 0;
+ } else {
+ this.headerInsertionPoint = headerInsertionPoint;
+ }
}
public void setFooterInsertionPoint(int footerInsertionPoint) {
- this.footerInsertionPoint = footerInsertionPoint;
+ int len = quotedContent.length();
+ if (footerInsertionPoint < 0 || footerInsertionPoint > len) {
+ this.footerInsertionPoint = len;
+ } else {
+ this.footerInsertionPoint = footerInsertionPoint;
+ }
}
/**
From d584492a6df117baec2b1aaf20138b77fc8d5744 Mon Sep 17 00:00:00 2001
From: cketti
Date: Thu, 29 Mar 2012 06:33:01 +0200
Subject: [PATCH 49/63] Changed internal representation of the selected theme
in the database
---
src/com/fsck/k9/K9.java | 25 ++++++++++-
src/com/fsck/k9/activity/K9Activity.java | 2 +-
src/com/fsck/k9/activity/K9ListActivity.java | 2 +-
src/com/fsck/k9/activity/setup/Prefs.java | 4 +-
.../fsck/k9/preferences/GlobalSettings.java | 43 ++++++++++++-------
.../fsck/k9/service/RemoteControlService.java | 2 +-
6 files changed, 56 insertions(+), 22 deletions(-)
diff --git a/src/com/fsck/k9/K9.java b/src/com/fsck/k9/K9.java
index 1da5b4d81..cc3065e4a 100644
--- a/src/com/fsck/k9/K9.java
+++ b/src/com/fsck/k9/K9.java
@@ -38,6 +38,9 @@ import com.fsck.k9.service.ShutdownReceiver;
import com.fsck.k9.service.StorageGoneReceiver;
public class K9 extends Application {
+ public static final int THEME_LIGHT = 0;
+ public static final int THEME_DARK = 1;
+
/**
* Components that are interested in knowing when the K9 instance is
* available and ready (Android invokes Application.onCreate() after other
@@ -72,7 +75,7 @@ public class K9 extends Application {
}
private static String language = "";
- private static int theme = android.R.style.Theme_Light;
+ private static int theme = THEME_LIGHT;
private static final FontSizes fontSizes = new FontSizes();
@@ -604,7 +607,17 @@ public class K9 extends Application {
}
K9.setK9Language(sprefs.getString("language", ""));
- K9.setK9Theme(sprefs.getInt("theme", android.R.style.Theme_Light));
+
+ int theme = sprefs.getInt("theme", THEME_LIGHT);
+
+ // We used to save the resource ID of the theme. So convert that to the new format if
+ // necessary.
+ if (theme == THEME_DARK || theme == android.R.style.Theme) {
+ theme = THEME_DARK;
+ } else {
+ theme = THEME_LIGHT;
+ }
+ K9.setK9Theme(theme);
}
private void maybeSetupStrictMode() {
@@ -663,6 +676,14 @@ public class K9 extends Application {
language = nlanguage;
}
+ public static int getK9ThemeResourceId(int theme) {
+ return (theme == THEME_LIGHT) ? android.R.style.Theme_Light : android.R.style.Theme;
+ }
+
+ public static int getK9ThemeResourceId() {
+ return getK9ThemeResourceId(theme);
+ }
+
public static int getK9Theme() {
return theme;
}
diff --git a/src/com/fsck/k9/activity/K9Activity.java b/src/com/fsck/k9/activity/K9Activity.java
index e9a68eccf..1c1a26eab 100644
--- a/src/com/fsck/k9/activity/K9Activity.java
+++ b/src/com/fsck/k9/activity/K9Activity.java
@@ -29,7 +29,7 @@ public class K9Activity extends Activity {
public void onCreate(Bundle icicle, boolean useTheme) {
setLanguage(this, K9.getK9Language());
if (useTheme) {
- setTheme(K9.getK9Theme());
+ setTheme(K9.getK9ThemeResourceId());
}
super.onCreate(icicle);
setupFormats();
diff --git a/src/com/fsck/k9/activity/K9ListActivity.java b/src/com/fsck/k9/activity/K9ListActivity.java
index 204182be2..613b22119 100644
--- a/src/com/fsck/k9/activity/K9ListActivity.java
+++ b/src/com/fsck/k9/activity/K9ListActivity.java
@@ -13,7 +13,7 @@ public class K9ListActivity extends ListActivity {
@Override
public void onCreate(Bundle icicle) {
K9Activity.setLanguage(this, K9.getK9Language());
- setTheme(K9.getK9Theme());
+ setTheme(K9.getK9ThemeResourceId());
super.onCreate(icicle);
setupFormats();
}
diff --git a/src/com/fsck/k9/activity/setup/Prefs.java b/src/com/fsck/k9/activity/setup/Prefs.java
index 1b359b808..abfa5391a 100644
--- a/src/com/fsck/k9/activity/setup/Prefs.java
+++ b/src/com/fsck/k9/activity/setup/Prefs.java
@@ -148,7 +148,7 @@ public class Prefs extends K9PreferenceActivity {
entryVector.toArray(EMPTY_CHAR_SEQUENCE_ARRAY),
entryValueVector.toArray(EMPTY_CHAR_SEQUENCE_ARRAY));
- final String theme = (K9.getK9Theme() == android.R.style.Theme) ? "dark" : "light";
+ final String theme = (K9.getK9Theme() == K9.THEME_DARK) ? "dark" : "light";
mTheme = setupListPreference(PREFERENCE_THEME, theme);
findPreference(PREFERENCE_FONT_SIZE).setOnPreferenceClickListener(
@@ -348,7 +348,7 @@ public class Prefs extends K9PreferenceActivity {
SharedPreferences preferences = Preferences.getPreferences(this).getPreferences();
K9.setK9Language(mLanguage.getValue());
- K9.setK9Theme(mTheme.getValue().equals("dark") ? android.R.style.Theme : android.R.style.Theme_Light);
+ K9.setK9Theme(mTheme.getValue().equals("dark") ? K9.THEME_DARK : K9.THEME_LIGHT);
K9.setAnimations(mAnimations.isChecked());
K9.setGesturesEnabled(mGestures.isChecked());
K9.setCompactLayouts(compactLayouts.isChecked());
diff --git a/src/com/fsck/k9/preferences/GlobalSettings.java b/src/com/fsck/k9/preferences/GlobalSettings.java
index 42ad9312d..d8087fbf4 100644
--- a/src/com/fsck/k9/preferences/GlobalSettings.java
+++ b/src/com/fsck/k9/preferences/GlobalSettings.java
@@ -181,7 +181,7 @@ public class GlobalSettings {
new V(1, new BooleanSetting(false))
));
s.put("theme", Settings.versions(
- new V(1, new ThemeSetting(android.R.style.Theme_Light))
+ new V(1, new ThemeSetting(K9.THEME_LIGHT))
));
s.put("useGalleryBugWorkaround", Settings.versions(
new V(1, new GalleryBugWorkaroundSetting())
@@ -291,34 +291,47 @@ public class GlobalSettings {
/**
* The theme setting.
*/
- public static class ThemeSetting extends PseudoEnumSetting {
- private final Map mMapping;
+ public static class ThemeSetting extends SettingsDescription {
+ private static final String THEME_LIGHT = "light";
+ private static final String THEME_DARK = "dark";
public ThemeSetting(int defaultValue) {
super(defaultValue);
-
- Map mapping = new HashMap();
- mapping.put(android.R.style.Theme_Light, "light");
- mapping.put(android.R.style.Theme, "dark");
- mMapping = Collections.unmodifiableMap(mapping);
- }
-
- @Override
- protected Map getMapping() {
- return mMapping;
}
@Override
public Object fromString(String value) throws InvalidSettingValueException {
try {
Integer theme = Integer.parseInt(value);
- if (mMapping.containsKey(theme)) {
- return theme;
+ if (theme == K9.THEME_LIGHT ||
+ // We used to store the resource ID of the theme in the preference storage,
+ // but don't use the database upgrade mechanism to update the values. So
+ // we have to deal with the old format here.
+ theme == android.R.style.Theme_Light) {
+ return K9.THEME_LIGHT;
+ } else if (theme == K9.THEME_DARK || theme == android.R.style.Theme) {
+ return K9.THEME_DARK;
}
} catch (NumberFormatException e) { /* do nothing */ }
throw new InvalidSettingValueException();
}
+
+ @Override
+ public Object fromPrettyString(String value) throws InvalidSettingValueException {
+ if (THEME_LIGHT.equals(value)) {
+ return K9.THEME_LIGHT;
+ } else if (THEME_DARK.equals(value)) {
+ return K9.THEME_DARK;
+ }
+
+ throw new InvalidSettingValueException();
+ }
+
+ @Override
+ public String toPrettyString(Object value) {
+ return (((Integer)value).intValue() == K9.THEME_LIGHT) ? THEME_LIGHT : THEME_DARK;
+ }
}
/**
diff --git a/src/com/fsck/k9/service/RemoteControlService.java b/src/com/fsck/k9/service/RemoteControlService.java
index 3cfa52a74..bd21b2061 100644
--- a/src/com/fsck/k9/service/RemoteControlService.java
+++ b/src/com/fsck/k9/service/RemoteControlService.java
@@ -123,7 +123,7 @@ public class RemoteControlService extends CoreService {
String theme = intent.getStringExtra(K9_THEME);
if (theme != null) {
- K9.setK9Theme(K9RemoteControl.K9_THEME_DARK.equals(theme) ? android.R.style.Theme : android.R.style.Theme_Light);
+ K9.setK9Theme(K9RemoteControl.K9_THEME_DARK.equals(theme) ? K9.THEME_DARK : K9.THEME_LIGHT);
}
SharedPreferences sPrefs = preferences.getPreferences();
From 2331696153dbeef1d2873c3b24e4cad5f03332b5 Mon Sep 17 00:00:00 2001
From: cketti
Date: Thu, 29 Mar 2012 06:39:31 +0200
Subject: [PATCH 50/63] Always use the light theme in MessageCompose
This fixes a display bug in the "Send as" dialog in MessageCompose.
---
src/com/fsck/k9/activity/MessageCompose.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java
index c85f98a12..19f94e0c3 100644
--- a/src/com/fsck/k9/activity/MessageCompose.java
+++ b/src/com/fsck/k9/activity/MessageCompose.java
@@ -377,6 +377,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setTheme(K9.getK9ThemeResourceId(K9.THEME_LIGHT));
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.message_compose);
From 240f7ea9ac743ed6d3f4391758c22ae2817c8a33 Mon Sep 17 00:00:00 2001
From: cketti
Date: Fri, 30 Mar 2012 05:24:44 +0200
Subject: [PATCH 51/63] Updated and improved german translation
---
res/values-de/strings.xml | 70 +++++++++++++++++++++++++--------------
1 file changed, 46 insertions(+), 24 deletions(-)
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index e6e26aae5..d22198d54 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -64,7 +64,7 @@
FertigEntfernenVerwerfen
- Als Entwurf speichern
+ SpeichernErneut versuchenAktualisierenNachrichten abrufen
@@ -218,7 +218,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
\n * Speichern von Anhängen auf SD-Karte
\n * Papierkorb leeren
\n * Sortieren der Nachrichten
-\n * ...und viele mehr
+\n * …und viele mehr
\n
\nBitte beachten Sie, dass K-9, wie viele andere E-Mail-Anwendungen auch, die meisten kostenlosen Hotmail-Accounts nicht unterstützt. Zudem gibt es einige Probleme mit Microsoft Exchange-Servern.
\n
@@ -256,6 +256,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
BCCBetreffNachrichtentext
+ Signatur-------- Original-Nachricht --------Betreff:Gesendet:
@@ -269,6 +270,11 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Einige Anhänge wurden nicht heruntergeladen. Sie werden automatisch heruntergeladen, bevor diese Nachricht gesendet wird.Einige Anhänge können nicht weitergeleitet werden, da diese nicht heruntergeladen wurden.Original-Nachricht zitieren
+ Empfänger hinzufügen
+ Empfänger hinzufügen (CC)
+ Empfänger hinzufügen (BCC)
+ Zitierten Text entfernen
+ Zitierten Text bearbeitenVon: %s <%s>An:
@@ -285,6 +291,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Anhang konnte nicht auf SD-Karte gespeichert werden.Wählen Sie \"Bilder anzeigen\", um eingebettete Bilder abzurufen.Bilder anzeigen
+ Zeige NachrichtZeige AnhängeMehr…Lade Anhang.
@@ -402,7 +409,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
TLS (falls verfügbar)TLS (immer)
- Bei Löschen von Nachrichten:
+ Beim Löschen von NachrichtenNie von Server löschenNach 7 Tagen löschenAuch auf Server löschen
@@ -426,7 +433,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Bei jedem AbrufenNur manuell
- IMAP Namensraum automatisch ermitteln
+ IMAP-Namensraum automatisch ermittelnIMAP-VerzeichnispräfixOrdner für Entwürfe
@@ -457,7 +464,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Anmeldung erforderlich.BenutzernamePasswort
- Authentifizierungstyp
+ AuthentifizierungsmethodeBenutzername & PasswortBenutzername
@@ -492,7 +499,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Abruf beim Start der Push-VerbindungPush-Mail für dieses Konto aktivierenNeue Nachrichten werden nach dem Eintreffen umgehend abgerufen, falls Ihr Server dies unterstützt. Diese Einstellung kann zur Reduzierung der Laufzeit führen oder diese verbessern.
- IDLE Verbindung refreshen
+ Push-Verbindung erneuernJede MinuteAlle 2 MinutenAlle 3 Minuten
@@ -544,6 +551,8 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Zeigt beim Öffnen einer Benachrichtigung Liste der ungelesenen Nachrichten anAnzahl ungelesener Nachrichten anzeigenZeigt die Anzahl der ungelesenen Nachrichten in der Statuszeile.
+ Nachricht beim Öffnen als gelesen markieren
+ Markiert eine Nachricht als gelesen, sobald sie zum Betrachten geöffnet wird.Spam-LeisteZeige Archivieren-, Verschieben- und Spam-Schaltfläche.
@@ -582,16 +591,15 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
OrdnerListe der NachrichtenAnzeige der Nachricht
- Prefix beim Zitieren
+ Präfix beim ZitierenKryptographieOpenPGP ProviderKeinerNicht verfügbar
- Auto-sign
- Email Adresse des Kontos verwenden um Signaturschlüssel zu schätzen.
-
- Automatische verschlüsselung
- Verschlüsselung aktivieren falls für den Empfänger ein öffentlichen Schlüssel abgespeichert ist.
+ Automatisches Signieren
+ Verwendet die E-Mail-Adresse des Kontos, um den Signaturschlüssel zu finden.
+ Automatische Verschlüsselung
+ Verschlüsselt automatisch, falls für den Empfänger ein öffentlicher Schlüssel vorhanden ist.Häufigkeit der E-Mail-AbfrageHäufigkeit der Abfrage für Nebenordner
@@ -664,7 +672,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Alle außer NebenordnerÜbernehme Löschungen vom Server
- Lösche Nachrichten wenn sie am Server gelöscht werden
+ Lösche Nachrichten, wenn sie vom Server gelöscht wurdenOrdner-Einstellungen
@@ -776,8 +784,9 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Nachrichten mit Anhängen zuerstNachrichten ohne Anhänge zuerst
- Sortieren nach...
+ Sortieren nach…Datum
+ AnkunftsdatumAbsenderBetreffWichtigkeit
@@ -978,6 +987,9 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
DatumNachrichtentext
+ Nachricht verfassen
+ Texteingabefelder
+
WinzigSehr kleinKleiner
@@ -1019,6 +1031,9 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Entwurf speichern?Entwurf speichern oder verwerfen?
+ Nachricht verwerfen?
+ Sind Sie sicher, dass Sie die Nachricht verwerfen möchten?
+
Speichern des Entwurfs verweigern.Die Speicherung von als verschlüsselt markierten Entwürfen verweigern.
@@ -1058,9 +1073,9 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Einstellungen importierenAuswahl importierenGlobale Einstellungen
- Einstellungen Exportieren...
- Einstellungen Importieren...
- Datei lesen...
+ Einstellungen exportieren…
+ Einstellungen importieren…
+ Datei lesen…Exportiere Einstellungen erfolgreich in %s gespeichertGlobale Einstellungen erfolgreich von %s importiert%s erfolgreich von %s importiert
@@ -1069,21 +1084,21 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
%s KontenExportieren der Einstellungen ist fehlgeschlagen
- Importieren der Einstellungen von %s sind fehlgeschlagen
+ Importieren der Einstellungen von %s ist fehlgeschlagenExport erfolgreichExport fehlgeschlagenImport erfolgreichImport fehlgeschlagenKonto aktivieren
- Um das Konto \"%s\" zu benutzen müssen sie das %s angeben.
+ Um das Konto \"%s\" benutzen zu können, müssen Sie %s angeben.
- Server Passwort
- Server Passwörter
+ das Server Passwort
+ die Server PasswörterPosteingangsserver (%s):Postausgangsserver (%s):
- Passwort Setzen...
+ Passwort setzen...Passwörter setzen...Passwort des Posteingangsservers benutzen
@@ -1093,12 +1108,19 @@ 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 speichern unter…Anhang speichernEs wurde kein Dateimanager gefunden. Wo soll der Anhang abgelegt werden?Nach oben verschiebenNach unten verschieben
- Konto verschieben...
+ Konto verschieben…
+ K-9 Ungelesen
+ Zeige die Anzahl ungelesener Nachrichten für…
+
+ Kein Dateimanager gefunden!
+ Es wurde keine geeignete Applikation gefunden, um den Import durchzuführen. Bitte installieren Sie einen Dateimanager aus dem Play Store.
+ Play Store öffnen
+ Abbrechen
From 1d25d2ff40e7db531d713ea41efbcb84555fc2a6 Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 1 Apr 2012 21:08:31 +0200
Subject: [PATCH 52/63] Added helper class to use the most recent
ClipboardManager
---
src/com/fsck/k9/helper/ClipboardManager.java | 63 +++++++++++++++++++
.../fsck/k9/helper/ClipboardManagerApi1.java | 22 +++++++
.../fsck/k9/helper/ClipboardManagerApi11.java | 23 +++++++
3 files changed, 108 insertions(+)
create mode 100644 src/com/fsck/k9/helper/ClipboardManager.java
create mode 100644 src/com/fsck/k9/helper/ClipboardManagerApi1.java
create mode 100644 src/com/fsck/k9/helper/ClipboardManagerApi11.java
diff --git a/src/com/fsck/k9/helper/ClipboardManager.java b/src/com/fsck/k9/helper/ClipboardManager.java
new file mode 100644
index 000000000..7751b3b89
--- /dev/null
+++ b/src/com/fsck/k9/helper/ClipboardManager.java
@@ -0,0 +1,63 @@
+package com.fsck.k9.helper;
+
+import android.content.Context;
+import android.os.Build;
+
+
+/**
+ * Helper class to access the system clipboard
+ *
+ * @see ClipboardManagerApi1
+ * @see ClipboardManagerApi11
+ */
+public abstract class ClipboardManager {
+ /**
+ * Instance of the API-specific class that interfaces with the clipboard API.
+ */
+ private static ClipboardManager sInstance = null;
+
+ /**
+ * Get API-specific instance of the {@code ClipboardManager} class
+ *
+ * @param context
+ * A {@link Context} instance.
+ *
+ * @return Appropriate {@link ClipboardManager} instance for this device.
+ */
+ public static ClipboardManager getInstance(Context context) {
+ Context appContext = context.getApplicationContext();
+
+ if (sInstance == null) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
+ sInstance = new ClipboardManagerApi1(appContext);
+ } else {
+ sInstance = new ClipboardManagerApi11(appContext);
+ }
+ }
+
+ return sInstance;
+ }
+
+
+ protected Context mContext;
+
+ /**
+ * Constructor
+ *
+ * @param context
+ * A {@link Context} instance.
+ */
+ protected ClipboardManager(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Copy a text string to the system clipboard
+ *
+ * @param label
+ * User-visible label for the content.
+ * @param text
+ * The actual text to be copied to the clipboard.
+ */
+ public abstract void setText(String label, String text);
+}
diff --git a/src/com/fsck/k9/helper/ClipboardManagerApi1.java b/src/com/fsck/k9/helper/ClipboardManagerApi1.java
new file mode 100644
index 000000000..80bfe714c
--- /dev/null
+++ b/src/com/fsck/k9/helper/ClipboardManagerApi1.java
@@ -0,0 +1,22 @@
+package com.fsck.k9.helper;
+
+import android.content.Context;
+import android.text.ClipboardManager;
+
+/**
+ * Access the system clipboard using the now deprecated {@link ClipboardManager}
+ */
+@SuppressWarnings("deprecation")
+public class ClipboardManagerApi1 extends com.fsck.k9.helper.ClipboardManager {
+
+ public ClipboardManagerApi1(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void setText(String label, String text) {
+ ClipboardManager clipboardManager =
+ (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
+ clipboardManager.setText(text);
+ }
+}
diff --git a/src/com/fsck/k9/helper/ClipboardManagerApi11.java b/src/com/fsck/k9/helper/ClipboardManagerApi11.java
new file mode 100644
index 000000000..cae25fa0f
--- /dev/null
+++ b/src/com/fsck/k9/helper/ClipboardManagerApi11.java
@@ -0,0 +1,23 @@
+package com.fsck.k9.helper;
+
+import android.content.ClipData;
+import android.content.Context;
+import android.content.ClipboardManager;
+
+/**
+ * Access the system clipboard using the new {@link ClipboardManager} introduced with API 11
+ */
+public class ClipboardManagerApi11 extends com.fsck.k9.helper.ClipboardManager {
+
+ public ClipboardManagerApi11(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void setText(String label, String text) {
+ ClipboardManager clipboardManager =
+ (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
+ ClipData clip = ClipData.newPlainText(label, text);
+ clipboardManager.setPrimaryClip(clip);
+ }
+}
From 1596ddfaaba40ba751aa4170d813a7ea3841a6e2 Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 1 Apr 2012 21:14:43 +0200
Subject: [PATCH 53/63] Moved sanitizeFilename() to com.fsck.k9.helper.Utility
---
src/com/fsck/k9/helper/Utility.java | 35 ++++++++++++++++++++++++
src/com/fsck/k9/view/AttachmentView.java | 35 +-----------------------
2 files changed, 36 insertions(+), 34 deletions(-)
diff --git a/src/com/fsck/k9/helper/Utility.java b/src/com/fsck/k9/helper/Utility.java
index 340bfabe1..814692219 100644
--- a/src/com/fsck/k9/helper/Utility.java
+++ b/src/com/fsck/k9/helper/Utility.java
@@ -19,6 +19,29 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Utility {
+ /**
+ * Regular expression that represents characters we won't allow in file names.
+ *
+ *
+ * Allowed are:
+ *
+ *
word characters (letters, digits, and underscores): {@code \w}
- */
- private static final String INVALID_CHARACTERS = "[^\\w !#$%&'()\\-@\\^`{}~.,]+";
-
- /**
- * Invalid characters in a file name are replaced by this character.
- */
- private static final String REPLACEMENT_CHARACTER = "_";
-
-
private Context mContext;
public Button viewButton;
public Button downloadButton;
@@ -259,7 +238,7 @@ public class AttachmentView extends FrameLayout implements OnClickListener, OnLo
*/
public void writeFile(File directory) {
try {
- String filename = sanitizeFilename(name);
+ String filename = Utility.sanitizeFilename(name);
File file = Utility.createUniqueFile(directory, filename);
Uri uri = AttachmentProvider.getAttachmentUri(mAccount, part.getAttachmentId());
InputStream in = mContext.getContentResolver().openInputStream(uri);
@@ -278,18 +257,6 @@ public class AttachmentView extends FrameLayout implements OnClickListener, OnLo
}
}
- /**
- * Replace characters we don't allow in file names with a replacement character.
- *
- * @param filename
- * The original file name.
- *
- * @return The sanitized file name containing only allowed characters.
- */
- private String sanitizeFilename(String filename) {
- return filename.replaceAll(INVALID_CHARACTERS, REPLACEMENT_CHARACTER);
- }
-
/**
* saves the file to the defaultpath setting in the config, or if the config
* is not set => to the Environment
From 5819d273946bbb9dd3e15af9025d8cd2c51eea0d Mon Sep 17 00:00:00 2001
From: cketti
Date: Sun, 1 Apr 2012 22:46:36 +0200
Subject: [PATCH 54/63] Added long-press popup menu to WebView in
SingleMessageView
Actions:
- Open link for viewing
- Share link
- Copy link to clipboard
- View image
- Download/save image
- Copy image URL to clipboard
- Call number
- Save phone number to Contacts
- Copy phone number to clipboard
- Send mail
- Save to Contacts
- Copy email address to clipboard
This is based on work done by kernelhunter92 and ShellZero.
Fixed issue 1248
---
res/values/strings.xml | 25 ++
src/com/fsck/k9/helper/Contacts.java | 8 +
src/com/fsck/k9/helper/ContactsSdk5.java | 11 +
src/com/fsck/k9/view/SingleMessageView.java | 370 +++++++++++++++++++-
4 files changed, 412 insertions(+), 2 deletions(-)
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c1cfb2b26..0851d3823 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1141,4 +1141,29 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
the import operation. Please install a file manager application from Android Market
Open MarketClose
+
+ Open for viewing
+ Share link
+ Copy link to clipboard
+ Link
+
+ Image
+ View image
+ Save image
+ Download image
+ Copy image URL to clipboard
+ Image URL
+
+ Call number
+ Save to Contacts
+ Copy phone number to clipboard
+ Phone number
+
+ Send mail
+ Save to Contacts
+ Copy email address to clipboard
+ Email address
+
+ Saved image as \"%s\"
+ Saving the image failed.
diff --git a/src/com/fsck/k9/helper/Contacts.java b/src/com/fsck/k9/helper/Contacts.java
index 7be312c22..c7beb05fd 100644
--- a/src/com/fsck/k9/helper/Contacts.java
+++ b/src/com/fsck/k9/helper/Contacts.java
@@ -104,6 +104,14 @@ public abstract class Contacts {
*/
public abstract void createContact(Address email);
+ /**
+ * Start the activity to add a phone number to an existing contact or add a new one.
+ *
+ * @param phoneNumber
+ * The phone number to add to a contact, or to use when creating a new contact.
+ */
+ public abstract void addPhoneContact(String phoneNumber);
+
/**
* Check whether the provided email address belongs to one of the contacts.
*
diff --git a/src/com/fsck/k9/helper/ContactsSdk5.java b/src/com/fsck/k9/helper/ContactsSdk5.java
index 83b21b567..74c19193a 100644
--- a/src/com/fsck/k9/helper/ContactsSdk5.java
+++ b/src/com/fsck/k9/helper/ContactsSdk5.java
@@ -9,6 +9,8 @@ import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Intents;
import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.Intents.Insert;
+
import com.fsck.k9.mail.Address;
import com.fsck.k9.K9;
@@ -85,6 +87,15 @@ public class ContactsSdk5 extends com.fsck.k9.helper.Contacts {
mContext.startActivity(contactIntent);
}
+ @Override
+ public void addPhoneContact(final String phoneNumber) {
+ Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+ addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
+ addIntent.putExtra(Insert.PHONE, Uri.decode(phoneNumber));
+ addIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(addIntent);
+ }
+
@Override
public boolean isInContacts(final String emailAddress) {
boolean result = false;
diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java
index a19796d8c..3dc1c92a1 100644
--- a/src/com/fsck/k9/view/SingleMessageView.java
+++ b/src/com/fsck/k9/view/SingleMessageView.java
@@ -7,16 +7,26 @@ import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
-import android.view.View.OnClickListener;
+import android.view.View.*;
+import android.webkit.WebView;
+import android.webkit.WebView.HitTestResult;
import android.widget.Button;
import android.widget.LinearLayout;
+import android.widget.Toast;
+
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.R;
@@ -25,16 +35,51 @@ import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.controller.MessagingListener;
import com.fsck.k9.crypto.CryptoProvider;
import com.fsck.k9.crypto.PgpData;
+import com.fsck.k9.helper.ClipboardManager;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.*;
+import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.store.LocalStore;
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
+import com.fsck.k9.provider.AttachmentProvider.AttachmentProviderColumns;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLDecoder;
import java.util.List;
public class SingleMessageView extends LinearLayout implements OnClickListener,
- MessageHeader.OnLayoutChangedListener {
+ MessageHeader.OnLayoutChangedListener, OnCreateContextMenuListener {
+ private static final int MENU_ITEM_LINK_VIEW = Menu.FIRST;
+ private static final int MENU_ITEM_LINK_SHARE = Menu.FIRST + 1;
+ private static final int MENU_ITEM_LINK_COPY = Menu.FIRST + 2;
+
+ private static final int MENU_ITEM_IMAGE_VIEW = Menu.FIRST;
+ private static final int MENU_ITEM_IMAGE_SAVE = Menu.FIRST + 1;
+ private static final int MENU_ITEM_IMAGE_COPY = Menu.FIRST + 2;
+
+ private static final int MENU_ITEM_PHONE_CALL = Menu.FIRST;
+ private static final int MENU_ITEM_PHONE_SAVE = Menu.FIRST + 1;
+ private static final int MENU_ITEM_PHONE_COPY = Menu.FIRST + 2;
+
+ private static final int MENU_ITEM_EMAIL_SEND = Menu.FIRST;
+ private static final int MENU_ITEM_EMAIL_SAVE = Menu.FIRST + 1;
+ private static final int MENU_ITEM_EMAIL_COPY = Menu.FIRST + 2;
+
+ private static final String[] ATTACHMENT_PROJECTION = new String[] {
+ AttachmentProviderColumns._ID,
+ AttachmentProviderColumns.DISPLAY_NAME
+ };
+ private static final int DISPLAY_NAME_INDEX = 1;
+
+
private boolean mScreenReaderEnabled;
private MessageCryptoView mCryptoView;
private MessageWebView mMessageContentView;
@@ -57,11 +102,15 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
private View mAttachmentsContainer;
private LinearLayout mInsideAttachmentsContainer;
private SavedState mSavedState;
+ private ClipboardManager mClipboardManager;
+
public void initialize(Activity activity) {
mMessageContentView = (MessageWebView) findViewById(R.id.message_content);
mAccessibleMessageContentView = (AccessibleWebView) findViewById(R.id.accessible_message_content);
mMessageContentView.configure();
+ activity.registerForContextMenu(mMessageContentView);
+ mMessageContentView.setOnCreateContextMenuListener(this);
mHeaderPlaceHolder = (LinearLayout) findViewById(R.id.message_view_header_container);
@@ -114,6 +163,210 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
mShowMessageAction.setOnClickListener(this);
mShowAttachmentsAction.setOnClickListener(this);
mShowPicturesAction.setOnClickListener(this);
+
+ mClipboardManager = ClipboardManager.getInstance(activity);
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu);
+
+ WebView webview = (WebView) v;
+ WebView.HitTestResult result = webview.getHitTestResult();
+ int type = result.getType();
+ Context context = getContext();
+
+ switch (type) {
+ case HitTestResult.SRC_ANCHOR_TYPE: {
+ final String url = result.getExtra();
+ OnMenuItemClickListener listener = new OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_ITEM_LINK_VIEW: {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ getContext().startActivity(intent);
+ break;
+ }
+ case MENU_ITEM_LINK_SHARE: {
+ Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setType("text/plain");
+ intent.putExtra(Intent.EXTRA_TEXT, url);
+ getContext().startActivity(intent);
+ break;
+ }
+ case MENU_ITEM_LINK_COPY: {
+ String label = getContext().getString(
+ R.string.webview_contextmenu_link_clipboard_label);
+ mClipboardManager.setText(label, url);
+ break;
+ }
+ }
+ return true;
+ }
+ };
+
+ menu.setHeaderTitle(url);
+
+ menu.add(Menu.NONE, MENU_ITEM_LINK_VIEW, 0,
+ context.getString(R.string.webview_contextmenu_link_view_action))
+ .setOnMenuItemClickListener(listener);
+
+ menu.add(Menu.NONE, MENU_ITEM_LINK_SHARE, 1,
+ context.getString(R.string.webview_contextmenu_link_share_action))
+ .setOnMenuItemClickListener(listener);
+
+ menu.add(Menu.NONE, MENU_ITEM_LINK_COPY, 2,
+ context.getString(R.string.webview_contextmenu_link_copy_action))
+ .setOnMenuItemClickListener(listener);
+
+ break;
+ }
+ case HitTestResult.IMAGE_TYPE:
+ case HitTestResult.SRC_IMAGE_ANCHOR_TYPE: {
+ final String url = result.getExtra();
+ final boolean externalImage = url.startsWith("http");
+ OnMenuItemClickListener listener = new OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_ITEM_IMAGE_VIEW: {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ if (!externalImage) {
+ // Grant read permission if this points to our
+ // AttachmentProvider
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ }
+ getContext().startActivity(intent);
+ break;
+ }
+ case MENU_ITEM_IMAGE_SAVE: {
+ new DownloadImageTask().execute(url);
+ break;
+ }
+ case MENU_ITEM_IMAGE_COPY: {
+ String label = getContext().getString(
+ R.string.webview_contextmenu_image_clipboard_label);
+ mClipboardManager.setText(label, url);
+ break;
+ }
+ }
+ return true;
+ }
+ };
+
+ menu.setHeaderTitle((externalImage) ?
+ url : context.getString(R.string.webview_contextmenu_image_title));
+
+ menu.add(Menu.NONE, MENU_ITEM_IMAGE_VIEW, 0,
+ context.getString(R.string.webview_contextmenu_image_view_action))
+ .setOnMenuItemClickListener(listener);
+
+ menu.add(Menu.NONE, MENU_ITEM_IMAGE_SAVE, 1,
+ (externalImage) ?
+ context.getString(R.string.webview_contextmenu_image_download_action) :
+ context.getString(R.string.webview_contextmenu_image_save_action))
+ .setOnMenuItemClickListener(listener);
+
+ if (externalImage) {
+ menu.add(Menu.NONE, MENU_ITEM_IMAGE_COPY, 2,
+ context.getString(R.string.webview_contextmenu_image_copy_action))
+ .setOnMenuItemClickListener(listener);
+ }
+
+ break;
+ }
+ case HitTestResult.PHONE_TYPE: {
+ final String phoneNumber = result.getExtra();
+ OnMenuItemClickListener listener = new OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_ITEM_PHONE_CALL: {
+ Uri uri = Uri.parse(WebView.SCHEME_TEL + phoneNumber);
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ getContext().startActivity(intent);
+ break;
+ }
+ case MENU_ITEM_PHONE_SAVE: {
+ Contacts contacts = Contacts.getInstance(getContext());
+ contacts.addPhoneContact(phoneNumber);
+ break;
+ }
+ case MENU_ITEM_PHONE_COPY: {
+ String label = getContext().getString(
+ R.string.webview_contextmenu_phone_clipboard_label);
+ mClipboardManager.setText(label, phoneNumber);
+ break;
+ }
+ }
+
+ return true;
+ }
+ };
+
+ menu.setHeaderTitle(phoneNumber);
+
+ menu.add(Menu.NONE, MENU_ITEM_PHONE_CALL, 0,
+ context.getString(R.string.webview_contextmenu_phone_call_action))
+ .setOnMenuItemClickListener(listener);
+
+ menu.add(Menu.NONE, MENU_ITEM_PHONE_SAVE, 1,
+ context.getString(R.string.webview_contextmenu_phone_save_action))
+ .setOnMenuItemClickListener(listener);
+
+ menu.add(Menu.NONE, MENU_ITEM_PHONE_COPY, 2,
+ context.getString(R.string.webview_contextmenu_phone_copy_action))
+ .setOnMenuItemClickListener(listener);
+
+ break;
+ }
+ case WebView.HitTestResult.EMAIL_TYPE: {
+ final String email = result.getExtra();
+ OnMenuItemClickListener listener = new OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_ITEM_EMAIL_SEND: {
+ Uri uri = Uri.parse(WebView.SCHEME_MAILTO + email);
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ getContext().startActivity(intent);
+ break;
+ }
+ case MENU_ITEM_EMAIL_SAVE: {
+ Contacts contacts = Contacts.getInstance(getContext());
+ contacts.createContact(new Address(email));
+ break;
+ }
+ case MENU_ITEM_EMAIL_COPY: {
+ String label = getContext().getString(
+ R.string.webview_contextmenu_email_clipboard_label);
+ mClipboardManager.setText(label, email);
+ break;
+ }
+ }
+
+ return true;
+ }
+ };
+
+ menu.setHeaderTitle(email);
+
+ menu.add(Menu.NONE, MENU_ITEM_EMAIL_SEND, 0,
+ context.getString(R.string.webview_contextmenu_email_send_action))
+ .setOnMenuItemClickListener(listener);
+
+ menu.add(Menu.NONE, MENU_ITEM_EMAIL_SAVE, 1,
+ context.getString(R.string.webview_contextmenu_email_save_action))
+ .setOnMenuItemClickListener(listener);
+
+ menu.add(Menu.NONE, MENU_ITEM_EMAIL_COPY, 2,
+ context.getString(R.string.webview_contextmenu_email_copy_action))
+ .setOnMenuItemClickListener(listener);
+
+ break;
+ }
+ }
}
@Override
@@ -555,4 +808,117 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
out.writeInt((this.showPictures) ? 1 : 0);
}
}
+
+ class DownloadImageTask extends AsyncTask {
+ @Override
+ protected String doInBackground(String... params) {
+ String urlString = params[0];
+ try {
+ boolean externalImage = urlString.startsWith("http");
+
+ String filename = null;
+ String mimeType = null;
+ InputStream in = null;
+
+ try {
+ if (externalImage) {
+ URL url = new URL(urlString);
+ URLConnection conn = url.openConnection();
+ in = conn.getInputStream();
+
+ String path = url.getPath();
+
+ // Try to get the filename from the URL
+ int start = path.lastIndexOf("/");
+ if (start != -1 && start + 1 < path.length()) {
+ filename = URLDecoder.decode(path.substring(start + 1), "UTF-8");
+ } else {
+ // Use a dummy filename if necessary
+ filename = "saved_image";
+ }
+
+ // Get the MIME type if we couldn't find a file extension
+ if (filename.indexOf('.') == -1) {
+ mimeType = conn.getContentType();
+ }
+ } else {
+ ContentResolver contentResolver = getContext().getContentResolver();
+ Uri uri = Uri.parse(urlString);
+
+ // Get the filename from AttachmentProvider
+ Cursor cursor = contentResolver.query(uri, ATTACHMENT_PROJECTION, null, null, null);
+ if (cursor != null) {
+ try {
+ if (cursor.moveToNext()) {
+ filename = cursor.getString(DISPLAY_NAME_INDEX);
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ // Use a dummy filename if necessary
+ if (filename == null) {
+ filename = "saved_image";
+ }
+
+ // Get the MIME type if we couldn't find a file extension
+ if (filename.indexOf('.') == -1) {
+ mimeType = contentResolver.getType(uri);
+ }
+
+ in = contentResolver.openInputStream(uri);
+ }
+
+ // Do we still need an extension?
+ if (filename.indexOf('.') == -1) {
+ // Use JPEG as fallback
+ String extension = "jpeg";
+ if (mimeType != null) {
+ // Try to find an extension for the given MIME type
+ String ext = MimeUtility.getExtensionByMimeType(mimeType);
+ if (ext != null) {
+ extension = ext;
+ }
+ }
+ filename += "." + extension;
+ }
+
+ String sanitized = Utility.sanitizeFilename(filename);
+
+ File directory = new File(K9.getAttachmentDefaultPath());
+ File file = Utility.createUniqueFile(directory, sanitized);
+ FileOutputStream out = new FileOutputStream(file);
+ try {
+ IOUtils.copy(in, out);
+ out.flush();
+ } finally {
+ out.close();
+ }
+
+ return file.getName();
+
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ @Override
+ protected void onPostExecute(String filename) {
+ String text;
+ if (filename == null) {
+ text = getContext().getString(R.string.image_saving_failed);
+ } else {
+ text = getContext().getString(R.string.image_saved_as, filename);
+ }
+
+ Toast.makeText(getContext(), text, Toast.LENGTH_LONG).show();
+ }
+ }
}
From 7715e396c482058eaf3c705c3447058003e58512 Mon Sep 17 00:00:00 2001
From: cketti
Date: Mon, 2 Apr 2012 01:35:02 +0200
Subject: [PATCH 55/63] Updated german translation
---
res/values-de/strings.xml | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index d22198d54..0fbd2d7d1 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -1123,4 +1123,29 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
Es wurde keine geeignete Applikation gefunden, um den Import durchzuführen. Bitte installieren Sie einen Dateimanager aus dem Play Store.Play Store öffnenAbbrechen
+
+ Öffnen
+ Link weitergeben
+ Link kopieren
+ Link
+
+ Bild
+ Bild anzeigen
+ Bild speichern
+ Bild herunterladen
+ Bild-URL kopieren
+ Bild-URL
+
+ Anrufen
+ Im Adressbuch speichern
+ Telefonnummer kopieren
+ Telefonnummer
+
+ E-Mail senden
+ Im Adressbuch speichern
+ E-Mail-Adresse kopieren
+ E-Mail-Adresse
+
+ Das Bild wurde als \"%s\" gespeichert.
+ Speichern des Bildes fehlgeschlagen.
From d1c065230f921ede45ffe389ffd235dd6eae8440 Mon Sep 17 00:00:00 2001
From: Koji Arai
Date: Tue, 3 Apr 2012 00:02:52 +0900
Subject: [PATCH 56/63] Updated Japanese translation. catch up with 5819d27.
---
res/values-ja/strings.xml | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 4c678800b..4e43c6997 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -258,6 +258,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
Bcc件名本文
+ 署名-------- 元メール --------件名:送信日:
@@ -271,6 +272,11 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
一部の添付ファイルをダウンロードしていません。このメールが送信される前に自動的にダウンロードされます。ダウンロードしていないため、一部の添付ファイルを転送することはできません。元のメッセージを引用する
+ Toに宛先を追加します
+ CCに宛先を追加します
+ BCCに宛先を追加します
+ 引用文を削除します
+ 引用文を編集します送信者: %s <%s>宛先:
@@ -547,6 +553,8 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
通知を開いた際に未読メールを検索する未読件数の表示通知バーに未読メッセージの件数を表示する
+ 開くと同時に既読にする
+ メッセージを参照したときに既読にするメール整理ボタンを有効にするアーカイブ、移動、迷惑メールボタンを表示
@@ -1118,4 +1126,29 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
設定をインポートするためのアプリケーションがありません。Androidマーケットからファイルマネージャをインストールしてください。マーケット閉じる
+
+ 開く
+ リンクを共有
+ リンクをコピー
+ リンク
+
+ 画像
+ 表示
+ 画像を保存
+ 画像をダウンロード
+ 画像のURLをコピー
+ 画像のURL
+
+ 発信
+ 連絡先に保存
+ 電話番号をコピー
+ 電話番号
+
+ メール送信
+ 連絡先に保存
+ メールアドレスをコピー
+ メールアドレス
+
+ \"%s\"に保存しました
+ 画像の保存に失敗しました
From 4612ceb3c8a2264741d929bb6d60d125f69a81bc Mon Sep 17 00:00:00 2001
From: cketti
Date: Tue, 3 Apr 2012 03:41:44 +0200
Subject: [PATCH 57/63] Enabled dark theme for MessageCompose and MessageView
---
.../divider_horizontal_email.9.png | Bin 434 -> 570 bytes
res/drawable/divider_horizontal_email.9.png | Bin 436 -> 570 bytes
res/layout/message_compose.xml | 17 ++--------------
src/com/fsck/k9/activity/K9Activity.java | 8 +-------
src/com/fsck/k9/activity/MessageCompose.java | 15 ++++++++------
src/com/fsck/k9/activity/MessageView.java | 2 +-
src/com/fsck/k9/view/MessageWebView.java | 19 ++++++++++++++++++
src/com/fsck/k9/view/SingleMessageView.java | 2 +-
8 files changed, 33 insertions(+), 30 deletions(-)
diff --git a/res/drawable-hdpi/divider_horizontal_email.9.png b/res/drawable-hdpi/divider_horizontal_email.9.png
index 8358af9c3eadc38b3d62ba371658a9c60421094f..46f5f48d5fb22c4fe1c5023164b4715bc5f96562 100644
GIT binary patch
literal 570
zcmV-A0>%A_P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9
za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv00050Nkl15)v`z)H$clIp>@?hlE5#M4!v1i?8Bhr2#h%g|gx}&a!cq1kNq
zgh%PoJzoTr5Q>O0s@Ll=SeErB5=uzHG|dIjd)~#8a!L0-pjNAW0$qQJZ%X(9!!Uk9
zpUZ1_o!`IqdHz0px8UE?-`DlX+OR%eudW|^5xPI!FYh0<5L_Rvm)1{eiF$H1-|+=en9Si@xfnBEry$sKC02R0N(cLabMMnR1$9CX48sXGNN%cW}{Pgskzn_
zr4~f7^~Kg}-fPxwCs^`=-~z-;dq3bJ-l7GM@@SgWW(*u>%*D8>eHV*CuJw7&loO^f
zwY~JmG5R20HQmk~dJR7R81|4~`|+#|!TL~l%QtA%^^&!s;-x!ZnMQ|EY@2L=WP
ch;IP~0CbSBzQWjTL;wH)07*qoM6N<$f*^g%5&!@I
diff --git a/res/drawable/divider_horizontal_email.9.png b/res/drawable/divider_horizontal_email.9.png
index 1f56364f274656e82667a81ae777788228a64c9d..46f5f48d5fb22c4fe1c5023164b4715bc5f96562 100644
GIT binary patch
literal 570
zcmV-A0>%A_P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9
za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv00050Nkl15)v`z)H$clIp>@?hlE5#M4!v1i?8Bhr2#h%g|gx}&a!cq1kNq
zgh%PoJzoTr5Q>O0s@Ll=SeErB5=uzHG|dIjd)~#8a!L0-pjNAW0$qQJZ%X(9!!Uk9
zpUZ1_o!`IqdHz0px8UE?-`DlX+OR%eudW|^5xPI!FYh0<5L_Rvm)1{eiF$HNYz1J;@2iSfc9piBb;MApANLh+A_z>Ean>(7;L&W75{BYM+bBHa5QU}tv1
zP|`$;EF@JZ)X>IvDBUjoVXx-q!^H_3)ydmB)lKOyJqd}083dYawG}T`a7KXtEP0*ThoL#e84z-R_AK|ukM4K>*Jic
zWSZjC_QD>*r;@&nyR%n>`BhmYQs(3|U9G@5vFbMan3
z&MEkRi0wSEhnU(vaIgB=V3wImEiI<#AL60EiJh>t*g+H8@WBp308L|D7GLj#&l2Ss
z^Ar;W4qyGnd~hN^EjR8@3h7kynLF7}!$u92N+>j!nR4`8@V$Oc?b*TI4sSVS#$_HD
e7#IM41sDKrcdx;_N6PE~0000
+ android:orientation="vertical">
+ android:background="#45bcbcbc">
@@ -160,7 +155,6 @@
android:id="@+id/userId"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@android:color/primary_text_light"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
@@ -168,7 +162,6 @@
android:id="@+id/userIdRest"
android:textSize="10sp"
android:ellipsize="end"
- android:textColor="@android:color/primary_text_light"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
@@ -179,7 +172,6 @@
Not all headers have been downloaded or saved. Select \"Save all headers locally\" in the account\'s incoming server settings to enable this for the future.
@@ -1142,6 +1142,8 @@ the import operation. Please install a file manager application from Android Mar
Open MarketClose
+ No text
+
Open for viewingShare linkCopy link to clipboard
diff --git a/src/com/fsck/k9/activity/MessageView.java b/src/com/fsck/k9/activity/MessageView.java
index 91ea29690..864668b98 100644
--- a/src/com/fsck/k9/activity/MessageView.java
+++ b/src/com/fsck/k9/activity/MessageView.java
@@ -980,7 +980,8 @@ public class MessageView extends K9Activity implements OnClickListener {
public void run() {
if (!clonedMessage.isSet(Flag.X_DOWNLOADED_FULL) &&
!clonedMessage.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
- mMessageView.loadBodyFromUrl("file:///android_asset/downloading.html");
+ String text = getString(R.string.message_view_downloading);
+ mMessageView.showStatusMessage(text);
}
mMessageView.setHeaders(clonedMessage, account);
mMessageView.setOnFlagListener(new OnClickListener() {
@@ -1033,7 +1034,7 @@ public class MessageView extends K9Activity implements OnClickListener {
}
if ((MessageView.this.mMessage == null) ||
!MessageView.this.mMessage.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
- mMessageView.loadBodyFromUrl("file:///android_asset/empty.html");
+ mMessageView.showStatusMessage(getString(R.string.webview_empty_message));
}
}
});
diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java
index c5109db8c..31df37bc2 100644
--- a/src/com/fsck/k9/view/SingleMessageView.java
+++ b/src/com/fsck/k9/view/SingleMessageView.java
@@ -524,15 +524,13 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
resetView();
String type;
- String text = pgpData.getDecryptedData();
+ String text = null;
+ if (pgpData != null) {
+ text = pgpData.getDecryptedData();
+ }
if (text != null) {
- /*
- * also return here html instead of text/plain. with text/plain the
- * webview does not render the CSS on the darktheme to make the text
- * white. so the user is not able to see the mailcontent.
- */
type = "text/html";
-
+ text = "
" + text + "
";
} else {
// getTextForDisplay() always returns HTML-ified content.
text = message.getTextForDisplay();
@@ -544,7 +542,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
loadBodyFromText(emailText, contentType);
updateCryptoLayout(account.getCryptoProvider(), pgpData, message);
} else {
- loadBodyFromUrl("file:///android_asset/empty.html");
+ showStatusMessage(getContext().getString(R.string.webview_empty_message));
}
mHasAttachments = message.hasAttachments();
@@ -596,10 +594,12 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
}
}
- public void loadBodyFromUrl(String url) {
- mMessageContentView.loadUrl(url);
+ public void showStatusMessage(String status) {
+ String text = "
" +
+ status +
+ "
";
+ loadBodyFromText(text, "text/html");
mCryptoView.hide();
-
}
private void loadBodyFromText(String emailText, String contentType) {
@@ -769,6 +769,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
mSavedState = savedState;
}
+ @Override
public void onLayoutChanged() {
if (mMessageContentView != null) {
mMessageContentView.invalidate();
From e88fbf43d036a769554ffe700cc477ebccda6776 Mon Sep 17 00:00:00 2001
From: cketti
Date: Wed, 4 Apr 2012 09:48:45 +0200
Subject: [PATCH 63/63] Removed unused ToggleScrollView
---
src/com/fsck/k9/view/ToggleScrollView.java | 143 ---------------------
1 file changed, 143 deletions(-)
delete mode 100644 src/com/fsck/k9/view/ToggleScrollView.java
diff --git a/src/com/fsck/k9/view/ToggleScrollView.java b/src/com/fsck/k9/view/ToggleScrollView.java
deleted file mode 100644
index 714e8ce24..000000000
--- a/src/com/fsck/k9/view/ToggleScrollView.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package com.fsck.k9.view;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.widget.ScrollView;
-import com.fsck.k9.K9;
-import com.fsck.k9.controller.MessagingListener;
-
-/**
- * An extension of {@link ScrollView} that allows scrolling to be selectively disabled.
- */
-public class ToggleScrollView extends ScrollView {
- private GestureDetector mDetector;
- private boolean mScrolling = true;
- private int mCurrentYPosition;
- private double mScrollPercentage;
- private ScrollToLastLocationListener mListener;
-
- public ToggleScrollView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mDetector = new GestureDetector(new YScrollDetector());
- }
-
- public void setScrolling(boolean enable) {
- mScrolling = enable;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- return (mScrolling) ? super.onTouchEvent(ev) : true;
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (!mScrolling) {
- return false;
- }
-
- // This doesn't quite get us to diagonal scrolling, but it's somewhat better than what we've
- // currently got. This is based on
- // http://stackoverflow.com/questions/2646028/android-horizontalscrollview-within-scrollview-touch-handling
- boolean result = super.onInterceptTouchEvent(ev);
- // Let the original ScrollView handle ACTION_DOWN so we can stop the scroll when someone touches the screen.
- if (ev.getAction() == MotionEvent.ACTION_DOWN || mDetector.onTouchEvent(ev)) {
- return result;
- }
-
- return false;
- }
-
- // Return false if we're scrolling in the x direction. That is, decline to consume the event and
- // let the parent class take a stab at it.
- class YScrollDetector extends GestureDetector.SimpleOnGestureListener {
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- try {
- if (Math.abs(distanceY) > Math.abs(distanceX)) {
- return true;
- } else {
- return false;
- }
- } catch (Exception e) {
- // nothing
- }
- return false;
- }
- }
-
- /**
- * Fetch the current percentage by which this view has been scrolled.
- * @return Scroll percentage based on the top edge of the screen, from 0 to 100. This number should never really
- * be 100, unless the screen is of 0 height...
- */
- public double getScrollPercentage() {
- // We save only the Y coordinate instead of the percentage because I don't know how expensive the
- // computeVerticalScrollRange() call is.
- final int scrollRange = computeVerticalScrollRange();
- if(scrollRange == 0) {
- return 0;
- }
- return (double) mCurrentYPosition / scrollRange;
- }
-
- /**
- * Set the percentage by which we should scroll the page once we get the load complete event. This is
- * based on the top edge of the view.
- * @param percentage Percentage of page to scroll to.
- */
- public void setScrollPercentage(final double percentage) {
- Log.d(K9.LOG_TAG, "ToggleView: Setting last scroll percentage to " + percentage);
- this.mScrollPercentage = percentage;
- }
-
- /**
- * Override {@link ScrollView#onScrollChanged(int, int, int, int)} to record the current x/y position. We use this
- * to save our current position for future scrolling.
- *
- * @param x
- * @param y
- * @param oldx
- * @param oldy
- */
- @Override
- protected void onScrollChanged(int x, int y, int oldx, int oldy) {
- super.onScrollChanged(x, y, oldx, oldy);
-
- this.mCurrentYPosition = y;
- // I wish Android has a TRACE log level so I wouldn't have to comment this out. This one is really noisy.
- // Log.d(K9.LOG_TAG, "ToggleScrollView: mCurrentYPosition=" + y + " scrollRange=" + computeVerticalScrollRange() + " pct=" + getScrollPercentage());
- }
-
- /**
- * This is a {@link MessagingListener} which listens for when the a message has finished being displayed on the
- * screen. We'll scroll the message to the user's last known location once it's done.
- */
- class ScrollToLastLocationListener extends MessagingListener {
- public void messageViewFinished() {
- // Don't scroll if our last position was at the top.
- if(mScrollPercentage != 0.0) {
- final int scrollRange = computeVerticalScrollRange();
- final int newY = (int)(mScrollPercentage * scrollRange);
- Log.d(K9.LOG_TAG, "ToggleScrollView: requested " + (100 * mScrollPercentage) + "%, " +
- "scrolling to " + newY + "/" + scrollRange);
- scrollTo(0, newY);
- }
- }
- }
-
- /**
- * Fetch the {@link MessagingListener} for this ScrollView.
- * @return
- */
- public MessagingListener getListener() {
- if(this.mListener != null) {
- return this.mListener;
- } else {
- return this.mListener = new ScrollToLastLocationListener();
- }
- }
-}