Пример #1
0
  /** Test giving the answer for a reviewed card */
  public void testAnswerCard() {
    Collection col;
    col = CollectionHelper.getInstance().getCol(getContext());
    Sched sched = col.getSched();
    long deckId = mTestDeckIds[0];
    col.getDecks().select(deckId);
    Card card = sched.getCard();

    ContentResolver cr = getContext().getContentResolver();
    Uri reviewInfoUri = FlashCardsContract.ReviewInfo.CONTENT_URI;
    ContentValues values = new ContentValues();
    long noteId = card.note().getId();
    int cardOrd = card.getOrd();
    int ease = AbstractFlashcardViewer.EASE_3; // <- insert real ease here

    values.put(FlashCardsContract.ReviewInfo.NOTE_ID, noteId);
    values.put(FlashCardsContract.ReviewInfo.CARD_ORD, cardOrd);
    values.put(FlashCardsContract.ReviewInfo.EASE, ease);
    int updateCount = cr.update(reviewInfoUri, values, null, null);

    assertEquals("Check if update returns 1", 1, updateCount);

    sched.reset();
    Card newCard = sched.getCard();
    if (newCard != null) {
      if (newCard.note().getId() == card.note().getId() && newCard.getOrd() == card.getOrd()) {
        fail("Next scheduled card has not changed");
      }
    } else {
      // We expected this
    }
  }
Пример #2
0
  /**
   * Test query to specific deck ID
   *
   * @throws Exception
   */
  public void testQueryCertainDeck() throws Exception {
    Collection col;
    col = CollectionHelper.getInstance().getCol(getContext());

    long deckId = mTestDeckIds[0];
    Uri deckUri =
        Uri.withAppendedPath(FlashCardsContract.Deck.CONTENT_ALL_URI, Long.toString(deckId));
    Cursor decksCursor = getContext().getContentResolver().query(deckUri, null, null, null, null);
    try {
      if (decksCursor == null || !decksCursor.moveToFirst()) {
        fail("No deck received. Should have delivered deck with id " + deckId);
      } else {
        long returnedDeckID =
            decksCursor.getLong(decksCursor.getColumnIndex(FlashCardsContract.Deck.DECK_ID));
        String returnedDeckName =
            decksCursor.getString(decksCursor.getColumnIndex(FlashCardsContract.Deck.DECK_NAME));

        JSONObject realDeck = col.getDecks().get(deckId);
        assertEquals("Check that received deck ID equals real deck ID", deckId, returnedDeckID);
        assertEquals(
            "Check that received deck name equals real deck name",
            realDeck.getString("name"),
            returnedDeckName);
      }
    } finally {
      decksCursor.close();
    }
  }
Пример #3
0
  /**
   * Test query to decks table
   *
   * @throws Exception
   */
  public void testQueryAllDecks() throws Exception {
    Collection col;
    col = CollectionHelper.getInstance().getCol(getContext());
    Decks decks = col.getDecks();

    Cursor decksCursor =
        getContext()
            .getContentResolver()
            .query(
                FlashCardsContract.Deck.CONTENT_ALL_URI,
                FlashCardsContract.Deck.DEFAULT_PROJECTION,
                null,
                null,
                null);

    assertNotNull(decksCursor);
    try {
      assertEquals("Check number of results", decks.count(), decksCursor.getCount());
      while (decksCursor.moveToNext()) {
        long deckID =
            decksCursor.getLong(decksCursor.getColumnIndex(FlashCardsContract.Deck.DECK_ID));
        String deckName =
            decksCursor.getString(decksCursor.getColumnIndex(FlashCardsContract.Deck.DECK_NAME));

        JSONObject deck = decks.get(deckID);
        assertNotNull("Check that the deck we received actually exists", deck);
        assertEquals(
            "Check that the received deck has the correct name", deck.getString("name"), deckName);
      }
    } finally {
      decksCursor.close();
    }
  }
