diff --git a/bin/EhViewer.apk b/bin/EhViewer.apk
index db3583773..8554e8e0c 100644
Binary files a/bin/EhViewer.apk and b/bin/EhViewer.apk differ
diff --git a/bin/classes.dex b/bin/classes.dex
index 1919b9841..b0cc30819 100644
Binary files a/bin/classes.dex and b/bin/classes.dex differ
diff --git a/bin/dexedLibs/slidingmenu-f48f3a4eceb3b9455e8ae38a55377052.jar b/bin/dexedLibs/slidingmenu-f48f3a4eceb3b9455e8ae38a55377052.jar
index 6ca5c1924..5978cdb95 100644
Binary files a/bin/dexedLibs/slidingmenu-f48f3a4eceb3b9455e8ae38a55377052.jar and b/bin/dexedLibs/slidingmenu-f48f3a4eceb3b9455e8ae38a55377052.jar differ
diff --git a/bin/resources.ap_ b/bin/resources.ap_
index 552351dfc..f5f3edb70 100644
Binary files a/bin/resources.ap_ and b/bin/resources.ap_ differ
diff --git a/res/layout/list_item.xml b/res/layout/list_item.xml
index 11c1ae69a..33c95eec9 100644
--- a/res/layout/list_item.xml
+++ b/res/layout/list_item.xml
@@ -7,6 +7,7 @@
android:id="@+id/cover"
android:layout_width="67dp"
android:layout_height="100dp"
+ android:layout_gravity="center"
android:scaleType="fitCenter" />
+ android:layout_height="wrap_content"
+ android:maxLines="3"
+ android:ellipsize="end" />
reads = mData.getAllReads();
+ for (GalleryInfo item : reads) {
+ File folder = new File(Config.getDownloadPath(),
+ StringEscapeUtils.escapeHtml4(item.title));
+ try {
+ Util.deleteContents(folder);
+ folder.delete();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ mData.deleteAllReads();
}
private void checkUpdate() {
@@ -1460,7 +1478,7 @@ public class MangaListActivity extends SlidingActivity {
.SetOnCheckUpdateListener(new UpdateHelper.OnCheckUpdateListener() {
@Override
public void onSuccess(String version, long size,
- final String url, String info) {
+ final String url, final String fileName, String info) {
String sizeStr = Util.sizeToString(size);
AlertDialog dialog = SuperDialogUtil.createUpdateDialog(MangaListActivity.this,
version, sizeStr, info,
@@ -1471,7 +1489,6 @@ public class MangaListActivity extends SlidingActivity {
// TODO
try {
Downloader downloader = new Downloader(MangaListActivity.this);
- String fileName = Util.getFileForUrl(url);
downloader.resetData(Config.getDownloadPath(), fileName, url);
downloader.setOnDownloadListener(
new UpdateHelper.UpdateListener(MangaListActivity.this,
diff --git a/src/com/hippo/ehviewer/activity/SettingsActivity.java b/src/com/hippo/ehviewer/activity/SettingsActivity.java
index 79bc1d18d..8d941016f 100644
--- a/src/com/hippo/ehviewer/activity/SettingsActivity.java
+++ b/src/com/hippo/ehviewer/activity/SettingsActivity.java
@@ -223,7 +223,7 @@ public class SettingsActivity extends PreferenceActivity {
.SetOnCheckUpdateListener(new UpdateHelper.OnCheckUpdateListener() {
@Override
public void onSuccess(String version, long size,
- final String url, String info) {
+ final String url, final String fileName, String info) {
update.setSummary(R.string.found_update);
String sizeStr = Util.sizeToString(size);
@@ -236,7 +236,6 @@ public class SettingsActivity extends PreferenceActivity {
// TODO
try {
Downloader downloader = new Downloader(SettingsActivity.this);
- String fileName = Util.getFileForUrl(url);
downloader.resetData(Config.getDownloadPath(), fileName, url);
downloader.setOnDownloadListener(
new UpdateHelper.UpdateListener(SettingsActivity.this,
diff --git a/src/com/hippo/ehviewer/data/Data.java b/src/com/hippo/ehviewer/data/Data.java
index 6ccd044aa..48eebd71c 100644
--- a/src/com/hippo/ehviewer/data/Data.java
+++ b/src/com/hippo/ehviewer/data/Data.java
@@ -6,14 +6,10 @@ import java.util.List;
import java.util.Map;
import com.hippo.ehviewer.GalleryInfo;
-import com.hippo.ehviewer.ListUrls;
-import com.hippo.ehviewer.Tag;
-import com.hippo.ehviewer.util.Util;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
-import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
@@ -33,6 +29,7 @@ public class Data {
private static final String TABLE_READ = "read";
private static final String TABLE_LOCAL_FAVOURITE = "local_favourite";
private static final String TABLE_TAG = "tag";
+ private static final String TABLE_DOWNLOAD = "download";
private static final String COLUMN_GID = "gid";
private static final String COLUMN_TOKEN = "token";
@@ -50,12 +47,18 @@ public class Data {
private static final String COLUMN_ADVANCE = "advance";
private static final String COLUMN_MIN_RATING = "min_rating";
+ private static final String COLUMN_STATE = "state";
+ private static final String COLUMN_DETAIL = "detail";
+ private static final String COLUMN_START_PAGE = "start_page";
+
private Map mGallerys;
- private long tagRowNum;
+ private long mTagRowNum;
private List mTags;
-
private List mLocalFavourites;
+ private List mReads;
+ private long mDownloadRowNum;
+ private List mDownloads;
private Context mContext;
@@ -70,7 +73,9 @@ public class Data {
mGallerys = new HashMap();
getTags();
+ getReads();
getLocalFavourites();
+ getDownloads();
}
@Override
@@ -79,6 +84,13 @@ public class Data {
}
/****** gallery ******/
+
+ /**
+ * Get galleryInfo in table, if do not exits return null
+ *
+ * @param gid
+ * @return
+ */
public GalleryInfo getGallery(String gid) {
GalleryInfo galleryInfo = mGallerys.get(gid);
if (galleryInfo == null) {
@@ -98,6 +110,7 @@ public class Data {
// add to map
mGallerys.put(gid, galleryInfo);
}
+ cursor.close();
}
return galleryInfo;
}
@@ -187,7 +200,10 @@ public class Data {
}
reference--;
if (reference == 0) { // delete gallery
+ // delete in sql
mDatabase.delete(TABLE_GALLERY, COLUMN_GID + "=?", new String[]{gid});
+ // delete in list
+ mGallerys.remove(gid);
} else { // update reference
ContentValues values = new ContentValues();
values.put(COLUMN_REFERENCE, reference);
@@ -195,6 +211,231 @@ public class Data {
}
}
+ /****** download ******/
+ private synchronized void getDownloads() {
+ mDownloads = new ArrayList();
+ mDownloadRowNum = 0;
+
+ List invaildGids = new ArrayList();
+
+ Cursor cursor = mDatabase.rawQuery("select * from " + TABLE_DOWNLOAD
+ + " order by " + COLUMN_ID + " asc", null);
+ if (cursor.moveToFirst()) {
+ while (!cursor.isAfterLast()) {
+
+ String gid = cursor.getString(1);
+ GalleryInfo galleryInfo = getGallery(gid);
+ if (galleryInfo == null) {
+ invaildGids.add(gid);
+ } else {
+ int state = cursor.getInt(2);
+ byte[] detail = cursor.getBlob(3);
+ int startPage = cursor.getInt(4);
+
+ DownloadInfo downloadInfo = new DownloadInfo(
+ galleryInfo, state, detail, startPage);
+
+ mDownloads.add(downloadInfo);
+ }
+ cursor.moveToNext();
+ mDownloadRowNum++;
+ }
+ }
+ cursor.close();
+ }
+
+ public synchronized boolean addDownload(DownloadInfo downloadInfo) {
+ GalleryInfo galleryInfo = downloadInfo.getGalleryInfo();
+
+ // add to sql
+ ContentValues values = new ContentValues();
+ values.put(COLUMN_ID, mDownloadRowNum);
+ values.put(COLUMN_GID, galleryInfo.gid);
+ values.put(COLUMN_STATE, downloadInfo.getState());
+ values.put(COLUMN_DETAIL, downloadInfo.getDetail());
+ values.put(COLUMN_START_PAGE, downloadInfo.getStartPage());
+
+ boolean ok = mDatabase.insert(
+ TABLE_DOWNLOAD, null, values) != -1;
+ if (ok) {
+ // add to list
+ mDownloadRowNum++;
+ mDownloads.add(downloadInfo);
+
+ // add reference
+ addGallery(galleryInfo, false);
+ }
+ return ok;
+ }
+
+ public synchronized boolean deleteDownload(int id) {
+ int deleteNum = mDatabase.delete(TABLE_DOWNLOAD, COLUMN_ID + "=?", new String[]{String.valueOf(id)});
+ if (deleteNum > 1)
+ Log.e(TAG, "WTF? more than one id is " + id);
+
+ if (deleteNum == 0)
+ return false;
+ if (id < 0 || id >= mDownloads.size()) {
+ Log.e(TAG, "id is out of bounds, id is " + id + ", mDownloads.size() is " + mDownloads.size());
+ return false;
+ }
+
+ // delete from sql
+ ContentValues values = new ContentValues();
+ for (int i = id + 1; i < mDownloadRowNum; i++) {
+ values.put(COLUMN_ID, i - 1);
+ mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(i)});
+ }
+ mDownloadRowNum -= deleteNum;
+
+ // delete from list
+ DownloadInfo downloadInfo = mDownloads.remove(id);
+
+ // sub reference
+ if (downloadInfo != null) {
+ deleteGallery(downloadInfo.getGalleryInfo().gid);
+ } else {
+ Log.e(TAG, id + " of mDownloads is null");
+ }
+
+ return true;
+ }
+
+ public synchronized List getAllDownloads() {
+ return mDownloads;
+ }
+
+ public synchronized DownloadInfo getDownload(int location) {
+ return mDownloads.get(location);
+ }
+
+ public synchronized void setDownload(int location, DownloadInfo downloadInfo) {
+ if (location == mDownloadRowNum) {
+ addDownload(downloadInfo);
+ } else {
+ // Update list
+ mDownloads.set(location, downloadInfo);
+
+ // Update sql
+ GalleryInfo galleryInfo = downloadInfo.getGalleryInfo();
+ ContentValues values = new ContentValues();
+ values.put(COLUMN_ID, mDownloadRowNum);
+ values.put(COLUMN_GID, galleryInfo.gid);
+ values.put(COLUMN_STATE, downloadInfo.getState());
+ values.put(COLUMN_DETAIL, downloadInfo.getDetail());
+ values.put(COLUMN_START_PAGE, downloadInfo.getStartPage());
+ mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(location)});
+
+ // Update gallery
+ addGallery(galleryInfo, true);
+ }
+ }
+
+ public synchronized void notifyDownloadChange(int location) {
+ setDownload(location, mDownloads.get(location));
+ }
+
+ public synchronized boolean swapDownload(int indexOne, int indexTwo) {
+ if (indexOne < 0 || indexOne > mDownloadRowNum
+ || indexTwo < 0 || indexTwo > mDownloadRowNum)
+ return false;
+
+ if (indexOne == indexTwo)
+ return true;
+
+ // Update list
+ DownloadInfo temp = mDownloads.get(indexOne);
+ mDownloads.set(indexOne, mDownloads.get(indexTwo));
+ mDownloads.set(indexTwo, temp);
+ // Update sql
+ ContentValues values = new ContentValues();
+ values.put(COLUMN_ID, -1);
+ mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(indexOne)});
+ values.put(COLUMN_ID, indexOne);
+ mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(indexTwo)});
+ values.put(COLUMN_ID, indexTwo);
+ mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(-1)});
+ return true;
+ }
+
+ /****** read ******/
+ private synchronized void getReads() {
+ mReads = new ArrayList();
+ Cursor cursor = mDatabase.rawQuery("select * from "
+ + TABLE_READ, null);
+
+ List invaildGids = new ArrayList();
+
+ if (cursor.moveToFirst()) {
+ while (!cursor.isAfterLast()) {
+ String gid = cursor.getString(0);
+ GalleryInfo galleryInfo = getGallery(gid);
+ if (galleryInfo == null) {
+ invaildGids.add(gid);
+ } else {
+ mReads.add(galleryInfo);
+ }
+ cursor.moveToNext();
+ }
+ }
+ cursor.close();
+
+ // remove invail gid
+ for (String invaildGid : invaildGids) {
+ mDatabase.delete(TABLE_READ, COLUMN_GID + "=?",
+ new String[]{String.valueOf(invaildGid)});
+ }
+ }
+
+ public synchronized List getAllReads() {
+ return mReads;
+ }
+
+ public synchronized void addRead(GalleryInfo galleryInfo) {
+ // add to sql
+ ContentValues values = new ContentValues();
+ values.put(COLUMN_GID, galleryInfo.gid);
+ boolean isUpdate = mDatabase.insert(
+ TABLE_READ, null, values) == -1;
+ addGallery(galleryInfo, isUpdate);
+
+ // add to list
+ if (!isUpdate)
+ mReads.add(galleryInfo);
+ }
+
+ public synchronized void deleteRead(String gid) {
+ // delete from list
+ for (GalleryInfo galleryInfo : mReads) {
+ if (galleryInfo.gid.equals(gid)) {
+ mReads.remove(galleryInfo);
+ break;
+ }
+ }
+
+ // delete from sql
+ mDatabase.delete(TABLE_READ, COLUMN_GID + "=?", new String[]{gid});
+ deleteGallery(gid);
+ }
+
+ public synchronized void deleteAllReads() {
+ // delete from list
+ mReads.clear();
+
+ // delete from sql
+ Cursor cursor = mDatabase.rawQuery("select * from "
+ + TABLE_READ, null);
+ if (cursor.moveToFirst()) {
+ while (!cursor.isAfterLast()) {
+ String gid = cursor.getString(0);
+ deleteGallery(gid);
+ cursor.moveToNext();
+ }
+ }
+ cursor.close();
+ mDatabase.delete(TABLE_READ, null, null);
+ }
+
/****** local favourite ******/
private synchronized void getLocalFavourites() {
mLocalFavourites = new ArrayList();
@@ -274,7 +515,7 @@ public class Data {
/****** tag ******/
private synchronized void getTags() {
mTags = new ArrayList();
- tagRowNum = 0;
+ mTagRowNum = 0;
Cursor cursor = mDatabase.rawQuery("select * from " + TABLE_TAG
+ " order by " + COLUMN_ID + " asc", null);
if (cursor.moveToFirst()) {
@@ -292,7 +533,7 @@ public class Data {
mTags.add(tag);
cursor.moveToNext();
- tagRowNum++;
+ mTagRowNum++;
}
}
cursor.close();
@@ -300,7 +541,7 @@ public class Data {
public synchronized boolean addTag(Tag tag) {
ContentValues values = new ContentValues();
- values.put(COLUMN_ID, tagRowNum);
+ values.put(COLUMN_ID, mTagRowNum);
values.put(COLUMN_NAME, tag.getName());
values.put(COLUMN_CATEGORY, tag.getType());
values.put(COLUMN_SEARCH, tag.getSearch());
@@ -310,7 +551,7 @@ public class Data {
boolean ok = mDatabase.insert(
TABLE_TAG, null, values) != -1;
if (ok) {
- tagRowNum++;
+ mTagRowNum++;
mTags.add(tag);
}
return ok;
@@ -330,11 +571,11 @@ public class Data {
// Update sql
ContentValues values = new ContentValues();
- for (int i = id + 1; i < tagRowNum; i++) {
+ for (int i = id + 1; i < mTagRowNum; i++) {
values.put(COLUMN_ID, i - 1);
mDatabase.update(TABLE_TAG, values, COLUMN_ID + "=?", new String[]{String.valueOf(i)});
}
- tagRowNum -= deleteNum;
+ mTagRowNum -= deleteNum;
// Update list
mTags.remove(id);
@@ -357,8 +598,13 @@ public class Data {
return names;
}
+ /**
+ * location >= 0 && location <= tagRowNum please
+ * @param location
+ * @param tag
+ */
public synchronized void setTag(int location, Tag tag) {
- if (location == tagRowNum) {
+ if (location == mTagRowNum) {
addTag(tag);
} else {
// Update list
@@ -376,8 +622,8 @@ public class Data {
}
public synchronized boolean swapTag(int indexOne, int indexTwo) {
- if (indexOne < 0 || indexOne > tagRowNum
- || indexTwo < 0 || indexTwo > tagRowNum)
+ if (indexOne < 0 || indexOne > mTagRowNum
+ || indexTwo < 0 || indexTwo > mTagRowNum)
return false;
if (indexOne == indexTwo)
@@ -408,39 +654,49 @@ public class Data {
public void onCreate(SQLiteDatabase db) {
// gallery
String CreateGallery = "create table " + TABLE_GALLERY + "("
- + "gid text primary key,"
- + "token text,"
- + "title text,"
- + "posted text,"
- + "category integer,"
- + "thumb text,"
- + "uploader text,"
- + "rating text,"
- + "reference integer);";
+ + COLUMN_GID + " text primary key,"
+ + COLUMN_TOKEN + " text,"
+ + COLUMN_TITLE + " text,"
+ + COLUMN_POSTED + " text,"
+ + COLUMN_CATEGORY + " integer,"
+ + COLUMN_THUMB + " text,"
+ + COLUMN_UPLOADER + " text,"
+ + COLUMN_RATING + " text,"
+ + COLUMN_REFERENCE + " integer);";
db.execSQL(CreateGallery);
// read
String CreateRead = "create table "
+ TABLE_READ + "("
- + "gid text primary key);";
+ + COLUMN_GID + " text primary key);";
db.execSQL(CreateRead);
// local favourite
String CreateLocalFavourite = "create table "
+ TABLE_LOCAL_FAVOURITE + "("
- + "gid text primary key);";
+ + COLUMN_GID + " text primary key);";
db.execSQL(CreateLocalFavourite);
// tag
String CreateTag = "create table "
+ TABLE_TAG + "("
- + "id integer primary key,"
- + "name text,"
- + "category integer,"
- + "search text,"
- + "advance integer,"
- + "min_rating integer);";
+ + COLUMN_ID + " integer primary key,"
+ + COLUMN_NAME + " text,"
+ + COLUMN_CATEGORY + " integer,"
+ + COLUMN_SEARCH + " text,"
+ + COLUMN_ADVANCE + " integer,"
+ + COLUMN_MIN_RATING + " integer);";
db.execSQL(CreateTag);
+
+ // download
+ String CreateDownload = "create table "
+ + TABLE_DOWNLOAD + "("
+ + COLUMN_ID + " integer primary key,"
+ + COLUMN_GID + " text unique,"
+ + COLUMN_STATE + " integer,"
+ + COLUMN_DETAIL + " blob,"
+ + COLUMN_START_PAGE + " integer);";
+ db.execSQL(CreateDownload);
}
@Override
diff --git a/src/com/hippo/ehviewer/data/DownloadInfo.java b/src/com/hippo/ehviewer/data/DownloadInfo.java
new file mode 100644
index 000000000..20cfbc0ed
--- /dev/null
+++ b/src/com/hippo/ehviewer/data/DownloadInfo.java
@@ -0,0 +1,124 @@
+package com.hippo.ehviewer.data;
+
+import com.hippo.ehviewer.GalleryInfo;
+
+/**
+ *
+ * Use byte[] to store download detail,
+ * each bit for each page, 0 for uncompleted,
+ * 1 for completed.
+ *
+ * @author Hippo
+ *
+ */
+public class DownloadInfo {
+ public static final int UNCOMPLETED = 0x0;
+ public static final int FAILED = 0x1;
+ public static final int COMPLETED = 0x2;
+
+ public static final int NONE = 0x0;
+ public static final int WAITING = 0x1;
+ public static final int DOWNLOADING = 0x2;
+
+ private GalleryInfo mGalleryInfo;
+ private int mState;
+ private int mDownloadState;
+ private byte[] mDetail;
+ private int mStartPage;
+
+ public DownloadInfo(GalleryInfo galleryInfo) {
+ mGalleryInfo = galleryInfo;
+ mState = UNCOMPLETED;
+ mDownloadState = NONE;
+ mDetail = null;
+ mStartPage = 0;
+ }
+
+ public DownloadInfo(GalleryInfo galleryInfo, int pages) {
+ mGalleryInfo = galleryInfo;
+ mState = UNCOMPLETED;
+ mDownloadState = NONE;
+ mDetail = new byte[(pages + 7)/8];
+ mStartPage = 0;
+ }
+
+ public DownloadInfo(GalleryInfo galleryInfo, int state, byte[] detail, int startPage) {
+ mGalleryInfo = galleryInfo;
+ mState = state;
+ mDownloadState = NONE;
+ mDetail = detail;
+ mStartPage = startPage;
+ }
+
+ public boolean finishPage(int index) {
+ int position; // byte index
+ int offset; // bit offset
+ if (mDetail == null)
+ return false;
+
+ position = index / 8;
+
+ if (position >= mDetail.length)
+ return false;
+
+ offset = index % 8;
+ int mask = 0x80 >> offset;
+ mDetail[position] |= mask;
+ return true;
+ }
+
+ public GalleryInfo getGalleryInfo() {
+ return mGalleryInfo;
+ }
+
+ public int getState() {
+ return mState;
+ }
+
+ public int getDownloadState() {
+ return mDownloadState;
+ }
+
+ public byte[] getDetail() {
+ return mDetail;
+ }
+
+ public int getStartPage() {
+ return mStartPage;
+ }
+
+ /**
+ * If you pass detail in constructor return true,
+ * if you have called it setPages return true.
+ * @return
+ */
+ public boolean isInit() {
+ return mDetail != null;
+ }
+
+ /**
+ * If you pass detail in constructor return false,
+ * if you call it before return false.
+ * @param pages
+ * @return
+ */
+ public boolean setPages(int pages) {
+ if (mDetail == null)
+ return false;
+
+ mDetail = new byte[(pages + 7) / 8];
+ return true;
+ }
+
+ public void setState(int state) {
+ mState = state;
+ }
+
+ public void setDownloadState(int downloadState) {
+ mDownloadState = downloadState;
+ }
+
+ public void setStartPage(int startPage) {
+ mStartPage = startPage;
+ }
+}
diff --git a/src/com/hippo/ehviewer/Tag.java b/src/com/hippo/ehviewer/data/Tag.java
similarity index 84%
rename from src/com/hippo/ehviewer/Tag.java
rename to src/com/hippo/ehviewer/data/Tag.java
index d1dbdb8bb..74f49edff 100644
--- a/src/com/hippo/ehviewer/Tag.java
+++ b/src/com/hippo/ehviewer/data/Tag.java
@@ -1,4 +1,6 @@
-package com.hippo.ehviewer;
+package com.hippo.ehviewer.data;
+
+import com.hippo.ehviewer.ListUrls;
public class Tag extends ListUrls {
private String mName;
diff --git a/src/com/hippo/ehviewer/gallery/GalleryView.java b/src/com/hippo/ehviewer/gallery/GalleryView.java
index c8edf11c6..8f93d2c2f 100644
--- a/src/com/hippo/ehviewer/gallery/GalleryView.java
+++ b/src/com/hippo/ehviewer/gallery/GalleryView.java
@@ -310,7 +310,7 @@ public class GalleryView extends GLView {
@Override
public Object run(JobContext jc) {
try {
- Thread.sleep(100);
+ Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {