use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.
the class CardContentProvider method delete.
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
if (!hasReadWritePermission()) {
throwSecurityException("delete", uri);
}
Collection col = CollectionHelper.getInstance().getCol(mContext);
if (col == null) {
throw new IllegalStateException(COL_NULL_ERROR_MSG);
}
col.log(getLogMessage("delete", uri));
switch(sUriMatcher.match(uri)) {
case NOTES_ID:
col.remNotes(new long[] { Long.parseLong(uri.getPathSegments().get(1)) });
return 1;
case MODELS_ID_EMPTY_CARDS:
Model model = col.getModels().get(getModelIdFromUri(uri, col));
if (model == null) {
return -1;
}
List<Long> cids = col.genCards(col.getModels().nids(model));
col.remCards(cids);
return cids.size();
default:
throw new UnsupportedOperationException();
}
}
use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.
the class CollectionTask method doInBackGroundAddField.
/**
* Adds a field with name in given model
*/
private TaskData doInBackGroundAddField(TaskData param) {
Timber.d("doInBackgroundRepositionField");
Object[] objects = param.getObjArray();
Model model = (Model) objects[0];
String fieldName = (String) objects[1];
Collection col = getCol();
col.getModels().addFieldModChanged(model, col.getModels().newField(fieldName));
col.save();
return new TaskData(true);
}
use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.
the class CollectionTask method doInBackGroundDeleteField.
/**
* Deletes thje given field in the given model
*/
private TaskData doInBackGroundDeleteField(TaskData param) {
Timber.d("doInBackGroundDeleteField");
Object[] objects = param.getObjArray();
Model model = (Model) objects[0];
JSONObject field = (JSONObject) objects[1];
Collection col = getCol();
try {
col.getModels().remField(model, field);
col.save();
} catch (ConfirmModSchemaException e) {
// Should never be reached
return new TaskData(false);
}
return new TaskData(true);
}
use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.
the class CollectionTask method doInBackgroundSaveModel.
/**
* Handles everything for a model change at once - template add / deletes as well as content updates
*/
private TaskData doInBackgroundSaveModel(TaskData param) {
Timber.d("doInBackgroundSaveModel");
Collection col = getCol();
Object[] args = param.getObjArray();
Model model = (Model) args[0];
ArrayList<Object[]> templateChanges = (ArrayList<Object[]>) args[1];
Model oldModel = col.getModels().get(model.getLong("id"));
// TODO need to save all the cards that will go away, for undo
// (do I need to remove them from graves during undo also?)
// - undo (except for cards) could just be Models.update(model) / Models.flush() / Collection.reset() (that was prior "undo")
JSONArray newTemplates = model.getJSONArray("tmpls");
col.getDb().getDatabase().beginTransaction();
try {
for (Object[] change : templateChanges) {
JSONArray oldTemplates = oldModel.getJSONArray("tmpls");
switch((TemporaryModel.ChangeType) change[1]) {
case ADD:
Timber.d("doInBackgroundSaveModel() adding template %s", change[0]);
try {
col.getModels().addTemplate(oldModel, newTemplates.getJSONObject((int) change[0]));
} catch (Exception e) {
Timber.e(e, "Unable to add template %s to model %s", change[0], model.getLong("id"));
return new TaskData(e.getLocalizedMessage(), false);
}
break;
case DELETE:
Timber.d("doInBackgroundSaveModel() deleting template currently at ordinal %s", change[0]);
try {
col.getModels().remTemplate(oldModel, oldTemplates.getJSONObject((int) change[0]));
} catch (Exception e) {
Timber.e(e, "Unable to delete template %s from model %s", change[0], model.getLong("id"));
return new TaskData(e.getLocalizedMessage(), false);
}
break;
default:
Timber.w("Unknown change type? %s", change[1]);
break;
}
}
col.getModels().save(model, true);
col.getModels().update(model);
col.reset();
col.save();
if (col.getDb().getDatabase().inTransaction()) {
col.getDb().getDatabase().setTransactionSuccessful();
} else {
Timber.i("CollectionTask::SaveModel was not in a transaction? Cannot mark transaction successful.");
}
} finally {
if (col.getDb().getDatabase().inTransaction()) {
col.getDb().getDatabase().endTransaction();
} else {
Timber.i("CollectionTask::SaveModel was not in a transaction? Cannot end transaction.");
}
}
return new TaskData(true);
}
use of com.ichi2.libanki.Model 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();
}
}
}
}
Aggregations