use of com.ichi2.libanki.sched.Counts 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.sched.Counts in project AnkiChinaAndroid by ankichinateam.
the class StudyOptionsFragment method getCollectionTaskListener.
/**
* Returns a listener that rebuilds the interface after execute.
*
* @param refreshDecklist If true, the listener notifies the parent activity to update its deck list
* to reflect the latest values.
*/
private TaskListener getCollectionTaskListener(final boolean refreshDecklist) {
return new TaskListener() {
@Override
public void onPreExecute() {
}
@Override
public void onPostExecute(TaskData result) {
dismissProgressDialog();
if (result != null) {
// Get the return values back from the AsyncTask
Object[] obj = result.getObjArray();
int newCards = (Integer) obj[0];
int lrnCards = (Integer) obj[1];
int revCards = (Integer) obj[1] + (Integer) obj[2];
int totalNew = (Integer) obj[3];
int totalCards = (Integer) obj[4];
Timber.i("start refresh list data:" + newCards + "," + lrnCards + "," + revCards + "," + totalNew + "," + totalCards);
// Don't do anything if the fragment is no longer attached to it's Activity or col has been closed
if (getActivity() == null) {
Timber.e("StudyOptionsFragment.mRefreshFragmentListener :: can't refresh");
return;
}
// #5506 If we have no view, short circuit all UI logic
if (mStudyOptionsView == null) {
tryOpenCramDeckOptions();
return;
}
// Reinitialize controls incase changed to filtered deck
initAllContentViews(mStudyOptionsView);
// Set the deck name
String fullName;
Deck deck = getCol().getDecks().current();
// Main deck name
fullName = deck.getString("name");
String[] name = Decks.path(fullName);
StringBuilder nameBuilder = new StringBuilder();
if (name.length > 0) {
nameBuilder.append(name[name.length - 1]);
}
// if (name.length > 1) {
// nameBuilder.append("\n").append(name[1]);
// }
// if (name.length > 3) {
// nameBuilder.append("...");
// }
// if (name.length > 2) {
// nameBuilder.append("\n").append(name[name.length - 1]);
// }
// mTextDeckName.setText(nameBuilder.toString());
mDeckListAdapter.mTextDeckName = nameBuilder.toString();
if (tryOpenCramDeckOptions()) {
return;
}
// Switch between the empty view, the ordinary view, and the "congratulations" view
boolean isDynamic = deck.optInt("dyn", 0) != 0;
if (totalCards == 0 && !isDynamic) {
mCurrentContentView = CONTENT_EMPTY;
mDeckListAdapter.mDeckInfoLayoutVisible = View.VISIBLE;
mDeckListAdapter.mTextCongratsMessageVisible = View.VISIBLE;
// mDeckListAdapter.mTextCongratsMessage=getString(R.string.studyoptions_empty);
mDeckListAdapter.mButtonStartEnable = false;
mDeckListAdapter.mTextButtonStart = getString(R.string.studyoptions_start);
} else if (newCards + lrnCards + revCards == 0) {
mCurrentContentView = CONTENT_CONGRATS;
if (!isDynamic) {
mDeckListAdapter.mDeckInfoLayoutVisible = View.GONE;
mDeckListAdapter.mButtonStartEnable = true;
mDeckListAdapter.mTextButtonStart = getString(R.string.add_today_study_amount);
} else {
mDeckListAdapter.mButtonStartEnable = true;
mDeckListAdapter.mTextButtonStart = getString(R.string.add_today_study_amount);
}
mDeckListAdapter.mTextCongratsMessageVisible = View.VISIBLE;
// mDeckListAdapter.mTextCongratsMessage=getCol().getSched().finishedMsg(getActivity()).toString();
// mTextCongratsMessage.setText(getCol().getSched().finishedMsg(getActivity()));
} else {
mCurrentContentView = CONTENT_STUDY_OPTIONS;
mDeckListAdapter.mDeckInfoLayoutVisible = View.VISIBLE;
mDeckListAdapter.mTextCongratsMessageVisible = View.GONE;
mDeckListAdapter.mButtonStartEnable = true;
mDeckListAdapter.mTextButtonStart = getString(R.string.studyoptions_start);
}
mDeckListAdapter.setButtonStartClickListener(mButtonClickListener);
mDeckListAdapter.setSelfStudyClickListener(mSelfStudyListener);
// Set deck description
String desc;
if (isDynamic) {
desc = getResources().getString(R.string.dyn_deck_desc);
} else {
desc = "";
// desc = getCol().getDecks().getActualDescription();
}
if (desc.length() > 0) {
mDeckListAdapter.mTextDeckDescription = desc;
mDeckListAdapter.mTextDeckDescriptionVisible = View.VISIBLE;
// mTextDeckDescription.setText(formatDescription(desc));
// mTextDeckDescription.setVisibility(View.VISIBLE);
} else {
mDeckListAdapter.mTextDeckDescriptionVisible = View.GONE;
}
// Set new/learn/review card counts
mDeckListAdapter.mTextTodayNew = String.valueOf(newCards);
mDeckListAdapter.mTextTodayRev = String.valueOf(revCards);
// Set the total number of new cards in deck
if (totalNew < NEW_CARD_COUNT_TRUNCATE_THRESHOLD) {
// if it hasn't been truncated by libanki then just set it usually
// mTextNewTotal.setText(String.valueOf(totalNew));
} else {
// mTextNewTotal.setText(">1000");
if (mFullNewCountThread != null) {
// a thread was previously made -- interrupt it
mFullNewCountThread.interrupt();
}
// mFullNewCountThread = new Thread(() -> {
// Collection collection = getCol();
// TODO: refactor code to not rewrite this query, add to Sched.totalNewForCurrentDeck()
// String query = "SELECT count(*) FROM cards WHERE did IN " +
// Utils.ids2str(collection.getDecks().active()) +
// " AND queue = " + Consts.QUEUE_TYPE_NEW;
// final int fullNewCount = collection.getDb().queryScalar(query);
// if (fullNewCount > 0) {
// Runnable setNewTotalText = new Runnable() {
// @Override
// public void run() {
// mTextNewTotal.setText(String.valueOf(fullNewCount));
// }
// };
// if (!Thread.currentThread().isInterrupted()) {
// mTextNewTotal.post(setNewTotalText);
// }
// }
// });
// mFullNewCountThread.start();
}
// Set total number of cards
// mTextTotal.setText(String.valueOf(totalCards));
double[] data = calculateStat(getCol(), getCol().getDecks().current().optLong("id"));
mNewCardsNum = (int) data[2];
mRevCardsNum = revCards;
mShouldConfigBeforeStudy = mNewCardsNum == totalCards && mShouldConfigBeforeStudy;
int hardNum = getLapses(getCol(), getCol().getDecks().current().optLong("id"));
mDeckListAdapter.mTextCountHandled = String.format(Locale.CHINA, "%d", (int) data[0]);
mDeckListAdapter.mTextCountLearning = String.format(Locale.CHINA, "%d", (int) data[1]);
mDeckListAdapter.mTextCountNew = String.format(Locale.CHINA, "%d", (int) data[2]);
mDeckListAdapter.mTextCountHard = String.format(Locale.CHINA, "%d", hardNum);
mDeckListAdapter.mTextTotal = String.format(Locale.CHINA, "共%d张卡牌", totalCards);
double percent = 0;
if (data[2] == 0) {
// 新卡已学完,显示已掌握
percent = (data[0] + data[1] + data[2] <= 0) ? 0 : (data[0] / (data[0] + data[1] + data[2]) * 100);
mDeckListAdapter.mTextHandledNum = String.format(Locale.CHINA, "%.0f/%.0f", data[0], (data[0] + data[1] + data[2]));
// holder.handled_percent.setText((String.format(Locale.CHINA, "已掌握 %.1f", percent)) + "%");
} else {
percent = (data[0] + data[1] + data[2] <= 0) ? 0 : ((data[0] + data[1]) / (data[0] + data[1] + data[2]) * 100);
mDeckListAdapter.mTextHandledNum = String.format(Locale.CHINA, "%.0f/%.0f", data[0] + data[1], data[0] + data[1] + data[2]);
// holder.handled_percent.setText((String.format(Locale.CHINA, "已学 %.1f", percent)) + "%");
}
// double percent = (data[0] + data[1] + data[2] <= 0) ? 0 : (data[0] / (data[0] + data[1] + data[2]) * 100);
// mStudyProgress.setMax(100*100);
mDeckListAdapter.mStudyProgress = (int) (percent * 100);
mDeckListAdapter.mTextHandledPercent = (String.format(Locale.CHINA, data[2] == 0 ? "已掌握 %.1f" : "已学 %.1f", percent)) + "%";
// Set estimated time remaining
int eta = (newCards + revCards) * 10 / 60;
if ((newCards + revCards) % 60 != 0) {
eta++;
}
if (eta != -1) {
mDeckListAdapter.mTextETA = "" + eta;
} else {
mDeckListAdapter.mTextETA = "-";
}
mDeckListAdapter.notifyDataSetChangedAll();
// Rebuild the options menu
configureToolbar();
}
updateDeckList();
// If in fragmented mode, refresh the deck list
if (mFragmented && refreshDecklist) {
mListener.onRequireDeckListUpdate();
}
}
};
}
use of com.ichi2.libanki.sched.Counts in project AnkiChinaAndroid by ankichinateam.
the class SelfStudyActivity method initSearchView.
private void initSearchView() {
mSearchView = findViewById(R.id.search_view);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mSearchView.getLayoutParams();
layoutParams.gravity = Gravity.CENTER;
mSearchView.setLayoutParams(layoutParams);
mSearchView.setOnCloseListener(() -> {
mSearchTerms = "";
Timber.i("close search view");
mSearchView.setQuery(mSearchTerms, false);
searchCards();
return false;
});
mSearchView.setQueryHint("输入关键词或语法");
mSearchView.setIconifiedByDefault(false);
// Get ImageView of icon
// ImageView searchViewIcon = (ImageView)mSearchView.findViewById(androidx.appcompat.R.id.search_mag_icon);
// // Get parent of gathered icon
// ViewGroup linearLayoutSearchView = (ViewGroup) searchViewIcon.getParent(); //Remove it from the left...
// linearLayoutSearchView.removeView(searchViewIcon); //then put it back (to the right by default)
// linearLayoutSearchView.addView(searchViewIcon);
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextChange(String newText) {
if (newText.equals("")) {
mSearchTerms = "";
}
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
onSearch();
mSearchView.clearFocus();
return true;
}
});
mSearchView.setOnSearchClickListener(v -> {
// Provide SearchView with the previous search terms
mSearchView.setQuery(mSearchTerms, false);
// System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
// //为数组最后一位赋值
// mHits[mHits.length - 1] = SystemClock.uptimeMillis();
// if (mHits[0] >= (SystemClock.uptimeMillis() - DURATION)) {
// mHits = new long[COUNTS];//重新初始化数组
// mShowGrammarInSearchView=true;
// Toast.makeText(SelfStudyActivity.this, "显示语法在搜索栏", Toast.LENGTH_LONG).show();
// }
});
mSearchView.setOnFocusChangeListener((v, hasFocus) -> {
mStartStudyButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
if (hasFocus) {
return;
}
InputMethodManager manager = ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE));
if (manager != null && getCurrentFocus() != null) {
manager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
});
mSearchView.setOnClickListener(v -> {
// 每次点击时,数组向前移动一位
System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
// 为数组最后一位赋值
mHits[mHits.length - 1] = SystemClock.uptimeMillis();
if (mHits[0] >= (SystemClock.uptimeMillis() - DURATION)) {
// 重新初始化数组
mHits = new long[COUNTS];
mShowGrammarInSearchView = true;
Toast.makeText(SelfStudyActivity.this, "显示语法在搜索栏", Toast.LENGTH_LONG).show();
}
});
}
use of com.ichi2.libanki.sched.Counts in project AnkiChinaAndroid by ankichinateam.
the class CollectionTask method doInBackgroundUpdateValuesFromDeck.
private TaskData doInBackgroundUpdateValuesFromDeck(TaskData param) {
Timber.d("doInBackgroundUpdateValuesFromDeck");
try {
Collection col = getCol();
AbstractSched sched = col.getSched();
Object[] obj = param.getObjArray();
boolean reset = (Boolean) obj[0];
if (reset) {
// reset actually required because of counts, which is used in getCollectionTaskListener
sched.resetCounts();
}
int[] counts = sched.counts();
int totalNewCount = sched.totalNewForCurrentDeck();
int totalCount = sched.cardCount();
return new TaskData(new Object[] { counts[0], counts[1], counts[2], totalNewCount, totalCount, sched.eta(counts) });
} catch (RuntimeException e) {
Timber.e(e, "doInBackgroundUpdateValuesFromDeck - an error occurred");
return null;
}
}
use of com.ichi2.libanki.sched.Counts in project AnkiChinaAndroid by ankichinateam.
the class DeckAdapter method onBindViewHolder.
@Override
public void onBindViewHolder(RecyclerView.ViewHolder tempHolder, int position) {
// Update views for this node
if (tempHolder instanceof HeaderViewHolder) {
HeaderViewHolder holder = (HeaderViewHolder) tempHolder;
holder.cost_time.setText(mCost == null || mCost.isEmpty() ? "0" : mCost);
holder.new_card_num.setText(mNewCard == null || mNewCard.isEmpty() ? "0" : mNewCard);
holder.review_card_num.setText(mNeedReviewCard == null || mNeedReviewCard.isEmpty() ? "0" : mNeedReviewCard);
holder.tv_resource.setOnClickListener(mMarketClickListener);
if (mAdText != null && !mAdText.isEmpty()) {
holder.main_ad_layout.setVisibility(View.VISIBLE);
holder.main_ad_text.setText(mAdText);
holder.main_ad_layout.setOnClickListener(mAdClickListener);
holder.remove_ad.setOnClickListener(v -> {
holder.main_ad_layout.setVisibility(View.GONE);
// LinearLayout.LayoutParams params= (LinearLayout.LayoutParams) holder.today_title.getLayoutParams();
// params.topMargin= AdaptionUtil.dip2px(mContext, 9);
});
} else {
holder.main_ad_layout.setVisibility(View.GONE);
}
} else if (tempHolder instanceof EmptyViewHolder) {
EmptyViewHolder holder = (EmptyViewHolder) tempHolder;
holder.btn_get_card.setOnClickListener(mMarketClickListener);
} else if (tempHolder instanceof DeckAdapter.ViewHolder) {
position--;
DeckAdapter.ViewHolder holder = (ViewHolder) tempHolder;
AbstractDeckTreeNode node = mDeckList.get(position);
// Set the expander icon and padding according to whether or not there are any subdecks
// RelativeLayout deckLayout = holder.deckLayout;
// int rightPadding = (int) deckLayout.getResources().getDimension(R.dimen.deck_picker_right_padding);
// Timber.d("onBindViewHolder,mHasSubdecks:" + mHasSubdecks);
// if (mHasSubdecks) {
// int smallPadding = (int) deckLayout.getResources().getDimension(R.dimen.deck_picker_left_padding_small);
// deckLayout.setPadding(smallPadding, 0, rightPadding, 0);
// holder.deckExpander.setVisibility(View.VISIBLE);
// holder.fileBag.setVisibility(View.VISIBLE);
// // Create the correct expander for this deck
//
// setDeckExpander(holder.deckExpander,holder.fileBag,holder.indentView, node);
// } else {
// holder.deckExpander.setVisibility(View.GONE);
// holder.fileBag.setVisibility(View.GONE);
// int normalPadding = (int) deckLayout.getResources().getDimension(R.dimen.deck_picker_left_padding);
// deckLayout.setPadding(normalPadding, 0, rightPadding, 0);
// }
// holder.fileBag.setOnClickListener(v -> holder.deckExpander.performClick());
// holder.filebagLayout.setOnClickListener(v -> holder.deckExpander.performClick());
// if (node.hasChildren()) {
// holder.deckExpander.setTag(node.getDid());
// holder.deckExpander.setOnClickListener(mDeckExpanderClickListener);
// } else {
// holder.deckExpander.setOnClickListener(null);
// }
// holder.deckLayout.setBackgroundResource(mRowCurrentDrawable);
// Set background colour. The current deck has its own color
// if (isCurrentlySelectedDeck(node)) {
// holder.deckLayout.setBackgroundResource(mRowCurrentDrawable);
// if (mPartiallyTransparentForBackground) {
// setBackgroundAlpha(holder.deckLayout, SELECTED_DECK_ALPHA_AGAINST_BACKGROUND);
// }
// } else {
// CompatHelper.getCompat().setSelectableBackground(holder.deckLayout);
// }
// Set deck name and colour. Filtered decks have their own colour
holder.deckName.setText(node.getLastDeckNameComponent());
if (mCol.getDecks().isDyn(node.getDid())) {
holder.deckName.setTextColor(mDeckNameDynColor);
} else {
holder.deckName.setTextColor(mDeckNameDefaultColor);
}
double[] data;
// Set the card counts and their colors
if (node.shouldDisplayCounts()) {
holder.deckNew.setText(String.valueOf(node.getNewCount()));
// holder.deckNew.setTextColor((node.getNewCount() == 0) ? mZeroCountColor : mNewCountColor);
holder.deckLearn.setText(String.valueOf(node.getLrnCount()));
// holder.deckLearn.setTextColor((node.getLrnCount() == 0) ? mZeroCountColor : mLearnCountColor);
holder.deckRev.setText(String.valueOf(node.getRevCount() + node.getLrnCount()));
// holder.deckRev.setTextColor((node.getRevCount() == 0) ? mZeroCountColor : mReviewCountColor);
data = node.getStudyData();
} else {
data = new double[] { 0.0, 0.0, 0.0 };
}
// Store deck ID in layout's tag for easy retrieval in our click listeners
holder.deckLayout.setTag(node.getDid());
holder.countsLayout.setTag(node.getDid());
// double[] data = calculateStat(mCol, node.getDid());
double percent = 0;
if (data[2] == 0) {
// 新卡已学完,显示已掌握
percent = (data[0] + data[1] + data[2] <= 0) ? 0 : (data[0] / (data[0] + data[1] + data[2]) * 100);
holder.handled_num.setText(String.format(Locale.CHINA, "%.0f/%.0f", data[0], (data[0] + data[1] + data[2])));
holder.handled_percent.setText((String.format(Locale.CHINA, "已掌握 %.1f", percent)) + "%");
} else {
percent = (data[0] + data[1] + data[2] <= 0) ? 0 : ((data[0] + data[1]) / (data[0] + data[1] + data[2]) * 100);
holder.handled_num.setText(String.format(Locale.CHINA, "%.0f/%.0f", data[0] + data[1], (data[0] + data[1] + data[2])));
holder.handled_percent.setText((String.format(Locale.CHINA, "已学 %.1f", percent)) + "%");
}
holder.studyProgress.setMax(100 * 100);
holder.studyProgress.setProgress((int) (percent * 100));
// Set click listeners
holder.deckLayout.setOnClickListener(mDeckClickListener);
holder.deckLayout.setOnLongClickListener(mDeckLongClickListener);
holder.countsLayout.setOnClickListener(mCountsClickListener);
}
}
Aggregations