1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-27 19:52:17 -05:00

- Add menu item to show additional headers in the message view

- Add option to save all headers locally (incoming server settings)

Applied patch provided by timmlinder with small modifications.

Fixes issue 43
This commit is contained in:
cketti 2010-05-21 15:34:29 +00:00
parent c29722a56c
commit c5486469c2
15 changed files with 361 additions and 27 deletions

View File

@ -212,6 +212,17 @@
android:text="@string/account_setup_incoming_other_label" android:text="@string/account_setup_incoming_other_label"
/> />
</LinearLayout> </LinearLayout>
<TextView
android:text="@string/account_setup_incoming_save_all_headers_title"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary" />
<CheckBox
android:id="@+id/save_all_headers"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/account_setup_incoming_save_all_headers_label" />
<LinearLayout <LinearLayout
android:id="@+id/push_poll_on_connect_section" android:id="@+id/push_poll_on_connect_section"
android:layout_width="fill_parent" android:layout_width="fill_parent"

View File

@ -98,8 +98,19 @@
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout> </LinearLayout>
</LinearLayout> <TextView android:id="@+id/additional_headers_view"
<LinearLayout android:id="@+id/topright_container" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="4dip"
android:baselineAligned="true"
android:singleLine="false"
android:ellipsize="none"
android:textSize="10sp"
android:textColor="?android:attr/textColorSecondary"
android:textAppearance="?android:attr/textAppearanceSmall" >
</TextView>
</LinearLayout>
<LinearLayout android:id="@+id/topright_container"
android:orientation="vertical" android:orientation="vertical"
android:layout_weight="0.1" android:layout_weight="0.1"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -30,7 +30,11 @@
android:title="@string/delete_action" android:title="@string/delete_action"
android:icon="@drawable/ic_menu_delete" android:icon="@drawable/ic_menu_delete"
/> />
<item <item
android:id="@+id/show_full_header"
android:title="@string/show_full_header_action"
/>
<item
android:id="@+id/flag" android:id="@+id/flag"
android:alphabeticShortcut="s" android:alphabeticShortcut="s"
android:title="@string/flag_action" android:title="@string/flag_action"

View File

@ -88,7 +88,9 @@
<string name="flag_action">Add star</string> <string name="flag_action">Add star</string>
<string name="unflag_action">Remove star</string> <string name="unflag_action">Remove star</string>
<string name="copy_action">Copy</string> <string name="copy_action">Copy</string>
<string name="show_full_header_action">Show full header</string>
<string name="hide_full_header_action">Hide full header</string>
<string name="mark_as_unread_action">Mark as unread</string> <string name="mark_as_unread_action">Mark as unread</string>
<string name="move_to_action">Move to</string> <string name="move_to_action">Move to</string>
<string name="folders_action">Folders</string> <string name="folders_action">Folders</string>
@ -260,7 +262,12 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
<string name="message_view_show_pictures_action">Show pictures</string> <string name="message_view_show_pictures_action">Show pictures</string>
<string name="message_view_fetching_attachment_toast">Fetching attachment.</string> <string name="message_view_fetching_attachment_toast">Fetching attachment.</string>
<string name="message_view_no_viewer">Unable to find viewer for <xliff:g id="mimetype">%s</xliff:g>.</string> <string name="message_view_no_viewer">Unable to find viewer for <xliff:g id="mimetype">%s</xliff:g>.</string>
<!-- NOTE: The following message refers to strings with id 'account_setup_incoming_save_all_headers_label' and 'account_setup_incoming_title' -->
<string name="message_additional_headers_not_downloaded">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.</string>
<string name="message_no_additional_headers_available">All headers have been downloaded, but there are no additional headers to show.</string>
<string name="message_additional_headers_retrieval_failed">The retrieval of additional headers from the database or mail server failed.</string>
<string name="mailbox_select_dlg_title">Folders</string> <string name="mailbox_select_dlg_title">Folders</string>
<string name="mailbox_select_dlg_new_mailbox_action">New folder</string> <string name="mailbox_select_dlg_new_mailbox_action">New folder</string>
@ -341,6 +348,9 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
<string name="account_setup_incoming_wifi_label">Wi-Fi</string> <string name="account_setup_incoming_wifi_label">Wi-Fi</string>
<string name="account_setup_incoming_other_label">Other</string> <string name="account_setup_incoming_other_label">Other</string>
<string name="account_setup_incoming_save_all_headers_title">Downloading of mail headers</string>
<string name="account_setup_incoming_save_all_headers_label">Save all headers locally</string>
<string name="account_setup_expunge_policy_label">Expunge messages</string> <string name="account_setup_expunge_policy_label">Expunge messages</string>
<string name="account_setup_expunge_policy_immediately">Immediately after delete or move</string> <string name="account_setup_expunge_policy_immediately">Immediately after delete or move</string>
<string name="account_setup_expunge_policy_on_poll">During each poll</string> <string name="account_setup_expunge_policy_on_poll">During each poll</string>
@ -764,6 +774,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
<string name="font_size_message_view_sender">Message sender</string> <string name="font_size_message_view_sender">Message sender</string>
<string name="font_size_message_view_to">Message receiver (To)</string> <string name="font_size_message_view_to">Message receiver (To)</string>
<string name="font_size_message_view_cc">Message receiver (CC)</string> <string name="font_size_message_view_cc">Message receiver (CC)</string>
<string name="font_size_message_view_additional_headers">Additional headers</string>
<string name="font_size_message_view_subject">Message subject</string> <string name="font_size_message_view_subject">Message subject</string>
<string name="font_size_message_view_time">Message time</string> <string name="font_size_message_view_time">Message time</string>
<string name="font_size_message_view_date">Message date</string> <string name="font_size_message_view_date">Message date</string>

View File

