Search in sources :

Example 6 with TaskData

use of com.ichi2.async.TaskData 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 7 with TaskData

use of com.ichi2.async.TaskData in project AnkiChinaAndroid by ankichinateam.

the class CardBrowser method onActivityResult.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // FIXME:
    Timber.d("onActivityResult(requestCode=%d, resultCode=%d)", requestCode, resultCode);
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == DeckPicker.RESULT_DB_ERROR) {
        closeCardBrowser(DeckPicker.RESULT_DB_ERROR);
    }
    if (requestCode == EDIT_CARD && resultCode != RESULT_CANCELED) {
        Timber.i("CardBrowser:: CardBrowser: Saving card...");
        CollectionTask.launchCollectionTask(UPDATE_NOTE, updateCardHandler(), new TaskData(sCardBrowserCard, false));
    } else if (requestCode == ADD_NOTE && resultCode == RESULT_OK) {
        if (mSearchView != null) {
            mSearchTerms = mSearchView.getQuery().toString();
            searchCards();
        } else {
            Timber.w("Note was added from browser and on return mSearchView == null");
        }
    }
    // Previewing can now perform an "edit", so it can pass on a reloadRequired
    if (requestCode == PREVIEW_CARDS && data != null && (data.getBooleanExtra("reloadRequired", false) || data.getBooleanExtra("noteChanged", false))) {
        searchCards();
        if (getReviewerCardId() == mCurrentCardId) {
            mReloadRequired = true;
        }
    }
    if (requestCode == EDIT_CARD && data != null && (data.getBooleanExtra("reloadRequired", false) || data.getBooleanExtra("noteChanged", false))) {
        // if reloadRequired or noteChanged flag was sent from note editor then reload card list
        searchCards();
        // in use by reviewer?
        if (getReviewerCardId() == mCurrentCardId) {
            mReloadRequired = true;
        }
    }
    // maybe the availability of undo changed
    invalidateOptionsMenu();
}
Also used : TaskData(com.ichi2.async.TaskData)

Example 8 with TaskData

use of com.ichi2.async.TaskData in project AnkiChinaAndroid by ankichinateam.

the class CardBrowser method updateMultiselectMenu.

private void updateMultiselectMenu() {
    Timber.d("updateMultiselectMenu()");
    if (mActionBarMenu == null || mActionBarMenu.findItem(R.id.action_suspend_card) == null) {
        return;
    }
    if (!mCheckedCards.isEmpty()) {
        CollectionTask.cancelAllTasks(CHECK_CARD_SELECTION);
        CollectionTask.launchCollectionTask(CHECK_CARD_SELECTION, mCheckSelectedCardsHandler, new TaskData(new Object[] { mCheckedCards, getCards() }));
    }
    mActionBarMenu.findItem(R.id.action_select_all).setVisible(!hasSelectedAllCards());
    // Note: Theoretically should not happen, as this should kick us back to the menu
    mActionBarMenu.findItem(R.id.action_select_none).setVisible(hasSelectedCards());
    mActionBarMenu.findItem(R.id.action_edit_note).setVisible(canPerformMultiSelectEditNote());
}
Also used : JSONObject(com.ichi2.utils.JSONObject) TaskData(com.ichi2.async.TaskData)

Example 9 with TaskData

use of com.ichi2.async.TaskData in project AnkiChinaAndroid by ankichinateam.

the class CardBrowser method executeChangeCollectionTask.

@VisibleForTesting(otherwise = VisibleForTesting.NONE)
// should only be called from changeDeck()
void executeChangeCollectionTask(long[] ids, long newDid) {
    // line required for unit tests, not necessary, but a noop in regular call.
    mNewDid = newDid;
    CollectionTask.launchCollectionTask(DISMISS_MULTI, new ChangeDeckHandler(this), new TaskData(new Object[] { ids, Collection.DismissType.CHANGE_DECK_MULTI, newDid }));
}
Also used : JSONObject(com.ichi2.utils.JSONObject) TaskData(com.ichi2.async.TaskData) VisibleForTesting(androidx.annotation.VisibleForTesting)

Example 10 with TaskData

use of com.ichi2.async.TaskData 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)

Aggregations

Collection (com.ichi2.libanki.Collection)67 TaskData (com.ichi2.async.TaskData)46 JSONObject (com.ichi2.utils.JSONObject)35 Card (com.ichi2.libanki.Card)16 JSONException (com.ichi2.utils.JSONException)15 ArrayList (java.util.ArrayList)14 JSONObject (org.json.JSONObject)13 Resources (android.content.res.Resources)12 HashMap (java.util.HashMap)12 SharedPreferences (android.content.SharedPreferences)11 Deck (com.ichi2.libanki.Deck)11 Intent (android.content.Intent)10 View (android.view.View)9 TextView (android.widget.TextView)9 ConfirmationDialog (com.ichi2.anki.dialogs.ConfirmationDialog)9 TaskListener (com.ichi2.async.TaskListener)9 Map (java.util.Map)9 VisibleForTesting (androidx.annotation.VisibleForTesting)8 CollectionTask (com.ichi2.async.CollectionTask)8 IOException (java.io.IOException)8