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