1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-03-03 01:51:49 -05:00

Merge remote-tracking branch 'zjw/folder_search'

* zjw/folder_search:
  Provide message search capability from the folder list.
  Eliminate unused code.
  Switch to using the action bar for folder searches.
  Use a more appropriate title when diplaying folder search results.
  Switch to using the action bar for folder searches.
  Provide new action bar "find folder" icons
  Create action buttons to search for folders.
  Readjust settings version number based on current master
  Control wrapping of folder names programmatically only
  Permit the folder list item to expand vertically.
  Create new preference option for wrapping folder names in folder list view.
  Issue 1911:  Permit folder names to wrap on multiple lines in folder list view so users can see the entire name.
This commit is contained in:
Jesse Vincent 2013-01-15 15:19:12 -05:00
commit f8414ffe99
23 changed files with 140 additions and 178 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -23,7 +23,7 @@
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center_vertical"
@ -33,8 +33,6 @@
android:id="@+id/folder_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="start"
android:textColor="?android:attr/textColorPrimary"
android:textAppearance="?android:attr/textAppearanceLarge" />

View File

@ -1,6 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/search"
android:icon="?attr/iconActionSearch"
android:showAsAction="always"
android:title="@string/search_action"/>
<item
android:id="@+id/filter_folders"
android:icon="?attr/iconActionSearchFolder"
android:showAsAction="always|collapseActionView"
android:title="@string/filter_folders_action"
android:actionViewClass="com.actionbarsherlock.widget.SearchView"/>
<item
android:id="@+id/check_mail"
android:alphabeticShortcut="r"
@ -29,9 +39,6 @@
<item
android:id="@+id/display_not_second_class"
android:title="@string/folder_list_display_mode_not_second_class"/>
<item
android:id="@+id/filter_folders"
android:title="@string/filter_folders_action"/>
</menu>
</item>
<item
@ -66,4 +73,4 @@
</menu>
</item>
</menu>
</menu>

View File

@ -6,6 +6,13 @@
android:icon="@drawable/ic_show_folders"
>
<menu>-->
<item
android:id="@+id/filter_folders"
android:icon="?attr/iconActionSearchFolder"
android:showAsAction="always|collapseActionView"
android:title="@string/filter_folders_action"
android:actionViewClass="com.actionbarsherlock.widget.SearchView"
/>
<item
android:id="@+id/display_all"
android:title="@string/folder_list_display_mode_all"
@ -31,11 +38,6 @@
android:title="@string/refresh_folders_action"
android:icon="?attr/iconMenuRefresh"
/>
<item
android:id="@+id/filter_folders"
android:title="@string/filter_folders_action"
android:icon="?attr/iconMenuSearch"
/>
<!-- </menu>
</item>-->

View File

@ -16,6 +16,7 @@
<attr name="iconActionPreviousMessage" format="reference" />
<attr name="iconActionRefresh" format="reference" />
<attr name="iconActionSearch" format="reference" />
<attr name="iconActionSearchFolder" format="reference" />
<attr name="iconActionSend" format="reference" />
<attr name="iconActionSettings" format="reference" />
<attr name="iconActionSingleMessageOptions" format="reference" />

View File

@ -324,6 +324,8 @@ Please submit bug reports, contribute new features and ask questions at
<string name="global_settings_registered_name_color_label">Colorize contacts</string>
<string name="global_settings_registered_name_color_default">Don\'t colorize names in your contact list</string>
<string name="global_settings_registered_name_color_changed">Colorize names in your contact list</string>
<string name="global_settings_folderlist_wrap_folder_names_label">Wrap folder names</string>
<string name="global_settings_folderlist_wrap_folder_names_summary">Show complete folder name wrapped on multiple lines rather than a partial name on a single line</string>
<string name="global_settings_messageview_fixedwidth_label">Fixed-width fonts</string>
<string name="global_settings_messageview_fixedwidth_summary">Use a fixed-width font when showing plain-text messages</string>
@ -814,6 +816,7 @@ Please submit bug reports, contribute new features and ask questions at
<string name="accountlist_preferences">Account list</string>
<string name="messagelist_preferences">Message lists</string>
<string name="messageview_preferences">Messages</string>
<string name="folderlist_preferences">Folder lists</string>
<string name="settings_theme_label">Theme</string>
<string name="settings_language_label">Language</string>

