mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-15 22:15:15 -05:00
Added "advanced options" option and more support for local-only messages and folders:
added message upload support. added advanced option to create local-only folder. disabled sync & push for local-only folders. hid expunge, check_mail, and "Load up to x more" for local-only folders. hid create/rename/delete folder options for webdav (someone give me a webdav account). added advanced option to change if a folder is local-only or syncable. add dialog to confirm clearing local messages, and if it should include local-only messages or just synced messages. added advanced option to automatically upload on move from local-only to syncable. changed background color in message list and subject color in message view of local-only messages. changed: keep local-only messages in folders no longer on server instead of deleting folder, and mark folder as local-only. added automatically fully downloading messages moved/copied to local-only folder. added advanced options option (if not enabled, those settings will be hidden). reworked onCreateFolder(), onRenameFolder(), onDeleteFolder(). added Store.isAppendCapable(). added LocalFolder.expunge() [unused].
This commit is contained in:
parent
14a0fdf27d
commit
d13aa61de3
30
res/layout/clear_local_folder.xml
Normal file
30
res/layout/clear_local_folder.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/layout_root"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:padding="10dp" >
|
||||
<TextView
|
||||
android:id="@+id/clear_local_folder_text"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:text="@+string/clear_local_folder_text"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="#FFF" />
|
||||
<TextView
|
||||
android:id="@+id/clear_local_only_folder_text"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:text="@+string/clear_local_only_folder_text"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="#FFF" />
|
||||
<CheckBox
|
||||
android:id="@+id/clear_local_folder_all"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:text="@string/clear_local_folder_all"
|
||||
android:textColor="#FFF"
|
||||
android:checked="false" />
|
||||
</LinearLayout>
|
21
res/layout/create_folder.xml
Normal file
21
res/layout/create_folder.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/layout_root"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:padding="10dp" >
|
||||
<EditText
|
||||
android:id="@+id/create_folder_text"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:hint="@string/create_folder_hint" />
|
||||
<CheckBox
|
||||
android:id="@+id/create_folder_local"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:text="@string/create_folder_local"
|
||||
android:textColor="#FFF"
|
||||
android:checked="false" />
|
||||
</LinearLayout>
|
@ -57,6 +57,10 @@
|
||||
android:id="@+id/copy"
|
||||
android:title="@string/copy_action"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/upload"
|
||||
android:title="@string/upload"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/send_alternate"
|
||||
android:title="@string/send_alternate_action"
|
||||
|
@ -93,6 +93,10 @@
|
||||
android:id="@+id/batch_copy_op"
|
||||
android:title="@string/batch_copy_op"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/batch_upload_op"
|
||||
android:title="@string/batch_upload_op"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/batch_select_all"
|
||||
android:title="@string/batch_select_all"
|
||||
|
@ -61,8 +61,12 @@
|
||||
android:id="@+id/copy"
|
||||
android:title="@string/copy_action"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/select_text"
|
||||
android:title="@string/select_text_action"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/upload"
|
||||
android:title="@string/upload"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/select_text"
|
||||
android:title="@string/select_text_action"
|
||||
/>
|
||||
</menu>
|
||||
|
@ -76,6 +76,8 @@
|
||||
<string name="create_folder_action">Create folder</string>
|
||||
<string name="rename_folder_action">Rename folder</string>
|
||||
<string name="delete_folder_action">Delete folder</string>
|
||||
<string name="create_folder_hint">New folder name</string>
|
||||
<string name="create_folder_local">Local-only</string>
|
||||
<string name="mark_all_as_read_action">Mark all messages as read</string>
|
||||
<string name="add_account_action">Add account</string>
|
||||
<string name="compose_action">Compose</string>
|
||||
@ -124,6 +126,9 @@
|
||||
<string name="empty_trash_action">Empty Trash</string>
|
||||
<string name="expunge_action">Expunge</string>
|
||||
<string name="clear_local_folder_action">Clear local messages</string>
|
||||
<string name="clear_local_folder_text">Clear local copies of remote messages?</string>
|
||||
<string name="clear_local_only_folder_text">Clear local-only messages? These will be permanently lost!</string>
|
||||
<string name="clear_local_folder_all">Include local-only messages? These will be permanently lost!</string>
|
||||
<string name="set_sort_action">Choose sort</string>
|
||||
<string name="reverse_sort_action">Reverse sort</string>
|
||||
<string name="about_action">About</string>
|
||||
@ -310,6 +315,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
||||
<string name="folder_push_active_symbol">(Push)</string>
|
||||
|
||||
<string name="from_same_sender">More from this sender</string>
|
||||
<string name="upload">Upload</string>
|
||||
|
||||
<string name="message_copied_toast">Message copied</string>
|
||||
<string name="message_moved_toast">Message moved</string>
|
||||
@ -421,6 +427,9 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
||||
<string name="account_setup_incoming_save_all_headers_title">Download headers</string>
|
||||
<string name="account_setup_incoming_save_all_headers_label">Save all message headers locally</string>
|
||||
|
||||
<string name="account_setup_auto_upload_on_move_title">Upload on move or copy</string>
|
||||
<string name="account_setup_auto_upload_on_move_label">Automatically upload local-only message when moved/copied to a syncable folder</string>
|
||||
|
||||
<string name="local_storage_provider_external_label">External storage (SD card)</string>
|
||||
<string name="local_storage_provider_internal_label">Regular internal storage</string>
|
||||
<string name="local_storage_provider_samsunggalaxy_label">%1$s additional internal storage</string>
|
||||
@ -681,6 +690,9 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
||||
<string name="folder_settings_in_top_group_label">Show in top group</string>
|
||||
<string name="folder_settings_in_top_group_summary">Show near the top of the folder list</string>
|
||||
|
||||
<string name="folder_settings_local_only_label">Local-only folder</string>
|
||||
<string name="folder_settings_local_only_summary">Set to local-only folder (never synced with server)</string>
|
||||
|
||||
<string name="folder_settings_folder_display_mode_label">Folder display class</string>
|
||||
<string name="folder_settings_folder_display_mode_normal">None</string>
|
||||
<string name="folder_settings_folder_display_mode_first_class">1st Class</string>
|
||||
@ -896,6 +908,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
||||
<string name="batch_spam_op">Move selected to Spam</string>
|
||||
<string name="batch_move_op">Move selected</string>
|
||||
<string name="batch_copy_op">Copy selected</string>
|
||||
<string name="batch_upload_op">Upload selected</string>
|
||||
<string name="batch_flag_mode">Star mode</string>
|
||||
<string name="batch_select_mode">Select mode</string>
|
||||
<string name="batch_plain_mode">Plain mode</string>
|
||||
@ -919,6 +932,9 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
||||
<string name="compact_layouts_title">Compact layouts</string>
|
||||
<string name="compact_layouts_summary">Adjust layouts to display more on each page</string>
|
||||
|
||||
<string name="show_advanced_options_title">Advanced options</string>
|
||||
<string name="show_advanced_options_summary">Show advanced options</string>
|
||||
|
||||
<string name="volume_navigation_title">Volume key navigation</string>
|
||||
<string name="volume_navigation_summary">Flip through items using the volume controls</string>
|
||||
<string name="volume_navigation_message">Message view</string>
|
||||
|
@ -179,6 +179,12 @@
|
||||
android:key="account_save_all_headers"
|
||||
android:summary="@string/account_setup_incoming_save_all_headers_label" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:persistent="false"
|
||||
android:title="@string/account_setup_auto_upload_on_move_title"
|
||||
android:key="account_auto_upload_on_move"
|
||||
android:summary="@string/account_setup_auto_upload_on_move_label" />
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="incoming"
|
||||
android:title="@string/account_settings_incoming_label"
|
||||
|
@ -61,6 +61,12 @@
|
||||
android:title="@string/folder_settings_include_in_integrated_inbox_label"
|
||||
android:summary="@string/folder_settings_include_in_integrated_inbox_summary" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:persistent="false"
|
||||
android:key="folder_settings_local_only"
|
||||
android:title="@string/folder_settings_local_only_label"
|
||||
android:summary="@string/folder_settings_local_only_summary" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
@ -73,6 +73,11 @@
|
||||
android:title="@string/compact_layouts_title"
|
||||
android:summary="@string/compact_layouts_summary" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:persistent="false"
|
||||
android:key="show_advanced_options"
|
||||
android:title="@string/show_advanced_options_title"
|
||||
android:summary="@string/show_advanced_options_summary" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
@ -68,6 +68,7 @@ public class Account implements BaseAccount {
|
||||
public static final boolean DEFAULT_QUOTED_TEXT_SHOWN = true;
|
||||
public static final boolean DEFAULT_REPLY_AFTER_QUOTE = false;
|
||||
public static final boolean DEFAULT_STRIP_SIGNATURE = true;
|
||||
public static final boolean DEFAULT_SHOW_ADVANCED_OPTIONS = false;
|
||||
|
||||
public static final String ACCOUNT_DESCRIPTION_KEY = "description";
|
||||
public static final String STORE_URI_KEY = "storeUri";
|
||||
@ -119,6 +120,7 @@ public class Account implements BaseAccount {
|
||||
private FolderMode mFolderTargetMode;
|
||||
private int mAccountNumber;
|
||||
private boolean mSaveAllHeaders;
|
||||
private boolean mAutoUploadOnMove;
|
||||
private boolean mPushPollOnConnect;
|
||||
private boolean mNotifySync;
|
||||
private ScrollButtons mScrollMessageViewButtons;
|
||||
@ -206,6 +208,7 @@ public class Account implements BaseAccount {
|
||||
mAutomaticCheckIntervalMinutes = -1;
|
||||
mIdleRefreshMinutes = 24;
|
||||
mSaveAllHeaders = true;
|
||||
mAutoUploadOnMove = true;
|
||||
mPushPollOnConnect = true;
|
||||
mDisplayCount = K9.DEFAULT_VISIBLE_LIMIT;
|
||||
mAccountNumber = -1;
|
||||
@ -284,6 +287,7 @@ public class Account implements BaseAccount {
|
||||
mAutomaticCheckIntervalMinutes = prefs.getInt(mUuid + ".automaticCheckIntervalMinutes", -1);
|
||||
mIdleRefreshMinutes = prefs.getInt(mUuid + ".idleRefreshMinutes", 24);
|
||||
mSaveAllHeaders = prefs.getBoolean(mUuid + ".saveAllHeaders", true);
|
||||
mAutoUploadOnMove = prefs.getBoolean(mUuid + ".autoUploadOnMove", true);
|
||||
mPushPollOnConnect = prefs.getBoolean(mUuid + ".pushPollOnConnect", true);
|
||||
mDisplayCount = prefs.getInt(mUuid + ".displayCount", K9.DEFAULT_VISIBLE_LIMIT);
|
||||
if (mDisplayCount < 0) {
|
||||
@ -445,6 +449,7 @@ public class Account implements BaseAccount {
|
||||
editor.remove(mUuid + ".automaticCheckIntervalMinutes");
|
||||
editor.remove(mUuid + ".pushPollOnConnect");
|
||||
editor.remove(mUuid + ".saveAllHeaders");
|
||||
editor.remove(mUuid + ".autoUploadOnMove");
|
||||
editor.remove(mUuid + ".idleRefreshMinutes");
|
||||
editor.remove(mUuid + ".lastAutomaticCheckTime");
|
||||
editor.remove(mUuid + ".latestOldMessageSeenTime");
|
||||
@ -601,6 +606,7 @@ public class Account implements BaseAccount {
|
||||
editor.putInt(mUuid + ".automaticCheckIntervalMinutes", mAutomaticCheckIntervalMinutes);
|
||||
editor.putInt(mUuid + ".idleRefreshMinutes", mIdleRefreshMinutes);
|
||||
editor.putBoolean(mUuid + ".saveAllHeaders", mSaveAllHeaders);
|
||||
editor.putBoolean(mUuid + ".autoUploadOnMove", mAutoUploadOnMove);
|
||||
editor.putBoolean(mUuid + ".pushPollOnConnect", mPushPollOnConnect);
|
||||
editor.putInt(mUuid + ".displayCount", mDisplayCount);
|
||||
editor.putLong(mUuid + ".lastAutomaticCheckTime", mLastAutomaticCheckTime);
|
||||
@ -1305,6 +1311,14 @@ public class Account implements BaseAccount {
|
||||
mSaveAllHeaders = saveAllHeaders;
|
||||
}
|
||||
|
||||
public synchronized boolean isAutoUploadOnMove() {
|
||||
return mAutoUploadOnMove;
|
||||
}
|
||||
|
||||
public synchronized void setAutoUploadOnMove(boolean autoUploadOnMove) {
|
||||
mAutoUploadOnMove = autoUploadOnMove;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are we storing out localStore on the SD-card instead of the local device
|
||||
* memory?<br/>
|
||||
|
@ -179,7 +179,7 @@ public class K9 extends Application {
|
||||
private static String mQuietTimeEnds = null;
|
||||
private static boolean compactLayouts = false;
|
||||
private static String mAttachmentDefaultPath = "";
|
||||
|
||||
private static boolean mShowAdvancedOptions;
|
||||
|
||||
private static boolean useGalleryBugWorkaround = false;
|
||||
private static boolean galleryBuggy;
|
||||
@ -445,6 +445,7 @@ public class K9 extends Application {
|
||||
|
||||
editor.putBoolean("compactLayouts", compactLayouts);
|
||||
editor.putString("attachmentdefaultpath", mAttachmentDefaultPath);
|
||||
editor.putBoolean("showAdvancedOptions", mShowAdvancedOptions);
|
||||
fontSizes.save(editor);
|
||||
}
|
||||
|
||||
@ -575,6 +576,7 @@ public class K9 extends Application {
|
||||
|
||||
compactLayouts = sprefs.getBoolean("compactLayouts", false);
|
||||
mAttachmentDefaultPath = sprefs.getString("attachmentdefaultpath", Environment.getExternalStorageDirectory().toString());
|
||||
mShowAdvancedOptions = sprefs.getBoolean("showAdvancedOptions", false);
|
||||
fontSizes.load(sprefs);
|
||||
|
||||
try {
|
||||
@ -1016,4 +1018,14 @@ public class K9 extends Application {
|
||||
public static void setAttachmentDefaultPath(String attachmentDefaultPath) {
|
||||
K9.mAttachmentDefaultPath = attachmentDefaultPath;
|
||||
}
|
||||
|
||||
public static boolean isShowAdvancedOptions() {
|
||||
return mShowAdvancedOptions;
|
||||
}
|
||||
|
||||
public static void setShowAdvancedOptions(boolean showAdvancedOptions) {
|
||||
mShowAdvancedOptions = showAdvancedOptions;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Filter;
|
||||
import android.widget.ListView;
|
||||
@ -33,6 +34,8 @@ import com.fsck.k9.mail.store.WebDavStore;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ChooseFolder extends K9ListActivity {
|
||||
String mFolder;
|
||||
@ -183,6 +186,9 @@ public class ChooseFolder extends K9ListActivity {
|
||||
@Override public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
getMenuInflater().inflate(R.menu.folder_select_option, menu);
|
||||
if (mAccount.getStoreUri().startsWith("webdav")) {
|
||||
menu.findItem(R.id.create_folder).setVisible(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -283,21 +289,37 @@ public class ChooseFolder extends K9ListActivity {
|
||||
}
|
||||
|
||||
/*
|
||||
Show a dialog to create a new folder on the remote Store.
|
||||
Currently only IMAP is supported.
|
||||
Exactly the same as activity.FolderList.onCreateFolder().
|
||||
Show a dialog to create a new folder.
|
||||
Currently only IMAP and Pop3 supported.
|
||||
IMAP folders are both remote and local. Pop3 folders are only local.
|
||||
Exactly the same as activity.FolderList.onCreateFolder(), plus one line, plus s/mInflater/getLayoutInflater()/;
|
||||
*/
|
||||
private void onCreateFolder() {
|
||||
final EditText input = new EditText(this);
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
||||
dialog.setTitle(R.string.create_folder_action);
|
||||
dialog.setView(input);
|
||||
View view = getLayoutInflater().inflate(R.layout.create_folder, null);
|
||||
final EditText input = (EditText) view.findViewById(R.id.create_folder_text);
|
||||
final CheckBox checkBox = (CheckBox) view.findViewById(R.id.create_folder_local);
|
||||
if (mAccount.getStoreUri().startsWith("pop3") || !K9.isShowAdvancedOptions()) {
|
||||
checkBox.setVisibility(View.GONE);
|
||||
}
|
||||
dialog.setView(view);
|
||||
dialog.setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
String folderName = input.getText().toString().trim();
|
||||
if (folderName.matches("")) {
|
||||
Toast.makeText(getApplication(), "Folder name not given!", Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Store store = mAccount.getRemoteStore();
|
||||
if (store instanceof ImapStore) {
|
||||
if (store instanceof Pop3Store || checkBox.isChecked()) {
|
||||
boolean result = mAccount.getLocalStore().createFolder(folderName, true);
|
||||
String toastText = "Creation of folder \"" + folderName +
|
||||
((result) ? "\" succeeded." : "\" failed.");
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
onRefresh(false);
|
||||
} else if (store instanceof ImapStore) {
|
||||
boolean result = ((ImapStore)store).createFolder(folderName);
|
||||
String toastText = "Creation of folder \"" + folderName +
|
||||
((result) ? "\" succeeded." : "\" failed.");
|
||||
@ -307,12 +329,6 @@ public class ChooseFolder extends K9ListActivity {
|
||||
} else if (store instanceof WebDavStore) {
|
||||
String toastText = "Creating WebDav Folders not currently implemented.";
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
} else if (store instanceof Pop3Store) {
|
||||
boolean result = mAccount.getLocalStore().createFolder(folderName, true);
|
||||
String toastText = "Creation of folder \"" + folderName +
|
||||
((result) ? "\" succeeded." : "\" failed.");
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
onRefresh(false);
|
||||
} else {
|
||||
Log.d(K9.LOG_TAG, "Unhandled store type " + store.getClass());
|
||||
}
|
||||
@ -323,9 +339,7 @@ public class ChooseFolder extends K9ListActivity {
|
||||
}
|
||||
});
|
||||
dialog.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
/* User clicked cancel so do some stuff */
|
||||
}
|
||||
public void onClick(DialogInterface dialog, int whichButton) {}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
@ -45,8 +45,10 @@ import com.fsck.k9.service.MailService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* FolderList is the primary user interface for the program. This
|
||||
@ -477,16 +479,31 @@ public class FolderList extends K9ListActivity {
|
||||
Exactly the same as activity.ChooseFolder.onCreateFolder().
|
||||
*/
|
||||
private void onCreateFolder() {
|
||||
final EditText input = new EditText(this);
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
||||
dialog.setTitle(R.string.create_folder_action);
|
||||
dialog.setView(input);
|
||||
View view = mInflater.inflate(R.layout.create_folder, null);
|
||||
final EditText input = (EditText) view.findViewById(R.id.create_folder_text);
|
||||
final CheckBox checkBox = (CheckBox) view.findViewById(R.id.create_folder_local);
|
||||
if (mAccount.getStoreUri().startsWith("pop3") || !K9.isShowAdvancedOptions()) {
|
||||
checkBox.setVisibility(View.GONE);
|
||||
}
|
||||
dialog.setView(view);
|
||||
dialog.setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
String folderName = input.getText().toString().trim();
|
||||
if (folderName.matches("")) {
|
||||
Toast.makeText(getApplication(), "Folder name not given!", Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Store store = mAccount.getRemoteStore();
|
||||
if (store instanceof ImapStore) {
|
||||
if (store instanceof Pop3Store || checkBox.isChecked()) {
|
||||
boolean result = mAccount.getLocalStore().createFolder(folderName, true);
|
||||
String toastText = "Creation of folder \"" + folderName +
|
||||
((result) ? "\" succeeded." : "\" failed.");
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
onRefresh(false);
|
||||
} else if (store instanceof ImapStore) {
|
||||
boolean result = ((ImapStore)store).createFolder(folderName);
|
||||
String toastText = "Creation of folder \"" + folderName +
|
||||
((result) ? "\" succeeded." : "\" failed.");
|
||||
@ -495,12 +512,6 @@ public class FolderList extends K9ListActivity {
|
||||
} else if (store instanceof WebDavStore) {
|
||||
String toastText = "Creating WebDav Folders not currently implemented.";
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
} else if (store instanceof Pop3Store) {
|
||||
boolean result = mAccount.getLocalStore().createFolder(folderName, true);
|
||||
String toastText = "Creation of folder \"" + folderName +
|
||||
((result) ? "\" succeeded." : "\" failed.");
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
onRefresh(false);
|
||||
} else {
|
||||
Log.d(K9.LOG_TAG, "Unhandled store type " + store.getClass());
|
||||
}
|
||||
@ -511,9 +522,7 @@ public class FolderList extends K9ListActivity {
|
||||
}
|
||||
});
|
||||
dialog.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
/* User clicked cancel so do some stuff */
|
||||
}
|
||||
public void onClick(DialogInterface dialog, int whichButton) {}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
@ -544,33 +553,65 @@ public class FolderList extends K9ListActivity {
|
||||
MessagingController.getInstance(getApplication()).expunge(account, folderName, null);
|
||||
}
|
||||
|
||||
|
||||
private void onClearFolder(Account account, String folderName) {
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
||||
dialog.setCancelable(false);
|
||||
dialog.setTitle(R.string.clear_local_folder_action);
|
||||
View view = mInflater.inflate(R.layout.clear_local_folder, null);
|
||||
final TextView text = (TextView) view.findViewById(R.id.clear_local_folder_text);
|
||||
final TextView textLocal = (TextView) view.findViewById(R.id.clear_local_only_folder_text);
|
||||
final CheckBox checkBox = (CheckBox) view.findViewById(R.id.clear_local_folder_all);
|
||||
|
||||
// There has to be a cheaper way to get at the localFolder object than this
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
if (account == null || folderName == null || !account.isAvailable(FolderList.this)) {
|
||||
Log.i(K9.LOG_TAG, "not clear folder of unavailable account");
|
||||
Log.i(K9.LOG_TAG, "Not clearing folder of unavailable account");
|
||||
return;
|
||||
}
|
||||
localFolder = account.getLocalStore().getFolder(folderName);
|
||||
localFolder.open(Folder.OpenMode.READ_WRITE);
|
||||
localFolder.clearAllMessages();
|
||||
if (localFolder.isLocalOnly()) {
|
||||
checkBox.setChecked(true);
|
||||
checkBox.setVisibility(View.GONE);
|
||||
text.setVisibility(View.GONE);
|
||||
} else {
|
||||
textLocal.setVisibility(View.GONE);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(K9.LOG_TAG, "Exception while clearing folder", e);
|
||||
} finally {
|
||||
if (localFolder != null) {
|
||||
localFolder.close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
final LocalFolder localFolderFinal = localFolder;
|
||||
|
||||
onRefresh(!REFRESH_REMOTE);
|
||||
dialog.setView(view);
|
||||
dialog.setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
try {
|
||||
localFolderFinal.clearAllMessages(checkBox.isChecked());
|
||||
} catch (MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "Exception while clearing folder", e);
|
||||
} finally {
|
||||
if (localFolderFinal != null) {
|
||||
localFolderFinal.close();
|
||||
}
|
||||
onRefresh(!REFRESH_REMOTE);
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
if (localFolderFinal != null) {
|
||||
localFolderFinal.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void sendMail(Account account) {
|
||||
MessagingController.getInstance(getApplication()).sendPendingMessages(account, mAdapter.mListener);
|
||||
}
|
||||
@ -759,7 +800,17 @@ public class FolderList extends K9ListActivity {
|
||||
String folderName = input.getText().toString().trim();
|
||||
try {
|
||||
Store store = mAccount.getRemoteStore();
|
||||
if (store instanceof ImapStore) {
|
||||
boolean isLocalOnly = ((LocalFolder)folder.folder).isLocalOnly();
|
||||
if (store instanceof Pop3Store || isLocalOnly) {
|
||||
boolean result = mAccount.getLocalStore().renameFolder(folder.name, folderName);
|
||||
if (result && mAccount.isSpecialFolder(folder.name)) {
|
||||
resetSpecialFolders(folder.name, folderName);
|
||||
}
|
||||
String toastText = "Renaming folder \"" + folder.name + "\" to \"" + folderName +
|
||||
((result) ? "\" succeeded." : "\" failed.");
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
onRefresh(false);
|
||||
} else if (store instanceof ImapStore) {
|
||||
boolean result = false;
|
||||
if (((ImapStore)store).renameFolder(folder.name, folderName)) {
|
||||
result = mAccount.getLocalStore().renameFolder(folder.name, folderName);
|
||||
@ -779,28 +830,17 @@ public class FolderList extends K9ListActivity {
|
||||
} else if (store instanceof WebDavStore) {
|
||||
String toastText = "Deleting WebDav Folders not currently implemented.";
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
} else if (store instanceof Pop3Store) {
|
||||
boolean result = mAccount.getLocalStore().renameFolder(folder.name, folderName);
|
||||
if (result && mAccount.isSpecialFolder(folder.name)) {
|
||||
resetSpecialFolders(folder.name, folderName);
|
||||
}
|
||||
String toastText = "Renaming folder \"" + folder.name + "\" to \"" + folderName +
|
||||
((result) ? "\" succeeded." : "\" failed.");
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
onRefresh(false);
|
||||
} else {
|
||||
Log.d(K9.LOG_TAG, "Unhandled store type " + store.getClass());
|
||||
}
|
||||
} catch (com.fsck.k9.mail.MessagingException me) {
|
||||
Log.e(K9.LOG_TAG, "MessagingException trying to deletefolder \"" +
|
||||
Log.e(K9.LOG_TAG, "MessagingException trying to rename folder \"" +
|
||||
folder.name + "\": " + me);
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
/* User clicked cancel so do some stuff */
|
||||
}
|
||||
public void onClick(DialogInterface dialog, int whichButton) {}
|
||||
});
|
||||
dialog.show();
|
||||
|
||||
@ -819,7 +859,17 @@ public class FolderList extends K9ListActivity {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
try {
|
||||
Store store = mAccount.getRemoteStore();
|
||||
if (store instanceof ImapStore) {
|
||||
boolean isLocalOnly = ((LocalFolder)folder.folder).isLocalOnly();
|
||||
if (store instanceof Pop3Store || isLocalOnly) {
|
||||
boolean result = mAccount.getLocalStore().delete(folder.name);
|
||||
if (result && mAccount.isSpecialFolder(folder.name)) {
|
||||
resetSpecialFolders(folder.name, K9.FOLDER_NONE);
|
||||
}
|
||||
String toastText = "Deletion of folder \"" + folder.name +
|
||||
((result) ? "\" succeeded." : "\" failed.");
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
onRefresh(false);
|
||||
} else if (store instanceof ImapStore) {
|
||||
boolean result = ((ImapStore)store).delete(folder.name);
|
||||
if (result) {
|
||||
mAccount.getLocalStore().delete(folder.name);
|
||||
@ -834,28 +884,17 @@ public class FolderList extends K9ListActivity {
|
||||
} else if (store instanceof WebDavStore) {
|
||||
String toastText = "Deleting WebDav Folders not currently implemented.";
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
} else if (store instanceof Pop3Store) {
|
||||
boolean result = mAccount.getLocalStore().delete(folder.name);
|
||||
if (result && mAccount.isSpecialFolder(folder.name)) {
|
||||
resetSpecialFolders(folder.name, K9.FOLDER_NONE);
|
||||
}
|
||||
String toastText = "Deletion of folder \"" + folder.name +
|
||||
((result) ? "\" succeeded." : "\" failed.");
|
||||
Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG).show();
|
||||
onRefresh(false);
|
||||
} else {
|
||||
Log.d(K9.LOG_TAG, "Unhandled store type " + store.getClass());
|
||||
}
|
||||
} catch (com.fsck.k9.mail.MessagingException me) {
|
||||
Log.e(K9.LOG_TAG, "MessagingException trying to deletefolder \"" +
|
||||
Log.e(K9.LOG_TAG, "MessagingException trying to delete folder \"" +
|
||||
folder.name + "\": " + me);
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
/* User clicked cancel so do some stuff */
|
||||
}
|
||||
public void onClick(DialogInterface dialog, int whichButton) {}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
@ -921,18 +960,28 @@ public class FolderList extends K9ListActivity {
|
||||
getMenuInflater().inflate(R.menu.folder_context, menu);
|
||||
|
||||
FolderInfoHolder folder = (FolderInfoHolder) mAdapter.getItem(info.position);
|
||||
boolean isLocalOnly = ((LocalFolder)folder.folder).isLocalOnly();
|
||||
boolean isExpungeCapable = false;
|
||||
try {
|
||||
isExpungeCapable = mAccount.getRemoteStore().isExpungeCapable();
|
||||
} catch (com.fsck.k9.mail.MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "MessagingException trying to get remote store " + e);
|
||||
}
|
||||
|
||||
menu.setHeaderTitle(folder.displayName);
|
||||
|
||||
if (!folder.name.equals(mAccount.getTrashFolderName()))
|
||||
if (!folder.name.equals(mAccount.getTrashFolderName())) {
|
||||
menu.findItem(R.id.empty_trash).setVisible(false);
|
||||
|
||||
}
|
||||
if (folder.name.equals(mAccount.getOutboxFolderName())) {
|
||||
menu.findItem(R.id.check_mail).setVisible(false);
|
||||
} else {
|
||||
menu.findItem(R.id.send_messages).setVisible(false);
|
||||
}
|
||||
if (K9.ERROR_FOLDER_NAME.equals(folder.name)) {
|
||||
if (isLocalOnly) {
|
||||
menu.findItem(R.id.check_mail).setVisible(false);
|
||||
}
|
||||
if (K9.ERROR_FOLDER_NAME.equals(folder.name) || isLocalOnly || !isExpungeCapable) {
|
||||
menu.findItem(R.id.expunge).setVisible(false);
|
||||
}
|
||||
|
||||
@ -946,6 +995,11 @@ public class FolderList extends K9ListActivity {
|
||||
menu.findItem(R.id.rename_folder).setVisible(false);
|
||||
menu.findItem(R.id.delete_folder).setVisible(false);
|
||||
}
|
||||
if (mAccount.getStoreUri().startsWith("webdav")) {
|
||||
menu.findItem(R.id.create_folder).setVisible(false);
|
||||
menu.findItem(R.id.rename_folder).setVisible(false);
|
||||
menu.findItem(R.id.delete_folder).setVisible(false);
|
||||
}
|
||||
|
||||
menu.setHeaderTitle(folder.displayName);
|
||||
}
|
||||
|
@ -245,11 +245,11 @@ public class MessageList
|
||||
private boolean mTouchView = true;
|
||||
private int mPreviewLines = 0;
|
||||
|
||||
|
||||
private MessageListAdapter mAdapter;
|
||||
private View mFooterView;
|
||||
|
||||
private FolderInfoHolder mCurrentFolder;
|
||||
private boolean mLocalOnly = false;
|
||||
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
@ -729,8 +729,26 @@ public class MessageList
|
||||
mCurrentFolder = mAdapter.getFolder(mFolderName, mAccount);
|
||||
}
|
||||
|
||||
// Hide "Load up to x more" footer for search views
|
||||
mFooterView.setVisibility((mQueryString != null) ? View.GONE : View.VISIBLE);
|
||||
// ASH this seems wrong, but it works for now.
|
||||
if (mCurrentFolder != null) {
|
||||
LocalFolder folder = (LocalFolder)mCurrentFolder.folder;
|
||||
if (folder != null) {
|
||||
try {
|
||||
folder.open(Folder.OpenMode.READ_ONLY);
|
||||
mLocalOnly = folder.isLocalOnly();
|
||||
} catch(com.fsck.k9.mail.MessagingException e) {
|
||||
Log.e("ASH", "ack! " + e);
|
||||
}
|
||||
}
|
||||
Log.d("ASH", "mLocalOnly = " + mLocalOnly + " for " + mCurrentFolder.name);
|
||||
} else {
|
||||
// should mLocalOnly be true or false or ???
|
||||
// if true, it hides "Load up to x more", but this should be hidden anyway.
|
||||
// it also hides R.id.check_mail and R.id.expunge
|
||||
}
|
||||
|
||||
// Hide "Load up to x more" footer for search views and local-only folders
|
||||
mFooterView.setVisibility((mQueryString != null || mLocalOnly) ? View.GONE : View.VISIBLE);
|
||||
|
||||
mController = MessagingController.getInstance(getApplication());
|
||||
mListView.setAdapter(mAdapter);
|
||||
@ -1527,6 +1545,10 @@ public class MessageList
|
||||
onMove(selection);
|
||||
return true;
|
||||
}
|
||||
case R.id.batch_upload_op: {
|
||||
onUpload(selection);
|
||||
return true;
|
||||
}
|
||||
case R.id.expunge: {
|
||||
if (mCurrentFolder != null) {
|
||||
onExpunge(mAccount, mCurrentFolder.name);
|
||||
@ -1569,18 +1591,28 @@ public class MessageList
|
||||
menu.findItem(R.id.batch_spam_op).setVisible(false);
|
||||
menu.findItem(R.id.batch_move_op).setVisible(false);
|
||||
menu.findItem(R.id.batch_copy_op).setVisible(false);
|
||||
menu.findItem(R.id.batch_upload_op).setVisible(false);
|
||||
menu.findItem(R.id.check_mail).setVisible(false);
|
||||
menu.findItem(R.id.send_messages).setVisible(false);
|
||||
menu.findItem(R.id.folder_settings).setVisible(false);
|
||||
menu.findItem(R.id.account_settings).setVisible(false);
|
||||
} else {
|
||||
boolean isExpungeCapable = false;
|
||||
try {
|
||||
isExpungeCapable = mAccount.getRemoteStore().isExpungeCapable();
|
||||
} catch (com.fsck.k9.mail.MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "MessagingException trying to get remote store " + e);
|
||||
}
|
||||
if (mCurrentFolder != null && mCurrentFolder.name.equals(mAccount.getOutboxFolderName())) {
|
||||
menu.findItem(R.id.check_mail).setVisible(false);
|
||||
} else {
|
||||
menu.findItem(R.id.send_messages).setVisible(false);
|
||||
}
|
||||
|
||||
if (mCurrentFolder != null && K9.ERROR_FOLDER_NAME.equals(mCurrentFolder.name)) {
|
||||
if (mLocalOnly) {
|
||||
menu.findItem(R.id.check_mail).setEnabled(false);
|
||||
}
|
||||
if ((mCurrentFolder != null && K9.ERROR_FOLDER_NAME.equals(mCurrentFolder.name)) ||
|
||||
mLocalOnly || !isExpungeCapable) {
|
||||
menu.findItem(R.id.expunge).setVisible(false);
|
||||
}
|
||||
if (K9.FOLDER_NONE.equalsIgnoreCase(mAccount.getArchiveFolderName())) {
|
||||
@ -1589,6 +1621,14 @@ public class MessageList
|
||||
if (K9.FOLDER_NONE.equalsIgnoreCase(mAccount.getSpamFolderName())) {
|
||||
menu.findItem(R.id.batch_spam_op).setVisible(false);
|
||||
}
|
||||
try {
|
||||
if (((com.fsck.k9.mail.store.LocalStore.LocalFolder)mCurrentFolder.folder).isLocalOnly() ||
|
||||
!mAccount.getRemoteStore().isAppendCapable()) {
|
||||
menu.findItem(R.id.batch_upload_op).setVisible(false);
|
||||
}
|
||||
} catch (com.fsck.k9.mail.MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "Error trying to get remote store: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
boolean newFlagState = computeBatchDirection(true);
|
||||
@ -1677,6 +1717,10 @@ public class MessageList
|
||||
onCopy(selection);
|
||||
break;
|
||||
}
|
||||
case R.id.upload: {
|
||||
onUpload(selection);
|
||||
break;
|
||||
}
|
||||
case R.id.send_alternate: {
|
||||
onSendAlternate(mAccount, holder);
|
||||
break;
|
||||
@ -1776,6 +1820,16 @@ public class MessageList
|
||||
menu.findItem(R.id.spam).setVisible(false);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!message.uid.startsWith(K9.LOCAL_UID_PREFIX) || mQueryString != null ||
|
||||
((com.fsck.k9.mail.store.LocalStore.LocalFolder)message.message.getFolder()).isLocalOnly() ||
|
||||
!account.getRemoteStore().isAppendCapable()) {
|
||||
menu.findItem(R.id.upload).setVisible(false);
|
||||
}
|
||||
} catch (com.fsck.k9.mail.MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "Error trying to get remote store: " + e);
|
||||
}
|
||||
|
||||
if (message.selected) {
|
||||
menu.findItem(R.id.select).setVisible(false);
|
||||
menu.findItem(R.id.deselect).setVisible(true);
|
||||
@ -2262,6 +2316,10 @@ public class MessageList
|
||||
holder.chip.setBackgroundDrawable(message.message.getFolder().getAccount().generateColorChip().drawable());
|
||||
holder.chip.getBackground().setAlpha(message.read ? 127 : 255);
|
||||
view.getBackground().setAlpha(message.downloaded ? 0 : 127);
|
||||
if (message.uid.startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||
view.setBackgroundColor(message.message.getFolder().getAccount().getChipColor());
|
||||
view.getBackground().setAlpha(31);
|
||||
}
|
||||
|
||||
if ((message.message.getSubject() == null) || message.message.getSubject().equals("")) {
|
||||
holder.subject.setText(getText(R.string.general_no_subject));
|
||||
@ -2662,6 +2720,31 @@ public class MessageList
|
||||
displayFolderChoice(ACTIVITY_CHOOSE_FOLDER_COPY, folder, holders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append messages to server.
|
||||
*
|
||||
* @param holders
|
||||
* Never {@code null}.
|
||||
*/
|
||||
private void onUpload(final List<MessageInfoHolder> holders) {
|
||||
if (holders.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
boolean isAppendCapable = false;
|
||||
try {
|
||||
isAppendCapable = mAccount.getRemoteStore().isAppendCapable();
|
||||
} catch (com.fsck.k9.mail.MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "Error trying to get remote store: " + e);
|
||||
}
|
||||
for (MessageInfoHolder holder : holders) {
|
||||
if (holder.uid.startsWith(K9.LOCAL_UID_PREFIX) && !((LocalFolder)holder.folder.folder).isLocalOnly() && isAppendCapable) {
|
||||
mController.saveMessage(mAccount, holder.message, holder.folder.name);
|
||||
} else {
|
||||
Log.d("ASH", "cannot sync " + holder.folder.name + " " + holder.uid + " " + holder.message.getSubject());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to manage the invocation of
|
||||
* {@link #startActivityForResult(Intent, int)} for a folder operation
|
||||
|
@ -752,6 +752,19 @@ public class MessageView extends K9Activity implements OnClickListener {
|
||||
startActivityForResult(intent, activity);
|
||||
}
|
||||
|
||||
private void onUpload() {
|
||||
boolean isAppendCapable = false;
|
||||
try {
|
||||
isAppendCapable = mAccount.getRemoteStore().isAppendCapable();
|
||||
} catch (com.fsck.k9.mail.MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "Error trying to get remote store: " + e);
|
||||
}
|
||||
if (mMessageReference.uid.startsWith(K9.LOCAL_UID_PREFIX) && !((com.fsck.k9.mail.store.LocalStore.LocalFolder)mMessage.getFolder()).isLocalOnly() && isAppendCapable) {
|
||||
mController.saveMessage(mAccount, mMessage, mMessageReference.folderName);
|
||||
} else {
|
||||
Log.d("ASH", "cannot sync " + mMessageReference.folderName + " " + mMessageReference.uid + " " + mMessage.getSubject());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
@ -965,6 +978,9 @@ public class MessageView extends K9Activity implements OnClickListener {
|
||||
case R.id.copy:
|
||||
onCopy();
|
||||
break;
|
||||
case R.id.upload:
|
||||
onUpload();
|
||||
break;
|
||||
case R.id.show_full_header:
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
@ -993,6 +1009,15 @@ public class MessageView extends K9Activity implements OnClickListener {
|
||||
if (K9.FOLDER_NONE.equalsIgnoreCase(mAccount.getSpamFolderName())) {
|
||||
menu.findItem(R.id.spam).setVisible(false);
|
||||
}
|
||||
try {
|
||||
if (!mMessage.getUid().startsWith(K9.LOCAL_UID_PREFIX) ||
|
||||
((com.fsck.k9.mail.store.LocalStore.LocalFolder)mMessage.getFolder()).isLocalOnly() ||
|
||||
!mAccount.getRemoteStore().isAppendCapable()) {
|
||||
menu.findItem(R.id.upload).setVisible(false);
|
||||
}
|
||||
} catch (com.fsck.k9.mail.MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "Error trying to get remote store: " + e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1057,6 +1082,8 @@ public class MessageView extends K9Activity implements OnClickListener {
|
||||
}
|
||||
|
||||
public void displayMessageBody(final Account account, final String folder, final String uid, final Message message) {
|
||||
Log.d("ASH", MessageView.this.mMessage.isSet(Flag.X_DOWNLOADED_PARTIAL) + " " + MessageView.this.mMessage.isSet(Flag.X_DOWNLOADED_FULL));
|
||||
Log.d("ASH", message.isSet(Flag.X_DOWNLOADED_PARTIAL) + " " + message.isSet(Flag.X_DOWNLOADED_FULL));
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
mTopView.scrollTo(0, 0);
|
||||
|
@ -86,6 +86,7 @@ public class AccountSettings extends K9PreferenceActivity {
|
||||
private static final String PREFERENCE_MESSAGE_AGE = "account_message_age";
|
||||
private static final String PREFERENCE_MESSAGE_SIZE = "account_autodownload_size";
|
||||
private static final String PREFERENCE_SAVE_ALL_HEADERS = "account_save_all_headers";
|
||||
private static final String PREFERENCE_AUTO_UPLOAD_ON_MOVE = "account_auto_upload_on_move";
|
||||
private static final String PREFERENCE_MESSAGE_FORMAT = "message_format";
|
||||
private static final String PREFERENCE_MESSAGE_READ_RECEIPT = "message_read_receipt";
|
||||
private static final String PREFERENCE_QUOTE_PREFIX = "account_quote_prefix";
|
||||
@ -112,6 +113,7 @@ public class AccountSettings extends K9PreferenceActivity {
|
||||
private Account mAccount;
|
||||
private boolean mIsPushCapable = false;
|
||||
private boolean mIsExpungeCapable = false;
|
||||
private boolean mIsAppendCapable = false;
|
||||
|
||||
private PreferenceScreen mComposingScreen;
|
||||
|
||||
@ -155,6 +157,7 @@ public class AccountSettings extends K9PreferenceActivity {
|
||||
private CheckBoxPreference mStripSignature;
|
||||
private CheckBoxPreference mSyncRemoteDeletions;
|
||||
private CheckBoxPreference mSaveAllHeaders;
|
||||
private CheckBoxPreference mAutoUploadOnMove;
|
||||
private CheckBoxPreference mPushPollOnConnect;
|
||||
private ListPreference mIdleRefreshPeriod;
|
||||
private ListPreference mMaxPushFolders;
|
||||
@ -189,6 +192,7 @@ public class AccountSettings extends K9PreferenceActivity {
|
||||
final Store store = mAccount.getRemoteStore();
|
||||
mIsPushCapable = store.isPushCapable();
|
||||
mIsExpungeCapable = store.isExpungeCapable();
|
||||
mIsAppendCapable = store.isAppendCapable();
|
||||
} catch (Exception e) {
|
||||
Log.e(K9.LOG_TAG, "Could not get remote store", e);
|
||||
}
|
||||
@ -362,6 +366,13 @@ public class AccountSettings extends K9PreferenceActivity {
|
||||
mSaveAllHeaders = (CheckBoxPreference) findPreference(PREFERENCE_SAVE_ALL_HEADERS);
|
||||
mSaveAllHeaders.setChecked(mAccount.saveAllHeaders());
|
||||
|
||||
mAutoUploadOnMove = (CheckBoxPreference) findPreference(PREFERENCE_AUTO_UPLOAD_ON_MOVE);
|
||||
mAutoUploadOnMove.setChecked(mAccount.isAutoUploadOnMove() && mIsAppendCapable);
|
||||
if (!mIsAppendCapable || !K9.isShowAdvancedOptions()) {
|
||||
((PreferenceScreen) findPreference(PREFERENCE_SCREEN_INCOMING)).
|
||||
removePreference(mAutoUploadOnMove);
|
||||
}
|
||||
|
||||
mSearchableFolders = (ListPreference) findPreference(PREFERENCE_SEARCHABLE_FOLDERS);
|
||||
mSearchableFolders.setValue(mAccount.getSearchableFolders().name());
|
||||
mSearchableFolders.setSummary(mSearchableFolders.getEntry());
|
||||
@ -721,6 +732,7 @@ public class AccountSettings extends K9PreferenceActivity {
|
||||
}
|
||||
mAccount.setSyncRemoteDeletions(mSyncRemoteDeletions.isChecked());
|
||||
mAccount.setSaveAllHeaders(mSaveAllHeaders.isChecked());
|
||||
mAccount.setAutoUploadOnMove(mAutoUploadOnMove.isChecked());
|
||||
mAccount.setSearchableFolders(Account.Searchable.valueOf(mSearchableFolders.getValue()));
|
||||
mAccount.setMessageFormat(Account.MessageFormat.valueOf(mMessageFormat.getValue()));
|
||||
mAccount.setMessageReadReceipt(mMessageReadReceipt.isChecked());
|
||||
|
@ -7,15 +7,19 @@ import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.util.Log;
|
||||
import com.fsck.k9.*;
|
||||
import com.fsck.k9.activity.K9PreferenceActivity;
|
||||
import com.fsck.k9.controller.MessagingController;
|
||||
import com.fsck.k9.mail.Folder;
|
||||
import com.fsck.k9.mail.Folder.FolderClass;
|
||||
import com.fsck.k9.mail.Folder.OpenMode;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.Store;
|
||||
import com.fsck.k9.mail.store.LocalStore;
|
||||
import com.fsck.k9.mail.store.LocalStore.LocalFolder;
|
||||
import com.fsck.k9.mail.store.Pop3Store;
|
||||
import com.fsck.k9.service.MailService;
|
||||
|
||||
public class FolderSettings extends K9PreferenceActivity {
|
||||
@ -29,11 +33,14 @@ public class FolderSettings extends K9PreferenceActivity {
|
||||
private static final String PREFERENCE_PUSH_CLASS = "folder_settings_folder_push_mode";
|
||||
private static final String PREFERENCE_IN_TOP_GROUP = "folder_settings_in_top_group";
|
||||
private static final String PREFERENCE_INTEGRATE = "folder_settings_include_in_integrated_inbox";
|
||||
private static final String PREFERENCE_LOCAL_ONLY = "folder_settings_local_only";
|
||||
|
||||
private Account mAccount;
|
||||
private LocalFolder mFolder;
|
||||
|
||||
private CheckBoxPreference mInTopGroup;
|
||||
private CheckBoxPreference mIntegrate;
|
||||
private CheckBoxPreference mLocalOnly;
|
||||
private ListPreference mDisplayClass;
|
||||
private ListPreference mSyncClass;
|
||||
private ListPreference mPushClass;
|
||||
@ -51,7 +58,7 @@ public class FolderSettings extends K9PreferenceActivity {
|
||||
|
||||
String folderName = (String)getIntent().getSerializableExtra(EXTRA_FOLDER_NAME);
|
||||
String accountUuid = getIntent().getStringExtra(EXTRA_ACCOUNT);
|
||||
Account mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
|
||||
mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
|
||||
|
||||
try {
|
||||
LocalStore localStore = mAccount.getLocalStore();
|
||||
@ -73,7 +80,7 @@ public class FolderSettings extends K9PreferenceActivity {
|
||||
|
||||
addPreferencesFromResource(R.xml.folder_settings_preferences);
|
||||
|
||||
Preference category = findPreference(PREFERENCE_TOP_CATERGORY);
|
||||
PreferenceCategory category = (PreferenceCategory)findPreference(PREFERENCE_TOP_CATERGORY);
|
||||
category.setTitle(folderName);
|
||||
|
||||
|
||||
@ -81,6 +88,8 @@ public class FolderSettings extends K9PreferenceActivity {
|
||||
mInTopGroup.setChecked(mFolder.isInTopGroup());
|
||||
mIntegrate = (CheckBoxPreference)findPreference(PREFERENCE_INTEGRATE);
|
||||
mIntegrate.setChecked(mFolder.isIntegrate());
|
||||
mLocalOnly = (CheckBoxPreference)findPreference(PREFERENCE_LOCAL_ONLY);
|
||||
mLocalOnly.setChecked(mFolder.isLocalOnly());
|
||||
|
||||
mDisplayClass = (ListPreference) findPreference(PREFERENCE_DISPLAY_CLASS);
|
||||
mDisplayClass.setValue(mFolder.getDisplayClass().name());
|
||||
@ -96,6 +105,7 @@ public class FolderSettings extends K9PreferenceActivity {
|
||||
});
|
||||
|
||||
mSyncClass = (ListPreference) findPreference(PREFERENCE_SYNC_CLASS);
|
||||
mSyncClass.setEnabled(!mLocalOnly.isChecked());
|
||||
mSyncClass.setValue(mFolder.getRawSyncClass().name());
|
||||
mSyncClass.setSummary(mSyncClass.getEntry());
|
||||
mSyncClass.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@ -107,9 +117,12 @@ public class FolderSettings extends K9PreferenceActivity {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (store instanceof Pop3Store) {
|
||||
category.removePreference(mSyncClass);
|
||||
}
|
||||
|
||||
mPushClass = (ListPreference) findPreference(PREFERENCE_PUSH_CLASS);
|
||||
mPushClass.setEnabled(isPushCapable);
|
||||
mPushClass.setEnabled(isPushCapable && !mLocalOnly.isChecked());
|
||||
mPushClass.setValue(mFolder.getRawPushClass().name());
|
||||
mPushClass.setSummary(mPushClass.getEntry());
|
||||
mPushClass.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@ -121,20 +134,55 @@ public class FolderSettings extends K9PreferenceActivity {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (store instanceof Pop3Store) {
|
||||
category.removePreference(mPushClass);
|
||||
}
|
||||
|
||||
mLocalOnly = (CheckBoxPreference)findPreference(PREFERENCE_LOCAL_ONLY);
|
||||
mLocalOnly.setChecked(mFolder.isLocalOnly());
|
||||
if (store instanceof Pop3Store || mAccount.getInboxFolderName().equals(folderName) ||
|
||||
mAccount.getOutboxFolderName().equals(folderName)) {
|
||||
mLocalOnly.setEnabled(false);
|
||||
}
|
||||
if (!K9.isShowAdvancedOptions()) {// ASH disabled for testing: || store instanceof Pop3Store) {
|
||||
category.removePreference(mLocalOnly);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void saveSettings() throws MessagingException {
|
||||
mFolder.setInTopGroup(mInTopGroup.isChecked());
|
||||
mFolder.setIntegrate(mIntegrate.isChecked());
|
||||
boolean oldIsLocalOnly = mFolder.isLocalOnly();
|
||||
mFolder.setLocalOnly(mLocalOnly.isChecked());
|
||||
// We call getPushClass() because display class changes can affect push class when push class is set to inherit
|
||||
FolderClass oldPushClass = mFolder.getPushClass();
|
||||
FolderClass oldDisplayClass = mFolder.getDisplayClass();
|
||||
mFolder.setDisplayClass(FolderClass.valueOf(mDisplayClass.getValue()));
|
||||
mFolder.setSyncClass(FolderClass.valueOf(mSyncClass.getValue()));
|
||||
mFolder.setPushClass(FolderClass.valueOf(mPushClass.getValue()));
|
||||
if (mLocalOnly.isChecked()) {
|
||||
mFolder.setSyncClass(FolderClass.NO_CLASS);
|
||||
mFolder.setPushClass(FolderClass.NO_CLASS);
|
||||
} else {
|
||||
mFolder.setSyncClass(FolderClass.valueOf(mSyncClass.getValue()));
|
||||
mFolder.setPushClass(FolderClass.valueOf(mPushClass.getValue()));
|
||||
}
|
||||
|
||||
mFolder.save();
|
||||
|
||||
if (!oldIsLocalOnly && mFolder.isLocalOnly()) {
|
||||
Log.w(K9.LOG_TAG, "Changing UIDs of messages in folder " + mFolder.getName() +
|
||||
" to local UIDs.");
|
||||
MessagingController.getInstance(getApplication()).localizeUids(mFolder);
|
||||
} else if (oldIsLocalOnly && !mFolder.isLocalOnly()) {
|
||||
// create folder if it does not exist.
|
||||
Folder folder = mAccount.getRemoteStore().getFolder(mFolder.getName());
|
||||
folder.close();
|
||||
if (!folder.exists()) {
|
||||
Log.w(K9.LOG_TAG, "creating remote folder " + mFolder.getName());
|
||||
folder.create();
|
||||
}
|
||||
}
|
||||
|
||||
FolderClass newPushClass = mFolder.getPushClass();
|
||||
FolderClass newDisplayClass = mFolder.getDisplayClass();
|
||||
|
||||
|
@ -67,6 +67,7 @@ public class Prefs extends K9PreferenceActivity {
|
||||
private static final String PREFERENCE_MESSAGELIST_CONTACT_NAME_COLOR = "messagelist_contact_name_color";
|
||||
private static final String PREFERENCE_MESSAGEVIEW_FIXEDWIDTH = "messageview_fixedwidth_font";
|
||||
private static final String PREFERENCE_COMPACT_LAYOUTS = "compact_layouts";
|
||||
private static final String PREFERENCE_SHOW_ADVANCED_OPTIONS = "show_advanced_options";
|
||||
|
||||
private static final String PREFERENCE_MESSAGEVIEW_RETURN_TO_LIST = "messageview_return_to_list";
|
||||
private static final String PREFERENCE_MESSAGEVIEW_SHOW_NEXT = "messageview_show_next";
|
||||
@ -115,6 +116,7 @@ public class Prefs extends K9PreferenceActivity {
|
||||
private CheckBoxPreference mDebugLogging;
|
||||
private CheckBoxPreference mSensitiveLogging;
|
||||
private CheckBoxPreference compactLayouts;
|
||||
private CheckBoxPreference showAdvancedOptions;
|
||||
|
||||
private CheckBoxPreference mQuietTimeEnabled;
|
||||
private com.fsck.k9.preferences.TimePickerPreference mQuietTimeStarts;
|
||||
@ -179,6 +181,9 @@ public class Prefs extends K9PreferenceActivity {
|
||||
compactLayouts = (CheckBoxPreference)findPreference(PREFERENCE_COMPACT_LAYOUTS);
|
||||
compactLayouts.setChecked(K9.useCompactLayouts());
|
||||
|
||||
showAdvancedOptions = (CheckBoxPreference)findPreference(PREFERENCE_SHOW_ADVANCED_OPTIONS);
|
||||
showAdvancedOptions.setChecked(K9.isShowAdvancedOptions());
|
||||
|
||||
mVolumeNavigation = (CheckBoxListPreference)findPreference(PREFERENCE_VOLUME_NAVIGATION);
|
||||
mVolumeNavigation.setItems(new CharSequence[] {getString(R.string.volume_navigation_message), getString(R.string.volume_navigation_list)});
|
||||
mVolumeNavigation.setCheckedItems(new boolean[] {K9.useVolumeKeysForNavigationEnabled(), K9.useVolumeKeysForListNavigationEnabled()});
|
||||
@ -352,6 +357,7 @@ public class Prefs extends K9PreferenceActivity {
|
||||
K9.setAnimations(mAnimations.isChecked());
|
||||
K9.setGesturesEnabled(mGestures.isChecked());
|
||||
K9.setCompactLayouts(compactLayouts.isChecked());
|
||||
K9.setShowAdvancedOptions(showAdvancedOptions.isChecked());
|
||||
K9.setUseVolumeKeysForNavigation(mVolumeNavigation.getCheckedItems()[0]);
|
||||
K9.setUseVolumeKeysForListNavigation(mVolumeNavigation.getCheckedItems()[1]);
|
||||
K9.setManageBack(mManageBack.isChecked());
|
||||
|
@ -27,6 +27,7 @@ import android.os.PowerManager;
|
||||
import android.os.Process;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.AccountStats;
|
||||
@ -476,20 +477,28 @@ public class MessagingController implements Runnable {
|
||||
localFolders = localStore.getPersonalNamespaces(false);
|
||||
|
||||
/*
|
||||
* Clear out any folders that are no longer on the remote store,
|
||||
* unless they are tagged as local-only or are special folders.
|
||||
* Clear out any folders that are no longer on the remote store, unless they
|
||||
* are tagged as local-only or are special folders. If a folder contains
|
||||
* messages with UIDs starting with K9.LOCAL_UID_PREFIX, then those messages
|
||||
* are saved and the folder is converted to local-only.
|
||||
*/
|
||||
// ASH todo: also don't clear out folders with K9.LOCAL_UID_PREFIX
|
||||
for (LocalFolder localFolder : localFolders) {
|
||||
String localFolderName = localFolder.getName();
|
||||
if (!account.isSpecialFolder(localFolderName) &&
|
||||
!remoteFolderNames.contains(localFolderName) &&
|
||||
!localFolder.isLocalOnly()) {
|
||||
localFolder.delete(false);
|
||||
for (Message message : localFolder.getMessages(null)) {
|
||||
if (message.getUid().startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||
localFolder.clearAllMessages(false);
|
||||
localFolder.setLocalOnly(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!localFolder.isLocalOnly()) {
|
||||
localFolder.delete(false);
|
||||
}
|
||||
}
|
||||
if (remoteFolderNames.contains(localFolderName)) {
|
||||
if (localFolder.isLocalOnly()) localFolder.setLocalOnly(false);
|
||||
} else if (localFolder.exists()) {
|
||||
if (!remoteFolderNames.contains(localFolderName) && localFolder.exists()) {
|
||||
if (!localFolder.isLocalOnly()) localFolder.setLocalOnly(true);
|
||||
}
|
||||
}
|
||||
@ -1016,8 +1025,9 @@ public class MessagingController implements Runnable {
|
||||
ArrayList<Message> missingMessages = new ArrayList<Message>();
|
||||
for (Message localMessage : localMessages) {
|
||||
String uid = localMessage.getUid();
|
||||
if (!uid.startsWith(K9.LOCAL_UID_PREFIX) && !remoteUidMap.containsKey(uid)) {
|
||||
// This message used to be on the server
|
||||
if ((!uid.startsWith(K9.LOCAL_UID_PREFIX) && !remoteUidMap.containsKey(uid)) ||
|
||||
(uid.startsWith(K9.LOCAL_UID_PREFIX) && localMessage.isSet(Flag.DELETED))) {
|
||||
// This message used to be on the server, or is local and should be expunged
|
||||
missingMessages.add(localMessage);
|
||||
}
|
||||
}
|
||||
@ -1988,6 +1998,12 @@ public class MessagingController implements Runnable {
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
localFolder = localStore.getFolder(folder);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
if (localFolder.isLocalOnly()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalMessage localMessage = (LocalMessage) localFolder.getMessage(uid);
|
||||
|
||||
if (localMessage == null) {
|
||||
@ -2101,15 +2117,26 @@ public class MessagingController implements Runnable {
|
||||
if (account.getErrorFolderName().equals(srcFolder)) {
|
||||
return;
|
||||
}
|
||||
final ArrayList<String> remoteUids = new ArrayList<String>();
|
||||
for (String uid : uids) {
|
||||
// ignore unsynced messages
|
||||
if (!uid.startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||
remoteUids.add(uid);
|
||||
}
|
||||
}
|
||||
if (remoteUids.size() == 0) {
|
||||
return;
|
||||
}
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_MOVE_OR_COPY_BULK;
|
||||
|
||||
int length = 3 + uids.length;
|
||||
int length = 3 + remoteUids.size();
|
||||
command.arguments = new String[length];
|
||||
command.arguments[0] = srcFolder;
|
||||
command.arguments[1] = destFolder;
|
||||
command.arguments[2] = Boolean.toString(isCopy);
|
||||
System.arraycopy(uids, 0, command.arguments, 3, uids.length);
|
||||
System.arraycopy(remoteUids.toArray(EMPTY_STRING_ARRAY), 0, command.arguments, 3,
|
||||
remoteUids.size());
|
||||
queuePendingCommand(account, command);
|
||||
}
|
||||
/**
|
||||
@ -2222,13 +2249,13 @@ public class MessagingController implements Runnable {
|
||||
remoteFolder = remoteStore.getFolder(folder);
|
||||
if (!remoteFolder.exists()) {
|
||||
if (!remoteFolder.create()) {
|
||||
// ASH log something?
|
||||
Log.w(K9.LOG_TAG, "updateUids: Cannot create remote folder " + folder);
|
||||
return;
|
||||
}
|
||||
}
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
if (remoteFolder.getMode() != OpenMode.READ_WRITE) {
|
||||
// ASH log something?
|
||||
Log.w(K9.LOG_TAG, "updateUids: Cannot open remote folder " + folder);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2247,12 +2274,12 @@ public class MessagingController implements Runnable {
|
||||
for (MessagingListener l : getListeners()) {
|
||||
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
||||
}
|
||||
} else {
|
||||
}/* else {
|
||||
Log.w(K9.LOG_TAG, "No remote message with message-id found, appending instead.");
|
||||
/*
|
||||
* If the message does not exist remotely we just upload it and then
|
||||
* update our local copy with the new uid.
|
||||
*/
|
||||
*//*
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
localFolder.fetch(new Message[] { localMessage } , fp, null);
|
||||
@ -2264,7 +2291,7 @@ public class MessagingController implements Runnable {
|
||||
for (MessagingListener l : getListeners()) {
|
||||
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
} finally {
|
||||
closeFolder(localFolder);
|
||||
@ -2272,19 +2299,47 @@ public class MessagingController implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
public void localizeUids(LocalFolder folder) throws MessagingException {
|
||||
Message[] messages = folder.getMessages(null);
|
||||
for (Message message : messages) {
|
||||
String oldUid = message.getUid();
|
||||
Log.d("ASH", "old UID = " + oldUid);
|
||||
if (!oldUid.startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||
String newUid = K9.LOCAL_UID_PREFIX + java.util.UUID.randomUUID().toString();
|
||||
Log.d("ASH", "new UID = " + newUid);
|
||||
message.setUid(newUid);
|
||||
folder.changeUid((LocalMessage)message);
|
||||
|
||||
for (MessagingListener l : getListeners()) {
|
||||
l.messageUidChanged(folder.getAccount(), folder.getName(), oldUid, newUid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void queueSetFlag(final Account account, final String folderName, final String newState, final String flag, final String[] uids) {
|
||||
final ArrayList<String> remoteUids = new ArrayList<String>();
|
||||
for (String uid : uids) {
|
||||
// ignore unsynced messages
|
||||
if (!uid.startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||
remoteUids.add(uid);
|
||||
}
|
||||
}
|
||||
if (remoteUids.size() == 0) {
|
||||
return;
|
||||
}
|
||||
putBackground("queueSetFlag " + account.getDescription() + ":" + folderName, null, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_SET_FLAG_BULK;
|
||||
int length = 3 + uids.length;
|
||||
int length = 3 + remoteUids.size();
|
||||
command.arguments = new String[length];
|
||||
command.arguments[0] = folderName;
|
||||
command.arguments[1] = newState;
|
||||
command.arguments[2] = flag;
|
||||
System.arraycopy(uids, 0, command.arguments, 3, uids.length);
|
||||
System.arraycopy(remoteUids.toArray(EMPTY_STRING_ARRAY), 0, command.arguments, 3,
|
||||
remoteUids.size());
|
||||
queuePendingCommand(account, command);
|
||||
processPendingCommands(account);
|
||||
}
|
||||
@ -2375,7 +2430,9 @@ public class MessagingController implements Runnable {
|
||||
closeFolder(remoteFolder);
|
||||
}
|
||||
}
|
||||
|
||||
private void queueExpunge(final Account account, final String folderName) {
|
||||
// ASH if folder.isLocalOnly() return ?
|
||||
putBackground("queueExpunge " + account.getDescription() + ":" + folderName, null, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -2390,6 +2447,7 @@ public class MessagingController implements Runnable {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void processPendingExpunge(PendingCommand command, Account account)
|
||||
throws MessagingException {
|
||||
String folder = command.arguments[0];
|
||||
@ -2445,6 +2503,10 @@ public class MessagingController implements Runnable {
|
||||
return;
|
||||
}
|
||||
|
||||
if (localFolder.isLocalOnly()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Store remoteStore = account.getRemoteStore();
|
||||
remoteFolder = remoteStore.getFolder(folder);
|
||||
|
||||
@ -2576,9 +2638,9 @@ public class MessagingController implements Runnable {
|
||||
final boolean newState) {
|
||||
// TODO: put this into the background, but right now that causes odd behavior
|
||||
// because the FolderMessageList doesn't have its own cache of the flag states
|
||||
Folder localFolder = null;
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
Store localStore = account.getLocalStore();
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
localFolder = localStore.getFolder(folderName);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
ArrayList<Message> messages = new ArrayList<Message>();
|
||||
@ -2606,6 +2668,10 @@ public class MessagingController implements Runnable {
|
||||
return;
|
||||
}
|
||||
|
||||
if (localFolder.isLocalOnly()) {
|
||||
return;
|
||||
}
|
||||
|
||||
queueSetFlag(account, folderName, Boolean.toString(newState), flag.toString(), uids);
|
||||
processPendingCommands(account);
|
||||
} catch (MessagingException me) {
|
||||
@ -2633,75 +2699,95 @@ public class MessagingController implements Runnable {
|
||||
put("loadMessageForViewRemote", listener, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Folder remoteFolder = null;
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
localFolder = localStore.getFolder(folder);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
Message message = localFolder.getMessage(uid);
|
||||
|
||||
if (message.isSet(Flag.X_DOWNLOADED_FULL)) {
|
||||
/*
|
||||
* If the message has been synchronized since we were called we'll
|
||||
* just hand it back cause it's ready to go.
|
||||
*/
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
localFolder.fetch(new Message[] { message }, fp, null);
|
||||
} else {
|
||||
/*
|
||||
* At this point the message is not available, so we need to download it
|
||||
* fully if possible.
|
||||
*/
|
||||
|
||||
Store remoteStore = account.getRemoteStore();
|
||||
remoteFolder = remoteStore.getFolder(folder);
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
// Get the remote message and fully download it
|
||||
Message remoteMessage = remoteFolder.getMessage(uid);
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
remoteFolder.fetch(new Message[] { remoteMessage }, fp, null);
|
||||
|
||||
// Store the message locally and load the stored message into memory
|
||||
localFolder.appendMessages(new Message[] { remoteMessage });
|
||||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
message = localFolder.getMessage(uid);
|
||||
localFolder.fetch(new Message[] { message }, fp, null);
|
||||
|
||||
// Mark that this message is now fully synched
|
||||
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||
}
|
||||
|
||||
// now that we have the full message, refresh the headers
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadMessageForViewHeadersAvailable(account, folder, uid, message);
|
||||
}
|
||||
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
||||
}
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadMessageForViewFinished(account, folder, uid, message);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadMessageForViewFailed(account, folder, uid, e);
|
||||
}
|
||||
addErrorMessage(account, null, e);
|
||||
|
||||
} finally {
|
||||
closeFolder(remoteFolder);
|
||||
closeFolder(localFolder);
|
||||
}
|
||||
}//run
|
||||
loadMessageForViewRemoteSynchronous(account, folder, uid, listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean loadMessageForViewRemoteSynchronous(final Account account, final String folder,
|
||||
final String uid, final MessagingListener listener) {
|
||||
Folder remoteFolder = null;
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
localFolder = localStore.getFolder(folder);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
Message message = localFolder.getMessage(uid);
|
||||
|
||||
if (uid.startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||
Log.w(K9.LOG_TAG, "Message has local UID so cannot download fully.");
|
||||
Toast.makeText(mApplication, "Message has local UID so cannot download fully",
|
||||
Toast.LENGTH_LONG).show();
|
||||
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||
message.setFlag(Flag.X_DOWNLOADED_PARTIAL, false);
|
||||
} else if (localFolder.isLocalOnly()) {
|
||||
Log.w(K9.LOG_TAG, "Message in local-only folder so cannot download fully.");
|
||||
Toast.makeText(mApplication, "Message in local-only folder so cannot download fully",
|
||||
Toast.LENGTH_LONG).show();
|
||||
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||
message.setFlag(Flag.X_DOWNLOADED_PARTIAL, false);
|
||||
}
|
||||
|
||||
if (message.isSet(Flag.X_DOWNLOADED_FULL)) {
|
||||
/*
|
||||
* If the message has been synchronized since we were called we'll
|
||||
* just hand it back cause it's ready to go.
|
||||
*/
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
localFolder.fetch(new Message[] { message }, fp, null);
|
||||
} else {
|
||||
/*
|
||||
* At this point the message is not available, so we need to download it
|
||||
* fully if possible.
|
||||
*/
|
||||
|
||||
Store remoteStore = account.getRemoteStore();
|
||||
remoteFolder = remoteStore.getFolder(folder);
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
// Get the remote message and fully download it
|
||||
Message remoteMessage = remoteFolder.getMessage(uid);
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
remoteFolder.fetch(new Message[] { remoteMessage }, fp, null);
|
||||
|
||||
// Store the message locally and load the stored message into memory
|
||||
localFolder.appendMessages(new Message[] { remoteMessage });
|
||||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
message = localFolder.getMessage(uid);
|
||||
localFolder.fetch(new Message[] { message }, fp, null);
|
||||
|
||||
// Mark that this message is now fully synched
|
||||
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||
}
|
||||
|
||||
// now that we have the full message, refresh the headers
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadMessageForViewHeadersAvailable(account, folder, uid, message);
|
||||
}
|
||||
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
||||
}
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadMessageForViewFinished(account, folder, uid, message);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
l.loadMessageForViewFailed(account, folder, uid, e);
|
||||
}
|
||||
addErrorMessage(account, null, e);
|
||||
return false;
|
||||
} finally {
|
||||
closeFolder(remoteFolder);
|
||||
closeFolder(localFolder);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadMessageForView(final Account account, final String folder, final String uid,
|
||||
final MessagingListener listener) {
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
@ -3105,11 +3191,13 @@ public class MessagingController implements Runnable {
|
||||
if (K9.DEBUG)
|
||||
Log.i(K9.LOG_TAG, "Moved sent message to folder '" + account.getSentFolderName() + "' (" + localSentFolder.getId() + ") ");
|
||||
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_APPEND;
|
||||
command.arguments = new String[] { localSentFolder.getName(), message.getUid() };
|
||||
queuePendingCommand(account, command);
|
||||
processPendingCommands(account);
|
||||
if (!localSentFolder.isLocalOnly()) {
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_APPEND;
|
||||
command.arguments = new String[] { localSentFolder.getName(), message.getUid() };
|
||||
queuePendingCommand(account, command);
|
||||
processPendingCommands(account);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
@ -3243,61 +3331,105 @@ public class MessagingController implements Runnable {
|
||||
Store remoteStore = account.getRemoteStore();
|
||||
LocalFolder localSrcFolder = localStore.getFolder(srcFolder);
|
||||
LocalFolder localDestFolder = localStore.getFolder(destFolder);
|
||||
|
||||
List<String> uids = new LinkedList<String>();
|
||||
List<String> localUids = new LinkedList<String>();
|
||||
|
||||
localSrcFolder.open(OpenMode.READ_WRITE);
|
||||
boolean needToLocalizeSourceFolder = false;
|
||||
|
||||
for (Message message : inMessages) {
|
||||
String uid = message.getUid();
|
||||
// ASH fixme: add all messages, and later handle local ones separately?
|
||||
if (!uid.startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||
// ASH instead, add all messages, and later handle local ones separately?
|
||||
if (!uid.startsWith(K9.LOCAL_UID_PREFIX) && !localSrcFolder.isLocalOnly()) {
|
||||
uids.add(uid);
|
||||
} else {
|
||||
localUids.add(uid);
|
||||
if (isCopy && !uid.startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||
needToLocalizeSourceFolder = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Message[] messages = localSrcFolder.getMessages(uids.toArray(EMPTY_STRING_ARRAY), null);
|
||||
if (messages.length > 0) {
|
||||
localDestFolder.open(OpenMode.READ_WRITE);
|
||||
boolean checkForPartialDownload = (!localSrcFolder.isLocalOnly() &&
|
||||
localDestFolder.isLocalOnly()) ? true : false;
|
||||
|
||||
Map<String, Message> origUidMap = new HashMap<String, Message>();
|
||||
|
||||
for (Message message : messages) {
|
||||
origUidMap.put(message.getUid(), message);
|
||||
}
|
||||
|
||||
if (K9.DEBUG) {
|
||||
Log.i(K9.LOG_TAG, "moveOrCopyMessageSynchronous: source folder = " + srcFolder
|
||||
+ ", " + messages.length + " messages, " + ", destination folder = " +
|
||||
destFolder + ", isCopy = " + isCopy);
|
||||
}
|
||||
|
||||
if (isCopy) {
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
localSrcFolder.fetch(messages, fp, null);
|
||||
localSrcFolder.copyMessages(messages, localDestFolder);
|
||||
} else {
|
||||
localSrcFolder.moveMessages(messages, localDestFolder);
|
||||
for (Map.Entry<String, Message> entry : origUidMap.entrySet()) {
|
||||
String origUid = entry.getKey();
|
||||
Message message = entry.getValue();
|
||||
for (MessagingListener l : getListeners()) {
|
||||
l.messageUidChanged(account, srcFolder, origUid, message.getUid());
|
||||
if (checkForPartialDownload && message.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
|
||||
// fully download message if it's moved/coied to a local-only folder
|
||||
Log.d("ASH", "downloading message...");
|
||||
if (loadMessageForViewRemoteSynchronous(account, srcFolder,
|
||||
message.getUid(), listener)) {
|
||||
Log.d("ASH", "downloaded message");
|
||||
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||
message.setFlag(Flag.X_DOWNLOADED_PARTIAL, false);
|
||||
origUidMap.put(message.getUid(), message);
|
||||
} else {
|
||||
Log.e(K9.LOG_TAG, "Cannot download message " + message.getUid() +
|
||||
" in folder " + srcFolder + " -- skipping it for move/copy.");
|
||||
Toast.makeText(mApplication, "Cannot download message " +
|
||||
message.getSubject() + " in folder " + srcFolder +
|
||||
" -- skipping it for move/copy.", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
unsuppressMessage(account, srcFolder, origUid);
|
||||
} else {
|
||||
origUidMap.put(message.getUid(), message);
|
||||
}
|
||||
}
|
||||
|
||||
if (!localDestFolder.isLocalOnly() && ((!isCopy && remoteStore.isMoveCapable()) ||
|
||||
(isCopy && remoteStore.isCopyCapable()))) {
|
||||
queueMoveOrCopy(account, srcFolder, destFolder, isCopy,
|
||||
origUidMap.keySet().toArray(EMPTY_STRING_ARRAY));
|
||||
} else if (!isCopy && !localSrcFolder.isLocalOnly()) {
|
||||
queueSetFlag(account, srcFolder, Boolean.toString(true),
|
||||
Flag.DELETED.toString(),
|
||||
origUidMap.keySet().toArray(EMPTY_STRING_ARRAY));
|
||||
if (Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy())) {
|
||||
queueExpunge(account, srcFolder);
|
||||
if (checkForPartialDownload) {
|
||||
messages = origUidMap.values().toArray(EMPTY_MESSAGE_ARRAY);
|
||||
}
|
||||
if (messages.length > 0) {
|
||||
if (K9.DEBUG) {
|
||||
Log.i(K9.LOG_TAG, "moveOrCopyMessageSynchronous: source folder = " + srcFolder
|
||||
+ ", " + messages.length + " messages, " + ", destination folder = " +
|
||||
destFolder + ", isCopy = " + isCopy);
|
||||
}
|
||||
|
||||
if (isCopy) {
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
localSrcFolder.fetch(messages, fp, null);
|
||||
localSrcFolder.copyMessages(messages, localDestFolder);
|
||||
} else {
|
||||
localSrcFolder.moveMessages(messages, localDestFolder);
|
||||
for (Map.Entry<String, Message> entry : origUidMap.entrySet()) {
|
||||
String origUid = entry.getKey();
|
||||
Message message = entry.getValue();
|
||||
for (MessagingListener l : getListeners()) {
|
||||
l.messageUidChanged(account, srcFolder, origUid, message.getUid());
|
||||
}
|
||||
unsuppressMessage(account, srcFolder, origUid);
|
||||
}
|
||||
}
|
||||
|
||||
if (!localDestFolder.isLocalOnly() &&
|
||||
(isCopy ? remoteStore.isCopyCapable() : remoteStore.isMoveCapable())) {
|
||||
// synced message copy/move to remote folder
|
||||
queueMoveOrCopy(account, srcFolder, destFolder, isCopy,
|
||||
origUidMap.keySet().toArray(EMPTY_STRING_ARRAY));
|
||||
} else if (!isCopy && !localSrcFolder.isLocalOnly()) {
|
||||
// synced message move to local folder: delete from source folder ASH maybe a better way.
|
||||
if (account.getDeletePolicy() == Account.DELETE_POLICY_ON_DELETE) {
|
||||
queueSetFlag(account, srcFolder, Boolean.toString(true),
|
||||
Flag.DELETED.toString(),
|
||||
origUidMap.keySet().toArray(EMPTY_STRING_ARRAY));
|
||||
if (Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy())) {
|
||||
queueExpunge(account, srcFolder);
|
||||
}
|
||||
} else if (account.getDeletePolicy() == Account.DELETE_POLICY_MARK_AS_READ) {
|
||||
queueSetFlag(account, srcFolder, Boolean.toString(true),
|
||||
Flag.SEEN.toString(),
|
||||
origUidMap.keySet().toArray(EMPTY_STRING_ARRAY));
|
||||
} else {
|
||||
if (K9.DEBUG)
|
||||
Log.d(K9.LOG_TAG, "Delete policy " + account.getDeletePolicy() + " prevents delete from server");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3334,17 +3466,22 @@ public class MessagingController implements Runnable {
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
localSrcFolder.fetch(localMessages, fp, null);
|
||||
|
||||
if ((!localDestFolder.isLocalOnly()) && ((!isCopy && (remoteStore.isMoveCapable()))
|
||||
|| (isCopy && (remoteStore.isCopyCapable())))) {
|
||||
if (account.isAutoUploadOnMove() && !localDestFolder.isLocalOnly() &&
|
||||
(isCopy ? remoteStore.isCopyCapable() : remoteStore.isMoveCapable())) {
|
||||
// local message copy/move to remote folder
|
||||
for (Message message : localMessages) {
|
||||
saveMessage(account, message, destFolder);
|
||||
}
|
||||
} else if (isCopy) {
|
||||
// local message copy to local folder
|
||||
localSrcFolder.copyMessages(localMessages, localDestFolder);
|
||||
}
|
||||
}
|
||||
|
||||
processPendingCommands(account);
|
||||
if (needToLocalizeSourceFolder) {
|
||||
localizeUids(localSrcFolder);
|
||||
}
|
||||
} catch (UnavailableStorageException e) {
|
||||
Log.i(K9.LOG_TAG, "Failed to move/copy message because storage is not available - trying again later.");
|
||||
throw new UnavailableAccountException(e);
|
||||
@ -3406,10 +3543,10 @@ public class MessagingController implements Runnable {
|
||||
|
||||
}
|
||||
|
||||
private void deleteMessagesSynchronous(final Account account, final String folder, final Message[] messages,
|
||||
private void deleteMessagesSynchronous(final Account account, final String folder, Message[] messages,
|
||||
MessagingListener listener) {
|
||||
Folder localFolder = null;
|
||||
Folder localTrashFolder = null;
|
||||
LocalFolder localFolder = null;
|
||||
LocalFolder localTrashFolder = null;
|
||||
String[] uids = getUidsFromMessages(messages);
|
||||
try {
|
||||
//We need to make these callbacks before moving the messages to the trash
|
||||
@ -3419,7 +3556,7 @@ public class MessagingController implements Runnable {
|
||||
l.messageDeleted(account, folder, message);
|
||||
}
|
||||
}
|
||||
Store localStore = account.getLocalStore();
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
localFolder = localStore.getFolder(folder);
|
||||
if (folder.equals(account.getTrashFolderName()) || K9.FOLDER_NONE.equals(account.getTrashFolderName())) {
|
||||
if (K9.DEBUG)
|
||||
@ -3429,12 +3566,54 @@ public class MessagingController implements Runnable {
|
||||
} else {
|
||||
localTrashFolder = localStore.getFolder(account.getTrashFolderName());
|
||||
if (!localTrashFolder.exists()) {
|
||||
localTrashFolder.create();
|
||||
if (account.getRemoteStore().isMoveCapable()) {
|
||||
localTrashFolder.create();
|
||||
} else {
|
||||
localTrashFolder.create(true);
|
||||
}
|
||||
}
|
||||
if (localTrashFolder.exists()) {
|
||||
if (K9.DEBUG)
|
||||
Log.d(K9.LOG_TAG, "Deleting messages in normal folder, moving");
|
||||
|
||||
localTrashFolder.open(OpenMode.READ_WRITE);
|
||||
// download messages first if trash folder is local-only,
|
||||
// otherwise it's not undoable.
|
||||
if (account.getDeletePolicy() == Account.DELETE_POLICY_ON_DELETE &&
|
||||
localTrashFolder.isLocalOnly() && !localFolder.isLocalOnly()) {
|
||||
Map<String, Message> origUidMap = new HashMap<String, Message>();
|
||||
Map<String, Message> skipUidMap = new HashMap<String, Message>();
|
||||
for (Message message : messages) {
|
||||
if (message.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
|
||||
Log.d("ASH", "downloading message...");
|
||||
if (loadMessageForViewRemoteSynchronous(account, folder,
|
||||
message.getUid(), listener)) {
|
||||
Log.d("ASH", "downloaded message");
|
||||
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||
message.setFlag(Flag.X_DOWNLOADED_PARTIAL, false);
|
||||
origUidMap.put(message.getUid(), message);
|
||||
} else {
|
||||
skipUidMap.put(message.getUid(), message);
|
||||
Log.e(K9.LOG_TAG, "Cannot download message -- skipping it for move to trash.");
|
||||
Toast.makeText(mApplication, "Cannot download message " +
|
||||
message.getSubject() + " in folder " + folder +
|
||||
" -- skipping it for move to trash.",
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
} else {
|
||||
origUidMap.put(message.getUid(), message);
|
||||
}
|
||||
}
|
||||
messages = origUidMap.values().toArray(EMPTY_MESSAGE_ARRAY);
|
||||
uids = origUidMap.keySet().toArray(EMPTY_STRING_ARRAY);
|
||||
for (String uid : skipUidMap.keySet()) {
|
||||
unsuppressMessage(account, folder, uid);
|
||||
}
|
||||
if (messages.length == 0) {
|
||||
Log.w(K9.LOG_TAG, "Not deleting any messages.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
localFolder.moveMessages(messages, localTrashFolder);
|
||||
|
||||
}
|
||||
@ -3451,32 +3630,37 @@ public class MessagingController implements Runnable {
|
||||
Log.d(K9.LOG_TAG, "Delete policy for account " + account.getDescription() + " is " + account.getDeletePolicy());
|
||||
|
||||
if (folder.equals(account.getOutboxFolderName())) {
|
||||
for (Message message : messages) {
|
||||
// If the message was in the Outbox, then it has been copied to local Trash, and has
|
||||
// to be copied to remote trash
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_APPEND;
|
||||
command.arguments =
|
||||
new String[] {
|
||||
account.getTrashFolderName(),
|
||||
message.getUid()
|
||||
};
|
||||
queuePendingCommand(account, command);
|
||||
localTrashFolder = (LocalFolder)localStore.getFolder(account.getTrashFolderName());
|
||||
localTrashFolder.open(OpenMode.READ_WRITE);
|
||||
if (!localTrashFolder.isLocalOnly()) {
|
||||
for (Message message : messages) {
|
||||
// If the message was in the Outbox, then it has been copied to local Trash, and has
|
||||
// to be copied to remote trash
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_APPEND;
|
||||
command.arguments = new String[] { account.getTrashFolderName(),
|
||||
message.getUid() };
|
||||
queuePendingCommand(account, command);
|
||||
}
|
||||
processPendingCommands(account);
|
||||
}
|
||||
processPendingCommands(account);
|
||||
} else if (account.getDeletePolicy() == Account.DELETE_POLICY_ON_DELETE) {
|
||||
if (folder.equals(account.getTrashFolderName())) {
|
||||
queueSetFlag(account, folder, Boolean.toString(true), Flag.DELETED.toString(), uids);
|
||||
} else if (!localFolder.isLocalOnly()) {
|
||||
localTrashFolder = (LocalFolder)localStore.getFolder(account.getTrashFolderName());
|
||||
localTrashFolder.open(OpenMode.READ_WRITE);
|
||||
if (account.getDeletePolicy() == Account.DELETE_POLICY_ON_DELETE) {
|
||||
if (folder.equals(account.getTrashFolderName()) || localTrashFolder.isLocalOnly()) {
|
||||
queueSetFlag(account, folder, Boolean.toString(true), Flag.DELETED.toString(), uids);
|
||||
} else {
|
||||
queueMoveOrCopy(account, folder, account.getTrashFolderName(), false, uids);
|
||||
}
|
||||
processPendingCommands(account);
|
||||
} else if (account.getDeletePolicy() == Account.DELETE_POLICY_MARK_AS_READ) {
|
||||
queueSetFlag(account, folder, Boolean.toString(true), Flag.SEEN.toString(), uids);
|
||||
processPendingCommands(account);
|
||||
} else {
|
||||
queueMoveOrCopy(account, folder, account.getTrashFolderName(), false, uids);
|
||||
if (K9.DEBUG)
|
||||
Log.d(K9.LOG_TAG, "Delete policy " + account.getDeletePolicy() + " prevents delete from server");
|
||||
}
|
||||
processPendingCommands(account);
|
||||
} else if (account.getDeletePolicy() == Account.DELETE_POLICY_MARK_AS_READ) {
|
||||
queueSetFlag(account, folder, Boolean.toString(true), Flag.SEEN.toString(), uids);
|
||||
processPendingCommands(account);
|
||||
} else {
|
||||
if (K9.DEBUG)
|
||||
Log.d(K9.LOG_TAG, "Delete policy " + account.getDeletePolicy() + " prevents delete from server");
|
||||
}
|
||||
for (String uid : uids) {
|
||||
unsuppressMessage(account, folder, uid);
|
||||
@ -3532,8 +3716,8 @@ public class MessagingController implements Runnable {
|
||||
public void run() {
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
Store localStore = account.getLocalStore();
|
||||
localFolder = (LocalFolder) localStore.getFolder(account.getTrashFolderName());
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
localFolder = localStore.getFolder(account.getTrashFolderName());
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
localFolder.setFlags(new Flag[] { Flag.DELETED }, true);
|
||||
localFolder.resetUnreadAndFlaggedCounts();
|
||||
@ -3541,12 +3725,14 @@ public class MessagingController implements Runnable {
|
||||
for (MessagingListener l : getListeners()) {
|
||||
l.emptyTrashCompleted(account);
|
||||
}
|
||||
List<String> args = new ArrayList<String>();
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_EMPTY_TRASH;
|
||||
command.arguments = args.toArray(EMPTY_STRING_ARRAY);
|
||||
queuePendingCommand(account, command);
|
||||
processPendingCommands(account);
|
||||
if (!localFolder.isLocalOnly()) {
|
||||
List<String> args = new ArrayList<String>();
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_EMPTY_TRASH;
|
||||
command.arguments = args.toArray(EMPTY_STRING_ARRAY);
|
||||
queuePendingCommand(account, command);
|
||||
processPendingCommands(account);
|
||||
} // ASH else do we need to destroy local messages? cketti says yes.
|
||||
} catch (UnavailableStorageException e) {
|
||||
Log.i(K9.LOG_TAG, "Failed to empty trash because storage is not available - trying again later.");
|
||||
throw new UnavailableAccountException(e);
|
||||
@ -3724,11 +3910,16 @@ public class MessagingController implements Runnable {
|
||||
Account.FolderMode aDisplayMode = account.getFolderDisplayMode();
|
||||
Account.FolderMode aSyncMode = account.getFolderSyncMode();
|
||||
|
||||
Store localStore = account.getLocalStore();
|
||||
for (final Folder folder : localStore.getPersonalNamespaces(false)) {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
for (final LocalFolder folder : localStore.getPersonalNamespaces(false)) {
|
||||
folder.open(Folder.OpenMode.READ_WRITE);
|
||||
folder.refresh(prefs);
|
||||
|
||||
if (folder.isLocalOnly()) {
|
||||
// Never sync a folder that is marked as local-only.
|
||||
continue;
|
||||
}
|
||||
|
||||
Folder.FolderClass fDisplayClass = folder.getDisplayClass();
|
||||
Folder.FolderClass fSyncClass = folder.getSyncClass();
|
||||
|
||||
@ -4171,14 +4362,13 @@ public class MessagingController implements Runnable {
|
||||
localMessage = localFolder.getMessage(message.getUid());
|
||||
localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_APPEND;
|
||||
command.arguments = new String[] {
|
||||
localFolder.getName(),
|
||||
localMessage.getUid()
|
||||
};
|
||||
queuePendingCommand(account, command);
|
||||
processPendingCommands(account);
|
||||
if (!localFolder.isLocalOnly()) {
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_APPEND;
|
||||
command.arguments = new String[] { localFolder.getName(), localMessage.getUid() };
|
||||
queuePendingCommand(account, command);
|
||||
processPendingCommands(account);
|
||||
}
|
||||
|
||||
} catch (MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "Unable to save message to " + folderName + ".", e);
|
||||
@ -4288,8 +4478,8 @@ public class MessagingController implements Runnable {
|
||||
|
||||
List<String> names = new ArrayList<String>();
|
||||
|
||||
Store localStore = account.getLocalStore();
|
||||
for (final Folder folder : localStore.getPersonalNamespaces(false)) {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
for (final LocalFolder folder : localStore.getPersonalNamespaces(false)) {
|
||||
if (folder.getName().equals(account.getErrorFolderName())
|
||||
|| folder.getName().equals(account.getOutboxFolderName())) {
|
||||
/*
|
||||
@ -4303,6 +4493,11 @@ public class MessagingController implements Runnable {
|
||||
folder.open(Folder.OpenMode.READ_WRITE);
|
||||
folder.refresh(prefs);
|
||||
|
||||
if (folder.isLocalOnly()) {
|
||||
// Never push a folder that is marked as local-only.
|
||||
continue;
|
||||
}
|
||||
|
||||
Folder.FolderClass fDisplayClass = folder.getDisplayClass();
|
||||
Folder.FolderClass fPushClass = folder.getPushClass();
|
||||
|
||||
|
@ -104,11 +104,7 @@ public abstract class Folder {
|
||||
|
||||
public void moveMessages(Message[] msgs, Folder folder) throws MessagingException {}
|
||||
|
||||
public void delete(Message[] msgs, String trashFolderName) throws MessagingException {
|
||||
// ASH remove these two lines but keep the empty method
|
||||
Log.e("ASH", "and i didn't think that Folder.delete(msgs, trashFolderName) ever got called: " + msgs[0].getClass());
|
||||
throw new MessagingException("ASH : and i didn't think that Folder.delete(msgs, trashFolderName) ever got called: " + msgs[0].getClass());
|
||||
}
|
||||
public void delete(Message[] msgs, String trashFolderName) throws MessagingException {}
|
||||
|
||||
public abstract void setFlags(Message[] messages, Flag[] flags, boolean value)
|
||||
throws MessagingException;
|
||||
|
@ -166,6 +166,10 @@ public abstract class Store {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAppendCapable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void sendMessages(Message[] messages) throws MessagingException {
|
||||
}
|
||||
|
||||
|
@ -833,6 +833,10 @@ public class ImapStore extends Store {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAppendCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
class ImapFolder extends Folder {
|
||||
private String mName;
|
||||
|
@ -888,6 +888,11 @@ Log.d("ASH", "updatedb " + mAccount.getDescription());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAppendCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Message[] searchForMessages(MessageRetrievalListener listener, String[] queryFields,
|
||||
String queryString, List<LocalFolder> folders, Message[] messages, final Flag[]
|
||||
requiredFlags, final Flag[] forbiddenFlags) throws MessagingException {
|
||||
@ -1248,7 +1253,8 @@ Log.d("ASH", "updatedb " + mAccount.getDescription());
|
||||
}
|
||||
} else {
|
||||
Log.w(K9.LOG_TAG, "Creating folder " + getName() + " with existing id " + getId());
|
||||
create(true); // ASH should this always be true?
|
||||
create(!LocalStore.this.mAccount.getRemoteStore().isAppendCapable() &&
|
||||
!LocalStore.this.mAccount.getInboxFolderName().equals(getName()));
|
||||
open(mode);
|
||||
}
|
||||
} catch (MessagingException e) {
|
||||
@ -2135,6 +2141,17 @@ Log.d("ASH", "setting folder " + mName + " to localOnly = " + localOnly);
|
||||
appendMessages(messages, false);
|
||||
}
|
||||
|
||||
public void expunge() throws MessagingException {
|
||||
List<Message> deletedMessages = new ArrayList<Message>();
|
||||
for (Message message : getMessages(null)) {
|
||||
if (message.isSet(Flag.DELETED)) {
|
||||
deletedMessages.add(message);
|
||||
Log.d("ASH", "about to destroy " + message.getUid());
|
||||
}
|
||||
}
|
||||
destroyMessages(deletedMessages.toArray(EMPTY_MESSAGE_ARRAY));
|
||||
}
|
||||
|
||||
public void destroyMessages(final Message[] messages) throws MessagingException {
|
||||
try {
|
||||
database.execute(true, new DbCallback<Void>() {
|
||||
@ -2709,14 +2726,14 @@ Log.d("ASH", "setting folder " + mName + " to localOnly = " + localOnly);
|
||||
clearMessagesWhere(where, params);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void clearAllMessages() throws MessagingException {
|
||||
final String where = "folder_id = ?";
|
||||
final String[] params = new String[] {
|
||||
Long.toString(mFolderId)
|
||||
};
|
||||
clearAllMessages(true);
|
||||
}
|
||||
|
||||
public void clearAllMessages(boolean includeLocalOnly) throws MessagingException {
|
||||
final String where = "folder_id = ?" + (includeLocalOnly ? "" :
|
||||
" AND uid NOT LIKE '" + K9.LOCAL_UID_PREFIX + "%'");
|
||||
final String[] params = new String[] { Long.toString(mFolderId) };
|
||||
|
||||
clearMessagesWhere(where, params);
|
||||
setPushState(null);
|
||||
|
@ -570,6 +570,11 @@ public class WebDavStore extends Store {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAppendCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getSpecialFoldersList() {
|
||||
StringBuilder buffer = new StringBuilder(200);
|
||||
buffer.append("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>");
|
||||
|
@ -171,6 +171,9 @@ public class GlobalSettings {
|
||||
s.put("registeredNameColor", Settings.versions(
|
||||
new V(1, new ColorSetting(0xFF00008F))
|
||||
));
|
||||
s.put("showAdvancedOptions", Settings.versions(
|
||||
new V(1, new BooleanSetting(false))
|
||||
));
|
||||
s.put("showContactName", Settings.versions(
|
||||
new V(1, new BooleanSetting(false))
|
||||
));
|
||||
|
@ -45,7 +45,6 @@ public class MessageHeader extends LinearLayout {
|
||||
|
||||
private View mChip;
|
||||
private CheckBox mFlagged;
|
||||
private int defaultSubjectColor;
|
||||
private LinearLayout mToContainerView;
|
||||
private LinearLayout mCcContainerView;
|
||||
private TextView mAdditionalHeadersView;
|
||||
@ -93,7 +92,6 @@ public class MessageHeader extends LinearLayout {
|
||||
mTimeView = (TextView) findViewById(R.id.time);
|
||||
mFlagged = (CheckBox) findViewById(R.id.flagged);
|
||||
|
||||
defaultSubjectColor = mSubjectView.getCurrentTextColor();
|
||||
mSubjectView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewSubject());
|
||||
mTimeView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewTime());
|
||||
mDateView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewDate());
|
||||
@ -212,7 +210,11 @@ public class MessageHeader extends LinearLayout {
|
||||
} else {
|
||||
mSubjectView.setText(subject);
|
||||
}
|
||||
mSubjectView.setTextColor(0xff000000 | defaultSubjectColor);
|
||||
if (message.getUid().startsWith(K9.LOCAL_UID_PREFIX)) {
|
||||
mSubjectView.setTextColor(mAccount.getChipColor());
|
||||
} else {
|
||||
mSubjectView.setTextColor(0xff000000);
|
||||
}
|
||||
|
||||
mFromView.setText(from);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user