Пример #4
0
 /** Check that inserting and removing a note into default deck works as expected */
 public void testInsertAndRemoveNote() throws Exception {
   // Get required objects for test
   final ContentResolver cr = getContext().getContentResolver();
   final Collection col = CollectionHelper.getInstance().getCol(getContext());
   final AddContentApi api = new AddContentApi(getContext());
   // Add the note
   Uri newNoteUri = api.addNewNote(mModelId, 1, TEST_NOTE_FIELDS, TEST_TAG);
   assertNotNull("Check that URI returned from addNewNote is not null", newNoteUri);
   // Check that it looks as expected
   Note addedNote = new Note(col, Long.parseLong(newNoteUri.getLastPathSegment()));
   addedNote.load();
   assertTrue(
       "Check that fields were set correctly",
       Arrays.equals(addedNote.getFields(), TEST_NOTE_FIELDS));
   assertEquals("Check that tag was set correctly", TEST_TAG, addedNote.getTags().get(0));
   int expectedNumCards = col.getModels().get(mModelId).getJSONArray("tmpls").length();
   assertEquals(
       "Check that correct number of cards generated", expectedNumCards, addedNote.cards().size());
   // Now delete the note
   cr.delete(newNoteUri, null, null);
   try {
     addedNote.load();
     fail("Expected RuntimeException to be thrown when deleting note");
   } catch (RuntimeException e) {
     // Expect RuntimeException to be thrown when loading deleted note
   }
 }
Пример #5
0
 /** Remove the notes and decks created in setUp(). */
 @Override
 protected void tearDown() throws Exception {
   Log.i(AnkiDroidApp.TAG, "tearDown()");
   final Collection col = CollectionHelper.getInstance().getCol(getContext());
   // Delete all notes
   List<Long> remnantNotes = col.findNotes("tag:" + TEST_TAG);
   if (remnantNotes.size() > 0) {
     long[] nids = new long[remnantNotes.size()];
     for (int i = 0; i < remnantNotes.size(); i++) {
       nids[i] = remnantNotes.get(i);
     }
     col.remNotes(nids);
     col.save();
     assertEquals(
         "Check that remnant notes have been deleted", 0, col.findNotes("tag:" + TEST_TAG).size());
   }
   // delete test decks
   for (long did : mTestDeckIds) {
     col.getDecks().rem(did, true);
   }
   col.getDecks().flush();
   assertEquals(
       "Check that all created decks have been deleted",
       mNumDecksBeforeTest,
       col.getDecks().count());
   // Delete test model
   col.modSchema(false);
   col.getModels().rem(col.getModels().get(mModelId));
   super.tearDown();
 }
Пример #6
0
 /** Check that inserting a new model works as expected */
 public void testInsertAndUpdateModel() throws Exception {
   final ContentResolver cr = getContext().getContentResolver();
   ContentValues cv = new ContentValues();
   // Insert a new model
   cv.put(FlashCardsContract.Model.NAME, TEST_MODEL_NAME);
   cv.put(FlashCardsContract.Model.FIELD_NAMES, Utils.joinFields(TEST_MODEL_FIELDS));
   cv.put(FlashCardsContract.Model.NUM_CARDS, TEST_MODEL_CARDS.length);
   cv.put(FlashCardsContract.Model.CSS, TEST_MODEL_CSS);
   Uri modelUri = cr.insert(FlashCardsContract.Model.CONTENT_URI, cv);
   assertNotNull("Check inserted model isn't null", modelUri);
   long mid = Long.parseLong(modelUri.getLastPathSegment());
   final Collection col = CollectionHelper.getInstance().getCol(getContext());
   try {
     JSONObject model = col.getModels().get(mid);
     assertEquals("Check model name", TEST_MODEL_NAME, model.getString("name"));
     assertEquals("Check css", TEST_MODEL_CSS, model.getString("css"));
     assertEquals(
         "Check templates length", TEST_MODEL_CARDS.length, model.getJSONArray("tmpls").length());
     assertEquals(
         "Check field length", TEST_MODEL_FIELDS.length, model.getJSONArray("flds").length());
     JSONArray flds = model.getJSONArray("flds");
     for (int i = 0; i < flds.length(); i++) {
       assertEquals(
           "Check name of fields", flds.getJSONObject(i).getString("name"), TEST_MODEL_FIELDS[i]);
     }
     // Update each of the templates in the model
     for (int i = 0; i < TEST_MODEL_CARDS.length; i++) {
       cv = new ContentValues();
       cv.put(FlashCardsContract.CardTemplate.NAME, TEST_MODEL_CARDS[i]);
       cv.put(FlashCardsContract.CardTemplate.QUESTION_FORMAT, TEST_MODEL_QFMT[i]);
       cv.put(FlashCardsContract.CardTemplate.ANSWER_FORMAT, TEST_MODEL_AFMT[i]);
       cv.put(FlashCardsContract.CardTemplate.BROWSER_QUESTION_FORMAT, TEST_MODEL_QFMT[i]);
       cv.put(FlashCardsContract.CardTemplate.BROWSER_ANSWER_FORMAT, TEST_MODEL_AFMT[i]);
       Uri tmplUri =
           Uri.withAppendedPath(Uri.withAppendedPath(modelUri, "templates"), Integer.toString(i));
       assertTrue("Update rows", cr.update(tmplUri, cv, null, null) > 0);
       JSONObject template = col.getModels().get(mid).getJSONArray("tmpls").getJSONObject(i);
       assertEquals("Check template name", TEST_MODEL_CARDS[i], template.getString("name"));
       assertEquals("Check qfmt", TEST_MODEL_QFMT[i], template.getString("qfmt"));
       assertEquals("Check afmt", TEST_MODEL_AFMT[i], template.getString("afmt"));
       assertEquals("Check bqfmt", TEST_MODEL_QFMT[i], template.getString("bqfmt"));
       assertEquals("Check bafmt", TEST_MODEL_AFMT[i], template.getString("bafmt"));
     }
   } finally {
     // Delete the model (this will force a full-sync)
     try {
       col.modSchema(false);
       col.getModels().rem(col.getModels().get(mid));
     } catch (ConfirmModSchemaException e) {
       // This will never happen
       throw new IllegalStateException(
           "Unexpected ConfirmModSchemaException trying to remove model");
     }
   }
 }
