Search in sources :

Example 1 with Template

use of com.ichi2.libanki.template.Template in project AnkiChinaAndroid by ankichinateam.

the class AbstractFlashcardViewer method getAnswerFormat.

/**
 * getAnswerFormat returns the answer part of this card's template as entered by user, without any parsing
 */
public String getAnswerFormat() {
    JSONObject model = mCurrentCard.model();
    JSONObject template;
    if (model.getInt("type") == Consts.MODEL_STD) {
        template = model.getJSONArray("tmpls").getJSONObject(mCurrentCard.getOrd());
    } else {
        template = model.getJSONArray("tmpls").getJSONObject(0);
    }
    return template.getString("afmt");
}
Also used : JSONObject(com.ichi2.utils.JSONObject)

Example 2 with Template

use of com.ichi2.libanki.template.Template in project AnkiChinaAndroid by ankichinateam.

the class NoteEditor method updateCards.

/**
 * Update the list of card templates for current note type
 */
private void updateCards(JSONObject model) {
    Timber.d("updateCards()");
    JSONArray tmpls = model.getJSONArray("tmpls");
    StringBuilder cardsList = new StringBuilder();
    // Build comma separated list of card names
    Timber.d("updateCards() template count is %s", tmpls.length());
    for (int i = 0; i < tmpls.length(); i++) {
        String name = tmpls.getJSONObject(i).optString("name");
        // If more than one card, and we have an existing card, underline existing card
        if (!mAddNote && tmpls.length() > 1 && model == mEditorNote.model() && mCurrentEditedCard != null && mCurrentEditedCard.template().optString("name").equals(name)) {
            name = "<u>" + name + "</u>";
        }
        cardsList.append(name);
        if (i < tmpls.length() - 1) {
            cardsList.append(", ");
        }
    }
    // Make cards list red if the number of cards is being reduced
    if (!mAddNote && tmpls.length() < mEditorNote.model().getJSONArray("tmpls").length()) {
        cardsList = new StringBuilder("<font color='red'>" + cardsList + "</font>");
    }
    mCardsButton.setText(CompatHelper.getCompat().fromHtml(getResources().getString(R.string.CardEditorCards, cardsList.toString())));
}
Also used : JSONArray(com.ichi2.utils.JSONArray) SuppressLint(android.annotation.SuppressLint)

Example 3 with Template

use of com.ichi2.libanki.template.Template in project AnkiChinaAndroid by ankichinateam.

the class CardTemplateEditor method onDeckSelected.

/**
 * When a deck is selected via Deck Override
 */
@Override
public void onDeckSelected(@Nullable SelectableDeck deck) {
    if (Models.isCloze(getTempModel().getModel())) {
        Timber.w("Attempted to set deck for cloze model");
        UIUtils.showThemedToast(this, getString(R.string.model_manager_deck_override_cloze_error), true);
        return;
    }
    int ordinal = mViewPager.getCurrentItem();
    JSONObject template = getTempModel().getTemplate(ordinal);
    String templateName = template.getString("name");
    if (deck != null && Decks.isDynamic(getCol(), deck.getDeckId())) {
        Timber.w("Attempted to set default deck of %s to dynamic deck %s", templateName, deck.getName());
        UIUtils.showThemedToast(this, getString(R.string.model_manager_deck_override_dynamic_deck_error), true);
        return;
    }
    String message;
    if (deck == null) {
        Timber.i("Removing default template from template '%s'", templateName);
        template.put("did", null);
        message = getString(R.string.model_manager_deck_override_removed_message, templateName);
    } else {
        Timber.i("Setting template '%s' to '%s'", templateName, deck.getName());
        template.put("did", deck.getDeckId());
        message = getString(R.string.model_manager_deck_override_added_message, templateName, deck.getName());
    }
    UIUtils.showThemedToast(this, message, true);
    // Deck Override can change from "on" <-> "off"
    supportInvalidateOptionsMenu();
}
Also used : JSONObject(com.ichi2.utils.JSONObject)

Example 4 with Template

use of com.ichi2.libanki.template.Template in project AnkiChinaAndroid by ankichinateam.

the class CardTemplatePreviewer method getDummyCard.

/**
 * Get a dummy card
 */
@Nullable
protected Card getDummyCard(Model model, int ordinal) {
    Timber.d("getDummyCard() Creating dummy note for ordinal %s", ordinal);
    if (model == null) {
        return null;
    }
    Note n = getCol().newNote(model);
    ArrayList<String> fieldNames = Models.fieldNames(model);
    for (int i = 0; i < fieldNames.size() && i < n.getFields().length; i++) {
        n.setField(i, fieldNames.get(i));
    }
    try {
        JSONObject template = model.getJSONArray("tmpls").getJSONObject(ordinal);
        PreviewerCard card = (PreviewerCard) getCol().getNewLinkedCard(new PreviewerCard(getCol()), n, template, 1, 0, false);
        card.setNote(n);
        return card;
    } catch (Exception e) {
        Timber.e("getDummyCard() unable to create card");
    }
    return null;
}
Also used : JSONObject(com.ichi2.utils.JSONObject) Note(com.ichi2.libanki.Note) IOException(java.io.IOException) Nullable(androidx.annotation.Nullable)