@ -86,6 +86,13 @@
android:entryValues="@array/font_values" android:entryValues="@array/font_values"
android:dialogTitle="@string/font_size_message_view_cc" /> android:dialogTitle="@string/font_size_message_view_cc" />
<ListPreference
android:key="message_view_additional_headers_font"
android:title="@string/font_size_message_view_additional_headers"
android:entries="@array/font_entries"
android:entryValues="@array/font_values"
android:dialogTitle="@string/font_size_message_view_additional_headers" />
<ListPreference <ListPreference
android:key="message_view_subject_font" android:key="message_view_subject_font"
android:title="@string/font_size_message_view_subject" android:title="@string/font_size_message_view_subject"

View File

@ -78,6 +78,7 @@ public class Account implements BaseAccount
private int mAccountNumber; private int mAccountNumber;
private boolean mVibrate; private boolean mVibrate;
private boolean mRing; private boolean mRing;
private boolean mSaveAllHeaders;
private boolean mPushPollOnConnect; private boolean mPushPollOnConnect;
private String mRingtoneUri; private String mRingtoneUri;
private boolean mNotifySync; private boolean mNotifySync;
@ -117,6 +118,7 @@ public class Account implements BaseAccount
mLocalStoreUri = "local://localhost/" + context.getDatabasePath(mUuid + ".db"); mLocalStoreUri = "local://localhost/" + context.getDatabasePath(mUuid + ".db");
mAutomaticCheckIntervalMinutes = -1; mAutomaticCheckIntervalMinutes = -1;
mIdleRefreshMinutes = 24; mIdleRefreshMinutes = 24;
mSaveAllHeaders = false;
mPushPollOnConnect = true; mPushPollOnConnect = true;
mDisplayCount = -1; mDisplayCount = -1;
mAccountNumber = -1; mAccountNumber = -1;
@ -172,6 +174,8 @@ public class Account implements BaseAccount
+ ".automaticCheckIntervalMinutes", -1); + ".automaticCheckIntervalMinutes", -1);
mIdleRefreshMinutes = preferences.getPreferences().getInt(mUuid mIdleRefreshMinutes = preferences.getPreferences().getInt(mUuid
+ ".idleRefreshMinutes", 24); + ".idleRefreshMinutes", 24);
mSaveAllHeaders = preferences.getPreferences().getBoolean(mUuid
+ ".saveAllHeaders", false);
mPushPollOnConnect = preferences.getPreferences().getBoolean(mUuid mPushPollOnConnect = preferences.getPreferences().getBoolean(mUuid
+ ".pushPollOnConnect", true); + ".pushPollOnConnect", true);
mDisplayCount = preferences.getPreferences().getInt(mUuid + ".displayCount", -1); mDisplayCount = preferences.getPreferences().getInt(mUuid + ".displayCount", -1);
@ -338,6 +342,7 @@ public class Account implements BaseAccount
editor.remove(mUuid + ".alwaysBcc"); editor.remove(mUuid + ".alwaysBcc");
editor.remove(mUuid + ".automaticCheckIntervalMinutes"); editor.remove(mUuid + ".automaticCheckIntervalMinutes");
editor.remove(mUuid + ".pushPollOnConnect"); editor.remove(mUuid + ".pushPollOnConnect");
editor.remove(mUuid + ".saveAllHeaders");
editor.remove(mUuid + ".idleRefreshMinutes"); editor.remove(mUuid + ".idleRefreshMinutes");
editor.remove(mUuid + ".lastAutomaticCheckTime"); editor.remove(mUuid + ".lastAutomaticCheckTime");
editor.remove(mUuid + ".notifyNewMail"); editor.remove(mUuid + ".notifyNewMail");
@ -417,6 +422,7 @@ public class Account implements BaseAccount
editor.putString(mUuid + ".alwaysBcc", mAlwaysBcc); editor.putString(mUuid + ".alwaysBcc", mAlwaysBcc);
editor.putInt(mUuid + ".automaticCheckIntervalMinutes", mAutomaticCheckIntervalMinutes); editor.putInt(mUuid + ".automaticCheckIntervalMinutes", mAutomaticCheckIntervalMinutes);
editor.putInt(mUuid + ".idleRefreshMinutes", mIdleRefreshMinutes); editor.putInt(mUuid + ".idleRefreshMinutes", mIdleRefreshMinutes);
editor.putBoolean(mUuid + ".saveAllHeaders", mSaveAllHeaders);
editor.putBoolean(mUuid + ".pushPollOnConnect", mPushPollOnConnect); editor.putBoolean(mUuid + ".pushPollOnConnect", mPushPollOnConnect);
editor.putInt(mUuid + ".displayCount", mDisplayCount); editor.putInt(mUuid + ".displayCount", mDisplayCount);
editor.putLong(mUuid + ".lastAutomaticCheckTime", mLastAutomaticCheckTime); editor.putLong(mUuid + ".lastAutomaticCheckTime", mLastAutomaticCheckTime);
@ -1175,6 +1181,16 @@ public class Account implements BaseAccount
mPushPollOnConnect = pushPollOnConnect; mPushPollOnConnect = pushPollOnConnect;
} }
public boolean isSaveAllHeaders()
{
return mSaveAllHeaders;
}
public void setSaveAllHeaders(boolean saveAllHeaders)
{
mSaveAllHeaders = saveAllHeaders;
}
public boolean goToUnreadMessageSearch() public boolean goToUnreadMessageSearch()
{ {
return goToUnreadMessageSearch; return goToUnreadMessageSearch;

View File

@ -22,6 +22,7 @@ public class FontSizes
private static final String MESSAGE_VIEW_SENDER = "fontSizeMessageViewSender"; private static final String MESSAGE_VIEW_SENDER = "fontSizeMessageViewSender";
private static final String MESSAGE_VIEW_TO = "fontSizeMessageViewTo"; private static final String MESSAGE_VIEW_TO = "fontSizeMessageViewTo";
private static final String MESSAGE_VIEW_CC = "fontSizeMessageViewCC"; private static final String MESSAGE_VIEW_CC = "fontSizeMessageViewCC";
private static final String MESSAGE_VIEW_ADDITIONAL_HEADERS = "fontSizeMessageViewAdditionalHeaders";
private static final String MESSAGE_VIEW_SUBJECT = "fontSizeMessageViewSubject"; private static final String MESSAGE_VIEW_SUBJECT = "fontSizeMessageViewSubject";
private static final String MESSAGE_VIEW_TIME = "fontSizeMessageViewTime"; private static final String MESSAGE_VIEW_TIME = "fontSizeMessageViewTime";
private static final String MESSAGE_VIEW_DATE = "fontSizeMessageViewDate"; private static final String MESSAGE_VIEW_DATE = "fontSizeMessageViewDate";
@ -89,6 +90,11 @@ public class FontSizes
*/ */
private int messageViewCC; private int messageViewCC;
/**
* Font size of additional headers in the message view activity.
*/
private int messageViewAdditionalHeaders;
/** /**
* Font size of the message subject in the message view activity. * Font size of the message subject in the message view activity.
*/ */
@ -129,6 +135,7 @@ public class FontSizes
messageViewSender = SMALL; messageViewSender = SMALL;
messageViewTo = FONT_12DIP; messageViewTo = FONT_12DIP;
messageViewCC = FONT_12DIP; messageViewCC = FONT_12DIP;
messageViewAdditionalHeaders = FONT_12DIP;
messageViewSubject = FONT_12DIP; messageViewSubject = FONT_12DIP;
messageViewTime = FONT_10DIP; messageViewTime = FONT_10DIP;
messageViewDate = FONT_10DIP; messageViewDate = FONT_10DIP;
@ -154,6 +161,7 @@ public class FontSizes
editor.putInt(MESSAGE_VIEW_SUBJECT, messageViewSubject); editor.putInt(MESSAGE_VIEW_SUBJECT, messageViewSubject);
editor.putInt(MESSAGE_VIEW_TO, messageViewTo); editor.putInt(MESSAGE_VIEW_TO, messageViewTo);
editor.putInt(MESSAGE_VIEW_CC, messageViewCC); editor.putInt(MESSAGE_VIEW_CC, messageViewCC);
editor.putInt(MESSAGE_VIEW_ADDITIONAL_HEADERS, messageViewAdditionalHeaders);
editor.putInt(MESSAGE_VIEW_SENDER, messageViewSender); editor.putInt(MESSAGE_VIEW_SENDER, messageViewSender);
editor.putInt(MESSAGE_VIEW_TIME, messageViewTime); editor.putInt(MESSAGE_VIEW_TIME, messageViewTime);
editor.putInt(MESSAGE_VIEW_DATE, messageViewDate); editor.putInt(MESSAGE_VIEW_DATE, messageViewDate);
@ -180,6 +188,7 @@ public class FontSizes
messageViewSubject = prefs.getInt(MESSAGE_VIEW_SENDER, FONT_12DIP); messageViewSubject = prefs.getInt(MESSAGE_VIEW_SENDER, FONT_12DIP);
messageViewTo = prefs.getInt(MESSAGE_VIEW_TO, messageViewTo); messageViewTo = prefs.getInt(MESSAGE_VIEW_TO, messageViewTo);
messageViewCC = prefs.getInt(MESSAGE_VIEW_CC, messageViewCC); messageViewCC = prefs.getInt(MESSAGE_VIEW_CC, messageViewCC);
messageViewAdditionalHeaders = prefs.getInt(MESSAGE_VIEW_ADDITIONAL_HEADERS, messageViewAdditionalHeaders);
messageViewSender = prefs.getInt(MESSAGE_VIEW_SUBJECT, messageViewSender); messageViewSender = prefs.getInt(MESSAGE_VIEW_SUBJECT, messageViewSender);
messageViewTime = prefs.getInt(MESSAGE_VIEW_TIME, messageViewTime); messageViewTime = prefs.getInt(MESSAGE_VIEW_TIME, messageViewTime);
messageViewDate = prefs.getInt(MESSAGE_VIEW_DATE, messageViewDate); messageViewDate = prefs.getInt(MESSAGE_VIEW_DATE, messageViewDate);
@ -286,6 +295,16 @@ public class FontSizes
this.messageViewCC = messageViewCC; this.messageViewCC = messageViewCC;
} }
public int getMessageViewAdditionalHeaders()
{
return messageViewAdditionalHeaders;
}
public void setMessageViewAdditionalHeaders(int messageViewAdditionalHeaders)
{
this.messageViewAdditionalHeaders = messageViewAdditionalHeaders;
}
public int getMessageViewSubject() public int getMessageViewSubject()
{ {
return messageViewSubject; return messageViewSubject;

View File

@ -1,4 +1,3 @@
package com.fsck.k9.activity; package com.fsck.k9.activity;
import android.content.Context; import android.content.Context;
@ -6,6 +5,7 @@ import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.media.MediaScannerConnection; import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient; import android.media.MediaScannerConnection.MediaScannerConnectionClient;
@ -15,6 +15,9 @@ import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.provider.Contacts; import android.provider.Contacts;
import android.provider.Contacts.Intents; import android.provider.Contacts.Intents;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.style.StyleSpan;
import android.util.Config; import android.util.Config;
import android.util.Log; import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
@ -38,7 +41,10 @@ import com.fsck.k9.provider.AttachmentProvider;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set;
public class MessageView extends K9Activity implements OnClickListener public class MessageView extends K9Activity implements OnClickListener
{ {
@ -62,6 +68,7 @@ public class MessageView extends K9Activity implements OnClickListener
private WebView mMessageContentView; private WebView mMessageContentView;
private LinearLayout mAttachments; private LinearLayout mAttachments;
private LinearLayout mCcContainerView; private LinearLayout mCcContainerView;
private TextView mAdditionalHeadersView;
private View mAttachmentIcon; private View mAttachmentIcon;
private View mDownloadingIcon; private View mDownloadingIcon;
private View mShowPicturesSection; private View mShowPicturesSection;
@ -86,7 +93,6 @@ public class MessageView extends K9Activity implements OnClickListener
private MessageReference mPreviousMessage = null; private MessageReference mPreviousMessage = null;
private Menu optionsMenu = null; private Menu optionsMenu = null;
private Listener mListener = new Listener(); private Listener mListener = new Listener();
@ -94,6 +100,22 @@ public class MessageView extends K9Activity implements OnClickListener
private FontSizes mFontSizes = K9.getFontSizes(); private FontSizes mFontSizes = K9.getFontSizes();
/**
* Pair class is only available since API Level 5, so we need
* this helper class unfortunately
*/
private class HeaderEntry
{
public String label;
public String value;
public HeaderEntry(String label, String value)
{
this.label = label;
this.value = value;
}
}
@Override @Override
public boolean dispatchKeyEvent(KeyEvent event) public boolean dispatchKeyEvent(KeyEvent event)
@ -410,7 +432,118 @@ public class MessageView extends K9Activity implements OnClickListener
} }
/**
* Clear the text field for the additional headers display if they are
* not shown, to save UI resources.
*/
public void hideAdditionalHeaders()
{
runOnUiThread(new Runnable()
{
public void run()
{
mAdditionalHeadersView.setVisibility(View.GONE);
mAdditionalHeadersView.setText("");
mTopView.scrollTo(0, 0);
}
});
}
/**
* Set up and then show the additional headers view. Called by
* {@link #onShowAdditionalHeaders()} and
* {@link #setHeaders(Account, String, String, Message)}
* (when switching between messages).
*/
public void showAdditionalHeaders()
{
runOnUiThread(new Runnable()
{
public void run()
{
Integer messageToShow = null;
try
{
// Retrieve additional headers
boolean allHeadersDownloaded = mMessage.isSet(Flag.X_GOT_ALL_HEADERS);
List<HeaderEntry> additionalHeaders = getAdditionalHeaders(mMessage);
if (!additionalHeaders.isEmpty())
{
// Show the additional headers that we have got.
setupAdditionalHeadersView(additionalHeaders);
mAdditionalHeadersView.setVisibility(View.VISIBLE);
}
if (!allHeadersDownloaded)
{
/*
* Tell the user about the "save all headers" setting
*
* NOTE: This is only a temporary solution... in fact,
* the system should download headers on-demand when they
* have not been saved in their entirety initially.
*/
messageToShow = R.string.message_additional_headers_not_downloaded;
}
else if (additionalHeaders.isEmpty())
{
// All headers have been downloaded, but there are no additional headers.
messageToShow = R.string.message_no_additional_headers_available;
}
}
catch(MessagingException e)
{
messageToShow = R.string.message_additional_headers_retrieval_failed;
}
// Show a message to the user, if any
if (messageToShow != null)
{
Toast toast = Toast.makeText(MessageView.this, messageToShow, Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
toast.show();
}
}
});
}
/**
* Set up the additional headers text view with the supplied header data.
*
* @param additionalHeaders
* List of header entries. Each entry consists of a header
* name and a header value. Header names may appear multiple
* times.
*
* This method is always called from within the UI thread by
* {@link #showAdditionalHeaders()}.
*/
private void setupAdditionalHeadersView(final List<HeaderEntry> additionalHeaders)
{
SpannableStringBuilder sb = new SpannableStringBuilder();
boolean first = true;
for (HeaderEntry additionalHeader : additionalHeaders)
{
if (!first)
{
sb.append("\n");
}
else
{
first = false;
}
StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
SpannableString label = new SpannableString(additionalHeader.label + ": ");
label.setSpan(boldSpan, 0, label.length(), 0);
sb.append(label);
sb.append(additionalHeader.value.replaceAll("\\r\\n", ""));
}
mAdditionalHeadersView.setText(sb);
}
} }
class Attachment class Attachment
@ -460,6 +593,8 @@ public class MessageView extends K9Activity implements OnClickListener
mSubjectView = (TextView)findViewById(R.id.subject); mSubjectView = (TextView)findViewById(R.id.subject);
defaultSubjectColor = mSubjectView.getCurrentTextColor(); defaultSubjectColor = mSubjectView.getCurrentTextColor();
mAdditionalHeadersView = (TextView)findViewById(R.id.additional_headers_view);
chip = findViewById(R.id.chip); chip = findViewById(R.id.chip);
mDateView = (TextView)findViewById(R.id.date); mDateView = (TextView)findViewById(R.id.date);
@ -503,7 +638,8 @@ public class MessageView extends K9Activity implements OnClickListener
mSubjectView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getMessageViewSubject()); mSubjectView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getMessageViewSubject());
mTimeView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getMessageViewTime()); mTimeView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getMessageViewTime());
mDateView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getMessageViewDate()); mDateView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getMessageViewDate());
mAdditionalHeadersView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getMessageViewAdditionalHeaders());
mAdditionalHeadersView.setVisibility(View.GONE);
mAttachments.setVisibility(View.GONE); mAttachments.setVisibility(View.GONE);
mAttachmentIcon.setVisibility(View.GONE); mAttachmentIcon.setVisibility(View.GONE);
@ -515,6 +651,9 @@ public class MessageView extends K9Activity implements OnClickListener
setOnClickListener(R.id.next); setOnClickListener(R.id.next);
setOnClickListener(R.id.previous); setOnClickListener(R.id.previous);
// To show full header
setOnClickListener(R.id.header_container);
setOnClickListener(R.id.reply_scrolling); setOnClickListener(R.id.reply_scrolling);
// setOnClickListener(R.id.reply_all_scrolling); // setOnClickListener(R.id.reply_all_scrolling);
setOnClickListener(R.id.delete_scrolling); setOnClickListener(R.id.delete_scrolling);
@ -830,7 +969,7 @@ public class MessageView extends K9Activity implements OnClickListener
{ {
mMessage.setFlag(Flag.FLAGGED, !mMessage.isSet(Flag.FLAGGED)); mMessage.setFlag(Flag.FLAGGED, !mMessage.isSet(Flag.FLAGGED));
setHeaders(mAccount, mMessage.getFolder().getName(), mMessage.getUid(), mMessage); setHeaders(mAccount, mMessage.getFolder().getName(), mMessage.getUid(), mMessage);
setMenuFlag(); prepareMenuItems();
} }
catch (MessagingException me) catch (MessagingException me)
{ {
@ -877,6 +1016,43 @@ public class MessageView extends K9Activity implements OnClickListener
startActivityForResult(intent, ACTIVITY_CHOOSE_FOLDER_COPY); startActivityForResult(intent, ACTIVITY_CHOOSE_FOLDER_COPY);
} }
private void onShowAdditionalHeaders()
{
int currentVisibility = mAdditionalHeadersView.getVisibility();
if (currentVisibility == View.VISIBLE)
{
mHandler.hideAdditionalHeaders();
}
else
{
mHandler.showAdditionalHeaders();
}
}
private List<HeaderEntry> getAdditionalHeaders(final Message message)
throws MessagingException
{
List<HeaderEntry> additionalHeaders = new LinkedList<HeaderEntry>();
// Do not include the following headers, since they are always visible anyway
Set<String> headerNames = new HashSet<String>(message.getHeaderNames());
headerNames.remove("To");
headerNames.remove("From");
headerNames.remove("Cc");
headerNames.remove("Subject");
for (String headerName : headerNames)
{
String[] headerValues = message.getHeader(headerName);
for (String headerValue : headerValues)
{
additionalHeaders.add(new HeaderEntry(headerName, headerValue));
}
}
return additionalHeaders;
}
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) protected void onActivityResult(int requestCode, int resultCode, Intent data)
{ {
@ -1100,6 +1276,9 @@ public class MessageView extends K9Activity implements OnClickListener
case R.id.show_pictures: case R.id.show_pictures:
onShowPictures(); onShowPictures();
break; break;
case R.id.header_container:
onShowAdditionalHeaders();
break;
} }
} }
@ -1135,6 +1314,9 @@ public class MessageView extends K9Activity implements OnClickListener
case R.id.copy: case R.id.copy:
onCopy(); onCopy();
break; break;
case R.id.show_full_header:
onShowAdditionalHeaders();
break;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -1147,7 +1329,7 @@ public class MessageView extends K9Activity implements OnClickListener
super.onCreateOptionsMenu(menu); super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.message_view_option, menu); getMenuInflater().inflate(R.menu.message_view_option, menu);
optionsMenu = menu; optionsMenu = menu;
setMenuFlag(); prepareMenuItems();
if (MessagingController.getInstance(getApplication()).isCopyCapable(mAccount) == false) if (MessagingController.getInstance(getApplication()).isCopyCapable(mAccount) == false)
{ {
menu.findItem(R.id.copy).setVisible(false); menu.findItem(R.id.copy).setVisible(false);
@ -1162,11 +1344,11 @@ public class MessageView extends K9Activity implements OnClickListener
@Override @Override
public boolean onPrepareOptionsMenu(Menu menu) public boolean onPrepareOptionsMenu(Menu menu)
{ {
setMenuFlag(); prepareMenuItems();
return super.onPrepareOptionsMenu(menu); return super.onPrepareOptionsMenu(menu);
} }
private void setMenuFlag() private void prepareMenuItems()
{ {
Menu menu = optionsMenu; Menu menu = optionsMenu;
if (menu != null) if (menu != null)
@ -1176,6 +1358,13 @@ public class MessageView extends K9Activity implements OnClickListener
{ {
flagItem.setTitle((mMessage.isSet(Flag.FLAGGED) ? R.string.unflag_action : R.string.flag_action)); flagItem.setTitle((mMessage.isSet(Flag.FLAGGED) ? R.string.unflag_action : R.string.flag_action));
} }
MenuItem additionalHeadersItem = menu.findItem(R.id.show_full_header);
if (additionalHeadersItem != null)
{
additionalHeadersItem.setTitle((mAdditionalHeadersView.getVisibility() == View.VISIBLE) ?
R.string.hide_full_header_action : R.string.show_full_header_action);
}
} }
} }
@ -1328,10 +1517,12 @@ public class MessageView extends K9Activity implements OnClickListener
String timeText = getTimeFormat().format(message.getSentDate()); String timeText = getTimeFormat().format(message.getSentDate());
String toText = Address.toFriendly(message.getRecipients(RecipientType.TO)); String toText = Address.toFriendly(message.getRecipients(RecipientType.TO));
String ccText = Address.toFriendly(message.getRecipients(RecipientType.CC)); String ccText = Address.toFriendly(message.getRecipients(RecipientType.CC));
int color = mAccount.getChipColor(); int color = mAccount.getChipColor();
boolean hasAttachments = ((LocalMessage) message).getAttachmentCount() > 0; boolean hasAttachments = ((LocalMessage) message).getAttachmentCount() > 0;
boolean isDownloading = !message.isSet(Flag.X_DOWNLOADED_FULL); boolean isDownloading = !message.isSet(Flag.X_DOWNLOADED_FULL);
boolean unread = !message.isSet(Flag.SEEN); boolean unread = !message.isSet(Flag.SEEN);
mHandler.setHeaders(subjectText, mHandler.setHeaders(subjectText,
fromText, fromText,
dateText, dateText,
@ -1344,6 +1535,12 @@ public class MessageView extends K9Activity implements OnClickListener
isDownloading, isDownloading,
message.isSet(Flag.FLAGGED), message.isSet(Flag.FLAGGED),
message.isSet(Flag.ANSWERED)); message.isSet(Flag.ANSWERED));
// Update additional headers display, if visible
if (mAdditionalHeadersView.getVisibility() == View.VISIBLE)
{
mHandler.showAdditionalHeaders();
}
} }
class Listener extends MessagingListener class Listener extends MessagingListener

