Search in sources :

Example 36 with ConfirmModSchemaException

use of com.ichi2.anki.exception.ConfirmModSchemaException in project AnkiChinaAndroid by ankichinateam.

the class ModelFieldEditor method renameField.

/*
     * Renames the current field
     */
private void renameField() throws ConfirmModSchemaException {
    String fieldLabel = mFieldNameInput.getText().toString().replaceAll("[\\n\\r]", "");
    JSONObject field = mNoteFields.getJSONObject(mCurrentPos);
    mCol.getModels().renameField(mMod, field, fieldLabel);
    mCol.getModels().save();
    fullRefreshList();
}
Also used : JSONObject(com.ichi2.utils.JSONObject)

Example 37 with ConfirmModSchemaException

use of com.ichi2.anki.exception.ConfirmModSchemaException in project AnkiChinaAndroid by ankichinateam.

the class DeckPicker method onFinishedStartup.

/**
 * Perform the following tasks:
 * Automatic backup
 * loadStudyOptionsFragment() if tablet
 * Automatic sync
 */
private void onFinishedStartup() {
    // create backup in background if needed
    if (getCol() == null) {
        return;
    }
    SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(this);
    if (preferences.getBoolean(AUTO_TURN_TO_LOGIN, true) && !Consts.isLogin()) {
        Intent myAccount = new Intent(this, MyAccount.class);
        myAccount.putExtra("notLoggedIn", true);
        startActivityForResultWithAnimation(myAccount, LOG_IN_FOR_SYNC, ActivityTransitionAnimation.FADE);
        preferences.edit().putBoolean(AUTO_TURN_TO_LOGIN, false).apply();
    }
    BackupManager.performBackupInBackground(getCol().getPath(), getCol().getTime());
    // Force a full sync if flag was set in upgrade path, asking the user to confirm if necessary
    if (mRecommendFullSync) {
        mRecommendFullSync = false;
        try {
            getCol().modSchema();
        } catch (ConfirmModSchemaException e) {
            Timber.w("Forcing full sync");
            // If libanki determines it's necessary to confirm the full sync then show a confirmation dialog
            // We have to show the dialog via the DialogHandler since this method is called via an async task
            Resources res = getResources();
            Message handlerMessage = Message.obtain();
            handlerMessage.what = DialogHandler.MSG_SHOW_FORCE_FULL_SYNC_DIALOG;
            Bundle handlerMessageData = new Bundle();
            handlerMessageData.putString("message", res.getString(R.string.full_sync_confirmation_upgrade) + "\n\n" + res.getString(R.string.full_sync_confirmation));
            handlerMessage.setData(handlerMessageData);
            getDialogHandler().sendMessage(handlerMessage);
        }
    }
    // Open StudyOptionsFragment if in fragmented mode
    automaticSync();
}
Also used : Message(android.os.Message) SharedPreferences(android.content.SharedPreferences) Bundle(android.os.Bundle) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) Intent(android.content.Intent) Resources(android.content.res.Resources)

Example 38 with ConfirmModSchemaException

use of com.ichi2.anki.exception.ConfirmModSchemaException in project AnkiChinaAndroid by ankichinateam.

the class CardContentProvider method insert.

