Search in sources :

Example 21 with START

use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project Anki-Android by ankidroid.

the class Media method maybeUpgrade.

public void maybeUpgrade() {
    String oldpath = dir() + ".db";
    File oldDbFile = new File(oldpath);
    if (oldDbFile.exists()) {
        mDb.execute(String.format(Locale.US, "attach \"%s\" as old", oldpath));
        try {
            String sql = "insert into media\n" + " select m.fname, csum, mod, ifnull((select 1 from log l2 where l2.fname=m.fname), 0) as dirty\n" + " from old.media m\n" + " left outer join old.log l using (fname)\n" + " union\n" + " select fname, null, 0, 1 from old.log where type=" + Consts.CARD_TYPE_LRN + ";";
            mDb.execute(sql);
            mDb.execute("delete from meta");
            mDb.execute("insert into meta select dirMod, usn from old.meta");
            mDb.commit();
        } catch (Exception e) {
            // if we couldn't import the old db for some reason, just start anew
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            mCol.log("failed to import old media db:" + sw.toString());
        }
        mDb.execute("detach old");
        File newDbFile = new File(oldpath + ".old");
        if (newDbFile.exists()) {
            newDbFile.delete();
        }
        oldDbFile.renameTo(newDbFile);
    }
}
Also used : StringWriter(java.io.StringWriter) ZipFile(java.util.zip.ZipFile) File(java.io.File) EmptyMediaException(com.ichi2.libanki.exception.EmptyMediaException) IOException(java.io.IOException) SQLException(android.database.SQLException) FileNotFoundException(java.io.FileNotFoundException) PrintWriter(java.io.PrintWriter)

Example 22 with START

use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project Anki-Android by ankidroid.

the class TemporaryModelTest method testAddDeleteTracking.

