Search in sources :

Example 6 with CancelListener

use of com.ichi2.async.CancelListener in project Anki-Android by ankidroid.

the class SchedV2 method deckDueList.

// Overridden
@Nullable
public List<DeckDueTreeNode> deckDueList(@Nullable CancelListener collectionTask) {
    _checkDay();
    mCol.getDecks().checkIntegrity();
    List<Deck> decks = mCol.getDecks().allSorted();
    HashMap<String, Integer[]> lims = HashUtil.HashMapInit(decks.size());
    ArrayList<DeckDueTreeNode> deckNodes = new ArrayList<>(decks.size());
    Decks.Node childMap = mCol.getDecks().childMap();
    for (Deck deck : decks) {
        if (isCancelled(collectionTask)) {
            return null;
        }
        String deckName = deck.getString("name");
        String p = Decks.parent(deckName);
        // new
        int nlim = _deckNewLimitSingle(deck, false);
        Integer plim = null;
        if (!TextUtils.isEmpty(p)) {
            Integer[] parentLims = lims.get(Decks.normalizeName(p));
            // 'temporary for diagnosis of bug #6383'
            Assert.that(parentLims != null, "Deck %s is supposed to have parent %s. It has not be found.", deckName, p);
            nlim = Math.min(nlim, parentLims[0]);
            // reviews
            plim = parentLims[1];
        }
        int _new = _newForDeck(deck.getLong("id"), nlim);
        // learning
        int lrn = _lrnForDeck(deck.getLong("id"));
        // reviews
        int rlim = _deckRevLimitSingle(deck, plim, false);
        int rev = _revForDeck(deck.getLong("id"), rlim, childMap);
        // save to list
        deckNodes.add(new DeckDueTreeNode(mCol, deck.getString("name"), deck.getLong("id"), rev, lrn, _new));
        // add deck as a parent
        lims.put(Decks.normalizeName(deck.getString("name")), new Integer[] { nlim, rlim });
    }
    return deckNodes;
}
Also used : Decks(com.ichi2.libanki.Decks) ArrayList(java.util.ArrayList) Deck(com.ichi2.libanki.Deck) Nullable(androidx.annotation.Nullable)

Example 7 with CancelListener

use of com.ichi2.async.CancelListener in project Anki-Android by ankidroid.

the class Collection method genCards.

/**
 * @param snids All ids of nodes of a note type, separated by comma
 * @param model
 * @param task Task to check for cancellation and update number of card processed
 * @return Cards that should be removed because they should not be generated
 * @param <T>
 */
