Search in sources :

Example 1 with Note

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

the class PreviewClass method setInterface.

private void setInterface() {
    if (mCurrentCard == null) {
        return;
    }
    if (mSimpleInterface) {
        Note note = mCurrentCard.note();
        mCurrentSimpleInterface = true;
        for (String s : mSimpleInterfaceExcludeTags) {
            if (note.hasTag(s)) {
                mCurrentSimpleInterface = false;
                break;
            }
        }
    }
    if (mCurrentSimpleInterface) {
        if (mSimpleCard == null) {
            mSimpleCard = new ScrollTextView(this);
            Themes.setRegularFont(mSimpleCard);
            mSimpleCard.setTextSize(mSimpleCard.getTextSize() * mDisplayFontSize / 100);
            mSimpleCard.setGravity(Gravity.CENTER);
            try {
                mSetTextIsSelectable = TextView.class.getMethod("setTextIsSelectable", boolean.class);
            } catch (Throwable e) {
                // Log.i(AnkiDroidApp.TAG, "mSetTextIsSelectable could not be found due to a too low Android version (< 3.0)");
                mSetTextIsSelectable = null;
            }
            if (mSetTextIsSelectable != null) {
                try {
                    mSetTextIsSelectable.invoke(mSimpleCard, true);
                } catch (Exception e) {
                    Log.e(AnkiDroidApp.TAG, e.toString());
                }
            }
            mSimpleCard.setClickable(true);
            mCardFrame.addView(mSimpleCard);
            mSimpleCard.setBackgroundColor(mCurrentBackgroundColor);
            mSimpleCard.setTextColor(mForegroundColor);
        }
        if (mSimpleCard.getVisibility() != View.VISIBLE || (mCard != null && mCard.getVisibility() == View.VISIBLE)) {
            mSimpleCard.setVisibility(View.VISIBLE);
            mCard.setVisibility(View.GONE);
        }
    } else {
        if (mCard == null) {
            mCard = createWebView();
            mCardFrame.addView(mCard);
            if (mRefreshWebview) {
                mNextCard = createWebView();
                mNextCard.setVisibility(View.GONE);
                mCardFrame.addView(mNextCard, 0);
                mCard.setBackgroundColor(mCurrentBackgroundColor);
                mCustomFontStyle = getCustomFontsStyle() + getDefaultFontStyle();
            }
        }
        if (mCard.getVisibility() != View.VISIBLE || (mSimpleCard != null && mSimpleCard.getVisibility() == View.VISIBLE)) {
            mSimpleCard.setVisibility(View.GONE);
            mCard.setVisibility(View.VISIBLE);
        }
    }
}
Also used : ScrollTextView(com.ichi2.anki.Reviewer.ScrollTextView) Note(com.ichi2.libanki.Note) TextView(android.widget.TextView) ScrollTextView(com.ichi2.anki.Reviewer.ScrollTextView) SpannedString(android.text.SpannedString) SpannableString(android.text.SpannableString) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException)

Example 2 with Note

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

the class Connection method doInBackgroundUpgradeDecks.

