Search in sources :

Example 31 with START

use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project AnkiChinaAndroid by ankichinateam.

the class AbstractFlashcardViewer method showLayoutDialog.

protected void showLayoutDialog() {
    SharedPreferences preference = AnkiDroidApp.getSharedPrefs(this);
    if (mLayoutConfigDialog == null) {
        mLayoutConfigDialog = new Dialog(this, R.style.DialogTheme2);
        View view = View.inflate(this, R.layout.dialog_layout_config, null);
        mLayoutConfigDialog.setContentView(view);
        Window window = mLayoutConfigDialog.getWindow();
        mLayoutConfigDialog.setOnDismissListener(dialog -> {
            if (mCurrentCSS.equals(mCurrentEditingDefaultCSS)) {
                // 没修改过,直接返回
                return;
            }
            // 将当前css转化为类,添加修改时间
            JSONObject object = convertCss2JsonAndSave();
            if (needUploadViewSetting == null) {
                needUploadViewSetting = new JSONObject();
            }
            needUploadViewSetting.put(String.valueOf(mCurrentCard.model().getLong("id")), object);
            Timber.i("save layout config :%s", needUploadViewSetting.toString());
            preference.edit().putString(Consts.KEY_LOCAL_LAYOUT_CONFIG, needUploadViewSetting.toString().replace("\\", "")).apply();
            getAccount().getToken(AbstractFlashcardViewer.this, new MyAccount.TokenCallback() {

                @Override
                public void onSuccess(String token) {
                    RequestBody formBody = new FormBody.Builder().add("models_view_settings", needUploadViewSetting.toString()).build();
                    OKHttpUtil.post(Consts.ANKI_CHINA_BASE + Consts.API_VERSION + "users/conf", formBody, token, "", new OKHttpUtil.MyCallBack() {

                        @Override
                        public void onFailure(Call call, IOException e) {
                            e.printStackTrace();
                        }

                        @Override
                        public void onResponse(Call call, String token, Object arg1, Response response) {
                            if (response.isSuccessful()) {
                                Timber.i("post view settings successfully!:%s", response.body());
                            } else {
                                Timber.e("post view settings failed, error code %d", response.code());
                            }
                        }
                    });
                }

                @Override
                public void onFail(String message) {
                }
            });
        });
        // addMenuBottomDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
        // 设置弹出位置
        window.setGravity(Gravity.BOTTOM);
        window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        view.findViewById(R.id.close).setOnClickListener(v -> mLayoutConfigDialog.dismiss());
        view.findViewById(R.id.reset).setOnClickListener(v -> {
            // 将当前样式变回css()样式
            // mCurrentCSS = mCurrentCard.css().replace("<style>", "").replace("</style>", "");
            mCurrentCSS = ".card {}";
            // mCurrentCSS = mCurrentEditingDefaultCSS;
            // Timber.i("show updateTypeAnswerInfo");
            // JSONObject temp = convertCss2JsonAndSave();
            fontSizeSeekBar.setProgress(0);
            for (View view1 : layers) {
                // 存在无一被选中的情况,通过预先全设置为非选中实现
                view1.setSelected(false);
            }
            for (View view1 : bgColors) {
                view1.setSelected(false);
            }
            for (View view1 : aligns) {
                view1.setSelected(false);
            }
            String localViewSettingStr = preference.getString(Consts.KEY_LOCAL_LAYOUT_CONFIG, "");
            mCurrentCSSModelID = mCurrentCard.model().getLong("id");
            if (localViewSettingStr != null && !localViewSettingStr.isEmpty()) {
                needUploadViewSetting = new JSONObject(localViewSettingStr);
                if (needUploadViewSetting.remove(String.valueOf(mCurrentCSSModelID)) != null) {
                    Timber.i("remove saved setting :%s", mCurrentCSSModelID);
                    preference.edit().putString(Consts.KEY_LOCAL_LAYOUT_CONFIG, needUploadViewSetting.toString().replace("\\", "")).apply();
                }
            }
            if (!mCacheContent.isEmpty()) {
                updateCard(mCacheContent);
            }
        });
        alignLeft = view.findViewById(R.id.ic_align_left);
        alignRight = view.findViewById(R.id.ic_align_right);
        alignNormal = view.findViewById(R.id.ic_align_normal);
        alignCenter = view.findViewById(R.id.ic_align_center);
        aligns.add(alignLeft);
        aligns.add(alignRight);
        aligns.add(alignNormal);
        aligns.add(alignCenter);
        layerTop = view.findViewById(R.id.ic_layer_top);
        layerCenter = view.findViewById(R.id.ic_layer_center);
        layerBottom = view.findViewById(R.id.ic_layer_bottom);
        layers.add(layerTop);
        layers.add(layerCenter);
        layers.add(layerBottom);
        bgColorWhite = view.findViewById(R.id.ic_bg_white);
        bgColorGrey = view.findViewById(R.id.ic_bg_grey);
        bgColorBrown = view.findViewById(R.id.ic_bg_brown);
        bgColorGreen = view.findViewById(R.id.ic_bg_green);
        bgColorBlack = view.findViewById(R.id.ic_bg_black);
        bgColors.add(bgColorWhite);
        bgColors.add(bgColorGrey);
        bgColors.add(bgColorBrown);
        bgColors.add(bgColorGreen);
        bgColors.add(bgColorBlack);
        alignLeft.setOnClickListener(v -> onLayoutConfigAlignClick("left", alignLeft));
        alignRight.setOnClickListener(v -> onLayoutConfigAlignClick("right", alignRight));
        alignNormal.setOnClickListener(v -> onLayoutConfigAlignClick("justify", alignNormal));
        alignCenter.setOnClickListener(v -> onLayoutConfigAlignClick("center", alignCenter));
        layerTop.setOnClickListener(v -> onLayoutConfigLayerClick("flex-start", layerTop));
        layerCenter.setOnClickListener(v -> onLayoutConfigLayerClick("center", layerCenter));
        layerBottom.setOnClickListener(v -> onLayoutConfigLayerClick("flex-end", layerBottom));
        bgColorWhite.setOnClickListener(v -> onLayoutConfigBgClick("white", bgColorWhite));
        bgColorGrey.setOnClickListener(v -> onLayoutConfigBgClick("#F4F4F6", bgColorGrey));
        bgColorBrown.setOnClickListener(v -> onLayoutConfigBgClick("#E4DCCE", bgColorBrown));
        bgColorGreen.setOnClickListener(v -> onLayoutConfigBgClick("#BADEBE", bgColorGreen));
        bgColorBlack.setOnClickListener(v -> onLayoutConfigBgClick("black", bgColorBlack));
        fontSizeSeekBar = view.findViewById(R.id.font_size_seek_bar);
        fontSizeSeekBar.setRange(0, 80);
        fontSizeSeekBar.setOnRangeChangedListener(new OnRangeChangedListener() {

            @Override
            public void onRangeChanged(RangeSeekBar view, float leftValue, float rightValue, boolean isFromUser) {
                if (!isFromUser) {
                    return;
                }
                Matcher fontSizeMatcher = Pattern.compile("font-size:(.+?)px").matcher(mCurrentCSS);
                if (fontSizeMatcher.find()) {
                    String fld1 = fontSizeMatcher.group(0);
                    mCurrentCSS = mCurrentCSS.replace(fld1, String.format(Locale.CHINA, "font-size: %.0fpx", leftValue));
                } else {
                    mCurrentCSS = mCurrentCSS.replace("}", String.format(Locale.CHINA, "font-size: %.0fpx;}", leftValue));
                }
                // 字体大小
                Timber.i("set font size fld:%s", leftValue);
                if (!mCacheContent.isEmpty()) {
                    updateCard(mCacheContent);
                }
            // needUploadViewSetting.put(String.valueOf(mCurrentCard.model().getLong("id")), mCurrentCSS.replace(".card", ""));
            }

            @Override
            public void onStartTrackingTouch(RangeSeekBar view, boolean isLeft) {
            }

            @Override
            public void onStopTrackingTouch(RangeSeekBar view, boolean isLeft) {
            }
        });
    }
    if (mLayoutConfigDialog.isShowing()) {
        mLayoutConfigDialog.dismiss();
        return;
    }
    if (mCurrentCSS.isEmpty() || mCurrentCSSModelID != mCurrentCard.model().getLong("id")) {
        // 获取preferences是否有保存的布局设置
        String localViewSettingStr = preference.getString(Consts.KEY_LOCAL_LAYOUT_CONFIG, "");
        boolean notSync = false;
        mCurrentCSSModelID = mCurrentCard.model().getLong("id");
        if (localViewSettingStr != null && !localViewSettingStr.isEmpty()) {
            Timber.i("find local view setting:%s", localViewSettingStr);
            needUploadViewSetting = new JSONObject(localViewSettingStr);
            try {
                JSONObject currentModelSetting = needUploadViewSetting.getJSONObject(String.valueOf(mCurrentCSSModelID));
                if (currentModelSetting != null) {
                    mCurrentCSS = convertJson2Css(currentModelSetting, true);
                } else {
                    notSync = true;
                    // 没这个记录,新建一个默认模板
                    mCurrentCSS = ".card {}";
                }
            } catch (Exception e) {
                e.printStackTrace();
                notSync = true;
                mCurrentCSS = ".card {}";
            // needUploadViewSetting.put()
            }
        } else {
            // needUploadViewSetting = new JSONObject();
            mCurrentCSS = ".card {}";
        }
    } else {
        // 将dialog改为原设布局
        convertJson2Css(convertCss2JsonAndSave(), true);
    }
    // 保存刚载入时的css,留着备用
    mCurrentEditingDefaultCSS = mCurrentCSS;
    // if (localViewSettingStr == null || localViewSettingStr.isEmpty() || notSync) {
    // //本地没数据或当前model未保存,则从数据库model里的css里找 //不找了。
    // mCurrentCSS = mCurrentCard.css().replace("<style>", "").replace("</style>", "");
    // //            Timber.i("show updateTypeAnswerInfo");
    // JSONObject temp = convertCss2JsonAndSave();
    // fontSizeSeekBar.setProgress(Float.parseFloat(temp.getString("font_size")) - 8);
    // updateLayoutConfigDialog(TYPE_ALIGN, temp.getString("text_align"));
    // updateLayoutConfigDialog(TYPE_LAYER, temp.getString("layout"));
    // updateLayoutConfigDialog(TYPE_BG, temp.getString("background_color"));
    // if (needUploadViewSetting == null) {
    // needUploadViewSetting = new JSONObject();
    // }
    // if (notSync) {
    // needUploadViewSetting.put(String.valueOf(mCurrentCSSModelID), temp.toString());
    // }
    // }
    mLayoutConfigDialog.show();
}
Also used : Window(android.view.Window) Call(okhttp3.Call) RangeSeekBar(com.jaygoo.widget.RangeSeekBar) OnRangeChangedListener(com.jaygoo.widget.OnRangeChangedListener) SharedPreferences(android.content.SharedPreferences) Matcher(java.util.regex.Matcher) FormBody(okhttp3.FormBody) IOException(java.io.IOException) ImageView(android.widget.ImageView) View(android.view.View) WebView(android.webkit.WebView) TextView(android.widget.TextView) AudioView(com.ichi2.anki.multimediacard.AudioView) JSONException(com.ichi2.utils.JSONException) IOException(java.io.IOException) ActivityNotFoundException(android.content.ActivityNotFoundException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) WebResourceResponse(android.webkit.WebResourceResponse) Response(okhttp3.Response) JSONObject(com.ichi2.utils.JSONObject) TagsDialog(com.ichi2.anki.dialogs.TagsDialog) Dialog(android.app.Dialog) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) JSONObject(com.ichi2.utils.JSONObject) RequestBody(okhttp3.RequestBody)

