Search in sources :

Example 86 with Model

use of com.ichi2.libanki.Model in project Anki-Android by ankidroid.

the class Models method moveTemplate.

@Override
public void moveTemplate(Model m, JSONObject template, int idx) {
    JSONArray tmpls = m.getJSONArray("tmpls");
    int oldidx = -1;
    ArrayList<JSONObject> l = new ArrayList<>();
    HashMap<Integer, Integer> oldidxs = new HashMap<>();
    for (int i = 0; i < tmpls.length(); ++i) {
        if (tmpls.getJSONObject(i).equals(template)) {
            oldidx = i;
            if (idx == oldidx) {
                return;
            }
        }
        JSONObject t = tmpls.getJSONObject(i);
        oldidxs.put(t.hashCode(), t.getInt("ord"));
        l.add(t);
    }
    l.remove(oldidx);
    l.add(idx, template);
    m.put("tmpls", new JSONArray(l));
    _updateTemplOrds(m);
    // generate change map - We use StringBuilder
    StringBuilder sb = new StringBuilder();
    tmpls = m.getJSONArray("tmpls");
    for (int i = 0; i < tmpls.length(); ++i) {
        JSONObject t = tmpls.getJSONObject(i);
        sb.append("when ord = ").append(oldidxs.get(t.hashCode())).append(" then ").append(t.getInt("ord"));
        if (i != tmpls.length() - 1) {
            sb.append(" ");
        }
    }
    // apply
    save(m);
    mCol.getDb().execute("update cards set ord = (case " + sb + " end),usn=?,mod=? where nid in (select id from notes where mid = ?)", mCol.usn(), mCol.getTime().intTime(), m.getLong("id"));
}
Also used : JSONObject(com.ichi2.utils.JSONObject) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) JSONArray(com.ichi2.utils.JSONArray) ArrayList(java.util.ArrayList)

Example 87 with Model

use of com.ichi2.libanki.Model in project Anki-Android by ankidroid.

the class Models method getTemplateNames.

public HashMap<Long, HashMap<Integer, String>> getTemplateNames() {
    HashMap<Long, HashMap<Integer, String>> result = HashUtil.HashMapInit(mModels.size());
    for (Model m : mModels.values()) {
        JSONArray templates = m.getJSONArray("tmpls");
        HashMap<Integer, String> names = HashUtil.HashMapInit(templates.length());
        for (JSONObject t : templates.jsonObjectIterable()) {
            names.put(t.getInt("ord"), t.getString("name"));
        }
        result.put(m.getLong("id"), names);
    }
    return result;
}
Also used : JSONObject(com.ichi2.utils.JSONObject) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) JSONArray(com.ichi2.utils.JSONArray)

Example 88 with Model

use of com.ichi2.libanki.Model in project Anki-Android by ankidroid.

the class Models method _availStandardOrds.

/**
 * Given a joined field string and a standard note type, return available template ordinals
 */
public static ArrayList<Integer> _availStandardOrds(Model m, String[] sfld, List<ParsedNode> nodes, boolean allowEmpty) {
    Set<String> nonEmptyFields = m.nonEmptyFields(sfld);
    ArrayList<Integer> avail = new ArrayList<>(nodes.size());
    for (int i = 0; i < nodes.size(); i++) {
        ParsedNode node = nodes.get(i);
        if (node != null && !node.template_is_empty(nonEmptyFields)) {
            avail.add(i);
        }
    }
    if (allowEmpty && avail.isEmpty()) {
        /* According to anki documentation:
            When adding/importing, if a normal note doesn’t generate any cards, Anki will now add a blank card 1 instead of refusing to add the note. */
        avail.add(0);
    }
    return avail;
}
Also used : ParsedNode(com.ichi2.libanki.template.ParsedNode) ArrayList(java.util.ArrayList)

Example 89 with Model

use of com.ichi2.libanki.Model in project Anki-Android by ankidroid.

the class Models method remTemplate.

/**
 * {@inheritDoc}
 */