Пример #7
0
  /** Test changing the selected deck */
  public void testSetSelectedDeck() {
    long deckId = mTestDeckIds[0];
    ContentResolver cr = getContext().getContentResolver();
    Uri selectDeckUri = FlashCardsContract.Deck.CONTENT_SELECTED_URI;
    ContentValues values = new ContentValues();
    values.put(FlashCardsContract.Deck.DECK_ID, deckId);
    cr.update(selectDeckUri, values, null, null);

    Collection col;
    col = CollectionHelper.getInstance().getCol(getContext());
    assertEquals(
        "Check that the selected deck has been correctly set", deckId, col.getDecks().selected());
  }
Пример #8
0
  /**
   * Test that query for the next card in the schedule returns a valid result WITH a deck selector
   */
  public void testQueryCardFromCertainDeck() {
    long deckToTest = mTestDeckIds[0];
    String deckSelector = "deckID=?";
    String deckArguments[] = {Long.toString(deckToTest)};
    Collection col;
    col = CollectionHelper.getInstance().getCol(getContext());
    Sched sched = col.getSched();
    long selectedDeckBeforeTest = col.getDecks().selected();
    col.getDecks().select(1); // select Default deck

    Cursor reviewInfoCursor =
        getContext()
            .getContentResolver()
            .query(
                FlashCardsContract.ReviewInfo.CONTENT_URI, null, deckSelector, deckArguments, null);
    assertNotNull(reviewInfoCursor);
    assertEquals("Check that we actually received one card", 1, reviewInfoCursor.getCount());
    try {
      reviewInfoCursor.moveToFirst();
      int cardOrd =
          reviewInfoCursor.getInt(
              reviewInfoCursor.getColumnIndex(FlashCardsContract.ReviewInfo.CARD_ORD));
      long noteID =
          reviewInfoCursor.getLong(
              reviewInfoCursor.getColumnIndex(FlashCardsContract.ReviewInfo.NOTE_ID));
      assertEquals("Check that the selected deck has not changed", 1, col.getDecks().selected());

      col.getDecks().select(deckToTest);
      Card nextCard = null;
      for (int i = 0;
          i < 10;
          i++) { // minimizing fails, when sched.reset() randomly chooses between multiple cards
        sched.reset();
        nextCard = sched.getCard();
        if (nextCard.note().getId() == noteID && nextCard.getOrd() == cardOrd) break;
      }
      assertNotNull("Check that there actually is a next scheduled card", nextCard);
      assertEquals(
          "Check that received card and actual card have same note id",
          nextCard.note().getId(),
          noteID);
      assertEquals(
          "Check that received card and actual card have same card ord",
          nextCard.getOrd(),
          cardOrd);
    } finally {
      reviewInfoCursor.close();
    }

    col.getDecks().select(selectedDeckBeforeTest);
  }
