Search in sources :

Example 41 with Time

use of com.ichi2.libanki.utils.Time in project Anki-Android by Ramblurr.

the class Feedback method postFeedback.

/**
 * Posting feedback or error info to the server. This is called from the AsyncTask.
 *
 * @param url The url to post the feedback to.
 * @param type The type of the info, eg Feedback.TYPE_CRASH_STACKTRACE.
 * @param feedback For feedback types this is the message. For error/crash types this is the path to the error file.
 * @param groupId A single time generated ID, so that errors/feedback send together can be grouped together.
 * @param index The index of the error in the list
 * @return A Payload file showing success, response code and response message.
 */
public static Payload postFeedback(String url, String type, String feedback, String groupId, int index, Application app) {
    Payload result = new Payload(null);
    List<NameValuePair> pairs = null;
    if (!isErrorType(type)) {
        pairs = new ArrayList<NameValuePair>();
        pairs.add(new BasicNameValuePair("type", type));
        pairs.add(new BasicNameValuePair("groupid", groupId));
        pairs.add(new BasicNameValuePair("index", "0"));
        pairs.add(new BasicNameValuePair("message", feedback));
        addTimestamp(pairs);
    } else {
        pairs = Feedback.extractPairsFromError(type, feedback, groupId, index, app);
        if (pairs == null) {
            result.success = false;
            result.result = null;
        }
    }
    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(url);
    httpPost.addHeader("User-Agent", "AnkiDroid");
    try {
        httpPost.setEntity(new UrlEncodedFormEntity(pairs));
        HttpResponse response = httpClient.execute(httpPost);
        Log.e(AnkiDroidApp.TAG, String.format("Bug report posted to %s", url));
        int respCode = response.getStatusLine().getStatusCode();
        switch(respCode) {
            case 200:
                result.success = true;
                result.returnType = respCode;
                result.result = Utils.convertStreamToString(response.getEntity().getContent());
                // Log.i(AnkiDroidApp.TAG, String.format("postFeedback OK: %s", result.result));
                break;
            default:
                Log.e(AnkiDroidApp.TAG, String.format("postFeedback failure: %d - %s", response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()));
                result.success = false;
                result.returnType = respCode;
                result.result = response.getStatusLine().getReasonPhrase();
                break;
        }
    } catch (ClientProtocolException ex) {
        Log.e(AnkiDroidApp.TAG, "ClientProtocolException: " + ex.toString());
        result.success = false;
        result.result = ex.toString();
    } catch (IOException ex) {
        Log.e(AnkiDroidApp.TAG, "IOException: " + ex.toString());
        result.success = false;
        result.result = ex.toString();
    }
    return result;
}
Also used : BasicNameValuePair(org.apache.http.message.BasicNameValuePair) NameValuePair(org.apache.http.NameValuePair) HttpPost(org.apache.http.client.methods.HttpPost) HttpResponse(org.apache.http.HttpResponse) UrlEncodedFormEntity(org.apache.http.client.entity.UrlEncodedFormEntity) IOException(java.io.IOException) DefaultHttpClient(org.apache.http.impl.client.DefaultHttpClient) ClientProtocolException(org.apache.http.client.ClientProtocolException) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) DefaultHttpClient(org.apache.http.impl.client.DefaultHttpClient) HttpClient(org.apache.http.client.HttpClient) Payload(com.ichi2.async.Connection.Payload)

Example 42 with Time

use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.

the class StudyOptionsFragment method configMaxDayLearnAndRev.