@Override
public void remTemplate(Model m, JSONObject template) throws ConfirmModSchemaException {
    if (m.getJSONArray("tmpls").length() <= 1) {
        return;
    }
    // find cards using this template
    JSONArray tmpls = m.getJSONArray("tmpls");
    int ord = -1;
    for (int i = 0; i < tmpls.length(); ++i) {
        if (tmpls.getJSONObject(i).equals(template)) {
            ord = i;
            break;
        }
    }
    if (ord == -1) {
        throw new IllegalArgumentException("Invalid template proposed for delete");
    }
    // the code in "isRemTemplateSafe" was in place here in libanki. It is extracted to a method for reuse
    List<Long> cids = getCardIdsForModel(m.getLong("id"), new int[] { ord });
    if (cids == null) {
        Timber.d("remTemplate getCardIdsForModel determined it was unsafe to delete the template");
        return;
    }
    // ok to proceed; remove cards
    Timber.d("remTemplate proceeding to delete the template and %d cards", cids.size());
    mCol.modSchema();
    mCol.remCards(cids);
    // shift ordinals
    mCol.getDb().execute("update cards set ord = ord - 1, usn = ?, mod = ? where nid in (select id from notes where mid = ?) and ord > ?", mCol.usn(), mCol.getTime().intTime(), m.getLong("id"), ord);
    tmpls = m.getJSONArray("tmpls");
    JSONArray tmpls2 = new JSONArray();
    for (int i = 0; i < tmpls.length(); ++i) {
        if (template.equals(tmpls.getJSONObject(i))) {
            continue;
        }
        tmpls2.put(tmpls.getJSONObject(i));
    }
    m.put("tmpls", tmpls2);
    _updateTemplOrds(m);
    save(m);
    Timber.d("remTemplate done working");
}
Also used : JSONArray(com.ichi2.utils.JSONArray)

Example 90 with Model

use of com.ichi2.libanki.Model in project Anki-Android by ankidroid.

the class Models method _reqForTemplate.

// 'String f' is unused upstream as well
@SuppressWarnings("PMD.UnusedLocalVariable")
private Object[] _reqForTemplate(Model m, List<String> flds, JSONObject t) {
    int nbFields = flds.size();
    String[] a = new String[nbFields];
    String[] b = new String[nbFields];
    Arrays.fill(a, "ankiflag");
    Arrays.fill(b, "");
    int ord = t.getInt("ord");
    String full = mCol._renderQA(1L, m, 1L, ord, "", a, 0).get("q");
    String empty = mCol._renderQA(1L, m, 1L, ord, "", b, 0).get("q");
    // if full and empty are the same, the template is invalid and there is no way to satisfy it
    if (full.equals(empty)) {
        return new Object[] { REQ_NONE, new JSONArray(), new JSONArray() };
    }
    String type = REQ_ALL;
    JSONArray req = new JSONArray();
    for (int i = 0; i < flds.size(); i++) {
        a[i] = "";
        // if no field content appeared, field is required
        if (!mCol._renderQA(1L, m, 1L, ord, "", a, 0).get("q").contains("ankiflag")) {
            req.put(i);
        }
        a[i] = "ankiflag";
    }
    if (req.length() > 0) {
        return new Object[] { type, req };
    }
    // if there are no required fields, switch to any mode
    type = REQ_ANY;
    req = new JSONArray();
    for (int i = 0; i < flds.size(); i++) {
        b[i] = "1";
        // if not the same as empty, this field can make the card non-blank
        if (!mCol._renderQA(1L, m, 1L, ord, "", b, 0).get("q").equals(empty)) {
            req.put(i);
        }
        b[i] = "";
    }
    return new Object[] { type, req };
}
Also used : JSONArray(com.ichi2.utils.JSONArray) JSONObject(com.ichi2.utils.JSONObject)

Aggregations

JSONObject (com.ichi2.utils.JSONObject)124 Model (com.ichi2.libanki.Model)95 Test (org.junit.Test)82 JSONArray (com.ichi2.utils.JSONArray)79 Collection (com.ichi2.libanki.Collection)53 ArrayList (java.util.ArrayList)48 Note (com.ichi2.libanki.Note)40 RobolectricTest (com.ichi2.anki.RobolectricTest)38 JSONException (com.ichi2.utils.JSONException)32 Intent (android.content.Intent)30 Card (com.ichi2.libanki.Card)27 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)26 HashMap (java.util.HashMap)22 Bundle (android.os.Bundle)20 NonNull (androidx.annotation.NonNull)20 SuppressLint (android.annotation.SuppressLint)16 View (android.view.View)16 ConfirmationDialog (com.ichi2.anki.dialogs.ConfirmationDialog)15 IOException (java.io.IOException)15 Nullable (androidx.annotation.Nullable)14