Search in sources :

Example 26 with TAGS

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

the class Collection method _renderQA.

public HashMap<String, String> _renderQA(Object[] data, List<String> args) {
    // data is [cid, nid, mid, did, ord, tags, flds]
    // unpack fields and create dict
    String[] flist = Utils.splitFields((String) data[6]);
    Map<String, String> fields = new HashMap<String, String>();
    long modelId = (Long) data[2];
    JSONObject model = mModels.get(modelId);
    Map<String, Pair<Integer, JSONObject>> fmap = mModels.fieldMap(model);
    for (String fname : fmap.keySet()) {
        fields.put(fname, flist[fmap.get(fname).first]);
    }
    fields.put("Tags", ((String) data[5]).trim());
    try {
        fields.put("Type", (String) model.get("name"));
        fields.put("Deck", mDecks.name((Long) data[3]));
        JSONObject template;
        if (model.getInt("type") == Sched.MODEL_STD) {
            template = model.getJSONArray("tmpls").getJSONObject((Integer) data[4]);
        } else {
            template = model.getJSONArray("tmpls").getJSONObject(0);
        }
        fields.put("Card", template.getString("name"));
        fields.put("c" + (((Integer) data[4]) + 1), "1");
        // render q & a
        HashMap<String, String> d = new HashMap<String, String>();
        try {
            d.put("id", Long.toString((Long) data[0]));
            String qfmt = template.getString("qfmt");
            String afmt = template.getString("afmt");
            String html;
            String format;
            // runFilter mungeFields for type "q"
            Models.fieldParser fparser = new Models.fieldParser(fields);
            Matcher m = fClozePattern.matcher(qfmt);
            format = m.replaceFirst(String.format(Locale.US, "{{cq:%d:", ((Integer) data[4]) + 1));
            m = fAltClozePattern.matcher(format);
            format = m.replaceFirst(String.format(Locale.US, "<%%cq:%d:", ((Integer) data[4]) + 1));
            html = mModels.getCmpldTemplate(format).execute(fparser);
            html = (String) AnkiDroidApp.getHooks().runFilter("mungeQA", html, "q", fields, model, data, this);
            d.put("q", html);
            // empty cloze?
            if (model.getInt("type") == Sched.MODEL_CLOZE) {
                if (getModels()._availClozeOrds(model, (String) data[6], false).size() == 0) {
                    d.put("q", "Please edit this note and add some cloze deletions.");
                }
            }
            fields.put("FrontSide", mMedia.stripAudio(d.get("q")));
            // runFilter mungeFields for type "a"
            fparser = new Models.fieldParser(fields);
            m = fClozePattern.matcher(afmt);
            format = m.replaceFirst(String.format(Locale.US, "{{ca:%d:", ((Integer) data[4]) + 1));
            m = fAltClozePattern.matcher(format);
            format = m.replaceFirst(String.format(Locale.US, "<%%ca:%d:", ((Integer) data[4]) + 1));
            html = mModels.getCmpldTemplate(format).execute(fparser);
            html = (String) AnkiDroidApp.getHooks().runFilter("mungeQA", html, "a", fields, model, data, this);
            d.put("a", html);
            // empty cloze?
            if (model.getInt("type") == Sched.MODEL_CLOZE) {
                if (getModels()._availClozeOrds(model, (String) data[6], false).size() == 0) {
                    d.put("q", AnkiDroidApp.getAppResources().getString(com.ichi2.anki.R.string.empty_cloze_warning, "<a href=" + HELP_SITE + "#cloze>" + AnkiDroidApp.getAppResources().getString(com.ichi2.anki.R.string.help_cloze) + "</a>"));
                }
            }
        } catch (MustacheException e) {
            Resources res = AnkiDroidApp.getAppResources();
            String templateError = String.format(TEMPLATE_ERROR, res.getString(R.string.template_error), res.getString(R.string.template_error_detail), e.getMessage(), res.getString(R.string.note_type), model.getString("name"), res.getString(R.string.card_type), template.getString("name"), res.getString(R.string.template_error_fix));
            d.put("q", templateError);
            d.put("a", templateError);
        }
        return d;
    } catch (JSONException e) {
        throw new RuntimeException(e);
    }
}
Also used : HashMap(java.util.HashMap) Matcher(java.util.regex.Matcher) MustacheException(com.samskivert.mustache.MustacheException) JSONException(org.json.JSONException) JSONObject(org.json.JSONObject) Resources(android.content.res.Resources) Pair(com.ichi2.anki.Pair)