@Test
public void testAddDeleteTracking() {
    // Assume you start with a 2 template model (like "Basic (and reversed)")
    // Add a 3rd new template, remove the 2nd, remove the 1st, add a new now-2nd, remove 1st again
    // ...and it should reduce to just removing the original 1st/2nd and adding the final as first
    TemporaryModel tempModel = new TemporaryModel(new Model("{ \"foo\": \"bar\" }"));
    tempModel.addTemplateChange(ADD, 3);
    Object[][] expected1 = { { 3, ADD } };
    // 3 templates and one change now
    assertTemplateChangesEqual(expected1, tempModel.getTemplateChanges());
    assertTemplateChangesEqual(expected1, tempModel.getAdjustedTemplateChanges());
    Assert.assertArrayEquals(new int[] { 3 }, tempModel.getDeleteDbOrds(3));
    tempModel.addTemplateChange(DELETE, 2);
    // 2 templates and two changes now
    Object[][] expected2 = { { 3, ADD }, { 2, DELETE } };
    Object[][] adjExpected2 = { { 2, ADD }, { 2, DELETE } };
    assertTemplateChangesEqual(expected2, tempModel.getTemplateChanges());
    assertTemplateChangesEqual(adjExpected2, tempModel.getAdjustedTemplateChanges());
    Assert.assertArrayEquals(new int[] { 2, 4 }, tempModel.getDeleteDbOrds(3));
    tempModel.addTemplateChange(DELETE, 1);
    // 1 template and three changes now
    Assert.assertArrayEquals(new int[] { 2, 1, 5 }, tempModel.getDeleteDbOrds(3));
    Object[][] expected3 = { { 3, ADD }, { 2, DELETE }, { 1, DELETE } };
    Object[][] adjExpected3 = { { 1, ADD }, { 2, DELETE }, { 1, DELETE } };
    assertTemplateChangesEqual(expected3, tempModel.getTemplateChanges());
    assertTemplateChangesEqual(adjExpected3, tempModel.getAdjustedTemplateChanges());
    tempModel.addTemplateChange(ADD, 2);
    // 2 templates and 4 changes now
    Assert.assertArrayEquals(new int[] { 2, 1, 5 }, tempModel.getDeleteDbOrds(3));
    Object[][] expected4 = { { 3, ADD }, { 2, DELETE }, { 1, DELETE }, { 2, ADD } };
    Object[][] adjExpected4 = { { 1, ADD }, { 2, DELETE }, { 1, DELETE }, { 2, ADD } };
    assertTemplateChangesEqual(expected4, tempModel.getTemplateChanges());
    assertTemplateChangesEqual(adjExpected4, tempModel.getAdjustedTemplateChanges());
    // Make sure we can resurrect these changes across lifecycle
    Bundle outBundle = tempModel.toBundle();
    assertTemplateChangesEqual(expected4, outBundle.getSerializable("mTemplateChanges"));
    // This is the hard part. We will delete a template we added so everything shifts.
    // The template currently at ordinal 1 was added as template 3 at the start before it slid down on the deletes
    // So the first template add should be negated by this delete, and the second template add should slide down to 1
    tempModel.addTemplateChange(DELETE, 1);
    // 1 template and 3 changes now (the delete just cancelled out one of the adds)
    Assert.assertArrayEquals(new int[] { 2, 1, 5 }, tempModel.getDeleteDbOrds(3));
    Object[][] expected5 = { { 2, DELETE }, { 1, DELETE }, { 1, ADD } };
    Object[][] adjExpected5 = { { 2, DELETE }, { 1, DELETE }, { 1, ADD } };
    assertTemplateChangesEqual(expected5, tempModel.getTemplateChanges());
    assertTemplateChangesEqual(adjExpected5, tempModel.getAdjustedTemplateChanges());
    tempModel.addTemplateChange(ADD, 2);
    // 2 template and 4 changes now (the delete just cancelled out one of the adds)
    Assert.assertArrayEquals(new int[] { 2, 1, 5 }, tempModel.getDeleteDbOrds(3));
    Object[][] expected6 = { { 2, DELETE }, { 1, DELETE }, { 1, ADD }, { 2, ADD } };
    Object[][] adjExpected6 = { { 2, DELETE }, { 1, DELETE }, { 1, ADD }, { 2, ADD } };
    assertTemplateChangesEqual(expected6, tempModel.getTemplateChanges());
    assertTemplateChangesEqual(adjExpected6, tempModel.getAdjustedTemplateChanges());
    tempModel.addTemplateChange(ADD, 3);
    // 2 template and 4 changes now (the delete just cancelled out one of the adds)
    Assert.assertArrayEquals(new int[] { 2, 1, 5 }, tempModel.getDeleteDbOrds(3));
    Object[][] expected7 = { { 2, DELETE }, { 1, DELETE }, { 1, ADD }, { 2, ADD }, { 3, ADD } };
    Object[][] adjExpected7 = { { 2, DELETE }, { 1, DELETE }, { 1, ADD }, { 2, ADD }, { 3, ADD } };
    assertTemplateChangesEqual(expected7, tempModel.getTemplateChanges());
    assertTemplateChangesEqual(adjExpected7, tempModel.getAdjustedTemplateChanges());
    tempModel.addTemplateChange(DELETE, 3);
    // 1 template and 3 changes now (two deletes cancelled out adds)
    Assert.assertArrayEquals(new int[] { 2, 1, 5 }, tempModel.getDeleteDbOrds(3));
    Object[][] expected8 = { { 2, DELETE }, { 1, DELETE }, { 1, ADD }, { 2, ADD } };
    Object[][] adjExpected8 = { { 2, DELETE }, { 1, DELETE }, { 1, ADD }, { 2, ADD } };
    assertTemplateChangesEqual(expected8, tempModel.getTemplateChanges());
    assertTemplateChangesEqual(adjExpected8, tempModel.getAdjustedTemplateChanges());
}
Also used : Bundle(android.os.Bundle) Model(com.ichi2.libanki.Model) Test(org.junit.Test)

Example 23 with START

use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project Anki-Android by ankidroid.

the class DBTest method testDBCorruption.

