Search in sources :

Example 6 with Decks

use of com.ichi2.libanki.Decks in project Anki-Android by Ramblurr.

the class DownloadManagerService method resumeDownload.

// It could be part of the AIDL Interface but at the moment no Activity uses it directly
public void resumeDownload(Download download) {
    // Create tmp folder where the temporal decks are going to be stored
    new File(mDestination + "/tmp/").mkdirs();
    AnkiDroidApp.createNoMediaFileIfMissing(new File(mDestination));
    if (download instanceof SharedDeckDownload) {
        SharedDeckDownload sharedDeckDownload = (SharedDeckDownload) download;
        // numUpdatedCards and numTotalCards to get updated, so that progress is displayed correctly
        if (sharedDeckDownload.getStatus() == SharedDeckDownload.STATUS_PAUSED || sharedDeckDownload.getStatus() == SharedDeckDownload.STATUS_UPDATING) {
            new UpdateDeckTask().execute(new Payload(new Object[] { sharedDeckDownload }));
        } else {
            new DownloadSharedDeckTask().execute(sharedDeckDownload);
        }
    } else {
        // TODO: Check if there is already a deck with the same name, and if that's so
        // add the current milliseconds to the end of the name or notify the user
        new DownloadPersonalDeckTask().execute(download);
    }
}
Also used : Payload(com.ichi2.async.Connection.Payload) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) SharedDeckDownload(com.ichi2.anki.SharedDeckDownload)

Example 7 with Decks

use of com.ichi2.libanki.Decks in project Anki-Android by Ramblurr.

the class Storage method check.

/*
     * Upgrading ************************************************************
     */
// public void upgrade(String path) {
// // mPath = path;
// // _openDB(path);
// // upgradeSchema();
// // _openCol();
// // _upgradeRest();
// // return mCol;
// }
/*
     * Integrity checking ************************************************************
     */
public static boolean check(String path) {
    AnkiDb db = AnkiDatabaseManager.getDatabase(path);
    // corrupt?
    try {
        if (!db.queryString("PRAGMA integrity_check").equalsIgnoreCase("ok")) {
            return false;
        }
    } catch (SQLException _) {
        return false;
    }
    // old version?
    if (db.queryScalar("SELECT version FROM decks") < 65) {
        return false;
    }
    // ensure we have indices for checks below
    db.execute("create index if not exists ix_cards_factId on cards (factId)");
    db.execute("create index if not exists ix_fields_factId on fieldModels (factId)");
    db.execute("analyze");
    // fields missing a field model?
    if (db.queryColumn(Integer.class, "select id from fields where fieldModelId not in (" + "select distinct id from fieldModels)", 0).size() > 0) {
        return false;
    }
    // facts missing a field?
    if (db.queryColumn(Integer.class, "select distinct facts.id from facts, fieldModels where " + "facts.modelId = fieldModels.modelId and fieldModels.id not in " + "(select fieldModelId from fields where factId = facts.id)", 0).size() > 0) {
        return false;
    }
    // cards missing a fact?
    if (db.queryColumn(Integer.class, "select id from cards where factId not in (select id from facts)", 0).size() > 0) {
        return false;
    }
    // cards missing a card model?
    if (db.queryColumn(Integer.class, "select id from cards where cardModelId not in (select id from cardModels)", 0).size() > 0) {
        return false;
    }
    // cards with a card model from the wrong model?
    if (db.queryColumn(Integer.class, "select id from cards where cardModelId not in (select cm.id from " + "cardModels cm, facts f where cm.modelId = f.modelId and " + "f.id = cards.factId)", 0).size() > 0) {
        return false;
    }
    // facts missing a card?
    if (db.queryColumn(Integer.class, "select facts.id from facts " + "where facts.id not in (select distinct factId from cards)", 0).size() > 0) {
        return false;
    }
    // dangling fields?
    if (db.queryColumn(Integer.class, "select id from fields where factId not in (select id from facts)", 0).size() > 0) {
        return false;
    }
    // fields without matching interval
    if (db.queryColumn(Integer.class, "select id from fields where ordinal != (select ordinal from fieldModels " + "where id = fieldModelId)", 0).size() > 0) {
        return false;
    }
    // incorrect types
    if (db.queryColumn(Integer.class, "select id from cards where relativeDelay != (case " + "when successive then 1 when reps then 0 else 2 end)", 0).size() > 0) {
        return false;
    }
    if (db.queryColumn(Integer.class, "select id from cards where type != (case " + "when type >= 0 then relativeDelay else relativeDelay - 3 end)", 0).size() > 0) {
        return false;
    }
    return true;
}
Also used : AnkiDb(com.ichi2.anki.AnkiDb) SQLException(android.database.SQLException)

