Search in sources :

Example 1 with JSONArray

use of com.ichi2.utils.JSONArray in project AnkiChinaAndroid by ankichinateam.

the class ContentProviderTest method testInsertField.

/**
 * Check that inserting and removing a note into default deck works as expected
 */
@Test
public void testInsertField() throws Exception {
    // Get required objects for test
    final ContentResolver cr = InstrumentationRegistry.getInstrumentation().getTargetContext().getContentResolver();
    Collection col = getCol();
    Model model = StdModels.basicModel.add(col, BASIC_MODEL_NAME);
    long modelId = model.getLong("id");
    JSONArray initialFieldsArr = model.getJSONArray("flds");
    int initialFieldCount = initialFieldsArr.length();
    Uri noteTypeUri = ContentUris.withAppendedId(FlashCardsContract.Model.CONTENT_URI, modelId);
    ContentValues insertFieldValues = new ContentValues();
    insertFieldValues.put(FlashCardsContract.Model.FIELD_NAME, TEST_FIELD_NAME);
    Uri fieldUri = cr.insert(Uri.withAppendedPath(noteTypeUri, "fields"), insertFieldValues);
    assertNotNull("Check field uri", fieldUri);
    // Ensure that the changes are physically saved to the DB
    col = reopenCol();
    model = col.getModels().get(modelId);
    // Test the field is as expected
    long fieldId = ContentUris.parseId(fieldUri);
    assertEquals("Check field id", initialFieldCount, fieldId);
    assertNotNull("Check model", model);
    JSONArray fldsArr = model.getJSONArray("flds");
    assertEquals("Check fields length", initialFieldCount + 1, fldsArr.length());
    assertEquals("Check last field name", TEST_FIELD_NAME, fldsArr.getJSONObject(fldsArr.length() - 1).optString("name", ""));
    col.getModels().rem(model);
}
Also used : ContentValues(android.content.ContentValues) Model(com.ichi2.libanki.Model) JSONArray(com.ichi2.utils.JSONArray) Collection(com.ichi2.libanki.Collection) Uri(android.net.Uri) ContentResolver(android.content.ContentResolver) Test(org.junit.Test)

Example 2 with JSONArray

use of com.ichi2.utils.JSONArray 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 JSONArray

use of com.ichi2.utils.JSONArray in project AnkiChinaAndroid by ankichinateam.

the class NoteEditor method saveNote.

@VisibleForTesting
void saveNote() {
    final Resources res = getResources();
    if (mSelectedTags == null) {
        mSelectedTags = new ArrayList<>(0);
    }
    // treat add new note and edit existing note independently
    if (mAddNote) {
        // DEFECT: This does not block addition if cloze transpositions are in non-cloze fields.
        if (isClozeType() && !hasClozeDeletions()) {
            displayErrorSavingNote();
            return;
        }
        // load all of the fields into the note
        for (FieldEditText f : mEditFields) {
            updateField(f);
        }
        // Save deck to model
        mEditorNote.model().put("did", mCurrentDid);
        // Save tags to model
        mEditorNote.setTagsFromStr(tagsAsString(mSelectedTags));
        JSONArray tags = new JSONArray();
        for (String t : mSelectedTags) {
            tags.put(t);
        }
        getCol().getModels().current().put("tags", tags);
        getCol().getModels().setChanged();
        mReloadRequired = true;
        CollectionTask.launchCollectionTask(ADD_NOTE, saveNoteHandler(), new TaskData(mEditorNote));
    } else {
        // Check whether note type has been changed
        final Model newModel = getCurrentlySelectedModel();
        final Model oldModel = (mCurrentEditedCard == null) ? null : mCurrentEditedCard.model();
        File target = new File(FileUtil.createTmpDir(this), mCurrentEditedCard.getId() + ".wav");
        if (target.exists()) {
            Timber.i("editing card audio is exists,delete it");
            target.delete();
        }
        if (!newModel.equals(oldModel)) {
            mReloadRequired = true;
            if (mModelChangeCardMap.size() < mEditorNote.numberOfCards() || mModelChangeCardMap.containsValue(null)) {
                // If cards will be lost via the new mapping then show a confirmation dialog before proceeding with the change
                ConfirmationDialog dialog = new ConfirmationDialog();
                dialog.setArgs(res.getString(R.string.confirm_map_cards_to_nothing));
                Runnable confirm = () -> {
                    // Bypass the check once the user confirms
                    changeNoteTypeWithErrorHandling(oldModel, newModel);
                };
                dialog.setConfirm(confirm);
                showDialogFragment(dialog);
            } else {
                // Otherwise go straight to changing note type
                changeNoteTypeWithErrorHandling(oldModel, newModel);
            }
            return;
        }
        // Regular changes in note content
        boolean modified = false;
        // changed did? this has to be done first as remFromDyn() involves a direct write to the database
        if (mCurrentEditedCard != null && mCurrentEditedCard.getDid() != mCurrentDid) {
            mReloadRequired = true;
            // remove card from filtered deck first (if relevant)
            getCol().getSched().remFromDyn(new long[] { mCurrentEditedCard.getId() });
            // refresh the card object to reflect the database changes in remFromDyn()
            mCurrentEditedCard.load();
            // also reload the note object
            mEditorNote = mCurrentEditedCard.note();
            // then set the card ID to the new deck
            mCurrentEditedCard.setDid(mCurrentDid);
            modified = true;
        }
        // now load any changes to the fields from the form
        for (FieldEditText f : mEditFields) {
            modified = modified | updateField(f);
        }
        // added tag?
        for (String t : mSelectedTags) {
            modified = modified || !mEditorNote.hasTag(t);
        }
        // removed tag?
        modified = modified || mEditorNote.getTags().size() > mSelectedTags.size();
        if (modified) {
            mEditorNote.setTagsFromStr(tagsAsString(mSelectedTags));
            mChanged = true;
        }
        closeNoteEditor();
    }
}
Also used : JSONArray(com.ichi2.utils.JSONArray) Model(com.ichi2.libanki.Model) Resources(android.content.res.Resources) File(java.io.File) TaskData(com.ichi2.async.TaskData) ConfirmationDialog(com.ichi2.anki.dialogs.ConfirmationDialog) VisibleForTesting(androidx.annotation.VisibleForTesting)