@Override
public Uri insert(Uri uri, ContentValues values) {
    if (!hasReadWritePermission() && shouldEnforceQueryOrInsertSecurity()) {
        throwSecurityException("insert", uri);
    }
    Collection col = CollectionHelper.getInstance().getCol(mContext);
    if (col == null) {
        throw new IllegalStateException(COL_NULL_ERROR_MSG);
    }
    col.log(getLogMessage("insert", uri));
    // Find out what data the user is requesting
    int match = sUriMatcher.match(uri);
    switch(match) {
        case NOTES:
            {
                /* Insert new note with specified fields and tags
                 */
                Long modelId = values.getAsLong(FlashCardsContract.Note.MID);
                String flds = values.getAsString(FlashCardsContract.Note.FLDS);
                String tags = values.getAsString(FlashCardsContract.Note.TAGS);
                // Create empty note
                com.ichi2.libanki.Note newNote = new com.ichi2.libanki.Note(col, col.getModels().get(modelId));
                // Set fields
                String[] fldsArray = Utils.splitFields(flds);
                // Check that correct number of flds specified
                if (fldsArray.length != newNote.getFields().length) {
                    throw new IllegalArgumentException("Incorrect flds argument : " + flds);
                }
                for (int idx = 0; idx < fldsArray.length; idx++) {
                    newNote.setField(idx, fldsArray[idx]);
                }
                // Set tags
                if (tags != null) {
                    newNote.setTagsFromStr(tags);
                }
                // Add to collection
                col.addNote(newNote);
                col.save();
                return Uri.withAppendedPath(FlashCardsContract.Note.CONTENT_URI, Long.toString(newNote.getId()));
            }
        case NOTES_ID:
            // Note ID is generated automatically by libanki
            throw new IllegalArgumentException("Not possible to insert note with specific ID");
        case NOTES_ID_CARDS:
            // Cards are generated automatically by libanki
            throw new IllegalArgumentException("Not possible to insert cards directly (only through NOTES)");
        case NOTES_ID_CARDS_ORD:
            // Cards are generated automatically by libanki
            throw new IllegalArgumentException("Not possible to insert cards directly (only through NOTES)");
        case MODELS:
            // Get input arguments
            String modelName = values.getAsString(FlashCardsContract.Model.NAME);
            String css = values.getAsString(FlashCardsContract.Model.CSS);
            Long did = values.getAsLong(FlashCardsContract.Model.DECK_ID);
            String fieldNames = values.getAsString(FlashCardsContract.Model.FIELD_NAMES);
            Integer numCards = values.getAsInteger(FlashCardsContract.Model.NUM_CARDS);
            Integer sortf = values.getAsInteger(FlashCardsContract.Model.SORT_FIELD_INDEX);
            Integer type = values.getAsInteger(FlashCardsContract.Model.TYPE);
            String latexPost = values.getAsString(FlashCardsContract.Model.LATEX_POST);
            String latexPre = values.getAsString(FlashCardsContract.Model.LATEX_PRE);
            // Throw exception if required fields empty
            if (modelName == null || fieldNames == null || numCards == null) {
                throw new IllegalArgumentException("Model name, field_names, and num_cards can't be empty");
            }
            if (did != null && col.getDecks().isDyn(did)) {
                throw new IllegalArgumentException("Cannot set a filtered deck as default deck for a model");
            }
            // Create a new model
            Models mm = col.getModels();
            Model newModel = mm.newModel(modelName);
            try {
                // Add the fields
                String[] allFields = Utils.splitFields(fieldNames);
                for (String f : allFields) {
                    mm.addFieldInNewModel(newModel, mm.newField(f));
                }
                // Add some empty card templates
                for (int idx = 0; idx < numCards; idx++) {
                    JSONObject t = mm.newTemplate("Card " + (idx + 1));
                    t.put("qfmt", String.format("{{%s}}", allFields[0]));
                    String answerField = allFields[0];
                    if (allFields.length > 1) {
                        answerField = allFields[1];
                    }
                    t.put("afmt", String.format("{{FrontSide}}\\n\\n<hr id=answer>\\n\\n{{%s}}", answerField));
                    mm.addTemplateInNewModel(newModel, t);
                }
                // Add the CSS if specified
                if (css != null) {
                    newModel.put("css", css);
                }
                // Add the did if specified
                if (did != null) {
                    newModel.put("did", did);
                }
                if (sortf != null && sortf < allFields.length) {
                    newModel.put("sortf", sortf);
                }
                if (type != null) {
                    newModel.put("type", type);
                }
                if (latexPost != null) {
                    newModel.put("latexPost", latexPost);
                }
                if (latexPre != null) {
                    newModel.put("latexPre", latexPre);
                }
                // Add the model to collection (from this point on edits will require a full-sync)
                mm.add(newModel);
                col.save();
                // Get the mid and return a URI
                String mid = Long.toString(newModel.getLong("id"));
                return Uri.withAppendedPath(FlashCardsContract.Model.CONTENT_URI, mid);
            } catch (JSONException e) {
                Timber.e(e, "Could not set a field of new model %s", modelName);
                return null;
            }
        case MODELS_ID:
            // Model ID is generated automatically by libanki
            throw new IllegalArgumentException("Not possible to insert model with specific ID");
        case MODELS_ID_TEMPLATES:
            {
                Models models = col.getModels();
                Long mid = getModelIdFromUri(uri, col);
                Model existingModel = models.get(mid);
                if (existingModel == null) {
                    throw new IllegalArgumentException("model missing: " + mid);
                }
                String name = values.getAsString(CardTemplate.NAME);
                String qfmt = values.getAsString(CardTemplate.QUESTION_FORMAT);
                String afmt = values.getAsString(CardTemplate.ANSWER_FORMAT);
                String bqfmt = values.getAsString(CardTemplate.BROWSER_QUESTION_FORMAT);
                String bafmt = values.getAsString(CardTemplate.BROWSER_ANSWER_FORMAT);
                try {
                    JSONObject t = models.newTemplate(name);
                    t.put("qfmt", qfmt);
                    t.put("afmt", afmt);
                    t.put("bqfmt", bqfmt);
                    t.put("bafmt", bafmt);
                    models.addTemplate(existingModel, t);
                    models.save(existingModel);
                    col.save();
                    return ContentUris.withAppendedId(uri, t.getInt("ord"));
                } catch (ConfirmModSchemaException e) {
                    throw new IllegalArgumentException("Unable to add template without user requesting/accepting full-sync", e);
                } catch (JSONException e) {
                    throw new IllegalArgumentException("Unable to get ord from new template", e);
                }
            }
        case MODELS_ID_TEMPLATES_ID:
            throw new IllegalArgumentException("Not possible to insert template with specific ORD");
        case MODELS_ID_FIELDS:
            {
                Models models = col.getModels();
                Long mid = getModelIdFromUri(uri, col);
                Model existingModel = models.get(mid);
                if (existingModel == null) {
                    throw new IllegalArgumentException("model missing: " + mid);
                }
                String name = values.getAsString(FlashCardsContract.Model.FIELD_NAME);
                if (name == null) {
                    throw new IllegalArgumentException("field name missing for model: " + mid);
                }
                JSONObject field = models.newField(name);
                try {
                    models.addField(existingModel, field);
                    col.save();
                    JSONArray flds = existingModel.getJSONArray("flds");
                    return ContentUris.withAppendedId(uri, flds.length() - 1);
                } catch (ConfirmModSchemaException e) {
                    throw new IllegalArgumentException("Unable to insert field: " + name, e);
                } catch (JSONException e) {
                    throw new IllegalArgumentException("Unable to get newly created field: " + name, e);
                }
            }
        case SCHEDULE:
            // Doesn't make sense to insert an object into the schedule table
            throw new IllegalArgumentException("Not possible to perform insert operation on schedule");
        case DECKS:
            // Insert new deck with specified name
            String deckName = values.getAsString(FlashCardsContract.Deck.DECK_NAME);
            did = col.getDecks().id(deckName, false);
            if (did != null) {
                throw new IllegalArgumentException("Deck name already exists: " + deckName);
            }
            if (!Decks.isValidDeckName(deckName)) {
                throw new IllegalArgumentException("Invalid deck name '" + deckName + "'");
            }
            did = col.getDecks().id(deckName, true);
            Deck deck = col.getDecks().get(did);
            if (deck != null) {
                try {
                    String deckDesc = values.getAsString(FlashCardsContract.Deck.DECK_DESC);
                    if (deckDesc != null) {
                        deck.put("desc", deckDesc);
                    }
                } catch (JSONException e) {
                    Timber.e(e, "Could not set a field of new deck %s", deckName);
                    return null;
                }
            }
            col.getDecks().flush();
            return Uri.withAppendedPath(FlashCardsContract.Deck.CONTENT_ALL_URI, Long.toString(did));
        case DECK_SELECTED:
            // Can't have more than one selected deck
            throw new IllegalArgumentException("Selected deck can only be queried and updated");
        case DECKS_ID:
            // Deck ID is generated automatically by libanki
            throw new IllegalArgumentException("Not possible to insert deck with specific ID");
        default:
            // Unknown URI type
            throw new IllegalArgumentException("uri " + uri + " is not supported");
    }
}
Also used : Note(com.ichi2.libanki.Note) JSONArray(com.ichi2.utils.JSONArray) JSONException(com.ichi2.utils.JSONException) Deck(com.ichi2.libanki.Deck) JSONObject(com.ichi2.utils.JSONObject) Note(com.ichi2.libanki.Note) Model(com.ichi2.libanki.Model) Collection(com.ichi2.libanki.Collection) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) Models(com.ichi2.libanki.Models)

