use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.
the class ContentProviderTest method testAnswerCard.
/**
* Test giving the answer for a reviewed card
*/
@Test
public void testAnswerCard() {
Collection col = getCol();
Card card = getFirstCardFromScheduler(col);
long cardId = card.getId();
// the card starts out being new
assertEquals("card is initial new", Consts.CARD_TYPE_NEW, card.getQueue());
ContentResolver cr = InstrumentationRegistry.getInstrumentation().getTargetContext().getContentResolver();
Uri reviewInfoUri = FlashCardsContract.ReviewInfo.CONTENT_URI;
ContentValues values = new ContentValues();
long noteId = card.note().getId();
int cardOrd = card.getOrd();
int earlyGraduatingEase = (schedVersion == 1) ? AbstractFlashcardViewer.EASE_3 : AbstractFlashcardViewer.EASE_4;
// 5 seconds
long timeTaken = 5000;
values.put(FlashCardsContract.ReviewInfo.NOTE_ID, noteId);
values.put(FlashCardsContract.ReviewInfo.CARD_ORD, cardOrd);
values.put(FlashCardsContract.ReviewInfo.EASE, earlyGraduatingEase);
values.put(FlashCardsContract.ReviewInfo.TIME_TAKEN, timeTaken);
int updateCount = cr.update(reviewInfoUri, values, null, null);
assertEquals("Check if update returns 1", 1, updateCount);
try {
Thread.currentThread().wait(500);
} catch (Exception e) {
/* do nothing */
}
col.reset();
Card newCard = col.getSched().getCard();
if (newCard != null) {
if (newCard.note().getId() == card.note().getId() && newCard.getOrd() == card.getOrd()) {
fail("Next scheduled card has not changed");
}
}
// lookup the card after update, ensure it's not new anymore
Card cardAfterReview = col.getCard(cardId);
assertEquals("card is now type rev", Card.TYPE_REV, cardAfterReview.getQueue());
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.
the class ContentProviderTest method testQueryCardFromCertainDeck.
/**
* Test that query for the next card in the schedule returns a valid result WITH a deck selector
*/
@Test
public void testQueryCardFromCertainDeck() {
long deckToTest = mTestDeckIds.get(0);
String deckSelector = "deckID=?";
String[] deckArguments = { Long.toString(deckToTest) };
Collection col = getCol();
AbstractSched sched = col.getSched();
long selectedDeckBeforeTest = col.getDecks().selected();
// select Default deck
col.getDecks().select(1);
Cursor reviewInfoCursor = InstrumentationRegistry.getInstrumentation().getTargetContext().getContentResolver().query(FlashCardsContract.ReviewInfo.CONTENT_URI, null, deckSelector, deckArguments, null);
assertNotNull(reviewInfoCursor);
assertEquals("Check that we actually received one card", 1, reviewInfoCursor.getCount());
try {
reviewInfoCursor.moveToFirst();
int cardOrd = reviewInfoCursor.getInt(reviewInfoCursor.getColumnIndex(FlashCardsContract.ReviewInfo.CARD_ORD));
long noteID = reviewInfoCursor.getLong(reviewInfoCursor.getColumnIndex(FlashCardsContract.ReviewInfo.NOTE_ID));
assertEquals("Check that the selected deck has not changed", 1, col.getDecks().selected());
col.getDecks().select(deckToTest);
Card nextCard = null;
for (int i = 0; i < 10; i++) {
// minimizing fails, when sched.reset() randomly chooses between multiple cards
col.reset();
nextCard = sched.getCard();
if (nextCard.note().getId() == noteID && nextCard.getOrd() == cardOrd)
break;
}
assertNotNull("Check that there actually is a next scheduled card", nextCard);
assertEquals("Check that received card and actual card have same note id", nextCard.note().getId(), noteID);
assertEquals("Check that received card and actual card have same card ord", nextCard.getOrd(), cardOrd);
} finally {
reviewInfoCursor.close();
}
col.getDecks().select(selectedDeckBeforeTest);
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.
the class NoteEditor method saveNote.
@VisibleForTesting
void saveNote() {
final Resources res = getResources();
if (mSelectedTags == null) {
mSelectedTags = new ArrayList<>(0);
}
// treat add new note and edit existing note independently
if (mAddNote) {
// DEFECT: This does not block addition if cloze transpositions are in non-cloze fields.
if (isClozeType() && !hasClozeDeletions()) {
displayErrorSavingNote();
return;
}
// load all of the fields into the note
for (FieldEditText f : mEditFields) {
updateField(f);
}
// Save deck to model
mEditorNote.model().put("did", mCurrentDid);
// Save tags to model
mEditorNote.setTagsFromStr(tagsAsString(mSelectedTags));
JSONArray tags = new JSONArray();
for (String t : mSelectedTags) {
tags.put(t);
}
getCol().getModels().current().put("tags", tags);
getCol().getModels().setChanged();
mReloadRequired = true;
CollectionTask.launchCollectionTask(ADD_NOTE, saveNoteHandler(), new TaskData(mEditorNote));
} else {
// Check whether note type has been changed
final Model newModel = getCurrentlySelectedModel();
final Model oldModel = (mCurrentEditedCard == null) ? null : mCurrentEditedCard.model();
File target = new File(FileUtil.createTmpDir(this), mCurrentEditedCard.getId() + ".wav");
if (target.exists()) {
Timber.i("editing card audio is exists,delete it");
target.delete();
}
if (!newModel.equals(oldModel)) {
mReloadRequired = true;
if (mModelChangeCardMap.size() < mEditorNote.numberOfCards() || mModelChangeCardMap.containsValue(null)) {
// If cards will be lost via the new mapping then show a confirmation dialog before proceeding with the change
ConfirmationDialog dialog = new ConfirmationDialog();
dialog.setArgs(res.getString(R.string.confirm_map_cards_to_nothing));
Runnable confirm = () -> {
// Bypass the check once the user confirms
changeNoteTypeWithErrorHandling(oldModel, newModel);
};
dialog.setConfirm(confirm);
showDialogFragment(dialog);
} else {
// Otherwise go straight to changing note type
changeNoteTypeWithErrorHandling(oldModel, newModel);
}
return;
}
// Regular changes in note content
boolean modified = false;
// changed did? this has to be done first as remFromDyn() involves a direct write to the database
if (mCurrentEditedCard != null && mCurrentEditedCard.getDid() != mCurrentDid) {
mReloadRequired = true;
// remove card from filtered deck first (if relevant)
getCol().getSched().remFromDyn(new long[] { mCurrentEditedCard.getId() });
// refresh the card object to reflect the database changes in remFromDyn()
mCurrentEditedCard.load();
// also reload the note object
mEditorNote = mCurrentEditedCard.note();
// then set the card ID to the new deck
mCurrentEditedCard.setDid(mCurrentDid);
modified = true;
}
// now load any changes to the fields from the form
for (FieldEditText f : mEditFields) {
modified = modified | updateField(f);
}
// added tag?
for (String t : mSelectedTags) {
modified = modified || !mEditorNote.hasTag(t);
}
// removed tag?
modified = modified || mEditorNote.getTags().size() > mSelectedTags.size();
if (modified) {
mEditorNote.setTagsFromStr(tagsAsString(mSelectedTags));
mChanged = true;
}
closeNoteEditor();
}
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.
the class CardBrowser method onActivityResult.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// FIXME:
Timber.d("onActivityResult(requestCode=%d, resultCode=%d)", requestCode, resultCode);
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");
}
}
// Previewing can now perform an "edit", so it can pass on a reloadRequired
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 NoteEditor method hasUnsavedChanges.
private boolean hasUnsavedChanges() {
if (!collectionHasLoaded()) {
return false;
}
// changed note type?
if (!mAddNote && mCurrentEditedCard != null) {
final JSONObject newModel = getCurrentlySelectedModel();
final JSONObject oldModel = mCurrentEditedCard.model();
if (!newModel.equals(oldModel)) {
return true;
}
}
// changed deck?
if (!mAddNote && mCurrentEditedCard != null && mCurrentEditedCard.getDid() != mCurrentDid) {
return true;
}
// changed fields?
if (mFieldEdited) {
return true;
}
// changed tags?
return mTagsEdited;
}
Aggregations