View File

@ -16,6 +16,7 @@
<item name="iconActionPreviousMessage">@drawable/ic_action_previous_message_light</item>
<item name="iconActionRefresh">@drawable/ic_action_refresh_light</item>
<item name="iconActionSearch">@drawable/ic_action_search_light</item>
<item name="iconActionSearchFolder">@drawable/action_search_folder_light</item>
<item name="iconActionSend">@drawable/ic_action_send_light</item>
<item name="iconActionSettings">@drawable/ic_action_settings_light</item>
<item name="iconActionSingleMessageOptions">@drawable/ic_action_single_message_options_light</item>
@ -64,6 +65,7 @@
<item name="iconActionPreviousMessage">@drawable/ic_action_previous_message_dark</item>
<item name="iconActionRefresh">@drawable/ic_action_refresh_dark</item>
<item name="iconActionSearch">@drawable/ic_action_search_dark</item>
<item name="iconActionSearchFolder">@drawable/action_search_folder_dark</item>
<item name="iconActionSend">@drawable/ic_action_send_dark</item>
<item name="iconActionSettings">@drawable/ic_action_settings_dark</item>
<item name="iconActionSingleMessageOptions">@drawable/ic_action_single_message_options_dark</item>

View File

@ -176,6 +176,18 @@
</PreferenceCategory>
<PreferenceCategory
android:key="folderlist_preferences"
android:title="@string/folderlist_preferences">
<CheckBoxPreference
android:persistent="false"
android:key="folderlist_wrap_folder_name"
android:title="@string/global_settings_folderlist_wrap_folder_names_label"
android:summary="@string/global_settings_folderlist_wrap_folder_names_summary" />
</PreferenceCategory>
</PreferenceScreen>
<PreferenceScreen

View File