Example 8 with Decks

use of com.ichi2.libanki.Decks in project Anki-Android by Ramblurr.

the class CardEditor method onCreateDialog.

@Override
protected Dialog onCreateDialog(int id) {
    StyledDialog dialog = null;
    Resources res = getResources();
    StyledDialog.Builder builder = new StyledDialog.Builder(this);
    switch(id) {
        case DIALOG_TAGS_SELECT:
            builder.setTitle(R.string.card_details_tags);
            builder.setPositiveButton(res.getString(R.string.select), new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if (mAddNote) {
                        try {
                            JSONArray ja = new JSONArray();
                            for (String t : selectedTags) {
                                ja.put(t);
                            }
                            mCol.getModels().current().put("tags", ja);
                            mCol.getModels().setChanged();
                        } catch (JSONException e) {
                            throw new RuntimeException(e);
                        }
                        mEditorNote.setTags(selectedTags);
                    }
                    mCurrentTags = selectedTags;
                    updateTags();
                }
            });
            builder.setNegativeButton(res.getString(R.string.cancel), null);
            mNewTagEditText = (EditText) new EditText(this);
            mNewTagEditText.setHint(R.string.add_new_tag);
            InputFilter filter = new InputFilter() {

                public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                    for (int i = start; i < end; i++) {
                        if (source.charAt(i) == ' ' || source.charAt(i) == ',') {
                            return "";
                        }
                    }
                    return null;
                }
            };
            mNewTagEditText.setFilters(new InputFilter[] { filter });
            ImageView mAddTextButton = new ImageView(this);
            mAddTextButton.setImageResource(R.drawable.ic_addtag);
            mAddTextButton.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    String tag = mNewTagEditText.getText().toString();
                    if (tag.length() != 0) {
                        if (mEditorNote.hasTag(tag)) {
                            mNewTagEditText.setText("");
                            return;
                        }
                        selectedTags.add(tag);
                        actualizeTagDialog(mTagsDialog);
                        mNewTagEditText.setText("");
                    }
                }
            });
            FrameLayout frame = new FrameLayout(this);
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.RIGHT | Gravity.CENTER_VERTICAL);
            params.rightMargin = 10;
            mAddTextButton.setLayoutParams(params);
            frame.addView(mNewTagEditText);
            frame.addView(mAddTextButton);
            builder.setView(frame, false, true);
            dialog = builder.create();
            mTagsDialog = dialog;
            break;
        case DIALOG_DECK_SELECT:
            ArrayList<CharSequence> dialogDeckItems = new ArrayList<CharSequence>();
            // Use this array to know which ID is associated with each
            // Item(name)
            final ArrayList<Long> dialogDeckIds = new ArrayList<Long>();
            ArrayList<JSONObject> decks = mCol.getDecks().all();
            Collections.sort(decks, new JSONNameComparator());
            builder.setTitle(R.string.deck);
            for (JSONObject d : decks) {
                try {
                    if (d.getInt("dyn") == 0) {
                        dialogDeckItems.add(d.getString("name"));
                        dialogDeckIds.add(d.getLong("id"));
                    }
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
            // Convert to Array
            String[] items = new String[dialogDeckItems.size()];
            dialogDeckItems.toArray(items);
            builder.setItems(items, new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int item) {
                    long newId = dialogDeckIds.get(item);
                    if (mCurrentDid != newId) {
                        if (mAddNote) {
                            try {
                                // TODO: mEditorNote.setDid(newId);
                                mEditorNote.model().put("did", newId);
                                mCol.getModels().setChanged();
                            } catch (JSONException e) {
                                throw new RuntimeException(e);
                            }
                        }
                        mCurrentDid = newId;
                        updateDeck();
                    }
                }
            });
            dialog = builder.create();
            mDeckSelectDialog = dialog;
            break;
        case DIALOG_MODEL_SELECT:
            ArrayList<CharSequence> dialogItems = new ArrayList<CharSequence>();
            // Use this array to know which ID is associated with each
            // Item(name)
            final ArrayList<Long> dialogIds = new ArrayList<Long>();
            ArrayList<JSONObject> models = mCol.getModels().all();
            Collections.sort(models, new JSONNameComparator());
            builder.setTitle(R.string.note_type);
            for (JSONObject m : models) {
                try {
                    dialogItems.add(m.getString("name"));
                    dialogIds.add(m.getLong("id"));
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
            // Convert to Array
            String[] items2 = new String[dialogItems.size()];
            dialogItems.toArray(items2);
            builder.setItems(items2, new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int item) {
                    long oldModelId;
                    try {
                        oldModelId = mCol.getModels().current().getLong("id");
                    } catch (JSONException e) {
                        throw new RuntimeException(e);
                    }
                    long newId = dialogIds.get(item);
                    if (oldModelId != newId) {
                        mCol.getModels().setCurrent(mCol.getModels().get(newId));
                        JSONObject cdeck = mCol.getDecks().current();
                        try {
                            cdeck.put("mid", newId);
                        } catch (JSONException e) {
                            throw new RuntimeException(e);
                        }
                        mCol.getDecks().save(cdeck);
                        int size = mEditFields.size();
                        String[] oldValues = new String[size];
                        for (int i = 0; i < size; i++) {
                            oldValues[i] = mEditFields.get(i).getText().toString();
                        }
                        setNote();
                        resetEditFields(oldValues);
                        mTimerHandler.removeCallbacks(checkDuplicatesRunnable);
                        duplicateCheck(false);
                    }
                }
            });
            dialog = builder.create();
            break;
        case DIALOG_RESET_CARD:
            builder.setTitle(res.getString(R.string.reset_card_dialog_title));
            builder.setMessage(res.getString(R.string.reset_card_dialog_message));
            builder.setPositiveButton(res.getString(R.string.yes), new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                // for (long cardId :
                // mDeck.getCardsFromFactId(mEditorNote.getId())) {
                // mDeck.cardFromId(cardId).resetCard();
                // }
                // mDeck.reset();
                // setResult(Reviewer.RESULT_EDIT_CARD_RESET);
                // mCardReset = true;
                // Themes.showThemedToast(CardEditor.this,
                // getResources().getString(
                // R.string.reset_card_dialog_confirmation), true);
                }
            });
            builder.setNegativeButton(res.getString(R.string.no), null);
            builder.setCancelable(true);
            dialog = builder.create();
            break;
        case DIALOG_INTENT_INFORMATION:
            dialog = createDialogIntentInformation(builder, res);
    }
    return dialog;
}
Also used : DialogInterface(android.content.DialogInterface) Builder(com.ichi2.themes.StyledDialog.Builder) StyledDialog(com.ichi2.themes.StyledDialog) ArrayList(java.util.ArrayList) ImageView(android.widget.ImageView) EditText(android.widget.EditText) InputFilter(android.text.InputFilter) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) Spanned(android.text.Spanned) ImageView(android.widget.ImageView) View(android.view.View) AdapterView(android.widget.AdapterView) TextView(android.widget.TextView) ListView(android.widget.ListView) OnClickListener(android.content.DialogInterface.OnClickListener) JSONObject(org.json.JSONObject) FrameLayout(android.widget.FrameLayout) Builder(com.ichi2.themes.StyledDialog.Builder) OnClickListener(android.content.DialogInterface.OnClickListener) Resources(android.content.res.Resources)

