Search in sources :

Example 16 with CREATED

use of com.ichi2.anki.CardBrowser.Column.CREATED in project Anki-Android by ankidroid.

the class DeckOptionsTest method changeHardFactor.

@Test
public void changeHardFactor() {
    Collection col = getCol();
    // Verify that for newly created deck hardFactor is default.
    double hardFactor = col.get_config("hardFactor", 1.2);
    Assert.assertEquals(1.2, hardFactor, 0.01);
    // Modify hard factor.
    col.set_config("hardFactor", 1.0);
    // Verify that hardFactor value has changed.
    hardFactor = col.get_config("hardFactor", 1.2);
    Assert.assertEquals(1.0, hardFactor, 0.01);
}
Also used : Collection(com.ichi2.libanki.Collection) Test(org.junit.Test)

Example 17 with CREATED

use of com.ichi2.anki.CardBrowser.Column.CREATED in project Anki-Android by ankidroid.

the class CardContentProvider method insertMediaFile.

private Uri insertMediaFile(ContentValues values, Collection col) {
    // Insert media file using libanki.Media.addFile and return Uri for the inserted file.
    Uri fileUri = Uri.parse(values.getAsString(FlashCardsContract.AnkiMedia.FILE_URI));
    String preferredName = values.getAsString(FlashCardsContract.AnkiMedia.PREFERRED_NAME);
    try {
        ContentResolver cR = mContext.getContentResolver();
        Media media = col.getMedia();
        // idea, open input stream and save to cache directory, then
        // pass this (hopefully temporary) file to the media.addFile function.
        // return eg "jpeg"
        String fileMimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType(cR.getType(fileUri));
        // should we be enforcing strict mimetypes? which types?
        File tempFile;
        File externalCacheDir = mContext.getExternalCacheDir();
        if (externalCacheDir == null) {
            Timber.e("createUI() unable to get external cache directory");
            return null;
        }
        File tempMediaDir = new File(externalCacheDir.getAbsolutePath() + "/temp-media");
        if (!tempMediaDir.exists() && !tempMediaDir.mkdir()) {
            Timber.e("temp-media dir did not exist and could not be created");
            return null;
        }
        try {
            tempFile = File.createTempFile(// the beginning of the filename.
            preferredName + "_", // this is the extension, if null, '.tmp' is used, need to get the extension from MIME type?
            "." + fileMimeType, tempMediaDir);
            tempFile.deleteOnExit();
        } catch (Exception e) {
            Timber.w(e, "Could not create temporary media file. ");
            return null;
        }
        FileUtil.internalizeUri(fileUri, tempFile, cR);
        String fname = media.addFile(tempFile);
        Timber.d("insert -> MEDIA: fname = %s", fname);
        File f = new File(fname);
        Timber.d("insert -> MEDIA: f = %s", f);
        Uri uriFromF = Uri.fromFile(f);
        Timber.d("insert -> MEDIA: uriFromF = %s", uriFromF);
        return Uri.fromFile(new File(fname));
    } catch (IOException | EmptyMediaException e) {
        Timber.w(e, "insert failed from %s", fileUri);
        return null;
    }
}
Also used : Media(com.ichi2.libanki.Media) IOException(java.io.IOException) Uri(android.net.Uri) File(java.io.File) EmptyMediaException(com.ichi2.libanki.exception.EmptyMediaException) JSONException(com.ichi2.utils.JSONException) DeckRenameException(com.ichi2.libanki.backend.exception.DeckRenameException) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) IOException(java.io.IOException) ContentResolver(android.content.ContentResolver) EmptyMediaException(com.ichi2.libanki.exception.EmptyMediaException)

Example 18 with CREATED

use of com.ichi2.anki.CardBrowser.Column.CREATED in project Anki-Android by ankidroid.

the class BasicImageFieldController method createUI.

