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);
}
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())));
}
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();
}
}
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));
}
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;
}
Aggregations