use of com.ichi2.anki.CardBrowser.Column in project AnkiChinaAndroid by ankichinateam.
the class CardContentProvider method addModelToCursor.
private void addModelToCursor(Long modelId, Models models, MatrixCursor rv, String[] columns) {
Model jsonObject = models.get(modelId);
MatrixCursor.RowBuilder rb = rv.newRow();
try {
for (String column : columns) {
if (column.equals(FlashCardsContract.Model._ID)) {
rb.add(modelId);
} else if (column.equals(FlashCardsContract.Model.NAME)) {
rb.add(jsonObject.getString("name"));
} else if (column.equals(FlashCardsContract.Model.FIELD_NAMES)) {
JSONArray flds = jsonObject.getJSONArray("flds");
String[] allFlds = new String[flds.length()];
for (int idx = 0; idx < flds.length(); idx++) {
allFlds[idx] = flds.getJSONObject(idx).optString("name", "");
}
rb.add(Utils.joinFields(allFlds));
} else if (column.equals(FlashCardsContract.Model.NUM_CARDS)) {
rb.add(jsonObject.getJSONArray("tmpls").length());
} else if (column.equals(FlashCardsContract.Model.CSS)) {
rb.add(jsonObject.getString("css"));
} else if (column.equals(FlashCardsContract.Model.DECK_ID)) {
// #6378 - Anki Desktop changed schema temporarily to allow null
rb.add(jsonObject.optLong("did", Consts.DEFAULT_DECK_ID));
} else if (column.equals(FlashCardsContract.Model.SORT_FIELD_INDEX)) {
rb.add(jsonObject.getLong("sortf"));
} else if (column.equals(FlashCardsContract.Model.TYPE)) {
rb.add(jsonObject.getLong("type"));
} else if (column.equals(FlashCardsContract.Model.LATEX_POST)) {
rb.add(jsonObject.getString("latexPost"));
} else if (column.equals(FlashCardsContract.Model.LATEX_PRE)) {
rb.add(jsonObject.getString("latexPre"));
} else if (column.equals(FlashCardsContract.Model.NOTE_COUNT)) {
rb.add(models.useCount(jsonObject));
} else {
throw new UnsupportedOperationException("Column \"" + column + "\" is unknown");
}
}
} catch (JSONException e) {
Timber.e(e, "Error parsing JSONArray");
throw new IllegalArgumentException("Model " + modelId + " is malformed", e);
}
}
use of com.ichi2.anki.CardBrowser.Column in project Anki-Android by ankidroid.
the class CardContentProvider method update.
@Override
public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
if (!hasReadWritePermission() && shouldEnforceUpdateSecurity(uri)) {
throwSecurityException("update", uri);
}
Collection col = CollectionHelper.getInstance().getCol(mContext);
if (col == null) {
throw new IllegalStateException(COL_NULL_ERROR_MSG);
}
col.log(getLogMessage("update", uri));
// Find out what data the user is requesting
int match = sUriMatcher.match(uri);
// Number of updated entries (return value)
int updated = 0;
switch(match) {
case NOTES_V2:
case NOTES:
throw new IllegalArgumentException("Not possible to update notes directly (only through data URI)");
case NOTES_ID:
{
/* Direct access note details
*/
Note currentNote = getNoteFromUri(uri, col);
// the key of the ContentValues contains the column name
// the value of the ContentValues contains the row value.
Set<Map.Entry<String, Object>> valueSet = values.valueSet();
for (Map.Entry<String, Object> entry : valueSet) {
String key = entry.getKey();
// when the client does not specify FLDS, then don't update the FLDS
if (key.equals(FlashCardsContract.Note.FLDS)) {
// Update FLDS
Timber.d("CardContentProvider: flds update...");
String newFldsEncoded = (String) entry.getValue();
String[] flds = Utils.splitFields(newFldsEncoded);
// Check that correct number of flds specified
if (flds.length != currentNote.getFields().length) {
throw new IllegalArgumentException("Incorrect flds argument : " + newFldsEncoded);
}
// Update the note
for (int idx = 0; idx < flds.length; idx++) {
currentNote.setField(idx, flds[idx]);
}
updated++;
} else if (key.equals(FlashCardsContract.Note.TAGS)) {
// Update tags
Timber.d("CardContentProvider: tags update...");
Object tags = entry.getValue();
if (tags != null) {
currentNote.setTagsFromStr(String.valueOf(tags));
}
updated++;
} else {
// Unsupported column
throw new IllegalArgumentException("Unsupported column: " + key);
}
}
Timber.d("CardContentProvider: Saving note...");
currentNote.flush();
break;
}
case NOTES_ID_CARDS:
// TODO: To be implemented
throw new UnsupportedOperationException("Not yet implemented");
// break;
case NOTES_ID_CARDS_ORD:
{
Card currentCard = getCardFromUri(uri, col);
boolean isDeckUpdate = false;
long did = Decks.NOT_FOUND_DECK_ID;
// the key of the ContentValues contains the column name
// the value of the ContentValues contains the row value.
Set<Map.Entry<String, Object>> valueSet = values.valueSet();
for (Map.Entry<String, Object> entry : valueSet) {
// Only updates on deck id is supported
String key = entry.getKey();
isDeckUpdate = key.equals(FlashCardsContract.Card.DECK_ID);
did = values.getAsLong(key);
}
if (col.getDecks().isDyn(did)) {
throw new IllegalArgumentException("Cards cannot be moved to a filtered deck");
}
/* now update the card
*/
if ((isDeckUpdate) && (did >= 0)) {
Timber.d("CardContentProvider: Moving card to other deck...");
col.getDecks().flush();
currentCard.setDid(did);
currentCard.flush();
col.save();
updated++;
} else {
// User tries an operation that is not (yet?) supported.
throw new IllegalArgumentException("Currently only updates of decks are supported");
}
break;
}
case MODELS:
throw new IllegalArgumentException("Cannot update models in bulk");
case MODELS_ID:
// Get the input parameters
String newModelName = values.getAsString(FlashCardsContract.Model.NAME);
String newCss = values.getAsString(FlashCardsContract.Model.CSS);
String newDid = values.getAsString(FlashCardsContract.Model.DECK_ID);
String newFieldList = values.getAsString(FlashCardsContract.Model.FIELD_NAMES);
if (newFieldList != null) {
// Changing the field names would require a full-sync
throw new IllegalArgumentException("Field names cannot be changed via provider");
}
Integer newSortf = values.getAsInteger(FlashCardsContract.Model.SORT_FIELD_INDEX);
Integer newType = values.getAsInteger(FlashCardsContract.Model.TYPE);
String newLatexPost = values.getAsString(FlashCardsContract.Model.LATEX_POST);
String newLatexPre = values.getAsString(FlashCardsContract.Model.LATEX_PRE);
// Get the original note JSON
Model model = col.getModels().get(getModelIdFromUri(uri, col));
try {
// Update model name and/or css
if (newModelName != null) {
model.put("name", newModelName);
updated++;
}
if (newCss != null) {
model.put("css", newCss);
updated++;
}
if (newDid != null) {
if (col.getDecks().isDyn(Long.parseLong(newDid))) {
throw new IllegalArgumentException("Cannot set a filtered deck as default deck for a model");
}
model.put("did", newDid);
updated++;
}
if (newSortf != null) {
model.put("sortf", newSortf);
updated++;
}
if (newType != null) {
model.put("type", newType);
updated++;
}
if (newLatexPost != null) {
model.put("latexPost", newLatexPost);
updated++;
}
if (newLatexPre != null) {
model.put("latexPre", newLatexPre);
updated++;
}
col.getModels().save(model);
col.save();
} catch (JSONException e) {
Timber.e(e, "JSONException updating model");
}
break;
case MODELS_ID_TEMPLATES:
throw new IllegalArgumentException("Cannot update templates in bulk");
case MODELS_ID_TEMPLATES_ID:
Long mid = values.getAsLong(CardTemplate.MODEL_ID);
Integer ord = values.getAsInteger(CardTemplate.ORD);
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);
// Throw exception if read-only fields are included
if (mid != null || ord != null) {
throw new IllegalArgumentException("Updates to mid or ord are not allowed");
}
// Update the model
try {
int templateOrd = Integer.parseInt(uri.getLastPathSegment());
Model existingModel = col.getModels().get(getModelIdFromUri(uri, col));
JSONArray templates = existingModel.getJSONArray("tmpls");
JSONObject template = templates.getJSONObject(templateOrd);
if (name != null) {
template.put("name", name);
updated++;
}
if (qfmt != null) {
template.put("qfmt", qfmt);
updated++;
}
if (afmt != null) {
template.put("afmt", afmt);
updated++;
}
if (bqfmt != null) {
template.put("bqfmt", bqfmt);
updated++;
}
if (bafmt != null) {
template.put("bafmt", bafmt);
updated++;
}
// Save the model
templates.put(templateOrd, template);
existingModel.put("tmpls", templates);
col.getModels().save(existingModel, true);
col.save();
} catch (JSONException e) {
throw new IllegalArgumentException("Model is malformed", e);
}
break;
case SCHEDULE:
{
Set<Map.Entry<String, Object>> valueSet = values.valueSet();
int cardOrd = -1;
long noteID = -1;
int ease = -1;
long timeTaken = -1;
int bury = -1;
int suspend = -1;
for (Map.Entry<String, Object> entry : valueSet) {
String key = entry.getKey();
switch(key) {
case FlashCardsContract.ReviewInfo.NOTE_ID:
noteID = values.getAsLong(key);
break;
case FlashCardsContract.ReviewInfo.CARD_ORD:
cardOrd = values.getAsInteger(key);
break;
case FlashCardsContract.ReviewInfo.EASE:
ease = values.getAsInteger(key);
break;
case FlashCardsContract.ReviewInfo.TIME_TAKEN:
timeTaken = values.getAsLong(key);
break;
case FlashCardsContract.ReviewInfo.BURY:
bury = values.getAsInteger(key);
break;
case FlashCardsContract.ReviewInfo.SUSPEND:
suspend = values.getAsInteger(key);
break;
}
}
if (cardOrd != -1 && noteID != -1) {
Card cardToAnswer = getCard(noteID, cardOrd, col);
if (cardToAnswer != null) {
if (bury == 1) {
// bury card
buryOrSuspendCard(col, col.getSched(), cardToAnswer, true);
} else if (suspend == 1) {
// suspend card
buryOrSuspendCard(col, col.getSched(), cardToAnswer, false);
} else {
answerCard(col, col.getSched(), cardToAnswer, ease, timeTaken);
}
updated++;
} else {
Timber.e("Requested card with noteId %d and cardOrd %d was not found. Either the provided " + "noteId/cardOrd were wrong or the card has been deleted in the meantime.", noteID, cardOrd);
}
}
break;
}
case DECKS:
throw new IllegalArgumentException("Can't update decks in bulk");
case DECKS_ID:
// TODO: be sure to throw exception if change to the dyn value of a deck is requested
throw new UnsupportedOperationException("Not yet implemented");
case DECK_SELECTED:
{
Set<Map.Entry<String, Object>> valueSet = values.valueSet();
for (Map.Entry<String, Object> entry : valueSet) {
String key = entry.getKey();
if (key.equals(FlashCardsContract.Deck.DECK_ID)) {
long deckId = values.getAsLong(key);
if (selectDeckWithCheck(col, deckId)) {
updated++;
}
}
}
col.save();
break;
}
default:
// Unknown URI type
throw new IllegalArgumentException("uri " + uri + " is not supported");
}
return updated;
}
use of com.ichi2.anki.CardBrowser.Column 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 in project AnkiChinaAndroid by ankichinateam.
the class CardContentProvider method update.
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
if (!hasReadWritePermission() && shouldEnforceUpdateSecurity(uri)) {
throwSecurityException("update", uri);
}
Collection col = CollectionHelper.getInstance().getCol(mContext);
if (col == null) {
throw new IllegalStateException(COL_NULL_ERROR_MSG);
}
col.log(getLogMessage("update", uri));
// Find out what data the user is requesting
int match = sUriMatcher.match(uri);
// Number of updated entries (return value)
int updated = 0;
switch(match) {
case NOTES_V2:
case NOTES:
throw new IllegalArgumentException("Not possible to update notes directly (only through data URI)");
case NOTES_ID:
{
/* Direct access note details
*/
Note currentNote = getNoteFromUri(uri, col);
// the key of the ContentValues contains the column name
// the value of the ContentValues contains the row value.
Set<Map.Entry<String, Object>> valueSet = values.valueSet();
for (Map.Entry<String, Object> entry : valueSet) {
String key = entry.getKey();
// when the client does not specify FLDS, then don't update the FLDS
if (key.equals(FlashCardsContract.Note.FLDS)) {
// Update FLDS
Timber.d("CardContentProvider: flds update...");
String newFldsEncoded = (String) entry.getValue();
String[] flds = Utils.splitFields(newFldsEncoded);
// Check that correct number of flds specified
if (flds.length != currentNote.getFields().length) {
throw new IllegalArgumentException("Incorrect flds argument : " + newFldsEncoded);
}
// Update the note
for (int idx = 0; idx < flds.length; idx++) {
currentNote.setField(idx, flds[idx]);
}
updated++;
} else if (key.equals(FlashCardsContract.Note.TAGS)) {
// Update tags
Timber.d("CardContentProvider: tags update...");
Object tags = entry.getValue();
if (tags != null) {
currentNote.setTagsFromStr(String.valueOf(tags));
}
updated++;
} else {
// Unsupported column
throw new IllegalArgumentException("Unsupported column: " + key);
}
}
Timber.d("CardContentProvider: Saving note...");
currentNote.flush();
break;
}
case NOTES_ID_CARDS:
// TODO: To be implemented
throw new UnsupportedOperationException("Not yet implemented");
// break;
case NOTES_ID_CARDS_ORD:
{
Card currentCard = getCardFromUri(uri, col);
boolean isDeckUpdate = false;
long did = -1;
// the key of the ContentValues contains the column name
// the value of the ContentValues contains the row value.
Set<Map.Entry<String, Object>> valueSet = values.valueSet();
for (Map.Entry<String, Object> entry : valueSet) {
// Only updates on deck id is supported
String key = entry.getKey();
isDeckUpdate = key.equals(FlashCardsContract.Card.DECK_ID);
did = values.getAsLong(key);
}
if (col.getDecks().isDyn(did)) {
throw new IllegalArgumentException("Cards cannot be moved to a filtered deck");
}
/* now update the card
*/
if ((isDeckUpdate) && (did >= 0)) {
Timber.d("CardContentProvider: Moving card to other deck...");
col.getDecks().flush();
currentCard.setDid(did);
currentCard.flush();
col.save();
updated++;
} else {
// User tries an operation that is not (yet?) supported.
throw new IllegalArgumentException("Currently only updates of decks are supported");
}
break;
}
case MODELS:
throw new IllegalArgumentException("Cannot update models in bulk");
case MODELS_ID:
// Get the input parameters
String newModelName = values.getAsString(FlashCardsContract.Model.NAME);
String newCss = values.getAsString(FlashCardsContract.Model.CSS);
String newDid = values.getAsString(FlashCardsContract.Model.DECK_ID);
String newFieldList = values.getAsString(FlashCardsContract.Model.FIELD_NAMES);
if (newFieldList != null) {
// Changing the field names would require a full-sync
throw new IllegalArgumentException("Field names cannot be changed via provider");
}
Integer newSortf = values.getAsInteger(FlashCardsContract.Model.SORT_FIELD_INDEX);
Integer newType = values.getAsInteger(FlashCardsContract.Model.TYPE);
String newLatexPost = values.getAsString(FlashCardsContract.Model.LATEX_POST);
String newLatexPre = values.getAsString(FlashCardsContract.Model.LATEX_PRE);
// Get the original note JSON
Model model = col.getModels().get(getModelIdFromUri(uri, col));
try {
// Update model name and/or css
if (newModelName != null) {
model.put("name", newModelName);
updated++;
}
if (newCss != null) {
model.put("css", newCss);
updated++;
}
if (newDid != null) {
if (col.getDecks().isDyn(Long.parseLong(newDid))) {
throw new IllegalArgumentException("Cannot set a filtered deck as default deck for a model");
}
model.put("did", newDid);
updated++;
}
if (newSortf != null) {
model.put("sortf", newSortf);
updated++;
}
if (newType != null) {
model.put("type", newType);
updated++;
}
if (newLatexPost != null) {
model.put("latexPost", newLatexPost);
updated++;
}
if (newLatexPre != null) {
model.put("latexPre", newLatexPre);
updated++;
}
col.getModels().save(model);
col.save();
} catch (JSONException e) {
Timber.e(e, "JSONException updating model");
}
break;
case MODELS_ID_TEMPLATES:
throw new IllegalArgumentException("Cannot update templates in bulk");
case MODELS_ID_TEMPLATES_ID:
Long mid = values.getAsLong(CardTemplate.MODEL_ID);
Integer ord = values.getAsInteger(CardTemplate.ORD);
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);
// Throw exception if read-only fields are included
if (mid != null || ord != null) {
throw new IllegalArgumentException("Updates to mid or ord are not allowed");
}
// Update the model
try {
Integer templateOrd = Integer.parseInt(uri.getLastPathSegment());
Model existingModel = col.getModels().get(getModelIdFromUri(uri, col));
JSONArray templates = existingModel.getJSONArray("tmpls");
JSONObject template = templates.getJSONObject(templateOrd);
if (name != null) {
template.put("name", name);
updated++;
}
if (qfmt != null) {
template.put("qfmt", qfmt);
updated++;
}
if (afmt != null) {
template.put("afmt", afmt);
updated++;
}
if (bqfmt != null) {
template.put("bqfmt", bqfmt);
updated++;
}
if (bafmt != null) {
template.put("bafmt", bafmt);
updated++;
}
// Save the model
templates.put(templateOrd, template);
existingModel.put("tmpls", templates);
col.getModels().save(existingModel, true);
col.save();
} catch (JSONException e) {
throw new IllegalArgumentException("Model is malformed", e);
}
break;
case SCHEDULE:
{
Set<Map.Entry<String, Object>> valueSet = values.valueSet();
int cardOrd = -1;
long noteID = -1;
int ease = -1;
long timeTaken = -1;
int bury = -1;
int suspend = -1;
for (Map.Entry<String, Object> entry : valueSet) {
String key = entry.getKey();
if (key.equals(FlashCardsContract.ReviewInfo.NOTE_ID)) {
noteID = values.getAsLong(key);
} else if (key.equals(FlashCardsContract.ReviewInfo.CARD_ORD)) {
cardOrd = values.getAsInteger(key);
} else if (key.equals(FlashCardsContract.ReviewInfo.EASE)) {
ease = values.getAsInteger(key);
} else if (key.equals(FlashCardsContract.ReviewInfo.TIME_TAKEN)) {
timeTaken = values.getAsLong(key);
} else if (key.equals(FlashCardsContract.ReviewInfo.BURY)) {
bury = values.getAsInteger(key);
} else if (key.equals(FlashCardsContract.ReviewInfo.SUSPEND)) {
suspend = values.getAsInteger(key);
}
}
if (cardOrd != -1 && noteID != -1) {
Card cardToAnswer = getCard(noteID, cardOrd, col);
if (cardToAnswer != null) {
if (bury == 1) {
// bury card
buryOrSuspendCard(col, col.getSched(), cardToAnswer, true);
} else if (suspend == 1) {
// suspend card
buryOrSuspendCard(col, col.getSched(), cardToAnswer, false);
} else {
answerCard(col, col.getSched(), cardToAnswer, ease, timeTaken);
}
updated++;
} else {
Timber.e("Requested card with noteId %d and cardOrd %d was not found. Either the provided " + "noteId/cardOrd were wrong or the card has been deleted in the meantime.", noteID, cardOrd);
}
}
break;
}
case DECKS:
throw new IllegalArgumentException("Can't update decks in bulk");
case DECKS_ID:
// TODO: be sure to throw exception if change to the dyn value of a deck is requested
throw new UnsupportedOperationException("Not yet implemented");
case DECK_SELECTED:
{
Set<Map.Entry<String, Object>> valueSet = values.valueSet();
for (Map.Entry<String, Object> entry : valueSet) {
String key = entry.getKey();
if (key.equals(FlashCardsContract.Deck.DECK_ID)) {
long deckId = values.getAsLong(key);
if (selectDeckWithCheck(col, deckId)) {
updated++;
}
}
}
col.save();
break;
}
default:
// Unknown URI type
throw new IllegalArgumentException("uri " + uri + " is not supported");
}
return updated;
}
use of com.ichi2.anki.CardBrowser.Column in project Anki-Android by ankidroid.
the class CardContentProvider method addModelToCursor.
private void addModelToCursor(Long modelId, ModelManager models, MatrixCursor rv, String[] columns) {
Model jsonObject = models.get(modelId);
MatrixCursor.RowBuilder rb = rv.newRow();
try {
for (String column : columns) {
switch(column) {
case FlashCardsContract.Model._ID:
rb.add(modelId);
break;
case FlashCardsContract.Model.NAME:
rb.add(jsonObject.getString("name"));
break;
case FlashCardsContract.Model.FIELD_NAMES:
JSONArray flds = jsonObject.getJSONArray("flds");
String[] allFlds = new String[flds.length()];
for (int idx = 0; idx < flds.length(); idx++) {
allFlds[idx] = flds.getJSONObject(idx).optString("name", "");
}
rb.add(Utils.joinFields(allFlds));
break;
case FlashCardsContract.Model.NUM_CARDS:
rb.add(jsonObject.getJSONArray("tmpls").length());
break;
case FlashCardsContract.Model.CSS:
rb.add(jsonObject.getString("css"));
break;
case FlashCardsContract.Model.DECK_ID:
// #6378 - Anki Desktop changed schema temporarily to allow null
rb.add(jsonObject.optLong("did", Consts.DEFAULT_DECK_ID));
break;
case FlashCardsContract.Model.SORT_FIELD_INDEX:
rb.add(jsonObject.getLong("sortf"));
break;
case FlashCardsContract.Model.TYPE:
rb.add(jsonObject.getLong("type"));
break;
case FlashCardsContract.Model.LATEX_POST:
rb.add(jsonObject.getString("latexPost"));
break;
case FlashCardsContract.Model.LATEX_PRE:
rb.add(jsonObject.getString("latexPre"));
break;
case FlashCardsContract.Model.NOTE_COUNT:
rb.add(models.useCount(jsonObject));
break;
default:
throw new UnsupportedOperationException("Queue \"" + column + "\" is unknown");
}
}
} catch (JSONException e) {
Timber.e(e, "Error parsing JSONArray");
throw new IllegalArgumentException("Model " + modelId + " is malformed", e);
}
}
Aggregations