public <T extends ProgressSender<Integer> & CancelListener> ArrayList<Long> genCards(String snids, @NonNull Model model, @Nullable T task) {
    int nbCount = noteCount();
    // For each note, indicates ords of cards it contains
    HashMap<Long, HashMap<Integer, Long>> have = HashUtil.HashMapInit(nbCount);
    // For each note, the deck containing all of its cards, or 0 if siblings in multiple deck
    HashMap<Long, Long> dids = HashUtil.HashMapInit(nbCount);
    // For each note, an arbitrary due of one of its due card processed, if any exists
    HashMap<Long, Long> dues = HashUtil.HashMapInit(nbCount);
    List<ParsedNode> nodes = null;
    if (model.getInt("type") != Consts.MODEL_CLOZE) {
        nodes = model.parsedNodes();
    }
    try (Cursor cur = mDb.query("select id, nid, ord, (CASE WHEN odid != 0 THEN odid ELSE did END), (CASE WHEN odid != 0 THEN odue ELSE due END), type from cards where nid in " + snids)) {
        while (cur.moveToNext()) {
            if (isCancelled(task)) {
                Timber.v("Empty card cancelled");
                return null;
            }
            @NonNull Long id = cur.getLong(0);
            @NonNull Long nid = cur.getLong(1);
            @NonNull Integer ord = cur.getInt(2);
            @NonNull Long did = cur.getLong(3);
            @NonNull Long due = cur.getLong(4);
            @Consts.CARD_TYPE int type = cur.getInt(5);
            // existing cards
            if (!have.containsKey(nid)) {
                have.put(nid, new HashMap<>());
            }
            have.get(nid).put(ord, id);
            // and their dids
            if (dids.containsKey(nid)) {
                if (dids.get(nid) != 0 && !Utils.equals(dids.get(nid), did)) {
                    // cards are in two or more different decks; revert to model default
                    dids.put(nid, 0L);
                }
            } else {
                // first card or multiple cards in same deck
                dids.put(nid, did);
            }
            if (!dues.containsKey(nid) && type == Consts.CARD_TYPE_NEW) {
                dues.put(nid, due);
            }
        }
    }
    // build cards for each note
    ArrayList<Object[]> data = new ArrayList<>();
    long ts = getTime().maxID(mDb);
    long now = getTime().intTime();
    ArrayList<Long> rem = new ArrayList<>(mDb.queryScalar("SELECT count() FROM notes where id in " + snids));
    int usn = usn();
    try (Cursor cur = mDb.query("SELECT id, flds FROM notes WHERE id IN " + snids)) {
        while (cur.moveToNext()) {
            if (isCancelled(task)) {
                Timber.v("Empty card cancelled");
                return null;
            }
            @NonNull Long nid = cur.getLong(0);
            String flds = cur.getString(1);
            ArrayList<Integer> avail = Models.availOrds(model, Utils.splitFields(flds), nodes, Models.AllowEmpty.TRUE);
            if (task != null) {
                task.doProgress(avail.size());
            }
            Long did = dids.get(nid);
            // use sibling due if there is one, else use a new id
            @NonNull Long due;
            if (dues.containsKey(nid)) {
                due = dues.get(nid);
            } else {
                due = (long) nextID("pos");
            }
            if (did == null || did == 0L) {
                did = model.getDid();
            }
            // add any missing cards
            ArrayList<JSONObject> tmpls = _tmplsFromOrds(model, avail);
            for (JSONObject t : tmpls) {
                int tord = t.getInt("ord");
                boolean doHave = have.containsKey(nid) && have.get(nid).containsKey(tord);
                if (!doHave) {
                    // check deck is not a cram deck
                    long ndid;
                    try {
                        ndid = t.optLong("did", 0);
                        if (ndid != 0) {
                            did = ndid;
                        }
                    } catch (JSONException e) {
                        Timber.w(e);
                    // do nothing
                    }
                    if (getDecks().isDyn(did)) {
                        did = 1L;
                    }
                    // if the deck doesn't exist, use default instead
                    did = mDecks.get(did).getLong("id");
                    // give it a new id instead
                    data.add(new Object[] { ts, nid, did, tord, now, usn, due });
                    ts += 1;
                }
            }
            // note any cards that need removing
            if (have.containsKey(nid)) {
                for (Map.Entry<Integer, Long> n : have.get(nid).entrySet()) {
                    if (!avail.contains(n.getKey())) {
                        rem.add(n.getValue());
                    }
                }
            }
        }
    }
    // bulk update
    mDb.executeMany("INSERT INTO cards VALUES (?,?,?,?,?,?,0,0,?,0,0,0,0,0,0,0,0,\"\")", data);
    return rem;
}
Also used : ParsedNode(com.ichi2.libanki.template.ParsedNode) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) JSONException(com.ichi2.utils.JSONException) Cursor(android.database.Cursor) SuppressLint(android.annotation.SuppressLint) JSONObject(com.ichi2.utils.JSONObject) NonNull(androidx.annotation.NonNull) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

Resources (android.content.res.Resources)3 Bundle (android.os.Bundle)3 MaterialDialog (com.afollestad.materialdialogs.MaterialDialog)3 DeckPicker (com.ichi2.anki.DeckPicker)3 R (com.ichi2.anki.R)3 AnalyticsDialogFragment (com.ichi2.anki.analytics.AnalyticsDialogFragment)3 Deck (com.ichi2.libanki.Deck)3 ArrayList (java.util.ArrayList)3 Nullable (androidx.annotation.Nullable)2 SuppressLint (android.annotation.SuppressLint)1 Cursor (android.database.Cursor)1 NonNull (androidx.annotation.NonNull)1 AnkiDroidApp (com.ichi2.anki.AnkiDroidApp)1 BackupManager (com.ichi2.anki.BackupManager)1 CollectionHelper (com.ichi2.anki.CollectionHelper)1 UsageAnalytics (com.ichi2.anki.analytics.UsageAnalytics)1 Decks (com.ichi2.libanki.Decks)1 ParsedNode (com.ichi2.libanki.template.ParsedNode)1 JSONException (com.ichi2.utils.JSONException)1 JSONObject (com.ichi2.utils.JSONObject)1