Пример #9
0
 /** Initially create one note for each model. */
 @Override
 protected void setUp() throws Exception {
   super.setUp();
   Log.i(AnkiDroidApp.TAG, "setUp()");
   mCreatedNotes = new ArrayList<>();
   final Collection col = CollectionHelper.getInstance().getCol(getContext());
   // Add a new basic model that we use for testing purposes (existing models could potentially be
   // corrupted)
   JSONObject model = Models.addBasicModel(col, BASIC_MODEL_NAME);
   mModelId = model.getLong("id");
   ArrayList<String> flds = col.getModels().fieldNames(model);
   // Use the names of the fields as test values for the notes which will be added
   mDummyFields = flds.toArray(new String[flds.size()]);
   // create test decks and add one note for every deck
   final AddContentApi api = new AddContentApi(getContext());
   HashMap<Long, String> deckList = api.getDeckList();
   mNumDecksBeforeTest = deckList.size();
   // TODO: add the notes directly with libanki
   for (int i = 0; i < TEST_DECKS.length; i++) {
     mTestDeckIds[i] = api.addNewDeck(TEST_DECKS[i]);
     Uri newNoteUri = api.addNewNote(mModelId, mTestDeckIds[i], mDummyFields, TEST_TAG);
     assertNotNull(newNoteUri);
     mCreatedNotes.add(newNoteUri);
     // Check that the flds data was set correctly
     long nid = Long.parseLong(newNoteUri.getLastPathSegment());
     Note addedNote = col.getNote(nid);
     assertTrue(
         "Check that the flds data was set correctly",
         Arrays.equals(addedNote.getFields(), mDummyFields));
     assertTrue("Check that there was at least one card generated", addedNote.cards().size() > 0);
   }
   // Add a note to the default deck as well so that testQueryNextCard() works
   Uri newNoteUri = api.addNewNote(mModelId, 1, mDummyFields, TEST_TAG);
   assertNotNull(newNoteUri);
   mCreatedNotes.add(newNoteUri);
 }