private void configMaxDayLearnAndRev() {
    CustomStyleDialog customDialog = new CustomStyleDialog.Builder(getAnkiActivity()).setTitle("设置每天学习量").setCustomLayout(R.layout.dialog_common_custom_next).setMultiEditorModeCallback(new CustomStyleDialog.Builder.MultiEditorModeCallback() {

        @Override
        public String[] getEditorText() {
            // return new String[] {mOptions.getJSONObject("new").getString("perDay"), mOptions.getJSONObject("rev").getString("perDay"),};
            return new String[] { "30", "200" };
        }

        @Override
        public String[] getEditorHint() {
            return new String[] { "每天新卡上限", "每天复习上限" };
        }

        @Override
        public String[] getItemHint() {
            return new String[] { "学习一段时间后,未来每天新卡+复习卡约180张,大约需30分钟", "建议设置为最大9999,有多少复习多少" };
        }
    }).addSingleTextChangedListener(new CustomStyleDialog.Builder.MyTextWatcher() {

        @Override
        public void beforeTextChanged(Dialog dialog, CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(Dialog dialog, CharSequence s, int start, int before, int count) {
            if (s.toString().isEmpty()) {
                ((CustomStyleDialog) dialog).getSingleEditorModeHintView().setText("未来每天学习量=新卡数x6");
            } else {
                int num = 0;
                try {
                    num = Integer.parseInt(s.toString()) * 6;
                } catch (Exception ignored) {
                }
                int time = num * 10 / 60;
                ((CustomStyleDialog) dialog).getSingleEditorModeHintView().setText(String.format("学习一段时间后,未来每天新卡+复习卡约%s张,大约需%s分钟", num, time));
            }
        }

        @Override
        public void afterTextChanged(Dialog dialog, Editable s) {
        }
    }).setPositiveButton("进入学习", (dialog, which) -> {
        String text1 = ((CustomStyleDialog) dialog).getMultiEditor().get(0).getText().toString();
        String text2 = ((CustomStyleDialog) dialog).getMultiEditor().get(1).getText().toString();
        int maxNewCard = 0;
        int maxRevCard = 0;
        try {
            maxNewCard = Integer.parseInt(text1);
        } catch (Exception ignored) {
        }
        try {
            maxRevCard = Integer.parseInt(text2);
        } catch (Exception ignored) {
        }
        if (maxNewCard >= 0 && maxNewCard <= 9999 && maxRevCard >= 0 && maxRevCard <= 9999) {
            mOptions.getJSONObject("new").put("perDay", maxNewCard);
            mOptions.getJSONObject("rev").put("perDay", maxRevCard);
            Timber.i("edit new and rev max:" + maxNewCard + "," + maxRevCard);
            try {
                getCol().getDecks().save(mOptions);
            } catch (RuntimeException e) {
                Timber.e(e, "DeckOptions - RuntimeException on saving conf");
                AnkiDroidApp.sendExceptionReport(e, "DeckOptionsSaveConf");
            }
            refreshOption();
            dialog.dismiss();
            openReviewerInternal();
        } else {
            UIUtils.showThemedToast(getAnkiActivity(), "请填写0至9999之间的数值", false);
        }
    }).setNegativeButton("跳过", (dialog, which) -> {
        dialog.dismiss();
        try {
            getCol().getDecks().save(mOptions);
        } catch (RuntimeException e) {
            Timber.e(e, "DeckOptions - RuntimeException on saving conf");
            AnkiDroidApp.sendExceptionReport(e, "DeckOptionsSaveConf");
        }
        refreshOption();
        openReviewerInternal();
    }).create();
    customDialog.show();
}
Also used : DividerItemDecoration(androidx.recyclerview.widget.DividerItemDecoration) Bundle(android.os.Bundle) TypeToken(com.google.gson.reflect.TypeToken) Deck(com.ichi2.libanki.Deck) NonNull(androidx.annotation.NonNull) Uri(android.net.Uri) WindowManager(android.view.WindowManager) ImageView(android.widget.ImageView) ColorDrawable(android.graphics.drawable.ColorDrawable) Drawable(android.graphics.drawable.Drawable) Maps(java8.util.Maps) KEY_STOPPED(com.ichi2.anki.StudySettingActivity.KEY_STOPPED) DeckInfoListAdapter(com.ichi2.anki.widgets.DeckInfoListAdapter) Decks(com.ichi2.libanki.Decks) Gson(com.google.gson.Gson) Locale(java.util.Locale) Handler(android.os.Handler) DeckConfig(com.ichi2.libanki.DeckConfig) Map(java.util.Map) Fragment(androidx.fragment.app.Fragment) View(android.view.View) Button(android.widget.Button) TaskData(com.ichi2.async.TaskData) RecyclerView(androidx.recyclerview.widget.RecyclerView) REQUEST_BROWSE_CARDS(com.ichi2.anki.DeckPicker.REQUEST_BROWSE_CARDS) TabLayout(com.google.android.material.tabs.TabLayout) TYPE_LIFE(com.ichi2.libanki.stats.Stats.AxisType.TYPE_LIFE) SHOW_STUDYOPTIONS(com.ichi2.anki.DeckPicker.SHOW_STUDYOPTIONS) Set(java.util.Set) FragmentTransaction(androidx.fragment.app.FragmentTransaction) DisplayMetrics(android.util.DisplayMetrics) ViewGroup(android.view.ViewGroup) Timber(timber.log.Timber) DeckPickerContextMenu(com.ichi2.anki.dialogs.DeckPickerContextMenu) List(java.util.List) Nullable(androidx.annotation.Nullable) TextView(android.widget.TextView) NextCardHandler(com.ichi2.anki.AbstractFlashcardViewer.NextCardHandler) ALL_DECKS_ID(com.ichi2.libanki.stats.Stats.ALL_DECKS_ID) CompatHelper(com.ichi2.compat.CompatHelper) Toolbar(androidx.appcompat.widget.Toolbar) RelativeLayout(android.widget.RelativeLayout) TaskListenerWithContext(com.ichi2.async.TaskListenerWithContext) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) Window(android.view.Window) Snackbar(com.google.android.material.snackbar.Snackbar) DialogFragment(androidx.fragment.app.DialogFragment) KEY_SHOW_TTS_ICON(com.ichi2.libanki.Consts.KEY_SHOW_TTS_ICON) Context(android.content.Context) TaskListener(com.ichi2.async.TaskListener) Dialog(android.app.Dialog) Intent(android.content.Intent) StepsPreference.convertToJSON(com.ichi2.preferences.StepsPreference.convertToJSON) HashMap(java.util.HashMap) Collection(com.ichi2.libanki.Collection) StyledProgressDialog(com.ichi2.themes.StyledProgressDialog) PixelFormat(android.graphics.PixelFormat) Editable(android.text.Editable) TypedArray(android.content.res.TypedArray) MenuItem(android.view.MenuItem) TASK_TYPE(com.ichi2.async.CollectionTask.TASK_TYPE) ArrayList(java.util.ArrayList) JSONArray(com.ichi2.utils.JSONArray) Menu(android.view.Menu) Utils(com.ichi2.libanki.Utils) AbstractDeckTreeNode(com.ichi2.libanki.sched.AbstractDeckTreeNode) Stats(com.ichi2.libanki.stats.Stats) LayoutInflater(android.view.LayoutInflater) CollectionTask(com.ichi2.async.CollectionTask) Color(android.graphics.Color) Gravity(android.view.Gravity) SharedPreferences(android.content.SharedPreferences) TypedValue(android.util.TypedValue) TreeMap(java.util.TreeMap) KEY_MIND_MODE(com.ichi2.anki.StudySettingActivity.KEY_MIND_MODE) CustomStudyDialog(com.ichi2.anki.dialogs.CustomStudyDialog) DeckPicker.fadeOut(com.ichi2.anki.DeckPicker.fadeOut) Activity(android.app.Activity) ActivityTransitionAnimation(com.ichi2.anim.ActivityTransitionAnimation) DeckPicker.fadeIn(com.ichi2.anki.DeckPicker.fadeIn) STUDY_SETTING(com.ichi2.anki.StudySettingActivity.STUDY_SETTING) EditText(android.widget.EditText) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) Resources(android.content.res.Resources) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) Dialog(android.app.Dialog) StyledProgressDialog(com.ichi2.themes.StyledProgressDialog) CustomStudyDialog(com.ichi2.anki.dialogs.CustomStudyDialog) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) Editable(android.text.Editable)

