Search in sources :

Example 36 with Deck

use of com.ichi2.libanki.Deck in project AnkiChinaAndroid by ankichinateam.

the class Collection method load.

/**
 * DB-related *************************************************************** ********************************
 */
public void load() {
    Cursor cursor = null;
    String deckConf = "";
    try {
        // Read in deck table columns
        cursor = mDb.query("SELECT crt, mod, scm, dty, usn, ls, " + "conf, dconf, tags,ver FROM col");
        if (!cursor.moveToFirst()) {
            return;
        }
        mCrt = cursor.getLong(0);
        mMod = cursor.getLong(1);
        mScm = cursor.getLong(2);
        // No longer used
        mDty = cursor.getInt(3) == 1;
        mUsn = cursor.getInt(4);
        mLs = cursor.getLong(5);
        mConf = new JSONObject(cursor.getString(6));
        deckConf = cursor.getString(7);
        mTagsJson = cursor.getString(8);
        mTags.load(mTagsJson);
        mVer = cursor.getInt(9);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
    // getModels().load(loadColumn("models")); This code has been
    // moved to `CollectionHelper::loadLazyCollection` for
    // efficiency Models are loaded lazily on demand. The
    // application layer can asynchronously pre-fetch those parts;
    // otherwise they get loaded when required.
    Timber.i("load new collection");
    mDecks.load(loadColumn("decks"), deckConf);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) Cursor(android.database.Cursor)

Example 37 with Deck

use of com.ichi2.libanki.Deck in project AnkiChinaAndroid by ankichinateam.

the class Collection method genCards.

public ArrayList<Long> genCards(long[] nids) {
    // build map of (nid,ord) so we don't create dupes
    String snids = Utils.ids2str(nids);
    HashMap<Long, HashMap<Integer, Long>> have = new HashMap<>();
    HashMap<Long, Long> dids = new HashMap<>();
    HashMap<Long, Long> dues = new HashMap<>();
    Cursor cur = null;
    try {
        cur = mDb.getDatabase().query("select id, nid, ord, did, due, odue, odid, type from cards where nid in " + snids, null);
        while (cur.moveToNext()) {
            long id = cur.getLong(0);
            long nid = cur.getLong(1);
            int ord = cur.getInt(2);
            long did = cur.getLong(3);
            long due = cur.getLong(4);
            long odue = cur.getLong(5);
            long odid = cur.getLong(6);
            @Consts.CARD_TYPE int type = cur.getInt(7);
            // existing cards
            if (!have.containsKey(nid)) {
                have.put(nid, new HashMap<Integer, Long>());
            }
            have.get(nid).put(ord, id);
            // if in a filtered deck, add new cards to original deck
            if (odid != 0) {
                did = odid;
            }
            // and their dids
            if (dids.containsKey(nid)) {
                if (dids.get(nid) != 0 && 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);
            }
            // save due
            if (odid != 0) {
                due = odue;
            }
            if (!dues.containsKey(nid) && type == Consts.CARD_TYPE_NEW) {
                dues.put(nid, due);
            }
        }
    } finally {
        if (cur != null && !cur.isClosed()) {
            cur.close();
        }
    }
    // build cards for each note
    ArrayList<Object[]> data = new ArrayList<>();
    long ts = getTime().maxID(mDb);
    long now = getTime().intTime();
    ArrayList<Long> rem = new ArrayList<>();
    int usn = usn();
    cur = null;
    try {
        cur = mDb.getDatabase().query("SELECT id, mid, flds FROM notes WHERE id IN " + snids, null);
        while (cur.moveToNext()) {
            long nid = cur.getLong(0);
            long mid = cur.getLong(1);
            String flds = cur.getString(2);
            Model model = getModels().get(mid);
            ArrayList<Integer> avail = getModels().availOrds(model, Utils.splitFields(flds));
            Long did = dids.get(nid);
            // use sibling due if there is one, else use a new id
            long due;
            if (dues.containsKey(nid)) {
                due = dues.get(nid);
            } else {
                due = nextID("pos");
            }
            if (did == null || did == 0L) {
                did = model.getLong("did");
            }
            // add any missing cards
            for (JSONObject t : _tmplsFromOrds(model, avail)) {
                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.getLong("did");
                        if (ndid != 0) {
                            did = ndid;
                        }
                    } catch (JSONException 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());
                    }
                }
            }
        }
    } finally {
        if (cur != null && !cur.isClosed()) {
            cur.close();
        }
    }
    // bulk update
    mDb.executeMany("INSERT INTO cards VALUES (?,?,?,?,?,?,0,0,?,0,0,0,0,0,0,0,0,\"\")", data);
    return rem;
}
Also used : 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) Map(java.util.Map) HashMap(java.util.HashMap)