Example 27 with TAGS

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

the class Models method _availClozeOrds.

public ArrayList<Integer> _availClozeOrds(JSONObject m, String flds, boolean allowEmpty) {
    String[] sflds = Utils.splitFields(flds);
    Map<String, Pair<Integer, JSONObject>> map = fieldMap(m);
    Set<Integer> ords = new HashSet<Integer>();
    Matcher matcher1 = null;
    try {
        matcher1 = fClozePattern1.matcher(m.getJSONArray("tmpls").getJSONObject(0).getString("qfmt"));
    // Libanki makes two finds for each case of the cloze tags, but we embed both in the pattern.
    // Please note, that this approach is not 100% correct, as we allow cases like {{cloze:...%>
    } catch (JSONException e) {
        throw new RuntimeException(e);
    }
    while (matcher1.find()) {
        String fname = matcher1.group(1);
        if (!map.containsKey(fname)) {
            continue;
        }
        int ord = map.get(fname).first;
        Matcher matcher2 = fClozePattern2.matcher(sflds[ord]);
        while (matcher2.find()) {
            ords.add(Integer.parseInt(matcher2.group(1)) - 1);
        }
    }
    if (ords.contains(-1)) {
        ords.remove(-1);
    }
    if (ords.isEmpty() && allowEmpty) {
        // empty clozes use first ord
        return new ArrayList<Integer>(Arrays.asList(new Integer[] { 0 }));
    }
    return new ArrayList<Integer>(ords);
}
Also used : Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) JSONException(org.json.JSONException) Pair(com.ichi2.anki.Pair) HashSet(java.util.HashSet)

Example 28 with TAGS

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

the class CardBrowser method onCreateDialog.

@Override
protected Dialog onCreateDialog(int id) {
    StyledDialog dialog = null;
    Resources res = getResources();
    StyledDialog.Builder builder = new StyledDialog.Builder(this);
    switch(id) {
        case DIALOG_ORDER:
            builder.setTitle(res.getString(R.string.card_browser_change_display_order_title));
            builder.setMessage(res.getString(R.string.card_browser_change_display_order_reverse));
            builder.setIcon(android.R.drawable.ic_menu_sort_by_size);
            builder.setSingleChoiceItems(res.getStringArray(R.array.card_browser_order_labels), mOrder, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface arg0, int which) {
                    if (which != mOrder) {
                        mOrder = which;
                        mOrderAsc = false;
                        try {
                            if (mOrder == 0) {
                                mCol.getConf().put("sortType", fSortTypes[1]);
                                AnkiDroidApp.getSharedPrefs(getBaseContext()).edit().putBoolean("cardBrowserNoSorting", true).commit();
                            } else {
                                mCol.getConf().put("sortType", fSortTypes[mOrder]);
                                AnkiDroidApp.getSharedPrefs(getBaseContext()).edit().putBoolean("cardBrowserNoSorting", false).commit();
                            }
                            // default to descending for non-text fields
                            if (fSortTypes[mOrder].equals("noteFld")) {
                                mOrderAsc = true;
                            }
                            mCol.getConf().put("sortBackwards", mOrderAsc);
                        } catch (JSONException e) {
                            throw new RuntimeException(e);
                        }
                        searchCards();
                    } else if (which != CARD_ORDER_NONE) {
                        mOrderAsc = !mOrderAsc;
                        try {
                            mCol.getConf().put("sortBackwards", mOrderAsc);
                        } catch (JSONException e) {
                            throw new RuntimeException(e);
                        }
                        Collections.reverse(mCards);
                        updateList();
                    }
                }
            });
            dialog = builder.create();
            break;
        case DIALOG_CONTEXT_MENU:
            // FIXME:
            String[] entries = new String[4];
            @SuppressWarnings("unused") MenuItem item;
            entries[CONTEXT_MENU_MARK] = res.getString(R.string.card_browser_mark_card);
            entries[CONTEXT_MENU_SUSPEND] = res.getString(R.string.card_browser_suspend_card);
            entries[CONTEXT_MENU_DELETE] = res.getString(R.string.card_browser_delete_card);
            entries[CONTEXT_MENU_DETAILS] = res.getString(R.string.card_browser_card_details);
            builder.setTitle("contextmenu");
            builder.setIcon(R.drawable.ic_menu_manage);
            builder.setItems(entries, mContextMenuListener);
            dialog = builder.create();
            break;
        case DIALOG_TAGS:
            allTags = mCol.getTags().all();
            builder.setTitle(R.string.studyoptions_limit_select_tags);
            builder.setMultiChoiceItems(allTags, new boolean[allTags.length], new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    String tag = allTags[which];
                    if (mSelectedTags.contains(tag)) {
                        // Log.i(AnkiDroidApp.TAG, "unchecked tag: " + tag);
                        mSelectedTags.remove(tag);
                    } else {
                        // Log.i(AnkiDroidApp.TAG, "checked tag: " + tag);
                        mSelectedTags.add(tag);
                    }
                }
            });
            builder.setPositiveButton(res.getString(R.string.select), new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    mSearchEditText.setText("");
                    String tags = mSelectedTags.toString();
                    mSearchEditText.setHint(getResources().getString(R.string.card_browser_tags_shown, tags.substring(1, tags.length() - 1)));
                    StringBuilder sb = new StringBuilder();
                    for (String tag : mSelectedTags) {
                        sb.append("tag:").append(tag).append(" ");
                    }
                    mSearchTerms = sb.toString();
                    searchCards();
                }
            });
            builder.setNegativeButton(res.getString(R.string.cancel), new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    mSelectedTags.clear();
                }
            });
            builder.setOnCancelListener(new OnCancelListener() {

                @Override
                public void onCancel(DialogInterface dialog) {
                    mSelectedTags.clear();
                }
            });
            dialog = builder.create();
            break;
    }
    return dialog;
}
Also used : DialogInterface(android.content.DialogInterface) StyledDialog(com.ichi2.themes.StyledDialog) JSONException(org.json.JSONException) MenuItem(android.view.MenuItem) OnClickListener(android.content.DialogInterface.OnClickListener) OnClickListener(android.content.DialogInterface.OnClickListener) Resources(android.content.res.Resources) OnCancelListener(android.content.DialogInterface.OnCancelListener)