View File

@ -85,6 +85,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
private CheckBox compressionMobile; private CheckBox compressionMobile;
private CheckBox compressionWifi; private CheckBox compressionWifi;
private CheckBox compressionOther; private CheckBox compressionOther;
private CheckBox saveAllHeaders;
private CheckBox pushPollOnConnect; private CheckBox pushPollOnConnect;
private Spinner idleRefreshPeriod; private Spinner idleRefreshPeriod;
private Spinner folderPushLimit; private Spinner folderPushLimit;
@ -130,6 +131,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
compressionMobile = (CheckBox)findViewById(R.id.compression_mobile); compressionMobile = (CheckBox)findViewById(R.id.compression_mobile);
compressionWifi = (CheckBox)findViewById(R.id.compression_wifi); compressionWifi = (CheckBox)findViewById(R.id.compression_wifi);
compressionOther = (CheckBox)findViewById(R.id.compression_other); compressionOther = (CheckBox)findViewById(R.id.compression_other);
saveAllHeaders = (CheckBox)findViewById(R.id.save_all_headers);
pushPollOnConnect = (CheckBox)findViewById(R.id.push_poll_on_connect); pushPollOnConnect = (CheckBox)findViewById(R.id.push_poll_on_connect);
idleRefreshPeriod = (Spinner)findViewById(R.id.idle_refresh_period); idleRefreshPeriod = (Spinner)findViewById(R.id.idle_refresh_period);
@ -389,6 +391,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
compressionMobile.setChecked(mAccount.useCompression(Account.TYPE_MOBILE)); compressionMobile.setChecked(mAccount.useCompression(Account.TYPE_MOBILE));
compressionWifi.setChecked(mAccount.useCompression(Account.TYPE_WIFI)); compressionWifi.setChecked(mAccount.useCompression(Account.TYPE_WIFI));
compressionOther.setChecked(mAccount.useCompression(Account.TYPE_OTHER)); compressionOther.setChecked(mAccount.useCompression(Account.TYPE_OTHER));
if (uri.getHost() != null) if (uri.getHost() != null)
{ {
mServerView.setText(uri.getHost()); mServerView.setText(uri.getHost());
@ -402,6 +405,8 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
{ {
updatePortFromSecurityType(); updatePortFromSecurityType();
} }
saveAllHeaders.setChecked(mAccount.isSaveAllHeaders());
pushPollOnConnect.setChecked(mAccount.isPushPollOnConnect()); pushPollOnConnect.setChecked(mAccount.isPushPollOnConnect());
SpinnerHelper.initSpinner(this, idleRefreshPeriod, R.array.idle_refresh_period_entries, SpinnerHelper.initSpinner(this, idleRefreshPeriod, R.array.idle_refresh_period_entries,
R.array.idle_refresh_period_values, String.valueOf(mAccount.getIdleRefreshMinutes())); R.array.idle_refresh_period_values, String.valueOf(mAccount.getIdleRefreshMinutes()));
@ -557,6 +562,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
mAccount.setCompression(Account.TYPE_MOBILE, compressionMobile.isChecked()); mAccount.setCompression(Account.TYPE_MOBILE, compressionMobile.isChecked());
mAccount.setCompression(Account.TYPE_WIFI, compressionWifi.isChecked()); mAccount.setCompression(Account.TYPE_WIFI, compressionWifi.isChecked());
mAccount.setCompression(Account.TYPE_OTHER, compressionOther.isChecked()); mAccount.setCompression(Account.TYPE_OTHER, compressionOther.isChecked());
mAccount.setSaveAllHeaders(saveAllHeaders.isChecked());
mAccount.setPushPollOnConnect(pushPollOnConnect.isChecked()); mAccount.setPushPollOnConnect(pushPollOnConnect.isChecked());
String idleRefreshPeriodValue = SpinnerHelper.getSpinnerValue(idleRefreshPeriod); String idleRefreshPeriodValue = SpinnerHelper.getSpinnerValue(idleRefreshPeriod);
try try

View File

@ -32,6 +32,7 @@ public class FontSizeSettings extends K9PreferenceActivity
private static final String PREFERENCE_MESSAGE_VIEW_SENDER_FONT = "message_view_sender_font"; private static final String PREFERENCE_MESSAGE_VIEW_SENDER_FONT = "message_view_sender_font";
private static final String PREFERENCE_MESSAGE_VIEW_TO_FONT = "message_view_to_font"; private static final String PREFERENCE_MESSAGE_VIEW_TO_FONT = "message_view_to_font";
private static final String PREFERENCE_MESSAGE_VIEW_CC_FONT = "message_view_cc_font"; private static final String PREFERENCE_MESSAGE_VIEW_CC_FONT = "message_view_cc_font";
private static final String PREFERENCE_MESSAGE_VIEW_ADDITIONAL_HEADERS_FONT = "message_view_additional_headers_font";
private static final String PREFERENCE_MESSAGE_VIEW_SUBJECT_FONT = "message_view_subject_font"; private static final String PREFERENCE_MESSAGE_VIEW_SUBJECT_FONT = "message_view_subject_font";
private static final String PREFERENCE_MESSAGE_VIEW_TIME_FONT = "message_view_time_font"; private static final String PREFERENCE_MESSAGE_VIEW_TIME_FONT = "message_view_time_font";
private static final String PREFERENCE_MESSAGE_VIEW_DATE_FONT = "message_view_date_font"; private static final String PREFERENCE_MESSAGE_VIEW_DATE_FONT = "message_view_date_font";
@ -47,6 +48,7 @@ public class FontSizeSettings extends K9PreferenceActivity
private ListPreference mMessageViewSender; private ListPreference mMessageViewSender;
private ListPreference mMessageViewTo; private ListPreference mMessageViewTo;
private ListPreference mMessageViewCC; private ListPreference mMessageViewCC;
private ListPreference mMessageViewAdditionalHeaders;
private ListPreference mMessageViewSubject; private ListPreference mMessageViewSubject;
private ListPreference mMessageViewTime; private ListPreference mMessageViewTime;
private ListPreference mMessageViewDate; private ListPreference mMessageViewDate;
@ -85,6 +87,7 @@ public class FontSizeSettings extends K9PreferenceActivity
mMessageViewSender = initializeListPreference(PREFERENCE_MESSAGE_VIEW_SENDER_FONT, fontSizes.getMessageViewSender()); mMessageViewSender = initializeListPreference(PREFERENCE_MESSAGE_VIEW_SENDER_FONT, fontSizes.getMessageViewSender());
mMessageViewTo = initializeListPreference(PREFERENCE_MESSAGE_VIEW_TO_FONT, fontSizes.getMessageViewTo()); mMessageViewTo = initializeListPreference(PREFERENCE_MESSAGE_VIEW_TO_FONT, fontSizes.getMessageViewTo());
mMessageViewCC = initializeListPreference(PREFERENCE_MESSAGE_VIEW_CC_FONT, fontSizes.getMessageViewCC()); mMessageViewCC = initializeListPreference(PREFERENCE_MESSAGE_VIEW_CC_FONT, fontSizes.getMessageViewCC());
mMessageViewAdditionalHeaders = initializeListPreference(PREFERENCE_MESSAGE_VIEW_ADDITIONAL_HEADERS_FONT, fontSizes.getMessageViewAdditionalHeaders());
mMessageViewSubject = initializeListPreference(PREFERENCE_MESSAGE_VIEW_SUBJECT_FONT, fontSizes.getMessageViewSubject()); mMessageViewSubject = initializeListPreference(PREFERENCE_MESSAGE_VIEW_SUBJECT_FONT, fontSizes.getMessageViewSubject());
mMessageViewTime = initializeListPreference(PREFERENCE_MESSAGE_VIEW_TIME_FONT, fontSizes.getMessageViewTime()); mMessageViewTime = initializeListPreference(PREFERENCE_MESSAGE_VIEW_TIME_FONT, fontSizes.getMessageViewTime());
mMessageViewDate = initializeListPreference(PREFERENCE_MESSAGE_VIEW_DATE_FONT, fontSizes.getMessageViewDate()); mMessageViewDate = initializeListPreference(PREFERENCE_MESSAGE_VIEW_DATE_FONT, fontSizes.getMessageViewDate());
@ -112,6 +115,7 @@ public class FontSizeSettings extends K9PreferenceActivity
fontSizes.setMessageViewSender(Integer.parseInt(mMessageViewSender.getValue())); fontSizes.setMessageViewSender(Integer.parseInt(mMessageViewSender.getValue()));
fontSizes.setMessageViewTo(Integer.parseInt(mMessageViewTo.getValue())); fontSizes.setMessageViewTo(Integer.parseInt(mMessageViewTo.getValue()));
fontSizes.setMessageViewCC(Integer.parseInt(mMessageViewCC.getValue())); fontSizes.setMessageViewCC(Integer.parseInt(mMessageViewCC.getValue()));
fontSizes.setMessageViewAdditionalHeaders(Integer.parseInt(mMessageViewAdditionalHeaders.getValue()));
fontSizes.setMessageViewSubject(Integer.parseInt(mMessageViewSubject.getValue())); fontSizes.setMessageViewSubject(Integer.parseInt(mMessageViewSubject.getValue()));
fontSizes.setMessageViewTime(Integer.parseInt(mMessageViewTime.getValue())); fontSizes.setMessageViewTime(Integer.parseInt(mMessageViewTime.getValue()));
fontSizes.setMessageViewDate(Integer.parseInt(mMessageViewDate.getValue())); fontSizes.setMessageViewDate(Integer.parseInt(mMessageViewDate.getValue()));

View File

@ -15,9 +15,6 @@ public enum Flag
/* /*
* The following flags are for internal library use only. * The following flags are for internal library use only.
* TODO Eventually we should creates a Flags class that extends ArrayList that allows
* these flags and Strings to represent user defined flags. At that point the below
* flags should become user defined flags.
*/ */
/** /**
* Delete and remove from the LocalStore immediately. * Delete and remove from the LocalStore immediately.
@ -51,4 +48,11 @@ public enum Flag
* Indicates that the copy of a message to the Sent folder has started. * Indicates that the copy of a message to the Sent folder has started.
*/ */
X_REMOTE_COPY_STARTED, X_REMOTE_COPY_STARTED,
/**
* Indicates that all headers of the message have been stored in the
* database. If this is false, additional headers might be retrieved from
* the server (if the message is still there).
*/
X_GOT_ALL_HEADERS,
} }