Example 38 with Deck

use of com.ichi2.libanki.Deck in project AnkiChinaAndroid by ankichinateam.

the class Collection method removeDeckOptionsFromDynamicDecks.

private ArrayList<String> removeDeckOptionsFromDynamicDecks(Runnable notifyProgress) {
    Timber.d("removeDeckOptionsFromDynamicDecks()");
    ArrayList<String> problems = new ArrayList<>();
    // #5708 - a dynamic deck should not have "Deck Options"
    notifyProgress.run();
    int fixCount = 0;
    for (long id : mDecks.allDynamicDeckIds()) {
        try {
            if (mDecks.hasDeckOptions(id)) {
                mDecks.removeDeckOptions(id);
                fixCount++;
            }
        } catch (NoSuchDeckException e) {
            Timber.e("Unable to find dynamic deck %d", id);
        }
    }
    if (fixCount > 0) {
        mDecks.save();
        problems.add(String.format(Locale.US, "%d dynamic deck(s) had deck options.", fixCount));
    }
    return problems;
}
Also used : ArrayList(java.util.ArrayList) NoSuchDeckException(com.ichi2.libanki.exception.NoSuchDeckException) SuppressLint(android.annotation.SuppressLint)

Example 39 with Deck

use of com.ichi2.libanki.Deck in project AnkiChinaAndroid by ankichinateam.

the class Sched method _updateCutoff.

/**
 * Daily cutoff ************************************************************* **********************************
 * This function uses GregorianCalendar so as to be sensitive to leap years, daylight savings, etc.
 */
@Override
public void _updateCutoff() {
    Integer oldToday = mToday;
    // days since col created
    mToday = (int) ((getTime().intTime() - mCol.getCrt()) / SECONDS_PER_DAY);
    // end of day cutoff
    mDayCutoff = mCol.getCrt() + ((mToday + 1) * SECONDS_PER_DAY);
    if (oldToday != mToday) {
        mCol.log(mToday, mDayCutoff);
    }
    // instead
    for (Deck deck : mCol.getDecks().all()) {
        update(deck);
    }
    // unbury if the day has rolled over
    int unburied = mCol.getConf().optInt("lastUnburied", 0);
    if (unburied < mToday) {
        SyncStatus.ignoreDatabaseModification(this::unburyCards);
    }
}
Also used : Deck(com.ichi2.libanki.Deck)

Example 40 with Deck

use of com.ichi2.libanki.Deck in project AnkiChinaAndroid by ankichinateam.

the class Sched method rebuildDyn.

@Override
public List<Long> rebuildDyn(long did) {
    if (did == 0) {
        did = mCol.getDecks().selected();
    }
    Deck deck = mCol.getDecks().get(did);
    if (deck.getInt("dyn") == 0) {
        Timber.e("error: deck is not a filtered deck");
        return null;
    }
    // move any existing cards back first, then fill
    emptyDyn(did);
    List<Long> ids = _fillDyn(deck);
    if (ids.isEmpty()) {
        return null;
    }
    // and change to our new deck
    mCol.getDecks().select(did);
    return ids;
}
Also used : Deck(com.ichi2.libanki.Deck)

Aggregations

Deck (com.ichi2.libanki.Deck)100 Collection (com.ichi2.libanki.Collection)97 JSONObject (com.ichi2.utils.JSONObject)88 Test (org.junit.Test)80 JSONArray (com.ichi2.utils.JSONArray)55 Card (com.ichi2.libanki.Card)53 Note (com.ichi2.libanki.Note)50 ArrayList (java.util.ArrayList)47 RobolectricTest (com.ichi2.anki.RobolectricTest)44 DeckConfig (com.ichi2.libanki.DeckConfig)37 JSONException (com.ichi2.utils.JSONException)34 NonNull (androidx.annotation.NonNull)30 HashMap (java.util.HashMap)29 Model (com.ichi2.libanki.Model)23 Map (java.util.Map)22 Intent (android.content.Intent)21 Resources (android.content.res.Resources)18 TextView (android.widget.TextView)18 SharedPreferences (android.content.SharedPreferences)17 Cursor (android.database.Cursor)17