use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.
the class AbstractFlashcardViewer method updateCard.
private void updateCard(final String newContent) {
Timber.d("updateCard()");
mCacheContent = newContent;
mUseTimerDynamicMS = 0;
// Add CSS for font color and font size
if (mCurrentCard == null) {
processCardAction(cardWebView -> cardWebView.getSettings().setDefaultFontSize(calculateDynamicFontSize(newContent)));
}
if (sDisplayAnswer) {
addAnswerSounds(newContent);
} else {
// reset sounds each time first side of card is displayed, which may happen repeatedly without ever
// leaving the card (such as when edited)
mSoundPlayer.resetSounds();
mAnswerSoundsAdded = false;
mSoundPlayer.addSounds(mBaseUrl, newContent, SoundSide.QUESTION);
if (mUseTimer && !mAnswerSoundsAdded && getConfigForCurrentCard().optBoolean("autoplay", false)) {
addAnswerSounds(mCurrentCard.a());
}
}
String content = Sound.expandSounds(mBaseUrl, newContent);
content = CardAppearance.fixBoldStyle(content);
Timber.v("content card = \n %s", content);
String style = mCardAppearance.getStyle();
Timber.v("::style:: / %s", style);
// CSS class for card-specific styling
String cardClass = mCardAppearance.getCardClass(mCurrentCard.getOrd() + 1, Themes.getCurrentTheme(this));
if (Template.textContainsMathjax(content)) {
cardClass += " mathjax-needs-to-render";
}
if (isInNightMode()) {
if (!mCardAppearance.hasUserDefinedNightMode(mCurrentCard)) {
content = HtmlColors.invertColors(content);
}
}
content = CardAppearance.convertSmpToHtmlEntity(content);
SharedPreferences prefs = AnkiDroidApp.getSharedPrefs(this);
String localViewSettingStr = prefs.getString(Consts.KEY_LOCAL_LAYOUT_CONFIG, "");
boolean dark = false;
if (AnkiDroidApp.getSharedPrefs(this).getBoolean("invertedColors", false)) {
int theme = Integer.parseInt(prefs.getString("nightTheme", "0"));
dark = theme == THEME_NIGHT_DARK || theme == THEME_NIGHT_BLACK;
}
if (mCurrentCSS.isEmpty() || mCurrentCSSModelID != mCurrentCard.model().getLong("id")) {
mCurrentCSSModelID = mCurrentCard.model().getLong("id");
Timber.i("find new model id css %s", mCurrentCSS);
if (localViewSettingStr != null && !localViewSettingStr.isEmpty()) {
try {
JSONObject viewSetting = new JSONObject(localViewSettingStr);
JSONObject currentModelSetting = viewSetting.getJSONObject(String.valueOf(mCurrentCSSModelID));
if (currentModelSetting != null) {
mCurrentCSS = convertJson2Css(currentModelSetting, false);
} else {
mCurrentCSS = "";
}
} catch (Exception e) {
e.printStackTrace();
mCurrentCSS = "";
}
}
}
Timber.i("now theme is dark:%s", dark);
if (!dark) {
if (!mCurrentCSS.isEmpty()) {
Matcher bgMatcher = Pattern.compile("background-color:(.+?);").matcher(mCurrentCSS);
Window window = getWindow();
if (bgMatcher.find()) {
String fld1 = bgMatcher.group(1).trim();
if (shouldChangeToolbarBgLikeCss2()) {
findViewById(R.id.toolbar).setBackgroundColor(Color.parseColor(fld1));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setStatusBarColor(Color.parseColor(fld1));
}
}
mCardWebView.setBackgroundColor(Color.parseColor(fld1));
findViewById(R.id.bottom_area_layout).setBackgroundColor(Color.parseColor(fld1));
} else {
if (shouldChangeToolbarBgLikeCss2()) {
int[] attrs = new int[] { R.attr.reviewStatusBarColor };
TypedArray ta = obtainStyledAttributes(attrs);
findViewById(R.id.toolbar).setBackground(ta.getDrawable(0));
ta.recycle();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setStatusBarColor(Themes.getColorFromAttr(this, getStatusBarColorAttr()));
}
}
mCardWebView.setBackgroundColor(Color.WHITE);
findViewById(R.id.bottom_area_layout).setBackgroundColor(Color.TRANSPARENT);
}
} else {
if (shouldChangeToolbarBgLikeCss2()) {
int[] attrs = new int[] { R.attr.reviewStatusBarColor };
TypedArray ta = obtainStyledAttributes(attrs);
findViewById(R.id.toolbar).setBackground(ta.getDrawable(0));
ta.recycle();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.setStatusBarColor(Themes.getColorFromAttr(this, getStatusBarColorAttr()));
}
}
mCardWebView.setBackgroundColor(Color.WHITE);
findViewById(R.id.bottom_area_layout).setBackgroundColor(Color.TRANSPARENT);
}
}
// if (mCurrentCSS.isEmpty()) {//保存的配置文件没有,则直接找默认的css
// mCurrentCSS = mCurrentCard.css().replace("<style>", "").replace("</style>", "");
// }
mCardContent = mCardTemplate.replace("::content::", content).replace("::style::", style).replace("::class::", cardClass).replace("::style2::", mCurrentCSS).replace("::class2::", sDisplayAnswer ? "ck-back" : "ck-front");
Timber.d("base url = %s", mBaseUrl);
Timber.v("::content:: / %s", content);
Timber.v("::style2:: / %s", mCurrentCSS);
if (AnkiDroidApp.getSharedPrefs(this).getBoolean("html_javascript_debugging", false)) {
try {
try (FileOutputStream f = new FileOutputStream(new File(CollectionHelper.getCurrentAnkiDroidDirectory(this), "card.html"))) {
f.write(mCardContent.getBytes());
}
} catch (IOException e) {
Timber.d(e, "failed to save card");
}
}
fillFlashcard();
if (!mConfigurationChanged) {
playSoundsVIP(false);
}
}
use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.
the class AbstractFlashcardViewer method getAnswerFormat.
/**
* getAnswerFormat returns the answer part of this card's template as entered by user, without any parsing
*/
public String getAnswerFormat() {
JSONObject model = mCurrentCard.model();
JSONObject template;
if (model.getInt("type") == Consts.MODEL_STD) {
template = model.getJSONArray("tmpls").getJSONObject(mCurrentCard.getOrd());
} else {
template = model.getJSONArray("tmpls").getJSONObject(0);
}
return template.getString("afmt");
}
use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.
the class ContentProviderTest method testInsertAndRemoveNote.
/**
* Check that inserting and removing a note into default deck works as expected
*/
@Test
public void testInsertAndRemoveNote() {
// Get required objects for test
final ContentResolver cr = InstrumentationRegistry.getInstrumentation().getTargetContext().getContentResolver();
// Add the note
ContentValues values = new ContentValues();
values.put(FlashCardsContract.Note.MID, mModelId);
values.put(FlashCardsContract.Note.FLDS, Utils.joinFields(TEST_NOTE_FIELDS));
values.put(FlashCardsContract.Note.TAGS, TEST_TAG);
Uri newNoteUri = cr.insert(FlashCardsContract.Note.CONTENT_URI, values);
assertNotNull("Check that URI returned from addNewNote is not null", newNoteUri);
// test that the changes are physically saved to the DB
final Collection col = reopenCol();
// Check that it looks as expected
assertNotNull("check note URI path", newNoteUri.getLastPathSegment());
Note addedNote = new Note(col, Long.parseLong(newNoteUri.getLastPathSegment()));
addedNote.load();
assertArrayEquals("Check that fields were set correctly", addedNote.getFields(), TEST_NOTE_FIELDS);
assertEquals("Check that tag was set correctly", TEST_TAG, addedNote.getTags().get(0));
JSONObject model = col.getModels().get(mModelId);
assertNotNull("Check model", model);
int expectedNumCards = model.getJSONArray("tmpls").length();
assertEquals("Check that correct number of cards generated", expectedNumCards, addedNote.numberOfCards());
// Now delete the note
cr.delete(newNoteUri, null, null);
try {
addedNote.load();
fail("Expected RuntimeException to be thrown when deleting note");
} catch (RuntimeException e) {
// Expect RuntimeException to be thrown when loading deleted note
}
}
use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.
the class ContentProviderTest method setUp.
/**
* Initially create one note for each model.
*/
@Before
public void setUp() throws Exception {
Log.i(AnkiDroidApp.TAG, "setUp()");
mCreatedNotes = new ArrayList<>();
final Collection col = getCol();
// We have parameterized the "schedVersion" variable, if we are on an emulator
// (so it is safe) we will try to run with multiple scheduler versions
tearDown = false;
if (InstrumentedTest.isEmulator()) {
col.changeSchedulerVer(schedVersion);
} else {
if (schedVersion == 1) {
assumeThat(col.getSched().getName(), is("std"));
} else {
assumeThat(col.getSched().getName(), is("std2"));
}
}
tearDown = true;
// Do not teardown if setup was aborted
// Add a new basic model that we use for testing purposes (existing models could potentially be corrupted)
Model model = StdModels.basicModel.add(col, BASIC_MODEL_NAME);
mModelId = model.getLong("id");
ArrayList<String> fields = Models.fieldNames(model);
// Use the names of the fields as test values for the notes which will be added
mDummyFields = fields.toArray(new String[0]);
// create test decks and add one note for every deck
mNumDecksBeforeTest = col.getDecks().count();
for (String fullName : TEST_DECKS) {
String[] path = Decks.path(fullName);
String partialName = "";
/* Looping over all parents of full name. Adding them to
* mTestDeckIds ensures the deck parents decks get deleted
* too at tear-down.
*/
for (String s : path) {
partialName += s;
/* If parent already exists, don't add the deck, so
* that we are sure it won't get deleted at
* set-down, */
if (col.getDecks().byName(partialName) != null) {
continue;
}
long did = col.getDecks().id(partialName);
mTestDeckIds.add(did);
mCreatedNotes.add(setupNewNote(col, mModelId, did, mDummyFields, TEST_TAG));
partialName += "::";
}
}
// Add a note to the default deck as well so that testQueryNextCard() works
mCreatedNotes.add(setupNewNote(col, mModelId, 1, mDummyFields, TEST_TAG));
}
use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.
the class ContentProviderTest method testInsertField.
/**
* Check that inserting and removing a note into default deck works as expected
*/
@Test
public void testInsertField() throws Exception {
// Get required objects for test
final ContentResolver cr = InstrumentationRegistry.getInstrumentation().getTargetContext().getContentResolver();
Collection col = getCol();
Model model = StdModels.basicModel.add(col, BASIC_MODEL_NAME);
long modelId = model.getLong("id");
JSONArray initialFieldsArr = model.getJSONArray("flds");
int initialFieldCount = initialFieldsArr.length();
Uri noteTypeUri = ContentUris.withAppendedId(FlashCardsContract.Model.CONTENT_URI, modelId);
ContentValues insertFieldValues = new ContentValues();
insertFieldValues.put(FlashCardsContract.Model.FIELD_NAME, TEST_FIELD_NAME);
Uri fieldUri = cr.insert(Uri.withAppendedPath(noteTypeUri, "fields"), insertFieldValues);
assertNotNull("Check field uri", fieldUri);
// Ensure that the changes are physically saved to the DB
col = reopenCol();
model = col.getModels().get(modelId);
// Test the field is as expected
long fieldId = ContentUris.parseId(fieldUri);
assertEquals("Check field id", initialFieldCount, fieldId);
assertNotNull("Check model", model);
JSONArray fldsArr = model.getJSONArray("flds");
assertEquals("Check fields length", initialFieldCount + 1, fldsArr.length());
assertEquals("Check last field name", TEST_FIELD_NAME, fldsArr.getJSONObject(fldsArr.length() - 1).optString("name", ""));
col.getModels().rem(model);
}
Aggregations