mirror of
https://github.com/ankidroid/Anki-Android.git
synced 2024-09-20 03:52:15 +02:00
add card browser
This commit is contained in:
parent
60c850cd32
commit
fde5066033
@ -4,6 +4,7 @@
|
||||
~ Copyright (c) 2009 Nicolas Raoul <nicolas.raoul@gmail.com>
|
||||
~ Copyright (c) 2009 Edu Zamora <edu.zasu@gmail.com>
|
||||
~ Copyright (c) 2009 Casey Link <unnamedrambler@gmail.com>
|
||||
~ Copyright (c) 2011 Norbert Nagold <norbert.nagold@gmail.com>
|
||||
~
|
||||
~ This program is free software; you can redistribute it and/or modify it under
|
||||
~ the terms of the GNU General Public License as published by the Free Software
|
||||
@ -40,6 +41,9 @@
|
||||
<activity android:name="DeckPicker"
|
||||
android:label="DeckPicker"
|
||||
android:configChanges="keyboardHidden|orientation"/>
|
||||
<activity android:name="CardBrowser"
|
||||
android:label="@string/card_browser_title"
|
||||
android:configChanges="keyboardHidden|orientation"/>
|
||||
<activity android:name="PersonalDeckPicker"
|
||||
android:label="@string/personaldeckpicker_title"
|
||||
android:configChanges="keyboardHidden|orientation"/>
|
||||
|
17
res/layout/card_browser.xml
Normal file
17
res/layout/card_browser.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical">
|
||||
<EditText
|
||||
android:id="@+id/card_browser_search"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:lines="1"
|
||||
android:hint="@string/downloaddeck_search"/>
|
||||
<ListView android:id="@+id/card_browser_list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fastScrollEnabled="true"/>
|
||||
</LinearLayout>
|
18
res/layout/card_item.xml
Normal file
18
res/layout/card_item.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@+id/card_question"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/card_answer"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
</LinearLayout>
|
@ -178,13 +178,21 @@
|
||||
android:textOn="@string/cram"
|
||||
android:layout_marginBottom="1.5dip"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/studyoptions_night_mode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/studyoptions_night_mode"
|
||||
android:layout_marginLeft="4dip"
|
||||
android:layout_weight="1"
|
||||
android:textSize="14dip"/>
|
||||
|
||||
<Button android:id="@+id/studyoptions_card_browser"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1"
|
||||
android:text="card browser"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -187,7 +187,9 @@
|
||||
<string name="select_card_model">Select Card Model</string>
|
||||
<string name="select">Select</string>
|
||||
|
||||
|
||||
<!-- CardBrowser -->
|
||||
<string name="card_browser_title">Card Browser</string>
|
||||
<string name="card_browser_load">Loading cards</string>
|
||||
|
||||
<!-- AnkiDroid.java -->
|
||||
<!--<string name="loading_new_card">Loading new card...</string>-->
|
||||
|
128
src/com/ichi2/anki/CardBrowser.java
Normal file
128
src/com/ichi2/anki/CardBrowser.java
Normal file
@ -0,0 +1,128 @@
|
||||
package com.ichi2.anki;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.SimpleAdapter;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CardBrowser extends Activity {
|
||||
private ArrayList<HashMap<String, String>> mCards;
|
||||
private ArrayList<HashMap<String, String>> mAllCards;
|
||||
private ListView mCardsListView;
|
||||
private SimpleAdapter mCardsAdapter;
|
||||
private EditText mSearchEditText;
|
||||
|
||||
private ProgressDialog mProgressDialog;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.card_browser);
|
||||
|
||||
mCards = new ArrayList<HashMap<String, String>>();
|
||||
mAllCards = new ArrayList<HashMap<String, String>>();
|
||||
mCardsListView = (ListView) findViewById(R.id.card_browser_list);
|
||||
|
||||
mCardsAdapter = new SimpleAdapter(this, mCards,
|
||||
R.layout.card_item, new String[] { "question", "answer" }, new int[] {
|
||||
R.id.card_question, R.id.card_answer });
|
||||
mCardsAdapter.setViewBinder(new SimpleAdapter.ViewBinder() {
|
||||
@Override
|
||||
public boolean setViewValue(View arg0, Object arg1, String arg2) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
mCardsListView.setAdapter(mCardsAdapter);
|
||||
mCardsListView.setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
Intent editCard = new Intent(CardBrowser.this, CardEditor.class);
|
||||
editCard.putExtra("card", Long.parseLong(mCards.get(position).get("id")));
|
||||
startActivityForResult(editCard, 0);
|
||||
}
|
||||
});
|
||||
|
||||
mSearchEditText = (EditText) findViewById(R.id.card_browser_search);
|
||||
mSearchEditText.addTextChangedListener(new TextWatcher() {
|
||||
public void afterTextChanged(Editable s) {
|
||||
mCards.clear();
|
||||
for (int i = 0; i < mAllCards.size(); i++) {
|
||||
if (mAllCards.get(i).get("question").toLowerCase().indexOf(mSearchEditText.getText().toString().toLowerCase()) != -1 ||
|
||||
mAllCards.get(i).get("answer").toLowerCase().indexOf(mSearchEditText.getText().toString().toLowerCase()) != -1) {
|
||||
mCards.add(mAllCards.get(i));
|
||||
}
|
||||
}
|
||||
mCardsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count){}
|
||||
});
|
||||
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
||||
|
||||
getCards();
|
||||
}
|
||||
|
||||
|
||||
private void getCards() {
|
||||
DeckTask.launchDeckTask(DeckTask.TASK_LOAD_CARDS, mLoadCardsHandler, new DeckTask.TaskData(AnkiDroidApp.deck(), "answer"));
|
||||
}
|
||||
|
||||
|
||||
DeckTask.TaskListener mLoadCardsHandler = new DeckTask.TaskListener() {
|
||||
|
||||
@Override
|
||||
public void onPreExecute() {
|
||||
mProgressDialog = ProgressDialog.show(CardBrowser.this, "", getResources().getString(R.string.card_browser_load), true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPostExecute(DeckTask.TaskData result) {
|
||||
mAllCards.clear();
|
||||
ArrayList<String[]> allCards = new ArrayList<String[]>();
|
||||
allCards.addAll(result.getAllCards());
|
||||
|
||||
for (String[] item : allCards) {
|
||||
HashMap<String, String> data = new HashMap<String, String>();
|
||||
data.put("id", item[0]);
|
||||
data.put("question", item[1]);
|
||||
data.put("answer", item[2]);
|
||||
mAllCards.add(data);
|
||||
}
|
||||
mCardsAdapter.notifyDataSetChanged();
|
||||
mCards.clear();
|
||||
mCards.addAll(mAllCards);
|
||||
|
||||
// This verification would not be necessary if onConfigurationChanged it's executed correctly (which seems
|
||||
// that emulator does not do)
|
||||
if (mProgressDialog.isShowing()) {
|
||||
try {
|
||||
mProgressDialog.dismiss();
|
||||
} catch (Exception e) {
|
||||
Log.e(AnkiDroidApp.TAG, "onPostExecute - Dialog dismiss Exception = " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onProgressUpdate(DeckTask.TaskData... values) {
|
||||
}
|
||||
};
|
||||
}
|
@ -77,8 +77,8 @@ public class CardEditor extends Activity {
|
||||
mSave = (Button) findViewById(R.id.CardEditorSaveButton);
|
||||
mCancel = (Button) findViewById(R.id.CardEditorCancelButton);
|
||||
|
||||
mEditorCard = Reviewer.getEditorCard();
|
||||
|
||||
mEditorCard = AnkiDroidApp.deck().cardFromId(getIntent().getExtras().getLong("card"));
|
||||
|
||||
// Card -> FactID -> FieldIDs -> FieldModels
|
||||
|
||||
Fact cardFact = mEditorCard.getFact();
|
||||
|
@ -2989,6 +2989,31 @@ public class Deck {
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<String[]> getAllCards(String order) {
|
||||
ArrayList<String[]> allCards = new ArrayList<String[]>();
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
cur = getDB().getDatabase().rawQuery("SELECT id, question, answer FROM cards ORDER BY " + order, null);
|
||||
while (cur.moveToNext()) {
|
||||
String[] data = new String[3];
|
||||
data[0] = Long.toString(cur.getLong(0));
|
||||
data[1] = Utils.stripHTML(cur.getString(1));
|
||||
data[2] = Utils.stripHTML(cur.getString(2));
|
||||
allCards.add(data);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Log.e(AnkiDroidApp.TAG, "getAllCards: " + e.toString());
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
if (cur != null && !cur.isClosed()) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
return allCards;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tags: adding/removing in bulk*********************************************************
|
||||
*/
|
||||
|
@ -17,6 +17,9 @@
|
||||
|
||||
package com.ichi2.anki;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import android.database.CursorIndexOutOfBoundsException;
|
||||
import android.database.SQLException;
|
||||
import android.os.AsyncTask;
|
||||
@ -35,6 +38,7 @@ public class DeckTask extends AsyncTask<DeckTask.TaskData, DeckTask.TaskData, De
|
||||
public static final int TASK_TYPE_UPDATE_FACT = 5;
|
||||
public static final int TASK_TYPE_UNDO = 6;
|
||||
public static final int TASK_TYPE_REDO = 7;
|
||||
public static final int TASK_LOAD_CARDS = 8;
|
||||
|
||||
/**
|
||||
* Possible outputs trying to load a deck.
|
||||
@ -116,7 +120,10 @@ public class DeckTask extends AsyncTask<DeckTask.TaskData, DeckTask.TaskData, De
|
||||
return doInBackgroundUndo(params);
|
||||
|
||||
case TASK_TYPE_REDO:
|
||||
return doInBackgroundRedo(params);
|
||||
return doInBackgroundRedo(params);
|
||||
|
||||
case TASK_LOAD_CARDS:
|
||||
return doInBackgroundLoadCards(params);
|
||||
|
||||
default:
|
||||
return null;
|
||||
@ -317,7 +324,17 @@ public class DeckTask extends AsyncTask<DeckTask.TaskData, DeckTask.TaskData, De
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private TaskData doInBackgroundLoadCards(TaskData... params) {
|
||||
Deck deck = params[0].getDeck();
|
||||
String order = params[0].getOrder();
|
||||
|
||||
Log.i(AnkiDroidApp.TAG, "doInBackgroundLoadCards");
|
||||
|
||||
return new TaskData(deck.getAllCards(order));
|
||||
}
|
||||
|
||||
|
||||
public static interface TaskListener {
|
||||
public void onPreExecute();
|
||||
@ -337,6 +354,8 @@ public class DeckTask extends AsyncTask<DeckTask.TaskData, DeckTask.TaskData, De
|
||||
private boolean previousCardLeech; // answer card resulted in card marked as leech
|
||||
private boolean previousCardSuspended; // answer card resulted in card marked as leech and suspended
|
||||
private boolean mLastCardInQueue;
|
||||
private ArrayList<String[]> mAllCards;
|
||||
private String mOrder;
|
||||
|
||||
|
||||
public TaskData(int value, Deck deck, Card card) {
|
||||
@ -362,6 +381,12 @@ public class DeckTask extends AsyncTask<DeckTask.TaskData, DeckTask.TaskData, De
|
||||
}
|
||||
|
||||
|
||||
public TaskData(ArrayList<String[]> allCards) {
|
||||
mAllCards = new ArrayList<String[]>();
|
||||
mAllCards.addAll(allCards);
|
||||
}
|
||||
|
||||
|
||||
public TaskData(Card card, boolean markedLeech, boolean suspendedLeech, boolean lastCardInQueue) {
|
||||
mCard = card;
|
||||
previousCardLeech = markedLeech;
|
||||
@ -370,6 +395,12 @@ public class DeckTask extends AsyncTask<DeckTask.TaskData, DeckTask.TaskData, De
|
||||
}
|
||||
|
||||
|
||||
public TaskData(Deck deck, String order) {
|
||||
mDeck = deck;
|
||||
mOrder = order;
|
||||
}
|
||||
|
||||
|
||||
public TaskData(int value) {
|
||||
mInteger = value;
|
||||
}
|
||||
@ -385,6 +416,16 @@ public class DeckTask extends AsyncTask<DeckTask.TaskData, DeckTask.TaskData, De
|
||||
}
|
||||
|
||||
|
||||
public String getOrder() {
|
||||
return mOrder;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<String[]> getAllCards() {
|
||||
return mAllCards;
|
||||
}
|
||||
|
||||
|
||||
public Card getCard() {
|
||||
return mCard;
|
||||
}
|
||||
|
@ -131,8 +131,6 @@ public class Reviewer extends Activity {
|
||||
private static final int HQIA_DO_SHOW = 1;
|
||||
private static final int HQIA_CARD_MODEL = 2;
|
||||
|
||||
private static Card sEditorCard; // To be assigned as the currentCard or a new card to be sent to and from editor
|
||||
|
||||
private static boolean sDisplayAnswer = false; // Indicate if "show answer" button has been pressed
|
||||
|
||||
/** The percentage of the absolute font size specified in the deck. */
|
||||
@ -761,8 +759,9 @@ public class Reviewer extends Activity {
|
||||
cramEditWarning.show();
|
||||
return false;
|
||||
} else {
|
||||
sEditorCard = mCurrentCard;
|
||||
Intent editCard = new Intent(Reviewer.this, CardEditor.class);
|
||||
|
||||
editCard.putExtra("card", mCurrentCard.getId());
|
||||
startActivityForResult(editCard, EDIT_CURRENT_CARD);
|
||||
return true;
|
||||
}
|
||||
@ -1560,11 +1559,6 @@ public class Reviewer extends Activity {
|
||||
}
|
||||
|
||||
|
||||
public static Card getEditorCard() {
|
||||
return sEditorCard;
|
||||
}
|
||||
|
||||
|
||||
private int getAvailableWidthInCard() {
|
||||
// The width available is equals to
|
||||
// the screen's width divided by the default scale factor used by the WebView, because this scale factor will be
|
||||
|
@ -99,6 +99,7 @@ public class StudyOptions extends Activity {
|
||||
private static final int DOWNLOAD_SHARED_DECK = 4;
|
||||
private static final int REPORT_ERROR = 5;
|
||||
private static final int ADD_FACT = 6;
|
||||
private static final int BROWSE_CARDS = 7;
|
||||
|
||||
/**
|
||||
* Constants for selecting which content view to display
|
||||
@ -183,6 +184,7 @@ public class StudyOptions extends Activity {
|
||||
private EditText mEditSessionTime;
|
||||
private EditText mEditSessionQuestions;
|
||||
private CheckBox mNightMode;
|
||||
private Button mCardBrowser;
|
||||
|
||||
/**
|
||||
* UI elements for "More Options" dialog
|
||||
@ -276,6 +278,9 @@ public class StudyOptions extends Activity {
|
||||
case R.id.studyoptions_download_deck:
|
||||
showDownloadSelector();
|
||||
return;
|
||||
case R.id.studyoptions_card_browser:
|
||||
openCardBrowser();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@ -564,6 +569,7 @@ public class StudyOptions extends Activity {
|
||||
|
||||
mButtonStart = (Button) mStudyOptionsView.findViewById(R.id.studyoptions_start);
|
||||
mToggleCram = (ToggleButton) mStudyOptionsView.findViewById(R.id.studyoptions_cram);
|
||||
mCardBrowser = (Button) mStudyOptionsView.findViewById(R.id.studyoptions_card_browser);
|
||||
|
||||
mTextReviewsDue = (TextView) mStudyOptionsView.findViewById(R.id.studyoptions_reviews_due);
|
||||
mTextNewToday = (TextView) mStudyOptionsView.findViewById(R.id.studyoptions_new_today);
|
||||
@ -587,7 +593,8 @@ public class StudyOptions extends Activity {
|
||||
|
||||
mButtonStart.setOnClickListener(mButtonClickListener);
|
||||
mToggleCram.setOnClickListener(mButtonClickListener);
|
||||
|
||||
mCardBrowser.setOnClickListener(mButtonClickListener);
|
||||
|
||||
mEditNewPerDay.addTextChangedListener(new TextWatcher() {
|
||||
public void afterTextChanged(Editable s) {
|
||||
Deck deck = AnkiDroidApp.deck();
|
||||
@ -1112,6 +1119,14 @@ public class StudyOptions extends Activity {
|
||||
// Log.i(AnkiDroidApp.TAG, "openDeckPicker - Ending");
|
||||
}
|
||||
|
||||
|
||||
private void openCardBrowser() {
|
||||
Intent cardBrowser = new Intent(StudyOptions.this, CardBrowser.class);
|
||||
cardBrowser.putExtra("deckFilename", mDeckFilename);
|
||||
startActivityForResult(cardBrowser, BROWSE_CARDS);
|
||||
}
|
||||
|
||||
|
||||
public void openPersonalDeckPicker() {
|
||||
if (AnkiDroidApp.isUserLoggedIn()) {
|
||||
if (AnkiDroidApp.deck() != null)// && sdCardAvailable)
|
||||
|
0
tools/comment-logs.sh
Executable file → Normal file
0
tools/comment-logs.sh
Executable file → Normal file
0
tools/translation-rates.sh
Executable file → Normal file
0
tools/translation-rates.sh
Executable file → Normal file
0
tools/uncomment-logs.sh
Executable file → Normal file
0
tools/uncomment-logs.sh
Executable file → Normal file
Loading…
Reference in New Issue
Block a user