Example 39 with ConfirmModSchemaException

use of com.ichi2.anki.exception.ConfirmModSchemaException in project AnkiChinaAndroid by ankichinateam.

the class CollectionTask method doInBackGroundDeleteModel.

/**
 * Deletes the given model (stored in the long field of TaskData)
 * and all notes associated with it
 */
private TaskData doInBackGroundDeleteModel(TaskData param) {
    Timber.d("doInBackGroundDeleteModel");
    long modID = param.getLong();
    Collection col = getCol();
    try {
        col.getModels().rem(col.getModels().get(modID));
        col.save();
    } catch (ConfirmModSchemaException e) {
        Timber.e("doInBackGroundDeleteModel :: ConfirmModSchemaException");
        return new TaskData(false);
    }
    return new TaskData(true);
}
Also used : Collection(com.ichi2.libanki.Collection) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException)

Example 40 with ConfirmModSchemaException

use of com.ichi2.anki.exception.ConfirmModSchemaException in project AnkiChinaAndroid by ankichinateam.

the class CollectionTask method doInBackGroundRepositionField.

/**
 * Repositions the given field in the given model
 */
private TaskData doInBackGroundRepositionField(TaskData param) {
    Timber.d("doInBackgroundRepositionField");
    Object[] objects = param.getObjArray();
    Model model = (Model) objects[0];
    JSONObject field = (JSONObject) objects[1];
    int index = (Integer) objects[2];
    Collection col = getCol();
    try {
        col.getModels().moveField(model, field, index);
        col.save();
    } catch (ConfirmModSchemaException e) {
        // Should never be reached
        return new TaskData(false);
    }
    return new TaskData(true);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) Model(com.ichi2.libanki.Model) TemporaryModel(com.ichi2.anki.TemporaryModel) Collection(com.ichi2.libanki.Collection) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) JSONObject(com.ichi2.utils.JSONObject)

Aggregations

JSONObject (com.ichi2.utils.JSONObject)39 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)26 JSONArray (com.ichi2.utils.JSONArray)23 Test (org.junit.Test)22 RobolectricTest (com.ichi2.anki.RobolectricTest)14 ConfirmationDialog (com.ichi2.anki.dialogs.ConfirmationDialog)12 Collection (com.ichi2.libanki.Collection)12 Model (com.ichi2.libanki.Model)12 Note (com.ichi2.libanki.Note)8 ArrayList (java.util.ArrayList)8 JSONException (com.ichi2.utils.JSONException)6 HashMap (java.util.HashMap)5 SdkSuppress (androidx.test.filters.SdkSuppress)4 TaskData (com.ichi2.async.TaskData)4 ModelManager (com.ichi2.libanki.ModelManager)4 TextImporter (com.ichi2.libanki.importer.TextImporter)4 Matchers.containsString (org.hamcrest.Matchers.containsString)4 Cursor (android.database.Cursor)3 Uri (android.net.Uri)3 Bundle (android.os.Bundle)3