@Override
public void createUI(Context context, LinearLayout layout) {
    Timber.d("createUI()");
    mViewModel = mViewModel.replaceNullValues(mField, mActivity);
    mImagePreview = new ImageView(mActivity);
    File externalCacheDirRoot = context.getExternalCacheDir();
    if (externalCacheDirRoot == null) {
        Timber.e("createUI() unable to get external cache directory");
        showSomethingWentWrong();
        return;
    }
    File externalCacheDir = new File(externalCacheDirRoot.getAbsolutePath() + "/temp-photos");
    if (!externalCacheDir.exists() && !externalCacheDir.mkdir()) {
        Timber.e("createUI() externalCacheDir did not exist and could not be created");
        showSomethingWentWrong();
        return;
    }
    mAnkiCacheDirectory = externalCacheDir.getAbsolutePath();
    LinearLayout.LayoutParams p = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
    drawUIComponents(context);
    mCropButton = new Button(mActivity);
    mCropButton.setText(gtxt(R.string.crop_button));
    mCropButton.setOnClickListener(v -> mViewModel = requestCrop(mViewModel));
    mCropButton.setVisibility(View.INVISIBLE);
    Button btnGallery = new Button(mActivity);
    btnGallery.setText(gtxt(R.string.multimedia_editor_image_field_editing_galery));
    btnGallery.setOnClickListener(v -> {
        Intent i = new Intent(Intent.ACTION_PICK);
        i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        mActivity.startActivityForResultWithoutAnimation(i, ACTIVITY_SELECT_IMAGE);
    });
    Button btnDraw = new Button(mActivity);
    btnDraw.setText(gtxt(R.string.drawing));
    btnDraw.setOnClickListener(v -> {
        mActivity.startActivityForResultWithoutAnimation(new Intent(mActivity, DrawingActivity.class), ACTIVITY_DRAWING);
    });
    Button btnCamera = new Button(mActivity);
    btnCamera.setText(gtxt(R.string.multimedia_editor_image_field_editing_photo));
    btnCamera.setOnClickListener(v -> mViewModel = captureImage(context));
    if (!canUseCamera(context)) {
        btnCamera.setVisibility(View.INVISIBLE);
    }
    setPreviewImage(mViewModel.mImagePath, getMaxImageSize());
    layout.addView(mImagePreview, ViewGroup.LayoutParams.MATCH_PARENT, p);
    layout.addView(mImageFileSize, ViewGroup.LayoutParams.MATCH_PARENT);
    layout.addView(mImageFileSizeWarning, ViewGroup.LayoutParams.MATCH_PARENT);
    layout.addView(btnGallery, ViewGroup.LayoutParams.MATCH_PARENT);
    // drew image appear far larger in preview in devices API < 24 #9439
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        layout.addView(btnDraw, ViewGroup.LayoutParams.MATCH_PARENT);
    }
    if (com.ichi2.utils.CheckCameraPermission.manifestContainsPermission(context)) {
        layout.addView(btnCamera, ViewGroup.LayoutParams.MATCH_PARENT);
    }
    layout.addView(mCropButton, ViewGroup.LayoutParams.MATCH_PARENT);
}
Also used : LayoutParams(android.widget.LinearLayout.LayoutParams) LayoutParams(android.widget.LinearLayout.LayoutParams) Button(android.widget.Button) Intent(android.content.Intent) ImageView(android.widget.ImageView) File(java.io.File) DrawingActivity(com.ichi2.anki.DrawingActivity) LinearLayout(android.widget.LinearLayout)

Example 19 with CREATED

use of com.ichi2.anki.CardBrowser.Column.CREATED in project Anki-Android by ankidroid.

the class DeckPicker method showStartupScreensAndDialogs.