Example 9 with Decks

use of com.ichi2.libanki.Decks in project Anki-Android by Ramblurr.

the class MetaDB method getWidgetStatus.

/**
     * Return the current status of the widget.
     * 
     * @return an array of {@link DeckStatus} objects, each representing the status of one of the known decks
     */
public static DeckStatus[] getWidgetStatus(Context context) {
    openDBIfClosed(context);
    Cursor cursor = null;
    try {
        cursor = mMetaDb.query("widgetStatus", new String[] { "deckId", "deckName", "newCards", "lrnCards", "dueCards", "progress", "eta" }, null, null, null, null, "deckName");
        int count = cursor.getCount();
        DeckStatus[] decks = new DeckStatus[count];
        for (int index = 0; index < count; ++index) {
            if (!cursor.moveToNext()) {
                throw new SQLiteException("cursor count was incorrect");
            }
            decks[index] = new DeckStatus(cursor.getLong(cursor.getColumnIndexOrThrow("deckId")), cursor.getString(cursor.getColumnIndexOrThrow("deckName")), cursor.getInt(cursor.getColumnIndexOrThrow("newCards")), cursor.getInt(cursor.getColumnIndexOrThrow("lrnCards")), cursor.getInt(cursor.getColumnIndexOrThrow("dueCards")), cursor.getInt(cursor.getColumnIndexOrThrow("progress")), cursor.getInt(cursor.getColumnIndexOrThrow("eta")));
        }
        return decks;
    } catch (SQLiteException e) {
        Log.e(AnkiDroidApp.TAG, "Error while querying widgetStatus", e);
    } finally {
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
    }
    return new DeckStatus[0];
}
Also used : DeckStatus(com.ichi2.widget.DeckStatus) Cursor(android.database.Cursor) SQLiteException(android.database.sqlite.SQLiteException)