private Payload doInBackgroundUpgradeDecks(Payload data) {
    // Enable http request canceller
    mCancelCallback = new CancelCallback();
    String path = (String) data.data[0];
    File ankiDir = new File(path);
    if (!ankiDir.isDirectory()) {
        data.success = false;
        data.data = new Object[] { "wrong anki directory" };
        return data;
    }
    // step 1: gather all .anki files into a zip, without media.
    // we must store them as 1.anki, 2.anki and provide a map so we don't run into
    // encoding issues with the zip file.
    File[] fileList = ankiDir.listFiles(new OldAnkiDeckFilter());
    List<String> corruptFiles = new ArrayList<String>();
    JSONObject map = new JSONObject();
    byte[] buf = new byte[1024];
    String zipFilename = path + "/upload.zip";
    String colFilename = path + AnkiDroidApp.COLLECTION_PATH;
    try {
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFilename));
        int n = 1;
        for (File f : fileList) {
            String deckPath = f.getAbsolutePath();
            // set journal mode to delete
            try {
                AnkiDb d = AnkiDatabaseManager.getDatabase(deckPath);
            } catch (SQLiteDatabaseCorruptException e) {
                // ignore invalid .anki files
                corruptFiles.add(f.getName());
                continue;
            } finally {
                AnkiDatabaseManager.closeDatabase(deckPath);
            }
            // zip file
            String tmpName = n + ".anki";
            FileInputStream in = new FileInputStream(deckPath);
            ZipEntry ze = new ZipEntry(tmpName);
            zos.putNextEntry(ze);
            int len;
            while ((len = in.read(buf)) >= 0) {
                zos.write(buf, 0, len);
            }
            zos.closeEntry();
            map.put(tmpName, f.getName());
            n++;
        }
        // if all .anki files were found corrupted, abort
        if (fileList.length == corruptFiles.size()) {
            data.success = false;
            data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_failed) };
            return data;
        }
        ZipEntry ze = new ZipEntry("map.json");
        zos.putNextEntry(ze);
        InputStream in = new ByteArrayInputStream(Utils.jsonToString(map).getBytes("UTF-8"));
        int len;
        while ((len = in.read(buf)) >= 0) {
            zos.write(buf, 0, len);
        }
        zos.closeEntry();
        zos.close();
    } catch (FileNotFoundException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (JSONException e) {
        throw new RuntimeException(e);
    }
    File zipFile = new File(zipFilename);
    // step 1.1: if it's over 50MB compressed, it must be upgraded by the user
    if (zipFile.length() > 50 * 1024 * 1024) {
        data.success = false;
        data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_exceeds) };
        return data;
    }
    // step 2: upload zip file to upgrade service and get token
    BasicHttpSyncer h = new BasicHttpSyncer(null, null);
    // note: server doesn't expect it to be gzip compressed, because the zip file is compressed
    // enable cancelling
    publishProgress(R.string.upgrade_decks_upload, null, true);
    try {
        HttpResponse resp = h.req("upgrade/upload", new FileInputStream(zipFile), 0, false, null, mCancelCallback);
        if (resp == null && !isCancelled()) {
            data.success = false;
            data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_failed) };
            return data;
        }
        String result;
        String key = null;
        if (!isCancelled()) {
            result = h.stream2String(resp.getEntity().getContent());
            if (result != null && result.startsWith("ok:")) {
                key = result.split(":")[1];
            } else {
                data.success = false;
                data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_failed) };
                return data;
            }
        }
        while (!isCancelled()) {
            result = h.stream2String(h.req("upgrade/status?key=" + key).getEntity().getContent());
            if (result.equals("error")) {
                data.success = false;
                data.data = new Object[] { "error" };
                return data;
            } else if (result.startsWith("waiting:")) {
                publishProgress(R.string.upgrade_decks_upload, result.split(":")[1]);
            } else if (result.equals("upgrading")) {
                publishProgress(new Object[] { R.string.upgrade_decks_upgrade_started });
            } else if (result.equals("ready")) {
                break;
            } else {
                data.success = false;
                data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_failed) };
                return data;
            }
            Thread.sleep(1000);
        }
        // gzip compression if the client says it can handle it
        if (!isCancelled()) {
            publishProgress(new Object[] { R.string.upgrade_decks_downloading });
            resp = h.req("upgrade/download?key=" + key, null, 6, true, null, mCancelCallback);
        // uploads/downloads have finished so disable cancelling
        }
        publishProgress(R.string.upgrade_decks_downloading, null, false);
        if (isCancelled()) {
            return null;
        }
        if (resp == null) {
            data.success = false;
            data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_failed) };
            return data;
        }
        // step 5: check the received file is valid
        InputStream cont = resp.getEntity().getContent();
        if (!h.writeToFile(cont, colFilename)) {
            data.success = false;
            data.data = new Object[] { sContext.getString(R.string.upgrade_deck_web_upgrade_sdcard, new File(colFilename).length() / 1048576 + 1) };
            (new File(colFilename)).delete();
            return data;
        }
        // check the received file is ok
        publishProgress(new Object[] { R.string.sync_check_download_file });
        publishProgress(R.string.sync_check_download_file);
        try {
            AnkiDb d = AnkiDatabaseManager.getDatabase(colFilename);
            if (!d.queryString("PRAGMA integrity_check").equalsIgnoreCase("ok")) {
                data.success = false;
                data.data = new Object[] { sContext.getResources() };
                return data;
            }
        } finally {
            AnkiDatabaseManager.closeDatabase(colFilename);
        }
        Collection col = AnkiDroidApp.openCollection(colFilename);
        ArrayList<String> decks = col.getDecks().allNames(false);
        ArrayList<String> failed = new ArrayList<String>();
        ArrayList<File> mediaDirs = new ArrayList<File>();
        for (File f : fileList) {
            String name = f.getName().replaceFirst("\\.anki$", "");
            if (!decks.contains(name)) {
                failed.add(name);
            } else {
                mediaDirs.add(new File(f.getAbsolutePath().replaceFirst("\\.anki$", ".media")));
            }
        }
        File newMediaDir = new File(col.getMedia().getDir());
        // step 6. move media files to new media directory
        publishProgress(new Object[] { R.string.upgrade_decks_media });
        ArrayList<String> failedMedia = new ArrayList<String>();
        File curMediaDir = null;
        for (File mediaDir : mediaDirs) {
            curMediaDir = mediaDir;
            // Check if media directory exists and is local
            if (!curMediaDir.exists() || !curMediaDir.isDirectory()) {
                // If not try finding it in dropbox 1.2.x
                curMediaDir = new File(AnkiDroidApp.getDropboxDir(), mediaDir.getName());
                if (!curMediaDir.exists() || !curMediaDir.isDirectory()) {
                    // No media for this deck
                    continue;
                }
            }
            // Found media dir, copy files
            for (File m : curMediaDir.listFiles()) {
                try {
                    Utils.copyFile(m, new File(newMediaDir, m.getName()));
                } catch (IOException e) {
                    failedMedia.add(curMediaDir.getName().replaceFirst("\\.media$", ".anki"));
                    break;
                }
            }
        }
        data.data = new Object[] { failed, failedMedia, newMediaDir.getAbsolutePath() };
        data.success = true;
        return data;
    } catch (FileNotFoundException e) {
        throw new RuntimeException(e);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    } catch (IllegalStateException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        throw new RuntimeException(e);
    } finally {
        (new File(zipFilename)).delete();
    }
}
Also used : ZipEntry(java.util.zip.ZipEntry) ArrayList(java.util.ArrayList) FileNotFoundException(java.io.FileNotFoundException) SQLiteDatabaseCorruptException(android.database.sqlite.SQLiteDatabaseCorruptException) AnkiDb(com.ichi2.anki.AnkiDb) BufferedInputStream(java.io.BufferedInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) JSONException(org.json.JSONException) HttpResponse(org.apache.http.HttpResponse) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) BasicHttpSyncer(com.ichi2.libanki.sync.BasicHttpSyncer) JSONObject(org.json.JSONObject) ByteArrayInputStream(java.io.ByteArrayInputStream) ZipOutputStream(java.util.zip.ZipOutputStream) FileOutputStream(java.io.FileOutputStream) Collection(com.ichi2.libanki.Collection) JSONObject(org.json.JSONObject) File(java.io.File)

