use of com.ichi2.anki.CardBrowser.Column.CREATED in project Anki-Android by Ramblurr.
the class DeckPicker method onActivityResult.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
mDontSaveOnStop = false;
if (resultCode == RESULT_MEDIA_EJECTED) {
showDialog(DIALOG_SD_CARD_NOT_MOUNTED);
return;
} else if (resultCode == RESULT_DB_ERROR) {
handleDbError();
return;
}
if (requestCode == SHOW_STUDYOPTIONS && resultCode == RESULT_OK) {
loadCounts();
} else if (requestCode == ADD_NOTE && resultCode != RESULT_CANCELED) {
loadCounts();
} else if (requestCode == BROWSE_CARDS && (resultCode == Activity.RESULT_OK || resultCode == Activity.RESULT_CANCELED)) {
loadCounts();
} else if (requestCode == ADD_CRAM_DECK) {
// TODO: check, if ok has been clicked
loadCounts();
} else if (requestCode == REPORT_ERROR) {
showStartupScreensAndDialogs(AnkiDroidApp.getSharedPrefs(getBaseContext()), 4);
} else if (requestCode == SHOW_INFO_UPGRADE_DECKS) {
if (intent != null && intent.hasExtra(Info.TYPE_UPGRADE_STAGE)) {
int type = intent.getIntExtra(Info.TYPE_UPGRADE_STAGE, Info.UPGRADE_SCREEN_BASIC1);
if (type == Info.UPGRADE_CONTINUE) {
showStartupScreensAndDialogs(AnkiDroidApp.getSharedPrefs(getBaseContext()), 3);
} else {
showUpgradeScreen(true, type, !intent.hasExtra(Info.TYPE_ANIMATION_RIGHT));
}
} else {
if (resultCode == RESULT_OK) {
if (mOpenCollectionDialog != null && mOpenCollectionDialog.isShowing()) {
mOpenCollectionDialog.dismiss();
}
if (AnkiDroidApp.colIsOpen()) {
AnkiDroidApp.closeCollection(true);
}
AnkiDroidApp.openCollection(AnkiDroidApp.getCollectionPath());
loadCounts();
} else {
finishWithAnimation();
}
}
} else if (requestCode == SHOW_INFO_WELCOME || requestCode == SHOW_INFO_NEW_VERSION) {
if (resultCode == RESULT_OK) {
showStartupScreensAndDialogs(AnkiDroidApp.getSharedPrefs(getBaseContext()), requestCode == SHOW_INFO_WELCOME ? 1 : 2);
} else {
finishWithAnimation();
}
} else if (requestCode == PREFERENCES_UPDATE) {
String oldPath = mPrefDeckPath;
SharedPreferences pref = restorePreferences();
String newLanguage = pref.getString("language", "");
if (AnkiDroidApp.setLanguage(newLanguage)) {
mInvalidateMenu = true;
}
if (mNotMountedDialog != null && mNotMountedDialog.isShowing() && pref.getBoolean("internalMemory", false)) {
showStartupScreensAndDialogs(pref, 0);
} else if (!mPrefDeckPath.equals(oldPath)) {
loadCollection();
}
// if (resultCode == StudyOptions.RESULT_RESTART) {
// setResult(StudyOptions.RESULT_RESTART);
// finishWithAnimation();
// } else {
// SharedPreferences preferences = PrefSettings.getSharedPrefs(getBaseContext());
// BackupManager.initBackup();
// if (!mPrefDeckPath.equals(preferences.getString("deckPath", AnkiDroidApp.getStorageDirectory())) ||
// mPrefDeckOrder != Integer.parseInt(preferences.getString("deckOrder", "0"))) {
// // populateDeckList(preferences.getString("deckPath", AnkiDroidApp.getStorageDirectory()));
// }
// }
} else if (requestCode == REPORT_FEEDBACK && resultCode == RESULT_OK) {
} else if (requestCode == LOG_IN_FOR_SYNC && resultCode == RESULT_OK) {
sync();
} else if (requestCode == LOG_IN_FOR_SHARED_DECK && resultCode == RESULT_OK) {
addSharedDeck();
} else if (requestCode == ADD_SHARED_DECKS) {
if (intent != null) {
mImportPath = intent.getStringExtra("importPath");
}
if (AnkiDroidApp.colIsOpen() && mImportPath != null) {
DeckTask.launchDeckTask(DeckTask.TASK_TYPE_IMPORT, mImportAddListener, new TaskData(AnkiDroidApp.getCol(), mImportPath, true));
mImportPath = null;
}
} else if (requestCode == REQUEST_REVIEW) {
// Log.i(AnkiDroidApp.TAG, "Result code = " + resultCode);
switch(resultCode) {
default:
// do not reload counts, if activity is created anew because it has been before destroyed by android
loadCounts();
break;
case Reviewer.RESULT_NO_MORE_CARDS:
mDontSaveOnStop = true;
Intent i = new Intent();
i.setClass(this, StudyOptionsActivity.class);
i.putExtra("onlyFnsMsg", true);
startActivityForResult(i, SHOW_STUDYOPTIONS);
if (AnkiDroidApp.SDK_VERSION > 4) {
ActivityTransitionAnimation.slide(this, ActivityTransitionAnimation.RIGHT);
}
break;
}
}
// workaround for hidden dialog on return
BroadcastMessages.showDialog();
}
use of com.ichi2.anki.CardBrowser.Column.CREATED in project Anki-Android by Ramblurr.
the class StudyOptionsFragment method createFilteredDeck.
private void createFilteredDeck(JSONArray delays, Object[] terms, Boolean resched) {
JSONObject dyn;
if (AnkiDroidApp.colIsOpen()) {
Collection col = AnkiDroidApp.getCol();
try {
String deckName = col.getDecks().current().getString("name");
String customStudyDeck = getResources().getString(R.string.custom_study_deck_name);
JSONObject cur = col.getDecks().byName(customStudyDeck);
if (cur != null) {
if (cur.getInt("dyn") != 1) {
StyledDialog.Builder builder = new StyledDialog.Builder(getActivity());
builder.setMessage(R.string.custom_study_deck_exists);
builder.setNegativeButton(getResources().getString(R.string.cancel), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//
}
});
builder.create().show();
return;
} else {
// safe to empty
col.getSched().emptyDyn(cur.getLong("id"));
// reuse; don't delete as it may have children
dyn = cur;
col.getDecks().select(cur.getLong("id"));
}
} else {
long did = col.getDecks().newDyn(customStudyDeck);
dyn = col.getDecks().get(did);
}
// and then set various options
dyn.put("delays", delays);
JSONArray ar = dyn.getJSONArray("terms");
ar.getJSONArray(0).put(0, new StringBuilder("deck:\"").append(deckName).append("\" ").append(terms[0]).toString());
ar.getJSONArray(0).put(1, terms[1]);
ar.getJSONArray(0).put(2, terms[2]);
dyn.put("resched", resched);
if (mFragmented) {
Bundle config = new Bundle();
config.putString("searchSuffix", "'deck:" + dyn.getString("name") + "'");
initAllContentViews(getLayoutInflater(config));
finishCongrats();
} else {
// Load a new fragment with the filtered deck view. The config passed is null, so it uses the
// current deck. The deck we just created is internally set as the current deck.
((StudyOptionsActivity) getActivity()).loadContent(false, null);
}
// Initial rebuild
mProgressDialog = StyledProgressDialog.show(getActivity(), "", getResources().getString(R.string.rebuild_custom_study_deck), true);
DeckTask.launchDeckTask(DeckTask.TASK_TYPE_REBUILD_CRAM, mRebuildCustomStudyListener, new DeckTask.TaskData(AnkiDroidApp.getCol(), AnkiDroidApp.getCol().getDecks().selected(), mFragmented));
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}
use of com.ichi2.anki.CardBrowser.Column.CREATED in project AnkiChinaAndroid by ankichinateam.
the class DeckPicker method showStartupScreensAndDialogs.
public void showStartupScreensAndDialogs(SharedPreferences preferences, int skip) {
if (!BackupManager.enoughDiscSpace(CollectionHelper.getCurrentAnkiDroidDirectory(this))) {
Timber.i("Not enough space to do backup");
showDialogFragment(DeckPickerNoSpaceLeftDialog.newInstance());
} else if (preferences.getBoolean("noSpaceLeft", false)) {
Timber.i("No space left");
showDialogFragment(DeckPickerBackupNoSpaceLeftDialog.newInstance());
preferences.edit().remove("noSpaceLeft").apply();
} else if ("".equals(preferences.getString("lastVersion", ""))) {
Timber.i("Fresh install");
preferences.edit().putString("lastVersion", VersionUtils.getPkgVersionName()).apply();
onFinishedStartup();
} else if (skip < 2 && !preferences.getString("lastVersion", "").equals(VersionUtils.getPkgVersionName())) {
Timber.i("AnkiDroid is being updated and a collection already exists.");
// The user might appreciate us now, see if they will help us get better?
if (!preferences.contains(UsageAnalytics.ANALYTICS_OPTIN_KEY)) {
showDialogFragment(DeckPickerAnalyticsOptInDialog.newInstance());
}
// For upgrades, we check if we are upgrading
// to a version that contains additions to the database integrity check routine that we would
// like to run on all collections. A missing version number is assumed to be a fresh
// installation of AnkiDroid and we don't run the check.
long current = VersionUtils.getPkgVersionCode();
Timber.i("Current AnkiDroid version: %s", current);
long previous;
if (preferences.contains(UPGRADE_VERSION_KEY)) {
// Upgrading currently installed app
previous = getPreviousVersion(preferences, current);
} else {
// Fresh install
previous = current;
}
preferences.edit().putLong(UPGRADE_VERSION_KEY, current).apply();
// It is rebuilt on the next sync or media check
if (previous < 20300200) {
Timber.i("Deleting media database");
File mediaDb = new File(CollectionHelper.getCurrentAnkiDroidDirectory(this), "collection.media.ad.db2");
if (mediaDb.exists()) {
mediaDb.delete();
}
}
// Recommend the user to do a full-sync if they're upgrading from before 2.3.1beta8
if (previous < 20301208) {
Timber.i("Recommend the user to do a full-sync");
mRecommendFullSync = true;
}
// Fix "font-family" definition in templates created by AnkiDroid before 2.6alhpa23
if (previous < 20600123) {
Timber.i("Fixing font-family definition in templates");
try {
Models models = getCol().getModels();
for (Model m : models.all()) {
String css = m.getString("css");
if (css.contains("font-familiy")) {
m.put("css", css.replace("font-familiy", "font-family"));
models.save(m);
}
}
models.flush();
} catch (JSONException e) {
Timber.e(e, "Failed to upgrade css definitions.");
}
}
// Check if preference upgrade or database check required, otherwise go to new feature screen
int upgradePrefsVersion = AnkiDroidApp.CHECK_PREFERENCES_AT_VERSION;
int upgradeDbVersion = AnkiDroidApp.CHECK_DB_AT_VERSION;
// Specifying a checkpoint in the future is not supported, please don't do it!
if (current < upgradePrefsVersion) {
Timber.e("Checkpoint in future produced.");
UIUtils.showSimpleSnackbar(this, "Invalid value for CHECK_PREFERENCES_AT_VERSION", false);
onFinishedStartup();
return;
}
if (current < upgradeDbVersion) {
Timber.e("Invalid value for CHECK_DB_AT_VERSION");
UIUtils.showSimpleSnackbar(this, "Invalid value for CHECK_DB_AT_VERSION", false);
onFinishedStartup();
return;
}
// Skip full DB check if the basic check is OK
// TODO: remove this variable if we really want to do the full db check on every user
boolean skipDbCheck = false;
// noinspection ConstantConditions
if ((!skipDbCheck && previous < upgradeDbVersion) || previous < upgradePrefsVersion) {
if (previous < upgradePrefsVersion) {
Timber.i("showStartupScreensAndDialogs() running upgradePreferences()");
upgradePreferences(previous);
}
// noinspection ConstantConditions
if (!skipDbCheck && previous < upgradeDbVersion) {
Timber.i("showStartupScreensAndDialogs() running integrityCheck()");
// #5852 - since we may have a warning about disk space, we don't want to force a check database
// and show a warning before the user knows what is happening.
new MaterialDialog.Builder(this).title(R.string.integrity_check_startup_title).content(R.string.integrity_check_startup_content).positiveText(R.string.integrity_check_positive).negativeText(R.string.close).onPositive((materialDialog, dialogAction) -> integrityCheck()).onNeutral((materialDialog, dialogAction) -> this.restartActivity()).onNegative((materialDialog, dialogAction) -> this.restartActivity()).canceledOnTouchOutside(false).cancelable(false).build().show();
} else if (previous < upgradePrefsVersion) {
Timber.i("Updated preferences with no integrity check - restarting activity");
// If integrityCheck() doesn't occur, but we did update preferences we should restart DeckPicker to
// proceed
this.restartActivity();
}
} else {
// If no changes are required we go to the new features activity
// There the "lastVersion" is set, so that this code is not reached again
// if (VersionUtils.isReleaseVersion()) {
// Timber.i("Displaying new features");
// Intent infoIntent = new Intent(this, Info.class);
// infoIntent.putExtra(Info.TYPE_EXTRA, Info.TYPE_NEW_VERSION);
//
// if (skip != 0) {
// startActivityForResultWithAnimation(infoIntent, SHOW_INFO_NEW_VERSION,
// ActivityTransitionAnimation.LEFT);
// } else {
// startActivityForResultWithoutAnimation(infoIntent, SHOW_INFO_NEW_VERSION);
// }
// } else {
Timber.i("Dev Build - not showing 'new features'");
// Don't show new features dialog for development builds
preferences.edit().putString("lastVersion", VersionUtils.getPkgVersionName()).apply();
String ver = getResources().getString(R.string.updated_version, VersionUtils.getPkgVersionName());
UIUtils.showSnackbar(this, ver, true, -1, null, findViewById(R.id.root_layout), null);
showStartupScreensAndDialogs(preferences, 2);
// }
}
} else {
// this is the main call when there is nothing special required
Timber.i("No startup screens required");
onFinishedStartup();
}
}
use of com.ichi2.anki.CardBrowser.Column.CREATED in project AnkiChinaAndroid by ankichinateam.
the class CardContentProvider method insert.
@Override
public Uri insert(Uri uri, ContentValues values) {
if (!hasReadWritePermission() && shouldEnforceQueryOrInsertSecurity()) {
throwSecurityException("insert", uri);
}
Collection col = CollectionHelper.getInstance().getCol(mContext);
if (col == null) {
throw new IllegalStateException(COL_NULL_ERROR_MSG);
}
col.log(getLogMessage("insert", uri));
// Find out what data the user is requesting
int match = sUriMatcher.match(uri);
switch(match) {
case NOTES:
{
/* Insert new note with specified fields and tags
*/
Long modelId = values.getAsLong(FlashCardsContract.Note.MID);
String flds = values.getAsString(FlashCardsContract.Note.FLDS);
String tags = values.getAsString(FlashCardsContract.Note.TAGS);
// Create empty note
com.ichi2.libanki.Note newNote = new com.ichi2.libanki.Note(col, col.getModels().get(modelId));
// Set fields
String[] fldsArray = Utils.splitFields(flds);
// Check that correct number of flds specified
if (fldsArray.length != newNote.getFields().length) {
throw new IllegalArgumentException("Incorrect flds argument : " + flds);
}
for (int idx = 0; idx < fldsArray.length; idx++) {
newNote.setField(idx, fldsArray[idx]);
}
// Set tags
if (tags != null) {
newNote.setTagsFromStr(tags);
}
// Add to collection
col.addNote(newNote);
col.save();
return Uri.withAppendedPath(FlashCardsContract.Note.CONTENT_URI, Long.toString(newNote.getId()));
}
case NOTES_ID:
// Note ID is generated automatically by libanki
throw new IllegalArgumentException("Not possible to insert note with specific ID");
case NOTES_ID_CARDS:
// Cards are generated automatically by libanki
throw new IllegalArgumentException("Not possible to insert cards directly (only through NOTES)");
case NOTES_ID_CARDS_ORD:
// Cards are generated automatically by libanki
throw new IllegalArgumentException("Not possible to insert cards directly (only through NOTES)");
case MODELS:
// Get input arguments
String modelName = values.getAsString(FlashCardsContract.Model.NAME);
String css = values.getAsString(FlashCardsContract.Model.CSS);
Long did = values.getAsLong(FlashCardsContract.Model.DECK_ID);
String fieldNames = values.getAsString(FlashCardsContract.Model.FIELD_NAMES);
Integer numCards = values.getAsInteger(FlashCardsContract.Model.NUM_CARDS);
Integer sortf = values.getAsInteger(FlashCardsContract.Model.SORT_FIELD_INDEX);
Integer type = values.getAsInteger(FlashCardsContract.Model.TYPE);
String latexPost = values.getAsString(FlashCardsContract.Model.LATEX_POST);
String latexPre = values.getAsString(FlashCardsContract.Model.LATEX_PRE);
// Throw exception if required fields empty
if (modelName == null || fieldNames == null || numCards == null) {
throw new IllegalArgumentException("Model name, field_names, and num_cards can't be empty");
}
if (did != null && col.getDecks().isDyn(did)) {
throw new IllegalArgumentException("Cannot set a filtered deck as default deck for a model");
}
// Create a new model
Models mm = col.getModels();
Model newModel = mm.newModel(modelName);
try {
// Add the fields
String[] allFields = Utils.splitFields(fieldNames);
for (String f : allFields) {
mm.addFieldInNewModel(newModel, mm.newField(f));
}
// Add some empty card templates
for (int idx = 0; idx < numCards; idx++) {
JSONObject t = mm.newTemplate("Card " + (idx + 1));
t.put("qfmt", String.format("{{%s}}", allFields[0]));
String answerField = allFields[0];
if (allFields.length > 1) {
answerField = allFields[1];
}
t.put("afmt", String.format("{{FrontSide}}\\n\\n<hr id=answer>\\n\\n{{%s}}", answerField));
mm.addTemplateInNewModel(newModel, t);
}
// Add the CSS if specified
if (css != null) {
newModel.put("css", css);
}
// Add the did if specified
if (did != null) {
newModel.put("did", did);
}
if (sortf != null && sortf < allFields.length) {
newModel.put("sortf", sortf);
}
if (type != null) {
newModel.put("type", type);
}
if (latexPost != null) {
newModel.put("latexPost", latexPost);
}
if (latexPre != null) {
newModel.put("latexPre", latexPre);
}
// Add the model to collection (from this point on edits will require a full-sync)
mm.add(newModel);
col.save();
// Get the mid and return a URI
String mid = Long.toString(newModel.getLong("id"));
return Uri.withAppendedPath(FlashCardsContract.Model.CONTENT_URI, mid);
} catch (JSONException e) {
Timber.e(e, "Could not set a field of new model %s", modelName);
return null;
}
case MODELS_ID:
// Model ID is generated automatically by libanki
throw new IllegalArgumentException("Not possible to insert model with specific ID");
case MODELS_ID_TEMPLATES:
{
Models models = col.getModels();
Long mid = getModelIdFromUri(uri, col);
Model existingModel = models.get(mid);
if (existingModel == null) {
throw new IllegalArgumentException("model missing: " + mid);
}
String name = values.getAsString(CardTemplate.NAME);
String qfmt = values.getAsString(CardTemplate.QUESTION_FORMAT);
String afmt = values.getAsString(CardTemplate.ANSWER_FORMAT);
String bqfmt = values.getAsString(CardTemplate.BROWSER_QUESTION_FORMAT);
String bafmt = values.getAsString(CardTemplate.BROWSER_ANSWER_FORMAT);
try {
JSONObject t = models.newTemplate(name);
t.put("qfmt", qfmt);
t.put("afmt", afmt);
t.put("bqfmt", bqfmt);
t.put("bafmt", bafmt);
models.addTemplate(existingModel, t);
models.save(existingModel);
col.save();
return ContentUris.withAppendedId(uri, t.getInt("ord"));
} catch (ConfirmModSchemaException e) {
throw new IllegalArgumentException("Unable to add template without user requesting/accepting full-sync", e);
} catch (JSONException e) {
throw new IllegalArgumentException("Unable to get ord from new template", e);
}
}
case MODELS_ID_TEMPLATES_ID:
throw new IllegalArgumentException("Not possible to insert template with specific ORD");
case MODELS_ID_FIELDS:
{
Models models = col.getModels();
Long mid = getModelIdFromUri(uri, col);
Model existingModel = models.get(mid);
if (existingModel == null) {
throw new IllegalArgumentException("model missing: " + mid);
}
String name = values.getAsString(FlashCardsContract.Model.FIELD_NAME);
if (name == null) {
throw new IllegalArgumentException("field name missing for model: " + mid);
}
JSONObject field = models.newField(name);
try {
models.addField(existingModel, field);
col.save();
JSONArray flds = existingModel.getJSONArray("flds");
return ContentUris.withAppendedId(uri, flds.length() - 1);
} catch (ConfirmModSchemaException e) {
throw new IllegalArgumentException("Unable to insert field: " + name, e);
} catch (JSONException e) {
throw new IllegalArgumentException("Unable to get newly created field: " + name, e);
}
}
case SCHEDULE:
// Doesn't make sense to insert an object into the schedule table
throw new IllegalArgumentException("Not possible to perform insert operation on schedule");
case DECKS:
// Insert new deck with specified name
String deckName = values.getAsString(FlashCardsContract.Deck.DECK_NAME);
did = col.getDecks().id(deckName, false);
if (did != null) {
throw new IllegalArgumentException("Deck name already exists: " + deckName);
}
if (!Decks.isValidDeckName(deckName)) {
throw new IllegalArgumentException("Invalid deck name '" + deckName + "'");
}
did = col.getDecks().id(deckName, true);
Deck deck = col.getDecks().get(did);
if (deck != null) {
try {
String deckDesc = values.getAsString(FlashCardsContract.Deck.DECK_DESC);
if (deckDesc != null) {
deck.put("desc", deckDesc);
}
} catch (JSONException e) {
Timber.e(e, "Could not set a field of new deck %s", deckName);
return null;
}
}
col.getDecks().flush();
return Uri.withAppendedPath(FlashCardsContract.Deck.CONTENT_ALL_URI, Long.toString(did));
case DECK_SELECTED:
// Can't have more than one selected deck
throw new IllegalArgumentException("Selected deck can only be queried and updated");
case DECKS_ID:
// Deck ID is generated automatically by libanki
throw new IllegalArgumentException("Not possible to insert deck with specific ID");
default:
// Unknown URI type
throw new IllegalArgumentException("uri " + uri + " is not supported");
}
}
use of com.ichi2.anki.CardBrowser.Column.CREATED in project AnkiChinaAndroid by ankichinateam.
the class ContentProviderTest method tearDown.
/**
* Remove the notes and decks created in setUp().
*/
@After
public void tearDown() throws Exception {
Log.i(AnkiDroidApp.TAG, "tearDown()");
if (!tearDown) {
return;
}
final Collection col = getCol();
// Delete all notes
List<Long> remnantNotes = col.findNotes("tag:" + TEST_TAG);
if (remnantNotes.size() > 0) {
long[] noteIds = Utils.collection2Array(remnantNotes);
col.remNotes(noteIds);
col.save();
assertEquals("Check that remnant notes have been deleted", 0, col.findNotes("tag:" + TEST_TAG).size());
}
// delete test decks
for (long did : mTestDeckIds) {
col.getDecks().rem(did, true, true);
}
col.getDecks().flush();
assertEquals("Check that all created decks have been deleted", mNumDecksBeforeTest, col.getDecks().count());
// Delete test model
col.modSchemaNoCheck();
removeAllModelsByName(col, BASIC_MODEL_NAME);
removeAllModelsByName(col, TEST_MODEL_NAME);
}
Aggregations