use of com.ichi2.anki.Previewer in project AnkiChinaAndroid by ankichinateam.
the class CardBrowser method onOptionsItemSelected.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// (when another operation will be performed on the model, it will undo the latest operation)
if (mUndoSnackbar != null && mUndoSnackbar.isShown()) {
mUndoSnackbar.dismiss();
}
switch(item.getItemId()) {
case android.R.id.home:
endMultiSelectMode();
return true;
case R.id.action_add_note_from_card_browser:
{
Intent intent = new Intent(CardBrowser.this, NoteEditor.class);
intent.putExtra(NoteEditor.EXTRA_CALLER, NoteEditor.CALLER_CARDBROWSER_ADD);
startActivityForResultWithAnimation(intent, ADD_NOTE, ActivityTransitionAnimation.LEFT);
return true;
}
case R.id.action_save_search:
{
String searchTerms = mSearchView.getQuery().toString();
showDialogFragment(CardBrowserMySearchesDialog.newInstance(null, mMySearchesDialogListener, searchTerms, CardBrowserMySearchesDialog.CARD_BROWSER_MY_SEARCHES_TYPE_SAVE));
return true;
}
case R.id.action_list_my_searches:
{
JSONObject savedFiltersObj = getCol().getConf().optJSONObject("savedFilters");
HashMap<String, String> savedFilters = new HashMap<>();
if (savedFiltersObj != null) {
Iterator<String> it = savedFiltersObj.keys();
while (it.hasNext()) {
String searchName = it.next();
savedFilters.put(searchName, savedFiltersObj.optString(searchName));
}
}
showDialogFragment(CardBrowserMySearchesDialog.newInstance(savedFilters, mMySearchesDialogListener, "", CardBrowserMySearchesDialog.CARD_BROWSER_MY_SEARCHES_TYPE_LIST));
return true;
}
case R.id.action_sort_by_size:
showDialogFragment(CardBrowserOrderDialog.newInstance(mOrder, mOrderAsc, mOrderDialogListener));
return true;
case R.id.action_show_marked:
mSearchTerms = "tag:marked";
mSearchView.setQuery("", false);
mSearchView.setQueryHint(getResources().getString(R.string.card_browser_show_marked));
searchCards();
return true;
case R.id.action_show_suspended:
mSearchTerms = "is:suspended";
mSearchView.setQuery("", false);
mSearchView.setQueryHint(getResources().getString(R.string.card_browser_show_suspended));
searchCards();
return true;
case R.id.action_search_by_tag:
showTagsDialog();
return true;
case R.id.action_flag_zero:
flagTask(0);
return true;
case R.id.action_flag_one:
flagTask(1);
return true;
case R.id.action_flag_two:
flagTask(2);
return true;
case R.id.action_flag_three:
flagTask(3);
return true;
case R.id.action_flag_four:
flagTask(4);
return true;
case R.id.action_delete_card:
if (mInMultiSelectMode) {
CollectionTask.launchCollectionTask(DISMISS_MULTI, mDeleteNoteHandler, new TaskData(new Object[] { getSelectedCardIds(), Collection.DismissType.DELETE_NOTE_MULTI }));
mCheckedCards.clear();
endMultiSelectMode();
mCardsAdapter.notifyDataSetChanged();
}
return true;
case R.id.action_mark_card:
CollectionTask.launchCollectionTask(DISMISS_MULTI, markCardHandler(), new TaskData(new Object[] { getSelectedCardIds(), Collection.DismissType.MARK_NOTE_MULTI }));
return true;
case R.id.action_suspend_card:
CollectionTask.launchCollectionTask(DISMISS_MULTI, suspendCardHandler(), new TaskData(new Object[] { getSelectedCardIds(), Collection.DismissType.SUSPEND_CARD_MULTI }));
return true;
case R.id.action_change_deck:
{
AlertDialog.Builder builderSingle = new AlertDialog.Builder(this);
builderSingle.setTitle(getString(R.string.move_all_to_deck));
// WARNING: changeDeck depends on this index, so any changes should be reflected there.
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.dropdown_deck_item);
for (Deck deck : getValidDecksForChangeDeck()) {
try {
arrayAdapter.add(deck.getString("name"));
} catch (JSONException e) {
e.printStackTrace();
}
}
builderSingle.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builderSingle.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
changeDeck(which);
}
});
builderSingle.show();
return true;
}
case R.id.action_undo:
if (getCol().undoAvailable()) {
CollectionTask.launchCollectionTask(UNDO, mUndoHandler);
}
return true;
case R.id.action_select_none:
onSelectNone();
return true;
case R.id.action_select_all:
onSelectAll();
return true;
case R.id.action_preview:
{
Intent previewer = new Intent(CardBrowser.this, Previewer.class);
if (mInMultiSelectMode && checkedCardCount() > 1) {
// Multiple cards have been explicitly selected, so preview only those cards
previewer.putExtra("index", 0);
previewer.putExtra("cardList", getSelectedCardIds());
} else {
// Preview all cards, starting from the one that is currently selected
int startIndex = mCheckedCards.isEmpty() ? 0 : mCheckedCards.iterator().next().getPosition();
previewer.putExtra("index", startIndex);
previewer.putExtra("cardList", getAllCardIds());
}
startActivityForResultWithoutAnimation(previewer, PREVIEW_CARDS);
return true;
}
case R.id.action_reset_cards_progress:
{
Timber.i("NoteEditor:: Reset progress button pressed");
// Show confirmation dialog before resetting card progress
ConfirmationDialog dialog = new ConfirmationDialog();
String title = getString(R.string.reset_card_dialog_title);
String message = getString(R.string.reset_card_dialog_message);
dialog.setArgs(title, message);
Runnable confirm = () -> {
Timber.i("CardBrowser:: ResetProgress button pressed");
CollectionTask.launchCollectionTask(DISMISS_MULTI, resetProgressCardHandler(), new TaskData(new Object[] { getSelectedCardIds(), Collection.DismissType.RESET_CARDS }));
};
dialog.setConfirm(confirm);
showDialogFragment(dialog);
return true;
}
case R.id.action_reschedule_cards:
{
Timber.i("CardBrowser:: Reschedule button pressed");
long[] selectedCardIds = getSelectedCardIds();
FunctionalInterfaces.Consumer<Integer> consumer = newDays -> CollectionTask.launchCollectionTask(DISMISS_MULTI, rescheduleCardHandler(), new TaskData(new Object[] { selectedCardIds, Collection.DismissType.RESCHEDULE_CARDS, newDays }));
RescheduleDialog rescheduleDialog;
if (selectedCardIds.length == 1) {
long cardId = selectedCardIds[0];
Card selected = getCol().getCard(cardId);
rescheduleDialog = RescheduleDialog.rescheduleSingleCard(getResources(), selected, consumer);
} else {
rescheduleDialog = RescheduleDialog.rescheduleMultipleCards(getResources(), consumer, selectedCardIds.length);
}
showDialogFragment(rescheduleDialog);
return true;
}
case R.id.action_reposition_cards:
{
Timber.i("CardBrowser:: Reposition button pressed");
// Only new cards may be repositioned
long[] cardIds = getSelectedCardIds();
for (int i = 0; i < cardIds.length; i++) {
if (getCol().getCard(cardIds[i]).getQueue() != Consts.CARD_TYPE_NEW) {
SimpleMessageDialog dialog = SimpleMessageDialog.newInstance(getString(R.string.vague_error), getString(R.string.reposition_card_not_new_error), false);
showDialogFragment(dialog);
return false;
}
}
IntegerDialog repositionDialog = new IntegerDialog();
repositionDialog.setArgs(getString(R.string.reposition_card_dialog_title), getString(R.string.reposition_card_dialog_message), 5);
repositionDialog.setCallbackRunnable(days -> CollectionTask.launchCollectionTask(DISMISS_MULTI, repositionCardHandler(), new TaskData(new Object[] { cardIds, Collection.DismissType.REPOSITION_CARDS, days })));
showDialogFragment(repositionDialog);
return true;
}
case R.id.action_edit_note:
{
openNoteEditorForCurrentlySelectedNote();
}
default:
return super.onOptionsItemSelected(item);
}
}
use of com.ichi2.anki.Previewer in project AnkiChinaAndroid by ankichinateam.
the class CardTemplateEditorTest method testEditTemplateContents.
@Test
@SuppressWarnings("PMD.NPathComplexity")
public void testEditTemplateContents() throws Exception {
String modelName = "Basic";
// Start the CardTemplateEditor with a specific model, and make sure the model starts unchanged
JSONObject collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra("modelId", collectionBasicModelOriginal.getLong("id"));
ActivityController<CardTemplateEditor> templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class, intent).create().start().resume().visible();
saveControllerForCleanup(templateEditorController);
CardTemplateEditor testEditor = (CardTemplateEditor) templateEditorController.get();
Assert.assertFalse("Model should not have changed yet", testEditor.modelHasChanged());
// Change the model and make sure it registers as changed, but the database is unchanged
EditText templateFront = testEditor.findViewById(R.id.front_edit);
String TEST_MODEL_QFMT_EDIT = "!@#$%^&*TEST*&^%$#@!";
templateFront.getText().append(TEST_MODEL_QFMT_EDIT);
advanceRobolectricLooper();
Assert.assertTrue("Model did not change after edit?", testEditor.modelHasChanged());
Assert.assertEquals("Change already in database?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
// Kill and restart the Activity, make sure model edit is preserved
Bundle outBundle = new Bundle();
templateEditorController.saveInstanceState(outBundle);
templateEditorController.pause().stop().destroy();
templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class).create(outBundle).start().resume().visible();
saveControllerForCleanup(templateEditorController);
testEditor = (CardTemplateEditor) templateEditorController.get();
ShadowActivity shadowTestEditor = shadowOf(testEditor);
Assert.assertTrue("model change not preserved across activity lifecycle?", testEditor.modelHasChanged());
Assert.assertEquals("Change already in database?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
// Make sure we get a confirmation dialog if we hit the back button
Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(android.R.id.home));
advanceRobolectricLooper();
Assert.assertEquals("Wrong dialog shown?", getDialogText(true), getResourceString(R.string.discard_unsaved_changes));
clickDialogButton(DialogAction.NEGATIVE, true);
advanceRobolectricLooper();
Assert.assertTrue("model change not preserved despite canceling back button?", testEditor.modelHasChanged());
// Make sure we things are cleared out after a cancel
Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(android.R.id.home));
Assert.assertEquals("Wrong dialog shown?", getDialogText(true), getResourceString(R.string.discard_unsaved_changes));
clickDialogButton(DialogAction.POSITIVE, true);
advanceRobolectricLooper();
Assert.assertFalse("model change not cleared despite discarding changes?", testEditor.modelHasChanged());
// Get going for content edit assertions again...
templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class, intent).create().start().resume().visible();
saveControllerForCleanup(templateEditorController);
testEditor = (CardTemplateEditor) templateEditorController.get();
shadowTestEditor = shadowOf(testEditor);
templateFront = testEditor.findViewById(R.id.front_edit);
templateFront.getText().append(TEST_MODEL_QFMT_EDIT);
advanceRobolectricLooper();
Assert.assertTrue("Model did not change after edit?", testEditor.modelHasChanged());
// Make sure we pass the edit to the Previewer
Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_preview));
advanceRobolectricLooper();
Intent startedIntent = shadowTestEditor.getNextStartedActivity();
ShadowIntent shadowIntent = shadowOf(startedIntent);
advanceRobolectricLooper();
Assert.assertEquals("Previewer not started?", CardTemplatePreviewer.class.getName(), shadowIntent.getIntentClass().getName());
Assert.assertNotNull("intent did not have model JSON filename?", startedIntent.getStringExtra(TemporaryModel.INTENT_MODEL_FILENAME));
Assert.assertNotEquals("Model sent to Previewer is unchanged?", testEditor.getTempModel().getModel(), TemporaryModel.getTempModel(startedIntent.getStringExtra(TemporaryModel.INTENT_MODEL_FILENAME)));
Assert.assertEquals("Change already in database?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
shadowTestEditor.receiveResult(startedIntent, Activity.RESULT_OK, new Intent());
// Save the template then fetch it from the collection to see if it was saved correctly
JSONObject testEditorModelEdited = testEditor.getTempModel().getModel();
advanceRobolectricLooper();
Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_confirm));
advanceRobolectricLooper();
JSONObject collectionBasicModelCopyEdited = getCurrentDatabaseModelCopy(modelName);
Assert.assertNotEquals("model is unchanged?", collectionBasicModelOriginal, collectionBasicModelCopyEdited);
Assert.assertEquals("model did not save?", testEditorModelEdited.toString().trim(), collectionBasicModelCopyEdited.toString().trim());
Assert.assertTrue("model does not have our change?", collectionBasicModelCopyEdited.toString().contains(TEST_MODEL_QFMT_EDIT));
}
use of com.ichi2.anki.Previewer in project AnkiChinaAndroid by ankichinateam.
the class CardTemplateEditorTest method testTemplateAdd.
@Test
public void testTemplateAdd() throws Exception {
// Make sure we test previewing a new card template - not working for real yet
String modelName = "Basic";
JSONObject collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra("modelId", collectionBasicModelOriginal.getLong("id"));
ActivityController<CardTemplateEditor> templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class, intent).create().start().resume().visible();
saveControllerForCleanup(templateEditorController);
CardTemplateEditor testEditor = (CardTemplateEditor) templateEditorController.get();
Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 0));
// Try to add a template - click add, click confirm for card add, click confirm again for full sync
ShadowActivity shadowTestEditor = shadowOf(testEditor);
Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_add));
advanceRobolectricLooper();
// if AnkiDroid moves to match AnkiDesktop it will pop a dialog to confirm card create
// Assert.assertEquals("Wrong dialog shown?", "This will create NN cards. Proceed?", getDialogText());
// clickDialogButton(DialogAction.POSITIVE);
Assert.assertTrue("Model should have changed", testEditor.modelHasChanged());
Assert.assertEquals("Change not pending add?", 1, TemporaryModel.getAdjustedAddOrdinalAtChangeIndex(testEditor.getTempModel(), 0));
Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 0));
Assert.assertTrue("Ordinal not pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 1));
Assert.assertEquals("Model should have 2 templates now", 2, testEditor.getTempModel().getTemplateCount());
// Make sure we pass the new template to the Previewer
Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_preview));
Intent startedIntent = shadowTestEditor.getNextStartedActivity();
ShadowIntent shadowIntent = shadowOf(startedIntent);
Assert.assertEquals("Previewer not started?", CardTemplatePreviewer.class.getName(), shadowIntent.getIntentClass().getName());
Assert.assertNotNull("intent did not have model JSON filename?", startedIntent.getStringExtra(TemporaryModel.INTENT_MODEL_FILENAME));
Assert.assertEquals("intent did not have ordinal?", 1, startedIntent.getIntExtra("ordinal", -1));
Assert.assertNotEquals("Model sent to Previewer is unchanged?", testEditor.getTempModel().getModel(), TemporaryModel.getTempModel(startedIntent.getStringExtra(TemporaryModel.INTENT_MODEL_FILENAME)));
Assert.assertEquals("Change already in database?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
// Save the change to the database and make sure there are two templates after
JSONObject testEditorModelEdited = testEditor.getTempModel().getModel();
Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_confirm));
advanceRobolectricLooper();
JSONObject collectionBasicModelCopyEdited = getCurrentDatabaseModelCopy(modelName);
Assert.assertNotEquals("model is unchanged?", collectionBasicModelOriginal, collectionBasicModelCopyEdited);
Assert.assertEquals("model did not save?", testEditorModelEdited.toString().trim(), collectionBasicModelCopyEdited.toString().trim());
}
use of com.ichi2.anki.Previewer in project Anki-Android by ankidroid.
the class PreviewerTest method editingNoteChangesContent.
@Test
public void editingNoteChangesContent() {
// #7801
addNoteUsingBasicModel("Hello", "World");
Card cardToPreview = addNoteUsingBasicModel("Hello", "World").firstCard();
setDeck("Deck", cardToPreview);
Previewer previewer = getPreviewerPreviewing(cardToPreview);
assertThat("Initial content assumption", previewer.getCardContent(), not(containsString("Hi")));
cardToPreview.note().setField(0, "Hi");
previewer.onActivityResult(AbstractFlashcardViewer.EDIT_CURRENT_CARD, Activity.RESULT_OK, null);
advanceRobolectricLooperWithSleep();
assertThat("Card content should be updated after editing", previewer.getCardContent(), containsString("Hi"));
}
use of com.ichi2.anki.Previewer in project Anki-Android by ankidroid.
the class PreviewerTest method editingNoteDoesNotChangePreviewedCardId.
@Test
public void editingNoteDoesNotChangePreviewedCardId() {
// #7801
addNoteUsingBasicModel("Hello", "World");
Card cardToPreview = addNoteUsingBasicModel("Hello", "World").firstCard();
setDeck("Deck", cardToPreview);
Previewer previewer = getPreviewerPreviewing(cardToPreview);
assertThat("Initially should be previewing selected card", previewer.getCurrentCardId(), is(cardToPreview.getId()));
previewer.onActivityResult(AbstractFlashcardViewer.EDIT_CURRENT_CARD, Activity.RESULT_OK, null);
advanceRobolectricLooperWithSleep();
assertThat("Should be previewing selected card after edit", previewer.getCurrentCardId(), is(cardToPreview.getId()));
}
Aggregations