protected void cacheValues() { Timber.i("DeckOptions - CacheValues"); try { mOptions = mCol.getDecks().confForDid(mDeck.getLong("id")); mValues.put("name", mDeck.getString("name")); mValues.put("desc", mDeck.getString("desc")); mValues.put("deckConf", mDeck.getString("conf")); // general mValues.put("maxAnswerTime", mOptions.getString("maxTaken")); mValues.put("showAnswerTimer", Boolean.toString(mOptions.getInt("timer") == 1)); mValues.put("autoPlayAudio", Boolean.toString(mOptions.getBoolean("autoplay"))); mValues.put("replayQuestion", Boolean.toString(mOptions.getBoolean("replayq"))); // new JSONObject newOptions = mOptions.getJSONObject("new"); mValues.put("newSteps", StepsPreference.convertFromJSON(newOptions.getJSONArray("delays"))); mValues.put("newGradIvl", newOptions.getJSONArray("ints").getString(0)); mValues.put("newEasy", newOptions.getJSONArray("ints").getString(1)); mValues.put("newFactor", Integer.toString(newOptions.getInt("initialFactor") / 10)); mValues.put("newOrder", newOptions.getString("order")); mValues.put("newPerDay", newOptions.getString("perDay")); mValues.put("newBury", Boolean.toString(newOptions.optBoolean("bury", true))); // rev JSONObject revOptions = mOptions.getJSONObject("rev"); mValues.put("revPerDay", revOptions.getString("perDay")); mValues.put("easyBonus", Integer.toString((int) (revOptions.getDouble("ease4") * 100))); mValues.put("revIvlFct", Integer.toString((int) (revOptions.getDouble("ivlFct") * 100))); mValues.put("revMaxIvl", revOptions.getString("maxIvl")); mValues.put("revBury", Boolean.toString(revOptions.optBoolean("bury", true))); // lapse JSONObject lapOptions = mOptions.getJSONObject("lapse"); mValues.put("lapSteps", StepsPreference.convertFromJSON(lapOptions.getJSONArray("delays"))); mValues.put("lapNewIvl", Integer.toString((int) (lapOptions.getDouble("mult") * 100))); mValues.put("lapMinIvl", lapOptions.getString("minInt")); mValues.put("lapLeechThres", lapOptions.getString("leechFails")); mValues.put("lapLeechAct", lapOptions.getString("leechAction")); // options group management mValues.put( "currentConf", mCol.getDecks().getConf(mDeck.getLong("conf")).getString("name")); } catch (JSONException e) { addMissingValues(); finish(); } }
@Override public boolean commit() { Timber.d("DeckOptions - commit() changes back to database"); try { for (Entry<String, Object> entry : mUpdate.valueSet()) { String key = entry.getKey(); Object value = entry.getValue(); Timber.i("Change value for key '" + key + "': " + value); if (key.equals("maxAnswerTime")) { mOptions.put("maxTaken", (Integer) value); } else if (key.equals("newFactor")) { mOptions.getJSONObject("new").put("initialFactor", (Integer) value * 10); } else if (key.equals("newOrder")) { int newValue = Integer.parseInt((String) value); // Sorting is slow, so only do it if we change order int oldValue = mOptions.getJSONObject("new").getInt("order"); if (oldValue != newValue) { mOptions.getJSONObject("new").put("order", newValue); DeckTask.launchDeckTask( DeckTask.TASK_TYPE_REORDER, mConfChangeHandler, new DeckTask.TaskData(new Object[] {mOptions})); } mOptions.getJSONObject("new").put("order", Integer.parseInt((String) value)); } else if (key.equals("newPerDay")) { mOptions.getJSONObject("new").put("perDay", (Integer) value); } else if (key.equals("newGradIvl")) { JSONArray ja = new JSONArray(); // [graduating, easy] ja.put((Integer) value); ja.put(mOptions.getJSONObject("new").getJSONArray("ints").get(1)); mOptions.getJSONObject("new").put("ints", ja); } else if (key.equals("newEasy")) { JSONArray ja = new JSONArray(); // [graduating, easy] ja.put(mOptions.getJSONObject("new").getJSONArray("ints").get(0)); ja.put((Integer) value); mOptions.getJSONObject("new").put("ints", ja); } else if (key.equals("newBury")) { mOptions.getJSONObject("new").put("bury", (Boolean) value); } else if (key.equals("revPerDay")) { mOptions.getJSONObject("rev").put("perDay", (Integer) value); } else if (key.equals("easyBonus")) { mOptions.getJSONObject("rev").put("ease4", (Integer) value / 100.0f); } else if (key.equals("revIvlFct")) { mOptions.getJSONObject("rev").put("ivlFct", (Integer) value / 100.0f); } else if (key.equals("revMaxIvl")) { mOptions.getJSONObject("rev").put("maxIvl", (Integer) value); } else if (key.equals("revBury")) { mOptions.getJSONObject("rev").put("bury", (Boolean) value); } else if (key.equals("lapMinIvl")) { mOptions.getJSONObject("lapse").put("minInt", (Integer) value); } else if (key.equals("lapLeechThres")) { mOptions.getJSONObject("lapse").put("leechFails", (Integer) value); } else if (key.equals("lapLeechAct")) { mOptions.getJSONObject("lapse").put("leechAction", Integer.parseInt((String) value)); } else if (key.equals("lapNewIvl")) { mOptions.getJSONObject("lapse").put("mult", (Integer) value / 100.0f); } else if (key.equals("showAnswerTimer")) { mOptions.put("timer", (Boolean) value ? 1 : 0); } else if (key.equals("autoPlayAudio")) { mOptions.put("autoplay", (Boolean) value); } else if (key.equals("replayQuestion")) { mOptions.put("replayq", (Boolean) value); } else if (key.equals("desc")) { mDeck.put("desc", (String) value); mCol.getDecks().save(mDeck); } else if (key.equals("newSteps")) { mOptions .getJSONObject("new") .put("delays", StepsPreference.convertToJSON((String) value)); } else if (key.equals("lapSteps")) { mOptions .getJSONObject("lapse") .put("delays", StepsPreference.convertToJSON((String) value)); } else if (key.equals("deckConf")) { long newConfId = Long.parseLong((String) value); mOptions = mCol.getDecks().getConf(newConfId); DeckTask.launchDeckTask( DeckTask.TASK_TYPE_CONF_CHANGE, mConfChangeHandler, new DeckTask.TaskData(new Object[] {mDeck, mOptions})); // Restart to reflect the new preference values restartActivity(); } else if (key.equals("confRename")) { String newName = (String) value; if (!TextUtils.isEmpty(newName)) { mOptions.put("name", newName); } } else if (key.equals("confReset")) { if ((Boolean) value) { DeckTask.launchDeckTask( DeckTask.TASK_TYPE_CONF_RESET, mConfChangeHandler, new DeckTask.TaskData(new Object[] {mOptions})); } } else if (key.equals("confAdd")) { String newName = (String) value; if (!TextUtils.isEmpty(newName)) { // New config clones current config long id = mCol.getDecks().confId(newName, mOptions.toString()); mDeck.put("conf", id); mCol.getDecks().save(mDeck); } } else if (key.equals("confRemove")) { if (mOptions.getLong("id") == 1) { // Don't remove the options group if it's the default group Themes.showThemedToast( DeckOptions.this, getResources().getString(R.string.default_conf_delete_error), false); } else { // Remove options group, handling the case where the user needs to confirm full sync try { remConf(); } catch (ConfirmModSchemaException e) { // Libanki determined that a full sync will be required, so confirm with the user // before proceeding // TODO : Use ConfirmationDialog DialogFragment -- not compatible with // PreferenceActivity new MaterialDialog.Builder(DeckOptions.this) .content(R.string.full_sync_confirmation) .positiveText(R.string.dialog_ok) .negativeText(R.string.dialog_cancel) .callback( new MaterialDialog.ButtonCallback() { @Override public void onPositive(MaterialDialog dialog) { mCol.modSchemaNoCheck(); try { remConf(); } catch (ConfirmModSchemaException e) { // This should never be reached as we just forced modSchema throw new RuntimeException(e); } } }) .build() .show(); } } } else if (key.equals("confSetSubdecks")) { if ((Boolean) value) { DeckTask.launchDeckTask( DeckTask.TASK_TYPE_CONF_SET_SUBDECKS, mConfChangeHandler, new DeckTask.TaskData(new Object[] {mDeck, mOptions})); } } } } catch (JSONException e) { throw new RuntimeException(e); } // save conf try { mCol.getDecks().save(mOptions); } catch (RuntimeException e) { Timber.e("DeckOptions - RuntimeException on saving conf: " + e); AnkiDroidApp.sendExceptionReport(e, "DeckOptionsSaveConf"); setResult(DeckPicker.RESULT_DB_ERROR); finish(); } // make sure we refresh the parent cached values cacheValues(); buildLists(); updateSummaries(); // and update any listeners for (OnSharedPreferenceChangeListener listener : listeners) { listener.onSharedPreferenceChanged(DeckPreferenceHack.this, null); } return true; }