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 {