Example 43 with Time

use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.

the class ReadText method initializeTts.

public static String initializeTts(Context context, boolean vipSpeak, boolean showToast, ReadTextListener listener) {
    // Store weak reference to Activity to prevent memory leak
    mReviewer = new WeakReference<>(context);
    // Create new TTS object and setup its onInit Listener
    mTts = new TextToSpeech(context, status -> {
        if (status == TextToSpeech.SUCCESS) {
            // build list of available languages
            buildAvailableLanguages(TextToSpeech.LANG_AVAILABLE);
            if (availableTtsLocales.size() > 0) {
                // notify the reviewer that TTS has been initialized
                Timber.d("TTS initialized and available languages found");
                if (listener != null) {
                    listener.ttsInitialized();
                }
            // ((AbstractFlashcardViewer) mReviewer.get()).ttsInitialized();
            } else {
                if (showToast) {
                    Toast.makeText(mReviewer.get(), mReviewer.get().getString(R.string.no_tts_available_message), Toast.LENGTH_LONG).show();
                }
                Timber.w("TTS initialized but no available languages found");
            }
            mTts.setOnUtteranceProgressListener(new UtteranceProgressListener() {

                @Override
                public void onDone(String arg0) {
                    if (ReadText.sTextQueue.size() > 0) {
                        String[] text = ReadText.sTextQueue.remove(0);
                        ReadText.speak(text[0], text[1], TextToSpeech.QUEUE_FLUSH);
                    }
                    if (listener != null) {
                        listener.onDone();
                    }
                }

                @Override
                @Deprecated
                public void onError(String utteranceId) {
                    Timber.v("Andoid TTS failed. Check logcat for error. Indicates a problem with Android TTS engine.");
                    final Uri helpUrl = Uri.parse(mReviewer.get().getString(R.string.link_faq_tts));
                    final AnkiActivity ankiActivity = (AnkiActivity) mReviewer.get();
                    ankiActivity.mayOpenUrl(helpUrl);
                    if (showToast) {
                        UIUtils.showSnackbar(ankiActivity, R.string.no_tts_available_message, false, R.string.help, v -> openTtsHelpUrl(helpUrl), ankiActivity.findViewById(R.id.root_layout), new Snackbar.Callback());
                    }
                }

                @Override
                public void onStart(String arg0) {
                // no nothing
                }
            });
        } else {
            if (showToast) {
                Toast.makeText(mReviewer.get(), mReviewer.get().getString(R.string.no_tts_available_message), Toast.LENGTH_LONG).show();
            }
            Timber.w("TTS not successfully initialized");
        }
    });
    // Show toast that it's getting initialized, as it can take a while before the sound plays the first time
    if (showToast) {
        Toast.makeText(context, context.getString(R.string.initializing_tts), Toast.LENGTH_LONG).show();
    }
    return mTts.getDefaultEngine();
}
Also used : Context(android.content.Context) NonNull(androidx.annotation.NonNull) Uri(android.net.Uri) WindowManager(android.view.WindowManager) UtteranceProgressListener(android.speech.tts.UtteranceProgressListener) Compat(com.ichi2.compat.Compat) Timber(timber.log.Timber) ArrayList(java.util.ArrayList) TextToSpeech(android.speech.tts.TextToSpeech) Nullable(androidx.annotation.Nullable) Locale(java.util.Locale) Handler(android.os.Handler) Toast(android.widget.Toast) CompatHelper(com.ichi2.compat.CompatHelper) View(android.view.View) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) WeakReference(java.lang.ref.WeakReference) Snackbar(com.google.android.material.snackbar.Snackbar) VisibleForTesting(androidx.annotation.VisibleForTesting) Sound(com.ichi2.libanki.Sound) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) Resources(android.content.res.Resources) UtteranceProgressListener(android.speech.tts.UtteranceProgressListener) TextToSpeech(android.speech.tts.TextToSpeech) Uri(android.net.Uri) Snackbar(com.google.android.material.snackbar.Snackbar)

