use of com.ichi2.libanki.Card in project Anki-Android by Ramblurr.
the class CustomFontsReviewerExt method getOverrideFontStyle.
/**
* Returns the CSS used to set the override font.
* @return the override font style, or the empty string if no override font is set
*/
private String getOverrideFontStyle(Context context, Map<String, AnkiFont> customFontsMap) {
if (mOverrideFontStyle == null) {
SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(context);
AnkiFont overrideFont = customFontsMap.get(preferences.getString("overrideFont", null));
if (overrideFont != null) {
mOverrideFontStyle = "BODY, .card, * { " + overrideFont.getCSS() + " }\n";
} else {
mOverrideFontStyle = "";
}
}
return mOverrideFontStyle;
}
use of com.ichi2.libanki.Card in project Anki-Android by Ramblurr.
the class Collection method _renderQA.
public HashMap<String, String> _renderQA(Object[] data, List<String> args) {
// data is [cid, nid, mid, did, ord, tags, flds]
// unpack fields and create dict
String[] flist = Utils.splitFields((String) data[6]);
Map<String, String> fields = new HashMap<String, String>();
long modelId = (Long) data[2];
JSONObject model = mModels.get(modelId);
Map<String, Pair<Integer, JSONObject>> fmap = mModels.fieldMap(model);
for (String fname : fmap.keySet()) {
fields.put(fname, flist[fmap.get(fname).first]);
}
fields.put("Tags", ((String) data[5]).trim());
try {
fields.put("Type", (String) model.get("name"));
fields.put("Deck", mDecks.name((Long) data[3]));
JSONObject template;
if (model.getInt("type") == Sched.MODEL_STD) {
template = model.getJSONArray("tmpls").getJSONObject((Integer) data[4]);
} else {
template = model.getJSONArray("tmpls").getJSONObject(0);
}
fields.put("Card", template.getString("name"));
fields.put("c" + (((Integer) data[4]) + 1), "1");
// render q & a
HashMap<String, String> d = new HashMap<String, String>();
try {
d.put("id", Long.toString((Long) data[0]));
String qfmt = template.getString("qfmt");
String afmt = template.getString("afmt");
String html;
String format;
// runFilter mungeFields for type "q"
Models.fieldParser fparser = new Models.fieldParser(fields);
Matcher m = fClozePattern.matcher(qfmt);
format = m.replaceFirst(String.format(Locale.US, "{{cq:%d:", ((Integer) data[4]) + 1));
m = fAltClozePattern.matcher(format);
format = m.replaceFirst(String.format(Locale.US, "<%%cq:%d:", ((Integer) data[4]) + 1));
html = mModels.getCmpldTemplate(format).execute(fparser);
html = (String) AnkiDroidApp.getHooks().runFilter("mungeQA", html, "q", fields, model, data, this);
d.put("q", html);
// empty cloze?
if (model.getInt("type") == Sched.MODEL_CLOZE) {
if (getModels()._availClozeOrds(model, (String) data[6], false).size() == 0) {
d.put("q", "Please edit this note and add some cloze deletions.");
}
}
fields.put("FrontSide", d.get("q"));
// runFilter mungeFields for type "a"
fparser = new Models.fieldParser(fields);
m = fClozePattern.matcher(afmt);
format = m.replaceFirst(String.format(Locale.US, "{{ca:%d:", ((Integer) data[4]) + 1));
m = fAltClozePattern.matcher(format);
format = m.replaceFirst(String.format(Locale.US, "<%%ca:%d:", ((Integer) data[4]) + 1));
html = mModels.getCmpldTemplate(format).execute(fparser);
html = (String) AnkiDroidApp.getHooks().runFilter("mungeQA", html, "a", fields, model, data, this);
d.put("a", html);
// empty cloze?
if (model.getInt("type") == Sched.MODEL_CLOZE) {
if (getModels()._availClozeOrds(model, (String) data[6], false).size() == 0) {
d.put("q", AnkiDroidApp.getAppResources().getString(com.ichi2.anki.R.string.empty_cloze_warning, "<a href=" + HELP_SITE + "#cloze>" + AnkiDroidApp.getAppResources().getString(com.ichi2.anki.R.string.help_cloze) + "</a>"));
}
}
} catch (MustacheException e) {
Resources res = AnkiDroidApp.getAppResources();
String templateError = String.format(TEMPLATE_ERROR, res.getString(R.string.template_error), res.getString(R.string.template_error_detail), e.getMessage(), res.getString(R.string.note_type), model.getString("name"), res.getString(R.string.card_type), template.getString("name"), res.getString(R.string.template_error_fix));
d.put("q", templateError);
d.put("a", templateError);
}
return d;
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
use of com.ichi2.libanki.Card in project Anki-Android by Ramblurr.
the class DeckTask method doInBackgroundDismissNote.
private TaskData doInBackgroundDismissNote(TaskData... params) {
Sched sched = params[0].getSched();
Collection col = sched.getCol();
Card card = params[0].getCard();
Note note = card.note();
int type = params[0].getInt();
try {
col.getDb().getDatabase().beginTransaction();
try {
switch(type) {
case 4:
// collect undo information
col.markUndo(Collection.UNDO_BURY_CARD, new Object[] { col.getDirty(), note.cards(), card.getId() });
// then bury
sched.buryCards(new long[] { card.getId() });
sHadCardQueue = true;
break;
case 0:
// collect undo information
col.markUndo(Collection.UNDO_BURY_NOTE, new Object[] { col.getDirty(), note.cards(), card.getId() });
// then bury
sched.buryNote(note.getId());
sHadCardQueue = true;
break;
case 1:
// collect undo information
col.markUndo(Collection.UNDO_SUSPEND_CARD, new Object[] { card });
// suspend card
if (card.getQueue() == -1) {
sched.unsuspendCards(new long[] { card.getId() });
} else {
sched.suspendCards(new long[] { card.getId() });
}
sHadCardQueue = true;
break;
case 2:
// collect undo information
ArrayList<Card> cards = note.cards();
long[] cids = new long[cards.size()];
for (int i = 0; i < cards.size(); i++) {
cids[i] = cards.get(i).getId();
}
col.markUndo(Collection.UNDO_SUSPEND_NOTE, new Object[] { cards, card.getId() });
// suspend note
sched.suspendCards(cids);
sHadCardQueue = true;
break;
case 3:
// collect undo information
ArrayList<Card> allCs = note.cards();
long[] cardIds = new long[allCs.size()];
for (int i = 0; i < allCs.size(); i++) {
cardIds[i] = allCs.get(i).getId();
}
col.markUndo(Collection.UNDO_DELETE_NOTE, new Object[] { note, allCs, card.getId() });
// delete note
col.remNotes(new long[] { note.getId() });
sHadCardQueue = true;
break;
}
publishProgress(new TaskData(getCard(col.getSched()), 0));
col.getDb().getDatabase().setTransactionSuccessful();
} finally {
col.getDb().getDatabase().endTransaction();
}
} catch (RuntimeException e) {
Log.e(AnkiDroidApp.TAG, "doInBackgroundSuspendCard - RuntimeException on suspending card: " + e);
AnkiDroidApp.saveExceptionReportFile(e, "doInBackgroundSuspendCard");
return new TaskData(false);
}
return new TaskData(true);
}
use of com.ichi2.libanki.Card in project Anki-Android by Ramblurr.
the class DeckTask method doInBackgroundUpdateNote.
private TaskData doInBackgroundUpdateNote(TaskData[] params) {
Log.i(AnkiDroidApp.TAG, "doInBackgroundUpdateNote");
// Save the note
Sched sched = params[0].getSched();
Collection col = sched.getCol();
Card editCard = params[0].getCard();
Note editNote = editCard.note();
boolean fromReviewer = params[0].getBoolean();
// mark undo
col.markUndo(Collection.UNDO_EDIT_NOTE, new Object[] { col.getNote(editNote.getId()), editCard.getId(), fromReviewer });
try {
col.getDb().getDatabase().beginTransaction();
try {
// TODO: undo integration
editNote.flush();
// flush card too, in case, did has been changed
editCard.flush();
if (fromReviewer) {
Card newCard;
if (col.getDecks().active().contains(editCard.getDid())) {
newCard = editCard;
newCard.load();
// reload qa-cache
newCard.getQuestion(true);
} else {
newCard = getCard(sched);
}
publishProgress(new TaskData(newCard));
} else {
publishProgress(new TaskData(editCard, editNote.stringTags()));
}
col.getDb().getDatabase().setTransactionSuccessful();
} finally {
col.getDb().getDatabase().endTransaction();
}
} catch (RuntimeException e) {
Log.e(AnkiDroidApp.TAG, "doInBackgroundUpdateNote - RuntimeException on updating fact: " + e);
AnkiDroidApp.saveExceptionReportFile(e, "doInBackgroundUpdateNote");
return new TaskData(false);
}
return new TaskData(true);
}
use of com.ichi2.libanki.Card in project Anki-Android by Ramblurr.
the class Storage method check.
/*
* Upgrading ************************************************************
*/
// public void upgrade(String path) {
// // mPath = path;
// // _openDB(path);
// // upgradeSchema();
// // _openCol();
// // _upgradeRest();
// // return mCol;
// }
/*
* Integrity checking ************************************************************
*/
public static boolean check(String path) {
AnkiDb db = AnkiDatabaseManager.getDatabase(path);
// corrupt?
try {
if (!db.queryString("PRAGMA integrity_check").equalsIgnoreCase("ok")) {
return false;
}
} catch (SQLException _) {
return false;
}
// old version?
if (db.queryScalar("SELECT version FROM decks") < 65) {
return false;
}
// ensure we have indices for checks below
db.execute("create index if not exists ix_cards_factId on cards (factId)");
db.execute("create index if not exists ix_fields_factId on fieldModels (factId)");
db.execute("analyze");
// fields missing a field model?
if (db.queryColumn(Integer.class, "select id from fields where fieldModelId not in (" + "select distinct id from fieldModels)", 0).size() > 0) {
return false;
}
// facts missing a field?
if (db.queryColumn(Integer.class, "select distinct facts.id from facts, fieldModels where " + "facts.modelId = fieldModels.modelId and fieldModels.id not in " + "(select fieldModelId from fields where factId = facts.id)", 0).size() > 0) {
return false;
}
// cards missing a fact?
if (db.queryColumn(Integer.class, "select id from cards where factId not in (select id from facts)", 0).size() > 0) {
return false;
}
// cards missing a card model?
if (db.queryColumn(Integer.class, "select id from cards where cardModelId not in (select id from cardModels)", 0).size() > 0) {
return false;
}
// cards with a card model from the wrong model?
if (db.queryColumn(Integer.class, "select id from cards where cardModelId not in (select cm.id from " + "cardModels cm, facts f where cm.modelId = f.modelId and " + "f.id = cards.factId)", 0).size() > 0) {
return false;
}
// facts missing a card?
if (db.queryColumn(Integer.class, "select facts.id from facts " + "where facts.id not in (select distinct factId from cards)", 0).size() > 0) {
return false;
}
// dangling fields?
if (db.queryColumn(Integer.class, "select id from fields where factId not in (select id from facts)", 0).size() > 0) {
return false;
}
// fields without matching interval
if (db.queryColumn(Integer.class, "select id from fields where ordinal != (select ordinal from fieldModels " + "where id = fieldModelId)", 0).size() > 0) {
return false;
}
// incorrect types
if (db.queryColumn(Integer.class, "select id from cards where relativeDelay != (case " + "when successive then 1 when reps then 0 else 2 end)", 0).size() > 0) {
return false;
}
if (db.queryColumn(Integer.class, "select id from cards where type != (case " + "when type >= 0 then relativeDelay else relativeDelay - 3 end)", 0).size() > 0) {
return false;
}
return true;
}
Aggregations