Search in sources :

Example 31 with CARD

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

the class CollectionTask method doInBackgroundResetDeck.

private TaskData doInBackgroundResetDeck(TaskData param) {
    Timber.d("doInBackgroundSearchCardIds");
    Collection col = getCol();
    String query = (String) param.getObjArray()[0];
    if (isCancelled()) {
        Timber.d("doInBackgroundSearchCards was cancelled so return null");
        return null;
    }
    List<Long> searchResult_ = col.findCards(query, true, this);
    long[] cardIds = new long[searchResult_.size()];
    Card[] cards = new Card[searchResult_.size()];
    for (int i = 0; i < searchResult_.size(); i++) {
        cardIds[i] = searchResult_.get(i);
        cards[i] = col.getCard(searchResult_.get(i));
    }
    try {
        col.getDb().getDatabase().beginTransaction();
        try {
            try {
                Timber.d("Saving undo information of type %s on %d cards", RESET_CARDS, cards.length);
                Card[] cards_copied = deepCopyCardArray(cards);
                Undoable repositionRescheduleResetCards = new UndoRepositionRescheduleResetCards(RESET_CARDS, cards_copied);
                col.markUndo(repositionRescheduleResetCards);
            } catch (CancellationException ce) {
                Timber.i(ce, "Cancelled while handling type %s, skipping undo", RESET_CARDS);
            }
            AbstractSched sched = col.getSched();
            sched.forgetCards(cardIds);
            col.reset();
            publishProgress(new TaskData(sched.getCard(), 0));
            col.getDb().getDatabase().setTransactionSuccessful();
        } finally {
            col.getDb().getDatabase().endTransaction();
        }
    } catch (RuntimeException e) {
        Timber.e(e, "doInBackgroundSuspendCard - RuntimeException on suspending card");
        AnkiDroidApp.sendExceptionReport(e, "doInBackgroundSuspendCard");
        return new TaskData(false);
    }
    return new TaskData(true, cards);
}
Also used : Undoable(com.ichi2.libanki.Undoable) AbstractSched(com.ichi2.libanki.sched.AbstractSched) Card(com.ichi2.libanki.Card) CancellationException(java.util.concurrent.CancellationException) Collection(com.ichi2.libanki.Collection)

Example 32 with CARD

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

the class CollectionTask method doInBackgroundRenderBrowserQA.

private TaskData doInBackgroundRenderBrowserQA(TaskData param) {
    // TODO: Convert this to accept the following to make thread-safe:
    // (Range<Position>, Function<Position, BrowserCard>)
    Timber.d("doInBackgroundRenderBrowserQA");
    Collection col = getCol();
    List<CardBrowser.CardCache> cards = (List<CardBrowser.CardCache>) param.getObjArray()[0];
    Integer startPos = (Integer) param.getObjArray()[1];
    Integer n = (Integer) param.getObjArray()[2];
    int column1Index = (Integer) param.getObjArray()[3];
    int column2Index = (Integer) param.getObjArray()[4];
    List<Long> invalidCardIds = new ArrayList<>();
    // for each specified card in the browser list
    for (int i = startPos; i < startPos + n; i++) {
        // Stop if cancelled
        if (isCancelled()) {
            Timber.d("doInBackgroundRenderBrowserQA was aborted");
            return null;
        }
        if (i < 0 || i >= cards.size()) {
            continue;
        }
        CardBrowser.CardCache card;
        try {
            card = cards.get(i);
        } catch (IndexOutOfBoundsException e) {
            // we won't reach any more cards.
            continue;
        }
        if (card.isLoaded()) {
            // We've already rendered the answer, we don't need to do it again.
            continue;
        }
        // Extract card item
        try {
            // Ensure that card still exists.
            card.getCard();
        } catch (WrongId e) {
            // #5891 - card can be inconsistent between the deck browser screen and the collection.
            // Realistically, we can skip any exception as it's a rendering task which should not kill the
            // process
            long cardId = card.getId();
            Timber.e(e, "Could not process card '%d' - skipping and removing from sight", cardId);
            invalidCardIds.add(cardId);
            continue;
        }
        // Update item
        card.load(false, column1Index, column2Index);
        float progress = (float) i / n * 100;
        publishProgress(new TaskData((int) progress));
    }
    return new TaskData(new Object[] { cards, invalidCardIds });
}
Also used : ArrayList(java.util.ArrayList) CardBrowser(com.ichi2.anki.CardBrowser) Collection(com.ichi2.libanki.Collection) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) WrongId(com.ichi2.libanki.WrongId)