Example 4 with JSONArray

use of com.ichi2.utils.JSONArray in project AnkiChinaAndroid by ankichinateam.

the class PosterActivity method onCreate.

@Override
protected void onCreate(Bundle savedInstanceState) {
    Themes.setThemeLegacy(this);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_poster);
    String poster = getIntent().getStringExtra("poster");
    root = new JSONObject(poster);
    JSONArray members = root.getJSONArray("members");
    setText(R.id.content_title, root.getString("title"));
    setText(R.id.content_classify, root.getString("level") + "/" + root.getString("subject"));
    setText(R.id.content_price_origin, "原价¥ " + root.getString("origin_price"));
    // 中划线
    ((TextView) findViewById(R.id.content_price_origin)).getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
    setText(R.id.content_price, "¥ " + root.getString("team_price"));
    setText(R.id.content_num, root.getString("study_users") + "人正在学习");
    setText(R.id.content_time_remain, "拼团特惠仅剩" + root.getInt("quota") + "名额\n" + convertSeconds(root.getInt("countDown")) + "后结束");
    setText(R.id.content_num_remain, "还差" + (root.getInt("users") - members.length()) + "人,特享团购价");
    ImageView qrcode = findViewById(R.id.qr_code);
    Bitmap mBitmap = QRCodeUtil.createQRCodeBitmap(root.getString("link"), Utils.dp2px(this, 160), Utils.dp2px(this, 160));
    qrcode.setImageBitmap(mBitmap);
    LinearLayout memberLayout = findViewById(R.id.join_list);
    for (int i = 0; i < members.length(); i++) {
        if (root.getInt("users") > 3) {
            // 需要人数大于3个,那就保留一个空位
            if (i > 1) {
                // 最多添加2个
                break;
            }
        }
        // if(root.getInt("users")==3) {
        // //需要人数刚好是3个,那就三个都占满
        // if (i > 2) {
        // break;
        // }
        // }
        View view = getLayoutInflater().inflate(R.layout.item_poster_avatar, null);
        ImageView avatar = view.findViewById(R.id.avatar);
        if (i == 0) {
            view.findViewById(R.id.host_role).setVisibility(View.VISIBLE);
        }
        Glide.with(this).asBitmap().load(members.getJSONObject(i).getString("avatar")).into(avatar);
        memberLayout.addView(view);
    }
    for (int i = memberLayout.getChildCount(); i < 3; i++) {
        View view = getLayoutInflater().inflate(R.layout.item_poster_avatar_empty, null);
        memberLayout.addView(view);
    }
    JSONArray tags = root.getJSONArray("tags");
    for (int i = 0; i < tags.length(); i++) {
        View view = getLayoutInflater().inflate(R.layout.item_warp_poster, null);
        Button button = view.findViewById(R.id.text);
        button.setText(tags.getString(i));
        ((WarpLinearLayout) findViewById(R.id.tags_layout)).addView(view);
    }
    showShareDialog(findViewById(R.id.rootView));
}
Also used : Bitmap(android.graphics.Bitmap) JSONObject(com.ichi2.utils.JSONObject) Button(android.widget.Button) JSONArray(com.ichi2.utils.JSONArray) WarpLinearLayout(com.ichi2.ui.WarpLinearLayout) ImageView(android.widget.ImageView) ImageView(android.widget.ImageView) View(android.view.View) TextView(android.widget.TextView) LinearLayout(android.widget.LinearLayout) WarpLinearLayout(com.ichi2.ui.WarpLinearLayout) Paint(android.graphics.Paint)