Example 32 with START

use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project AnkiChinaAndroid by ankichinateam.

the class TagsDialog method adjustToolbar.

private void adjustToolbar(View tagsDialogView) {
    Toolbar mToolbar = tagsDialogView.findViewById(R.id.tags_dialog_toolbar);
    mToolbar.setTitle(mDialogTitle);
    mToolbar.inflateMenu(R.menu.tags_dialog_menu);
    final InputFilter addTagFilter = (source, start, end, dest, dstart, dend) -> {
        for (int i = start; i < end; i++) {
            if (source.charAt(i) == ' ') {
                return "";
            }
        }
        return null;
    };
    MenuItem mToolbarAddItem = mToolbar.getMenu().findItem(R.id.tags_dialog_action_add);
    mToolbarAddItem.setOnMenuItemClickListener(menuItem -> {
        String query = mToolbarSearchView.getQuery().toString();
        if (mToolbarSearchItem.isActionViewExpanded() && !TextUtils.isEmpty(query)) {
            addTag(query);
            mToolbarSearchView.setQuery("", true);
        } else {
            MaterialDialog.Builder addTagBuilder = new MaterialDialog.Builder(getActivity()).title(getString(R.string.add_tag)).negativeText(R.string.dialog_cancel).positiveText(R.string.dialog_ok).inputType(InputType.TYPE_CLASS_TEXT).input(R.string.tag_name, R.string.empty_string, (dialog, input) -> addTag(input.toString()));
            final MaterialDialog addTagDialog = addTagBuilder.build();
            EditText inputET = addTagDialog.getInputEditText();
            inputET.setFilters(new InputFilter[] { addTagFilter });
            addTagDialog.show();
        }
        return true;
    });
    mToolbarSearchItem = mToolbar.getMenu().findItem(R.id.tags_dialog_action_filter);
    mToolbarSearchView = (SearchView) mToolbarSearchItem.getActionView();
    EditText queryET = mToolbarSearchView.findViewById(R.id.search_src_text);
    queryET.setFilters(new InputFilter[] { addTagFilter });
    mToolbarSearchView.setQueryHint(getString(R.string.filter_tags));
    mToolbarSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

        @Override
        public boolean onQueryTextSubmit(String query) {
            mToolbarSearchView.clearFocus();
            return true;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            TagsArrayAdapter adapter = (TagsArrayAdapter) mTagsListRecyclerView.getAdapter();
            adapter.getFilter().filter(newText);
            return true;
        }
    });
    MenuItem checkAllItem = mToolbar.getMenu().findItem(R.id.tags_dialog_action_select_all);
    checkAllItem.setOnMenuItemClickListener(menuItem -> {
        boolean changed = false;
        if (mCurrentTags.containsAll(mTagsArrayAdapter.mTagsList)) {
            mCurrentTags.removeAll(mTagsArrayAdapter.mTagsList);
            changed = true;
        } else {
            for (String tag : mTagsArrayAdapter.mTagsList) {
                if (!mCurrentTags.contains(tag)) {
                    mCurrentTags.add(tag);
                    changed = true;
                }
            }
        }
        if (changed) {
            mTagsArrayAdapter.notifyDataSetChanged();
        }
        return true;
    });
    switch(mType) {
        case TYPE_ADD_TAG:
            mToolbarSearchView.setQueryHint(getString(R.string.add_new_filter_tags));
            break;
        default:
            mToolbarAddItem.setVisible(false);
            break;
    }
}
Also used : Bundle(android.os.Bundle) NonNull(androidx.annotation.NonNull) AnalyticsDialogFragment(com.ichi2.anki.analytics.AnalyticsDialogFragment) WindowManager(android.view.WindowManager) R(com.ichi2.anki.R) Filter(android.widget.Filter) Dialog(android.app.Dialog) RadioGroup(android.widget.RadioGroup) TreeSet(java.util.TreeSet) MenuItem(android.view.MenuItem) ArrayList(java.util.ArrayList) UIUtils(com.ichi2.anki.UIUtils) View(android.view.View) RecyclerView(androidx.recyclerview.widget.RecyclerView) LayoutInflater(android.view.LayoutInflater) InputType(android.text.InputType) TextUtils(android.text.TextUtils) SearchView(androidx.appcompat.widget.SearchView) ViewGroup(android.view.ViewGroup) List(java.util.List) TextView(android.widget.TextView) CheckedTextView(android.widget.CheckedTextView) Toolbar(androidx.appcompat.widget.Toolbar) Filterable(android.widget.Filterable) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) InputFilter(android.text.InputFilter) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) Collections(java.util.Collections) EditText(android.widget.EditText) Resources(android.content.res.Resources) EditText(android.widget.EditText) InputFilter(android.text.InputFilter) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) MenuItem(android.view.MenuItem) SearchView(androidx.appcompat.widget.SearchView) Toolbar(androidx.appcompat.widget.Toolbar)