@Test
public void testDBCorruption() throws Exception {
    String storagePath = CollectionHelper.getDefaultAnkiDroidDirectory(getTestContext());
    File illFatedDBFile = new File(storagePath, "illFatedDB.anki2");
    // Make sure we have clean state to start with
    SQLiteDatabase.deleteDatabase(illFatedDBFile);
    Assert.assertFalse("database exists already", illFatedDBFile.exists());
    TestDB illFatedDB = new TestDB(illFatedDBFile.getCanonicalPath());
    Assert.assertFalse("database should not be corrupt yet", illFatedDB.mDatabaseIsCorrupt);
    // Scribble in it
    byte[] b = new byte[1024];
    new Random().nextBytes(b);
    FileOutputStream illFatedDBFileStream = new FileOutputStream(illFatedDBFile);
    illFatedDBFileStream.write(b, 0, 1024);
    illFatedDBFileStream.flush();
    illFatedDBFileStream.close();
    // Try to do something
    try {
        illFatedDB.execute("CREATE TABLE test_table (test_column INTEGER NOT NULL);");
        Assert.fail("There should have been a corruption exception");
    } catch (SQLiteDatabaseCorruptException e) {
    // do nothing, it is expected
    }
    Assert.assertTrue("database corruption not detected", illFatedDB.mDatabaseIsCorrupt);
    // our handler avoids deleting databases, in contrast with default handler
    Assert.assertTrue("database incorrectly deleted on corruption", illFatedDBFile.exists());
    illFatedDB.close();
    SQLiteDatabase.deleteDatabase(illFatedDBFile);
}
Also used : Random(java.util.Random) FileOutputStream(java.io.FileOutputStream) SQLiteDatabaseCorruptException(android.database.sqlite.SQLiteDatabaseCorruptException) File(java.io.File) Test(org.junit.Test) InstrumentedTest(com.ichi2.anki.tests.InstrumentedTest)

Example 24 with START

use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project Anki-Android by Ramblurr.

the class Reviewer method onCreate.

