use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.
the class Preferences method updatePreference.
/**
* Code which is run when a SharedPreference change has been detected
* @param prefs instance of SharedPreferences
* @param key key in prefs which is being updated
* @param listener android.preference.PreferenceActivity of PreferenceFragment which is hosting the preference
*/
// Tracked as #5019 on github - convert to fragments
@SuppressWarnings("deprecation")
private void updatePreference(SharedPreferences prefs, String key, PreferenceContext listener) {
try {
android.preference.PreferenceScreen screen = listener.getPreferenceScreen();
android.preference.Preference pref = screen.findPreference(key);
if (pref == null) {
Timber.e("Preferences: no preference found for the key: %s", key);
return;
}
// Handle special cases
switch(key) {
case CustomSyncServer.PREFERENCE_CUSTOM_MEDIA_SYNC_URL:
case CustomSyncServer.PREFERENCE_CUSTOM_SYNC_BASE:
case CustomSyncServer.PREFERENCE_ENABLE_CUSTOM_SYNC_SERVER:
// This may be a tad hasty - performed before "back" is pressed.
CustomSyncServer.handleSyncServerPreferenceChange(getBaseContext());
break;
case "timeoutAnswer":
{
android.preference.CheckBoxPreference keepScreenOn = (android.preference.CheckBoxPreference) screen.findPreference("keepScreenOn");
keepScreenOn.setChecked(((android.preference.CheckBoxPreference) pref).isChecked());
break;
}
case LANGUAGE:
closePreferences();
break;
case "showProgress":
getCol().getConf().put("dueCounts", ((android.preference.CheckBoxPreference) pref).isChecked());
getCol().setMod();
break;
case "showEstimates":
getCol().getConf().put("estTimes", ((android.preference.CheckBoxPreference) pref).isChecked());
getCol().setMod();
break;
case "newSpread":
getCol().getConf().put("newSpread", Integer.parseInt(((android.preference.ListPreference) pref).getValue()));
getCol().setMod();
break;
case "timeLimit":
getCol().getConf().put("timeLim", ((NumberRangePreference) pref).getValue() * 60);
getCol().setMod();
break;
case "learnCutoff":
getCol().getConf().put("collapseTime", ((NumberRangePreference) pref).getValue() * 60);
getCol().setMod();
break;
case "useCurrent":
getCol().getConf().put("addToCur", "0".equals(((android.preference.ListPreference) pref).getValue()));
getCol().setMod();
break;
case "dayOffset":
{
int hours = ((SeekBarPreference) pref).getValue();
Calendar date = getCol().crtGregorianCalendar();
date.set(Calendar.HOUR_OF_DAY, hours);
getCol().setCrt(date.getTimeInMillis() / 1000);
getCol().setMod();
BootService.scheduleNotification(getCol().getTime(), this);
break;
}
case "minimumCardsDueForNotification":
{
android.preference.ListPreference listpref = (android.preference.ListPreference) screen.findPreference("minimumCardsDueForNotification");
if (listpref != null) {
updateNotificationPreference(listpref);
if (Integer.valueOf(listpref.getValue()) < PENDING_NOTIFICATIONS_ONLY) {
BootService.scheduleNotification(getCol().getTime(), this);
} else {
PendingIntent intent = PendingIntent.getBroadcast(this, 0, new Intent(this, NotificationService.class), 0);
final AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(intent);
}
}
break;
}
case AnkiDroidApp.FEEDBACK_REPORT_KEY:
{
String value = prefs.getString(AnkiDroidApp.FEEDBACK_REPORT_KEY, "");
AnkiDroidApp.getInstance().setAcraReportingMode(value);
// If the user changed error reporting, make sure future reports have a chance to post
AnkiDroidApp.deleteACRALimiterData(this);
// We also need to re-chain our UncaughtExceptionHandlers
UsageAnalytics.reInitialize();
break;
}
case "syncAccount":
{
SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(getBaseContext());
String username = preferences.getString("username", "");
android.preference.Preference syncAccount = screen.findPreference("syncAccount");
if (syncAccount != null) {
if (TextUtils.isEmpty(username)) {
syncAccount.setSummary(R.string.sync_account_summ_logged_out);
} else {
syncAccount.setSummary(getString(R.string.sync_account_summ_logged_in, username));
}
}
break;
}
case "providerEnabled":
{
ComponentName providerName = new ComponentName(this, "com.ichi2.anki.provider.CardContentProvider");
PackageManager pm = getPackageManager();
int state;
if (((android.preference.CheckBoxPreference) pref).isChecked()) {
state = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
Timber.i("AnkiDroid ContentProvider enabled by user");
} else {
state = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
Timber.i("AnkiDroid ContentProvider disabled by user");
}
pm.setComponentEnabledSetting(providerName, state, PackageManager.DONT_KILL_APP);
break;
}
case "schedVer":
{
boolean wantNew = ((android.preference.CheckBoxPreference) pref).isChecked();
boolean haveNew = getCol().schedVer() == 2;
// northing to do?
if (haveNew == wantNew) {
break;
}
MaterialDialog.Builder builder = new MaterialDialog.Builder(this);
if (haveNew && !wantNew) {
// Going back to V1
builder.title(R.string.sched_ver_toggle_title);
builder.content(R.string.sched_ver_2to1);
builder.onPositive((dialog, which) -> {
getCol().modSchemaNoCheck();
try {
getCol().changeSchedulerVer(1);
((android.preference.CheckBoxPreference) pref).setChecked(false);
} catch (ConfirmModSchemaException e2) {
// This should never be reached as we explicitly called modSchemaNoCheck()
throw new RuntimeException(e2);
}
});
builder.onNegative((dialog, which) -> {
((android.preference.CheckBoxPreference) pref).setChecked(true);
});
builder.positiveText(R.string.dialog_ok);
builder.negativeText(R.string.dialog_cancel);
builder.show();
break;
}
// Going to V2
builder.title(R.string.sched_ver_toggle_title);
builder.content(R.string.sched_ver_1to2);
builder.onPositive((dialog, which) -> {
getCol().modSchemaNoCheck();
try {
getCol().changeSchedulerVer(2);
((android.preference.CheckBoxPreference) pref).setChecked(true);
} catch (ConfirmModSchemaException e2) {
// This should never be reached as we explicitly called modSchemaNoCheck()
throw new RuntimeException(e2);
}
});
builder.onNegative((dialog, which) -> {
((android.preference.CheckBoxPreference) pref).setChecked(false);
});
builder.positiveText(R.string.dialog_ok);
builder.negativeText(R.string.dialog_cancel);
builder.show();
break;
}
case CardBrowserContextMenu.CARD_BROWSER_CONTEXT_MENU_PREF_KEY:
CardBrowserContextMenu.ensureConsistentStateWithSharedPreferences(this);
break;
case AnkiCardContextMenu.ANKI_CARD_CONTEXT_MENU_PREF_KEY:
AnkiCardContextMenu.ensureConsistentStateWithSharedPreferences(this);
break;
}
// Update the summary text to reflect new value
updateSummary(pref);
} catch (BadTokenException e) {
Timber.e(e, "Preferences: BadTokenException on showDialog");
} catch (NumberFormatException e) {
throw new RuntimeException(e);
}
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.
the class StudyOptionsFragment method getCollectionTaskListener.
/**
* Returns a listener that rebuilds the interface after execute.
*
* @param refreshDecklist If true, the listener notifies the parent activity to update its deck list
* to reflect the latest values.
*/
private TaskListener getCollectionTaskListener(final boolean refreshDecklist) {
return new TaskListener() {
@Override
public void onPreExecute() {
}
@Override
public void onPostExecute(TaskData result) {
dismissProgressDialog();
if (result != null) {
// Get the return values back from the AsyncTask
Object[] obj = result.getObjArray();
int newCards = (Integer) obj[0];
int lrnCards = (Integer) obj[1];
int revCards = (Integer) obj[1] + (Integer) obj[2];
int totalNew = (Integer) obj[3];
int totalCards = (Integer) obj[4];
Timber.i("start refresh list data:" + newCards + "," + lrnCards + "," + revCards + "," + totalNew + "," + totalCards);
// Don't do anything if the fragment is no longer attached to it's Activity or col has been closed
if (getActivity() == null) {
Timber.e("StudyOptionsFragment.mRefreshFragmentListener :: can't refresh");
return;
}
// #5506 If we have no view, short circuit all UI logic
if (mStudyOptionsView == null) {
tryOpenCramDeckOptions();
return;
}
// Reinitialize controls incase changed to filtered deck
initAllContentViews(mStudyOptionsView);
// Set the deck name
String fullName;
Deck deck = getCol().getDecks().current();
// Main deck name
fullName = deck.getString("name");
String[] name = Decks.path(fullName);
StringBuilder nameBuilder = new StringBuilder();
if (name.length > 0) {
nameBuilder.append(name[name.length - 1]);
}
// if (name.length > 1) {
// nameBuilder.append("\n").append(name[1]);
// }
// if (name.length > 3) {
// nameBuilder.append("...");
// }
// if (name.length > 2) {
// nameBuilder.append("\n").append(name[name.length - 1]);
// }
// mTextDeckName.setText(nameBuilder.toString());
mDeckListAdapter.mTextDeckName = nameBuilder.toString();
if (tryOpenCramDeckOptions()) {
return;
}
// Switch between the empty view, the ordinary view, and the "congratulations" view
boolean isDynamic = deck.optInt("dyn", 0) != 0;
if (totalCards == 0 && !isDynamic) {
mCurrentContentView = CONTENT_EMPTY;
mDeckListAdapter.mDeckInfoLayoutVisible = View.VISIBLE;
mDeckListAdapter.mTextCongratsMessageVisible = View.VISIBLE;
// mDeckListAdapter.mTextCongratsMessage=getString(R.string.studyoptions_empty);
mDeckListAdapter.mButtonStartEnable = false;
mDeckListAdapter.mTextButtonStart = getString(R.string.studyoptions_start);
} else if (newCards + lrnCards + revCards == 0) {
mCurrentContentView = CONTENT_CONGRATS;
if (!isDynamic) {
mDeckListAdapter.mDeckInfoLayoutVisible = View.GONE;
mDeckListAdapter.mButtonStartEnable = true;
mDeckListAdapter.mTextButtonStart = getString(R.string.add_today_study_amount);
} else {
mDeckListAdapter.mButtonStartEnable = true;
mDeckListAdapter.mTextButtonStart = getString(R.string.add_today_study_amount);
}
mDeckListAdapter.mTextCongratsMessageVisible = View.VISIBLE;
// mDeckListAdapter.mTextCongratsMessage=getCol().getSched().finishedMsg(getActivity()).toString();
// mTextCongratsMessage.setText(getCol().getSched().finishedMsg(getActivity()));
} else {
mCurrentContentView = CONTENT_STUDY_OPTIONS;
mDeckListAdapter.mDeckInfoLayoutVisible = View.VISIBLE;
mDeckListAdapter.mTextCongratsMessageVisible = View.GONE;
mDeckListAdapter.mButtonStartEnable = true;
mDeckListAdapter.mTextButtonStart = getString(R.string.studyoptions_start);
}
mDeckListAdapter.setButtonStartClickListener(mButtonClickListener);
mDeckListAdapter.setSelfStudyClickListener(mSelfStudyListener);
// Set deck description
String desc;
if (isDynamic) {
desc = getResources().getString(R.string.dyn_deck_desc);
} else {
desc = "";
// desc = getCol().getDecks().getActualDescription();
}
if (desc.length() > 0) {
mDeckListAdapter.mTextDeckDescription = desc;
mDeckListAdapter.mTextDeckDescriptionVisible = View.VISIBLE;
// mTextDeckDescription.setText(formatDescription(desc));
// mTextDeckDescription.setVisibility(View.VISIBLE);
} else {
mDeckListAdapter.mTextDeckDescriptionVisible = View.GONE;
}
// Set new/learn/review card counts
mDeckListAdapter.mTextTodayNew = String.valueOf(newCards);
mDeckListAdapter.mTextTodayRev = String.valueOf(revCards);
// Set the total number of new cards in deck
if (totalNew < NEW_CARD_COUNT_TRUNCATE_THRESHOLD) {
// if it hasn't been truncated by libanki then just set it usually
// mTextNewTotal.setText(String.valueOf(totalNew));
} else {
// mTextNewTotal.setText(">1000");
if (mFullNewCountThread != null) {
// a thread was previously made -- interrupt it
mFullNewCountThread.interrupt();
}
// mFullNewCountThread = new Thread(() -> {
// Collection collection = getCol();
// TODO: refactor code to not rewrite this query, add to Sched.totalNewForCurrentDeck()
// String query = "SELECT count(*) FROM cards WHERE did IN " +
// Utils.ids2str(collection.getDecks().active()) +
// " AND queue = " + Consts.QUEUE_TYPE_NEW;
// final int fullNewCount = collection.getDb().queryScalar(query);
// if (fullNewCount > 0) {
// Runnable setNewTotalText = new Runnable() {
// @Override
// public void run() {
// mTextNewTotal.setText(String.valueOf(fullNewCount));
// }
// };
// if (!Thread.currentThread().isInterrupted()) {
// mTextNewTotal.post(setNewTotalText);
// }
// }
// });
// mFullNewCountThread.start();
}
// Set total number of cards
// mTextTotal.setText(String.valueOf(totalCards));
double[] data = calculateStat(getCol(), getCol().getDecks().current().optLong("id"));
mNewCardsNum = (int) data[2];
mRevCardsNum = revCards;
mShouldConfigBeforeStudy = mNewCardsNum == totalCards && mShouldConfigBeforeStudy;
int hardNum = getLapses(getCol(), getCol().getDecks().current().optLong("id"));
mDeckListAdapter.mTextCountHandled = String.format(Locale.CHINA, "%d", (int) data[0]);
mDeckListAdapter.mTextCountLearning = String.format(Locale.CHINA, "%d", (int) data[1]);
mDeckListAdapter.mTextCountNew = String.format(Locale.CHINA, "%d", (int) data[2]);
mDeckListAdapter.mTextCountHard = String.format(Locale.CHINA, "%d", hardNum);
mDeckListAdapter.mTextTotal = String.format(Locale.CHINA, "共%d张卡牌", totalCards);
double percent = 0;
if (data[2] == 0) {
// 新卡已学完,显示已掌握
percent = (data[0] + data[1] + data[2] <= 0) ? 0 : (data[0] / (data[0] + data[1] + data[2]) * 100);
mDeckListAdapter.mTextHandledNum = String.format(Locale.CHINA, "%.0f/%.0f", data[0], (data[0] + data[1] + data[2]));
// holder.handled_percent.setText((String.format(Locale.CHINA, "已掌握 %.1f", percent)) + "%");
} else {
percent = (data[0] + data[1] + data[2] <= 0) ? 0 : ((data[0] + data[1]) / (data[0] + data[1] + data[2]) * 100);
mDeckListAdapter.mTextHandledNum = String.format(Locale.CHINA, "%.0f/%.0f", data[0] + data[1], data[0] + data[1] + data[2]);
// holder.handled_percent.setText((String.format(Locale.CHINA, "已学 %.1f", percent)) + "%");
}
// double percent = (data[0] + data[1] + data[2] <= 0) ? 0 : (data[0] / (data[0] + data[1] + data[2]) * 100);
// mStudyProgress.setMax(100*100);
mDeckListAdapter.mStudyProgress = (int) (percent * 100);
mDeckListAdapter.mTextHandledPercent = (String.format(Locale.CHINA, data[2] == 0 ? "已掌握 %.1f" : "已学 %.1f", percent)) + "%";
// Set estimated time remaining
int eta = (newCards + revCards) * 10 / 60;
if ((newCards + revCards) % 60 != 0) {
eta++;
}
if (eta != -1) {
mDeckListAdapter.mTextETA = "" + eta;
} else {
mDeckListAdapter.mTextETA = "-";
}
mDeckListAdapter.notifyDataSetChangedAll();
// Rebuild the options menu
configureToolbar();
}
updateDeckList();
// If in fragmented mode, refresh the deck list
if (mFragmented && refreshDecklist) {
mListener.onRequireDeckListUpdate();
}
}
};
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.
the class SelfStudyActivity method updateCardsInList.
/**
* @param cards Cards that were changed
* @param updatedCardTags Mapping note id -> updated tags
*/
private void updateCardsInList(List<Card> cards, Map<Long, String> updatedCardTags) {
List<CardCache> cardList = getCards();
Map<Long, Integer> idToPos = getPositionMap(cardList);
for (Card c : cards) {
// get position in the mCards search results HashMap
Integer pos = idToPos.get(c.getId());
if (pos == null || pos >= getCardCount()) {
continue;
}
// update Q & A etc
cardList.get(pos).load(true, 0, 1);
}
updateList();
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.
the class SelfStudyActivity method onActivityResult.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// FIXME:
Timber.d("onActivityResult(requestCode=%d, resultCode=%d)", requestCode, resultCode);
if (data != null) {
Timber.d("onActivityResult data (reloadRequired=%s, noteChanged=%s)", data.getBooleanExtra("reloadRequired", false), data.getBooleanExtra("noteChanged", false));
}
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == DeckPicker.RESULT_DB_ERROR) {
closeCardBrowser(DeckPicker.RESULT_DB_ERROR);
}
if (requestCode == EDIT_CARD && resultCode != RESULT_CANCELED) {
Timber.i("CardBrowser:: CardBrowser: Saving card...");
CollectionTask.launchCollectionTask(UPDATE_NOTE, updateCardHandler(), new TaskData(sCardBrowserCard, false));
} else if (requestCode == ADD_NOTE && resultCode == RESULT_OK) {
if (mSearchView != null) {
mSearchTerms = mSearchView.getQuery().toString();
searchCards();
} else {
Timber.w("Note was added from browser and on return mSearchView == null");
}
}
// }
if (requestCode == PREVIEW_CARDS && data != null && (data.getBooleanExtra("reloadRequired", false) || data.getBooleanExtra("noteChanged", false))) {
searchCards();
if (getReviewerCardId() == mCurrentCardId) {
mReloadRequired = true;
}
}
if (requestCode == EDIT_CARD && data != null && (data.getBooleanExtra("reloadRequired", false) || data.getBooleanExtra("noteChanged", false))) {
// if reloadRequired or noteChanged flag was sent from note editor then reload card list
searchCards();
// in use by reviewer?
if (getReviewerCardId() == mCurrentCardId) {
mReloadRequired = true;
}
}
// maybe the availability of undo changed
invalidateOptionsMenu();
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.
the class CardContentProvider method addModelToCursor.
private void addModelToCursor(Long modelId, Models models, MatrixCursor rv, String[] columns) {
Model jsonObject = models.get(modelId);
MatrixCursor.RowBuilder rb = rv.newRow();
try {
for (String column : columns) {
if (column.equals(FlashCardsContract.Model._ID)) {
rb.add(modelId);
} else if (column.equals(FlashCardsContract.Model.NAME)) {
rb.add(jsonObject.getString("name"));
} else if (column.equals(FlashCardsContract.Model.FIELD_NAMES)) {
JSONArray flds = jsonObject.getJSONArray("flds");
String[] allFlds = new String[flds.length()];
for (int idx = 0; idx < flds.length(); idx++) {
allFlds[idx] = flds.getJSONObject(idx).optString("name", "");
}
rb.add(Utils.joinFields(allFlds));
} else if (column.equals(FlashCardsContract.Model.NUM_CARDS)) {
rb.add(jsonObject.getJSONArray("tmpls").length());
} else if (column.equals(FlashCardsContract.Model.CSS)) {
rb.add(jsonObject.getString("css"));
} else if (column.equals(FlashCardsContract.Model.DECK_ID)) {
// #6378 - Anki Desktop changed schema temporarily to allow null
rb.add(jsonObject.optLong("did", Consts.DEFAULT_DECK_ID));
} else if (column.equals(FlashCardsContract.Model.SORT_FIELD_INDEX)) {
rb.add(jsonObject.getLong("sortf"));
} else if (column.equals(FlashCardsContract.Model.TYPE)) {
rb.add(jsonObject.getLong("type"));
} else if (column.equals(FlashCardsContract.Model.LATEX_POST)) {
rb.add(jsonObject.getString("latexPost"));
} else if (column.equals(FlashCardsContract.Model.LATEX_PRE)) {
rb.add(jsonObject.getString("latexPre"));
} else if (column.equals(FlashCardsContract.Model.NOTE_COUNT)) {
rb.add(models.useCount(jsonObject));
} else {
throw new UnsupportedOperationException("Column \"" + column + "\" is unknown");
}
}
} catch (JSONException e) {
Timber.e(e, "Error parsing JSONArray");
throw new IllegalArgumentException("Model " + modelId + " is malformed", e);
}
}
Aggregations