Example 5 with JSONArray

use of com.ichi2.utils.JSONArray in project AnkiChinaAndroid by ankichinateam.

the class CustomStudyDialog method buildInputDialog.

/**
 * Build an input dialog that is used to get a parameter related to custom study from the user
 *
 * @param dialogId
 * @return
 */
private MaterialDialog buildInputDialog(final int dialogId) {
    /*
            TODO: Try to change to a standard input dialog (currently the thing holding us back is having the extra
            TODO: hint line for the number of cards available, and having the pre-filled text selected by default)
        */
    // Input dialogs
    Resources res = getActivity().getResources();
    // Show input dialog for an individual custom study dialog
    View v = getActivity().getLayoutInflater().inflate(R.layout.styled_custom_study_details_dialog, null);
    TextView textView1 = (TextView) v.findViewById(R.id.custom_study_details_text1);
    TextView textView2 = (TextView) v.findViewById(R.id.custom_study_details_text2);
    final EditText mEditText = (EditText) v.findViewById(R.id.custom_study_details_edittext2);
    // Set the text
    textView1.setText(getText1());
    textView2.setText(getText2());
    mEditText.setText(getDefaultValue());
    // Give EditText focus and show keyboard
    mEditText.setSelectAllOnFocus(true);
    mEditText.requestFocus();
    if (dialogId == CUSTOM_STUDY_NEW || dialogId == CUSTOM_STUDY_REV) {
        mEditText.setInputType(EditorInfo.TYPE_CLASS_NUMBER | EditorInfo.TYPE_NUMBER_FLAG_SIGNED);
    }
    // deck id
    final long did = getArguments().getLong("did");
    // Whether or not to jump straight to the reviewer
    final boolean jumpToReviewer = getArguments().getBoolean("jumpToReviewer");
    // Set builder parameters
    MaterialDialog.Builder builder = new MaterialDialog.Builder(getActivity()).customView(v, true).positiveText(res.getString(R.string.dialog_ok)).negativeText(res.getString(R.string.dialog_cancel)).onPositive((dialog, which) -> {
        Collection col = CollectionHelper.getInstance().getCol(getActivity());
        // Get the value selected by user
        int n;
        try {
            n = Integer.parseInt(mEditText.getText().toString());
        } catch (Exception ignored) {
            // This should never happen because we disable positive button for non-parsable inputs
            return;
        }
        // Set behavior when clicking OK button
        switch(dialogId) {
            case CUSTOM_STUDY_NEW:
                {
                    AnkiDroidApp.getSharedPrefs(getActivity()).edit().putInt("extendNew", n).commit();
                    Deck deck = col.getDecks().get(did);
                    deck.put("extendNew", n);
                    col.getDecks().save(deck);
                    col.getSched().extendLimits(n, 0);
                    onLimitsExtended(jumpToReviewer);
                    break;
                }
            case CUSTOM_STUDY_REV:
                {
                    AnkiDroidApp.getSharedPrefs(getActivity()).edit().putInt("extendRev", n).commit();
                    Deck deck = col.getDecks().get(did);
                    deck.put("extendRev", n);
                    col.getDecks().save(deck);
                    col.getSched().extendLimits(0, n);
                    onLimitsExtended(jumpToReviewer);
                    break;
                }
            case CUSTOM_STUDY_FORGOT:
                {
                    JSONArray ar = new JSONArray();
                    ar.put(0, 1);
                    createCustomStudySession(ar, new Object[] { String.format(Locale.US, "rated:%d:1", n), Consts.DYN_MAX_SIZE, Consts.DYN_RANDOM }, false);
                    break;
                }
            case CUSTOM_STUDY_AHEAD:
                {
                    createCustomStudySession(new JSONArray(), new Object[] { String.format(Locale.US, "prop:due<=%d", n), Consts.DYN_MAX_SIZE, Consts.DYN_DUE }, true);
                    break;
                }
            case CUSTOM_STUDY_RANDOM:
                {
                    createCustomStudySession(new JSONArray(), new Object[] { "", n, Consts.DYN_RANDOM }, true);
                    break;
                }
            case CUSTOM_STUDY_PREVIEW:
                {
                    createCustomStudySession(new JSONArray(), new Object[] { "is:new added:" + Integer.toString(n), Consts.DYN_MAX_SIZE, Consts.DYN_OLDEST }, false);
                    break;
                }
            default:
                break;
        }
    }).onNegative((dialog, which) -> getAnkiActivity().dismissAllDialogFragments());
    final MaterialDialog dialog = builder.build();
    mEditText.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void afterTextChanged(Editable editable) {
            try {
                Integer.parseInt(mEditText.getText().toString());
                dialog.getActionButton(DialogAction.POSITIVE).setEnabled(true);
            } catch (Exception ignored) {
                dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
            }
        }
    });
    // Show soft keyboard
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    return dialog;
}
Also used : EditText(android.widget.EditText) TaskListener(com.ichi2.async.TaskListener) Bundle(android.os.Bundle) Deck(com.ichi2.libanki.Deck) NonNull(androidx.annotation.NonNull) AnalyticsDialogFragment(com.ichi2.anki.analytics.AnalyticsDialogFragment) WindowManager(android.view.WindowManager) R(com.ichi2.anki.R) Dialog(android.app.Dialog) Intent(android.content.Intent) HashMap(java.util.HashMap) Collection(com.ichi2.libanki.Collection) Editable(android.text.Editable) ArrayList(java.util.ArrayList) TASK_TYPE(com.ichi2.async.CollectionTask.TASK_TYPE) JSONArray(com.ichi2.utils.JSONArray) Locale(java.util.Locale) UIUtils(com.ichi2.anki.UIUtils) View(android.view.View) TaskData(com.ichi2.async.TaskData) DeckPicker(com.ichi2.anki.DeckPicker) TextUtils(android.text.TextUtils) DialogAction(com.afollestad.materialdialogs.DialogAction) CollectionTask(com.ichi2.async.CollectionTask) JSONObject(com.ichi2.utils.JSONObject) Timber(timber.log.Timber) CollectionHelper(com.ichi2.anki.CollectionHelper) AnkiActivity(com.ichi2.anki.AnkiActivity) List(java.util.List) TextView(android.widget.TextView) SharedPreferences(android.content.SharedPreferences) AnkiDroidApp(com.ichi2.anki.AnkiDroidApp) Consts(com.ichi2.libanki.Consts) Reviewer(com.ichi2.anki.Reviewer) TaskListenerWithContext(com.ichi2.async.TaskListenerWithContext) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) VisibleForTesting(androidx.annotation.VisibleForTesting) EditorInfo(android.view.inputmethod.EditorInfo) DeckOptions(com.ichi2.anki.DeckOptions) EditText(android.widget.EditText) Resources(android.content.res.Resources) TextWatcher(android.text.TextWatcher) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) JSONArray(com.ichi2.utils.JSONArray) Deck(com.ichi2.libanki.Deck) View(android.view.View) TextView(android.widget.TextView) Collection(com.ichi2.libanki.Collection) TextWatcher(android.text.TextWatcher) Editable(android.text.Editable) TextView(android.widget.TextView) Resources(android.content.res.Resources)

Aggregations

JSONArray (com.ichi2.utils.JSONArray)188 JSONObject (com.ichi2.utils.JSONObject)97 Collection (com.ichi2.libanki.Collection)54 Test (org.junit.Test)44 ArrayList (java.util.ArrayList)42 Note (com.ichi2.libanki.Note)40 Card (com.ichi2.libanki.Card)39 DeckConfig (com.ichi2.libanki.DeckConfig)37 RobolectricTest (com.ichi2.anki.RobolectricTest)36 Deck (com.ichi2.libanki.Deck)19 Model (com.ichi2.libanki.Model)19 JSONException (com.ichi2.utils.JSONException)19 Cursor (android.database.Cursor)17 HashMap (java.util.HashMap)16 SuppressLint (android.annotation.SuppressLint)15 IOException (java.io.IOException)14 NonNull (androidx.annotation.NonNull)13 File (java.io.File)10 Response (okhttp3.Response)10 JSONArray (org.json.JSONArray)8