Example 5 with Template

use of com.ichi2.libanki.template.Template in project AnkiChinaAndroid by ankichinateam.

the class CollectionTask method doInBackgroundSaveModel.

/**
 * Handles everything for a model change at once - template add / deletes as well as content updates
 */
private TaskData doInBackgroundSaveModel(TaskData param) {
    Timber.d("doInBackgroundSaveModel");
    Collection col = getCol();
    Object[] args = param.getObjArray();
    Model model = (Model) args[0];
    ArrayList<Object[]> templateChanges = (ArrayList<Object[]>) args[1];
    Model oldModel = col.getModels().get(model.getLong("id"));
    // TODO need to save all the cards that will go away, for undo
    // (do I need to remove them from graves during undo also?)
    // - undo (except for cards) could just be Models.update(model) / Models.flush() / Collection.reset() (that was prior "undo")
    JSONArray newTemplates = model.getJSONArray("tmpls");
    col.getDb().getDatabase().beginTransaction();
    try {
        for (Object[] change : templateChanges) {
            JSONArray oldTemplates = oldModel.getJSONArray("tmpls");
            switch((TemporaryModel.ChangeType) change[1]) {
                case ADD:
                    Timber.d("doInBackgroundSaveModel() adding template %s", change[0]);
                    try {
                        col.getModels().addTemplate(oldModel, newTemplates.getJSONObject((int) change[0]));
                    } catch (Exception e) {
                        Timber.e(e, "Unable to add template %s to model %s", change[0], model.getLong("id"));
                        return new TaskData(e.getLocalizedMessage(), false);
                    }
                    break;
                case DELETE:
                    Timber.d("doInBackgroundSaveModel() deleting template currently at ordinal %s", change[0]);
                    try {
                        col.getModels().remTemplate(oldModel, oldTemplates.getJSONObject((int) change[0]));
                    } catch (Exception e) {
                        Timber.e(e, "Unable to delete template %s from model %s", change[0], model.getLong("id"));
                        return new TaskData(e.getLocalizedMessage(), false);
                    }
                    break;
                default:
                    Timber.w("Unknown change type? %s", change[1]);
                    break;
            }
        }
        col.getModels().save(model, true);
        col.getModels().update(model);
        col.reset();
        col.save();
        if (col.getDb().getDatabase().inTransaction()) {
            col.getDb().getDatabase().setTransactionSuccessful();
        } else {
            Timber.i("CollectionTask::SaveModel was not in a transaction? Cannot mark transaction successful.");
        }
    } finally {
        if (col.getDb().getDatabase().inTransaction()) {
            col.getDb().getDatabase().endTransaction();
        } else {
            Timber.i("CollectionTask::SaveModel was not in a transaction? Cannot end transaction.");
        }
    }
    return new TaskData(true);
}
Also used : Model(com.ichi2.libanki.Model) TemporaryModel(com.ichi2.anki.TemporaryModel) ArrayList(java.util.ArrayList) JSONArray(com.ichi2.utils.JSONArray) Collection(com.ichi2.libanki.Collection) JSONObject(com.ichi2.utils.JSONObject) JSONException(com.ichi2.utils.JSONException) CancellationException(java.util.concurrent.CancellationException) FileNotFoundException(java.io.FileNotFoundException) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) ImportExportException(com.ichi2.anki.exception.ImportExportException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

JSONObject (com.ichi2.utils.JSONObject)53 Test (org.junit.Test)35 JSONArray (com.ichi2.utils.JSONArray)28 Model (com.ichi2.libanki.Model)24 ArrayList (java.util.ArrayList)16 Intent (android.content.Intent)14 RobolectricTest (com.ichi2.anki.RobolectricTest)14 Collection (com.ichi2.libanki.Collection)12 Note (com.ichi2.libanki.Note)12 SuppressLint (android.annotation.SuppressLint)9 HashMap (java.util.HashMap)8 Bundle (android.os.Bundle)7 JSONException (com.ichi2.utils.JSONException)7 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)6 Card (com.ichi2.libanki.Card)6 ShadowActivity (org.robolectric.shadows.ShadowActivity)6 ShadowIntent (org.robolectric.shadows.ShadowIntent)6 View (android.view.View)5 ContentResolver (android.content.ContentResolver)4 ContentValues (android.content.ContentValues)4