View File

@ -3,6 +3,7 @@ package com.fsck.k9.mail;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set;
import com.fsck.k9.activity.MessageReference; import com.fsck.k9.activity.MessageReference;
@ -123,6 +124,8 @@ public abstract class Message implements Part, Body
public abstract String[] getHeader(String name) throws MessagingException; public abstract String[] getHeader(String name) throws MessagingException;
public abstract Set<String> getHeaderNames();
public abstract void removeHeader(String name) throws MessagingException; public abstract void removeHeader(String name) throws MessagingException;
public abstract void setBody(Body body) throws MessagingException; public abstract void setBody(Body body) throws MessagingException;

View File

@ -9,8 +9,7 @@ import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.util.ArrayList; import java.util.*;
import java.util.List;
public class MimeHeader public class MimeHeader
{ {
@ -69,9 +68,9 @@ public class MimeHeader
addHeader(name, value); addHeader(name, value);
} }
public List<String> getHeaderNames() public Set<String> getHeaderNames()
{ {
ArrayList<String> names = new ArrayList<String>(); Set<String> names = new HashSet<String>();
for (Field field : mFields) for (Field field : mFields)
{ {
names.add(field.name); names.add(field.name);

View File

@ -459,7 +459,8 @@ public class MimeMessage extends Message
mHeader.removeHeader(name); mHeader.removeHeader(name);
} }
public List<String> getHeaderNames() @Override
public Set<String> getHeaderNames()
{ {
return mHeader.getHeaderNames(); return mHeader.getHeaderNames();
} }

View File

@ -1441,6 +1441,13 @@ public class LocalStore extends Store implements Serializable
"LocalStore.getMessages(int, int, MessageRetrievalListener) not yet implemented"); "LocalStore.getMessages(int, int, MessageRetrievalListener) not yet implemented");
} }
/**
* Populate the header fields of the given list of messages by reading
* the saved header data from the database.
*
* @param messages
* The messages whose headers should be loaded.
*/
private void populateHeaders(List<LocalMessage> messages) private void populateHeaders(List<LocalMessage> messages)
{ {
Cursor cursor = null; Cursor cursor = null;
@ -1635,6 +1642,11 @@ public class LocalStore extends Store implements Serializable
* assigned and it matches the uid of an existing message then this message will replace the * assigned and it matches the uid of an existing message then this message will replace the
* old message. It is implemented as a delete/insert. This functionality is used in saving * old message. It is implemented as a delete/insert. This functionality is used in saving
* of drafts and re-synchronization of updated server messages. * of drafts and re-synchronization of updated server messages.
*
* NOTE that although this method is located in the LocalStore class, it is not guaranteed
* that the messages supplied as parameters are actually {@link LocalMessage} instances (in
* fact, in most cases, they are not). Therefore, if you want to make local changes only to a
* message, retrieve the appropriate local message instance first (if it already exists).
*/ */
@Override @Override
public void appendMessages(Message[] messages) throws MessagingException public void appendMessages(Message[] messages) throws MessagingException
@ -1647,6 +1659,11 @@ public class LocalStore extends Store implements Serializable
* assigned and it matches the uid of an existing message then this message will replace the * assigned and it matches the uid of an existing message then this message will replace the
* old message. It is implemented as a delete/insert. This functionality is used in saving * old message. It is implemented as a delete/insert. This functionality is used in saving
* of drafts and re-synchronization of updated server messages. * of drafts and re-synchronization of updated server messages.
*
* NOTE that although this method is located in the LocalStore class, it is not guaranteed
* that the messages supplied as parameters are actually {@link LocalMessage} instances (in
* fact, in most cases, they are not). Therefore, if you want to make local changes only to a
* message, retrieve the appropriate local message instance first (if it already exists).
*/ */
private void appendMessages(Message[] messages, boolean copy) throws MessagingException private void appendMessages(Message[] messages, boolean copy) throws MessagingException
{ {
@ -1863,12 +1880,19 @@ public class LocalStore extends Store implements Serializable
} }
} }
private void saveHeaders(long id, MimeMessage message) /**
* Save the headers of the given message. Note that the message is not
* necessarily a {@link LocalMessage} instance.
*/
private void saveHeaders(long id, MimeMessage message) throws MessagingException
{ {
boolean saveAllHeaders = mAccount.isSaveAllHeaders();
boolean gotAdditionalHeaders = false;
deleteHeaders(id); deleteHeaders(id);
for (String name : message.getHeaderNames()) for (String name : message.getHeaderNames())
{ {
if (HEADERS_TO_SAVE.contains(name)) if (saveAllHeaders || HEADERS_TO_SAVE.contains(name))
{ {
String[] values = message.getHeader(name); String[] values = message.getHeader(name);
for (String value : values) for (String value : values)
@ -1880,6 +1904,22 @@ public class LocalStore extends Store implements Serializable
mDb.insert("headers", "name", cv); mDb.insert("headers", "name", cv);
} }
} }
else
{
gotAdditionalHeaders = true;
}
}
if (!gotAdditionalHeaders)
{
// Remember that all headers for this message have been saved, so it is
// not necessary to download them again in case the user wants to see all headers.
List<Flag> appendedFlags = new ArrayList<Flag>();
appendedFlags.addAll(Arrays.asList(message.getFlags()));
appendedFlags.add(Flag.X_GOT_ALL_HEADERS);
mDb.execSQL("UPDATE messages " + "SET flags = ? " + " WHERE id = ?", new Object[]
{ Utility.combine(appendedFlags.toArray(), ',').toUpperCase(), id } );
} }
} }
@ -2698,9 +2738,7 @@ public class LocalStore extends Store implements Serializable
public void addHeader(String name, String value) public void addHeader(String name, String value)
{ {
if (!mHeadersLoaded) if (!mHeadersLoaded)
{
loadHeaders(); loadHeaders();
}
super.addHeader(name, value); super.addHeader(name, value);
} }
@ -2717,7 +2755,6 @@ public class LocalStore extends Store implements Serializable
{ {
if (!mHeadersLoaded) if (!mHeadersLoaded)
loadHeaders(); loadHeaders();
return super.getHeader(name); return super.getHeader(name);
} }
@ -2729,8 +2766,12 @@ public class LocalStore extends Store implements Serializable
super.removeHeader(name); super.removeHeader(name);
} }
@Override
public Set<String> getHeaderNames() {
if (!mHeadersLoaded)
loadHeaders();
return super.getHeaderNames();
}
} }
public class LocalAttachmentBodyPart extends MimeBodyPart public class LocalAttachmentBodyPart extends MimeBodyPart