Example 29 with TAGS

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

the class StudyOptionsFragment method onPrepareDialog.

private void onPrepareDialog(int id, StyledDialog styledDialog) {
    Resources res = getResources();
    switch(id) {
        case DIALOG_CUSTOM_STUDY_DETAILS:
            styledDialog.setTitle(res.getStringArray(R.array.custom_study_options_labels)[mCustomDialogChoice]);
            switch(mCustomDialogChoice + 1) {
                case CUSTOM_STUDY_NEW:
                    if (AnkiDroidApp.colIsOpen()) {
                        Collection col = AnkiDroidApp.getCol();
                        mCustomStudyTextView1.setText(res.getString(R.string.custom_study_new_total_new, col.getSched().totalNewForCurrentDeck()));
                    }
                    mCustomStudyTextView2.setText(res.getString(R.string.custom_study_new_extend));
                    mCustomStudyEditText.setText(Integer.toString(AnkiDroidApp.getSharedPrefs(getActivity()).getInt("extendNew", 10)));
                    styledDialog.setButtonOnClickListener(Dialog.BUTTON_POSITIVE, new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (AnkiDroidApp.colIsOpen()) {
                                try {
                                    int n = Integer.parseInt(mCustomStudyEditText.getText().toString());
                                    AnkiDroidApp.getSharedPrefs(getActivity()).edit().putInt("extendNew", n).commit();
                                    Collection col = AnkiDroidApp.getCol();
                                    JSONObject deck = col.getDecks().current();
                                    deck.put("extendNew", n);
                                    col.getDecks().save(deck);
                                    col.getSched().extendLimits(n, 0);
                                    resetAndUpdateValuesFromDeck();
                                    finishCongrats();
                                } catch (NumberFormatException e) {
                                    // ignore non numerical values
                                    Themes.showThemedToast(getActivity().getBaseContext(), getResources().getString(R.string.custom_study_invalid_number), false);
                                } catch (JSONException e) {
                                    throw new RuntimeException(e);
                                }
                            }
                        }
                    });
                    break;
                case CUSTOM_STUDY_REV:
                    if (AnkiDroidApp.colIsOpen()) {
                        Collection col = AnkiDroidApp.getCol();
                        mCustomStudyTextView1.setText(res.getString(R.string.custom_study_rev_total_rev, col.getSched().totalRevForCurrentDeck()));
                    }
                    mCustomStudyTextView2.setText(res.getString(R.string.custom_study_rev_extend));
                    mCustomStudyEditText.setText(Integer.toString(AnkiDroidApp.getSharedPrefs(getActivity()).getInt("extendRev", 10)));
                    styledDialog.setButtonOnClickListener(Dialog.BUTTON_POSITIVE, new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (AnkiDroidApp.colIsOpen()) {
                                try {
                                    int n = Integer.parseInt(mCustomStudyEditText.getText().toString());
                                    AnkiDroidApp.getSharedPrefs(getActivity()).edit().putInt("extendRev", n).commit();
                                    Collection col = AnkiDroidApp.getCol();
                                    JSONObject deck = col.getDecks().current();
                                    deck.put("extendRev", n);
                                    col.getDecks().save(deck);
                                    col.getSched().extendLimits(0, n);
                                    resetAndUpdateValuesFromDeck();
                                    finishCongrats();
                                } catch (NumberFormatException e) {
                                    // ignore non numerical values
                                    Themes.showThemedToast(getActivity().getBaseContext(), getResources().getString(R.string.custom_study_invalid_number), false);
                                } catch (JSONException e) {
                                    throw new RuntimeException(e);
                                }
                            }
                        }
                    });
                    break;
                case CUSTOM_STUDY_FORGOT:
                    mCustomStudyTextView1.setText("");
                    mCustomStudyTextView2.setText(res.getString(R.string.custom_study_forgotten));
                    mCustomStudyEditText.setText(Integer.toString(AnkiDroidApp.getSharedPrefs(getActivity()).getInt("forgottenDays", 2)));
                    styledDialog.setButtonOnClickListener(Dialog.BUTTON_POSITIVE, new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            JSONArray ar = new JSONArray();
                            try {
                                int forgottenDays = Integer.parseInt(((EditText) mCustomStudyEditText).getText().toString());
                                ar.put(0, 1);
                                createFilteredDeck(ar, new Object[] { String.format(Locale.US, "rated:%d:1", forgottenDays), 9999, Sched.DYN_RANDOM }, false);
                            } catch (NumberFormatException e) {
                                // ignore non numerical values
                                Themes.showThemedToast(getActivity().getBaseContext(), getResources().getString(R.string.custom_study_invalid_number), false);
                            } catch (JSONException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    });
                    break;
                case CUSTOM_STUDY_AHEAD:
                    mCustomStudyTextView1.setText("");
                    mCustomStudyTextView2.setText(res.getString(R.string.custom_study_ahead));
                    mCustomStudyEditText.setText(Integer.toString(AnkiDroidApp.getSharedPrefs(getActivity()).getInt("aheadDays", 1)));
                    styledDialog.setButtonOnClickListener(Dialog.BUTTON_POSITIVE, new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            try {
                                int days = Integer.parseInt(((EditText) mCustomStudyEditText).getText().toString());
                                createFilteredDeck(new JSONArray(), new Object[] { String.format(Locale.US, "prop:due<=%d", days), 9999, Sched.DYN_DUE }, true);
                            } catch (NumberFormatException e) {
                                // ignore non numerical values
                                Themes.showThemedToast(getActivity().getBaseContext(), getResources().getString(R.string.custom_study_invalid_number), false);
                            }
                        }
                    });
                    break;
                case CUSTOM_STUDY_RANDOM:
                    mCustomStudyTextView1.setText("");
                    mCustomStudyTextView2.setText(res.getString(R.string.custom_study_random));
                    mCustomStudyEditText.setText(Integer.toString(AnkiDroidApp.getSharedPrefs(getActivity()).getInt("randomCards", 100)));
                    styledDialog.setButtonOnClickListener(Dialog.BUTTON_POSITIVE, new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            try {
                                int randomCards = Integer.parseInt(((EditText) mCustomStudyEditText).getText().toString());
                                createFilteredDeck(new JSONArray(), new Object[] { "", randomCards, Sched.DYN_RANDOM }, true);
                            } catch (NumberFormatException e) {
                                // ignore non numerical values
                                Themes.showThemedToast(getActivity().getBaseContext(), getResources().getString(R.string.custom_study_invalid_number), false);
                            }
                        }
                    });
                    break;
                case CUSTOM_STUDY_PREVIEW:
                    mCustomStudyTextView1.setText("");
                    mCustomStudyTextView2.setText(res.getString(R.string.custom_study_preview));
                    mCustomStudyEditText.setText(Integer.toString(AnkiDroidApp.getSharedPrefs(getActivity()).getInt("previewDays", 1)));
                    styledDialog.setButtonOnClickListener(Dialog.BUTTON_POSITIVE, new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            String previewDays = ((EditText) mCustomStudyEditText).getText().toString();
                            createFilteredDeck(new JSONArray(), new Object[] { "is:new added:" + previewDays, 9999, Sched.DYN_OLDEST }, false);
                        }
                    });
                    break;
                case CUSTOM_STUDY_TAGS:
                    mCustomStudyTextView1.setText("");
                    mCustomStudyTextView2.setText(res.getString(R.string.custom_study_tags));
                    mCustomStudyEditText.setText(AnkiDroidApp.getSharedPrefs(getActivity()).getString("customTags", ""));
                    styledDialog.setButtonOnClickListener(Dialog.BUTTON_POSITIVE, new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            String tags = ((EditText) mCustomStudyEditText).getText().toString();
                            createFilteredDeck(new JSONArray(), new Object[] { "(is:new or is:due) " + tags, 9999, Sched.DYN_RANDOM }, true);
                        }
                    });
                    break;
            }
    }
}
Also used : EditText(android.widget.EditText) DialogInterface(android.content.DialogInterface) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) OnClickListener(android.content.DialogInterface.OnClickListener) JSONObject(org.json.JSONObject) Collection(com.ichi2.libanki.Collection) JSONObject(org.json.JSONObject) Resources(android.content.res.Resources)

