use of com.ichi2.libanki.utils.Time 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.utils.Time in project AnkiChinaAndroid by ankichinateam.
the class ModelFieldEditor method repositionFieldDialog.
/*
* Allows the user to select a number less than the number of fields in the current model to
* reposition the current field to
* Processing time is scales with number of items
*/
private void repositionFieldDialog() {
mFieldNameInput = new EditText(this);
mFieldNameInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
new MaterialDialog.Builder(this).title(String.format(getResources().getString(R.string.model_field_editor_reposition), 1, mFieldLabels.size())).positiveText(R.string.dialog_ok).customView(mFieldNameInput, true).onPositive((dialog, which) -> {
String newPosition = mFieldNameInput.getText().toString();
int pos;
try {
pos = Integer.parseInt(newPosition);
} catch (NumberFormatException n) {
UIUtils.showThemedToast(this, getResources().getString(R.string.toast_out_of_range), true);
return;
}
if (pos < 1 || pos > mFieldLabels.size()) {
UIUtils.showThemedToast(this, getResources().getString(R.string.toast_out_of_range), true);
} else {
changeHandler listener = changeFieldHandler();
// Input is valid, now attempt to modify
try {
mCol.modSchema();
CollectionTask.launchCollectionTask(REPOSITION_FIELD, listener, new TaskData(new Object[] { mMod, mNoteFields.getJSONObject(mCurrentPos), pos - 1 }));
} catch (ConfirmModSchemaException e) {
// Handle mod schema confirmation
ConfirmationDialog c = new ConfirmationDialog();
c.setArgs(getResources().getString(R.string.full_sync_confirmation));
Runnable confirm = () -> {
try {
mCol.modSchemaNoCheck();
String newPosition1 = mFieldNameInput.getText().toString();
int pos1 = Integer.parseInt(newPosition1);
CollectionTask.launchCollectionTask(REPOSITION_FIELD, listener, new TaskData(new Object[] { mMod, mNoteFields.getJSONObject(mCurrentPos), pos1 - 1 }));
dismissContextMenu();
} catch (JSONException e1) {
throw new RuntimeException(e1);
}
};
c.setConfirm(confirm);
c.setCancel(mConfirmDialogCancel);
ModelFieldEditor.this.showDialogFragment(c);
}
}
}).negativeText(R.string.dialog_cancel).show();
}
use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.
the class DatabaseErrorDialog method onCreateDialog.
@Override
public MaterialDialog onCreateDialog(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int mType = getArguments().getInt("dialogType");
Resources res = getResources();
MaterialDialog.Builder builder = new MaterialDialog.Builder(getActivity());
builder.cancelable(true).title(getTitle());
boolean sqliteInstalled = false;
try {
sqliteInstalled = Runtime.getRuntime().exec("sqlite3 --version").waitFor() == 0;
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
switch(mType) {
case DIALOG_LOAD_FAILED:
{
// the activity
return builder.cancelable(false).content(getMessage()).iconAttr(R.attr.dialogErrorIcon).positiveText(res.getString(R.string.error_handling_options)).negativeText(res.getString(R.string.close)).onPositive((inner_dialog, which) -> ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_ERROR_HANDLING)).onNegative((inner_dialog, which) -> exit()).show();
}
case DIALOG_DB_ERROR:
{
// Database Check failed to execute successfully; give user the option of either choosing from repair
// options, submitting an error report, or closing the activity
MaterialDialog dialog = builder.cancelable(false).content(getMessage()).iconAttr(R.attr.dialogErrorIcon).positiveText(res.getString(R.string.error_handling_options)).negativeText(res.getString(R.string.answering_error_report)).neutralText(res.getString(R.string.close)).onPositive((inner_dialog, which) -> ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_ERROR_HANDLING)).onNegative((inner_dialog, which) -> {
((DeckPicker) getActivity()).sendErrorReport();
dismissAllDialogFragments();
}).onNeutral((inner_dialog, which) -> exit()).show();
dialog.getCustomView().findViewById(R.id.md_buttonDefaultNegative).setEnabled(((DeckPicker) getActivity()).hasErrorFiles());
return dialog;
}
case DIALOG_ERROR_HANDLING:
{
// The user has asked to see repair options; allow them to choose one of the repair options or go back
// to the previous dialog
ArrayList<String> options = new ArrayList<>();
ArrayList<Integer> values = new ArrayList<>();
if (!((AnkiActivity) getActivity()).colIsOpen()) {
// retry
options.add(res.getString(R.string.backup_retry_opening));
values.add(0);
} else {
// fix integrity
options.add(res.getString(R.string.check_db));
values.add(1);
}
// repair db with sqlite
if (sqliteInstalled) {
options.add(res.getString(R.string.backup_error_menu_repair));
values.add(2);
}
// // restore from backup
options.add(res.getString(R.string.backup_restore));
values.add(3);
// delete old collection and build new one
options.add(res.getString(R.string.backup_full_sync_from_server));
values.add(4);
// delete old collection and build new one
options.add(res.getString(R.string.backup_del_collection));
values.add(5);
String[] titles = new String[options.size()];
mRepairValues = new int[options.size()];
for (int i = 0; i < options.size(); i++) {
titles[i] = options.get(i);
mRepairValues[i] = values.get(i);
}
return builder.iconAttr(R.attr.dialogErrorIcon).negativeText(res.getString(R.string.dialog_cancel)).items(titles).itemsCallback((materialDialog, view, which, charSequence) -> {
switch(mRepairValues[which]) {
case 0:
((DeckPicker) getActivity()).restartActivity();
return;
case 1:
((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_CONFIRM_DATABASE_CHECK);
return;
case 2:
((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_REPAIR_COLLECTION);
return;
case 3:
((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_RESTORE_BACKUP);
return;
case 4:
((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_FULL_SYNC_FROM_SERVER);
return;
case 5:
((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_NEW_COLLECTION);
return;
default:
throw new RuntimeException("Unknown dialog selection: " + mRepairValues[which]);
}
}).show();
}
case DIALOG_REPAIR_COLLECTION:
{
// Allow user to run BackupManager.repairCollection()
return builder.content(getMessage()).iconAttr(R.attr.dialogErrorIcon).positiveText(res.getString(R.string.dialog_positive_repair)).negativeText(res.getString(R.string.dialog_cancel)).onPositive((inner_dialog, which) -> {
((DeckPicker) getActivity()).repairCollection();
dismissAllDialogFragments();
}).show();
}
case DIALOG_RESTORE_BACKUP:
{
// Allow user to restore one of the backups
String path = CollectionHelper.getInstance().getCollectionPath(getActivity());
File[] files = BackupManager.getBackups(new File(path));
mBackups = new File[files.length];
for (int i = 0; i < files.length; i++) {
mBackups[i] = files[files.length - 1 - i];
}
if (mBackups.length == 0) {
builder.title(res.getString(R.string.backup_restore)).content(getMessage()).positiveText(res.getString(R.string.dialog_ok)).onPositive((inner_dialog, which) -> ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_ERROR_HANDLING));
} else {
String[] dates = new String[mBackups.length];
for (int i = 0; i < mBackups.length; i++) {
dates[i] = mBackups[i].getName().replaceAll(".*-(\\d{4}-\\d{2}-\\d{2})-(\\d{2})-(\\d{2}).apkg", "$1 ($2:$3 h)");
}
builder.title(res.getString(R.string.backup_restore_select_title)).negativeText(res.getString(R.string.dialog_cancel)).onNegative((inner_dialog, which) -> dismissAllDialogFragments()).items(dates).itemsCallbackSingleChoice(dates.length, (materialDialog, view, which, charSequence) -> {
if (mBackups[which].length() > 0) {
// restore the backup if it's valid
((DeckPicker) getActivity()).restoreFromBackup(mBackups[which].getPath());
dismissAllDialogFragments();
} else {
// otherwise show an error dialog
new MaterialDialog.Builder(getActivity()).title(R.string.backup_error).content(R.string.backup_invalid_file_error).positiveText(R.string.dialog_ok).build().show();
}
return true;
});
}
MaterialDialog materialDialog = builder.build();
materialDialog.setOnKeyListener((dialog, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Timber.i("DIALOG_RESTORE_BACKUP caught hardware back button");
dismissAllDialogFragments();
return true;
}
return false;
});
return materialDialog;
}
case DIALOG_NEW_COLLECTION:
{
// Allow user to create a new empty collection
return builder.content(getMessage()).positiveText(res.getString(R.string.dialog_positive_create)).negativeText(res.getString(R.string.dialog_cancel)).onPositive((inner_dialog, which) -> {
CollectionHelper ch = CollectionHelper.getInstance();
Time time = ch.getTimeSafe(getContext());
ch.closeCollection(false, "DatabaseErrorDialog: Before Create New Collection");
String path1 = CollectionHelper.getCollectionPath(getActivity());
if (BackupManager.moveDatabaseToBrokenFolder(path1, false, time)) {
((DeckPicker) getActivity()).restartActivity();
} else {
((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_LOAD_FAILED);
}
}).show();
}
case DIALOG_CONFIRM_DATABASE_CHECK:
{
// Confirmation dialog for database check
return builder.content(getMessage()).positiveText(res.getString(R.string.dialog_ok)).negativeText(res.getString(R.string.dialog_cancel)).onPositive((inner_dialog, which) -> {
((DeckPicker) getActivity()).integrityCheck();
dismissAllDialogFragments();
}).show();
}
case DIALOG_CONFIRM_RESTORE_BACKUP:
{
// Confirmation dialog for backup restore
return builder.content(getMessage()).positiveText(res.getString(R.string.dialog_continue)).negativeText(res.getString(R.string.dialog_cancel)).onPositive((inner_dialog, which) -> ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_RESTORE_BACKUP)).show();
}
case DIALOG_FULL_SYNC_FROM_SERVER:
{
// Allow user to do a full-sync from the server
return builder.content(getMessage()).positiveText(res.getString(R.string.dialog_positive_overwrite)).negativeText(res.getString(R.string.dialog_cancel)).onPositive((inner_dialog, which) -> {
((DeckPicker) getActivity()).sync("download");
dismissAllDialogFragments();
}).show();
}
case DIALOG_DB_LOCKED:
{
// If the database is locked, all we can do is ask the user to exit.
return builder.content(getMessage()).positiveText(res.getString(R.string.close)).cancelable(false).onPositive((inner_dialog, which) -> exit()).show();
}
default:
return null;
}
}
use of com.ichi2.libanki.utils.Time 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.utils.Time in project AnkiChinaAndroid by ankichinateam.
the class MultimediaEditFieldActivity method recreateEditingUi.
private void recreateEditingUi(ChangeUIRequest newUI, @Nullable Bundle savedInstanceState) {
Timber.d("recreateEditingUi()");
// Permissions are checked async, save our current state to allow continuation
mCurrentChangeRequest = newUI;
// As we only get here a second time if we have the required permissions
if (newUI.getRequiresPermissionCheck() && performPermissionRequest(newUI.getField())) {
newUI.markAsPermissionRequested();
return;
}
IControllerFactory controllerFactory = BasicControllerFactory.getInstance(getCol().getTime());
IFieldController fieldController = controllerFactory.createControllerForField(newUI.getField());
if (fieldController == null) {
Timber.w("Field controller creation failed");
UIRecreationHandler.onControllerCreationFailed(newUI, this);
return;
}
UIRecreationHandler.onPreFieldControllerReplacement(mFieldController);
mFieldController = fieldController;
mField = newUI.getField();
setupUIController(mFieldController, savedInstanceState);
LinearLayout linearLayout = findViewById(R.id.LinearLayoutInScrollViewFieldEdit);
linearLayout.removeAllViews();
mFieldController.createUI(this, linearLayout);
UIRecreationHandler.onPostUICreation(newUI, this);
}
Aggregations