Extended *Settings classes to handle multiple versions

This commit is contained in:
cketti 2011-12-11 05:16:22 +01:00
parent 09fa9d406f
commit d57e684296
7 changed files with 496 additions and 179 deletions

View file

@ -4,6 +4,8 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import android.content.SharedPreferences;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
@ -15,87 +17,198 @@ import com.fsck.k9.mail.store.StorageManager;
import com.fsck.k9.preferences.Settings.*;
public class AccountSettings {
public static final Map<String, SettingsDescription> SETTINGS;
public static final Map<String, TreeMap<Integer, SettingsDescription>> SETTINGS;
static {
Map<String, SettingsDescription> s = new LinkedHashMap<String, SettingsDescription>();
Map<String, TreeMap<Integer, SettingsDescription>> s =
new LinkedHashMap<String, TreeMap<Integer, SettingsDescription>>();
s.put("archiveFolderName", new StringSetting("Archive"));
s.put("autoExpandFolderName", new StringSetting("INBOX"));
s.put("automaticCheckIntervalMinutes",
new IntegerResourceSetting(-1, R.array.account_settings_check_frequency_values));
s.put("chipColor", new ColorSetting(0xFF0000FF));
s.put("cryptoApp", new StringSetting(Apg.NAME));
s.put("cryptoAutoSignature", new BooleanSetting(false));
s.put("cryptoAutoEncrypt", new BooleanSetting(false)); // added to version 3
s.put("defaultQuotedTextShown", new BooleanSetting(Account.DEFAULT_QUOTED_TEXT_SHOWN));
s.put("deletePolicy", new DeletePolicySetting(Account.DELETE_POLICY_NEVER));
s.put("displayCount", new IntegerResourceSetting(K9.DEFAULT_VISIBLE_LIMIT,
R.array.account_settings_display_count_values));
s.put("draftsFolderName", new StringSetting("Drafts"));
s.put("enableMoveButtons", new BooleanSetting(false));
s.put("expungePolicy", new StringResourceSetting(Account.EXPUNGE_IMMEDIATELY,
R.array.account_setup_expunge_policy_values));
s.put("folderDisplayMode", new EnumSetting(FolderMode.class, FolderMode.NOT_SECOND_CLASS));
s.put("folderPushMode", new EnumSetting(FolderMode.class, FolderMode.FIRST_CLASS));
s.put("folderSyncMode", new EnumSetting(FolderMode.class, FolderMode.FIRST_CLASS));
s.put("folderTargetMode", new EnumSetting(FolderMode.class, FolderMode.NOT_SECOND_CLASS));
s.put("goToUnreadMessageSearch", new BooleanSetting(false));
s.put("hideButtonsEnum", new EnumSetting(ScrollButtons.class, ScrollButtons.NEVER));
s.put("hideMoveButtonsEnum", new EnumSetting(ScrollButtons.class, ScrollButtons.NEVER));
s.put("idleRefreshMinutes", new IntegerResourceSetting(24,
R.array.idle_refresh_period_values));
s.put("inboxFolderName", new StringSetting("INBOX"));
s.put("led", new BooleanSetting(true));
s.put("ledColor", new ColorSetting(0xFF0000FF));
s.put("localStorageProvider", new StorageProviderSetting());
s.put("maxPushFolders", new IntegerRangeSetting(0, 100, 10));
s.put("maximumAutoDownloadMessageSize", new IntegerResourceSetting(32768,
R.array.account_settings_autodownload_message_size_values));
s.put("maximumPolledMessageAge", new IntegerResourceSetting(-1,
R.array.account_settings_message_age_values));
s.put("messageFormat",
new EnumSetting(Account.MessageFormat.class, Account.DEFAULT_MESSAGE_FORMAT));
s.put("messageFormatAuto", new BooleanSetting(Account.DEFAULT_MESSAGE_FORMAT_AUTO)); // added to version 2
s.put("messageReadReceipt", new BooleanSetting(Account.DEFAULT_MESSAGE_READ_RECEIPT));
s.put("notificationUnreadCount", new BooleanSetting(true));
s.put("notifyMailCheck", new BooleanSetting(false));
s.put("notifyNewMail", new BooleanSetting(false));
s.put("notifySelfNewMail", new BooleanSetting(true));
s.put("pushPollOnConnect", new BooleanSetting(true));
s.put("quotePrefix", new StringSetting(Account.DEFAULT_QUOTE_PREFIX));
s.put("quoteStyle",
new EnumSetting(Account.QuoteStyle.class, Account.DEFAULT_QUOTE_STYLE));
s.put("replyAfterQuote", new BooleanSetting(Account.DEFAULT_REPLY_AFTER_QUOTE));
s.put("stripSignature", new BooleanSetting(Account.DEFAULT_STRIP_SIGNATURE)); // added to version 2
s.put("ring", new BooleanSetting(true));
s.put("ringtone", new RingtoneSetting("content://settings/system/notification_sound"));
s.put("saveAllHeaders", new BooleanSetting(true));
s.put("searchableFolders",
new EnumSetting(Account.Searchable.class, Account.Searchable.ALL));
s.put("sentFolderName", new StringSetting("Sent"));
s.put("showPicturesEnum",
new EnumSetting(Account.ShowPictures.class, Account.ShowPictures.NEVER));
s.put("signatureBeforeQuotedText", new BooleanSetting(false));
s.put("spamFolderName", new StringSetting("Spam"));
s.put("subscribedFoldersOnly", new BooleanSetting(false));
s.put("syncRemoteDeletions", new BooleanSetting(true));
s.put("trashFolderName", new StringSetting("Trash"));
s.put("useCompression.MOBILE", new BooleanSetting(true));
s.put("useCompression.OTHER", new BooleanSetting(true));
s.put("useCompression.WIFI", new BooleanSetting(true));
s.put("vibrate", new BooleanSetting(false));
s.put("vibratePattern", new IntegerResourceSetting(0,
R.array.account_settings_vibrate_pattern_values));
s.put("vibrateTimes", new IntegerResourceSetting(5,
R.array.account_settings_vibrate_times_label));
s.put("archiveFolderName", Settings.versions(
new V(1, new StringSetting("Archive"))
));
s.put("autoExpandFolderName", Settings.versions(
new V(1, new StringSetting("INBOX"))
));
s.put("automaticCheckIntervalMinutes", Settings.versions(
new V(1, new IntegerResourceSetting(-1,
R.array.account_settings_check_frequency_values))
));
s.put("chipColor", Settings.versions(
new V(1, new ColorSetting(0xFF0000FF))
));
s.put("cryptoApp", Settings.versions(
new V(1, new StringSetting(Apg.NAME))
));
s.put("cryptoAutoSignature", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("cryptoAutoEncrypt", Settings.versions(
new V(3, new BooleanSetting(false)) // added to version 3
));
s.put("defaultQuotedTextShown", Settings.versions(
new V(1, new BooleanSetting(Account.DEFAULT_QUOTED_TEXT_SHOWN))
));
s.put("deletePolicy", Settings.versions(
new V(1, new DeletePolicySetting(Account.DELETE_POLICY_NEVER))
));
s.put("displayCount", Settings.versions(
new V(1, new IntegerResourceSetting(K9.DEFAULT_VISIBLE_LIMIT,
R.array.account_settings_display_count_values))
));
s.put("draftsFolderName", Settings.versions(
new V(1, new StringSetting("Drafts"))
));
s.put("enableMoveButtons", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("expungePolicy", Settings.versions(
new V(1, new StringResourceSetting(Account.EXPUNGE_IMMEDIATELY,
R.array.account_setup_expunge_policy_values))
));
s.put("folderDisplayMode", Settings.versions(
new V(1, new EnumSetting(FolderMode.class, FolderMode.NOT_SECOND_CLASS))
));
s.put("folderPushMode", Settings.versions(
new V(1, new EnumSetting(FolderMode.class, FolderMode.FIRST_CLASS))
));
s.put("folderSyncMode", Settings.versions(
new V(1, new EnumSetting(FolderMode.class, FolderMode.FIRST_CLASS))
));
s.put("folderTargetMode", Settings.versions(
new V(1, new EnumSetting(FolderMode.class, FolderMode.NOT_SECOND_CLASS))
));
s.put("goToUnreadMessageSearch", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("hideButtonsEnum", Settings.versions(
new V(1, new EnumSetting(ScrollButtons.class, ScrollButtons.NEVER))
));
s.put("hideMoveButtonsEnum", Settings.versions(
new V(1, new EnumSetting(ScrollButtons.class, ScrollButtons.NEVER))
));
s.put("idleRefreshMinutes", Settings.versions(
new V(1, new IntegerResourceSetting(24, R.array.idle_refresh_period_values))
));
s.put("inboxFolderName", Settings.versions(
new V(1, new StringSetting("INBOX"))
));
s.put("led", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("ledColor", Settings.versions(
new V(1, new ColorSetting(0xFF0000FF))
));
s.put("localStorageProvider", Settings.versions(
new V(1, new StorageProviderSetting())
));
s.put("maxPushFolders", Settings.versions(
new V(1, new IntegerRangeSetting(0, 100, 10))
));
s.put("maximumAutoDownloadMessageSize", Settings.versions(
new V(1, new IntegerResourceSetting(32768,
R.array.account_settings_autodownload_message_size_values))
));
s.put("maximumPolledMessageAge", Settings.versions(
new V(1, new IntegerResourceSetting(-1,
R.array.account_settings_message_age_values))
));
s.put("messageFormat", Settings.versions(
new V(1, new EnumSetting(Account.MessageFormat.class,
Account.DEFAULT_MESSAGE_FORMAT))
));
s.put("messageFormatAuto", Settings.versions(
new V(2, new BooleanSetting(Account.DEFAULT_MESSAGE_FORMAT_AUTO)) // added to version 2
));
s.put("messageReadReceipt", Settings.versions(
new V(1, new BooleanSetting(Account.DEFAULT_MESSAGE_READ_RECEIPT))
));
s.put("notificationUnreadCount", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("notifyMailCheck", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("notifyNewMail", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("notifySelfNewMail", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("pushPollOnConnect", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("quotePrefix", Settings.versions(
new V(1, new StringSetting(Account.DEFAULT_QUOTE_PREFIX))
));
s.put("quoteStyle", Settings.versions(
new V(1, new EnumSetting(Account.QuoteStyle.class, Account.DEFAULT_QUOTE_STYLE))
));
s.put("replyAfterQuote", Settings.versions(
new V(1, new BooleanSetting(Account.DEFAULT_REPLY_AFTER_QUOTE))
));
s.put("stripSignature", Settings.versions(
new V(2, new BooleanSetting(Account.DEFAULT_STRIP_SIGNATURE)) // added to version 2
));
s.put("ring", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("ringtone", Settings.versions(
new V(1, new RingtoneSetting("content://settings/system/notification_sound"))
));
s.put("saveAllHeaders", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("searchableFolders", Settings.versions(
new V(1, new EnumSetting(Account.Searchable.class, Account.Searchable.ALL))
));
s.put("sentFolderName", Settings.versions(
new V(1, new StringSetting("Sent"))
));
s.put("showPicturesEnum", Settings.versions(
new V(1, new EnumSetting(Account.ShowPictures.class, Account.ShowPictures.NEVER))
));
s.put("signatureBeforeQuotedText", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("spamFolderName", Settings.versions(
new V(1, new StringSetting("Spam"))
));
s.put("subscribedFoldersOnly", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("syncRemoteDeletions", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("trashFolderName", Settings.versions(
new V(1, new StringSetting("Trash"))
));
s.put("useCompression.MOBILE", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("useCompression.OTHER", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("useCompression.WIFI", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("vibrate", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("vibratePattern", Settings.versions(
new V(1, new IntegerResourceSetting(0,
R.array.account_settings_vibrate_pattern_values))
));
s.put("vibrateTimes", Settings.versions(
new V(1, new IntegerResourceSetting(5,
R.array.account_settings_vibrate_times_label))
));
SETTINGS = Collections.unmodifiableMap(s);
}
public static Map<String, String> validate(Map<String, String> importedSettings,
public static Map<String, String> validate(int version, Map<String, String> importedSettings,
boolean useDefaultValues) {
return Settings.validate(SETTINGS, importedSettings, useDefaultValues);
return Settings.validate(version, SETTINGS, importedSettings, useDefaultValues);
}
public static Map<String, String> getAccountSettings(SharedPreferences storage, String uuid) {

View file

@ -4,29 +4,42 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import android.content.SharedPreferences;
import com.fsck.k9.mail.Folder.FolderClass;
import com.fsck.k9.preferences.Settings.*;
public class FolderSettings {
public static final Map<String, SettingsDescription> SETTINGS;
public static final Map<String, TreeMap<Integer, SettingsDescription>> SETTINGS;
static {
Map<String, SettingsDescription> s = new LinkedHashMap<String, SettingsDescription>();
Map<String, TreeMap<Integer, SettingsDescription>> s =
new LinkedHashMap<String, TreeMap<Integer, SettingsDescription>>();
s.put("displayMode", new EnumSetting(FolderClass.class, FolderClass.NO_CLASS));
s.put("syncMode", new EnumSetting(FolderClass.class, FolderClass.INHERITED));
s.put("pushMode", new EnumSetting(FolderClass.class, FolderClass.INHERITED));
s.put("inTopGroup", new BooleanSetting(false));
s.put("integrate", new BooleanSetting(false));
s.put("displayMode", Settings.versions(
new V(1, new EnumSetting(FolderClass.class, FolderClass.NO_CLASS))
));
s.put("syncMode", Settings.versions(
new V(1, new EnumSetting(FolderClass.class, FolderClass.INHERITED))
));
s.put("pushMode", Settings.versions(
new V(1, new EnumSetting(FolderClass.class, FolderClass.INHERITED))
));
s.put("inTopGroup", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("integrate", Settings.versions(
new V(1, new BooleanSetting(false))
));
SETTINGS = Collections.unmodifiableMap(s);
}
public static Map<String, String> validate(Map<String, String> importedSettings,
public static Map<String, String> validate(int version, Map<String, String> importedSettings,
boolean useDefaultValues) {
return Settings.validate(SETTINGS, importedSettings, useDefaultValues);
return Settings.validate(version, SETTINGS, importedSettings, useDefaultValues);
}
public static Map<String, String> getFolderSettings(SharedPreferences storage, String uuid,

View file

@ -6,6 +6,8 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import android.content.SharedPreferences;
import android.os.Environment;
@ -16,74 +18,183 @@ import com.fsck.k9.helper.DateFormatter;
import com.fsck.k9.preferences.Settings.*;
public class GlobalSettings {
public static final Map<String, SettingsDescription> SETTINGS;
public static final Map<String, TreeMap<Integer, SettingsDescription>> SETTINGS;
static {
Map<String, SettingsDescription> s = new LinkedHashMap<String, SettingsDescription>();
Map<String, TreeMap<Integer, SettingsDescription>> s =
new LinkedHashMap<String, TreeMap<Integer, SettingsDescription>>();
s.put("animations", new BooleanSetting(false));
s.put("attachmentdefaultpath",
new DirectorySetting(Environment.getExternalStorageDirectory().toString()));
s.put("backgroundOperations",
new EnumSetting(K9.BACKGROUND_OPS.class, K9.BACKGROUND_OPS.WHEN_CHECKED));
s.put("changeRegisteredNameColor", new BooleanSetting(false));
s.put("compactLayouts", new BooleanSetting(false));
s.put("confirmDelete", new BooleanSetting(false));
s.put("confirmDeleteStarred", new BooleanSetting(false)); // added to version 2
s.put("confirmMarkAllAsRead", new BooleanSetting(false));
s.put("confirmSpam", new BooleanSetting(false));
s.put("countSearchMessages", new BooleanSetting(false));
s.put("dateFormat", new DateFormatSetting(DateFormatter.DEFAULT_FORMAT));
s.put("enableDebugLogging", new BooleanSetting(false));
s.put("enableSensitiveLogging", new BooleanSetting(false));
s.put("fontSizeAccountDescription", new FontSizeSetting(FontSizes.SMALL));
s.put("fontSizeAccountName", new FontSizeSetting(FontSizes.MEDIUM));
s.put("fontSizeFolderName", new FontSizeSetting(FontSizes.LARGE));
s.put("fontSizeFolderStatus", new FontSizeSetting(FontSizes.SMALL));
s.put("fontSizeMessageListDate", new FontSizeSetting(FontSizes.SMALL));
s.put("fontSizeMessageListPreview", new FontSizeSetting(FontSizes.SMALL));
s.put("fontSizeMessageListSender", new FontSizeSetting(FontSizes.SMALL));
s.put("fontSizeMessageListSubject", new FontSizeSetting(FontSizes.FONT_16DIP));
s.put("fontSizeMessageViewAdditionalHeaders", new FontSizeSetting(FontSizes.FONT_12DIP));
s.put("fontSizeMessageViewCC", new FontSizeSetting(FontSizes.FONT_12DIP));
s.put("fontSizeMessageViewContent", new WebFontSizeSetting(3));
s.put("fontSizeMessageViewDate", new FontSizeSetting(FontSizes.FONT_10DIP));
s.put("fontSizeMessageViewSender", new FontSizeSetting(FontSizes.SMALL));
s.put("fontSizeMessageViewSubject", new FontSizeSetting(FontSizes.FONT_12DIP));
s.put("fontSizeMessageViewTime", new FontSizeSetting(FontSizes.FONT_10DIP));
s.put("fontSizeMessageViewTo", new FontSizeSetting(FontSizes.FONT_12DIP));
s.put("gesturesEnabled", new BooleanSetting(true));
s.put("hideSpecialAccounts", new BooleanSetting(false));
s.put("keyguardPrivacy", new BooleanSetting(false));
s.put("language", new LanguageSetting());
s.put("manageBack", new BooleanSetting(false));
s.put("measureAccounts", new BooleanSetting(true));
s.put("messageListCheckboxes", new BooleanSetting(false));
s.put("messageListPreviewLines", new IntegerRangeSetting(1, 100, 2));
s.put("messageListStars", new BooleanSetting(true));
s.put("messageListTouchable", new BooleanSetting(false));
s.put("messageViewFixedWidthFont", new BooleanSetting(false));
s.put("messageViewReturnToList", new BooleanSetting(false));
s.put("messageViewShowNext", new BooleanSetting(false));
s.put("mobileOptimizedLayout", new BooleanSetting(false));
s.put("quietTimeEnabled", new BooleanSetting(false));
s.put("quietTimeEnds", new TimeSetting("7:00"));
s.put("quietTimeStarts", new TimeSetting("21:00"));
s.put("registeredNameColor", new ColorSetting(0xFF00008F));
s.put("showContactName", new BooleanSetting(false));
s.put("showCorrespondentNames", new BooleanSetting(true));
s.put("startIntegratedInbox", new BooleanSetting(false));
s.put("theme", new ThemeSetting(android.R.style.Theme_Light));
s.put("useGalleryBugWorkaround", new GalleryBugWorkaroundSetting());
s.put("useVolumeKeysForListNavigation", new BooleanSetting(false));
s.put("useVolumeKeysForNavigation", new BooleanSetting(false));
s.put("zoomControlsEnabled", new BooleanSetting(false));
s.put("animations", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("attachmentdefaultpath", Settings.versions(
new V(1, new DirectorySetting(Environment.getExternalStorageDirectory().toString()))
));
s.put("backgroundOperations", Settings.versions(
new V(1, new EnumSetting(K9.BACKGROUND_OPS.class, K9.BACKGROUND_OPS.WHEN_CHECKED))
));
s.put("changeRegisteredNameColor", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("compactLayouts", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("confirmDelete", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("confirmDeleteStarred", Settings.versions(
new V(2, new BooleanSetting(false)) // added to version 2
));
s.put("confirmMarkAllAsRead", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("confirmSpam", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("countSearchMessages", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("dateFormat", Settings.versions(
new V(1, new DateFormatSetting(DateFormatter.DEFAULT_FORMAT))
));
s.put("enableDebugLogging", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("enableSensitiveLogging", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("fontSizeAccountDescription", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.SMALL))
));
s.put("fontSizeAccountName", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.MEDIUM))
));
s.put("fontSizeFolderName", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.LARGE))
));
s.put("fontSizeFolderStatus", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.SMALL))
));
s.put("fontSizeMessageListDate", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.SMALL))
));
s.put("fontSizeMessageListPreview", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.SMALL))
));
s.put("fontSizeMessageListSender", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.SMALL))
));
s.put("fontSizeMessageListSubject", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.FONT_16DIP))
));
s.put("fontSizeMessageViewAdditionalHeaders", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.FONT_12DIP))
));
s.put("fontSizeMessageViewCC", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.FONT_12DIP))
));
s.put("fontSizeMessageViewContent", Settings.versions(
new V(1, new WebFontSizeSetting(3))
));
s.put("fontSizeMessageViewDate", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.FONT_10DIP))
));
s.put("fontSizeMessageViewSender", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.SMALL))
));
s.put("fontSizeMessageViewSubject", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.FONT_12DIP))
));
s.put("fontSizeMessageViewTime", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.FONT_10DIP))
));
s.put("fontSizeMessageViewTo", Settings.versions(
new V(1, new FontSizeSetting(FontSizes.FONT_12DIP))
));
s.put("gesturesEnabled", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("hideSpecialAccounts", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("keyguardPrivacy", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("language", Settings.versions(
new V(1, new LanguageSetting())
));
s.put("manageBack", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("measureAccounts", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("messageListCheckboxes", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("messageListPreviewLines", Settings.versions(
new V(1, new IntegerRangeSetting(1, 100, 2))
));
s.put("messageListStars", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("messageListTouchable", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("messageViewFixedWidthFont", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("messageViewReturnToList", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("messageViewShowNext", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("mobileOptimizedLayout", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("quietTimeEnabled", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("quietTimeEnds", Settings.versions(
new V(1, new TimeSetting("7:00"))
));
s.put("quietTimeStarts", Settings.versions(
new V(1, new TimeSetting("21:00"))
));
s.put("registeredNameColor", Settings.versions(
new V(1, new ColorSetting(0xFF00008F))
));
s.put("showContactName", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("showCorrespondentNames", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("startIntegratedInbox", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("theme", Settings.versions(
new V(1, new ThemeSetting(android.R.style.Theme_Light))
));
s.put("useGalleryBugWorkaround", Settings.versions(
new V(1, new GalleryBugWorkaroundSetting())
));
s.put("useVolumeKeysForListNavigation", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("useVolumeKeysForNavigation", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("zoomControlsEnabled", Settings.versions(
new V(1, new BooleanSetting(false))
));
SETTINGS = Collections.unmodifiableMap(s);
}
public static Map<String, String> validate(Map<String, String> importedSettings) {
return Settings.validate(SETTINGS, importedSettings, false);
public static Map<String, String> validate(int version, Map<String, String> importedSettings) {
return Settings.validate(version, SETTINGS, importedSettings, false);
}
public static Map<String, String> getGlobalSettings(SharedPreferences storage) {

View file

@ -4,6 +4,8 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import android.content.SharedPreferences;
import com.fsck.k9.EmailAddressValidator;
@ -12,21 +14,28 @@ import com.fsck.k9.R;
import com.fsck.k9.preferences.Settings.*;
public class IdentitySettings {
public static final Map<String, SettingsDescription> SETTINGS;
public static final Map<String, TreeMap<Integer, SettingsDescription>> SETTINGS;
static {
Map<String, SettingsDescription> s = new LinkedHashMap<String, SettingsDescription>();
Map<String, TreeMap<Integer, SettingsDescription>> s =
new LinkedHashMap<String, TreeMap<Integer, SettingsDescription>>();
s.put("signature", new SignatureSetting());
s.put("signatureUse", new BooleanSetting(true));
s.put("replyTo", new OptionalEmailAddressSetting());
s.put("signature", Settings.versions(
new V(1, new SignatureSetting())
));
s.put("signatureUse", Settings.versions(
new V(1, new BooleanSetting(true))
));
s.put("replyTo", Settings.versions(
new V(1, new OptionalEmailAddressSetting())
));
SETTINGS = Collections.unmodifiableMap(s);
}
public static Map<String, String> validate(Map<String, String> importedSettings,
public static Map<String, String> validate(int version, Map<String, String> importedSettings,
boolean useDefaultValues) {
return Settings.validate(SETTINGS, importedSettings, useDefaultValues);
return Settings.validate(version, SETTINGS, importedSettings, useDefaultValues);
}
public static Map<String, String> getIdentitySettings(SharedPreferences storage, String uuid,

View file

@ -3,6 +3,7 @@ package com.fsck.k9.preferences;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import android.util.Log;
@ -34,12 +35,22 @@ public class Settings {
*/
public static final int VERSION = 3;
public static Map<String, String> validate(Map<String, SettingsDescription> settings,
public static Map<String, String> validate(int version, Map<String,
TreeMap<Integer, SettingsDescription>> settings,
Map<String, String> importedSettings, boolean useDefaultValues) {
Map<String, String> validatedSettings = new HashMap<String, String>();
for (Map.Entry<String, SettingsDescription> setting : settings.entrySet()) {
String key = setting.getKey();
for (Map.Entry<String, TreeMap<Integer, SettingsDescription>> versionedSetting :
settings.entrySet()) {
Entry<Integer, SettingsDescription> setting =
versionedSetting.getValue().floorEntry(version);
if (setting == null) {
continue;
}
String key = versionedSetting.getKey();
SettingsDescription desc = setting.getValue();
boolean useDefaultValue;
@ -72,6 +83,31 @@ public class Settings {
return validatedSettings;
}
/**
* Creates a {@link TreeMap} linking version numbers to {@link SettingsDescription} instances.
*
* <p>
* This {@code TreeMap} is used to quickly find the {@code SettingsDescription} belonging to a
* content version as read by {@link SettingsImporter}. See e.g.
* {@link Settings#validate(int, Map, Map, boolean)}.
* </p>
*
* @param versionDescriptions
* A list of descriptions for a specific setting mapped to version numbers. Never
* {@code null}.
*
* @return A {@code TreeMap} using the version number as key, the {@code SettingsDescription}
* as value.
*/
public static TreeMap<Integer, SettingsDescription> versions(
V... versionDescriptions) {
TreeMap<Integer, SettingsDescription> map = new TreeMap<Integer, SettingsDescription>();
for (V v : versionDescriptions) {
map.put(v.version, v.description);
}
return map;
}
/**
* Indicates an invalid setting value.
@ -183,6 +219,22 @@ public class Settings {
}
}
/**
* Container to hold a {@link SettingsDescription} instance and a version number.
*
* @see Settings#versions(V...)
*/
public static class V {
public final Integer version;
public final SettingsDescription description;
public V(Integer version, SettingsDescription description) {
this.version = version;
this.description = description;
}
}
/**
* A string setting.
*/

View file

@ -167,11 +167,14 @@ public class SettingsExporter {
private static void writeSettings(XmlSerializer serializer,
Map<String, Object> prefs) throws IOException {
for (String key : GlobalSettings.SETTINGS.keySet()) {
for (Entry<String, TreeMap<Integer, SettingsDescription>> versionedSetting :
GlobalSettings.SETTINGS.entrySet()) {
String key = versionedSetting.getKey();
String valueString = (String) prefs.get(key);
SettingsDescription setting = versionedSetting.getValue().lastEntry().getValue();
if (valueString != null) {
try {
SettingsDescription setting = GlobalSettings.SETTINGS.get(key);
Object value = setting.fromString(valueString);
String outputValue = setting.toPrettyString(value);
writeKeyValue(serializer, key, outputValue);
@ -185,7 +188,6 @@ public class SettingsExporter {
"Using default value.");
}
SettingsDescription setting = GlobalSettings.SETTINGS.get(key);
Object value = setting.getDefaultValue();
String outputValue = setting.toPrettyString(value);
writeKeyValue(serializer, key, outputValue);
@ -311,8 +313,12 @@ public class SettingsExporter {
keyPart = secondPart;
}
SettingsDescription setting = AccountSettings.SETTINGS.get(keyPart);
if (setting != null) {
TreeMap<Integer, SettingsDescription> versionedSetting =
AccountSettings.SETTINGS.get(keyPart);
if (versionedSetting != null) {
SettingsDescription setting = versionedSetting.lastEntry().getValue();
// Only export account settings that can be found in AccountSettings.SETTINGS
try {
Object value = setting.fromString(valueString);
@ -399,8 +405,12 @@ public class SettingsExporter {
continue;
}
SettingsDescription setting = IdentitySettings.SETTINGS.get(identityKey);
if (setting != null) {
TreeMap<Integer, SettingsDescription> versionedSetting =
IdentitySettings.SETTINGS.get(identityKey);
if (versionedSetting != null) {
SettingsDescription setting = versionedSetting.lastEntry().getValue();
// Only write settings that have an entry in IdentitySettings.SETTINGS
try {
Object value = setting.fromString(valueString);
@ -444,8 +454,12 @@ public class SettingsExporter {
continue;
}
SettingsDescription setting = FolderSettings.SETTINGS.get(folderKey);
if (setting != null) {
TreeMap<Integer, SettingsDescription> versionedSetting =
FolderSettings.SETTINGS.get(folderKey);
if (versionedSetting != null) {
SettingsDescription setting = versionedSetting.lastEntry().getValue();
// Only write settings that have an entry in FolderSettings.SETTINGS
try {
Object value = setting.fromString(valueString);

View file

@ -191,7 +191,8 @@ public class SettingsImporter {
try {
SharedPreferences.Editor editor = storage.edit();
if (imported.globalSettings != null) {
importGlobalSettings(storage, editor, imported.globalSettings);
importGlobalSettings(storage, editor, imported.contentVersion,
imported.globalSettings);
} else {
Log.w(K9.LOG_TAG, "Was asked to import global settings but none found.");
}
@ -222,7 +223,7 @@ public class SettingsImporter {
SharedPreferences.Editor editor = storage.edit();
AccountDescriptionPair importResult = importAccount(context,
editor, account, overwrite);
editor, imported.contentVersion, account, overwrite);
String newUuid = importResult.imported.uuid;
if (!importResult.overwritten) {
@ -300,9 +301,10 @@ public class SettingsImporter {
}
private static void importGlobalSettings(SharedPreferences storage,
SharedPreferences.Editor editor, ImportedSettings settings) {
SharedPreferences.Editor editor, int contentVersion, ImportedSettings settings) {
Map<String, String> validatedSettings = GlobalSettings.validate(settings.settings);
Map<String, String> validatedSettings = GlobalSettings.validate(contentVersion,
settings.settings);
// Use current global settings as base and overwrite with validated settings read from the
// import file.
@ -318,8 +320,8 @@ public class SettingsImporter {
}
private static AccountDescriptionPair importAccount(Context context,
SharedPreferences.Editor editor, ImportedAccount account, boolean overwrite)
throws InvalidSettingValueException {
SharedPreferences.Editor editor, int contentVersion, ImportedAccount account,
boolean overwrite) throws InvalidSettingValueException {
AccountDescription original = new AccountDescription(account.name, account.uuid);
@ -391,7 +393,8 @@ public class SettingsImporter {
// Validate account settings
Map<String, String> validatedSettings =
AccountSettings.validate(account.settings.settings, !mergeImportedAccount);
AccountSettings.validate(contentVersion, account.settings.settings,
!mergeImportedAccount);
// Merge account settings if necessary
Map<String, String> writeSettings;
@ -418,7 +421,8 @@ public class SettingsImporter {
// Write identities
if (account.identities != null) {
importIdentities(editor, uuid, account, overwrite, existingAccount, prefs);
importIdentities(editor, contentVersion, uuid, account, overwrite, existingAccount,
prefs);
} else if (!mergeImportedAccount) {
// Require accounts to at least have one identity
throw new InvalidSettingValueException();
@ -427,7 +431,7 @@ public class SettingsImporter {
// Write folder settings
if (account.folders != null) {
for (ImportedFolder folder : account.folders) {
importFolder(editor, uuid, folder, mergeImportedAccount, prefs);
importFolder(editor, contentVersion, uuid, folder, mergeImportedAccount, prefs);
}
}
@ -437,12 +441,12 @@ public class SettingsImporter {
return new AccountDescriptionPair(original, imported, mergeImportedAccount);
}
private static void importFolder(SharedPreferences.Editor editor, String uuid,
ImportedFolder folder, boolean overwrite, Preferences prefs) {
private static void importFolder(SharedPreferences.Editor editor, int contentVersion,
String uuid, ImportedFolder folder, boolean overwrite, Preferences prefs) {
// Validate folder settings
Map<String, String> validatedSettings =
FolderSettings.validate(folder.settings.settings, !overwrite);
FolderSettings.validate(contentVersion, folder.settings.settings, !overwrite);
// Merge folder settings if necessary
Map<String, String> writeSettings;
@ -463,8 +467,8 @@ public class SettingsImporter {
}
}
private static void importIdentities(SharedPreferences.Editor editor, String uuid,
ImportedAccount account, boolean overwrite, Account existingAccount,
private static void importIdentities(SharedPreferences.Editor editor, int contentVersion,
String uuid, ImportedAccount account, boolean overwrite, Account existingAccount,
Preferences prefs) throws InvalidSettingValueException {
String accountKeyPrefix = uuid + ".";
@ -531,7 +535,7 @@ public class SettingsImporter {
if (identity.settings != null) {
// Validate identity settings
Map<String, String> validatedSettings = IdentitySettings.validate(
identity.settings.settings, !mergeSettings);
contentVersion, identity.settings.settings, !mergeSettings);
// Merge identity settings if necessary
Map<String, String> writeSettings;
@ -677,7 +681,7 @@ public class SettingsImporter {
String contentVersionString = xpp.getAttributeValue(null,
SettingsExporter.VERSION_ATTRIBUTE);
validateContentVersion(contentVersionString);
result.contentVersion = validateContentVersion(contentVersionString);
int eventType = xpp.next();
while (!(eventType == XmlPullParser.END_TAG &&
@ -756,7 +760,7 @@ public class SettingsImporter {
versionString);
}
if (version != Settings.VERSION) {
if (version < 1 || version > Settings.VERSION) {
throw new SettingsImportExportException("Unsupported content version: " +
versionString);
}
@ -1066,6 +1070,7 @@ public class SettingsImporter {
}
private static class Imported {
public int contentVersion;
public ImportedSettings globalSettings;
public Map<String, ImportedAccount> accounts;
}