Search in sources :

Example 1 with UNDO

use of com.ichi2.async.CollectionTask.TASK_TYPE.UNDO 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 2 with UNDO

use of com.ichi2.async.CollectionTask.TASK_TYPE.UNDO in project AnkiChinaAndroid by ankichinateam.

the class CardBrowser method onCreateOptionsMenu.

@Override
public boolean onCreateOptionsMenu(final Menu menu) {
    Timber.d("onCreateOptionsMenu()");
    mActionBarMenu = menu;
    if (!mInMultiSelectMode) {
        // restore drawer click listener and icon
        // restoreDrawerIcon();
        getMenuInflater().inflate(R.menu.card_browser, menu);
        mSaveSearchItem = menu.findItem(R.id.action_save_search);
        // the searchview's query always starts empty.
        mSaveSearchItem.setVisible(false);
        mMySearchesItem = menu.findItem(R.id.action_list_my_searches);
        JSONObject savedFiltersObj = getCol().getConf().optJSONObject("savedFilters");
        mMySearchesItem.setVisible(savedFiltersObj != null && savedFiltersObj.length() > 0);
        mSearchItem = menu.findItem(R.id.action_search);
        mSearchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {

            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                return true;
            }

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                // SearchView doesn't support empty queries so we always reset the search when collapsing
                mSearchTerms = "";
                mSearchView.setQuery(mSearchTerms, false);
                searchCards();
                // invalidate options menu so that disappeared icons would appear again
                supportInvalidateOptionsMenu();
                return true;
            }
        });
        mSearchView = (SearchView) mSearchItem.getActionView();
        mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override
            public boolean onQueryTextChange(String newText) {
                mSaveSearchItem.setVisible(!TextUtils.isEmpty(newText));
                return true;
            }

            @Override
            public boolean onQueryTextSubmit(String query) {
                onSearch();
                mSearchView.clearFocus();
                return true;
            }
        });
        mSearchView.setOnSearchClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // Provide SearchView with the previous search terms
                mSearchView.setQuery(mSearchTerms, false);
            }
        });
        // Fixes #6500 - keep the search consistent
        if (!TextUtils.isEmpty(mSearchTerms)) {
            mSearchItem.expandActionView();
            mSearchView.setQuery(mSearchTerms, false);
        }
    } else {
        // multi-select mode
        getMenuInflater().inflate(R.menu.card_browser_multiselect, menu);
    // showBackIcon();
    }
    if (mActionBarMenu != null && mActionBarMenu.findItem(R.id.action_undo) != null) {
        MenuItem undo = mActionBarMenu.findItem(R.id.action_undo);
        undo.setVisible(getCol().undoAvailable());
        undo.setTitle(getResources().getString(R.string.studyoptions_congrats_undo, getCol().undoName(getResources())));
    }
    // Maybe we were called from ACTION_PROCESS_TEXT.
    // In that case we already fill in the search.
    Intent intent = getIntent();
    Compat compat = CompatHelper.getCompat();
    if (intent.getAction() == compat.ACTION_PROCESS_TEXT) {
        CharSequence search = intent.getCharSequenceExtra(compat.EXTRA_PROCESS_TEXT);
        if (search != null && search.length() != 0) {
            Timber.i("CardBrowser :: Called with search intent: %s", search.toString());
            mSearchView.setQuery(search, true);
            intent.setAction(Intent.ACTION_DEFAULT);
        }
    }
    mPreviewItem = menu.findItem(R.id.action_preview);
    onSelectionChanged();
    updatePreviewMenuItem();
    return super.onCreateOptionsMenu(menu);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) SearchView(androidx.appcompat.widget.SearchView) Compat(com.ichi2.compat.Compat) MenuItem(android.view.MenuItem) Intent(android.content.Intent) View(android.view.View) AdapterView(android.widget.AdapterView) SearchView(androidx.appcompat.widget.SearchView) TextView(android.widget.TextView) ListView(android.widget.ListView) AbsListView(android.widget.AbsListView)

Example 3 with UNDO

use of com.ichi2.async.CollectionTask.TASK_TYPE.UNDO in project AnkiChinaAndroid by ankichinateam.

the class StudyOptionsFragment method handleDeckSelection.