Example 33 with CARD

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

the class DeckInfoListAdapter method onBindViewHolder.

@Override
public void onBindViewHolder(RecyclerView.ViewHolder tempHolder, int position) {
    if (tempHolder instanceof HeaderViewHolder) {
        HeaderViewHolder holder = (HeaderViewHolder) tempHolder;
        holder.mTextDeckName.setText(mTextDeckName);
        holder.mDeckListHeader.setVisibility(mDeckList.isEmpty() ? View.GONE : View.VISIBLE);
        // holder.mTextCongratsMessage.setText(mTextCongratsMessage);
        holder.mTextDeckDescription.setText(mTextDeckDescription != null && mTextDeckDescription.length() > 0 ? formatDescription(mTextDeckDescription) : "");
        holder.mTextTodayNew.setText(mTextTodayNew);
        holder.mTextTodayRev.setText(mTextTodayRev);
        holder.mTextCountHandled.setText(mTextCountHandled);
        holder.mTextCountLearning.setText(mTextCountLearning);
        holder.mTextCountNew.setText(mTextCountNew);
        holder.mTextCountHard.setText(mTextCountHard);
        holder.mTextTotal.setText(mTextTotal);
        holder.mTextHandledPercent.setText(mTextHandledPercent);
        holder.mTextHandledNum.setText(mTextHandledNum);
        holder.mTextETA.setText(mTextETA);
        holder.mButtonStart.setText(mTextButtonStart);
        holder.mButtonStart.setOnClickListener(mButtonStartClickListener);
        holder.mSelfStudyAskIcon.setOnClickListener(v -> {
            if (mSelfStudyQADialog == null) {
                mSelfStudyQADialog = new Dialog(mContext, R.style.CommonDialogTheme);
                View view = View.inflate(mContext, R.layout.pop_window_self_study_introduce, null);
                mSelfStudyQADialog.setContentView(view);
                Window window = mSelfStudyQADialog.getWindow();
                WindowManager.LayoutParams lps = window.getAttributes();
                lps.width = WindowManager.LayoutParams.MATCH_PARENT;
                window.setAttributes(lps);
                window.setGravity(Gravity.BOTTOM);
                window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            }
            mSelfStudyQADialog.show();
        });
        holder.mStudyProgress.setProgress(mStudyProgress);
        // holder.mDeckInfoLayout.setVisibility(mDeckInfoLayoutVisible);
        // holder.mTextCongratsMessage.setVisibility(mTextCongratsMessageVisible);
        holder.mTextDeckDescription.setVisibility(mTextDeckDescriptionVisible);
        holder.mButtonStart.setEnabled(mButtonStartEnable);
        holder.mSelfStudyHandle.setTag(SelfStudyActivity.TAB_STUDY_STATE);
        holder.mSelfStudyMark.setTag(SelfStudyActivity.TAB_MARK_STATE);
        holder.mSelfStudyAnswer.setTag(SelfStudyActivity.TAB_ANSWER_STATE);
        holder.mSelfStudyCustom.setTag(SelfStudyActivity.TAB_CUSTOM_STATE);
        holder.mSelfStudyHandle.setOnClickListener(mSelfStudyClickListener);
        holder.mSelfStudyMark.setOnClickListener(mSelfStudyClickListener);
        holder.mSelfStudyAnswer.setOnClickListener(mSelfStudyClickListener);
        holder.mSelfStudyCustom.setOnClickListener(mSelfStudyClickListener);
        holder.mTextStudySetting.setVisibility(mCurrentDeck == null || mCurrentDeck.optInt("dyn", 0) == 1 ? View.GONE : View.VISIBLE);
        holder.mTextStudySetting.setOnClickListener(v -> {
            Intent i = new Intent(mContext, StudySettingActivity.class);
            i.putExtra("did", mCurrentDeck.optLong("id"));
            mContext.startActivityForResultWithAnimation(i, DECK_OPTIONS, ActivityTransitionAnimation.FADE);
        });
        if (AD_IMAGE_URL != null && !AD_IMAGE_URL.isEmpty() && AD_LINK_URL != null && !AD_LINK_URL.isEmpty()) {
            holder.mAdLayout.setVisibility(View.VISIBLE);
            CornerTransform transformation = new CornerTransform(mContext, AdaptionUtil.dip2px(mContext, 9));
            transformation.setExceptCorner(false, false, false, false);
            RequestOptions coverRequestOptions = new RequestOptions().transform(transformation).diskCacheStrategy(// 不做磁盘缓存
            DiskCacheStrategy.NONE).skipMemoryCache(// 不做内存缓存
            true);
            Glide.with(mContext).asBitmap().load(AD_IMAGE_URL).apply(coverRequestOptions).into(holder.mAdImage);
            holder.mAdLayout.setOnClickListener(v -> WebViewActivity.openUrlInApp(mContext, AD_LINK_URL, ""));
        } else {
            holder.mAdLayout.setVisibility(View.GONE);
        }
    } else if (tempHolder instanceof ViewHolder) {
        position--;
        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);
        if (mHasSubdecks) {
            int smallPadding = (int) deckLayout.getResources().getDimension(R.dimen.deck_picker_left_padding_small);
            deckLayout.setPadding(smallPadding, 0, (int) deckLayout.getResources().getDimension(R.dimen.deck_picker_right_padding), 0);
            holder.deckExpander.setVisibility(View.VISIBLE);
            // Create the correct expander for this deck
            setDeckExpander(holder.deckExpander, holder.indentView, node);
        } else {
            holder.deckExpander.setVisibility(View.GONE);
            int normalPadding = (int) deckLayout.getResources().getDimension(R.dimen.deck_picker_left_padding);
            deckLayout.setPadding(normalPadding, 0, (int) deckLayout.getResources().getDimension(R.dimen.deck_picker_right_padding), 0);
        }
        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)) {
        // Timber.d("can be shown:%s", node.getDid());
        // Timber.d("mHasSubdecks:%s", node.hasChildren() + "");
        // if (mCurrentIDs.contains(node.getDid())) {
        // holder.deckLayout.setVisibility(View.VISIBLE);
        // holder.deckLayout.setBackgroundResource(mRowCurrentDrawable);
        // if (mPartiallyTransparentForBackground) {
        // setBackgroundAlpha(holder.deckLayout, SELECTED_DECK_ALPHA_AGAINST_BACKGROUND);
        // }
        // } else {
        // holder.deckLayout.setVisibility(View.GONE);
        // 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 {
            if (node.getDepth() == Decks.path(mCurrentDeck.optString("name")).length) {
                holder.deckName.setTextColor(mDeckNameDefaultColor);
            } else {
                holder.deckName.setTextColor(mDeckNameDefaultColorChild);
            }
        }
        if (node.shouldDisplayCounts()) {
            // holder.deckNew.setText(String.valueOf(node.getNewCount()));
            // holder.deckLearn.setText(String.valueOf(node.getLrnCount()));
            // holder.deckRev.setText(String.valueOf(node.getRevCount()+node.getLrnCount()));
            holder.deckNew.setText(String.valueOf(node.getNewCount() + node.getRevCount() + node.getLrnCount()));
            String ids = Stats.deckLimit(node.getDid(), mCol);
            holder.deckRev.setText(String.valueOf(mCol.cardCount(ids)));
        }
        // Store deck ID in layout's tag for easy retrieval in our click listeners
        holder.deckLayout.setTag(node.getDid());
        holder.countsLayout.setTag(node.getDid());
        holder.endIcon.setTag(node.getDid());
        // holder.endLayout.setTag(node.getDid());
        // Set click listeners
        holder.deckLayout.setOnClickListener(mDeckClickListener);
        holder.deckLayout.setOnLongClickListener(mDeckLongClickListener);
        holder.countsLayout.setOnClickListener(mCountsClickListener);
        holder.endIcon.setOnClickListener(mCountsClickListener);
    // holder.endLayout.setOnClickListener(mCountsClickListener);
    } else if (mCurrentDeck != null) {
        if (tempHolder instanceof CardsListAdapter.CardsViewHolder) {
            CardsListAdapter.CardsViewHolder holder = (CardsListAdapter.CardsViewHolder) tempHolder;
            CardBrowser.CardCache card = mCards.get(position - mDeckList.size() - 1 - 1);
            Timber.i("refresh card:%s", card.getId());
            String question = card.getColumnHeaderText(CardBrowser.Column.SFLD);
            if (card.getColumnHeaderText(CardBrowser.Column.SUSPENDED).equals("True")) {
                holder.deckQuestion.setTextColor(ContextCompat.getColor(mContext, R.color.new_primary_text_third_color));
            // holder.deckAnswer.setTextColor(ContextCompat.getColor(mContext, R.color.new_primary_text_third_color));
            }
            String firstColumnStr = question.isEmpty() ? card.getColumnHeaderText(CardBrowser.Column.MEDIA_NAME) : card.getColumnHeaderText(CardBrowser.Column.SFLD);
            Pattern pattern = Pattern.compile("(?<=≯#).*?(?=#≮)");
            Matcher matcher = pattern.matcher(firstColumnStr);
            String val = "";
            if (matcher.find()) {
                val = matcher.group(0);
                try {
                    String key = mModelKeys.getString(String.valueOf(card.getCard().model().getLong("id")));
                    Timber.i("match key:%s", key);
                    holder.deckQuestion.setText(HtmlUtils.delHTMLTag(firstColumnStr.substring(0, firstColumnStr.indexOf("≯#")) + AESUtil.decrypt(val, key) + firstColumnStr.substring(firstColumnStr.indexOf("#≮") + 2)));
                // holder.deckQuestion.setText(firstColumnStr.substring(0, firstColumnStr.indexOf("≯#")) + aesUtil.getDecryptedMessage(val) + firstColumnStr.substring(firstColumnStr.indexOf("#≮") + 2));
                } catch (Exception e) {
                    e.printStackTrace();
                    holder.deckQuestion.setText(firstColumnStr);
                }
            } else {
                holder.deckQuestion.setText(firstColumnStr);
            }
            // holder.deckAnswer.setText(card.getColumnHeaderText(CardBrowser.Column.ANSWER));
            holder.reviewCount.setText(card.getColumnHeaderText(CardBrowser.Column.REVIEWS));
            holder.forgetCount.setText(card.getColumnHeaderText(CardBrowser.Column.LAPSES));
            holder.due.setText(card.getColumnHeaderText(CardBrowser.Column.DUE2));
            holder.mark.setTag(card.getId());
            holder.flag.setTag(card.getId());
            holder.itemRoot.setTag(card.getId());
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) holder.itemRoot.getLayoutParams();
            layoutParams.rightMargin = 0;
            holder.itemRoot.setLayoutParams(layoutParams);
            if (card.getCard().note().hasTag("marked")) {
                holder.mark.setImageResource(R.mipmap.mark_star_normal);
            } else {
                holder.mark.setImageResource(R.mipmap.note_star_unselected);
            }
            if (getFlagRes(card.getCard()) != -1) {
                holder.flag.setImageResource(getFlagRes(card.getCard()));
            } else {
                holder.flag.setImageResource(R.mipmap.note_flag_unselected);
            }
            holder.mark.setOnClickListener(v -> {
                CollectionTask.launchCollectionTask(DISMISS_MULTI, markCardHandler(), new TaskData(new Object[] { new long[] { (long) v.getTag() }, Collection.DismissType.MARK_NOTE_MULTI }));
                notifyDataSetChanged();
            });
            holder.flag.setOnClickListener(v -> {
                if (mListPop == null) {
                    mListPop = new ListPopupWindow(mContext);
                    for (int i = 0; i < mFlagRes.length; i++) {
                        Map<String, Object> map = new HashMap<>();
                        map.put("img", mFlagRes[i]);
                        map.put("content", mFlagContent[i]);
                        mFlagList.add(map);
                    }
                    mListPop.setAdapter(new SimpleAdapter(mContext, mFlagList, R.layout.item_flags_list, new String[] { "img", "content" }, new int[] { R.id.flag_icon, R.id.flag_text }));
                    mListPop.setWidth(v.getRootView().getWidth() / 2);
                    mListPop.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
                    // 设置是否是模式
                    mListPop.setModal(true);
                }
                mListPop.setOnItemClickListener((parent, view, position1, id) -> {
                    CollectionTask.launchCollectionTask(DISMISS_MULTI, flagCardHandler(), new TaskData(new Object[] { new long[] { (long) v.getTag() }, Collection.DismissType.FLAG, position1 }));
                    notifyDataSetChanged();
                    mListPop.dismiss();
                });
                mListPop.setAnchorView(v);
                mListPop.show();
            });
            holder.itemRoot.setOnClickListener(v -> {
                Intent previewer = new Intent(mContext, Previewer.class);
                long[] ids = getAllCardIds();
                long targetId = (long) v.getTag();
                // }
                for (int i = 0; i < ids.length; i++) {
                    if (ids[i] == targetId) {
                        previewer.putExtra("index", i);
                        break;
                    }
                }
                previewer.putExtra("cardList", ids);
                mContext.startActivityForResultWithoutAnimation(previewer, PREVIEW_CARDS);
            });
        // holder.itemRoot.setOnLongClickListener(mDeckLongClickListener);
        } else if (tempHolder instanceof BrowserTabViewHolder) {
            BrowserTabViewHolder holder = (BrowserTabViewHolder) tempHolder;
            String[] tabArray = mContext.getResources().getStringArray(R.array.deck_info_browser_tab);
            holder.cardsCount.setText(String.format("筛选出%d张卡片", mCards.size()));
            // CardsListAdapter  mCardsAdapter = new CardsListAdapter(mContext.getLayoutInflater(), mContext, new CardsListAdapter.CardListAdapterCallback() {
            // @Override
            // public List<CardBrowser.CardCache> getCards() {
            // if (mCards == null) {
            // mCards = new ArrayList<>();
            // }
            // return mCards;
            // }
            // 
            // 
            // @Override
            // public void onChangeMultiMode(boolean isMultiMode) {
            // }
            // 
            // 
            // @Override
            // public void onItemSelect(int count) {
            // }
            // });
            // mCardsAdapter.setStudyCountLayoutRes(R.layout.item_option_study_count);
            // mCardsAdapter.setDeckClickListener(view -> {
            // Intent previewer = new Intent(mContext, Previewer.class);
            // long[] ids =  getAllCardIds();
            // long targetId = (long) view.getTag();
            // if (ids.length > 100) {
            // //为提高效率 直接复制卡牌
            // long[] finalIds = new long[ids.length + 1];
            // finalIds[0] = targetId;
            // System.arraycopy(ids, 0, finalIds, 1, ids.length);
            // previewer.putExtra("cardList", finalIds);
            // } else {
            // for (int i = 0; i < ids.length; i++) {
            // if (ids[i] == targetId) {
            // ids[i] = ids[0];
            // ids[0] = targetId;
            // }
            // }
            // previewer.putExtra("cardList", ids);
            // }
            // previewer.putExtra("index", 0);
            // mContext.startActivityForResultWithoutAnimation(previewer, PREVIEW_CARDS);
            // });
            // holder.mList .setAdapter(mCardsAdapter);
            // holder.mList.setRecycledViewPool(new RecyclerView.RecycledViewPool());
            // holder.mList.setNestedScrollingEnabled(false);
            // holder.mList.setHasFixedSize(true);
            // holder.mList.setLayoutManager(new LinearLayoutManager(mContext));
            holder.mMore.setTag(SelfStudyActivity.TAB_MAIN_STATE);
            holder.mFixBottom.setVisibility(mDeckList.isEmpty() ? View.GONE : View.VISIBLE);
            holder.mMore.setOnClickListener(mSelfStudyClickListener);
            holder.mTabLayout.removeAllTabs();
            LinearLayout linearLayout = (LinearLayout) holder.mTabLayout.getChildAt(0);
            linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
            linearLayout.setDividerDrawable(ContextCompat.getDrawable(mContext, // 设置分割线的样式
            R.drawable.divider_vertical));
            // 设置分割线间隔
            linearLayout.setDividerPadding((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 18, mContext.getResources().getDisplayMetrics()));
            for (int i = 0; i < tabArray.length; i++) {
                TabLayout.Tab tab = holder.mTabLayout.newTab();
                View view = mContext.getLayoutInflater().inflate(R.layout.item_option_tab, null);
                ((TextView) view.findViewById(R.id.name)).setText(tabArray[i]);
                tab.setCustomView(view);
                view.setTag(i);
                int finalI = i;
                view.setOnClickListener(v -> {
                    if (mContext.colIsOpen()) {
                        mCurrentSelectedTab = finalI;
                        holder.mTabLayout.selectTab(holder.mTabLayout.getTabAt(finalI));
                        // estimate maximum number of cards that could be visible (assuming worst-case minimum row height of 20dp)
                        int numCardsToRender = (int) Math.ceil(holder.mList.getHeight() / TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, mContext.getResources().getDisplayMetrics())) + 5;
                        Timber.i("I wanna get %d cards", numCardsToRender);
                        // Perform database query to get all card ids
                        mSearchCardsHandler = new SearchCardsHandler();
                        String searchText = getRestrictByTab(finalI) + "deck:\"" + mCurrentDeck.getString("name") + "\" ";
                        CollectionTask.launchCollectionTask(SEARCH_CARDS, mSearchCardsHandler, new TaskData(new Object[] { searchText, true, numCardsToRender, 0, 0 }));
                    }
                });
                holder.mTabLayout.addTab(tab);
            }
            holder.mTabLayout.selectTab(holder.mTabLayout.getTabAt(mCurrentSelectedTab));
            if (!mInitBrowserCards) {
                mInitBrowserCards = true;
                holder.mTabLayout.getTabAt(0).getCustomView().performClick();
            }
        }
    }
}
Also used : ImageButton(android.widget.ImageButton) LinearLayout(android.widget.LinearLayout) Arrays(java.util.Arrays) Deck(com.ichi2.libanki.Deck) ProgressBar(android.widget.ProgressBar) NonNull(androidx.annotation.NonNull) WindowManager(android.view.WindowManager) ImageView(android.widget.ImageView) ColorDrawable(android.graphics.drawable.ColorDrawable) LinkMovementMethod(android.text.method.LinkMovementMethod) Drawable(android.graphics.drawable.Drawable) SelfStudyActivity(com.ichi2.anki.SelfStudyActivity) Decks(com.ichi2.libanki.Decks) Matcher(java.util.regex.Matcher) Map(java.util.Map) Previewer(com.ichi2.anki.Previewer) View(android.view.View) Button(android.widget.Button) TaskData(com.ichi2.async.TaskData) RecyclerView(androidx.recyclerview.widget.RecyclerView) StudySettingActivity(com.ichi2.anki.StudySettingActivity) ContextCompat(androidx.core.content.ContextCompat) CardView(androidx.cardview.widget.CardView) DeckPicker(com.ichi2.anki.DeckPicker) HtmlUtils(com.ichi2.utils.HtmlUtils) TabLayout(com.google.android.material.tabs.TabLayout) CardUtils(com.ichi2.anki.CardUtils) SEARCH_CARDS(com.ichi2.async.CollectionTask.TASK_TYPE.SEARCH_CARDS) Set(java.util.Set) JSONObject(com.ichi2.utils.JSONObject) CardBrowser(com.ichi2.anki.CardBrowser) Timber(timber.log.Timber) ViewGroup(android.view.ViewGroup) CollectionHelper(com.ichi2.anki.CollectionHelper) AnkiActivity(com.ichi2.anki.AnkiActivity) List(java.util.List) Nullable(androidx.annotation.Nullable) TextView(android.widget.TextView) SimpleAdapter(android.widget.SimpleAdapter) AnkiDroidApp(com.ichi2.anki.AnkiDroidApp) Consts(com.ichi2.libanki.Consts) CompatHelper(com.ichi2.compat.CompatHelper) RelativeLayout(android.widget.RelativeLayout) DECK_OPTIONS(com.ichi2.anki.AbstractFlashcardViewer.DECK_OPTIONS) TaskListenerWithContext(com.ichi2.async.TaskListenerWithContext) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) Pattern(java.util.regex.Pattern) Window(android.view.Window) WebViewActivity(com.ichi2.anki.WebViewActivity) TaskListener(com.ichi2.async.TaskListener) Spanned(android.text.Spanned) CornerTransform(com.ichi2.utils.CornerTransform) R(com.ichi2.anki.R) Dialog(android.app.Dialog) Intent(android.content.Intent) HashMap(java.util.HashMap) DISMISS_MULTI(com.ichi2.async.CollectionTask.TASK_TYPE.DISMISS_MULTI) Collection(com.ichi2.libanki.Collection) TypedArray(android.content.res.TypedArray) ArrayList(java.util.ArrayList) CardsListAdapter.getFlagRes(com.ichi2.anki.widgets.CardsListAdapter.getFlagRes) DiskCacheStrategy(com.bumptech.glide.load.engine.DiskCacheStrategy) Utils(com.ichi2.libanki.Utils) ListPopupWindow(androidx.appcompat.widget.ListPopupWindow) RequestOptions(com.bumptech.glide.request.RequestOptions) AbstractDeckTreeNode(com.ichi2.libanki.sched.AbstractDeckTreeNode) Stats(com.ichi2.libanki.stats.Stats) LayoutInflater(android.view.LayoutInflater) CollectionTask(com.ichi2.async.CollectionTask) SelfStudyActivity.getPositionMap(com.ichi2.anki.SelfStudyActivity.getPositionMap) Color(android.graphics.Color) Gravity(android.view.Gravity) AESUtil(com.ichi2.utils.AESUtil) Glide(com.bumptech.glide.Glide) SharedPreferences(android.content.SharedPreferences) TypedValue(android.util.TypedValue) TreeMap(java.util.TreeMap) AdaptionUtil(com.ichi2.utils.AdaptionUtil) PREVIEW_CARDS(com.ichi2.anki.SelfStudyActivity.PREVIEW_CARDS) Card(com.ichi2.libanki.Card) KEY_STRUCT_INIT(com.ichi2.anki.StudyOptionsFragment.KEY_STRUCT_INIT) VisibleForTesting(androidx.annotation.VisibleForTesting) ActivityTransitionAnimation(com.ichi2.anim.ActivityTransitionAnimation) RequestOptions(com.bumptech.glide.request.RequestOptions) Matcher(java.util.regex.Matcher) HashMap(java.util.HashMap) CardBrowser(com.ichi2.anki.CardBrowser) WindowManager(android.view.WindowManager) TaskData(com.ichi2.async.TaskData) CornerTransform(com.ichi2.utils.CornerTransform) ListPopupWindow(androidx.appcompat.widget.ListPopupWindow) Dialog(android.app.Dialog) AbstractDeckTreeNode(com.ichi2.libanki.sched.AbstractDeckTreeNode) Window(android.view.Window) ListPopupWindow(androidx.appcompat.widget.ListPopupWindow) Pattern(java.util.regex.Pattern) SimpleAdapter(android.widget.SimpleAdapter) Intent(android.content.Intent) ImageView(android.widget.ImageView) View(android.view.View) RecyclerView(androidx.recyclerview.widget.RecyclerView) CardView(androidx.cardview.widget.CardView) TextView(android.widget.TextView) ColorDrawable(android.graphics.drawable.ColorDrawable) RelativeLayout(android.widget.RelativeLayout) JSONObject(com.ichi2.utils.JSONObject) LinearLayout(android.widget.LinearLayout)

