Search in sources :

Example 1 with R

use of com.ichi2.anki.R in project AnkiChinaAndroid by ankichinateam.

the class ModelFieldEditor method addFieldDialog.

// ----------------------------------------------------------------------------
// CONTEXT MENU DIALOGUES
// ----------------------------------------------------------------------------
/*
    * Creates a dialog to create a field
    */
private void addFieldDialog() {
    mFieldNameInput = new EditText(this);
    mFieldNameInput.setSingleLine(true);
    new MaterialDialog.Builder(this).title(R.string.model_field_editor_add).positiveText(R.string.dialog_ok).customView(mFieldNameInput, true).onPositive((dialog, which) -> {
        String fieldName = mFieldNameInput.getText().toString().replaceAll("[\\n\\r]", "");
        if (fieldName.length() == 0) {
            UIUtils.showThemedToast(this, getResources().getString(R.string.toast_empty_name), true);
        } else if (containsField(fieldName)) {
            UIUtils.showThemedToast(this, getResources().getString(R.string.toast_duplicate_field), true);
        } else {
            // Name is valid, now field is added
            changeHandler listener = changeFieldHandler();
            try {
                mCol.modSchema();
                CollectionTask.launchCollectionTask(ADD_FIELD, listener, new TaskData(new Object[] { mMod, fieldName }));
            } catch (ConfirmModSchemaException e) {
                // Create dialogue to for schema change
                ConfirmationDialog c = new ConfirmationDialog();
                c.setArgs(getResources().getString(R.string.full_sync_confirmation));
                Runnable confirm = () -> {
                    mCol.modSchemaNoCheck();
                    String fieldName1 = mFieldNameInput.getText().toString().replaceAll("[\\n\\r]", "");
                    CollectionTask.launchCollectionTask(ADD_FIELD, listener, new TaskData(new Object[] { mMod, fieldName1 }));
                    dismissContextMenu();
                };
                c.setConfirm(confirm);
                c.setCancel(mConfirmDialogCancel);
                ModelFieldEditor.this.showDialogFragment(c);
            }
            mCol.getModels().update(mMod);
            fullRefreshList();
        }
    }).negativeText(R.string.dialog_cancel).show();
}
Also used : EditText(android.widget.EditText) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) TaskData(com.ichi2.async.TaskData) ConfirmationDialog(com.ichi2.anki.dialogs.ConfirmationDialog)

Example 2 with R

use of com.ichi2.anki.R in project AnkiChinaAndroid by ankichinateam.

the class ZipFile method exportFiltered.

private JSONObject exportFiltered(ZipFile z, String path, Context context) throws IOException, JSONException, ImportExportException {
    // export into the anki2 file
    String colfile = path.replace(".apkg", ".anki2");
    super.exportInto(colfile, context);
    z.write(colfile, CollectionHelper.COLLECTION_FILENAME);
    // and media
    prepareMedia();
    JSONObject media = _exportMedia(z, mMediaFiles, mCol.getMedia().dir());
    // tidy up intermediate files
    SQLiteDatabase.deleteDatabase(new File(colfile));
    SQLiteDatabase.deleteDatabase(new File(path.replace(".apkg", ".media.ad.db2")));
    String tempPath = path.replace(".apkg", ".media");
    File file = new File(tempPath);
    if (file.exists()) {
        String deleteCmd = "rm -r " + tempPath;
        Runtime runtime = Runtime.getRuntime();
        try {
            runtime.exec(deleteCmd);
        } catch (IOException e) {
        }
    }
    return media;
}
Also used : JSONObject(com.ichi2.utils.JSONObject) IOException(java.io.IOException) File(java.io.File)

Example 3 with R

use of com.ichi2.anki.R in project AnkiChinaAndroid by ankichinateam.

the class Sched method _fillRev.