private void handleDeckSelection(long did, boolean dontSkipStudyOptions) {
    // Clear the undo history when selecting a new deck
    if (getCol().getDecks().selected() != did) {
        getCol().clearUndo();
    }
    // Select the deck
    getCol().getDecks().select(did);
    // Also forget the last deck used by the Browser
    CardBrowser.clearLastDeckId();
    // Reset the schedule so that we get the counts for the currently selected deck
    mFocusedDeck = did;
    // Get some info about the deck to handle special cases
    int pos = mDeckListAdapter.findDeckPosition(did);
    AbstractDeckTreeNode deckDueTreeNode = mDeckListAdapter.getDeckList().get(pos);
    // if (!deckDueTreeNode.shouldDisplayCounts() || deckDueTreeNode.knownToHaveRep()) {
    // If we don't yet have numbers, we trust the user that they knows what they opens, tries to open it.
    // If there is nothing to review, it'll come back to deck picker.
    openReviewerOrStudyOptions(dontSkipStudyOptions);
// return;
// }
// There are numbers
// Figure out what action to take
// if (getCol().getSched().hasCardsTodayAfterStudyAheadLimit()) {
// // If there are cards due that can't be studied yet (due to the learn ahead limit) then go to study options
// openStudyOptions(false);
// } else if (getCol().getSched().newDue() || getCol().getSched().revDue()) {
// // If there are no cards to review because of the daily study limit then give "Study more" option
// UIUtils.showSnackbar(getAnkiActivity(), R.string.studyoptions_limit_reached, false, R.string.study_more, v -> {
// CustomStudyDialog d = CustomStudyDialog.newInstance(
// CustomStudyDialog.CONTEXT_MENU_LIMITS,
// getCol().getDecks().selected(), true, this);
// showDialogFragment(d);
// }, getView().findViewById(R.id.root_layout), mSnackbarShowHideCallback);
// // Check if we need to update the fragment or update the deck list. The same checks
// // are required for all snackbars below.
// if (mFragmented) {
// // Tablets must always show the study options that corresponds to the current deck,
// // regardless of whether the deck is currently reviewable or not.
// openStudyOptions(false);
// } else {
// // On phones, we update the deck list to ensure the currently selected deck is
// // highlighted correctly.
// updateDeckList();
// }
// } else if (getCol().getDecks().isDyn(did)) {
// // Go to the study options screen if filtered deck with no cards to study
// openStudyOptions(false);
// } else if (!deckDueTreeNode.hasChildren() && getCol().cardCount(new Long[] {did}) == 0) {
// // If the deck is empty and has no children then show a message saying it's empty
// final Uri helpUrl = Uri.parse(getResources().getString(R.string.link_manual_getting_started));
// getAnkiActivity().mayOpenUrl(helpUrl);
// UIUtils.showSnackbar(getAnkiActivity(), R.string.empty_deck, false, R.string.help,
// v -> openHelpUrl(helpUrl), getView().findViewById(R.id.root_layout), mSnackbarShowHideCallback);
// if (mFragmented) {
// openStudyOptions(false);
// } else {
// updateDeckList();
// }
// } else {
// // Otherwise say there are no cards scheduled to study, and give option to do custom study
// UIUtils.showSnackbar(getAnkiActivity(), R.string.studyoptions_empty_schedule, false, R.string.custom_study, v -> {
// CustomStudyDialog d = CustomStudyDialog.newInstance(
// CustomStudyDialog.CONTEXT_MENU_EMPTY_SCHEDULE,
// getCol().getDecks().selected(), true, this);
// showDialogFragment(d);
// }, getView().findViewById(R.id.root_layout), mSnackbarShowHideCallback);
// if (mFragmented) {
// openStudyOptions(false);
// } else {
// updateDeckList();
// }
// }
}
Also used : AbstractDeckTreeNode(com.ichi2.libanki.sched.AbstractDeckTreeNode)

Example 4 with UNDO

use of com.ichi2.async.CollectionTask.TASK_TYPE.UNDO in project AnkiChinaAndroid by ankichinateam.

the class StudyOptionsFragment method configureToolbarInternal.

