Search in sources :

Example 21 with Deck

use of com.ichi2.libanki.Deck in project AnkiChinaAndroid by ankichinateam.

the class Statistics method loadData.

public void loadData(Collection col) {
    Timber.d("onCollectionLoaded():%s", getAnkiActivity());
    if (getAnkiActivity() == null || col == null) {
        return;
    }
    mDropDownDecks = col.getDecks().allSorted();
    mActionBarSpinner.setAdapter(new DeckDropDownAdapter(getContext(), mDropDownDecks, R.layout.dropdown_deck_selected_item_static, this));
    // Setup Task Handler
    mTaskHandler = new AnkiStatsTaskHandler(col);
    // Dirty way to get text size from a TextView with current style, change if possible
    float size = new TextView(getContext()).getTextSize();
    mTaskHandler.setmStandardTextSize(size);
    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    // Set up the ViewPager with the sections adapter.
    mViewPager.setAdapter(new StatsPagerAdapter(getChildFragmentManager()));
    mSlidingTabLayout = mRoot.findViewById(R.id.sliding_tabs);
    // Fixes #8984: scroll to position 0 in RTL layouts
    ViewTreeObserver tabObserver = mSlidingTabLayout.getViewTreeObserver();
    tabObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        // Note: we can't use a lambda as we use 'this' to refer to the class.
        @Override
        public void onGlobalLayout() {
            // we need this here: If we select tab 0 before in an RTL context the layout has been drawn,
            // then it doesn't perform a scroll animation and selects the wrong element
            mSlidingTabLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            mSlidingTabLayout.selectTab(mSlidingTabLayout.getTabAt(0));
        }
    });
    // Prepare options menu only after loading everything
    getAnkiActivity().supportInvalidateOptionsMenu();
    // initMenu(mToolbar.getMenu());
    mViewPager.getAdapter().notifyDataSetChanged();
    // Default to libanki's selected deck
    selectDeckById(col.getDecks().selected());
}
Also used : TextView(android.widget.TextView) AnkiStatsTaskHandler(com.ichi2.anki.stats.AnkiStatsTaskHandler) ViewTreeObserver(android.view.ViewTreeObserver) DeckDropDownAdapter(com.ichi2.anki.widgets.DeckDropDownAdapter)

Example 22 with Deck

use of com.ichi2.libanki.Deck in project AnkiChinaAndroid by ankichinateam.

the class StudyOptionsFragment method handleDeckSelection.

private void handleDeckSelection(long did, boolean dontSkipStudyOptions) {
    // Clear the undo history when selecting a new deck
    if (getCol().getDecks().selected() != did) {
        getCol().clearUndo();
    }
    // Select the deck
    getCol().getDecks().select(did);
    // Also forget the last deck used by the Browser
    CardBrowser.clearLastDeckId();
    // Reset the schedule so that we get the counts for the currently selected deck
    mFocusedDeck = did;
    // Get some info about the deck to handle special cases
    int pos = mDeckListAdapter.findDeckPosition(did);
    AbstractDeckTreeNode deckDueTreeNode = mDeckListAdapter.getDeckList().get(pos);
    // if (!deckDueTreeNode.shouldDisplayCounts() || deckDueTreeNode.knownToHaveRep()) {
    // If we don't yet have numbers, we trust the user that they knows what they opens, tries to open it.
    // If there is nothing to review, it'll come back to deck picker.
    openReviewerOrStudyOptions(dontSkipStudyOptions);
// return;
// }
// There are numbers
// Figure out what action to take
// if (getCol().getSched().hasCardsTodayAfterStudyAheadLimit()) {
// // If there are cards due that can't be studied yet (due to the learn ahead limit) then go to study options
// openStudyOptions(false);
// } else if (getCol().getSched().newDue() || getCol().getSched().revDue()) {
// // If there are no cards to review because of the daily study limit then give "Study more" option
// UIUtils.showSnackbar(getAnkiActivity(), R.string.studyoptions_limit_reached, false, R.string.study_more, v -> {
// CustomStudyDialog d = CustomStudyDialog.newInstance(
// CustomStudyDialog.CONTEXT_MENU_LIMITS,
// getCol().getDecks().selected(), true, this);
// showDialogFragment(d);
// }, getView().findViewById(R.id.root_layout), mSnackbarShowHideCallback);
// // Check if we need to update the fragment or update the deck list. The same checks
// // are required for all snackbars below.
// if (mFragmented) {
// // Tablets must always show the study options that corresponds to the current deck,
// // regardless of whether the deck is currently reviewable or not.
// openStudyOptions(false);
// } else {
// // On phones, we update the deck list to ensure the currently selected deck is
// // highlighted correctly.
// updateDeckList();
// }
// } else if (getCol().getDecks().isDyn(did)) {
// // Go to the study options screen if filtered deck with no cards to study
// openStudyOptions(false);
// } else if (!deckDueTreeNode.hasChildren() && getCol().cardCount(new Long[] {did}) == 0) {
// // If the deck is empty and has no children then show a message saying it's empty
// final Uri helpUrl = Uri.parse(getResources().getString(R.string.link_manual_getting_started));
// getAnkiActivity().mayOpenUrl(helpUrl);
// UIUtils.showSnackbar(getAnkiActivity(), R.string.empty_deck, false, R.string.help,
// v -> openHelpUrl(helpUrl), getView().findViewById(R.id.root_layout), mSnackbarShowHideCallback);
// if (mFragmented) {
// openStudyOptions(false);
// } else {
// updateDeckList();
// }
// } else {
// // Otherwise say there are no cards scheduled to study, and give option to do custom study
// UIUtils.showSnackbar(getAnkiActivity(), R.string.studyoptions_empty_schedule, false, R.string.custom_study, v -> {
// CustomStudyDialog d = CustomStudyDialog.newInstance(
// CustomStudyDialog.CONTEXT_MENU_EMPTY_SCHEDULE,
// getCol().getDecks().selected(), true, this);
// showDialogFragment(d);
// }, getView().findViewById(R.id.root_layout), mSnackbarShowHideCallback);
// if (mFragmented) {
// openStudyOptions(false);
// } else {
// updateDeckList();
// }
// }
}
Also used : AbstractDeckTreeNode(com.ichi2.libanki.sched.AbstractDeckTreeNode)