@ -136,7 +136,7 @@ public class FontSizes {
accountName = MEDIUM;
accountDescription = SMALL;
folderName = LARGE;
folderName = FONT_16SP;
folderStatus = SMALL;
messageListSubject = FONT_16SP;

View File

@ -234,6 +234,7 @@ public class K9 extends Application {
private static String mQuietTimeStarts = null;
private static String mQuietTimeEnds = null;
private static String mAttachmentDefaultPath = "";
private static boolean mWrapFolderNames = false;
private static boolean mBatchButtonsMarkRead = true;
private static boolean mBatchButtonsDelete = true;
@ -501,6 +502,7 @@ public class K9 extends Application {
editor.putBoolean("messageViewFixedWidthFont", mMessageViewFixedWidthFont);
editor.putBoolean("messageViewReturnToList", mMessageViewReturnToList);
editor.putBoolean("messageViewShowNext", mMessageViewShowNext);
editor.putBoolean("wrapFolderNames", mWrapFolderNames);
editor.putBoolean("batchButtonsMarkRead", mBatchButtonsMarkRead);
editor.putBoolean("batchButtonsDelete", mBatchButtonsDelete);
@ -694,6 +696,7 @@ public class K9 extends Application {
mMessageViewFixedWidthFont = sprefs.getBoolean("messageViewFixedWidthFont", false);
mMessageViewReturnToList = sprefs.getBoolean("messageViewReturnToList", false);
mMessageViewShowNext = sprefs.getBoolean("messageViewShowNext", false);
mWrapFolderNames = sprefs.getBoolean("wrapFolderNames", false);
mBatchButtonsMarkRead = sprefs.getBoolean("batchButtonsMarkRead", true);
mBatchButtonsDelete = sprefs.getBoolean("batchButtonsDelete", true);
@ -1214,6 +1217,13 @@ public class K9 extends Application {
}
}
public static boolean wrapFolderNames() {
return mWrapFolderNames;
}
public static void setWrapFolderNames(final boolean state) {
mWrapFolderNames = state;
}
public static String getAttachmentDefaultPath() {
return mAttachmentDefaultPath;
}

View File

@ -6,22 +6,18 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
import com.actionbarsherlock.widget.SearchView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.ListView;
import android.widget.TextView;
@ -172,9 +168,30 @@ public class ChooseFolder extends K9ListActivity {
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getSupportMenuInflater().inflate(R.menu.folder_select_option, menu);
configureFolderSearchView(menu);
return true;
}
private void configureFolderSearchView(Menu menu) {
final MenuItem folderMenuItem = menu.findItem(R.id.filter_folders);
final SearchView folderSearchView = (SearchView) folderMenuItem.getActionView();
folderSearchView.setQueryHint(getString(R.string.folder_list_filter_hint));
folderSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
folderMenuItem.collapseActionView();
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
mAdapter.getFilter().filter(newText);
return true;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@ -198,10 +215,6 @@ public class ChooseFolder extends K9ListActivity {
onRefresh();
return true;
}
case R.id.filter_folders: {
onEnterFilter();
return true;
}
default: {
return super.onOptionsItemSelected(item);
}
@ -212,50 +225,6 @@ public class ChooseFolder extends K9ListActivity {
MessagingController.getInstance(getApplication()).listFolders(mAccount, true, mListener);
}
/**
* Show an alert with an input-field for a filter-expression.
* Filter {@link #mAdapter} with the user-input.
*/
private void onEnterFilter() {
final AlertDialog.Builder filterAlert = new AlertDialog.Builder(this);
final EditText input = new EditText(this);
input.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mAdapter.getFilter().filter(input.getText().toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
/* not used */ }
@Override
public void afterTextChanged(Editable s) { /* not used */ }
});
input.setHint(R.string.folder_list_filter_hint);
filterAlert.setView(input);
String okay = getString(R.string.okay_action);
filterAlert.setPositiveButton(okay, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString().trim();
mAdapter.getFilter().filter(value);
}
});
String cancel = getString(R.string.cancel_action);
filterAlert.setNegativeButton(cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
mAdapter.getFilter().filter("");
}
});
filterAlert.show();
}
private void setDisplayMode(FolderMode aMode) {
mMode = aMode;
// invalidate the current filter as it is working on an inval

View File

@ -6,17 +6,13 @@ import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.TextUtils.TruncateAt;
import android.util.Log;
import android.util.TypedValue;
import android.view.ContextMenu;
@ -30,7 +26,6 @@ import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.LinearLayout;
@ -41,9 +36,9 @@ import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.widget.SearchView;
import com.fsck.k9.Account;
import com.fsck.k9.Account.FolderMode;
import com.fsck.k9.AccountStats;
@ -52,7 +47,6 @@ import com.fsck.k9.FontSizes;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.R;
import com.fsck.k9.activity.FolderList.FolderListAdapter.FolderListFilter;
import com.fsck.k9.activity.misc.ActionBarNavigationSpinner;
import com.fsck.k9.activity.setup.AccountSettings;
import com.fsck.k9.activity.setup.FolderSettings;
@ -79,11 +73,6 @@ import de.cketti.library.changelog.ChangeLog;
*/
public class FolderList extends K9ListActivity implements OnNavigationListener {
/*
* Constants for showDialog() etc.
*/
private static final int DIALOG_FIND_FOLDER = 2;
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_INITIAL_FOLDER = "initialFolder";
@ -499,14 +488,6 @@ public class FolderList extends K9ListActivity implements OnNavigationListener {
}
/**
* Show an alert with an input-field for a filter-expression.
* Filter {@link #mAdapter} with the user-input.
*/
private void onEnterFilter() {
showDialog(DIALOG_FIND_FOLDER);
}
private void onEditPrefs() {
Prefs.actionPrefs(this);
}
@ -525,11 +506,6 @@ public class FolderList extends K9ListActivity implements OnNavigationListener {
MessagingController.getInstance(getApplication()).emptyTrash(account, null);
}
private void onExpunge(final Account account, String folderName) {
MessagingController.getInstance(getApplication()).expunge(account, folderName, null);
}
private void onClearFolder(Account account, String folderName) {
// There has to be a cheaper way to get at the localFolder object than this
LocalFolder localFolder = null;
@ -567,6 +543,11 @@ public class FolderList extends K9ListActivity implements OnNavigationListener {
return true;
case R.id.search:
onSearchRequested();
return true;
case R.id.compose:
MessageCompose.actionCompose(this, mAccount);
@ -587,11 +568,6 @@ public class FolderList extends K9ListActivity implements OnNavigationListener {
return true;
case R.id.filter_folders:
onEnterFilter();
return true;
case R.id.account_settings:
onEditAccount();
@ -633,6 +609,14 @@ public class FolderList extends K9ListActivity implements OnNavigationListener {
}
}
@Override
public boolean onSearchRequested() {
Bundle appData = new Bundle();
appData.putString(MessageList.EXTRA_SEARCH_ACCOUNT, mAccount.getUuid());
startSearch(null, false, appData, false);
return true;
}
private void onOpenFolder(String folder) {
LocalSearch search = new LocalSearch(folder);
search.addAccountUuid(mAccount.getUuid());
@ -649,9 +633,40 @@ public class FolderList extends K9ListActivity implements OnNavigationListener {
super.onCreateOptionsMenu(menu);
getSupportMenuInflater().inflate(R.menu.folder_list_option, menu);
mRefreshMenuItem = menu.findItem(R.id.check_mail);
configureFolderSearchView(menu);
return true;
}
private void configureFolderSearchView(Menu menu) {
final MenuItem folderMenuItem = menu.findItem(R.id.filter_folders);
final SearchView folderSearchView = (SearchView) folderMenuItem.getActionView();
folderSearchView.setQueryHint(getString(R.string.folder_list_filter_hint));
folderSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
folderMenuItem.collapseActionView();
mActionBarTitle.setText(getString(R.string.filter_folders_action));
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
mAdapter.getFilter().filter(newText);
return true;
}
});
folderSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
mActionBarTitle.setText(getString(R.string.folders_title));
return false;
}
});
}
@Override public boolean onContextItemSelected(android.view.MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item .getMenuInfo();
FolderInfoHolder folder = (FolderInfoHolder) mAdapter.getItem(info.position);
@ -671,83 +686,6 @@ public class FolderList extends K9ListActivity implements OnNavigationListener {
return super.onContextItemSelected(item);
}
private FolderInfoHolder mSelectedContextFolder = null;
@Override
public Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_FIND_FOLDER: {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.filter_folders_action);
final EditText input = new EditText(this);
input.setId(R.id.filter_folders);
input.setHint(R.string.folder_list_filter_hint);
input.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mAdapter.getFilter().filter(input.getText());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
/* not used */
}
@Override
public void afterTextChanged(Editable s) {
/* not used */
}
});
builder.setView(input);
builder.setPositiveButton(getString(R.string.okay_action),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString();
mAdapter.getFilter().filter(value);
}
});
builder.setNegativeButton(getString(R.string.cancel_action),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
mAdapter.getFilter().filter(null);
}
});
return builder.create();
}
}
return super.onCreateDialog(id);
}
@Override
public void onPrepareDialog(int id, Dialog dialog) {
switch (id) {
case DIALOG_FIND_FOLDER: {
AlertDialog alertDialog = (AlertDialog) dialog;
EditText input = (EditText) alertDialog.findViewById(R.id.filter_folders);
// Populate the EditText with the current search term
FolderListFilter filter = (FolderListFilter) mAdapter.getFilter();
input.setText(filter.getSearchTerm());
// Place the cursor at the end of the text
input.setSelection(input.getText().length());
break;
}
default: {
super.onPrepareDialog(id, dialog);
}
}
}
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
@ -1166,6 +1104,14 @@ public class FolderList extends K9ListActivity implements OnNavigationListener {
holder.chip.setBackgroundDrawable(mAccount.generateColorChip((folder.unreadMessageCount == 0 ? true : false ), false, false, false,false).drawable());
holder.folderName.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getFolderName());
if (K9.wrapFolderNames()) {
holder.folderName.setEllipsize(null);
holder.folderName.setSingleLine(false);
}
else {
holder.folderName.setEllipsize(TruncateAt.START);
holder.folderName.setSingleLine(true);
}
holder.folderStatus.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getFolderStatus());