// This will allow a maximum of one recur in order to workaround database closes
// caused by sync on startup where this might be running then have the collection close
private void configureToolbarInternal(boolean recur) {
    try {
        mToolbar.setOnMenuItemClickListener(this);
        Menu menu = mToolbar.getMenu();
        // Switch on or off rebuild/empty/custom study depending on whether or not filtered deck
        if (getCol().getDecks().isDyn(getCol().getDecks().selected())) {
            menu.findItem(R.id.action_add_card).setVisible(false);
            menu.findItem(R.id.action_rebuild).setVisible(true);
            menu.findItem(R.id.action_empty).setVisible(true);
            menu.findItem(R.id.action_custom_study).setVisible(false);
            menu.findItem(R.id.action_rename).setVisible(false);
            menu.findItem(R.id.create_deck).setVisible(false);
            menu.findItem(R.id.action_suspend).setVisible(false);
            menu.findItem(R.id.action_reset_card_progress).setVisible(false);
            menu.findItem(R.id.action_delete).setVisible(false);
            menu.findItem(R.id.action_export).setVisible(false);
            menu.findItem(R.id.action_setting).setVisible(false);
        } else {
            menu.findItem(R.id.action_rebuild).setVisible(false);
            menu.findItem(R.id.action_empty).setVisible(false);
            menu.findItem(R.id.action_custom_study).setVisible(true);
            menu.findItem(R.id.action_rename).setVisible(true);
            menu.findItem(R.id.create_deck).setVisible(true);
            menu.findItem(R.id.action_suspend).setVisible(true);
            menu.findItem(R.id.action_suspend).setTitle(deckIsStopped() ? "恢复学习" : "停止学习");
            menu.findItem(R.id.action_reset_card_progress).setVisible(true);
            menu.findItem(R.id.action_delete).setVisible(true);
            menu.findItem(R.id.action_export).setVisible(true);
            menu.findItem(R.id.action_setting).setVisible(true);
            menu.findItem(R.id.action_deck_options).setVisible(true);
        }
        // Don't show custom study icon if congrats shown
        // if (mCurrentContentView == CONTENT_CONGRATS) {
        // menu.findItem(R.id.action_custom_study).setVisible(false);
        // }
        // Switch on or off unbury depending on if there are cards to unbury
        menu.findItem(R.id.action_unbury).setVisible(getCol().getSched().haveBuried());
        // Switch on or off undo depending on whether undo is available
        menu.findItem(R.id.action_undo).setVisible(false);
    } catch (IllegalStateException e) {
        if (!CollectionHelper.getInstance().colIsOpen()) {
            if (recur) {
                Timber.i(e, "Database closed while working. Probably auto-sync. Will re-try after sleep.");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Timber.i(ex, "Thread interrupted while waiting to retry. Likely unimportant.");
                    Thread.currentThread().interrupt();
                }
                configureToolbarInternal(false);
            } else {
                Timber.w(e, "Database closed while working. No re-tries left.");
            }
        }
    }
}
Also used : DeckPickerContextMenu(com.ichi2.anki.dialogs.DeckPickerContextMenu) Menu(android.view.Menu)

Example 5 with UNDO

use of com.ichi2.async.CollectionTask.TASK_TYPE.UNDO in project AnkiChinaAndroid by ankichinateam.

the class SelfStudyActivity method onActivityResult.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // FIXME:
    Timber.d("onActivityResult(requestCode=%d, resultCode=%d)", requestCode, resultCode);
    if (data != null) {
        Timber.d("onActivityResult data (reloadRequired=%s, noteChanged=%s)", data.getBooleanExtra("reloadRequired", false), data.getBooleanExtra("noteChanged", false));
    }
    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");
        }
    }
    // }
    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)

Aggregations

Collection (com.ichi2.libanki.Collection)22 Card (com.ichi2.libanki.Card)15 JSONObject (com.ichi2.utils.JSONObject)13 Intent (android.content.Intent)8 JSONException (com.ichi2.utils.JSONException)7 ArrayList (java.util.ArrayList)7 MenuItem (android.view.MenuItem)6 View (android.view.View)6 VisibleForTesting (androidx.annotation.VisibleForTesting)6 Context (android.content.Context)5 SharedPreferences (android.content.SharedPreferences)5 Bundle (android.os.Bundle)5 Menu (android.view.Menu)5 WindowManager (android.view.WindowManager)5 TextView (android.widget.TextView)5 NonNull (androidx.annotation.NonNull)5 Nullable (androidx.annotation.Nullable)5 SearchView (androidx.appcompat.widget.SearchView)5 MaterialDialog (com.afollestad.materialdialogs.MaterialDialog)5 Snackbar (com.google.android.material.snackbar.Snackbar)5