private void showStartupScreensAndDialogs(SharedPreferences preferences, int skip) {
    // For Android 8/8.1 we want to use software rendering by default or the Reviewer UI is broken #7369
    if (CompatHelper.getSdkVersion() == Build.VERSION_CODES.O || CompatHelper.getSdkVersion() == Build.VERSION_CODES.O_MR1) {
        if (!preferences.contains("softwareRender")) {
            Timber.i("Android 8/8.1 detected with no render preference. Turning on software render.");
            preferences.edit().putBoolean("softwareRender", true).apply();
        } else {
            Timber.i("Android 8/8.1 detected, software render preference already exists.");
        }
    }
    if (!BackupManager.enoughDiscSpace(CollectionHelper.getCurrentAnkiDroidDirectory(this))) {
        Timber.i("Not enough space to do backup");
        showDialogFragment(DeckPickerNoSpaceLeftDialog.newInstance());
    } else if (preferences.getBoolean("noSpaceLeft", false)) {
        Timber.i("No space left");
        showDialogFragment(DeckPickerBackupNoSpaceLeftDialog.newInstance());
        preferences.edit().remove("noSpaceLeft").apply();
    } else if (InitialActivity.performSetupFromFreshInstallOrClearedPreferences(preferences)) {
        onFinishedStartup();
    } else if (skip < 2 && !InitialActivity.isLatestVersion(preferences)) {
        Timber.i("AnkiDroid is being updated and a collection already exists.");
        // The user might appreciate us now, see if they will help us get better?
        if (!preferences.contains(UsageAnalytics.ANALYTICS_OPTIN_KEY)) {
            displayAnalyticsOptInDialog();
        }
        // For upgrades, we check if we are upgrading
        // to a version that contains additions to the database integrity check routine that we would
        // like to run on all collections. A missing version number is assumed to be a fresh
        // installation of AnkiDroid and we don't run the check.
        long current = VersionUtils.getPkgVersionCode();
        Timber.i("Current AnkiDroid version: %s", current);
        long previous;
        if (preferences.contains(UPGRADE_VERSION_KEY)) {
            // Upgrading currently installed app
            previous = getPreviousVersion(preferences, current);
        } else {
            // Fresh install
            previous = current;
        }
        preferences.edit().putLong(UPGRADE_VERSION_KEY, current).apply();
        // It is rebuilt on the next sync or media check
        if (previous < 20300200) {
            Timber.i("Deleting media database");
            File mediaDb = new File(CollectionHelper.getCurrentAnkiDroidDirectory(this), "collection.media.ad.db2");
            if (mediaDb.exists()) {
                mediaDb.delete();
            }
        }
        // Recommend the user to do a full-sync if they're upgrading from before 2.3.1beta8
        if (previous < 20301208) {
            Timber.i("Recommend the user to do a full-sync");
            mRecommendFullSync = true;
        }
        // Fix "font-family" definition in templates created by AnkiDroid before 2.6alhpa23
        if (previous < 20600123) {
            Timber.i("Fixing font-family definition in templates");
            try {
                ModelManager models = getCol().getModels();
                for (Model m : models.all()) {
                    String css = m.getString("css");
                    if (css.contains("font-familiy")) {
                        m.put("css", css.replace("font-familiy", "font-family"));
                        models.save(m);
                    }
                }
                models.flush();
            } catch (JSONException e) {
                Timber.e(e, "Failed to upgrade css definitions.");
            }
        }
        // Check if preference upgrade or database check required, otherwise go to new feature screen
        int upgradeDbVersion = AnkiDroidApp.CHECK_DB_AT_VERSION;
        // Specifying a checkpoint in the future is not supported, please don't do it!
        if (current < upgradeDbVersion) {
            Timber.e("Invalid value for CHECK_DB_AT_VERSION");
            UIUtils.showSimpleSnackbar(this, "Invalid value for CHECK_DB_AT_VERSION", false);
            onFinishedStartup();
            return;
        }
        // Skip full DB check if the basic check is OK
        // TODO: remove this variable if we really want to do the full db check on every user
        boolean skipDbCheck = false;
        // if (previous < upgradeDbVersion && getCol().basicCheck()) {
        // skipDbCheck = true;
        // }
        boolean upgradedPreferences = InitialActivity.upgradePreferences(this, previous);
        // noinspection ConstantConditions
        if (!skipDbCheck && previous < upgradeDbVersion) {
            Timber.i("showStartupScreensAndDialogs() running integrityCheck()");
            // #5852 - since we may have a warning about disk space, we don't want to force a check database
            // and show a warning before the user knows what is happening.
            new MaterialDialog.Builder(this).title(R.string.integrity_check_startup_title).content(R.string.integrity_check_startup_content).positiveText(R.string.check_db).negativeText(R.string.close).onPositive((materialDialog, dialogAction) -> integrityCheck()).onNeutral((materialDialog, dialogAction) -> restartActivity()).onNegative((materialDialog, dialogAction) -> restartActivity()).canceledOnTouchOutside(false).cancelable(false).build().show();
            return;
        }
        if (upgradedPreferences) {
            Timber.i("Updated preferences with no integrity check - restarting activity");
            // If integrityCheck() doesn't occur, but we did update preferences we should restart DeckPicker to
            // proceed
            restartActivity();
            return;
        }
        // There the "lastVersion" is set, so that this code is not reached again
        if (VersionUtils.isReleaseVersion()) {
            Timber.i("Displaying new features");
            Intent infoIntent = new Intent(this, Info.class);
            infoIntent.putExtra(Info.TYPE_EXTRA, Info.TYPE_NEW_VERSION);
            if (skip != 0) {
                startActivityForResultWithAnimation(infoIntent, SHOW_INFO_NEW_VERSION, START);
            } else {
                startActivityForResultWithoutAnimation(infoIntent, SHOW_INFO_NEW_VERSION);
            }
        } else {
            Timber.i("Dev Build - not showing 'new features'");
            // Don't show new features dialog for development builds
            InitialActivity.setUpgradedToLatestVersion(preferences);
            String ver = getResources().getString(R.string.updated_version, VersionUtils.getPkgVersionName());
            UIUtils.showSnackbar(this, ver, true, -1, null, findViewById(R.id.root_layout), null);
            showStartupScreensAndDialogs(preferences, 2);
        }
    } else {
        // This is the main call when there is nothing special required
        Timber.i("No startup screens required");
        onFinishedStartup();
    }
}
Also used : DividerItemDecoration(androidx.recyclerview.widget.DividerItemDecoration) StartupFailure(com.ichi2.anki.InitialActivity.StartupFailure) Bundle(android.os.Bundle) NonNull(androidx.annotation.NonNull) Uri(android.net.Uri) DialogHandler(com.ichi2.anki.dialogs.DialogHandler) Drawable(android.graphics.drawable.Drawable) ShortcutManagerCompat(androidx.core.content.pm.ShortcutManagerCompat) Manifest(android.Manifest) Decks(com.ichi2.libanki.Decks) Fragment(androidx.fragment.app.Fragment) JSONException(com.ichi2.utils.JSONException) ContextCompat(androidx.core.content.ContextCompat) DeckPickerBackupNoSpaceLeftDialog(com.ichi2.anki.dialogs.DeckPickerBackupNoSpaceLeftDialog) IntentFilter(android.content.IntentFilter) Triple(com.ichi2.utils.Triple) SearchView(androidx.appcompat.widget.SearchView) DeckPickerContextMenu(com.ichi2.anki.dialogs.DeckPickerContextMenu) Cancellable(com.ichi2.async.Cancellable) DeckRenameException(com.ichi2.libanki.backend.exception.DeckRenameException) StringRes(androidx.annotation.StringRes) Unit(kotlin.Unit) Nullable(androidx.annotation.Nullable) Message(android.os.Message) HostNumFactory(com.ichi2.anki.web.HostNumFactory) CompatHelper(com.ichi2.compat.CompatHelper) DeckAdapter(com.ichi2.anki.widgets.DeckAdapter) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) DeckPickerNoSpaceToDowngradeDialog(com.ichi2.anki.dialogs.DeckPickerNoSpaceToDowngradeDialog) DeckPickerConfirmDeleteDeckDialog(com.ichi2.anki.dialogs.DeckPickerConfirmDeleteDeckDialog) Direction(com.ichi2.anim.ActivityTransitionAnimation.Direction) FULL_DOWNLOAD(com.ichi2.async.Connection.ConflictResolution.FULL_DOWNLOAD) SdCardReceiver(com.ichi2.anki.receiver.SdCardReceiver) Editor(android.content.SharedPreferences.Editor) CustomSyncServerUrlException(com.ichi2.libanki.sync.CustomSyncServerUrlException) FileSizeFormatter(com.ichi2.anki.dialogs.DeckPickerNoSpaceToDowngradeDialog.FileSizeFormatter) DeckPickerNoSpaceLeftDialog(com.ichi2.anki.dialogs.DeckPickerNoSpaceLeftDialog) StudyOptionsListener(com.ichi2.anki.StudyOptionsFragment.StudyOptionsListener) BadgeDrawableBuilder(com.ichi2.ui.BadgeDrawableBuilder) Menu(android.view.Menu) DeckService(com.ichi2.anki.servicelayer.DeckService) Connection(com.ichi2.async.Connection) Settings(android.provider.Settings) AnkiPackageImporter(com.ichi2.libanki.importer.AnkiPackageImporter) SwipeRefreshLayout(androidx.swiperefreshlayout.widget.SwipeRefreshLayout) CollectionIntegrityStorageCheck(com.ichi2.anki.CollectionHelper.CollectionIntegrityStorageCheck) ActivityExportingDelegate(com.ichi2.anki.export.ActivityExportingDelegate) TextUtils(android.text.TextUtils) File(java.io.File) SharedPreferences(android.content.SharedPreferences) TypedValue(android.util.TypedValue) IconCompat(androidx.core.graphics.drawable.IconCompat) ImportUtils(com.ichi2.utils.ImportUtils) EditText(android.widget.EditText) SchedulerService(com.ichi2.anki.servicelayer.SchedulerService) LinearLayout(android.widget.LinearLayout) AsyncDialogFragment(com.ichi2.anki.dialogs.AsyncDialogFragment) PackageManager(android.content.pm.PackageManager) TaskManager(com.ichi2.async.TaskManager) WindowManager(android.view.WindowManager) UsageAnalytics(com.ichi2.anki.analytics.UsageAnalytics) ModelManager(com.ichi2.libanki.ModelManager) ConfirmationDialog(com.ichi2.anki.dialogs.ConfirmationDialog) AnkiStatsTaskHandler(com.ichi2.anki.stats.AnkiStatsTaskHandler) Permissions(com.ichi2.utils.Permissions) View(android.view.View) RecyclerView(androidx.recyclerview.widget.RecyclerView) SyncStatus(com.ichi2.utils.SyncStatus) FragmentTransaction(androidx.fragment.app.FragmentTransaction) BroadcastReceiver(android.content.BroadcastReceiver) DatabaseErrorDialog(com.ichi2.anki.dialogs.DatabaseErrorDialog) CustomStudyDialogFactory(com.ichi2.anki.dialogs.customstudy.CustomStudyDialogFactory) Timber(timber.log.Timber) UndoService(com.ichi2.anki.servicelayer.UndoService) List(java.util.List) TextView(android.widget.TextView) ImportFileSelectionFragment(com.ichi2.anki.dialogs.ImportFileSelectionFragment) RelativeLayout(android.widget.RelativeLayout) Filterable(android.widget.Filterable) TaskListenerWithContext(com.ichi2.async.TaskListenerWithContext) ViewPropertyAnimator(android.view.ViewPropertyAnimator) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) Snackbar(com.google.android.material.snackbar.Snackbar) Window(android.view.Window) VersionUtils(com.ichi2.utils.VersionUtils) Context(android.content.Context) TaskListener(com.ichi2.async.TaskListener) KeyEvent(android.view.KeyEvent) GravityEnum(com.afollestad.materialdialogs.GravityEnum) Pair(android.util.Pair) DeckPickerAnalyticsOptInDialog(com.ichi2.anki.dialogs.DeckPickerAnalyticsOptInDialog) ImportDialog(com.ichi2.anki.dialogs.ImportDialog) Intent(android.content.Intent) Collection(com.ichi2.libanki.Collection) StyledProgressDialog(com.ichi2.themes.StyledProgressDialog) PixelFormat(android.graphics.PixelFormat) TypedArray(android.content.res.TypedArray) MenuItem(android.view.MenuItem) WidgetStatus(com.ichi2.widget.WidgetStatus) SyncErrorDialog(com.ichi2.anki.dialogs.SyncErrorDialog) Payload(com.ichi2.async.Connection.Payload) Model(com.ichi2.libanki.Model) Build(android.os.Build) ShortcutInfoCompat(androidx.core.content.pm.ShortcutInfoCompat) Utils(com.ichi2.libanki.Utils) DialogInterface(android.content.DialogInterface) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) Computation(com.ichi2.utils.Computation) AbstractDeckTreeNode(com.ichi2.libanki.sched.AbstractDeckTreeNode) ActivityCompat(androidx.core.app.ActivityCompat) CreateDeckDialog(com.ichi2.anki.dialogs.CreateDeckDialog) CollectionTask(com.ichi2.async.CollectionTask) SQLException(android.database.SQLException) CustomStudyDialog(com.ichi2.anki.dialogs.customstudy.CustomStudyDialog) Syncer(com.ichi2.libanki.sync.Syncer) MediaCheckDialog(com.ichi2.anki.dialogs.MediaCheckDialog) AdaptionUtil(com.ichi2.utils.AdaptionUtil) VisibleForTesting(androidx.annotation.VisibleForTesting) Resources(android.content.res.Resources) OnClickListener(android.view.View.OnClickListener) BadgeDrawableBuilder(com.ichi2.ui.BadgeDrawableBuilder) Model(com.ichi2.libanki.Model) JSONException(com.ichi2.utils.JSONException) Intent(android.content.Intent) ModelManager(com.ichi2.libanki.ModelManager) File(java.io.File)