Example 3 with Note

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

the class MultimediaCardEditorActivity method changeCurrentModel.

/**
     * Change current model for the Note. Changes both MultimediaNote and the mEditorNote (Note Object) and copies
     * existing values to both.
     * 
     * @param newId
     */
protected void changeCurrentModel(long newId) {
    try {
        JSONObject currentModel = mCol.getModels().get(newId);
        mCol.getModels().setCurrent(currentModel);
        JSONObject cdeck = mCol.getDecks().current();
        cdeck.put("mid", newId);
        mCol.getDecks().save(cdeck);
        int size = mNote.getNumberOfFields();
        String[] oldValues = new String[size];
        for (int i = 0; i < size; i++) {
            oldValues[i] = mNote.getField(i).getFormattedValue();
        }
        mEditorNote = new Note(mCol, currentModel);
        mEditorNote.model().put("did", mCurrentDid);
        MultimediaEditableNote newNote = NoteService.createEmptyNote(currentModel);
        for (int i = 0; i < newNote.getNumberOfFields(); i++) {
            if (i < mNote.getNumberOfFields()) {
                newNote.setField(i, mNote.getField(i));
            }
        }
        mNote = newNote;
    } catch (JSONException e) {
        Log.e("Multimedia Editor", e.getMessage());
    }
}
Also used : IMultimediaEditableNote(com.ichi2.anki.multimediacard.IMultimediaEditableNote) MultimediaEditableNote(com.ichi2.anki.multimediacard.impl.MultimediaEditableNote) JSONObject(org.json.JSONObject) Note(com.ichi2.libanki.Note) IMultimediaEditableNote(com.ichi2.anki.multimediacard.IMultimediaEditableNote) MultimediaEditableNote(com.ichi2.anki.multimediacard.impl.MultimediaEditableNote) JSONException(org.json.JSONException) SuppressLint(android.annotation.SuppressLint)

Example 4 with Note

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

the class MultimediaCardEditorActivity method createEditorUI.

