use of com.ichi2.anki.CardBrowser.Column.ANSWER in project AnkiChinaAndroid by ankichinateam.
the class Preferences method initSubscreen.
private void initSubscreen(String action, PreferenceContext listener) {
android.preference.PreferenceScreen screen;
switch(action) {
case "com.ichi2.anki.prefs.general":
listener.addPreferencesFromResource(R.xml.preferences_general);
screen = listener.getPreferenceScreen();
if (AdaptionUtil.isRestrictedLearningDevice()) {
android.preference.CheckBoxPreference mCheckBoxPref_Vibrate = (android.preference.CheckBoxPreference) screen.findPreference("widgetVibrate");
android.preference.CheckBoxPreference mCheckBoxPref_Blink = (android.preference.CheckBoxPreference) screen.findPreference("widgetBlink");
android.preference.PreferenceCategory mCategory = (android.preference.PreferenceCategory) screen.findPreference("category_general_notification_pref");
mCategory.removePreference(mCheckBoxPref_Vibrate);
mCategory.removePreference(mCheckBoxPref_Blink);
}
// Build languages
initializeLanguageDialog(screen);
break;
case "com.ichi2.anki.prefs.reviewing":
listener.addPreferencesFromResource(R.xml.preferences_reviewing);
screen = listener.getPreferenceScreen();
// Show error toast if the user tries to disable answer button without gestures on
// android.preference.ListPreference fullscreenPreference = (android.preference.ListPreference)
// screen.findPreference("fullscreenMode");
// fullscreenPreference.setOnPreferenceChangeListener((preference, newValue) -> {
// SharedPreferences prefs = AnkiDroidApp.getSharedPrefs(Preferences.this);
// if (prefs.getBoolean("gestures", false) || !"2".equals(newValue)) {
// return true;
// } else {
// Toast.makeText(getApplicationContext(),
// R.string.full_screen_error_gestures, Toast.LENGTH_LONG).show();
// return false;
// }
// });
// Custom buttons options
android.preference.Preference customButtonsPreference = screen.findPreference("custom_buttons_link");
customButtonsPreference.setOnPreferenceClickListener(preference -> {
Intent i = getPreferenceSubscreenIntent(Preferences.this, "com.ichi2.anki.prefs.custom_buttons");
startActivity(i);
return true;
});
break;
case "com.ichi2.anki.prefs.appearance":
listener.addPreferencesFromResource(R.xml.preferences_appearance);
screen = listener.getPreferenceScreen();
backgroundImage = (android.preference.CheckBoxPreference) screen.findPreference("deckPickerBackground");
backgroundImage.setOnPreferenceClickListener(preference -> {
if (backgroundImage.isChecked()) {
try {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
backgroundImage.setChecked(true);
} catch (Exception ex) {
Timber.e("%s", ex.getLocalizedMessage());
}
} else {
backgroundImage.setChecked(false);
String currentAnkiDroidDirectory = CollectionHelper.getCurrentAnkiDroidDirectory(this);
File imgFile = new File(currentAnkiDroidDirectory, "DeckPickerBackground.png");
if (imgFile.exists()) {
if (imgFile.delete()) {
UIUtils.showThemedToast(this, getString(R.string.background_image_removed), false);
} else {
UIUtils.showThemedToast(this, getString(R.string.error_deleting_image), false);
}
} else {
UIUtils.showThemedToast(this, getString(R.string.background_image_removed), false);
}
}
return true;
});
initializeCustomFontsDialog(screen);
break;
case "com.ichi2.anki.prefs.gestures":
listener.addPreferencesFromResource(R.xml.preferences_gestures);
break;
case "com.ichi2.anki.prefs.custom_controller_buttons":
getSupportActionBar().setTitle(R.string.pref_cat_controller);
listener.addPreferencesFromResource(R.xml.preferences_custom_controller_buttons);
break;
case "com.ichi2.anki.prefs.custom_buttons":
getSupportActionBar().setTitle(R.string.custom_buttons);
listener.addPreferencesFromResource(R.xml.preferences_custom_buttons);
screen = listener.getPreferenceScreen();
// Reset toolbar button customizations
android.preference.Preference reset_custom_buttons = screen.findPreference("reset_custom_buttons");
reset_custom_buttons.setOnPreferenceClickListener(preference -> {
SharedPreferences.Editor edit = AnkiDroidApp.getSharedPrefs(getBaseContext()).edit();
edit.remove("customButtonUndo");
edit.remove("customButtonScheduleCard");
edit.remove("customButtonMarkCard");
edit.remove("customButtonEditCard");
edit.remove("customButtonAddCard");
edit.remove("customButtonReplay");
edit.remove("customButtonSelectTts");
edit.remove("customButtonDeckOptions");
edit.remove("customButtonBury");
edit.remove("customButtonSuspend");
edit.remove("customButtonFlag");
edit.remove("customButtonDelete");
edit.remove("customButtonClearWhiteboard");
edit.remove("customButtonShowHideWhiteboard");
edit.apply();
// TODO: Should reload the preferences screen on completion
return true;
});
break;
case "com.ichi2.anki.prefs.advanced":
listener.addPreferencesFromResource(R.xml.preferences_advanced);
screen = listener.getPreferenceScreen();
// Check that input is valid before committing change in the collection path
android.preference.EditTextPreference collectionPathPreference = (android.preference.EditTextPreference) screen.findPreference("deckPath");
collectionPathPreference.setOnPreferenceChangeListener((preference, newValue) -> {
final String newPath = (String) newValue;
try {
CollectionHelper.initializeAnkiDroidDirectory(newPath);
return true;
} catch (StorageAccessException e) {
Timber.e(e, "Could not initialize directory: %s", newPath);
Toast.makeText(getApplicationContext(), R.string.dialog_collection_path_not_dir, Toast.LENGTH_LONG).show();
return false;
}
});
// Custom sync server option
// android.preference.Preference customSyncServerPreference = screen.findPreference("custom_sync_server_link");
// customSyncServerPreference.setOnPreferenceClickListener(preference -> {
// Intent i = getPreferenceSubscreenIntent(Preferences.this,
// "com.ichi2.anki.prefs.custom_sync_server");
// startActivity(i);
// return true;
// });
// Advanced statistics option
android.preference.Preference advancedStatisticsPreference = screen.findPreference("advanced_statistics_link");
advancedStatisticsPreference.setOnPreferenceClickListener(preference -> {
Intent i = getPreferenceSubscreenIntent(Preferences.this, "com.ichi2.anki.prefs.advanced_statistics");
startActivity(i);
return true;
});
setupContextMenuPreference(screen, CardBrowserContextMenu.CARD_BROWSER_CONTEXT_MENU_PREF_KEY, R.string.card_browser_context_menu);
setupContextMenuPreference(screen, AnkiCardContextMenu.ANKI_CARD_CONTEXT_MENU_PREF_KEY, R.string.context_menu_anki_card_label);
// Make it possible to test crash reporting, but only for DEBUG builds
if (BuildConfig.DEBUG && !AdaptionUtil.isUserATestClient()) {
Timber.i("Debug mode, allowing for test crashes");
android.preference.Preference triggerTestCrashPreference = new android.preference.Preference(this);
triggerTestCrashPreference.setKey("trigger_crash_preference");
triggerTestCrashPreference.setTitle("Trigger test crash");
triggerTestCrashPreference.setSummary("Touch here for an immediate test crash");
triggerTestCrashPreference.setOnPreferenceClickListener(preference -> {
Timber.w("Crash triggered on purpose from advanced preferences in debug mode");
throw new RuntimeException("This is a test crash");
});
screen.addPreference(triggerTestCrashPreference);
}
// Make it possible to test analytics, but only for DEBUG builds
if (BuildConfig.DEBUG) {
Timber.i("Debug mode, allowing for dynamic analytics config");
android.preference.Preference analyticsDebugMode = new android.preference.Preference(this);
analyticsDebugMode.setKey("analytics_debug_preference");
analyticsDebugMode.setTitle("Switch Analytics to dev mode");
analyticsDebugMode.setSummary("Touch here to use Analytics dev tag and 100% sample rate");
analyticsDebugMode.setOnPreferenceClickListener(preference -> {
UsageAnalytics.setDevMode();
return true;
});
screen.addPreference(analyticsDebugMode);
}
if (BuildConfig.DEBUG) {
Timber.i("Debug mode, allowing database lock preference");
android.preference.Preference lockDbPreference = new android.preference.Preference(this);
lockDbPreference.setKey("debug_lock_database");
lockDbPreference.setTitle("Lock Database");
lockDbPreference.setSummary("Touch here to lock the database (all threads block in-process, exception if using second process)");
lockDbPreference.setOnPreferenceClickListener(preference -> {
DatabaseLock.engage(this);
return true;
});
screen.addPreference(lockDbPreference);
}
// Force full sync option
ConfirmationPreference fullSyncPreference = (ConfirmationPreference) screen.findPreference("force_full_sync");
fullSyncPreference.setDialogMessage(R.string.force_full_sync_summary);
fullSyncPreference.setDialogTitle(R.string.force_full_sync_title);
fullSyncPreference.setOkHandler(() -> {
if (getCol() == null) {
Toast.makeText(getApplicationContext(), R.string.directory_inaccessible, Toast.LENGTH_LONG).show();
return;
}
getCol().modSchemaNoCheck();
getCol().setMod();
Toast.makeText(getApplicationContext(), android.R.string.ok, Toast.LENGTH_SHORT).show();
});
// Workaround preferences
removeUnnecessaryAdvancedPrefs(screen);
addThirdPartyAppsListener(screen);
break;
case "com.ichi2.anki.prefs.custom_sync_server":
getSupportActionBar().setTitle(R.string.custom_sync_server_title);
listener.addPreferencesFromResource(R.xml.preferences_custom_sync_server);
screen = listener.getPreferenceScreen();
android.preference.Preference syncUrlPreference = screen.findPreference("syncBaseUrl");
android.preference.Preference mSyncUrlPreference = screen.findPreference("syncMediaUrl");
syncUrlPreference.setOnPreferenceChangeListener((android.preference.Preference preference, Object newValue) -> {
String newUrl = newValue.toString();
if (!URLUtil.isValidUrl(newUrl)) {
new AlertDialog.Builder(this).setTitle(R.string.custom_sync_server_base_url_invalid).setPositiveButton(R.string.dialog_ok, null).show();
return false;
}
return true;
});
mSyncUrlPreference.setOnPreferenceChangeListener((android.preference.Preference preference, Object newValue) -> {
String newUrl = newValue.toString();
if (!URLUtil.isValidUrl(newUrl)) {
new AlertDialog.Builder(this).setTitle(R.string.custom_sync_server_media_url_invalid).setPositiveButton(R.string.dialog_ok, null).show();
return false;
}
return true;
});
break;
case "com.ichi2.anki.prefs.advanced_statistics":
getSupportActionBar().setTitle(R.string.advanced_statistics_title);
listener.addPreferencesFromResource(R.xml.preferences_advanced_statistics);
break;
}
}
use of com.ichi2.anki.CardBrowser.Column.ANSWER in project AnkiChinaAndroid by ankichinateam.
the class CardBrowser method onCollectionLoaded.
// Finish initializing the activity after the collection has been correctly loaded
@Override
protected void onCollectionLoaded(Collection col) {
super.onCollectionLoaded(col);
Timber.d("onCollectionLoaded()");
registerExternalStorageListener();
SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(getBaseContext());
// Load reference to action bar title
mActionBarTitle = (TextView) findViewById(R.id.toolbar_title);
// Add drop-down menu to select deck to action bar.
mDropDownDecks = getCol().getDecks().allSorted();
mDropDownAdapter = new DeckDropDownAdapter(this, mDropDownDecks, R.layout.dropdown_deck_selected_item, this);
Toolbar toolbar = findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
// enable ActionBar app icon to behave as action to toggle nav drawer
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
// Decide which action to take when the navigation button is tapped.
toolbar.setNavigationOnClickListener(v -> finishActivityWithFade(this, ActivityTransitionAnimation.RIGHT));
}
ActionBar mActionBar = getSupportActionBar();
if (mActionBar != null) {
mActionBar.setDisplayShowTitleEnabled(false);
}
mActionBarSpinner = (Spinner) findViewById(R.id.toolbar_spinner);
mActionBarSpinner.setAdapter(mDropDownAdapter);
mActionBarSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
deckDropDownItemChanged(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// do nothing
}
});
mActionBarSpinner.setVisibility(View.VISIBLE);
mOrder = CARD_ORDER_NONE;
String colOrder = getCol().getConf().getString("sortType");
for (int c = 0; c < fSortTypes.length; ++c) {
if (fSortTypes[c].equals(colOrder)) {
mOrder = c;
break;
}
}
if (mOrder == 1 && preferences.getBoolean("cardBrowserNoSorting", false)) {
mOrder = 0;
}
// This upgrade should already have been done during
// setConf. However older version of AnkiDroid didn't call
// upgradeJSONIfNecessary during setConf, which means the
// conf saved may still have this bug.
mOrderAsc = Upgrade.upgradeJSONIfNecessary(getCol(), getCol().getConf(), "sortBackwards", false);
mCards = new ArrayList<>();
mCardsListView = (ListView) findViewById(R.id.card_browser_list);
// Create a spinner for column1
Spinner cardsColumn1Spinner = (Spinner) findViewById(R.id.browser_column1_spinner);
ArrayAdapter<CharSequence> column1Adapter = ArrayAdapter.createFromResource(this, R.array.browser_column1_headings, android.R.layout.simple_spinner_item);
column1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
cardsColumn1Spinner.setAdapter(column1Adapter);
mColumn1Index = AnkiDroidApp.getSharedPrefs(getBaseContext()).getInt("cardBrowserColumn1", 0);
cardsColumn1Spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// If a new column was selected then change the key used to map from mCards to the column TextView
if (pos != mColumn1Index) {
mColumn1Index = pos;
AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext()).edit().putInt("cardBrowserColumn1", mColumn1Index).commit();
Column[] fromMap = mCardsAdapter.getFromMapping();
fromMap[0] = COLUMN1_KEYS[mColumn1Index];
mCardsAdapter.setFromMapping(fromMap);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Do Nothing
}
});
// Load default value for column2 selection
mColumn2Index = AnkiDroidApp.getSharedPrefs(getBaseContext()).getInt("cardBrowserColumn2", 0);
// Setup the column 2 heading as a spinner so that users can easily change the column type
Spinner cardsColumn2Spinner = (Spinner) findViewById(R.id.browser_column2_spinner);
ArrayAdapter<CharSequence> column2Adapter = ArrayAdapter.createFromResource(this, R.array.browser_column2_headings, android.R.layout.simple_spinner_item);
column2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
cardsColumn2Spinner.setAdapter(column2Adapter);
// Create a new list adapter with updated column map any time the user changes the column
cardsColumn2Spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// If a new column was selected then change the key used to map from mCards to the column TextView
if (pos != mColumn2Index) {
mColumn2Index = pos;
AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext()).edit().putInt("cardBrowserColumn2", mColumn2Index).commit();
Column[] fromMap = mCardsAdapter.getFromMapping();
fromMap[1] = COLUMN2_KEYS[mColumn2Index];
mCardsAdapter.setFromMapping(fromMap);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Do Nothing
}
});
// get the font and font size from the preferences
int sflRelativeFontSize = preferences.getInt("relativeCardBrowserFontSize", DEFAULT_FONT_SIZE_RATIO);
String sflCustomFont = preferences.getString("browserEditorFont", "");
Column[] columnsContent = { COLUMN1_KEYS[mColumn1Index], COLUMN2_KEYS[mColumn2Index] };
// make a new list adapter mapping the data in mCards to column1 and column2 of R.layout.card_item_browser
mCardsAdapter = new MultiColumnListAdapter(this, R.layout.card_item_browser, columnsContent, new int[] { R.id.card_sfld, R.id.card_column2 }, sflRelativeFontSize, sflCustomFont);
// link the adapter to the main mCardsListView
mCardsListView.setAdapter(mCardsAdapter);
// make the items (e.g. question & answer) render dynamically when scrolling
mCardsListView.setOnScrollListener(new RenderOnScroll());
// set the spinner index
cardsColumn1Spinner.setSelection(mColumn1Index);
cardsColumn2Spinner.setSelection(mColumn2Index);
mCardsListView.setOnItemClickListener(new ListView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mInMultiSelectMode) {
// click on whole cell triggers select
CheckBox cb = (CheckBox) view.findViewById(R.id.card_checkbox);
cb.toggle();
onCheck(position, view);
} else {
// load up the card selected on the list
long clickedCardId = getCards().get(position).getId();
openNoteEditorForCard(clickedCardId);
}
}
});
mCardsListView.setOnItemLongClickListener(new ListView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int position, long id) {
mLastSelectedPosition = position;
loadMultiSelectMode();
// click on whole cell triggers select
CheckBox cb = (CheckBox) view.findViewById(R.id.card_checkbox);
cb.toggle();
onCheck(position, view);
recenterListView(view);
mCardsAdapter.notifyDataSetChanged();
return true;
}
});
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
// If a valid value for last deck exists then use it, otherwise use libanki selected deck
if (getLastDeckId() != null && getLastDeckId() == ALL_DECKS_ID) {
selectAllDecks();
} else if (getLastDeckId() != null && getCol().getDecks().get(getLastDeckId(), false) != null) {
selectDeckById(getLastDeckId());
} else {
selectDeckById(getCol().getDecks().selected());
}
}
use of com.ichi2.anki.CardBrowser.Column.ANSWER in project AnkiChinaAndroid by ankichinateam.
the class AbstractFlashcardViewer method showSnackbar.
/**
* Displays a snackbar which does not obscure the answer buttons
*/
protected void showSnackbar(String mainText, @StringRes int buttonText, OnClickListener onClickListener) {
// BUG: Moving from full screen to non-full screen obscures the buttons
Snackbar sb = UIUtils.getSnackbar(this, mainText, Snackbar.LENGTH_LONG, buttonText, onClickListener, mCardWebView, null);
View easeButtons = findViewById(R.id.answer_options_layout);
View previewButtons = findViewById(R.id.preview_buttons_layout);
View upperView = previewButtons != null && previewButtons.getVisibility() != View.GONE ? previewButtons : easeButtons;
if (upperView != null && upperView.getVisibility() != View.GONE) {
View sbView = sb.getView();
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) sbView.getLayoutParams();
layoutParams.setAnchorId(upperView.getId());
layoutParams.anchorGravity = Gravity.TOP;
layoutParams.gravity = Gravity.TOP;
sbView.setLayoutParams(layoutParams);
}
sb.show();
}
use of com.ichi2.anki.CardBrowser.Column.ANSWER in project AnkiChinaAndroid by ankichinateam.
the class AbstractFlashcardViewer method typeAnsAnswerFilter.
/**
* Fill the placeholder for the type comparison. Show the correct answer, and the comparison if appropriate.
*
* @param buf The answer text
* @param userAnswer Text typed by the user, or empty.
* @param correctAnswer The correct answer, taken from the note.
* @return The formatted answer text
*/
@VisibleForTesting
String typeAnsAnswerFilter(String buf, String userAnswer, String correctAnswer) {
Matcher m = sTypeAnsPat.matcher(buf);
DiffEngine diffEngine = new DiffEngine();
StringBuilder sb = new StringBuilder();
sb.append("<div><code id=\"typeans\">");
if (!TextUtils.isEmpty(userAnswer)) {
// The user did type something.
if (userAnswer.equals(correctAnswer)) {
// and it was right.
sb.append(Matcher.quoteReplacement(DiffEngine.wrapGood(correctAnswer)));
// Heavy check mark
sb.append("<span id=\"typecheckmark\">\u2714</span>");
} else {
// Answer not correct.
// Only use the complex diff code when needed, that is when we have some typed text that is not
// exactly the same as the correct text.
String[] diffedStrings = diffEngine.diffedHtmlStrings(correctAnswer, userAnswer);
// We know we get back two strings.
sb.append(Matcher.quoteReplacement(diffedStrings[0]));
sb.append("<br><span id=\"typearrow\">↓</span><br>");
sb.append(Matcher.quoteReplacement(diffedStrings[1]));
}
} else {
if (!mUseInputTag) {
sb.append(Matcher.quoteReplacement(DiffEngine.wrapMissing(correctAnswer)));
} else {
sb.append(Matcher.quoteReplacement(correctAnswer));
}
}
sb.append("</code></div>");
return m.replaceAll(sb.toString());
}
use of com.ichi2.anki.CardBrowser.Column.ANSWER in project AnkiChinaAndroid by ankichinateam.
the class CardTemplatePreviewer method onCollectionLoaded.
@Override
protected void onCollectionLoaded(Collection col) {
super.onCollectionLoaded(col);
if ((mCurrentCard == null) && (mCardList == null)) {
Timber.d("onCollectionLoaded - incorrect state to load, closing");
closeCardTemplatePreviewer();
return;
}
if (mCardList != null && mOrdinal >= 0 && mOrdinal < mCardList.length) {
mCurrentCard = new PreviewerCard(col, mCardList[mOrdinal]);
}
if (mNoteEditorBundle != null) {
long newDid = mNoteEditorBundle.getLong("did");
if (col.getDecks().isDyn(newDid)) {
mCurrentCard.setODid(mCurrentCard.getDid());
}
mCurrentCard.setDid(newDid);
Note currentNote = mCurrentCard.note();
ArrayList<String> tagsList = mNoteEditorBundle.getStringArrayList("tags");
NoteUtils.setTags(currentNote, tagsList);
Bundle noteFields = mNoteEditorBundle.getBundle("editFields");
if (noteFields != null) {
for (String fieldOrd : noteFields.keySet()) {
// In case the fields on the card are out of sync with the bundle
int fieldOrdInt = Integer.parseInt(fieldOrd);
if (fieldOrdInt < currentNote.getFields().length) {
currentNote.setField(fieldOrdInt, noteFields.getString(fieldOrd));
}
}
}
}
displayCardQuestion();
Timber.i("display card question while showing answer:%s", mShowingAnswer);
if (mShowingAnswer) {
displayCardAnswer();
}
// showBackIcon();
}
Aggregations