Search in sources :

Example 1 with CardBrowser

use of com.ichi2.anki.CardBrowser in project AnkiChinaAndroid by ankichinateam.

the class AnkiDroidApp method onCreate.

/**
 * On application creation.
 */
@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(activityLifecycleCallbacks);
    if (sInstance != null) {
        Timber.i("onCreate() called multiple times");
        // 5887 - fix crash.
        if (sInstance.getResources() == null) {
            Timber.w("Skipping re-initialisation - no resources. Maybe uninstalling app?");
            return;
        }
    }
    sInstance = this;
    // Get preferences
    SharedPreferences preferences = getSharedPrefs(this);
    Consts.LOGIN_SERVER = preferences.getInt(Consts.KEY_ANKI_ACCOUNT_SERVER, 0);
    // Setup logging and crash reporting
    acraCoreConfigBuilder = new CoreConfigurationBuilder(this);
    if (BuildConfig.DEBUG) {
        // Enable verbose error logging and do method tracing to put the Class name as log tag
        Timber.plant(new DebugTree());
        setDebugACRAConfig(preferences);
    } else {
        Timber.plant(new ProductionCrashReportingTree());
        setProductionACRAConfig(preferences);
    }
    Timber.tag(TAG);
    Timber.d("Startup - Application Start");
    // Analytics falls back to a sensible default if this is not set.
    if (ACRA.isACRASenderServiceProcess() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        try {
            WebViewDebugging.setDataDirectorySuffix("acra");
        } catch (Exception e) {
            Timber.w(e, "Failed to set WebView data directory");
        }
    }
    // analytics after ACRA, they both install UncaughtExceptionHandlers but Analytics chains while ACRA does not
    UsageAnalytics.initialize(this);
    if (BuildConfig.DEBUG) {
        UsageAnalytics.setDryRun(true);
    }
    // Stop after analytics and logging are initialised.
    if (ACRA.isACRASenderServiceProcess()) {
        Timber.d("Skipping AnkiDroidApp.onCreate from ACRA sender process");
        return;
    }
    if (AdaptionUtil.isUserATestClient()) {
        UIUtils.showThemedToast(this.getApplicationContext(), getString(R.string.user_is_a_robot), false);
    }
    CardBrowserContextMenu.ensureConsistentStateWithSharedPreferences(this);
    AnkiCardContextMenu.ensureConsistentStateWithSharedPreferences(this);
    NotificationChannels.setup(getApplicationContext());
    // Configure WebView to allow file scheme pages to access cookies.
    CookieManager.setAcceptFileSchemeCookies(true);
    // Prepare Cookies to be synchronized between RAM and permanent storage.
    CompatHelper.getCompat().prepareWebViewCookies(this.getApplicationContext());
    // Set good default values for swipe detection
    final ViewConfiguration vc = ViewConfiguration.get(this);
    DEFAULT_SWIPE_MIN_DISTANCE = vc.getScaledPagingTouchSlop();
    DEFAULT_SWIPE_THRESHOLD_VELOCITY = vc.getScaledMinimumFlingVelocity();
    // Forget the last deck that was used in the CardBrowser
    CardBrowser.clearLastDeckId();
    // Create the AnkiDroid directory if missing. Send exception report if inaccessible.
    if (Permissions.hasStorageAccessPermission(this)) {
        try {
            String dir = CollectionHelper.getCurrentAnkiDroidDirectory(this);
            CollectionHelper.initializeAnkiDroidDirectory(dir);
        } catch (StorageAccessException e) {
            Timber.e(e, "Could not initialize AnkiDroid directory");
            String defaultDir = CollectionHelper.getDefaultAnkiDroidDirectory();
            if (isSdCardMounted() && CollectionHelper.getCurrentAnkiDroidDirectory(this).equals(defaultDir)) {
                // Don't send report if the user is using a custom directory as SD cards trip up here a lot
                sendExceptionReport(e, "AnkiDroidApp.onCreate");
            }
        }
    }
    Timber.i("AnkiDroidApp: Starting Services");
    new BootService().onReceive(this, new Intent(this, BootService.class));
    // Register BroadcastReceiver NotificationService
    NotificationService ns = new NotificationService();
    LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
    lbm.registerReceiver(ns, new IntentFilter(NotificationService.INTENT_ACTION));
}
Also used : IntentFilter(android.content.IntentFilter) SharedPreferences(android.content.SharedPreferences) StorageAccessException(com.ichi2.anki.exception.StorageAccessException) Intent(android.content.Intent) NotificationService(com.ichi2.anki.services.NotificationService) LocalBroadcastManager(androidx.localbroadcastmanager.content.LocalBroadcastManager) ManuallyReportedException(com.ichi2.anki.exception.ManuallyReportedException) StorageAccessException(com.ichi2.anki.exception.StorageAccessException) CoreConfigurationBuilder(org.acra.config.CoreConfigurationBuilder) DebugTree(timber.log.Timber.DebugTree) ViewConfiguration(android.view.ViewConfiguration) BootService(com.ichi2.anki.services.BootService)

Example 2 with CardBrowser

use of com.ichi2.anki.CardBrowser 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 3 with CardBrowser

use of com.ichi2.anki.CardBrowser 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 4 with CardBrowser

use of com.ichi2.anki.CardBrowser 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)

Example 5 with CardBrowser

use of com.ichi2.anki.CardBrowser in project AnkiChinaAndroid by ankichinateam.

the class CardBrowserTest method tagWithBracketsDisplaysProperly.

@Test
public void tagWithBracketsDisplaysProperly() {
    Note n = addNoteUsingBasicModel("Hello", "World");
    n.addTag("sketchy::(1)");
    n.flush();
    CardBrowser b = getBrowserWithNoNewCards();
    b.filterByTag("sketchy::(1)");
    assertThat("tagged card should be returned", b.getCardCount(), is(1));
}
Also used : Note(com.ichi2.libanki.Note) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)16 Intent (android.content.Intent)9 Deck (com.ichi2.libanki.Deck)9 Note (com.ichi2.libanki.Note)7 Card (com.ichi2.libanki.Card)6 MenuItem (android.view.MenuItem)5 CollectionTask (com.ichi2.async.CollectionTask)5 JSONObject (com.ichi2.utils.JSONObject)5 HashSet (java.util.HashSet)5 IntentFilter (android.content.IntentFilter)4 SharedPreferences (android.content.SharedPreferences)4 View (android.view.View)4 AdapterView (android.widget.AdapterView)4 SearchView (androidx.appcompat.widget.SearchView)4 Bundle (android.os.Bundle)3 ListView (android.widget.ListView)3 TextView (android.widget.TextView)3 IntegerDialog (com.ichi2.anki.dialogs.IntegerDialog)3 SimpleMessageDialog (com.ichi2.anki.dialogs.SimpleMessageDialog)3 Consts (com.ichi2.libanki.Consts)3