Пример #10
0
  /**
   * Test that query for the next card in the schedule returns a valid result without any deck
   * selector
   */
  public void testQueryNextCard() {
    Collection col;
    col = CollectionHelper.getInstance().getCol(getContext());
    Sched sched = col.getSched();

    Cursor reviewInfoCursor =
        getContext()
            .getContentResolver()
            .query(FlashCardsContract.ReviewInfo.CONTENT_URI, null, null, null, null);
    assertNotNull(reviewInfoCursor);
    assertEquals("Check that we actually received one card", 1, reviewInfoCursor.getCount());

    reviewInfoCursor.moveToFirst();
    int cardOrd =
        reviewInfoCursor.getInt(
            reviewInfoCursor.getColumnIndex(FlashCardsContract.ReviewInfo.CARD_ORD));
    long noteID =
        reviewInfoCursor.getLong(
            reviewInfoCursor.getColumnIndex(FlashCardsContract.ReviewInfo.NOTE_ID));

    Card nextCard = null;
    for (int i = 0;
        i < 10;
        i++) { // minimizing fails, when sched.reset() randomly chooses between multiple cards
      sched.reset();
      nextCard = sched.getCard();
      if (nextCard.note().getId() == noteID && nextCard.getOrd() == cardOrd) break;
    }
    assertNotNull("Check that there actually is a next scheduled card", nextCard);
    assertEquals(
        "Check that received card and actual card have same note id",
        nextCard.note().getId(),
        noteID);
    assertEquals(
        "Check that received card and actual card have same card ord", nextCard.getOrd(), cardOrd);
  }
  @Override
  public MaterialDialog onCreateDialog(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mType = getArguments().getInt("dialogType");
    Resources res = getResources();
    MaterialDialog.Builder builder = new MaterialDialog.Builder(getActivity());
    builder.cancelable(true).title(getTitle());

    boolean sqliteInstalled = false;
    try {
      sqliteInstalled = Runtime.getRuntime().exec("sqlite3 --version").waitFor() == 0;
    } catch (IOException | InterruptedException e) {
      e.printStackTrace();
    }

    switch (mType) {
      case DIALOG_CURSOR_SIZE_LIMIT_EXCEEDED:
      case DIALOG_LOAD_FAILED:
        // Collection failed to load; give user the option of either choosing from repair options,
        // or closing
        // the activity
        return builder
            .cancelable(false)
            .content(getMessage())
            .iconAttr(R.attr.dialogErrorIcon)
            .positiveText(res.getString(R.string.error_handling_options))
            .negativeText(res.getString(R.string.close))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_ERROR_HANDLING);
                  }

                  @Override
                  public void onNegative(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).exit();
                  }
                })
            .show();

      case DIALOG_DB_ERROR:
        // Database Check failed to execute successfully; give user the option of either choosing
        // from repair
        // options, submitting an error report, or closing the activity
        MaterialDialog dialog =
            builder
                .cancelable(false)
                .content(getMessage())
                .iconAttr(R.attr.dialogErrorIcon)
                .positiveText(res.getString(R.string.error_handling_options))
                .negativeText(res.getString(R.string.answering_error_report))
                .neutralText(res.getString(R.string.close))
                .callback(
                    new MaterialDialog.ButtonCallback() {
                      @Override
                      public void onPositive(MaterialDialog dialog) {
                        ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_ERROR_HANDLING);
                      }

                      @Override
                      public void onNegative(MaterialDialog dialog) {
                        ((DeckPicker) getActivity()).sendErrorReport();
                        dismissAllDialogFragments();
                      }

                      @Override
                      public void onNeutral(MaterialDialog dialog) {
                        ((DeckPicker) getActivity()).exit();
                      }
                    })
                .show();
        dialog
            .getCustomView()
            .findViewById(R.id.buttonDefaultNegative)
            .setEnabled(((DeckPicker) getActivity()).hasErrorFiles());
        return dialog;

      case DIALOG_ERROR_HANDLING:
        // The user has asked to see repair options; allow them to choose one of the repair options
        // or go back
        // to the previous dialog
        ArrayList<String> options = new ArrayList<>();
        ArrayList<Integer> values = new ArrayList<>();
        if (!((AnkiActivity) getActivity()).colIsOpen()) {
          // retry
          options.add(res.getString(R.string.backup_retry_opening));
          values.add(0);
        } else {
          // fix integrity
          options.add(res.getString(R.string.check_db));
          values.add(1);
        }
        // repair db with sqlite
        if (sqliteInstalled) {
          options.add(res.getString(R.string.backup_error_menu_repair));
          values.add(2);
        }
        // // restore from backup
        options.add(res.getString(R.string.backup_restore));
        values.add(3);
        // delete old collection and build new one
        options.add(res.getString(R.string.backup_full_sync_from_server));
        values.add(4);
        // delete old collection and build new one
        options.add(res.getString(R.string.backup_del_collection));
        values.add(5);

        String[] titles = new String[options.size()];
        mRepairValues = new int[options.size()];
        for (int i = 0; i < options.size(); i++) {
          titles[i] = options.get(i);
          mRepairValues[i] = values.get(i);
        }

        dialog =
            builder
                .iconAttr(R.attr.dialogErrorIcon)
                .negativeText(res.getString(R.string.dialog_cancel))
                .items(titles)
                .itemsCallback(
                    new MaterialDialog.ListCallback() {
                      @Override
                      public void onSelection(
                          MaterialDialog materialDialog,
                          View view,
                          int which,
                          CharSequence charSequence) {
                        switch (mRepairValues[which]) {
                          case 0:
                            ((DeckPicker) getActivity()).restartActivity();
                            return;
                          case 1:
                            ((DeckPicker) getActivity())
                                .showDatabaseErrorDialog(DIALOG_CONFIRM_DATABASE_CHECK);
                            return;
                          case 2:
                            ((DeckPicker) getActivity())
                                .showDatabaseErrorDialog(DIALOG_REPAIR_COLLECTION);
                            return;
                          case 3:
                            ((DeckPicker) getActivity())
                                .showDatabaseErrorDialog(DIALOG_RESTORE_BACKUP);
                            return;
                          case 4:
                            ((DeckPicker) getActivity())
                                .showDatabaseErrorDialog(DIALOG_FULL_SYNC_FROM_SERVER);
                            return;
                          case 5:
                            ((DeckPicker) getActivity())
                                .showDatabaseErrorDialog(DIALOG_NEW_COLLECTION);
                        }
                      }
                    })
                .show();
        return dialog;

      case DIALOG_REPAIR_COLLECTION:
        // Allow user to run BackupManager.repairCollection()
        return builder
            .content(getMessage())
            .iconAttr(R.attr.dialogErrorIcon)
            .positiveText(res.getString(R.string.dialog_positive_repair))
            .negativeText(res.getString(R.string.dialog_cancel))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).repairDeck();
                    dismissAllDialogFragments();
                  }
                })
            .show();

      case DIALOG_RESTORE_BACKUP:
        // Allow user to restore one of the backups
        String path = CollectionHelper.getInstance().getCollectionPath(getActivity());
        File[] files = BackupManager.getBackups(new File(path));
        mBackups = new File[files.length];
        for (int i = 0; i < files.length; i++) {
          mBackups[i] = files[files.length - 1 - i];
        }
        if (mBackups.length == 0) {
          builder
              .title(res.getString(R.string.backup_restore))
              .content(getMessage())
              .positiveText(res.getString(R.string.dialog_ok))
              .callback(
                  new MaterialDialog.ButtonCallback() {
                    @Override
                    public void onPositive(MaterialDialog dialog) {
                      ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_ERROR_HANDLING);
                    }
                  });
        } else {
          String[] dates = new String[mBackups.length];
          for (int i = 0; i < mBackups.length; i++) {
            dates[i] =
                mBackups[i]
                    .getName()
                    .replaceAll(".*-(\\d{4}-\\d{2}-\\d{2})-(\\d{2})-(\\d{2}).apkg", "$1 ($2:$3 h)");
          }
          builder
              .title(res.getString(R.string.backup_restore_select_title))
              .negativeText(res.getString(R.string.dialog_cancel))
              .callback(
                  new MaterialDialog.ButtonCallback() {
                    @Override
                    public void onNegative(MaterialDialog dialog) {
                      dismissAllDialogFragments();
                    }
                  })
              .items(dates)
              .itemsCallbackSingleChoice(
                  dates.length,
                  new MaterialDialog.ListCallbackSingleChoice() {
                    @Override
                    public boolean onSelection(
                        MaterialDialog materialDialog,
                        View view,
                        int which,
                        CharSequence charSequence) {
                      if (mBackups[which].length() > 0) {
                        // restore the backup if it's valid
                        ((DeckPicker) getActivity()).restoreFromBackup(mBackups[which].getPath());
                        dismissAllDialogFragments();
                      } else {
                        // otherwise show an error dialog
                        new MaterialDialog.Builder(getActivity())
                            .title(R.string.backup_error)
                            .content(R.string.backup_invalid_file_error)
                            .positiveText(R.string.dialog_ok)
                            .build()
                            .show();
                      }
                      return true;
                    }
                  });
        }
        return builder.show();

      case DIALOG_NEW_COLLECTION:
        // Allow user to create a new empty collection
        return builder
            .content(getMessage())
            .positiveText(res.getString(R.string.dialog_positive_create))
            .negativeText(res.getString(R.string.dialog_cancel))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    CollectionHelper.getInstance().closeCollection(false);
                    String path = CollectionHelper.getCollectionPath(getActivity());
                    if (BackupManager.moveDatabaseToBrokenFolder(path, false)) {
                      ((DeckPicker) getActivity()).restartActivity();
                    } else {
                      ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_LOAD_FAILED);
                    }
                  }
                })
            .show();

      case DIALOG_CONFIRM_DATABASE_CHECK:
        // Confirmation dialog for database check
        return builder
            .content(getMessage())
            .positiveText(res.getString(R.string.dialog_ok))
            .negativeText(res.getString(R.string.dialog_cancel))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).integrityCheck();
                    dismissAllDialogFragments();
                  }
                })
            .show();

      case DIALOG_CONFIRM_RESTORE_BACKUP:
        // Confirmation dialog for backup restore
        return builder
            .content(getMessage())
            .positiveText(res.getString(R.string.dialog_continue))
            .negativeText(res.getString(R.string.dialog_cancel))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_RESTORE_BACKUP);
                  }
                })
            .show();

      case DIALOG_FULL_SYNC_FROM_SERVER:
        // Allow user to do a full-sync from the server
        return builder
            .content(getMessage())
            .positiveText(res.getString(R.string.dialog_positive_overwrite))
            .negativeText(res.getString(R.string.dialog_cancel))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).sync("download");
                    dismissAllDialogFragments();
                  }
                })
            .show();

      default:
        return null;
    }
  }