diff --git a/res/layout/account_setup_options.xml b/res/layout/account_setup_options.xml index a0a4e7316..9267b208d 100644 --- a/res/layout/account_setup_options.xml +++ b/res/layout/account_setup_options.xml @@ -29,6 +29,19 @@ android:id="@+id/account_check_frequency" android:layout_height="wrap_content" android:layout_width="fill_parent" /> + + 60 + + + @string/account_setup_options_mail_window_1day + @string/account_setup_options_mail_window_3days + @string/account_setup_options_mail_window_1week + @string/account_setup_options_mail_window_2weeks + @string/account_setup_options_mail_window_1month + @string/account_setup_options_mail_window_all + + + + 1 + 2 + 3 + 4 + 5 + 6 + + diff --git a/res/values/strings.xml b/res/values/strings.xml index a7d8da2cf..0109d31bf 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -329,6 +329,20 @@ Notify me when email arrives. Setup could not finish + + Amount to synchronize + + One day + + Three days + + One week + + Two weeks + + One month + + All mail Username or password incorrect. diff --git a/res/xml/account_settings_preferences.xml b/res/xml/account_settings_preferences.xml index a9f40f50f..b691e8ba0 100644 --- a/res/xml/account_settings_preferences.xml +++ b/res/xml/account_settings_preferences.xml @@ -20,25 +20,31 @@ android:key="account_settings"> + + diff --git a/res/xml/stores.xml b/res/xml/stores.xml index 22db39c20..d362a8e4c 100644 --- a/res/xml/stores.xml +++ b/res/xml/stores.xml @@ -36,5 +36,5 @@ + push="true" visibleLimitDefault="-1" visibleLimitIncrement="-1" accountInstanceLimit="1" /> diff --git a/src/com/android/email/Account.java b/src/com/android/email/Account.java index f0037d216..cea3a25d6 100644 --- a/src/com/android/email/Account.java +++ b/src/com/android/email/Account.java @@ -37,6 +37,14 @@ public class Account implements Serializable { public static final int CHECK_INTERVAL_NEVER = -1; public static final int CHECK_INTERVAL_PUSH = -2; + + public static final int SYNC_WINDOW_USER = -1; + public static final int SYNC_WINDOW_1_DAY = 1; + public static final int SYNC_WINDOW_3_DAYS = 2; + public static final int SYNC_WINDOW_1_WEEK = 3; + public static final int SYNC_WINDOW_2_WEEKS = 4; + public static final int SYNC_WINDOW_1_MONTH = 5; + public static final int SYNC_WINDOW_ALL = 6; /** * This should never be used for persistance, only for marshalling. @@ -65,6 +73,7 @@ public class Account implements Serializable { int mAccountNumber; boolean mVibrate; String mRingtoneUri; + int mSyncWindow; /** *
@@ -75,6 +84,11 @@ public class Account implements Serializable {
      */
     int mDeletePolicy;
 
+    /**
+     * All new fields should have named keys
+     */
+    private final String KEY_SYNC_WINDOW = ".syncWindow";
+
     public Account(Context context) {
         // TODO Change local store path to something readable / recognizable
         mUuid = UUID.randomUUID().toString();
@@ -84,6 +98,7 @@ public class Account implements Serializable {
         mNotifyNewMail = true;
         mVibrate = false;
         mRingtoneUri = "content://settings/system/notification_sound";
+        mSyncWindow = SYNC_WINDOW_USER;       // IMAP & POP3
     }
 
     Account(Preferences preferences, String uuid) {
@@ -139,7 +154,9 @@ public class Account implements Serializable {
         mVibrate = preferences.mSharedPreferences.getBoolean(mUuid + ".vibrate", false);
         mRingtoneUri = preferences.mSharedPreferences.getString(mUuid  + ".ringtone", 
                 "content://settings/system/notification_sound");
-
+        
+        mSyncWindow = preferences.mSharedPreferences.getInt(mUuid + KEY_SYNC_WINDOW, 
+                SYNC_WINDOW_USER);
     }
 
     public String getUuid() {
@@ -234,6 +251,7 @@ public class Account implements Serializable {
         editor.remove(mUuid + ".accountNumber");
         editor.remove(mUuid + ".vibrate");
         editor.remove(mUuid + ".ringtone");
+        editor.remove(mUuid + KEY_SYNC_WINDOW);
 
         // also delete any deprecated fields
         editor.remove(mUuid + ".transportUri");
@@ -296,6 +314,7 @@ public class Account implements Serializable {
         editor.putInt(mUuid + ".accountNumber", mAccountNumber);
         editor.putBoolean(mUuid + ".vibrate", mVibrate);
         editor.putString(mUuid + ".ringtone", mRingtoneUri);
+        editor.putInt(mUuid + KEY_SYNC_WINDOW, mSyncWindow);
         
         // The following fields are *not* written because they need to be more fine-grained
         // and not risk rewriting with old data.
@@ -398,6 +417,14 @@ public class Account implements Serializable {
         return mAccountNumber;
     }
 
+    public int getSyncWindow() {
+        return mSyncWindow;
+    }
+    
+    public void setSyncWindow(int window) {
+        mSyncWindow = window;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (o instanceof Account) {
diff --git a/src/com/android/email/activity/FolderMessageList.java b/src/com/android/email/activity/FolderMessageList.java
index 1d2548d03..bd8b1fa61 100644
--- a/src/com/android/email/activity/FolderMessageList.java
+++ b/src/com/android/email/activity/FolderMessageList.java
@@ -97,6 +97,8 @@ public class FolderMessageList extends ExpandableListActivity {
             "com.android.email.activity.folderlist_expandedGroup";
     private static final String STATE_KEY_EXPANDED_GROUP_SELECTION =
             "com.android.email.activity.folderlist_expandedGroupSelection";
+    private static final String STATE_KEY_REFRESH_REMOTE = 
+            "com.android.email.activity.refresh_remote";
 
     private static final int UPDATE_FOLDER_ON_EXPAND_INTERVAL_MS = (1000 * 60 * 3);
 
@@ -130,6 +132,8 @@ public class FolderMessageList extends ExpandableListActivity {
     private FolderMessageListAdapter mAdapter;
     private LayoutInflater mInflater;
     private Account mAccount;
+    private boolean mSyncWindowUser;
+
     /**
      * Stores the name of the folder that we want to open as soon as possible after load. It is
      * set to null once the folder has been opened once.
@@ -462,6 +466,12 @@ public class FolderMessageList extends ExpandableListActivity {
          */
         colorChipResId = colorChipResIds[mAccount.getAccountNumber() % colorChipResIds.length];
 
+        /**
+         * "User" means the user adjusts the sync window in the UI (load more messages).
+         * Non-user means that it's set to a fixed window e.g. 3 days
+         */
+        mSyncWindowUser = mAccount.getSyncWindow() == Account.SYNC_WINDOW_USER;
+        
         mAdapter = new FolderMessageListAdapter();
 
         final Object previousData = getLastNonConfigurationInstance();
@@ -476,6 +486,7 @@ public class FolderMessageList extends ExpandableListActivity {
             mRestoringState = true;
             onRestoreListState(savedInstanceState);
             mRestoringState = false;
+            mRefreshRemote |= savedInstanceState.getBoolean(STATE_KEY_REFRESH_REMOTE);
         }
 
         setTitle(mAccount.getDescription());
@@ -528,6 +539,7 @@ public class FolderMessageList extends ExpandableListActivity {
         outState.putParcelable(STATE_KEY_LIST, mListView.onSaveInstanceState());
         outState.putInt(STATE_KEY_EXPANDED_GROUP, mExpandedGroup);
         outState.putLong(STATE_KEY_EXPANDED_GROUP_SELECTION, mListView.getSelectedPosition());
+        outState.putBoolean(STATE_KEY_REFRESH_REMOTE, mRefreshRemote);
     }
 
     @Override
@@ -576,7 +588,7 @@ public class FolderMessageList extends ExpandableListActivity {
             return false;
         }
         if (childPosition == folder.messages.size() && !folder.loading) {
-            if (folder.status == null) {
+            if (folder.status == null && mSyncWindowUser) {
                 MessagingController.getInstance(getApplication()).loadMoreMessages(
                         mAccount,
                         folder.name,
@@ -610,7 +622,7 @@ public class FolderMessageList extends ExpandableListActivity {
                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                 MessagingController.getInstance(getApplication()).listFolders(
                         mAccount,
-                        forceRemote,
+                        mRefreshRemote,
                         mAdapter.mListener);
                 if (forceRemote) {
                     MessagingController.getInstance(getApplication()).sendPendingMessages(
@@ -647,6 +659,9 @@ public class FolderMessageList extends ExpandableListActivity {
     }
 
     private void onEditAccount() {
+        // We request a remote refresh *after* the account settings because user changes may
+        // change the results we get from the server.  This will be picked up in onResume().
+        mRefreshRemote = true;
         AccountSettings.actionSettings(this, mAccount);
     }
 
@@ -1234,7 +1249,12 @@ public class FolderMessageList extends ExpandableListActivity {
                 }
                 else {
                     if (folder.status == null) {
-                        holder.main.setText(getString(R.string.message_list_load_more_messages_action));
+                        if (mSyncWindowUser) {
+                            holder.main.setText(getString(
+                                    R.string.message_list_load_more_messages_action));
+                        } else {
+                            holder.main.setText(getString(R.string.refresh_action));
+                        }
                     }
                     else {
                         holder.main.setText(getString(R.string.status_loading_more_failed));
diff --git a/src/com/android/email/activity/setup/AccountSettings.java b/src/com/android/email/activity/setup/AccountSettings.java
index c21c2bee1..bc21dbd06 100644
--- a/src/com/android/email/activity/setup/AccountSettings.java
+++ b/src/com/android/email/activity/setup/AccountSettings.java
@@ -32,6 +32,7 @@ import android.preference.EditTextPreference;
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
 import android.preference.RingtonePreference;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -56,6 +57,7 @@ public class AccountSettings extends PreferenceActivity {
     private EditTextPreference mAccountDescription;
     private EditTextPreference mAccountName;
     private ListPreference mCheckFrequency;
+    private ListPreference mSyncWindow;
     private CheckBoxPreference mAccountDefault;
     private CheckBoxPreference mAccountNotify;
     private CheckBoxPreference mAccountVibrate;
@@ -75,7 +77,7 @@ public class AccountSettings extends PreferenceActivity {
 
         addPreferencesFromResource(R.xml.account_settings_preferences);
 
-        Preference category = findPreference(PREFERENCE_TOP_CATERGORY);
+        PreferenceCategory category = (PreferenceCategory) findPreference(PREFERENCE_TOP_CATERGORY);
         category.setTitle(getString(R.string.account_settings_title_fmt));
 
         mAccountDescription = (EditTextPreference) findPreference(PREFERENCE_DESCRIPTION);
@@ -122,6 +124,28 @@ public class AccountSettings extends PreferenceActivity {
                 return false;
             }
         });
+        
+        // Add check window preference
+        mSyncWindow = null;
+        if (info.mVisibleLimitDefault == -1) {
+            mSyncWindow = new ListPreference(this);
+            mSyncWindow.setTitle(R.string.account_setup_options_mail_window_label);
+            mSyncWindow.setEntries(R.array.account_settings_mail_window_entries);
+            mSyncWindow.setEntryValues(R.array.account_settings_mail_window_values);
+            mSyncWindow.setValue(String.valueOf(mAccount.getSyncWindow()));
+            mSyncWindow.setSummary(mSyncWindow.getEntry());
+            mSyncWindow.setOrder(4);
+            mSyncWindow.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+                public boolean onPreferenceChange(Preference preference, Object newValue) {
+                    final String summary = newValue.toString();
+                    int index = mSyncWindow.findIndexOfValue(summary);
+                    mSyncWindow.setSummary(mSyncWindow.getEntries()[index]);
+                    mSyncWindow.setValue(summary);
+                    return false;
+                }
+            });
+            category.addPreference(mSyncWindow);
+        }
 
         mAccountDefault = (CheckBoxPreference) findPreference(PREFERENCE_DEFAULT);
         mAccountDefault.setChecked(
@@ -178,6 +202,10 @@ public class AccountSettings extends PreferenceActivity {
         mAccount.setName(mAccountName.getText());
         mAccount.setNotifyNewMail(mAccountNotify.isChecked());
         mAccount.setAutomaticCheckIntervalMinutes(Integer.parseInt(mCheckFrequency.getValue()));
+        if (mSyncWindow != null)
+        {
+            mAccount.setSyncWindow(Integer.parseInt(mSyncWindow.getValue()));
+        }
         mAccount.setVibrate(mAccountVibrate.isChecked());
         SharedPreferences prefs = mAccountRingtone.getPreferenceManager().getSharedPreferences();
         mAccount.setRingtone(prefs.getString(PREFERENCE_RINGTONE, null));
diff --git a/src/com/android/email/activity/setup/AccountSetupAccountType.java b/src/com/android/email/activity/setup/AccountSetupAccountType.java
index a951b026b..335d639ca 100644
--- a/src/com/android/email/activity/setup/AccountSetupAccountType.java
+++ b/src/com/android/email/activity/setup/AccountSetupAccountType.java
@@ -19,7 +19,6 @@ package com.android.email.activity.setup;
 import com.android.email.Account;
 import com.android.email.Preferences;
 import com.android.email.R;
-import com.android.email.mail.MessagingException;
 import com.android.email.mail.Store;
 
 import android.app.Activity;
@@ -128,6 +127,7 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
         // TODO: Confirm correct delete policy for exchange
         mAccount.setDeletePolicy(Account.DELETE_POLICY_ON_DELETE);
         mAccount.setAutomaticCheckIntervalMinutes(Account.CHECK_INTERVAL_PUSH);
+        mAccount.setSyncWindow(Account.SYNC_WINDOW_3_DAYS);
         AccountSetupExchange.actionIncomingSettings(this, mAccount, mMakeDefault);
         finish();
     }
diff --git a/src/com/android/email/activity/setup/AccountSetupOptions.java b/src/com/android/email/activity/setup/AccountSetupOptions.java
index a82877da9..61f2aa75a 100644
--- a/src/com/android/email/activity/setup/AccountSetupOptions.java
+++ b/src/com/android/email/activity/setup/AccountSetupOptions.java
@@ -37,6 +37,7 @@ public class AccountSetupOptions extends Activity implements OnClickListener {
     private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
 
     private Spinner mCheckFrequencyView;
+    private Spinner mSyncWindowView;
 
     private CheckBox mDefaultView;
 
@@ -57,6 +58,7 @@ public class AccountSetupOptions extends Activity implements OnClickListener {
         setContentView(R.layout.account_setup_options);
 
         mCheckFrequencyView = (Spinner)findViewById(R.id.account_check_frequency);
+        mSyncWindowView = (Spinner) findViewById(R.id.account_sync_window);
         mDefaultView = (CheckBox)findViewById(R.id.account_default);
         mNotifyView = (CheckBox)findViewById(R.id.account_notify);
 
@@ -91,6 +93,10 @@ public class AccountSetupOptions extends Activity implements OnClickListener {
         checkFrequenciesAdapter
                 .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         mCheckFrequencyView.setAdapter(checkFrequenciesAdapter);
+        
+        if (info.mVisibleLimitDefault == -1) {
+            enableEASSyncWindowSpinner();
+        }
 
         if (mAccount.equals(Preferences.getPreferences(this).getDefaultAccount()) || makeDefault) {
             mDefaultView.setChecked(true);
@@ -105,6 +111,10 @@ public class AccountSetupOptions extends Activity implements OnClickListener {
         mAccount.setNotifyNewMail(mNotifyView.isChecked());
         mAccount.setAutomaticCheckIntervalMinutes((Integer)((SpinnerOption)mCheckFrequencyView
                 .getSelectedItem()).value);
+        if (mSyncWindowView.getVisibility() == View.VISIBLE) {
+            int window = (Integer)((SpinnerOption)mSyncWindowView.getSelectedItem()).value;
+            mAccount.setSyncWindow(window);
+        }
         mAccount.save(Preferences.getPreferences(this));
         if (mDefaultView.isChecked()) {
             Preferences.getPreferences(this).setDefaultAccount(mAccount);
@@ -121,4 +131,34 @@ public class AccountSetupOptions extends Activity implements OnClickListener {
                 break;
         }
     }
+    
+    /**
+     * Enable an additional spinner using the arrays normally handled by preferences
+     */
+    private void enableEASSyncWindowSpinner() {
+        // Show everything
+        findViewById(R.id.account_sync_window_label).setVisibility(View.VISIBLE);
+        mSyncWindowView.setVisibility(View.VISIBLE);
+
+        // Generate spinner entries using XML arrays used by the preferences
+        CharSequence[] windowValues = getResources().getTextArray(
+                R.array.account_settings_mail_window_values);
+        CharSequence[] windowEntries = getResources().getTextArray(
+                R.array.account_settings_mail_window_entries);
+        
+        // Now create the array used by the Spinner
+        SpinnerOption[] windowOptions = new SpinnerOption[windowEntries.length];
+        for (int i = 0; i < windowEntries.length; i++) {
+            windowOptions[i] = new SpinnerOption(
+                    Integer.valueOf(windowValues[i].toString()), windowEntries[i].toString());
+        }
+
+        ArrayAdapter windowOptionsAdapter = new ArrayAdapter(this,
+                android.R.layout.simple_spinner_item, windowOptions);
+        windowOptionsAdapter
+                .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mSyncWindowView.setAdapter(windowOptionsAdapter);
+        
+        SpinnerOption.setSpinnerOptionValue(mSyncWindowView, mAccount.getSyncWindow());
+    }
 }