Search in sources :

Example 6 with QUESTION

use of com.ichi2.anki.CardBrowser.Column.QUESTION in project Anki-Android by ankidroid.

the class Model method parsedNodes.

/**
 * @return A list of parsed nodes for each template's question. null in case of exception
 */
public List<ParsedNode> parsedNodes() {
    JSONArray tmpls = getJSONArray("tmpls");
    List<ParsedNode> nodes = new ArrayList<>(tmpls.length());
    for (JSONObject tmpl : tmpls.jsonObjectIterable()) {
        String format_question = tmpl.getString("qfmt");
        ParsedNode node = null;
        try {
            node = ParsedNode.parse_inner(format_question);
        } catch (TemplateError er) {
            Timber.w(er);
        }
        nodes.add(node);
    }
    return nodes;
}
Also used : ParsedNode(com.ichi2.libanki.template.ParsedNode) JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) ArrayList(java.util.ArrayList) TemplateError(com.ichi2.libanki.template.TemplateError)

Example 7 with QUESTION

use of com.ichi2.anki.CardBrowser.Column.QUESTION in project Anki-Android by ankidroid.

the class CollectionTest method test_furigana.

@Test
@Ignore("Pending port of media search from Rust code")
public void test_furigana() {
    Collection col = getCol();
    ModelManager mm = col.getModels();
    Model m = mm.current();
    // filter should work
    m.getJSONArray("tmpls").getJSONObject(0).put("qfmt", "{{kana:Front}}");
    mm.save(m);
    Note n = col.newNote();
    n.setItem("Front", "foo[abc]");
    col.addNote(n);
    Card c = n.cards().get(0);
    assertTrue(c.q().endsWith("abc"));
    // and should avoid sound
    n.setItem("Front", "foo[sound:abc.mp3]");
    n.flush();
    String question = c.q(true);
    assertThat("Question «" + question + "» does not contains «anki:play».", question, containsString("anki:play"));
    // it shouldn't throw an error while people are editing
    m.getJSONArray("tmpls").getJSONObject(0).put("qfmt", "{{kana:}}");
    mm.save(m);
    c.q(true);
}
Also used : Matchers.containsString(org.hamcrest.Matchers.containsString) Ignore(org.junit.Ignore) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 8 with QUESTION

use of com.ichi2.anki.CardBrowser.Column.QUESTION in project Anki-Android by ankidroid.

the class ModelTest method test_chained_mods.

@Test
public void test_chained_mods() throws ConfirmModSchemaException {
    Collection col = getCol();
    col.getModels().setCurrent(col.getModels().byName("Cloze"));
    Model m = col.getModels().current();
    ModelManager mm = col.getModels();
    // We replace the default Cloze template
    JSONObject t = Models.newTemplate("ChainedCloze");
    t.put("qfmt", "{{cloze:text:Text}}");
    t.put("afmt", "{{cloze:text:Text}}");
    mm.addTemplateModChanged(m, t);
    mm.save(m);
    col.getModels().remTemplate(m, m.getJSONArray("tmpls").getJSONObject(0));
    Note note = col.newNote();
    String q1 = "<span style=\"color:red\">phrase</span>";
    String a1 = "<b>sentence</b>";
    String q2 = "<span style=\"color:red\">en chaine</span>";
    String a2 = "<i>chained</i>";
    note.setItem("Text", "This {{c1::" + q1 + "::" + a1 + "}} demonstrates {{c1::" + q2 + "::" + a2 + "}} clozes.");
    assertEquals(1, col.addNote(note));
    String question = note.cards().get(0).q();
/* TODO: chained modifier
        assertThat("Question «"+question+"» does not contain the expected string", question, containsString("This <span class=cloze>[sentence]</span> demonstrates <span class=cloze>[chained]</span> clozes.")
                   );
        assertThat(note.cards().get(0).a(), containsString("This <span class=cloze>phrase</span> demonstrates <span class=cloze>en chaine</span> clozes."
                                                    ));

         */
}
Also used : JSONObject(com.ichi2.utils.JSONObject) Matchers.containsString(org.hamcrest.Matchers.containsString) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 9 with QUESTION