Example 33 with START

use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project AnkiChinaAndroid by ankichinateam.

the class UIProgressListener method onProgress.

@Override
public void onProgress(long bytesWrite, long contentLength, boolean done) {
    // 如果是第一次,发送消息
    if (!isFirst) {
        isFirst = true;
        Message start = Message.obtain();
        start.obj = new ProgressModel(bytesWrite, contentLength, done);
        start.what = ProgressHandler.START;
        mHandler.sendMessage(start);
    }
    // 通过Handler发送进度消息
    Message message = Message.obtain();
    message.obj = new ProgressModel(bytesWrite, contentLength, done);
    message.what = ProgressHandler.UPDATE;
    mHandler.sendMessage(message);
    if (done) {
        Message finish = Message.obtain();
        finish.obj = new ProgressModel(bytesWrite, contentLength, done);
        finish.what = ProgressHandler.FINISH;
        mHandler.sendMessage(finish);
    }
}
Also used : ProgressModel(com.ichi2.utils.okhttp.listener.impl.model.ProgressModel) Message(android.os.Message)

Example 34 with START

use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project AnkiChinaAndroid by ankichinateam.

the class BasicTextFieldController method createTranslateButton.

// Here is all the functionality to provide translations
private void createTranslateButton(LinearLayout layoutTool, LayoutParams ps) {
    Button btnTranslate = new Button(mActivity);
    btnTranslate.setText(gtxt(R.string.multimedia_editor_text_field_editing_translate));
    btnTranslate.setOnClickListener(v -> {
        String source = mEditText.getText().toString();
        // Checks and warnings
        if (source.length() == 0) {
            showToast(gtxt(R.string.multimedia_editor_text_field_editing_no_text));
            return;
        }
        if (source.contains(" ")) {
            showToast(gtxt(R.string.multimedia_editor_text_field_editing_many_words));
        }
        // Pick from two translation sources
        PickStringDialogFragment fragment = new PickStringDialogFragment();
        final ArrayList<String> translationSources = new ArrayList<>();
        translationSources.add("Glosbe.com");
        // Chromebooks do not support dependent apps yet.
        if (!CompatHelper.isChromebook()) {
            translationSources.add("ColorDict");
        }
        fragment.setChoices(translationSources);
        fragment.setOnclickListener((dialog, which) -> {
            String translationSource = translationSources.get(which);
            if ("Glosbe.com".equals(translationSource)) {
                startTranslationWithGlosbe();
            } else if ("ColorDict".equals(translationSource)) {
                startTranslationWithColorDict();
            }
        });
        fragment.setTitle(gtxt(R.string.multimedia_editor_trans_pick_translation_source));
        fragment.show(mActivity.getSupportFragmentManager(), "pick.translation.source");
    });
    layoutTool.addView(btnTranslate, ps);
// flow continues in Start Translation with...
}
Also used : Button(android.widget.Button) PickStringDialogFragment(com.ichi2.anki.multimediacard.activity.PickStringDialogFragment) ArrayList(java.util.ArrayList)

