1
0
Fork 0
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:
Vasiliy Bout 2010-09-13 19:06:14 +00:00
parent 5f4f6ac801
commit b9b7f61ad9
7 changed files with 120 additions and 11 deletions

View file

@ -15,6 +15,7 @@ DONE Возможность открывать локальные файлы и
DONE На этой странице есть ссылка на epub-файл "для ПК". http://www.zone4iphone.ru/index.php?p_id=7&b_id=18413
Проверить скачивание книги браузером и возможность чтения из папки, куда файл был скачан.
** добавлять в библиотеку (сделать таблицу добавленных вручную книг)
** сделать новый диалог удаления файлов (удаление файла / удаление из библиотеки)
------------------------------

View file

@ -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();
}

View file

@ -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))");
}
}

View file

@ -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()) {

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
BooksDatabase.Instance().deleteFromBookList(book.getId());
if ((removeMode & REMOVE_FROM_DISK) != 0) {
book.File.getPhysicalFile().delete();
}
}
}