@Override
protected boolean _fillRev(boolean allowSibling) {
    if (!mRevQueue.isEmpty()) {
        return true;
    }
    if (mRevCount == 0) {
        return false;
    }
    SupportSQLiteDatabase db = mCol.getDb().getDatabase();
    while (!mRevDids.isEmpty()) {
        long did = mRevDids.getFirst();
        int lim = Math.min(mQueueLimit, _deckRevLimit(did));
        Cursor cur = null;
        if (lim != 0) {
            mRevQueue.clear();
            // fill the queue with the current did
            try {
                /* Difference with upstream: we take current card into account.
                     *
                     * When current card is answered, the card is not due anymore, so does not belong to the queue.
                     * Furthermore, _burySiblings ensure that the siblings of the current cards are removed from the
                     * queue to ensure same day spacing. We simulate this action by ensuring that those siblings are not
                     * filled, except if we know there are cards and we didn't find any non-sibling card. This way, the
                     * queue is not empty if it should not be empty (important for the conditional belows), but the
                     * front of the queue contains distinct card.
                     */
                String idName = (allowSibling) ? "id" : "nid";
                long id = (allowSibling) ? currentCardId() : currentCardNid();
                cur = db.query("SELECT id FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ?" + " AND " + idName + " != ? LIMIT ?", new Object[] { did, mToday, id, lim });
                while (cur.moveToNext()) {
                    mRevQueue.add(cur.getLong(0));
                }
            } finally {
                if (cur != null && !cur.isClosed()) {
                    cur.close();
                }
            }
            if (!mRevQueue.isEmpty()) {
                // ordering
                if (mCol.getDecks().get(did).getInt("dyn") != 0) {
                // dynamic decks need due order preserved
                // Note: libanki reverses mRevQueue and returns the last element in _getRevCard().
                // AnkiDroid differs by leaving the queue intact and returning the *first* element
                // in _getRevCard().
                } else {
                    Random r = new Random();
                    r.setSeed(mToday);
                    mRevQueue.shuffle(r);
                }
                // is the current did empty?
                if (mRevQueue.size() < lim) {
                    mRevDids.remove();
                }
                return true;
            }
        }
        // nothing left in the deck; move to next
        mRevDids.remove();
    }
    // Since we didn't get a card and the count is non-zero, we
    // need to check again for any cards that were removed from
    // the queue but not buried
    _resetRev();
    return _fillRev(true);
}
Also used : SupportSQLiteDatabase(androidx.sqlite.db.SupportSQLiteDatabase) Random(java.util.Random) JSONObject(com.ichi2.utils.JSONObject) Cursor(android.database.Cursor)

Example 4 with R

use of com.ichi2.anki.R in project AnkiChinaAndroid by ankichinateam.

the class Syncer method mergeModels.

private void mergeModels(JSONArray rchg) throws UnexpectedSchemaChange {
    for (int i = 0; i < rchg.length(); i++) {
        Model r = new Model(rchg.getJSONObject(i));
        Model l = mCol.getModels().get(r.getLong("id"));
        // if missing locally or server is newer, update
        if (l == null || r.getLong("mod") > l.getLong("mod")) {
            // syncing algorithm should handle this in a better way.
            if (l != null) {
                if (l.getJSONArray("flds").length() != r.getJSONArray("flds").length()) {
                    throw new UnexpectedSchemaChange();
                }
                if (l.getJSONArray("tmpls").length() != r.getJSONArray("tmpls").length()) {
                    throw new UnexpectedSchemaChange();
                }
            }
            mCol.getModels().update(r);
        }
    }
}
Also used : Model(com.ichi2.libanki.Model)

Example 5 with R

use of com.ichi2.anki.R in project AnkiChinaAndroid by ankichinateam.

the class Syncer method newerRows.

private ArrayList<Object[]> newerRows(JSONArray data, String table, int modIdx) {
    long[] ids = new long[data.length()];
    for (int i = 0; i < data.length(); i++) {
        ids[i] = data.getJSONArray(i).getLong(0);
    }
    HashMap<Long, Long> lmods = new HashMap<>();
    Cursor cur = null;
    try {
        cur = mCol.getDb().getDatabase().query("SELECT id, mod FROM " + table + " WHERE id IN " + Utils.ids2str(ids) + " AND " + usnLim(), null);
        while (cur.moveToNext()) {
            lmods.put(cur.getLong(0), cur.getLong(1));
        }
    } finally {
        if (cur != null && !cur.isClosed()) {
            cur.close();
        }
    }
    ArrayList<Object[]> update = new ArrayList<>();
    for (int i = 0; i < data.length(); i++) {
        JSONArray r = data.getJSONArray(i);
        if (!lmods.containsKey(r.getLong(0)) || lmods.get(r.getLong(0)) < r.getLong(modIdx)) {
            update.add(Utils.jsonArray2Objects(r));
        }
    }
    mCol.log(table, data);
    return update;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) JSONArray(com.ichi2.utils.JSONArray) Cursor(android.database.Cursor)

Aggregations

JSONObject (com.ichi2.utils.JSONObject)17 JSONArray (com.ichi2.utils.JSONArray)14 ArrayList (java.util.ArrayList)10 Test (org.junit.Test)7 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)6 Model (com.ichi2.libanki.Model)6 EditText (android.widget.EditText)5 File (java.io.File)5 Random (java.util.Random)5 Nullable (androidx.annotation.Nullable)4 ConfirmationDialog (com.ichi2.anki.dialogs.ConfirmationDialog)4 Connection (com.ichi2.async.Connection)4 IOException (java.io.IOException)4 Intent (android.content.Intent)3 SharedPreferences (android.content.SharedPreferences)3 Cursor (android.database.Cursor)3 Bundle (android.os.Bundle)3 Timber (timber.log.Timber)3 Context (android.content.Context)2 LayoutInflater (android.view.LayoutInflater)2