use of com.ichi2.anki.CardBrowser.Column.CHANGED in project Anki-Android by ankidroid.
the class CardContentProvider method query.
@Override
public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String order) {
if (!hasReadWritePermission() && shouldEnforceQueryOrInsertSecurity()) {
throwSecurityException("query", uri);
}
Collection col = CollectionHelper.getInstance().getCol(mContext);
if (col == null) {
throw new IllegalStateException(COL_NULL_ERROR_MSG);
}
Timber.d(getLogMessage("query", uri));
// Find out what data the user is requesting
int match = sUriMatcher.match(uri);
switch(match) {
case NOTES_V2:
{
/* Search for notes using direct SQL query */
String[] proj = sanitizeNoteProjection(projection);
String sql = SQLiteQueryBuilder.buildQueryString(false, "notes", proj, selection, null, null, order, null);
// Needed for varargs of query
return col.getDb().query(sql, (Object[]) selectionArgs);
}
case NOTES:
{
/* Search for notes using the libanki browser syntax */
String[] proj = sanitizeNoteProjection(projection);
String query = (selection != null) ? selection : "";
List<Long> noteIds = col.findNotes(query);
if ((noteIds != null) && (!noteIds.isEmpty())) {
String sel = String.format("id in (%s)", TextUtils.join(",", noteIds));
String sql = SQLiteQueryBuilder.buildQueryString(false, "notes", proj, sel, null, null, order, null);
return col.getDb().getDatabase().query(sql);
} else {
return null;
}
}
case NOTES_ID:
{
/* Direct access note with specific ID*/
String noteId = uri.getPathSegments().get(1);
String[] proj = sanitizeNoteProjection(projection);
String sql = SQLiteQueryBuilder.buildQueryString(false, "notes", proj, "id=?", null, null, order, null);
return col.getDb().query(sql, noteId);
}
case NOTES_ID_CARDS:
{
Note currentNote = getNoteFromUri(uri, col);
String[] columns = ((projection != null) ? projection : FlashCardsContract.Card.DEFAULT_PROJECTION);
MatrixCursor rv = new MatrixCursor(columns, 1);
for (Card currentCard : currentNote.cards()) {
addCardToCursor(currentCard, rv, col, columns);
}
return rv;
}
case NOTES_ID_CARDS_ORD:
{
Card currentCard = getCardFromUri(uri, col);
String[] columns = ((projection != null) ? projection : FlashCardsContract.Card.DEFAULT_PROJECTION);
MatrixCursor rv = new MatrixCursor(columns, 1);
addCardToCursor(currentCard, rv, col, columns);
return rv;
}
case MODELS:
{
ModelManager models = col.getModels();
String[] columns = ((projection != null) ? projection : FlashCardsContract.Model.DEFAULT_PROJECTION);
MatrixCursor rv = new MatrixCursor(columns, 1);
for (Long modelId : models.getModels().keySet()) {
addModelToCursor(modelId, models, rv, columns);
}
return rv;
}
case MODELS_ID:
{
long modelId = getModelIdFromUri(uri, col);
String[] columns = ((projection != null) ? projection : FlashCardsContract.Model.DEFAULT_PROJECTION);
MatrixCursor rv = new MatrixCursor(columns, 1);
addModelToCursor(modelId, col.getModels(), rv, columns);
return rv;
}
case MODELS_ID_TEMPLATES:
{
/* Direct access model templates */
ModelManager models = col.getModels();
Model currentModel = models.get(getModelIdFromUri(uri, col));
String[] columns = ((projection != null) ? projection : CardTemplate.DEFAULT_PROJECTION);
MatrixCursor rv = new MatrixCursor(columns, 1);
try {
JSONArray templates = currentModel.getJSONArray("tmpls");
for (int idx = 0; idx < templates.length(); idx++) {
JSONObject template = templates.getJSONObject(idx);
addTemplateToCursor(template, currentModel, idx + 1, models, rv, columns);
}
} catch (JSONException e) {
throw new IllegalArgumentException("Model is malformed", e);
}
return rv;
}
case MODELS_ID_TEMPLATES_ID:
{
/* Direct access model template with specific ID */
ModelManager models = col.getModels();
int ord = Integer.parseInt(uri.getLastPathSegment());
Model currentModel = models.get(getModelIdFromUri(uri, col));
String[] columns = ((projection != null) ? projection : CardTemplate.DEFAULT_PROJECTION);
MatrixCursor rv = new MatrixCursor(columns, 1);
try {
JSONObject template = getTemplateFromUri(uri, col);
addTemplateToCursor(template, currentModel, ord + 1, models, rv, columns);
} catch (JSONException e) {
throw new IllegalArgumentException("Model is malformed", e);
}
return rv;
}
case SCHEDULE:
{
String[] columns = ((projection != null) ? projection : FlashCardsContract.ReviewInfo.DEFAULT_PROJECTION);
MatrixCursor rv = new MatrixCursor(columns, 1);
long selectedDeckBeforeQuery = col.getDecks().selected();
long deckIdOfTemporarilySelectedDeck = -1;
// the number of scheduled cards to return
int limit = 1;
int selectionArgIndex = 0;
// parsing the selection arguments
if (selection != null) {
// split selection to get arguments like "limit=?"
String[] args = selection.split(",");
for (String arg : args) {
// split arguments into key ("limit") and value ("?")
String[] keyAndValue = arg.split("=");
try {
// check if value is a placeholder ("?"), if so replace with the next value of selectionArgs
String value = "?".equals(keyAndValue[1].trim()) ? selectionArgs[selectionArgIndex++] : keyAndValue[1];
if ("limit".equals(keyAndValue[0].trim())) {
limit = Integer.parseInt(value);
} else if ("deckID".equals(keyAndValue[0].trim())) {
deckIdOfTemporarilySelectedDeck = Long.parseLong(value);
if (!selectDeckWithCheck(col, deckIdOfTemporarilySelectedDeck)) {
// if the provided deckID is wrong, return empty cursor.
return rv;
}
}
} catch (NumberFormatException nfe) {
Timber.w(nfe);
}
}
}
// retrieve the number of cards provided by the selection parameter "limit"
col.getSched().deferReset();
for (int k = 0; k < limit; k++) {
Card currentCard = col.getSched().getCard();
if (currentCard == null) {
break;
}
int buttonCount = col.getSched().answerButtons(currentCard);
JSONArray buttonTexts = new JSONArray();
for (int i = 0; i < buttonCount; i++) {
buttonTexts.put(col.getSched().nextIvlStr(mContext, currentCard, i + 1));
}
addReviewInfoToCursor(currentCard, buttonTexts, buttonCount, rv, col, columns);
}
if (deckIdOfTemporarilySelectedDeck != -1) {
// if the selected deck was changed
// change the selected deck back to the one it was before the query
col.getDecks().select(selectedDeckBeforeQuery);
}
return rv;
}
case DECKS:
{
List<DeckDueTreeNode> allDecks = col.getSched().deckDueList();
String[] columns = ((projection != null) ? projection : FlashCardsContract.Deck.DEFAULT_PROJECTION);
MatrixCursor rv = new MatrixCursor(columns, allDecks.size());
for (DeckDueTreeNode deck : allDecks) {
long id = deck.getDid();
String name = deck.getFullDeckName();
addDeckToCursor(id, name, getDeckCountsFromDueTreeNode(deck), rv, col, columns);
}
return rv;
}
case DECKS_ID:
{
/* Direct access deck */
String[] columns = ((projection != null) ? projection : FlashCardsContract.Deck.DEFAULT_PROJECTION);
MatrixCursor rv = new MatrixCursor(columns, 1);
List<DeckDueTreeNode> allDecks = col.getSched().deckDueList();
long deckId = Long.parseLong(uri.getPathSegments().get(1));
for (DeckDueTreeNode deck : allDecks) {
if (deck.getDid() == deckId) {
addDeckToCursor(deckId, deck.getFullDeckName(), getDeckCountsFromDueTreeNode(deck), rv, col, columns);
return rv;
}
}
return rv;
}
case DECK_SELECTED:
{
long id = col.getDecks().selected();
String name = col.getDecks().name(id);
String[] columns = ((projection != null) ? projection : FlashCardsContract.Deck.DEFAULT_PROJECTION);
MatrixCursor rv = new MatrixCursor(columns, 1);
JSONArray counts = new JSONArray(Collections.singletonList(col.getSched().counts()));
addDeckToCursor(id, name, counts, rv, col, columns);
return rv;
}
default:
// Unknown URI type
throw new IllegalArgumentException("uri " + uri + " is not supported");
}
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED 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);
}
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED in project Anki-Android by ankidroid.
the class ImportTest method testAnki2DiffmodelTemplates.
@Test
public void testAnki2DiffmodelTemplates() throws IOException, JSONException, ImportExportException {
// different from the above as this one tests only the template text being
// changed, not the number of cards/fields
// import the first version of the model
String tmp = Shared.getTestFilePath(getTestContext(), "diffmodeltemplates-1.apkg");
AnkiPackageImporter imp = new AnkiPackageImporter(mTestCol, tmp);
imp.setDupeOnSchemaChange(true);
imp.run();
// then the version with updated template
tmp = Shared.getTestFilePath(getTestContext(), "diffmodeltemplates-2.apkg");
imp = new AnkiPackageImporter(mTestCol, tmp);
imp.setDupeOnSchemaChange(true);
imp.run();
// collection should contain the note we imported
assertEquals(1, mTestCol.noteCount());
// the front template should contain the text added in the 2nd package
Long tcid = mTestCol.findCards("").get(0);
Note tnote = mTestCol.getCard(tcid).note();
assertTrue(mTestCol.findTemplates(tnote).get(0).getString("qfmt").contains("Changed Front Template"));
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED in project Anki-Android by ankidroid.
the class NoteServiceTest method updateJsonNoteTest.
// tests if the text fields of the notes are the same after calling updateJsonNoteFromMultimediaNote
@Test
public void updateJsonNoteTest() {
Model testModel = mTestCol.getModels().byName("Basic");
IMultimediaEditableNote multiMediaNote = NoteService.createEmptyNote(testModel);
multiMediaNote.getField(0).setText("foo");
multiMediaNote.getField(1).setText("bar");
Note basicNote = new Note(mTestCol, testModel);
basicNote.setField(0, "this should be changed to foo");
basicNote.setField(1, "this should be changed to bar");
NoteService.updateJsonNoteFromMultimediaNote(multiMediaNote, basicNote);
assertEquals(basicNote.getFields()[0], multiMediaNote.getField(0).getText());
assertEquals(basicNote.getFields()[1], multiMediaNote.getField(1).getText());
}
use of com.ichi2.anki.CardBrowser.Column.CHANGED in project Anki-Android by ankidroid.
the class ReviewerNoParamTest method whiteboardPenColorChangeChangesDatabaseDark.
@Test
public void whiteboardPenColorChangeChangesDatabaseDark() {
enableDarkMode();
Whiteboard whiteboard = startReviewerForWhiteboard();
whiteboard.setPenColor(ARBITRARY_PEN_COLOR_VALUE);
WhiteboardPenColor penColor = getPenColor();
assertThat("Dark pen color is changed", penColor.getDarkPenColor(), is(ARBITRARY_PEN_COLOR_VALUE));
}
Aggregations