/**
     * Creates the UI for editor area inside EditorLayout
     * 
     * @param note
     */
private void createEditorUI(IMultimediaEditableNote note) {
    try {
        if (mNote == null) {
            finishCancel();
            return;
        } else {
            for (int i = 0; i < mNote.getNumberOfFields(); ++i) {
                IField f = mNote.getField(i);
                if (f == null) {
                    finishCancel();
                    return;
                }
            }
        }
        LinearLayout linearLayout = mEditorLayout;
        linearLayout.removeAllViews();
        for (int i = 0; i < note.getNumberOfFields(); ++i) {
            createNewViewer(linearLayout, note.getField(i), i);
        }
        mModelButton.setText(gtxt(R.string.multimedia_editor_activity_note_type) + " : " + mEditorNote.model().getString("name"));
        mDeckButton.setText(gtxt(R.string.multimedia_editor_activity_deck) + " : " + mCol.getDecks().get(mCurrentDid).getString("name"));
    } catch (JSONException e) {
        Log.e("Multimedia Editor", e.getMessage());
        return;
    }
}
Also used : JSONException(org.json.JSONException) IField(com.ichi2.anki.multimediacard.fields.IField) SuppressLint(android.annotation.SuppressLint) LinearLayout(android.widget.LinearLayout)

Example 5 with Note

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

the class MultimediaCardEditorActivity method initData.

/**
     * If a note has been passed, loads it. Otherwise creates a new Note It checks for a noteId, a long value with
     * EXTRA_NOTE_ID as key. If not 0, edits the note, else creates a new note
     */
private void initData() {
    try {
        mCol = AnkiDroidApp.getCol();
        Intent callerIntent = getIntent();
        long cardId = callerIntent.getLongExtra(EXTRA_CARD_ID, 0);
        if (cardId != 0) {
            mCard = mCol.getCard(cardId);
            mCurrentDid = mCard.getDid();
            mEditorNote = mCard.note();
            mCol.getModels().setCurrent(mEditorNote.model());
            mNote = NoteService.createEmptyNote(mEditorNote.model());
            NoteService.updateMultimediaNoteFromJsonNote(mEditorNote, mNote);
            mAddNote = false;
        } else {
            mCurrentDid = mCol.getDecks().current().getLong("id");
            if (mCol.getDecks().isDyn(mCurrentDid)) {
                mCurrentDid = 1;
            }
            mAddNote = true;
            JSONObject currentModel = mCol.getModels().current();
            mNote = NoteService.createEmptyNote(currentModel);
            if (mNote == null) {
                Log.e("Multimedia Editor", "Cannot create a Note");
                throw new Exception("Could not create a not");
            }
            mEditorNote = new Note(mCol, currentModel);
            mEditorNote.model().put("did", mCurrentDid);
        }
    // TODO take care of tags @see CardEditor setNote(Note)
    } catch (Exception e) {
        Log.e("Multimedia Editor", e.getMessage());
        finishCancel();
        return;
    }
}
Also used : JSONObject(org.json.JSONObject) Note(com.ichi2.libanki.Note) IMultimediaEditableNote(com.ichi2.anki.multimediacard.IMultimediaEditableNote) MultimediaEditableNote(com.ichi2.anki.multimediacard.impl.MultimediaEditableNote) Intent(android.content.Intent) JSONException(org.json.JSONException)

Aggregations

Note (com.ichi2.libanki.Note)11 JSONException (org.json.JSONException)11 JSONObject (org.json.JSONObject)8 IMultimediaEditableNote (com.ichi2.anki.multimediacard.IMultimediaEditableNote)7 MultimediaEditableNote (com.ichi2.anki.multimediacard.impl.MultimediaEditableNote)6 Collection (com.ichi2.libanki.Collection)6 TextField (com.ichi2.anki.multimediacard.fields.TextField)4 Card (com.ichi2.libanki.Card)4 AnkiDb (com.ichi2.anki.AnkiDb)3 IField (com.ichi2.anki.multimediacard.fields.IField)3 ImageField (com.ichi2.anki.multimediacard.fields.ImageField)3 Sched (com.ichi2.libanki.Sched)3 IOException (java.io.IOException)3 JSONArray (org.json.JSONArray)3 SuppressLint (android.annotation.SuppressLint)2 Intent (android.content.Intent)2 Resources (android.content.res.Resources)2 SpannableString (android.text.SpannableString)2 SpannedString (android.text.SpannedString)2 TextView (android.widget.TextView)2