Example 44 with Time

use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.

the class StudySettingActivity method onClick.

@Override
public void onClick(View v) {
    int id = v.getId();
    CustomStyleDialog customDialog = null;
    switch(id) {
        case R.id.rl_max_learn_card:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("每日新卡上限").setEditorText(tx_max_learn_card.getText().toString(), "学习一段时间后,未来每天新卡+复习卡约180张,大约需30分钟").addSingleTextChangedListener(new CustomStyleDialog.Builder.MyTextWatcher() {

                @Override
                public void beforeTextChanged(Dialog dialog, CharSequence s, int start, int count, int after) {
                }

                @Override
                public void onTextChanged(Dialog dialog, CharSequence s, int start, int before, int count) {
                    if (s.toString().isEmpty()) {
                        ((CustomStyleDialog) dialog).getSingleEditorModeHintView().setText("未来每天学习量=新卡数x6");
                    } else {
                        try {
                            int num = Integer.parseInt(s.toString()) * 6;
                            int time = num * 10 / 60;
                            ((CustomStyleDialog) dialog).getSingleEditorModeHintView().setText(String.format("学习一段时间后,未来每天新卡+复习卡约%s张,大约需%s分钟", num, time));
                        } catch (Exception e) {
                            e.printStackTrace();
                            UIUtils.showThemedToast(StudySettingActivity.this, "请填写0至9999之间的数值", false);
                        }
                    }
                }

                @Override
                public void afterTextChanged(Dialog dialog, Editable s) {
                }
            }).setPositiveButton("确认", (dialog, which) -> {
                try {
                    int num = Integer.parseInt(((CustomStyleDialog) dialog).getEditorText());
                    Timber.i("edit num:%s", num);
                    if (num >= 0 && num <= 9999) {
                        mOptions.getJSONObject("new").put("perDay", num);
                        saveAndUpdateValues();
                        dialog.dismiss();
                    } else {
                        UIUtils.showThemedToast(this, "请填写0至9999之间的数值", false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    UIUtils.showThemedToast(this, "请填写0至9999之间的数值", false);
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_max_review_card:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("每日复习数上限").setEditorText(tx_max_review_card.getText().toString(), "建议设置为最大9999,有多少复习多少").setPositiveButton("确认", (dialog, which) -> {
                try {
                    int num = Integer.parseInt(((CustomStyleDialog) dialog).getEditorText());
                    Timber.i("edit num:%s", num);
                    if (num >= 0 && num <= 9999) {
                        mOptions.getJSONObject("rev").put("perDay", num);
                        saveAndUpdateValues();
                        dialog.dismiss();
                    } else {
                        UIUtils.showThemedToast(this, "请填写0至9999之间的数值", false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    UIUtils.showThemedToast(this, "请填写0至9999之间的数值", false);
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_deck_conf_max_ivl:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("最大时间间隔").setEditorText(tx_max_review_card.getText().toString(), "").setPositiveButton("确认", (dialog, which) -> {
                try {
                    int num = Integer.parseInt(((CustomStyleDialog) dialog).getEditorText());
                    Timber.i("edit num:%s", num);
                    if (num >= 0 && num <= 99999) {
                        mOptions.getJSONObject("rev").put("maxIvl", num);
                        saveAndUpdateValues();
                        dialog.dismiss();
                    } else {
                        UIUtils.showThemedToast(this, "请填写0至99999之间的数值", false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    UIUtils.showThemedToast(this, "请填写0至99999之间的数值", false);
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_interval_step:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("间隔的步伐(以分钟计)").setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_CLASS_TEXT).setEditorText(tx_interval_step.getText().toString(), "").setPositiveButton("确认", (dialog, which) -> {
                String num = ((CustomStyleDialog) dialog).getEditorText();
                String validated = getValidatedStepsInput(num);
                if (validated == null) {
                    UIUtils.showThemedToast(this, getResources().getString(R.string.steps_error), false);
                } else if (TextUtils.isEmpty(validated)) {
                    UIUtils.showThemedToast(this, getResources().getString(R.string.steps_min_error), false);
                } else {
                    mOptions.getJSONObject("new").put("delays", convertToJSON(num));
                    saveAndUpdateValues();
                    Timber.i("edit num:%s", num);
                    dialog.dismiss();
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_interval_graduate:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("毕业时间间隔(以天计)").setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_CLASS_TEXT).setEditorText(tx_interval_graduate.getText().toString(), "").setPositiveButton("确认", (dialog, which) -> {
                try {
                    int num = Integer.parseInt(((CustomStyleDialog) dialog).getEditorText());
                    Timber.i("edit num:%s", num);
                    if (num >= 1 && num <= 99) {
                        // [graduating, easy]
                        JSONArray newInts = new JSONArray();
                        newInts.put(num);
                        newInts.put(mOptions.getJSONObject("new").getJSONArray("ints").getInt(1));
                        mOptions.getJSONObject("new").put("ints", newInts);
                        saveAndUpdateValues();
                        dialog.dismiss();
                    } else {
                        UIUtils.showThemedToast(this, "请填写1至99之间的数值", false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    UIUtils.showThemedToast(this, "请填写1至99之间的数值", false);
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_interval_simple:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("简单按钮对应的时间间隔").setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_CLASS_TEXT).setEditorText(tx_interval_simple.getText().toString(), "").setPositiveButton("确认", (dialog, which) -> {
                try {
                    int num = Integer.parseInt(((CustomStyleDialog) dialog).getEditorText());
                    Timber.i("edit num:%s", num);
                    if (num >= 1 && num <= 99) {
                        JSONArray newInts = new JSONArray();
                        // 
                        newInts.put(mOptions.getJSONObject("new").getJSONArray("ints").getInt(0));
                        newInts.put(num);
                        mOptions.getJSONObject("new").put("ints", newInts);
                        saveAndUpdateValues();
                        dialog.dismiss();
                    } else {
                        UIUtils.showThemedToast(this, "请填写1至99之间的数值", false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    UIUtils.showThemedToast(this, "请填写1至99之间的数值", false);
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_init_level:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("初始难度").setEditorText(tx_init_level.getText().toString(), "").setPositiveButton("确认", (dialog, which) -> {
                try {
                    int num = Integer.parseInt(((CustomStyleDialog) dialog).getEditorText());
                    Timber.i("edit num:%s", num);
                    if (num >= 100 && num <= 999) {
                        mOptions.getJSONObject("new").put("initialFactor", num * 10);
                        saveAndUpdateValues();
                        dialog.dismiss();
                    } else {
                        UIUtils.showThemedToast(this, "请填写100至999之间的数值", false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    UIUtils.showThemedToast(this, "请填写1至99之间的数值", false);
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_new_card_sequence:
            final int[] selectPosition = { mCurrentNewOrderValue };
            customDialog = new CustomStyleDialog.Builder(this).setTitle("新卡顺序").setSelectListModeCallback(new CustomStyleDialog.Builder.SelectListModeCallback() {

                @Override
                public String[] getItemContent() {
                    return mNewOrderLabels;
                }

                @Override
                public String[] getItemHint() {
                    return new String[0];
                }

                @Override
                public int getDefaultSelectedPosition() {
                    return selectPosition[0];
                }

                @Override
                public void onItemSelect(int position) {
                    selectPosition[0] = position;
                }
            }).setPositiveButton("确认", (dialog, which) -> {
                int oldValue = mOptions.getJSONObject("new").getInt("order");
                if (oldValue != selectPosition[0]) {
                    mOptions.getJSONObject("new").put("order", selectPosition[0]);
                    CollectionTask.launchCollectionTask(REORDER, new ConfChangeHandler(StudySettingActivity.this), new TaskData(new Object[] { mOptions }));
                }
                dialog.dismiss();
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            customDialog.show();
            break;
        case R.id.rl_learn_sequence:
            final int[] selectPosition3 = { mCurrentStudyPreferenceValue };
            customDialog = new CustomStyleDialog.Builder(this).setTitle("学习顺序").setSelectListModeCallback(new CustomStyleDialog.Builder.SelectListModeCallback() {

                @Override
                public String[] getItemContent() {
                    return mStudyPreferenceLabels;
                }

                @Override
                public String[] getItemHint() {
                    return new String[0];
                }

                @Override
                public int getDefaultSelectedPosition() {
                    return selectPosition3[0];
                }

                @Override
                public void onItemSelect(int position) {
                    selectPosition3[0] = position;
                }
            }).setPositiveButton("确认", (dialog, which) -> {
                int oldValue = mCol.getConf().getInt("newSpread");
                if (oldValue != selectPosition3[0]) {
                    mCol.getConf().put("newSpread", selectPosition3[0]);
                    mCol.setMod();
                    CollectionTask.launchCollectionTask(REORDER, new ConfChangeHandler(StudySettingActivity.this), new TaskData(new Object[] { mOptions }));
                }
                dialog.dismiss();
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            customDialog.show();
            break;
        case R.id.rl_medal_simple:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("回答简单的时间间隔增加比例").setEditorText(tx_medal_simple.getText().toString(), "").setPositiveButton("确认", (dialog, which) -> {
                try {
                    int num = Integer.parseInt(((CustomStyleDialog) dialog).getEditorText());
                    Timber.i("edit num:%s", num);
                    if (num >= 100 && num <= 1000) {
                        mOptions.getJSONObject("rev").put("ease4", (Integer) num / 100.0f);
                        saveAndUpdateValues();
                        dialog.dismiss();
                    } else {
                        UIUtils.showThemedToast(this, "请填写100至1000之间的数值", false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    UIUtils.showThemedToast(this, "请填写100至1000之间的数值", false);
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_interval_decoration:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("时间间隔因子").setEditorText(tx_interval_decoration.getText().toString(), "").setPositiveButton("确认", (dialog, which) -> {
                try {
                    int num = Integer.parseInt(((CustomStyleDialog) dialog).getEditorText());
                    Timber.i("edit num: " + num / 100.0f);
                    if (num >= 0 && num <= 999) {
                        mOptions.getJSONObject("rev").put("ivlFct", num / 100.0f);
                        saveAndUpdateValues();
                        dialog.dismiss();
                    } else {
                        UIUtils.showThemedToast(this, "请填写0至999之间的数值", false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    UIUtils.showThemedToast(this, "请填写0至999之间的数值", false);
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_error_interval_step:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("间隔的步伐(以分钟计)").setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_CLASS_TEXT).setEditorText(tx_error_interval_step.getText().toString(), "").setPositiveButton("确认", (dialog, which) -> {
                String num = ((CustomStyleDialog) dialog).getEditorText();
                String validated = getValidatedStepsInput(num);
                if (validated == null) {
                    UIUtils.showThemedToast(this, getResources().getString(R.string.steps_error), false);
                } else {
                    mOptions.getJSONObject("lapse").put("delays", StepsPreference.convertToJSON(num));
                    saveAndUpdateValues();
                    Timber.i("edit num:%s", num);
                    dialog.dismiss();
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_error_new_interval:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("新的时间间隔").setEditorText(tx_error_new_interval.getText().toString(), "").setPositiveButton("确认", (dialog, which) -> {
                try {
                    int num = Integer.parseInt(((CustomStyleDialog) dialog).getEditorText());
                    Timber.i("edit num:%s", num);
                    if (num >= 0 && num <= 100) {
                        mOptions.getJSONObject("lapse").put("mult", num / 100.0f);
                        saveAndUpdateValues();
                        dialog.dismiss();
                    } else {
                        UIUtils.showThemedToast(this, "请填写0至100之间的数值", false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    UIUtils.showThemedToast(this, "请填写0至100之间的数值", false);
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.rl_error_min_interval:
            customDialog = new CustomStyleDialog.Builder(this).setTitle("最小时间间隔(天)").setEditorText(tx_error_min_interval.getText().toString(), "").setPositiveButton("确认", (dialog, which) -> {
                try {
                    int num = Integer.parseInt(((CustomStyleDialog) dialog).getEditorText());
                    Timber.i("edit num:%s", num);
                    if (num >= 1 && num <= 99) {
                        mOptions.getJSONObject("lapse").put("minInt", num);
                        saveAndUpdateValues();
                        dialog.dismiss();
                    } else {
                        UIUtils.showThemedToast(this, "请填写1至99之间的数值", false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    UIUtils.showThemedToast(this, "请填写1至99之间的数值", false);
                }
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            Timber.i("build a dialog!");
            customDialog.show();
            break;
        case R.id.ll_algorithm:
            final int[] selectPosition4 = { mCurrentMindModeValue };
            customDialog = new CustomStyleDialog.Builder(this).setTitle("选择记忆模式").setSelectListModeCallback(new CustomStyleDialog.Builder.SelectListModeCallback() {

                @Override
                public String[] getItemContent() {
                    return mMindModeLabels;
                }

                @Override
                public String[] getItemHint() {
                    return mMindModeHints;
                }

                @Override
                public int getDefaultSelectedPosition() {
                    return selectPosition4[0];
                }

                @Override
                public void onItemSelect(int position) {
                    selectPosition4[0] = position;
                }
            }).setPositiveButton("确认", (dialog, which) -> {
                SharedPreferences sharedPreferences = getSharedPreferences(STUDY_SETTING, 0);
                String oldValue = sharedPreferences.getString(KEY_MIND_MODE, "");
                // Timber.i("看看保存成什么样子了 %s ", oldValue);
                Map<String, Integer> oldMap = null;
                Gson gson = new Gson();
                try {
                    oldMap = gson.fromJson(oldValue, Map.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (oldMap == null) {
                    oldMap = new HashMap<>();
                }
                for (long did : getDeckIds(mDeckId, getCol())) {
                    // Timber.i("看看都是什么id %s,%s", did, selectPosition4[0]);
                    oldMap.put(String.valueOf(did), selectPosition4[0]);
                }
                String newValue = gson.toJson(oldMap);
                sharedPreferences.edit().putString(KEY_MIND_MODE, newValue).apply();
                mSavedMaxNewCardNum = mOptions.getJSONObject("new").getInt("perDay");
                mSavedMaxRevCardNum = mOptions.getJSONObject("rev").getInt("perDay");
                CollectionTask.launchCollectionTask(CONF_RESET, new ConfChangeHandler(StudySettingActivity.this, selectPosition4[0]), // 先恢复默认,即长记模式
                new TaskData(new Object[] { mOptions }));
                dialog.dismiss();
            }).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
            customDialog.show();
            break;
    }
}
Also used : LinearLayout(android.widget.LinearLayout) Bundle(android.os.Bundle) KeyEvent(android.view.KeyEvent) TypeToken(com.google.gson.reflect.TypeToken) Deck(com.ichi2.libanki.Deck) NonNull(androidx.annotation.NonNull) Dialog(android.app.Dialog) HashMap(java.util.HashMap) StepsPreference.convertToJSON(com.ichi2.preferences.StepsPreference.convertToJSON) Collection(com.ichi2.libanki.Collection) Editable(android.text.Editable) TypedArray(android.content.res.TypedArray) JSONArray(com.ichi2.utils.JSONArray) StepsPreference(com.ichi2.preferences.StepsPreference) Gson(com.google.gson.Gson) DeckConfig(com.ichi2.libanki.DeckConfig) Map(java.util.Map) View(android.view.View) TaskData(com.ichi2.async.TaskData) ContextCompat(androidx.core.content.ContextCompat) REORDER(com.ichi2.async.CollectionTask.TASK_TYPE.REORDER) InputType(android.text.InputType) TextUtils(android.text.TextUtils) CollectionTask(com.ichi2.async.CollectionTask) JSONObject(com.ichi2.utils.JSONObject) Timber(timber.log.Timber) StudyOptionsFragment.getDeckIds(com.ichi2.anki.StudyOptionsFragment.getDeckIds) IdRes(androidx.annotation.IdRes) CONF_RESET(com.ichi2.async.CollectionTask.TASK_TYPE.CONF_RESET) TextView(android.widget.TextView) SharedPreferences(android.content.SharedPreferences) RelativeLayout(android.widget.RelativeLayout) Toolbar(androidx.appcompat.widget.Toolbar) TaskListenerWithContext(com.ichi2.async.TaskListenerWithContext) ActivityTransitionAnimation(com.ichi2.anim.ActivityTransitionAnimation) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) SharedPreferences(android.content.SharedPreferences) HashMap(java.util.HashMap) JSONArray(com.ichi2.utils.JSONArray) Gson(com.google.gson.Gson) TaskData(com.ichi2.async.TaskData) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) Dialog(android.app.Dialog) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) Editable(android.text.Editable) HashMap(java.util.HashMap) Map(java.util.Map)

Example 45 with Time

use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.

the class ModelFieldEditor method renameFieldDialog.

/*
     * Creates a dialog to rename the currently selected field
     * Processing time is constant
     */
private void renameFieldDialog() {
    mFieldNameInput = new EditText(this);
    mFieldNameInput.setSingleLine(true);
    mFieldNameInput.setText(mFieldLabels.get(mCurrentPos));
    mFieldNameInput.setSelection(mFieldNameInput.getText().length());
    new MaterialDialog.Builder(this).title(R.string.rename_model).positiveText(R.string.rename).customView(mFieldNameInput, true).onPositive((dialog, which) -> {
        String fieldLabel = mFieldNameInput.getText().toString().replaceAll("[\\n\\r]", "");
        if (fieldLabel.length() == 0) {
            UIUtils.showThemedToast(this, getResources().getString(R.string.toast_empty_name), true);
        } else if (containsField(fieldLabel)) {
            UIUtils.showThemedToast(this, getResources().getString(R.string.toast_duplicate_field), true);
        } else {
            // Field is valid, now rename
            try {
                renameField();
            } catch (ConfirmModSchemaException e) {
                // Handler mod schema confirmation
                ConfirmationDialog c = new ConfirmationDialog();
                c.setArgs(getResources().getString(R.string.full_sync_confirmation));
                Runnable confirm = () -> {
                    mCol.modSchemaNoCheck();
                    try {
                        renameField();
                    } catch (ConfirmModSchemaException e1) {
                    // This should never be thrown
                    }
                    dismissContextMenu();
                };
                c.setConfirm(confirm);
                c.setCancel(mConfirmDialogCancel);
                ModelFieldEditor.this.showDialogFragment(c);
            }
        }
    }).negativeText(R.string.dialog_cancel).show();
}
Also used : EditText(android.widget.EditText) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) ConfirmationDialog(com.ichi2.anki.dialogs.ConfirmationDialog)

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