use of com.ichi2.libanki.Deck in project Anki-Android by ankidroid.
the class SchedV2Test method regression_test_preview.
@Test
public void regression_test_preview() throws Exception {
// "https://github.com/ankidroid/Anki-Android/issues/7285"
Collection col = getColV2();
DeckManager decks = col.getDecks();
AbstractSched sched = col.getSched();
addNoteUsingBasicModel("foo", "bar");
long did = addDynamicDeck("test");
Deck deck = decks.get(did);
deck.put("resched", false);
sched.rebuildDyn(did);
col.reset();
Card card;
for (int i = 0; i < 3; i++) {
advanceRobolectricLooperWithSleep();
card = sched.getCard();
assertNotNull(card);
sched.answerCard(card, BUTTON_ONE);
}
advanceRobolectricLooperWithSleep();
assertEquals(1, sched.lrnCount());
card = sched.getCard();
assertEquals(1, sched.counts(card).getLrn());
advanceRobolectricLooperWithSleep();
sched.answerCard(card, BUTTON_ONE);
assertDoesNotThrow(col::undo);
}
use of com.ichi2.libanki.Deck in project Anki-Android by ankidroid.
the class AnkiDroidApp method onCreate.
/**
* On application creation.
*/
@Override
public void onCreate() {
super.onCreate();
if (sInstance != null) {
Timber.i("onCreate() called multiple times");
// 5887 - fix crash.
if (sInstance.getResources() == null) {
Timber.w("Skipping re-initialisation - no resources. Maybe uninstalling app?");
return;
}
}
sInstance = this;
// Get preferences
SharedPreferences preferences = getSharedPrefs(this);
// Setup logging and crash reporting
mAcraCoreConfigBuilder = new CoreConfigurationBuilder(this);
if (BuildConfig.DEBUG) {
// Enable verbose error logging and do method tracing to put the Class name as log tag
Timber.plant(new DebugTree());
setDebugACRAConfig(preferences);
List<ReferenceMatcher> referenceMatchers = new ArrayList<>();
// Add known memory leaks to 'referenceMatchers'
matchKnownMemoryLeaks(referenceMatchers);
// AppWatcher manual install if not already installed
if (!AppWatcher.INSTANCE.isInstalled()) {
AppWatcher.INSTANCE.manualInstall(this);
}
// Show 'Leaks' app launcher. It has been removed by default via constants.xml.
LeakCanary.INSTANCE.showLeakDisplayActivityLauncherIcon(true);
} else {
Timber.plant(new ProductionCrashReportingTree());
setProductionACRAConfig(preferences);
disableLeakCanary();
}
Timber.tag(TAG);
Timber.d("Startup - Application Start");
// Analytics falls back to a sensible default if this is not set.
if (ACRA.isACRASenderServiceProcess() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
try {
WebViewDebugging.setDataDirectorySuffix("acra");
} catch (Exception e) {
Timber.w(e, "Failed to set WebView data directory");
}
}
// analytics after ACRA, they both install UncaughtExceptionHandlers but Analytics chains while ACRA does not
UsageAnalytics.initialize(this);
if (BuildConfig.DEBUG) {
UsageAnalytics.setDryRun(true);
}
// Stop after analytics and logging are initialised.
if (ACRA.isACRASenderServiceProcess()) {
Timber.d("Skipping AnkiDroidApp.onCreate from ACRA sender process");
return;
}
if (AdaptionUtil.isUserATestClient()) {
UIUtils.showThemedToast(this.getApplicationContext(), getString(R.string.user_is_a_robot), false);
}
// make default HTML / JS debugging true for debug build and disable for unit/android tests
if (BuildConfig.DEBUG && !AdaptionUtil.isRunningAsUnitTest()) {
preferences.edit().putBoolean("html_javascript_debugging", true).apply();
}
CardBrowserContextMenu.ensureConsistentStateWithSharedPreferences(this);
AnkiCardContextMenu.ensureConsistentStateWithSharedPreferences(this);
NotificationChannels.setup(getApplicationContext());
// Configure WebView to allow file scheme pages to access cookies.
if (!acceptFileSchemeCookies()) {
return;
}
// Forget the last deck that was used in the CardBrowser
CardBrowser.clearLastDeckId();
// Create the AnkiDroid directory if missing. Send exception report if inaccessible.
if (Permissions.hasStorageAccessPermission(this)) {
try {
String dir = CollectionHelper.getCurrentAnkiDroidDirectory(this);
CollectionHelper.initializeAnkiDroidDirectory(dir);
} catch (StorageAccessException e) {
Timber.e(e, "Could not initialize AnkiDroid directory");
String defaultDir = CollectionHelper.getDefaultAnkiDroidDirectory(this);
if (isSdCardMounted() && CollectionHelper.getCurrentAnkiDroidDirectory(this).equals(defaultDir)) {
// Don't send report if the user is using a custom directory as SD cards trip up here a lot
sendExceptionReport(e, "AnkiDroidApp.onCreate");
}
}
}
Timber.i("AnkiDroidApp: Starting Services");
new BootService().onReceive(this, new Intent(this, BootService.class));
// Register BroadcastReceiver NotificationService
NotificationService ns = new NotificationService();
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.registerReceiver(ns, new IntentFilter(NotificationService.INTENT_ACTION));
}
use of com.ichi2.libanki.Deck in project Anki-Android by ankidroid.
the class DeckOptions method getOptionsGroupCount.
/**
* Returns the number of decks using the options group of the current deck.
*/
private int getOptionsGroupCount() {
int count = 0;
long conf = mDeck.getLong("conf");
for (Deck deck : mCol.getDecks().all()) {
if (deck.isDyn()) {
continue;
}
if (deck.getLong("conf") == conf) {
count++;
}
}
return count;
}
use of com.ichi2.libanki.Deck in project Anki-Android by ankidroid.
the class DeckPicker method onOptionsItemSelected.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Resources res = getResources();
if (getDrawerToggle().onOptionsItemSelected(item)) {
return true;
}
int itemId = item.getItemId();
if (itemId == R.id.action_undo) {
Timber.i("DeckPicker:: Undo button pressed");
undo();
return true;
} else if (itemId == R.id.action_sync) {
Timber.i("DeckPicker:: Sync button pressed");
sync();
return true;
} else if (itemId == R.id.action_import) {
Timber.i("DeckPicker:: Import button pressed");
showDialogFragment(ImportFileSelectionFragment.createInstance(this));
return true;
} else if (itemId == R.id.action_new_filtered_deck) {
CreateDeckDialog createFilteredDeckDialog = new CreateDeckDialog(DeckPicker.this, R.string.new_deck, CreateDeckDialog.DeckDialogType.FILTERED_DECK, null);
createFilteredDeckDialog.setOnNewDeckCreated((id) -> {
// a filtered deck was created
openStudyOptions(true);
});
createFilteredDeckDialog.showFilteredDeckDialog();
return true;
} else if (itemId == R.id.action_check_database) {
Timber.i("DeckPicker:: Check database button pressed");
showDatabaseErrorDialog(DatabaseErrorDialog.DIALOG_CONFIRM_DATABASE_CHECK);
return true;
} else if (itemId == R.id.action_check_media) {
Timber.i("DeckPicker:: Check media button pressed");
showMediaCheckDialog(MediaCheckDialog.DIALOG_CONFIRM_MEDIA_CHECK);
return true;
} else if (itemId == R.id.action_empty_cards) {
Timber.i("DeckPicker:: Empty cards button pressed");
handleEmptyCards();
return true;
} else if (itemId == R.id.action_model_browser_open) {
Timber.i("DeckPicker:: Model browser button pressed");
Intent noteTypeBrowser = new Intent(this, ModelBrowser.class);
startActivityForResultWithAnimation(noteTypeBrowser, 0, START);
return true;
} else if (itemId == R.id.action_restore_backup) {
Timber.i("DeckPicker:: Restore from backup button pressed");
showDatabaseErrorDialog(DatabaseErrorDialog.DIALOG_CONFIRM_RESTORE_BACKUP);
return true;
} else if (itemId == R.id.action_export) {
Timber.i("DeckPicker:: Export collection button pressed");
String msg = getResources().getString(R.string.confirm_apkg_export);
mExportingDelegate.showExportDialog(msg);
return true;
}
return super.onOptionsItemSelected(item);
}
use of com.ichi2.libanki.Deck in project Anki-Android by ankidroid.
the class ImportTest method testAnki2Mediadupes.
@Test
public void testAnki2Mediadupes() throws IOException, JSONException, ImportExportException {
// add a note that references a sound
Note n = mTestCol.newNote();
n.setField(0, "[sound:foo.mp3]");
long mid = n.model().getLong("id");
mTestCol.addNote(n);
// add that sound to the media directory
FileOutputStream os = new FileOutputStream(new File(mTestCol.getMedia().dir(), "foo.mp3"), false);
os.write("foo".getBytes());
os.close();
mTestCol.close();
// it should be imported correctly into an empty deck
Collection empty = getEmptyCol();
Importer imp = new Anki2Importer(empty, mTestCol.getPath());
imp.run();
List<String> expected = Collections.singletonList("foo.mp3");
List<String> actual = Arrays.asList(new File(empty.getMedia().dir()).list());
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
// and importing again will not duplicate, as the file content matches
empty.remCards(empty.getDb().queryLongList("select id from cards"));
imp = new Anki2Importer(empty, mTestCol.getPath());
imp.run();
expected = Collections.singletonList("foo.mp3");
actual = Arrays.asList(new File(empty.getMedia().dir()).list());
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
n = empty.getNote(empty.getDb().queryLongScalar("select id from notes"));
assertTrue(n.getFields()[0].contains("foo.mp3"));
// if the local file content is different, and import should trigger a rename
empty.remCards(empty.getDb().queryLongList("select id from cards"));
os = new FileOutputStream(new File(empty.getMedia().dir(), "foo.mp3"), false);
os.write("bar".getBytes());
os.close();
imp = new Anki2Importer(empty, mTestCol.getPath());
imp.run();
expected = Arrays.asList("foo.mp3", String.format("foo_%s.mp3", mid));
actual = Arrays.asList(new File(empty.getMedia().dir()).list());
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
n = empty.getNote(empty.getDb().queryLongScalar("select id from notes"));
assertTrue(n.getFields()[0].contains("_"));
// if the localized media file already exists, we rewrite the note and media
empty.remCards(empty.getDb().queryLongList("select id from cards"));
os = new FileOutputStream(new File(empty.getMedia().dir(), "foo.mp3"));
os.write("bar".getBytes());
os.close();
imp = new Anki2Importer(empty, mTestCol.getPath());
imp.run();
expected = Arrays.asList("foo.mp3", String.format("foo_%s.mp3", mid));
actual = Arrays.asList(new File(empty.getMedia().dir()).list());
actual.retainAll(expected);
assertEquals(expected.size(), actual.size());
n = empty.getNote(empty.getDb().queryLongScalar("select id from notes"));
assertTrue(n.getFields()[0].contains("_"));
empty.close();
}
Aggregations