View File

@ -60,7 +60,7 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
private static final String EXTRA_SPECIAL_FOLDER = "special_folder";
// used for remote search
private static final String EXTRA_SEARCH_ACCOUNT = "com.fsck.k9.search_account";
public static final String EXTRA_SEARCH_ACCOUNT = "com.fsck.k9.search_account";
private static final String EXTRA_SEARCH_FOLDER = "com.fsck.k9.search_folder";
public static void actionDisplaySearch(Context context, SearchSpecification search,
@ -191,7 +191,10 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
if (appData != null) {
mSearch.addAccountUuid(appData.getString(EXTRA_SEARCH_ACCOUNT));
mSearch.addAllowedFolder(appData.getString(EXTRA_SEARCH_FOLDER));
// searches started from a folder list activity will provide an account, but no folder
if (appData.getString(EXTRA_SEARCH_FOLDER) != null) {
mSearch.addAllowedFolder(appData.getString(EXTRA_SEARCH_FOLDER));
}
} else {
mSearch.addAccountUuid(LocalSearch.ALL_ACCOUNTS);
}

View File

@ -92,6 +92,7 @@ public class Prefs extends K9PreferenceActivity {
private static final String PREFERENCE_ATTACHMENT_DEF_PATH = "attachment_default_path";
private static final String PREFERENCE_BACKGROUND_AS_UNREAD_INDICATOR = "messagelist_background_as_unread_indicator";
private static final String PREFERENCE_THREADED_VIEW = "threaded_view";
private static final String PREFERENCE_FOLDERLIST_WRAP_NAME = "folderlist_wrap_folder_name";
private static final int ACTIVITY_CHOOSE_FOLDER = 1;
@ -122,6 +123,7 @@ public class Prefs extends K9PreferenceActivity {
private CheckBoxPreference mUseGalleryBugWorkaround;
private CheckBoxPreference mDebugLogging;
private CheckBoxPreference mSensitiveLogging;
private CheckBoxPreference mWrapFolderNames;
private CheckBoxPreference mQuietTimeEnabled;
private com.fsck.k9.preferences.TimePickerPreference mQuietTimeStarts;
@ -394,6 +396,9 @@ public class Prefs extends K9PreferenceActivity {
}
};
});
mWrapFolderNames = (CheckBoxPreference)findPreference(PREFERENCE_FOLDERLIST_WRAP_NAME);
mWrapFolderNames.setChecked(K9.wrapFolderNames());
mBatchButtonsMarkRead = (CheckBoxPreference)findPreference(PREFERENCE_BATCH_BUTTONS_MARK_READ);
mBatchButtonsDelete = (CheckBoxPreference)findPreference(PREFERENCE_BATCH_BUTTONS_DELETE);
@ -468,6 +473,7 @@ public class Prefs extends K9PreferenceActivity {
K9.setQuietTimeStarts(mQuietTimeStarts.getTime());
K9.setQuietTimeEnds(mQuietTimeEnds.getTime());
K9.setWrapFolderNames(mWrapFolderNames.isChecked());
if (mNotificationQuickDelete != null) {
K9.setNotificationQuickDeleteBehaviour(

View File

@ -197,6 +197,9 @@ public class GlobalSettings {
s.put("useVolumeKeysForNavigation", Settings.versions(
new V(1, new BooleanSetting(false))
));
s.put("wrapFolderNames", Settings.versions(
new V(22, new BooleanSetting(false))
));
s.put("batchButtonsMarkRead", Settings.versions(
new V(8, new BooleanSetting(true))
));

View File

@ -35,7 +35,7 @@ public class Settings {
*
* @see SettingsExporter
*/
public static final int VERSION = 21;
public static final int VERSION = 22;
public static Map<String, Object> validate(int version, Map<String,
TreeMap<Integer, SettingsDescription>> settings,