Example 30 with TAGS

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

the class MultimediaCardEditorActivity method initData.

/**
 * If a note has been passed, loads it. Otherwise creates a new Note It checks for a noteId, a long value with
 * EXTRA_NOTE_ID as key. If not 0, edits the note, else creates a new note
 */
private void initData() {
    try {
        mCol = AnkiDroidApp.getCol();
        Intent callerIntent = getIntent();
        long cardId = callerIntent.getLongExtra(EXTRA_CARD_ID, 0);
        if (cardId != 0) {
            mCard = mCol.getCard(cardId);
            mCurrentDid = mCard.getDid();
            mEditorNote = mCard.note();
            mCol.getModels().setCurrent(mEditorNote.model());
            mNote = NoteService.createEmptyNote(mEditorNote.model());
            NoteService.updateMultimediaNoteFromJsonNote(mEditorNote, mNote);
            mAddNote = false;
        } else {
            mCurrentDid = mCol.getDecks().current().getLong("id");
            if (mCol.getDecks().isDyn(mCurrentDid)) {
                mCurrentDid = 1;
            }
            mAddNote = true;
            JSONObject currentModel = mCol.getModels().current();
            mNote = NoteService.createEmptyNote(currentModel);
            if (mNote == null) {
                Log.e("Multimedia Editor", "Cannot create a Note");
                throw new Exception("Could not create a not");
            }
            mEditorNote = new Note(mCol, currentModel);
            mEditorNote.model().put("did", mCurrentDid);
        }
    // TODO take care of tags @see CardEditor setNote(Note)
    } catch (Exception e) {
        Log.e("Multimedia Editor", e.getMessage());
        finishCancel();
        return;
    }
}
Also used : JSONObject(org.json.JSONObject) Note(com.ichi2.libanki.Note) IMultimediaEditableNote(com.ichi2.anki.multimediacard.IMultimediaEditableNote) MultimediaEditableNote(com.ichi2.anki.multimediacard.impl.MultimediaEditableNote) Intent(android.content.Intent) JSONException(org.json.JSONException)

Aggregations

JSONObject (com.ichi2.utils.JSONObject)27 Note (com.ichi2.libanki.Note)18 JSONArray (com.ichi2.utils.JSONArray)18 ArrayList (java.util.ArrayList)13 Card (com.ichi2.libanki.Card)12 Collection (com.ichi2.libanki.Collection)12 Model (com.ichi2.libanki.Model)11 Map (java.util.Map)10 HashMap (java.util.HashMap)9 SuppressLint (android.annotation.SuppressLint)8 Resources (android.content.res.Resources)8 Deck (com.ichi2.libanki.Deck)8 JSONException (com.ichi2.utils.JSONException)8 JSONException (org.json.JSONException)8 Intent (android.content.Intent)7 View (android.view.View)7 TextView (android.widget.TextView)7 Pair (android.util.Pair)5 ContentValues (android.content.ContentValues)4 Uri (android.net.Uri)4