Example 20 with CREATED

use of com.ichi2.anki.CardBrowser.Column.CREATED in project Anki-Android by ankidroid.

the class DeckPicker method createSubDeckDialog.

public void createSubDeckDialog(long did) {
    CreateDeckDialog createDeckDialog = new CreateDeckDialog(DeckPicker.this, R.string.create_subdeck, CreateDeckDialog.DeckDialogType.SUB_DECK, did);
    createDeckDialog.setOnNewDeckCreated((i) -> {
        // a deck was created
        mDeckListAdapter.notifyDataSetChanged();
        updateDeckList();
        if (mFragmented) {
            loadStudyOptionsFragment(false);
        }
    });
    createDeckDialog.showDialog();
}
Also used : CreateDeckDialog(com.ichi2.anki.dialogs.CreateDeckDialog)

Aggregations

Collection (com.ichi2.libanki.Collection)9 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)7 JSONException (com.ichi2.utils.JSONException)7 File (java.io.File)7 Intent (android.content.Intent)5 Model (com.ichi2.libanki.Model)5 SharedPreferences (android.content.SharedPreferences)4 Uri (android.net.Uri)4 Bundle (android.os.Bundle)4 View (android.view.View)4 TextView (android.widget.TextView)4 Deck (com.ichi2.libanki.Deck)4 Manifest (android.Manifest)3 BroadcastReceiver (android.content.BroadcastReceiver)3 Context (android.content.Context)3 IntentFilter (android.content.IntentFilter)3 PackageManager (android.content.pm.PackageManager)3 Resources (android.content.res.Resources)3 Message (android.os.Message)3 DeckRenameException (com.ichi2.libanki.backend.exception.DeckRenameException)3