Example 34 with CARD

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

the class CardsListAdapter method onBindViewHolder.

@Override
public void onBindViewHolder(RecyclerView.ViewHolder tempHolder, int position) {
    // Timber.i("onBindViewHolder:%s", position);
    if (tempHolder instanceof CardsViewHolder) {
        position--;
        CardsViewHolder holder = (CardsViewHolder) tempHolder;
        CardBrowser.CardCache card = mCallback.getCards().get(position);
        String question = card.getColumnHeaderText(CardBrowser.Column.SFLD);
        if (card.getColumnHeaderText(CardBrowser.Column.SUSPENDED).equals("True")) {
            holder.deckQuestion.setTextColor(ContextCompat.getColor(mContext, R.color.new_primary_text_third_color));
        // holder.deckAnswer.setTextColor(ContextCompat.getColor(mContext, R.color.new_primary_text_third_color));
        }
        String firstColumnStr = question.isEmpty() ? card.getColumnHeaderText(CardBrowser.Column.MEDIA_NAME) : card.getColumnHeaderText(CardBrowser.Column.SFLD);
        Pattern pattern = Pattern.compile("(?<=≯#).*?(?=#≮)");
        Matcher matcher = pattern.matcher(firstColumnStr);
        String val = "";
        if (matcher.find()) {
            val = matcher.group(0);
            try {
                String key = mModelKeys.getString(String.valueOf(card.getCard().model().getLong("id")));
                Timber.i("match key:%s", key);
                holder.deckQuestion.setText(HtmlUtils.delHTMLTag(firstColumnStr.substring(0, firstColumnStr.indexOf("≯#")) + AESUtil.decrypt(val, key) + firstColumnStr.substring(firstColumnStr.indexOf("#≮") + 2)));
            // holder.deckQuestion.setText(firstColumnStr.substring(0, firstColumnStr.indexOf("≯#")) + aesUtil.getDecryptedMessage(val) + firstColumnStr.substring(firstColumnStr.indexOf("#≮") + 2));
            } catch (Exception e) {
                e.printStackTrace();
                holder.deckQuestion.setText(firstColumnStr);
            }
        } else {
            holder.deckQuestion.setText(firstColumnStr);
        }
        Timber.i("match content:%s", val);
        // if(mModelKeys!=null&&(  key=mModelKeys.getString(String.valueOf(card.getCard().model().getLong("id"))))!=JSONObject.NULL){
        // holder.deckQuestion.setText(AESUtil.decrypt(firstColumnStr,key));
        // }else {
        // holder.deckQuestion.setText((mModelKeys!=null&&(  key=mModelKeys.getString(String.valueOf(card.getCard().model().getLong("id"))))!=JSONObject.NULL)?AESUtil.decrypt(firstColumnStr,key):firstColumnStr);
        // }
        // holder.deckQuestion.setText((mModelKeys!=null&&(  key=mModelKeys.getString(String.valueOf(card.getCard().model().getLong("id"))))!=JSONObject.NULL)?AESUtil.decrypt(firstColumnStr,key):firstColumnStr);
        // if (question.isEmpty()) {
        // 
        // holder.deckQuestion.setText(card.getColumnHeaderText(CardBrowser.Column.MEDIA_NAME));
        // } else {
        // holder.deckQuestion.setText(card.getColumnHeaderText(CardBrowser.Column.SFLD));
        // }
        // holder.deckAnswer.setText(card.getColumnHeaderText(CardBrowser.Column.ANSWER));
        holder.reviewCount.setText(card.getColumnHeaderText(CardBrowser.Column.REVIEWS));
        holder.forgetCount.setText(card.getColumnHeaderText(CardBrowser.Column.LAPSES));
        holder.due.setText(card.getColumnHeaderText(CardBrowser.Column.DUE2));
        holder.mark.setTag(card.getId());
        holder.flag.setTag(card.getId());
        holder.itemRoot.setTag(card.getId());
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) holder.itemRoot.getLayoutParams();
        if (mMultiCheckableMode) {
            layoutParams.rightMargin = -60;
            holder.itemRoot.setLayoutParams(layoutParams);
            holder.stick.setVisibility(View.VISIBLE);
        } else {
            layoutParams.rightMargin = 0;
            holder.itemRoot.setLayoutParams(layoutParams);
            holder.stick.setVisibility(View.GONE);
        }
        holder.stick.setChecked(mSelectedPosition.contains(card.getId()));
        // Timber.i("mSelectedPosition size " + mSelectedPosition.size() + "," + card.getId());
        holder.stick.setOnClickListener(v -> {
            if (mSelectedPosition.contains(card.getId())) {
                mSelectedPosition.remove(card.getId());
                mCheckedCards.remove(card);
            } else {
                mSelectedPosition.add(card.getId());
                mCheckedCards.add(card);
            }
            mCallback.onItemSelect(mSelectedPosition.size());
        });
        // });
        if (card.getCard().note().hasTag("marked")) {
            holder.mark.setImageResource(R.mipmap.mark_star_normal);
        // holder.mark.setVisibility(View.VISIBLE);
        } else {
            holder.mark.setImageResource(R.mipmap.note_star_unselected);
        // holder.flag.setVisibility(View.GONE);
        }
        if (getFlagRes(card.getCard()) != -1) {
            holder.flag.setImageResource(getFlagRes(card.getCard()));
        // holder.flag.setVisibility(View.VISIBLE);
        } else {
            // holder.flag.setImageDrawable(mEmptyFlag);
            holder.flag.setImageResource(R.mipmap.note_flag_unselected);
        // holder.flag.setVisibility(View.GONE);
        }
        holder.mark.setOnClickListener(mMarkClickListener);
        holder.flag.setOnClickListener(mSetFlagClickListener);
        holder.itemRoot.setOnClickListener(mDeckClickListener);
        holder.itemRoot.setOnLongClickListener(mDeckLongClickListener);
    } else {
        HeaderViewHolder holder = (HeaderViewHolder) tempHolder;
        holder.cardsCount.setText(String.format("筛选出%d张卡片", getItemCount() - 1));
        holder.cardsCount.setVisibility(isMultiCheckableMode() ? View.GONE : View.VISIBLE);
        if (holder.order != null) {
            holder.order.setOnClickListener(mIvOrderClickListener);
            holder.orderText.setOnClickListener(mTvOrderClickListener);
            holder.orderText.setText(mOrderName);
            holder.order.setSelected(mAsc);
        }
    }
}
Also used : Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) CardBrowser(com.ichi2.anki.CardBrowser) LinearLayout(android.widget.LinearLayout)

Example 35 with CARD

use of com.ichi2.anki.CardBrowser.Column.CARD 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);
    }
}
Also used : AbstractDeckTreeNode(com.ichi2.libanki.sched.AbstractDeckTreeNode)

Aggregations

Card (com.ichi2.libanki.Card)222 Test (org.junit.Test)212 Collection (com.ichi2.libanki.Collection)179 Note (com.ichi2.libanki.Note)173 RobolectricTest (com.ichi2.anki.RobolectricTest)168 JSONObject (com.ichi2.utils.JSONObject)114 JSONArray (com.ichi2.utils.JSONArray)80 DeckConfig (com.ichi2.libanki.DeckConfig)72 ArrayList (java.util.ArrayList)48 NonNull (androidx.annotation.NonNull)33 Deck (com.ichi2.libanki.Deck)32 Intent (android.content.Intent)29 JSONException (com.ichi2.utils.JSONException)27 Model (com.ichi2.libanki.Model)26 Context (android.content.Context)23 SuppressLint (android.annotation.SuppressLint)22 Cursor (android.database.Cursor)22 HashMap (java.util.HashMap)21 Matchers.containsString (org.hamcrest.Matchers.containsString)20 List (java.util.List)17