use of com.ichi2.anki.CardBrowser.Column.QUESTION in project Anki-Android by Ramblurr.

the class Reviewer method displayCardAnswer.

private void displayCardAnswer() {
    // prevent answering (by e.g. gestures) before card is loaded
    if (mCurrentCard == null) {
        return;
    }
    sDisplayAnswer = true;
    setFlipCardAnimation();
    String answer = mCurrentCard.getAnswer(mCurrentSimpleInterface);
    answer = typeAnsAnswerFilter(answer);
    String displayString = "";
    if (mCurrentSimpleInterface) {
        mCardContent = convertToSimple(answer);
        if (mCardContent.length() == 0) {
            SpannableString hint = new SpannableString(getResources().getString(R.string.simple_interface_hint, R.string.card_details_answer));
            hint.setSpan(new StyleSpan(Typeface.ITALIC), 0, mCardContent.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            mCardContent = hint;
        }
    } else {
        Sound.stopSounds();
        if (mPrefFixArabic) {
            // reshape
            answer = ArabicUtilities.reshapeSentence(answer, true);
        }
        // If the user wrote an answer
        if (typeAnswer()) {
            mAnswerField.setVisibility(View.GONE);
            if (mCurrentCard != null) {
                if (mPrefFixArabic) {
                    // reshape
                    mTypeCorrect = ArabicUtilities.reshapeSentence(mTypeCorrect, true);
                }
                // Obtain the user answer and the correct answer
                String userAnswer = mAnswerField.getText().toString();
                Matcher matcher = sSpanPattern.matcher(Utils.stripHTMLMedia(mTypeCorrect));
                String correctAnswer = matcher.replaceAll("");
                matcher = sBrPattern.matcher(correctAnswer);
                correctAnswer = matcher.replaceAll("\n");
                matcher = Sound.sSoundPattern.matcher(correctAnswer);
                correctAnswer = matcher.replaceAll("");
                // Log.i(AnkiDroidApp.TAG, "correct answer = " + correctAnswer);
                // Obtain the diff and send it to updateCard
                DiffEngine diff = new DiffEngine();
                StringBuffer span = new StringBuffer();
                span.append("<span style=\"font-family: '").append(mTypeFont).append("'; font-size: ").append(mTypeSize).append("px\">");
                span.append(diff.diff_prettyHtml(diff.diff_main(userAnswer, correctAnswer), mNightMode));
                span.append("</span>");
                span.append("<br/>").append(answer);
                displayString = enrichWithQADiv(span.toString(), true);
            }
            // Hide soft keyboard
            InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(mAnswerField.getWindowToken(), 0);
        } else {
            displayString = enrichWithQADiv(answer, true);
        }
    }
    mIsSelecting = false;
    updateCard(displayString);
    showEaseButtons();
    // If the user want to show next question automatically
    if (mPrefUseTimer) {
        mTimeoutHandler.removeCallbacks(mShowQuestionTask);
        mTimeoutHandler.postDelayed(mShowQuestionTask, mWaitQuestionSecond * 1000);
    }
}
Also used : SpannableString(android.text.SpannableString) DiffEngine(com.ichi2.utils.DiffEngine) Matcher(java.util.regex.Matcher) StyleSpan(android.text.style.StyleSpan) InputMethodManager(android.view.inputmethod.InputMethodManager) SpannedString(android.text.SpannedString) SpannableString(android.text.SpannableString)

Example 10 with QUESTION

use of com.ichi2.anki.CardBrowser.Column.QUESTION in project AnkiChinaAndroid by ankichinateam.

the class CardBrowser method onCollectionLoaded.

// Finish initializing the activity after the collection has been correctly loaded
@Override
protected void onCollectionLoaded(Collection col) {
    super.onCollectionLoaded(col);
    Timber.d("onCollectionLoaded()");
    registerExternalStorageListener();
    SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(getBaseContext());
    // Load reference to action bar title
    mActionBarTitle = (TextView) findViewById(R.id.toolbar_title);
    // Add drop-down menu to select deck to action bar.
    mDropDownDecks = getCol().getDecks().allSorted();
    mDropDownAdapter = new DeckDropDownAdapter(this, mDropDownDecks, R.layout.dropdown_deck_selected_item, this);
    Toolbar toolbar = findViewById(R.id.toolbar);
    if (toolbar != null) {
        setSupportActionBar(toolbar);
        // enable ActionBar app icon to behave as action to toggle nav drawer
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        // Decide which action to take when the navigation button is tapped.
        toolbar.setNavigationOnClickListener(v -> finishActivityWithFade(this, ActivityTransitionAnimation.RIGHT));
    }
    ActionBar mActionBar = getSupportActionBar();
    if (mActionBar != null) {
        mActionBar.setDisplayShowTitleEnabled(false);
    }
    mActionBarSpinner = (Spinner) findViewById(R.id.toolbar_spinner);
    mActionBarSpinner.setAdapter(mDropDownAdapter);
    mActionBarSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            deckDropDownItemChanged(position);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        // do nothing
        }
    });
    mActionBarSpinner.setVisibility(View.VISIBLE);
    mOrder = CARD_ORDER_NONE;
    String colOrder = getCol().getConf().getString("sortType");
    for (int c = 0; c < fSortTypes.length; ++c) {
        if (fSortTypes[c].equals(colOrder)) {
            mOrder = c;
            break;
        }
    }
    if (mOrder == 1 && preferences.getBoolean("cardBrowserNoSorting", false)) {
        mOrder = 0;
    }
    // This upgrade should already have been done during
    // setConf. However older version of AnkiDroid didn't call
    // upgradeJSONIfNecessary during setConf, which means the
    // conf saved may still have this bug.
    mOrderAsc = Upgrade.upgradeJSONIfNecessary(getCol(), getCol().getConf(), "sortBackwards", false);
    mCards = new ArrayList<>();
    mCardsListView = (ListView) findViewById(R.id.card_browser_list);
    // Create a spinner for column1
    Spinner cardsColumn1Spinner = (Spinner) findViewById(R.id.browser_column1_spinner);
    ArrayAdapter<CharSequence> column1Adapter = ArrayAdapter.createFromResource(this, R.array.browser_column1_headings, android.R.layout.simple_spinner_item);
    column1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    cardsColumn1Spinner.setAdapter(column1Adapter);
    mColumn1Index = AnkiDroidApp.getSharedPrefs(getBaseContext()).getInt("cardBrowserColumn1", 0);
    cardsColumn1Spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
            // If a new column was selected then change the key used to map from mCards to the column TextView
            if (pos != mColumn1Index) {
                mColumn1Index = pos;
                AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext()).edit().putInt("cardBrowserColumn1", mColumn1Index).commit();
                Column[] fromMap = mCardsAdapter.getFromMapping();
                fromMap[0] = COLUMN1_KEYS[mColumn1Index];
                mCardsAdapter.setFromMapping(fromMap);
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        // Do Nothing
        }
    });
    // Load default value for column2 selection
    mColumn2Index = AnkiDroidApp.getSharedPrefs(getBaseContext()).getInt("cardBrowserColumn2", 0);
    // Setup the column 2 heading as a spinner so that users can easily change the column type
    Spinner cardsColumn2Spinner = (Spinner) findViewById(R.id.browser_column2_spinner);
    ArrayAdapter<CharSequence> column2Adapter = ArrayAdapter.createFromResource(this, R.array.browser_column2_headings, android.R.layout.simple_spinner_item);
    column2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    cardsColumn2Spinner.setAdapter(column2Adapter);
    // Create a new list adapter with updated column map any time the user changes the column
    cardsColumn2Spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
            // If a new column was selected then change the key used to map from mCards to the column TextView
            if (pos != mColumn2Index) {
                mColumn2Index = pos;
                AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext()).edit().putInt("cardBrowserColumn2", mColumn2Index).commit();
                Column[] fromMap = mCardsAdapter.getFromMapping();
                fromMap[1] = COLUMN2_KEYS[mColumn2Index];
                mCardsAdapter.setFromMapping(fromMap);
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        // Do Nothing
        }
    });
    // get the font and font size from the preferences
    int sflRelativeFontSize = preferences.getInt("relativeCardBrowserFontSize", DEFAULT_FONT_SIZE_RATIO);
    String sflCustomFont = preferences.getString("browserEditorFont", "");
    Column[] columnsContent = { COLUMN1_KEYS[mColumn1Index], COLUMN2_KEYS[mColumn2Index] };
    // make a new list adapter mapping the data in mCards to column1 and column2 of R.layout.card_item_browser
    mCardsAdapter = new MultiColumnListAdapter(this, R.layout.card_item_browser, columnsContent, new int[] { R.id.card_sfld, R.id.card_column2 }, sflRelativeFontSize, sflCustomFont);
    // link the adapter to the main mCardsListView
    mCardsListView.setAdapter(mCardsAdapter);
    // make the items (e.g. question & answer) render dynamically when scrolling
    mCardsListView.setOnScrollListener(new RenderOnScroll());
    // set the spinner index
    cardsColumn1Spinner.setSelection(mColumn1Index);
    cardsColumn2Spinner.setSelection(mColumn2Index);
    mCardsListView.setOnItemClickListener(new ListView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if (mInMultiSelectMode) {
                // click on whole cell triggers select
                CheckBox cb = (CheckBox) view.findViewById(R.id.card_checkbox);
                cb.toggle();
                onCheck(position, view);
            } else {
                // load up the card selected on the list
                long clickedCardId = getCards().get(position).getId();
                openNoteEditorForCard(clickedCardId);
            }
        }
    });
    mCardsListView.setOnItemLongClickListener(new ListView.OnItemLongClickListener() {

        @Override
        public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int position, long id) {
            mLastSelectedPosition = position;
            loadMultiSelectMode();
            // click on whole cell triggers select
            CheckBox cb = (CheckBox) view.findViewById(R.id.card_checkbox);
            cb.toggle();
            onCheck(position, view);
            recenterListView(view);
            mCardsAdapter.notifyDataSetChanged();
            return true;
        }
    });
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    // If a valid value for last deck exists then use it, otherwise use libanki selected deck
    if (getLastDeckId() != null && getLastDeckId() == ALL_DECKS_ID) {
        selectAllDecks();
    } else if (getLastDeckId() != null && getCol().getDecks().get(getLastDeckId(), false) != null) {
        selectDeckById(getLastDeckId());
    } else {
        selectDeckById(getCol().getDecks().selected());
    }
}
Also used : SharedPreferences(android.content.SharedPreferences) Spinner(android.widget.Spinner) View(android.view.View) AdapterView(android.widget.AdapterView) SearchView(androidx.appcompat.widget.SearchView) TextView(android.widget.TextView) ListView(android.widget.ListView) AbsListView(android.widget.AbsListView) DeckDropDownAdapter(com.ichi2.anki.widgets.DeckDropDownAdapter) ListView(android.widget.ListView) AbsListView(android.widget.AbsListView) Column(com.ichi2.anki.CardBrowser.Column) CheckBox(android.widget.CheckBox) OnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener) ActionBar(androidx.appcompat.app.ActionBar) Toolbar(androidx.appcompat.widget.Toolbar)

Aggregations

Test (org.junit.Test)7 RobolectricTest (com.ichi2.anki.RobolectricTest)6 Matchers.containsString (org.hamcrest.Matchers.containsString)6 JSONObject (com.ichi2.utils.JSONObject)4 SharedPreferences (android.content.SharedPreferences)3 View (android.view.View)3 TextView (android.widget.TextView)3 Matcher (java.util.regex.Matcher)3 Intent (android.content.Intent)2 AbsListView (android.widget.AbsListView)2 AdapterView (android.widget.AdapterView)2 OnItemSelectedListener (android.widget.AdapterView.OnItemSelectedListener)2 CheckBox (android.widget.CheckBox)2 LinearLayout (android.widget.LinearLayout)2 ListView (android.widget.ListView)2 Spinner (android.widget.Spinner)2 SearchView (androidx.appcompat.widget.SearchView)2 CardBrowser (com.ichi2.anki.CardBrowser)2 Column (com.ichi2.anki.CardBrowser.Column)2 ArrayList (java.util.ArrayList)2