Search in sources :

Example 1 with Time

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);
    }
}
Also used : Window(android.view.Window) SharedPreferences(android.content.SharedPreferences) Matcher(java.util.regex.Matcher) IOException(java.io.IOException) SuppressLint(android.annotation.SuppressLint) JSONException(com.ichi2.utils.JSONException) IOException(java.io.IOException) ActivityNotFoundException(android.content.ActivityNotFoundException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) JSONObject(com.ichi2.utils.JSONObject) TypedArray(android.content.res.TypedArray) FileOutputStream(java.io.FileOutputStream) File(java.io.File)

Example 2 with Time

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();
}
Also used : EditText(android.widget.EditText) JSONException(com.ichi2.utils.JSONException) TaskData(com.ichi2.async.TaskData) ConfirmationDialog(com.ichi2.anki.dialogs.ConfirmationDialog) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) JSONObject(com.ichi2.utils.JSONObject)

Example 3 with Time

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;
    }
}
Also used : DeckPicker(com.ichi2.anki.DeckPicker) Bundle(android.os.Bundle) KeyEvent(android.view.KeyEvent) BackupManager(com.ichi2.anki.BackupManager) R(com.ichi2.anki.R) IOException(java.io.IOException) Time(com.ichi2.libanki.utils.Time) CollectionHelper(com.ichi2.anki.CollectionHelper) File(java.io.File) Timber(timber.log.Timber) ArrayList(java.util.ArrayList) AnkiActivity(com.ichi2.anki.AnkiActivity) Message(android.os.Message) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) Resources(android.content.res.Resources) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) ArrayList(java.util.ArrayList) Time(com.ichi2.libanki.utils.Time) IOException(java.io.IOException) AnkiActivity(com.ichi2.anki.AnkiActivity) Resources(android.content.res.Resources) CollectionHelper(com.ichi2.anki.CollectionHelper) DeckPicker(com.ichi2.anki.DeckPicker) File(java.io.File)

Example 4 with Time

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();
            }
        }
    };
}
Also used : Deck(com.ichi2.libanki.Deck) TaskData(com.ichi2.async.TaskData) TaskListener(com.ichi2.async.TaskListener)

Example 5 with Time

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);
}
Also used : IControllerFactory(com.ichi2.anki.multimediacard.fields.IControllerFactory) IFieldController(com.ichi2.anki.multimediacard.fields.IFieldController) LinearLayout(android.widget.LinearLayout)

Aggregations

Test (org.junit.Test)27 Collection (com.ichi2.libanki.Collection)26 JSONObject (com.ichi2.utils.JSONObject)26 RobolectricTest (com.ichi2.anki.RobolectricTest)19 Card (com.ichi2.libanki.Card)19 Note (com.ichi2.libanki.Note)15 JSONArray (com.ichi2.utils.JSONArray)15 Deck (com.ichi2.libanki.Deck)11 ArrayList (java.util.ArrayList)11 DeckConfig (com.ichi2.libanki.DeckConfig)10 IOException (java.io.IOException)10 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)9 HashMap (java.util.HashMap)9 Cursor (android.database.Cursor)8 Nullable (androidx.annotation.Nullable)8 JSONException (com.ichi2.utils.JSONException)8 SharedPreferences (android.content.SharedPreferences)7 Resources (android.content.res.Resources)7 File (java.io.File)7 View (android.view.View)5