Example 23 with Deck

use of com.ichi2.libanki.Deck 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)

Example 24 with Deck

use of com.ichi2.libanki.Deck in project AnkiChinaAndroid by ankichinateam.

the class StudyOptionsFragment method configureToolbarInternal.

// This will allow a maximum of one recur in order to workaround database closes
// caused by sync on startup where this might be running then have the collection close
private void configureToolbarInternal(boolean recur) {
    try {
        mToolbar.setOnMenuItemClickListener(this);
        Menu menu = mToolbar.getMenu();
        // Switch on or off rebuild/empty/custom study depending on whether or not filtered deck
        if (getCol().getDecks().isDyn(getCol().getDecks().selected())) {
            menu.findItem(R.id.action_add_card).setVisible(false);
            menu.findItem(R.id.action_rebuild).setVisible(true);
            menu.findItem(R.id.action_empty).setVisible(true);
            menu.findItem(R.id.action_custom_study).setVisible(false);
            menu.findItem(R.id.action_rename).setVisible(false);
            menu.findItem(R.id.create_deck).setVisible(false);
            menu.findItem(R.id.action_suspend).setVisible(false);
            menu.findItem(R.id.action_reset_card_progress).setVisible(false);
            menu.findItem(R.id.action_delete).setVisible(false);
            menu.findItem(R.id.action_export).setVisible(false);
            menu.findItem(R.id.action_setting).setVisible(false);
        } else {
            menu.findItem(R.id.action_rebuild).setVisible(false);
            menu.findItem(R.id.action_empty).setVisible(false);
            menu.findItem(R.id.action_custom_study).setVisible(true);
            menu.findItem(R.id.action_rename).setVisible(true);
            menu.findItem(R.id.create_deck).setVisible(true);
            menu.findItem(R.id.action_suspend).setVisible(true);
            menu.findItem(R.id.action_suspend).setTitle(deckIsStopped() ? "恢复学习" : "停止学习");
            menu.findItem(R.id.action_reset_card_progress).setVisible(true);
            menu.findItem(R.id.action_delete).setVisible(true);
            menu.findItem(R.id.action_export).setVisible(true);
            menu.findItem(R.id.action_setting).setVisible(true);
            menu.findItem(R.id.action_deck_options).setVisible(true);
        }
        // Don't show custom study icon if congrats shown
        // if (mCurrentContentView == CONTENT_CONGRATS) {
        // menu.findItem(R.id.action_custom_study).setVisible(false);
        // }
        // Switch on or off unbury depending on if there are cards to unbury
        menu.findItem(R.id.action_unbury).setVisible(getCol().getSched().haveBuried());
        // Switch on or off undo depending on whether undo is available
        menu.findItem(R.id.action_undo).setVisible(false);
    } catch (IllegalStateException e) {
        if (!CollectionHelper.getInstance().colIsOpen()) {
            if (recur) {
                Timber.i(e, "Database closed while working. Probably auto-sync. Will re-try after sleep.");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Timber.i(ex, "Thread interrupted while waiting to retry. Likely unimportant.");
                    Thread.currentThread().interrupt();
                }
                configureToolbarInternal(false);
            } else {
                Timber.w(e, "Database closed while working. No re-tries left.");
            }
        }
    }
}
Also used : DeckPickerContextMenu(com.ichi2.anki.dialogs.DeckPickerContextMenu) Menu(android.view.Menu)

Example 25 with Deck

use of com.ichi2.libanki.Deck in project AnkiChinaAndroid by ankichinateam.

the class StudyOptionsFragment method processNames.

private void processNames() {
    Deck deck = getCol().getDecks().current();
    long id = deck.optLong("id");
    TreeMap<String, Long> children = getCol().getDecks().children(id);
    // for (Deck parent : getCol().getDecks().parents(id)) {
    // parent.put("collapsed", false);//祖先节点全部打开
    // getCol().getDecks().save(parent);
    // }
    mHasSubDecks = children.size() > 0;
    mNoSubDeckHint.setText(mHasSubDecks ? "" : "暂无子记忆库");
    mInitCollapsedStatus = true;
}
Also used : Deck(com.ichi2.libanki.Deck)

Aggregations

Deck (com.ichi2.libanki.Deck)100 Collection (com.ichi2.libanki.Collection)97 JSONObject (com.ichi2.utils.JSONObject)88 Test (org.junit.Test)80 JSONArray (com.ichi2.utils.JSONArray)55 Card (com.ichi2.libanki.Card)53 Note (com.ichi2.libanki.Note)50 ArrayList (java.util.ArrayList)47 RobolectricTest (com.ichi2.anki.RobolectricTest)44 DeckConfig (com.ichi2.libanki.DeckConfig)37 JSONException (com.ichi2.utils.JSONException)34 NonNull (androidx.annotation.NonNull)30 HashMap (java.util.HashMap)29 Model (com.ichi2.libanki.Model)23 Map (java.util.Map)22 Intent (android.content.Intent)21 Resources (android.content.res.Resources)18 TextView (android.widget.TextView)18 SharedPreferences (android.content.SharedPreferences)17 Cursor (android.database.Cursor)17