// ----------------------------------------------------------------------------
// ANDROID METHODS
// ----------------------------------------------------------------------------
@Override
protected void onCreate(Bundle savedInstanceState) {
    Themes.applyTheme(this);
    super.onCreate(savedInstanceState);
    // Remove the status bar and title bar
    if (mPrefFullscreenReview) {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        // Do not hide the title bar in Honeycomb, since it contains the action bar.
        if (AnkiDroidApp.SDK_VERSION <= 11) {
            requestWindowFeature(Window.FEATURE_NO_TITLE);
        }
    }
    mChangeBorderStyle = Themes.getTheme() == Themes.THEME_ANDROID_LIGHT || Themes.getTheme() == Themes.THEME_ANDROID_DARK;
    // The hardware buttons should control the music volume while reviewing.
    setVolumeControlStream(AudioManager.STREAM_MUSIC);
    Collection col = AnkiDroidApp.getCol();
    if (col == null) {
        reloadCollection(savedInstanceState);
        return;
    } else {
        mSched = col.getSched();
        mCollectionFilename = col.getPath();
        mBaseUrl = Utils.getBaseUrl(col.getMedia().getDir());
        restorePreferences();
        setFullScreen(mPrefFullscreenReview);
        registerExternalStorageListener();
        if (mNightMode) {
            mCurrentBackgroundColor = Themes.getNightModeCardBackground(this);
        } else {
            mCurrentBackgroundColor = Color.WHITE;
        }
        mUseQuickUpdate = shouldUseQuickUpdate();
        initLayout(R.layout.flashcard);
        try {
            String[] title = mSched.getCol().getDecks().current().getString("name").split("::");
            AnkiDroidApp.getCompat().setTitle(this, title[title.length - 1], mInvertedColors);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
        AnkiDroidApp.getCompat().setSubtitle(this, "", mInvertedColors);
        if (mPrefTextSelection) {
            clipboardSetText("");
        }
        // Load the template for the card
        try {
            mCardTemplate = Utils.convertStreamToString(getAssets().open("card_template.html"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // Initialize text-to-speech. This is an asynchronous operation.
        if (mSpeakText) {
            ReadText.initializeTts(this);
        }
        // Get last whiteboard state
        if (mPrefWhiteboard && mCurrentCard != null && MetaDB.getWhiteboardState(this, mCurrentCard.getDid()) == 1) {
            mShowWhiteboard = true;
            mWhiteboard.setVisibility(View.VISIBLE);
        }
        // Load the first card and start reviewing. Uses the answer card
        // task to load a card, but since we send null
        // as the card to answer, no card will be answered.
        DeckTask.launchDeckTask(DeckTask.TASK_TYPE_ANSWER_CARD, mAnswerCardHandler, new DeckTask.TaskData(mSched, null, 0));
        // Since we aren't actually answering a card, decrement the rep count
        mSched.setReps(mSched.getReps() - 1);
    }
}
Also used : Collection(com.ichi2.libanki.Collection) JSONException(org.json.JSONException) SpannedString(android.text.SpannedString) SpannableString(android.text.SpannableString) IOException(java.io.IOException) DeckTask(com.ichi2.async.DeckTask)

Example 25 with START

use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project Anki-Android by Ramblurr.

the class BasicTextFieldController method createTranslateButton.

// Here is all the functionality to provide translations
private void createTranslateButton(LinearLayout layoutTool, LayoutParams ps) {
    Button btnTranslate = new Button(mActivity);
    btnTranslate.setText(gtxt(R.string.multimedia_editor_text_field_editing_translate));
    btnTranslate.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            String source = mEditText.getText().toString();
            // Checks and warnings
            if (source.length() == 0) {
                showToast(gtxt(R.string.multimedia_editor_text_field_editing_no_text));
                return;
            }
            if (source.contains(" ")) {
                showToast(gtxt(R.string.multimedia_editor_text_field_editing_many_words));
            }
            // Pick from two translation sources
            PickStringDialogFragment fragment = new PickStringDialogFragment();
            ArrayList<String> translationSources = new ArrayList<String>();
            translationSources.add("Glosbe.com");
            translationSources.add("ColorDict");
            fragment.setChoices(translationSources);
            fragment.setOnclickListener(new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if (which == 0) {
                        startTranslationWithGlosbe();
                    } else if (which == 1) {
                        startTranslationWithColorDict();
                    }
                }
            });
            fragment.setTitle(gtxt(R.string.multimedia_editor_trans_pick_translation_source));
            fragment.show(mActivity.getSupportFragmentManager(), "pick.translation.source");
        }
    });
    layoutTool.addView(btnTranslate, ps);
// flow continues in Start Translation with...
}
Also used : Button(android.widget.Button) PickStringDialogFragment(com.ichi2.anki.multimediacard.activity.PickStringDialogFragment) DialogInterface(android.content.DialogInterface) ArrayList(java.util.ArrayList) OnClickListener(android.view.View.OnClickListener) View(android.view.View)

Aggregations

Test (org.junit.Test)23 Intent (android.content.Intent)21 JSONObject (com.ichi2.utils.JSONObject)17 Model (com.ichi2.libanki.Model)14 View (android.view.View)13 ArrayList (java.util.ArrayList)13 Bundle (android.os.Bundle)12 Collection (com.ichi2.libanki.Collection)11 Note (com.ichi2.libanki.Note)9 File (java.io.File)9 JSONArray (com.ichi2.utils.JSONArray)8 SharedPreferences (android.content.SharedPreferences)7 TextView (android.widget.TextView)7 EditText (android.widget.EditText)6 Deck (com.ichi2.libanki.Deck)6 Dialog (android.app.Dialog)5 NonNull (androidx.annotation.NonNull)5 MaterialDialog (com.afollestad.materialdialogs.MaterialDialog)5 RobolectricTest (com.ichi2.anki.RobolectricTest)5 TaskData (com.ichi2.async.TaskData)5