Example 35 with START

use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project AnkiChinaAndroid by ankichinateam.

the class CardTemplateEditorTest method testDeleteTemplateWithGeneratedCards.

/**
 * Normal template deletion - with no selective generation should of course work
 */
@SuppressWarnings("PMD.ExcessiveMethodLength")
@Test
public void testDeleteTemplateWithGeneratedCards() {
    String modelName = "Basic (and reversed card)";
    Model collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName);
    // Start the CardTemplateEditor with a specific model, and make sure the model starts unchanged
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.putExtra("modelId", collectionBasicModelOriginal.getLong("id"));
    ActivityController<CardTemplateEditor> templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class, intent).create().start().resume().visible();
    saveControllerForCleanup(templateEditorController);
    CardTemplateEditor testEditor = (CardTemplateEditor) templateEditorController.get();
    Assert.assertFalse("Model should not have changed yet", testEditor.modelHasChanged());
    Assert.assertEquals("Model should have 2 templates now", 2, testEditor.getTempModel().getTemplateCount());
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 0));
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 1));
    // Create note with forward and back info
    Note selectiveGeneratedNote = getCol().newNote(collectionBasicModelOriginal);
    selectiveGeneratedNote.setField(0, "TestFront");
    selectiveGeneratedNote.setField(1, "TestBack");
    getCol().addNote(selectiveGeneratedNote);
    Assert.assertEquals("card generation should result in two cards", 2, getModelCardCount(collectionBasicModelOriginal));
    // Test if we can delete the template - should be possible - but cancel the delete
    ShadowActivity shadowTestEditor = shadowOf(testEditor);
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_delete));
    advanceRobolectricLooper();
    Assert.assertEquals("Did not show dialog about deleting template and it's card?", getQuantityString(R.plurals.card_template_editor_confirm_delete, 1, 1, "Card 1"), getDialogText(true));
    clickDialogButton(DialogAction.NEGATIVE, true);
    advanceRobolectricLooper();
    Assert.assertNotNull("Cannot delete template?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 0 }));
    Assert.assertNotNull("Cannot delete template?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 1 }));
    Assert.assertNull("Can delete both templates?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 0, 1 }));
    Assert.assertEquals("Change in database despite no change?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
    Assert.assertEquals("Model should have 2 templates still", 2, testEditor.getTempModel().getTemplateCount());
    // Add a template - click add, click confirm for card add, click confirm again for full sync
    shadowTestEditor.clickMenuItem(R.id.action_add);
    advanceRobolectricLooper();
    Assert.assertTrue("Model should have changed", testEditor.modelHasChanged());
    Assert.assertEquals("Change added but not adjusted correctly?", 2, TemporaryModel.getAdjustedAddOrdinalAtChangeIndex(testEditor.getTempModel(), 0));
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 0));
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 1));
    Assert.assertTrue("Ordinal not pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 2));
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_confirm));
    advanceRobolectricLooper();
    Assert.assertFalse("Model should now be unchanged", testEditor.modelHasChanged());
    Assert.assertEquals("card generation should result in three cards", 3, getModelCardCount(collectionBasicModelOriginal));
    // reload the model for future comparison after saving the edit
    collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName);
    // Start the CardTemplateEditor back up after saving (which closes the thing...)
    intent = new Intent(Intent.ACTION_VIEW);
    intent.putExtra("modelId", collectionBasicModelOriginal.getLong("id"));
    templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class, intent).create().start().resume().visible();
    testEditor = (CardTemplateEditor) templateEditorController.get();
    shadowTestEditor = shadowOf(testEditor);
    Assert.assertFalse("Model should not have changed yet", testEditor.modelHasChanged());
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 0));
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 1));
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 2));
    Assert.assertEquals("Model should have 3 templates now", 3, testEditor.getTempModel().getTemplateCount());
    // Add another template - but we work in memory for a while before saving
    shadowTestEditor.clickMenuItem(R.id.action_add);
    advanceRobolectricLooper();
    Assert.assertEquals("Change added but not adjusted correctly?", 3, TemporaryModel.getAdjustedAddOrdinalAtChangeIndex(testEditor.getTempModel(), 0));
    Assert.assertTrue("Model should have changed", testEditor.modelHasChanged());
    Assert.assertEquals("Model should have 4 templates now", 4, testEditor.getTempModel().getTemplateCount());
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 0));
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 1));
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 2));
    Assert.assertTrue("Ordinal not pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 3));
    Assert.assertEquals("Change added but not adjusted correctly?", 3, TemporaryModel.getAdjustedAddOrdinalAtChangeIndex(testEditor.getTempModel(), 0));
    // Delete two pre-existing templates for real now - but still without saving it out, should work fine
    advanceRobolectricLooper();
    testEditor.mViewPager.setCurrentItem(0);
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_delete));
    advanceRobolectricLooper();
    Assert.assertEquals("Did not show dialog about deleting template and it's card?", getQuantityString(R.plurals.card_template_editor_confirm_delete, 1, 1, "Card 1"), getDialogText(true));
    clickDialogButton(DialogAction.POSITIVE, true);
    advanceRobolectricLooper();
    advanceRobolectricLooper();
    testEditor.mViewPager.setCurrentItem(0);
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_delete));
    advanceRobolectricLooper();
    Assert.assertEquals("Did not show dialog about deleting template and it's card?", getQuantityString(R.plurals.card_template_editor_confirm_delete, 1, 1, "Card 2"), getDialogText(true));
    clickDialogButton(DialogAction.POSITIVE, true);
    advanceRobolectricLooper();
    // - assert can delete any 1 or 2 Card templates but not all
    Assert.assertNotNull("Cannot delete template?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 0 }));
    Assert.assertNotNull("Cannot delete template?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 1 }));
    Assert.assertNotNull("Cannot delete template?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 2 }));
    Assert.assertNotNull("Cannot delete two templates?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 0, 1 }));
    Assert.assertNotNull("Cannot delete two templates?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 0, 2 }));
    Assert.assertNotNull("Cannot delete two templates?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 1, 2 }));
    Assert.assertNull("Can delete all templates?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 0, 1, 2 }));
    Assert.assertEquals("Change already in database?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
    Assert.assertEquals("Change added but not adjusted correctly?", 1, TemporaryModel.getAdjustedAddOrdinalAtChangeIndex(testEditor.getTempModel(), 0));
    Assert.assertEquals("Change incorrectly pending add?", -1, TemporaryModel.getAdjustedAddOrdinalAtChangeIndex(testEditor.getTempModel(), 1));
    Assert.assertEquals("Change incorrectly pending add?", -1, TemporaryModel.getAdjustedAddOrdinalAtChangeIndex(testEditor.getTempModel(), 2));
    // Now confirm everything to persist it to the database
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_confirm));
    advanceRobolectricLooper();
    advanceRobolectricLooper();
    Assert.assertNotEquals("Change not in database?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
    Assert.assertEquals("Model should have 2 templates now", 2, getCurrentDatabaseModelCopy(modelName).getJSONArray("tmpls").length());
    Assert.assertEquals("should be two cards", 2, getModelCardCount(collectionBasicModelOriginal));
}
Also used : Note(com.ichi2.libanki.Note) Model(com.ichi2.libanki.Model) ShadowActivity(org.robolectric.shadows.ShadowActivity) ShadowIntent(org.robolectric.shadows.ShadowIntent) Intent(android.content.Intent) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)23 Intent (android.content.Intent)21 JSONObject (com.ichi2.utils.JSONObject)17 Model (com.ichi2.libanki.Model)14 View (android.view.View)13 ArrayList (java.util.ArrayList)13 Bundle (android.os.Bundle)12 Collection (com.ichi2.libanki.Collection)11 Note (com.ichi2.libanki.Note)9 File (java.io.File)9 JSONArray (com.ichi2.utils.JSONArray)8 SharedPreferences (android.content.SharedPreferences)7 TextView (android.widget.TextView)7 EditText (android.widget.EditText)6 Deck (com.ichi2.libanki.Deck)6 Dialog (android.app.Dialog)5 NonNull (androidx.annotation.NonNull)5 MaterialDialog (com.afollestad.materialdialogs.MaterialDialog)5 RobolectricTest (com.ichi2.anki.RobolectricTest)5 TaskData (com.ichi2.async.TaskData)5