Example 10 with Decks

use of com.ichi2.libanki.Decks in project Anki-Android by Ramblurr.

the class DeckPicker method showStartupScreensAndDialogs.

private void showStartupScreensAndDialogs(SharedPreferences preferences, int skip) {
    if (skip < 1 && preferences.getLong("lastTimeOpened", 0) == 0) {
        Intent infoIntent = new Intent(this, Info.class);
        infoIntent.putExtra(Info.TYPE_EXTRA, Info.TYPE_WELCOME);
        startActivityForResult(infoIntent, SHOW_INFO_WELCOME);
        if (skip != 0 && AnkiDroidApp.SDK_VERSION > 4) {
            ActivityTransitionAnimation.slide(this, ActivityTransitionAnimation.LEFT);
        }
    } else if (skip < 2 && !preferences.getString("lastVersion", "").equals(AnkiDroidApp.getPkgVersionName())) {
        preferences.edit().putBoolean("showBroadcastMessageToday", true).commit();
        Intent infoIntent = new Intent(this, Info.class);
        infoIntent.putExtra(Info.TYPE_EXTRA, Info.TYPE_NEW_VERSION);
        startActivityForResult(infoIntent, SHOW_INFO_NEW_VERSION);
        if (skip != 0 && AnkiDroidApp.SDK_VERSION > 4) {
            ActivityTransitionAnimation.slide(this, ActivityTransitionAnimation.LEFT);
        }
    } else if (skip < 3 && upgradeNeeded()) {
        // Note that the "upgrade needed" refers to upgrading Anki 1.x decks, not to newer
        // versions of AnkiDroid.
        AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext()).edit().putInt("lastUpgradeVersion", AnkiDroidApp.getPkgVersionCode()).commit();
        showUpgradeScreen(skip != 0, Info.UPGRADE_SCREEN_BASIC1);
    } else if (skip < 4 && hasErrorFiles()) {
        Intent i = new Intent(this, Feedback.class);
        startActivityForResult(i, REPORT_ERROR);
        if (skip != 0 && AnkiDroidApp.SDK_VERSION > 4) {
            ActivityTransitionAnimation.slide(this, ActivityTransitionAnimation.LEFT);
        }
    } else if (!AnkiDroidApp.isSdCardMounted()) {
        showDialog(DIALOG_SD_CARD_NOT_MOUNTED);
    } else if (!BackupManager.enoughDiscSpace(mPrefDeckPath)) {
        // && !preferences.getBoolean("dontShowLowMemory",
        // false)) {
        showDialog(DIALOG_NO_SPACE_LEFT);
    } else if (preferences.getBoolean("noSpaceLeft", false)) {
        showDialog(DIALOG_BACKUP_NO_SPACE_LEFT);
        preferences.edit().putBoolean("noSpaceLeft", false).commit();
    } else if (mImportPath != null && AnkiDroidApp.colIsOpen()) {
        showDialog(DIALOG_IMPORT);
    } else {
        // AnkiDroid is being updated and a collection already exists. 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.
        int current = AnkiDroidApp.getPkgVersionCode();
        // a non-final variable, for intermediate calculations
        int previousTemp;
        if (!preferences.contains("lastUpgradeVersion")) {
            // Fresh install
            previousTemp = current;
        } else {
            try {
                previousTemp = preferences.getInt("lastUpgradeVersion", current);
            } catch (ClassCastException e) {
                // Previous versions stored this as a string.
                String s = preferences.getString("lastUpgradeVersion", "");
                // check.
                if (s.equals("2.0.2")) {
                    previousTemp = 40;
                } else {
                    previousTemp = 0;
                }
            }
        }
        final int previous = previousTemp;
        preferences.edit().putInt("lastUpgradeVersion", current).commit();
        if (previous < AnkiDroidApp.CHECK_DB_AT_VERSION || previous < AnkiDroidApp.CHECK_PREFERENCES_AT_VERSION) {
            DeckTask.launchDeckTask(DeckTask.TASK_TYPE_OPEN_COLLECTION, new Listener() {

                @Override
                public void onPostExecute(DeckTask task, TaskData result) {
                    mOpenCollectionHandler.onPostExecute(result);
                    if (previous < AnkiDroidApp.CHECK_DB_AT_VERSION) {
                        integrityCheck();
                    }
                    if (previous < AnkiDroidApp.CHECK_PREFERENCES_AT_VERSION) {
                        upgradePreferences(previous);
                    }
                }

                @Override
                public void onPreExecute(DeckTask task) {
                }

                @Override
                public void onProgressUpdate(DeckTask task, TaskData... values) {
                }
            }, new DeckTask.TaskData(AnkiDroidApp.getCollectionPath()));
        } else {
            loadCollection();
        }
    }
}
Also used : OnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener) OnCancelListener(android.content.DialogInterface.OnCancelListener) SimpleOnGestureListener(android.view.GestureDetector.SimpleOnGestureListener) Listener(com.ichi2.async.DeckTask.Listener) OnClickListener(android.view.View.OnClickListener) Intent(android.content.Intent) ActivityInfo(android.content.pm.ActivityInfo) ContextMenuInfo(android.view.ContextMenu.ContextMenuInfo) DeckTask(com.ichi2.async.DeckTask) TaskData(com.ichi2.async.DeckTask.TaskData)

Aggregations

JSONObject (org.json.JSONObject)6 File (java.io.File)4 JSONException (org.json.JSONException)4 Collection (com.ichi2.libanki.Collection)3 DialogInterface (android.content.DialogInterface)2 SharedPreferences (android.content.SharedPreferences)2 Cursor (android.database.Cursor)2 SQLiteException (android.database.sqlite.SQLiteException)2 AnkiDb (com.ichi2.anki.AnkiDb)2 SharedDeckDownload (com.ichi2.anki.SharedDeckDownload)2 BasicHttpSyncer (com.ichi2.libanki.sync.BasicHttpSyncer)2 BufferedInputStream (java.io.BufferedInputStream)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 FileInputStream (java.io.FileInputStream)2 FileOutputStream (java.io.FileOutputStream)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 RandomAccessFile (java.io.RandomAccessFile)2 ArrayList (java.util.ArrayList)2 SuppressLint (android.annotation.SuppressLint)1