mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-04 10:19:33 +02:00
Support for external books in the Library
git-svn-id: https://only.mawhrin.net/repos/FBReaderJ/trunk@1738 6a642e6f-84f6-412e-ac94-c4a38d5a04b0
This commit is contained in:
parent
5f4f6ac801
commit
b9b7f61ad9
7 changed files with 120 additions and 11 deletions
|
@ -15,6 +15,7 @@ DONE Возможность открывать локальные файлы и
|
|||
DONE На этой странице есть ссылка на epub-файл "для ПК". http://www.zone4iphone.ru/index.php?p_id=7&b_id=18413
|
||||
Проверить скачивание книги браузером и возможность чтения из папки, куда файл был скачан.
|
||||
** добавлять в библиотеку (сделать таблицу добавленных вручную книг)
|
||||
** сделать новый диалог удаления файлов (удаление файла / удаление из библиотеки)
|
||||
|
||||
------------------------------
|
||||
|
||||
|
|
|
@ -173,7 +173,8 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
|
|||
menu.setHeaderTitle(tree.getName());
|
||||
final ZLResource resource = ZLResource.resource("libraryView");
|
||||
menu.add(0, OPEN_BOOK_ITEM_ID, 0, resource.getResource("openBook").getValue());
|
||||
if (Library.Instance().canDeleteBook(((BookTree)tree).Book)) {
|
||||
if ((Library.Instance().getRemoveBookMode(((BookTree)tree).Book)
|
||||
& Library.REMOVE_FROM_DISK) != 0) {
|
||||
menu.add(0, DELETE_BOOK_ITEM_ID, 0, resource.getResource("deleteBook").getValue());
|
||||
}
|
||||
}
|
||||
|
@ -263,9 +264,11 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
|
|||
|
||||
private class BookDeleter implements DialogInterface.OnClickListener {
|
||||
private final Book myBook;
|
||||
private final int myMode;
|
||||
|
||||
BookDeleter(Book book) {
|
||||
BookDeleter(Book book, int removeMode) {
|
||||
myBook = book;
|
||||
myMode = removeMode;
|
||||
}
|
||||
|
||||
private void invalidateView(View v) {
|
||||
|
@ -276,7 +279,7 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
|
|||
}
|
||||
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Library.Instance().deleteBook(myBook);
|
||||
Library.Instance().removeBook(myBook, myMode);
|
||||
|
||||
invalidateView(findViewById(R.id.by_author));
|
||||
invalidateView(findViewById(R.id.by_tag));
|
||||
|
@ -293,7 +296,7 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
|
|||
.setTitle(book.getTitle())
|
||||
.setMessage(boxResource.getResource("message").getValue())
|
||||
.setIcon(0)
|
||||
.setPositiveButton(buttonResource.getResource("yes").getValue(), new BookDeleter(book))
|
||||
.setPositiveButton(buttonResource.getResource("yes").getValue(), new BookDeleter(book, Library.REMOVE_FROM_DISK))
|
||||
.setNegativeButton(buttonResource.getResource("no").getValue(), null)
|
||||
.create().show();
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
|||
|
||||
private void migrate() {
|
||||
final int version = myDatabase.getVersion();
|
||||
if (version >= 8) {
|
||||
final int currentVersion = 9;
|
||||
if (version >= currentVersion) {
|
||||
return;
|
||||
}
|
||||
ZLDialogManager.Instance().wait((version == 0) ? "creatingBooksDatabase" : "updatingBooksDatabase", new Runnable() {
|
||||
|
@ -82,12 +83,14 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
|||
updateTables6();
|
||||
case 7:
|
||||
updateTables7();
|
||||
case 8:
|
||||
updateTables8();
|
||||
}
|
||||
myDatabase.setTransactionSuccessful();
|
||||
myDatabase.endTransaction();
|
||||
|
||||
myDatabase.execSQL("VACUUM");
|
||||
myDatabase.setVersion(8);
|
||||
myDatabase.setVersion(currentVersion);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -768,6 +771,42 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
|||
myStorePositionStatement.execute();
|
||||
}
|
||||
|
||||
private SQLiteStatement myInsertIntoBookListStatement;
|
||||
protected boolean insertIntoBookList(long bookId) {
|
||||
if (myInsertIntoBookListStatement == null) {
|
||||
myInsertIntoBookListStatement = myDatabase.compileStatement(
|
||||
"INSERT OR IGNORE INTO BookList(book_id) VALUES (?)"
|
||||
);
|
||||
}
|
||||
myInsertIntoBookListStatement.bindLong(1, bookId);
|
||||
myInsertIntoBookListStatement.execute();
|
||||
return true;
|
||||
}
|
||||
|
||||
private SQLiteStatement myDeleteFromBookListStatement;
|
||||
protected boolean deleteFromBookList(long bookId) {
|
||||
if (myDeleteFromBookListStatement == null) {
|
||||
myDeleteFromBookListStatement = myDatabase.compileStatement(
|
||||
"DELETE FROM BookList WHERE book_id = ?"
|
||||
);
|
||||
}
|
||||
myDeleteFromBookListStatement.bindLong(1, bookId);
|
||||
myDeleteFromBookListStatement.execute();
|
||||
return true;
|
||||
}
|
||||
|
||||
private SQLiteStatement myCheckBookListStatement;
|
||||
protected boolean checkBookList(long bookId) {
|
||||
if (myCheckBookListStatement == null) {
|
||||
myCheckBookListStatement = myDatabase.compileStatement(
|
||||
"SELECT COUNT(*) FROM BookList WHERE book_id = ?"
|
||||
);
|
||||
}
|
||||
myCheckBookListStatement.bindLong(1, bookId);
|
||||
return myCheckBookListStatement.simpleQueryForLong() > 0;
|
||||
}
|
||||
|
||||
|
||||
private void createTables() {
|
||||
myDatabase.execSQL(
|
||||
"CREATE TABLE Books(" +
|
||||
|
@ -1014,4 +1053,10 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
|||
myDatabase.execSQL("DELETE FROM BookTag WHERE book_id=" + id);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTables8() {
|
||||
myDatabase.execSQL(
|
||||
"CREATE TABLE IF NOT EXISTS BookList ( " +
|
||||
"book_id INTEGER UNIQUE NOT NULL REFERENCES Books (book_id))");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -234,6 +234,7 @@ public final class FBReader extends ZLApplication {
|
|||
}
|
||||
Book book = Book.getByFile(file);
|
||||
if (book != null) {
|
||||
book.insertIntoBookList();
|
||||
return book;
|
||||
}
|
||||
if (file.isArchive()) {
|
||||
|
|
|
@ -73,7 +73,7 @@ public class Book {
|
|||
book.loadLists();
|
||||
}
|
||||
|
||||
if (fileInfos.check(physicalFile) && (book != null)) {
|
||||
if (book != null && fileInfos.check(physicalFile)) {
|
||||
return book;
|
||||
}
|
||||
fileInfos.save();
|
||||
|
@ -346,6 +346,12 @@ public class Book {
|
|||
}
|
||||
}
|
||||
|
||||
public void insertIntoBookList() {
|
||||
if (myId != -1) {
|
||||
BooksDatabase.Instance().insertIntoBookList(myId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int)myId;
|
||||
|
|
|
@ -95,4 +95,8 @@ public abstract class BooksDatabase {
|
|||
|
||||
protected abstract ZLTextPosition getStoredPosition(long bookId);
|
||||
protected abstract void storePosition(long bookId, ZLTextPosition position);
|
||||
|
||||
protected abstract boolean insertIntoBookList(long bookId);
|
||||
protected abstract boolean deleteFromBookList(long bookId);
|
||||
protected abstract boolean checkBookList(long bookId);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ public final class Library {
|
|||
}
|
||||
|
||||
private final LinkedList<Book> myBooks = new LinkedList<Book>();
|
||||
private final HashSet<Book> myExternalBooks = new HashSet<Book>();
|
||||
private final LibraryTree myLibraryByAuthor = new RootTree();
|
||||
private final LibraryTree myLibraryByTag = new RootTree();
|
||||
private final LibraryTree myRecentBooks = new RootTree();
|
||||
|
@ -52,6 +53,7 @@ public final class Library {
|
|||
myDoRebuild = true;
|
||||
|
||||
myBooks.clear();
|
||||
myExternalBooks.clear();
|
||||
myLibraryByAuthor.clear();
|
||||
myLibraryByTag.clear();
|
||||
myRecentBooks.clear();
|
||||
|
@ -70,7 +72,7 @@ public final class Library {
|
|||
}
|
||||
|
||||
private static Book getBook(ZLFile bookFile, FileInfoSet fileInfos, Map<Long,Book> saved, boolean doReadMetaInfo) {
|
||||
Book book = saved.get(fileInfos.getId(bookFile));
|
||||
Book book = saved.remove(fileInfos.getId(bookFile));
|
||||
if (book == null) {
|
||||
doReadMetaInfo = true;
|
||||
book = new Book(bookFile);
|
||||
|
@ -98,6 +100,33 @@ public final class Library {
|
|||
}
|
||||
}
|
||||
|
||||
private void collectExternalBooks(FileInfoSet fileInfos, Map<Long,Book> savedBooks) {
|
||||
final HashSet<ZLPhysicalFile> myUpdatedFiles = new HashSet<ZLPhysicalFile>();
|
||||
final HashSet<Long> files = new HashSet<Long>(savedBooks.keySet());
|
||||
for (Long fileId: files) {
|
||||
final ZLFile bookFile = fileInfos.getFile(fileId);
|
||||
if (bookFile == null) {
|
||||
continue;
|
||||
}
|
||||
final ZLPhysicalFile physicalFile = bookFile.getPhysicalFile();
|
||||
if (!physicalFile.exists()) {
|
||||
continue;
|
||||
}
|
||||
boolean reloadMetaInfo = false;
|
||||
if (myUpdatedFiles.contains(physicalFile)) {
|
||||
reloadMetaInfo = true;
|
||||
} else if (!fileInfos.check(physicalFile)) {
|
||||
reloadMetaInfo = true;
|
||||
myUpdatedFiles.add(physicalFile);
|
||||
}
|
||||
final Book book = getBook(bookFile, fileInfos, savedBooks, reloadMetaInfo);
|
||||
if (book != null) {
|
||||
myBooks.add(book);
|
||||
myExternalBooks.add(book);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<ZLPhysicalFile> collectPhysicalFiles() {
|
||||
final Queue<ZLFile> dirQueue = new LinkedList<ZLFile>();
|
||||
final HashSet<ZLFile> dirSet = new HashSet<ZLFile>();
|
||||
|
@ -147,6 +176,8 @@ public final class Library {
|
|||
//android.os.Debug.stopMethodTracing();
|
||||
//System.err.println("books have been synchronized " + (System.currentTimeMillis() - start));
|
||||
|
||||
collectExternalBooks(fileInfos, savedBooks);
|
||||
|
||||
//android.os.Debug.startMethodTracing("/sdcard/ll4");
|
||||
fileInfos.save();
|
||||
//android.os.Debug.stopMethodTracing();
|
||||
|
@ -315,7 +346,18 @@ public final class Library {
|
|||
db.saveRecentBookIds(ids);
|
||||
}
|
||||
|
||||
public boolean canDeleteBook(Book book) {
|
||||
public static final int REMOVE_DONT_REMOVE = 0x00;
|
||||
public static final int REMOVE_FROM_LIBRARY = 0x01;
|
||||
public static final int REMOVE_FROM_DISK = 0x02;
|
||||
public static final int REMOVE_FROM_LIBRARY_AND_DISK = REMOVE_FROM_LIBRARY | REMOVE_FROM_DISK;
|
||||
|
||||
public int getRemoveBookMode(Book book) {
|
||||
synchronize();
|
||||
return (myExternalBooks.contains(book) ? REMOVE_FROM_LIBRARY : REMOVE_DONT_REMOVE)
|
||||
| (canDeleteBookFile(book) ? REMOVE_FROM_DISK : REMOVE_DONT_REMOVE);
|
||||
}
|
||||
|
||||
private boolean canDeleteBookFile(Book book) {
|
||||
ZLFile file = book.File;
|
||||
if (file.getPhysicalFile() == null) {
|
||||
return false;
|
||||
|
@ -329,7 +371,10 @@ public final class Library {
|
|||
return true;
|
||||
}
|
||||
|
||||
public void deleteBook(Book book) {
|
||||
public void removeBook(Book book, int removeMode) {
|
||||
if (removeMode == REMOVE_DONT_REMOVE) {
|
||||
return;
|
||||
}
|
||||
synchronize();
|
||||
myBooks.remove(book);
|
||||
myLibraryByAuthor.removeBook(book);
|
||||
|
@ -341,6 +386,10 @@ public final class Library {
|
|||
db.saveRecentBookIds(ids);
|
||||
}
|
||||
mySearchResult.removeBook(book);
|
||||
book.File.getPhysicalFile().delete();
|
||||
|
||||
BooksDatabase.Instance().deleteFromBookList(book.getId());
|
||||
if ((removeMode & REMOVE_FROM_DISK) != 0) {
|
||||
book.File.getPhysicalFile().delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue