diff --git a/src/org/geometerplus/android/fbreader/library/BookInfoActivity.java b/src/org/geometerplus/android/fbreader/library/BookInfoActivity.java index 84b3ab600..3338c08ca 100644 --- a/src/org/geometerplus/android/fbreader/library/BookInfoActivity.java +++ b/src/org/geometerplus/android/fbreader/library/BookInfoActivity.java @@ -241,7 +241,7 @@ public class BookInfoActivity extends Activity { setupInfoPair(R.id.book_authors, "authors", buffer, authors.size()); final SeriesInfo series = book.getSeriesInfo(); - setupInfoPair(R.id.book_series, "series", series == null ? null : series.Title); + setupInfoPair(R.id.book_series, "series", series == null ? null : series.Series.getTitle()); String seriesIndexString = null; if (series != null && series.Index != null) { seriesIndexString = series.Index.toString(); diff --git a/src/org/geometerplus/android/fbreader/libraryService/SQLiteBooksDatabase.java b/src/org/geometerplus/android/fbreader/libraryService/SQLiteBooksDatabase.java index 649dd019b..804a4c9f0 100644 --- a/src/org/geometerplus/android/fbreader/libraryService/SQLiteBooksDatabase.java +++ b/src/org/geometerplus/android/fbreader/libraryService/SQLiteBooksDatabase.java @@ -492,10 +492,10 @@ final class SQLiteBooksDatabase extends BooksDatabase { } else { long seriesId; try { - myGetSeriesIdStatement.bindString(1, seriesInfo.Title); + myGetSeriesIdStatement.bindString(1, seriesInfo.Series.getTitle()); seriesId = myGetSeriesIdStatement.simpleQueryForLong(); } catch (SQLException e) { - myInsertSeriesStatement.bindString(1, seriesInfo.Title); + myInsertSeriesStatement.bindString(1, seriesInfo.Series.getTitle()); seriesId = myInsertSeriesStatement.executeInsert(); } myInsertBookSeriesStatement.bindLong(1, bookId); diff --git a/src/org/geometerplus/fbreader/book/Book.java b/src/org/geometerplus/fbreader/book/Book.java index 9b4de8f89..d4ceebf82 100644 --- a/src/org/geometerplus/fbreader/book/Book.java +++ b/src/org/geometerplus/fbreader/book/Book.java @@ -37,9 +37,9 @@ import org.geometerplus.zlibrary.text.view.ZLTextPosition; import org.geometerplus.fbreader.Paths; import org.geometerplus.fbreader.bookmodel.BookReadingException; import org.geometerplus.fbreader.formats.*; -import org.geometerplus.fbreader.sort.Title; +import org.geometerplus.fbreader.sort.TitledEntity; -public class Book { +public class Book extends TitledEntity { public static final String FAVORITE_LABEL = "favorite"; public final ZLFile File; @@ -47,7 +47,7 @@ public class Book { private volatile long myId; private volatile String myEncoding; - private volatile Title myInfo; + private volatile String myLanguage; private volatile List myAuthors; private volatile List myTags; private volatile SeriesInfo mySeriesInfo; @@ -58,14 +58,16 @@ public class Book { private WeakReference myCover; Book(long id, ZLFile file, String title, String encoding, String language) { + super(title); myId = id; File = file; - myInfo = new Title(title, language); + myLanguage = language; myEncoding = encoding; myIsSaved = true; } Book(ZLFile file) throws BookReadingException { + super(null); myId = -1; final FormatPlugin plugin = getPlugin(file); File = plugin.realBookFile(file); @@ -77,7 +79,8 @@ public class Book { if (myId != book.myId) { return; } - myInfo = book.myInfo; + setTitle(book.getTitle()); + myLanguage = book.myLanguage; myEncoding = book.myEncoding; myAuthors = book.myAuthors != null ? new ArrayList(book.myAuthors) : null; myTags = book.myTags != null ? new ArrayList(book.myTags) : null; @@ -109,8 +112,9 @@ public class Book { } private void readMetaInfo(FormatPlugin plugin) throws BookReadingException { + setTitle(null); myEncoding = null; - myInfo = new Title (null, null); + myLanguage = null; myAuthors = null; myTags = null; mySeriesInfo = null; @@ -119,7 +123,7 @@ public class Book { plugin.readMetaInfo(this); - if (myInfo.getTitle() == null || myInfo.getTitle().length() == 0) { + if (getTitle() == null || getTitle().length() == 0) { final String fileName = File.getShortName(); final int index = fileName.lastIndexOf('.'); setTitle(index > 0 ? fileName.substring(0, index) : fileName); @@ -204,13 +208,9 @@ public class Book { return myId; } - public String getTitle() { - return myInfo.getTitle(); - } - public void setTitle(String title) { - if (!MiscUtil.equals(myInfo.getTitle(), title)) { - myInfo.setTitle(title); + if (!MiscUtil.equals(getTitle(), title)) { + super.setTitle(title); myIsSaved = false; } } @@ -236,23 +236,20 @@ public class Book { } else if (name == null) { mySeriesInfo = null; myIsSaved = false; - } else if (!name.equals(mySeriesInfo.Title) || mySeriesInfo.Index != index) { + } else if (!name.equals(mySeriesInfo.Series.getTitle()) || mySeriesInfo.Index != index) { mySeriesInfo = new SeriesInfo(name, index); myIsSaved = false; } } - public Title getInfo() { - return myInfo; - } - public String getLanguage() { - return myInfo.getLanguage(); + return myLanguage; } public void setLanguage(String language) { - if (!MiscUtil.equals(myInfo.getLanguage(), language)) { - myInfo.setLanguage(language); + if (!MiscUtil.equals(myLanguage, language)) { + myLanguage = language; + resetSortKey(); myIsSaved = false; } } @@ -316,10 +313,10 @@ public class Book { } public boolean matches(String pattern) { - if (myInfo.getTitle() != null && MiscUtil.matchesIgnoreCase(myInfo.getTitle(), pattern)) { + if (getTitle() != null && MiscUtil.matchesIgnoreCase(getTitle(), pattern)) { return true; } - if (mySeriesInfo != null && MiscUtil.matchesIgnoreCase(mySeriesInfo.Title, pattern)) { + if (mySeriesInfo != null && MiscUtil.matchesIgnoreCase(mySeriesInfo.Series.getTitle(), pattern)) { return true; } if (myAuthors != null) { @@ -351,9 +348,9 @@ public class Book { public void run() { if (myId >= 0) { final FileInfoSet fileInfos = new FileInfoSet(database, File); - database.updateBookInfo(myId, fileInfos.getId(File), myEncoding, myInfo.getLanguage(), myInfo.getTitle()); + database.updateBookInfo(myId, fileInfos.getId(File), myEncoding, myLanguage, getTitle()); } else { - myId = database.insertBookInfo(File, myEncoding, myInfo.getLanguage(), myInfo.getTitle()); + myId = database.insertBookInfo(File, myEncoding, myLanguage, getTitle()); if (myId != -1 && myVisitedHyperlinks != null) { for (String linkId : myVisitedHyperlinks) { database.addVisitedHyperlink(myId, linkId); diff --git a/src/org/geometerplus/fbreader/book/BookCollection.java b/src/org/geometerplus/fbreader/book/BookCollection.java index 25cb4716d..05dfb9c6b 100644 --- a/src/org/geometerplus/fbreader/book/BookCollection.java +++ b/src/org/geometerplus/fbreader/book/BookCollection.java @@ -228,7 +228,7 @@ public class BookCollection extends AbstractBookCollection { final LinkedList filtered = new LinkedList(); for (Book b : books()) { final SeriesInfo info = b.getSeriesInfo(); - if (info != null && series.equals(info.Title)) { + if (info != null && series.equals(info.Series.getTitle())) { filtered.add(b); } } @@ -241,7 +241,7 @@ public class BookCollection extends AbstractBookCollection { for (Book b : books()) { final List bookAuthors = b.authors(); final SeriesInfo info = b.getSeriesInfo(); - if (info != null && series.equals(info.Title) + if (info != null && series.equals(info.Series.getTitle()) && (isNull && bookAuthors.isEmpty() || bookAuthors.contains(author))) { filtered.add(b); } @@ -358,7 +358,7 @@ public class BookCollection extends AbstractBookCollection { for (Book book : myBooksByFile.values()) { final SeriesInfo info = book.getSeriesInfo(); if (info != null) { - series.add(info.Title); + series.add(info.Series.getTitle()); } } } @@ -402,7 +402,7 @@ public class BookCollection extends AbstractBookCollection { synchronized (myBooksByFile) { for (Book b : myBooksByFile.values()) { final SeriesInfo info = b.getSeriesInfo(); - if (info != null && series.equals(info.Title)) { + if (info != null && series.equals(info.Series.getTitle())) { titles.add(b.getTitle()); if (--limit == 0) { break; @@ -423,7 +423,7 @@ public class BookCollection extends AbstractBookCollection { for (Book b : myBooksByFile.values()) { final List bookAuthors = b.authors(); final SeriesInfo info = b.getSeriesInfo(); - if (info != null && series.equals(info.Title) + if (info != null && series.equals(info.Series.getTitle()) && (isNull && bookAuthors.isEmpty() || bookAuthors.contains(author))) { titles.add(b.getTitle()); if (--limit == 0) { diff --git a/src/org/geometerplus/fbreader/sort/TitleComparator.java b/src/org/geometerplus/fbreader/book/Series.java similarity index 57% rename from src/org/geometerplus/fbreader/sort/TitleComparator.java rename to src/org/geometerplus/fbreader/book/Series.java index 56f49d35f..ab274fc95 100644 --- a/src/org/geometerplus/fbreader/sort/TitleComparator.java +++ b/src/org/geometerplus/fbreader/book/Series.java @@ -17,13 +17,35 @@ * 02110-1301, USA. */ -package org.geometerplus.fbreader.sort; +package org.geometerplus.fbreader.book; -import java.util.*; +import org.geometerplus.zlibrary.core.util.MiscUtil; -public class TitleComparator implements Comparator { - @Override - public int compare(Title title0, Title title1) { - return title0.getSortKey().compareTo(title1.getSortKey()); +import org.geometerplus.fbreader.sort.TitledEntity; + +public class Series extends TitledEntity { + public Series(String title) { + super(title); } -} \ No newline at end of file + + public String getLanguage() { + // TODO: return real language + return "en"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Series)) { + return false; + } + return MiscUtil.equals(getTitle(), ((Series)o).getTitle()); + } + + @Override + public int hashCode() { + return MiscUtil.hashCode(getTitle()); + } +} diff --git a/src/org/geometerplus/fbreader/book/SeriesInfo.java b/src/org/geometerplus/fbreader/book/SeriesInfo.java index 61f1f0cf9..d3d9f833a 100644 --- a/src/org/geometerplus/fbreader/book/SeriesInfo.java +++ b/src/org/geometerplus/fbreader/book/SeriesInfo.java @@ -37,11 +37,11 @@ public final class SeriesInfo { } } - public final String Title; + public final Series Series; public final BigDecimal Index; SeriesInfo(String title, BigDecimal index) { - Title = title; + Series = new Series(title); Index = index; } } diff --git a/src/org/geometerplus/fbreader/book/TitleUtil.java b/src/org/geometerplus/fbreader/book/TitleUtil.java index 3cb04c560..bddfbbaab 100644 --- a/src/org/geometerplus/fbreader/book/TitleUtil.java +++ b/src/org/geometerplus/fbreader/book/TitleUtil.java @@ -24,7 +24,7 @@ public abstract class TitleUtil { if (book == null) { return null; } - return firstLetter(book.getInfo().getSortKey()); + return firstLetter(book.getSortKey()); } public static String firstLetter(String title) { @@ -37,4 +37,4 @@ public abstract class TitleUtil { } return String.valueOf(Character.toUpperCase(title.charAt(0))); } -} \ No newline at end of file +} diff --git a/src/org/geometerplus/fbreader/book/XMLSerializer.java b/src/org/geometerplus/fbreader/book/XMLSerializer.java index 3da881a91..7d87d466d 100644 --- a/src/org/geometerplus/fbreader/book/XMLSerializer.java +++ b/src/org/geometerplus/fbreader/book/XMLSerializer.java @@ -63,7 +63,7 @@ class XMLSerializer extends AbstractSerializer { final SeriesInfo seriesInfo = book.getSeriesInfo(); if (seriesInfo != null) { - appendTagWithContent(buffer, "calibre:series", seriesInfo.Title); + appendTagWithContent(buffer, "calibre:series", seriesInfo.Series.getTitle()); if (seriesInfo.Index != null) { appendTagWithContent(buffer, "calibre:series_index", seriesInfo.Index); } diff --git a/src/org/geometerplus/fbreader/library/AuthorTree.java b/src/org/geometerplus/fbreader/library/AuthorTree.java index 0ba1175ea..d330be053 100644 --- a/src/org/geometerplus/fbreader/library/AuthorTree.java +++ b/src/org/geometerplus/fbreader/library/AuthorTree.java @@ -107,7 +107,7 @@ public class AuthorTree extends LibraryTree { } } - private SeriesTree getSeriesSubTree(String series) { + private SeriesTree getSeriesSubTree(Series series) { final SeriesTree temp = new SeriesTree(Collection, series, Author); int position = Collections.binarySearch(subTrees(), temp); if (position >= 0) { @@ -120,7 +120,7 @@ public class AuthorTree extends LibraryTree { private boolean createBookSubTree(Book book) { final SeriesInfo seriesInfo = book.getSeriesInfo(); if (seriesInfo != null) { - return getSeriesSubTree(seriesInfo.Title).createBookInSeriesSubTree(book); + return getSeriesSubTree(seriesInfo.Series).createBookInSeriesSubTree(book); } final BookTree temp = new BookTree(Collection, book); diff --git a/src/org/geometerplus/fbreader/library/BookTree.java b/src/org/geometerplus/fbreader/library/BookTree.java index d319541cd..abfc8a070 100644 --- a/src/org/geometerplus/fbreader/library/BookTree.java +++ b/src/org/geometerplus/fbreader/library/BookTree.java @@ -22,10 +22,10 @@ package org.geometerplus.fbreader.library; import org.geometerplus.zlibrary.core.image.ZLImage; import org.geometerplus.fbreader.book.*; -import org.geometerplus.fbreader.sort.Title; +import org.geometerplus.fbreader.sort.TitledEntity; import org.geometerplus.fbreader.tree.FBTree; -public class BookTree extends LibraryTree { +public class BookTree extends TitledEntityTree { public final Book Book; BookTree(IBookCollection collection, Book book) { @@ -97,8 +97,7 @@ public class BookTree extends LibraryTree { } @Override - public Title getTitle() { - // TODO Auto-generated method stub - return Book.getInfo(); + public TitledEntity getTitledEntity() { + return Book; } } diff --git a/src/org/geometerplus/fbreader/library/LibraryTree.java b/src/org/geometerplus/fbreader/library/LibraryTree.java index d21cddd0e..6acb11107 100644 --- a/src/org/geometerplus/fbreader/library/LibraryTree.java +++ b/src/org/geometerplus/fbreader/library/LibraryTree.java @@ -24,8 +24,6 @@ import java.util.*; import org.geometerplus.zlibrary.core.resources.ZLResource; import org.geometerplus.fbreader.book.*; -import org.geometerplus.fbreader.sort.Title; -import org.geometerplus.fbreader.sort.TitleComparator; import org.geometerplus.fbreader.tree.FBTree; public abstract class LibraryTree extends FBTree { @@ -35,8 +33,6 @@ public abstract class LibraryTree extends FBTree { public final IBookCollection Collection; - private static final TitleComparator COMPARATOR = new TitleComparator(); - static final String ROOT_FOUND = "found"; static final String ROOT_FAVORITES = "favorites"; static final String ROOT_RECENT = "recent"; @@ -45,7 +41,7 @@ public abstract class LibraryTree extends FBTree { static final String ROOT_BY_SERIES = "bySeries"; static final String ROOT_BY_TAG = "byTag"; static final String ROOT_FILE_TREE = "fileTree"; - + protected LibraryTree(IBookCollection collection) { super(); Collection = collection; @@ -134,20 +130,10 @@ public abstract class LibraryTree extends FBTree { @Override public int compareTo(FBTree tree) { - final int cmp; - if (tree instanceof LibraryTree && null != getTitle() && null != ((LibraryTree)tree).getTitle()) { - cmp = COMPARATOR.compare(getTitle(), ((LibraryTree) tree).getTitle()); - } - else { - cmp = super.compareTo(tree); - } + final int cmp = super.compareTo(tree); if (cmp == 0) { return getClass().getSimpleName().compareTo(tree.getClass().getSimpleName()); } return cmp; } - - public Title getTitle() { - return null; - } -} \ No newline at end of file +} diff --git a/src/org/geometerplus/fbreader/library/SeriesListTree.java b/src/org/geometerplus/fbreader/library/SeriesListTree.java index fa0f70536..5933886f0 100644 --- a/src/org/geometerplus/fbreader/library/SeriesListTree.java +++ b/src/org/geometerplus/fbreader/library/SeriesListTree.java @@ -59,7 +59,8 @@ public class SeriesListTree extends FirstLevelTree { { // TODO: remove empty series tree after update (?) final SeriesInfo info = book.getSeriesInfo(); - return info != null && createSeriesSubTree(info.Title); + // TODO: pass series + return info != null && createSeriesSubTree(info.Series.getTitle()); } case Removed: // TODO: remove empty series tree (?) @@ -69,7 +70,9 @@ public class SeriesListTree extends FirstLevelTree { } } - private boolean createSeriesSubTree(String series) { + private boolean createSeriesSubTree(String seriesTitle) { + // TODO: pass series as parameter + final Series series = new Series(seriesTitle); final SeriesTree temp = new SeriesTree(Collection, series, null); int position = Collections.binarySearch(subTrees(), temp); if (position >= 0) { diff --git a/src/org/geometerplus/fbreader/library/SeriesTree.java b/src/org/geometerplus/fbreader/library/SeriesTree.java index efc3ee62c..87a518ecc 100644 --- a/src/org/geometerplus/fbreader/library/SeriesTree.java +++ b/src/org/geometerplus/fbreader/library/SeriesTree.java @@ -25,25 +25,21 @@ import java.util.List; import org.geometerplus.zlibrary.core.util.MiscUtil; import org.geometerplus.fbreader.book.*; -import org.geometerplus.fbreader.sort.Title; +import org.geometerplus.fbreader.sort.TitledEntity; -import android.widget.Toast; - -public final class SeriesTree extends LibraryTree { - public final Title Series; +public final class SeriesTree extends TitledEntityTree { + public final Series Series; public final Author Author; - SeriesTree(IBookCollection collection, String series, Author author) { + SeriesTree(IBookCollection collection, Series series, Author author) { super(collection); - String language = collection.booksForSeries(series).get(0).getLanguage(); - Series = new Title(series, language); + Series = series; Author = author; } - SeriesTree(LibraryTree parent, String series, Author author, int position) { + SeriesTree(LibraryTree parent, Series series, Author author, int position) { super(parent, position); - String language = parent.Collection.booksForSeries(series).get(0).getLanguage(); - Series = new Title(series, language); + Series = series; Author = author; } @@ -72,7 +68,7 @@ public final class SeriesTree extends LibraryTree { return false; } final SeriesInfo info = book.getSeriesInfo(); - return info != null && Series.getTitle().equals(info.Title); + return info != null && Series.equals(info.Series); } @Override @@ -128,9 +124,7 @@ public final class SeriesTree extends LibraryTree { } @Override - public Title getTitle() { - // TODO Auto-generated method stub - //System.err.println(Series.getSortKey() + Series.getLanguage()); + public TitledEntity getTitledEntity() { return Series; } -} \ No newline at end of file +} diff --git a/src/org/geometerplus/fbreader/library/TitleListTree.java b/src/org/geometerplus/fbreader/library/TitleListTree.java index 10f36767d..7be609ff0 100644 --- a/src/org/geometerplus/fbreader/library/TitleListTree.java +++ b/src/org/geometerplus/fbreader/library/TitleListTree.java @@ -44,7 +44,7 @@ public class TitleListTree extends FirstLevelTree { final List<Book> book = Collection.books(); final List<String> keys = new ArrayList<String>(); for (Book b : book) { - keys.add(b.getInfo().getSortKey()); + keys.add(b.getSortKey()); } if (keys.size() > 9) { for (String t : keys) { diff --git a/src/org/geometerplus/fbreader/library/TitledEntityTree.java b/src/org/geometerplus/fbreader/library/TitledEntityTree.java new file mode 100644 index 000000000..185d08846 --- /dev/null +++ b/src/org/geometerplus/fbreader/library/TitledEntityTree.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009-2013 Geometer Plus <contact@geometerplus.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 Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +package org.geometerplus.fbreader.library; + +import org.geometerplus.fbreader.book.IBookCollection; +import org.geometerplus.fbreader.sort.TitledEntity; +import org.geometerplus.fbreader.tree.FBTree; + +public abstract class TitledEntityTree extends LibraryTree { + TitledEntityTree(IBookCollection collection) { + super(collection); + } + + TitledEntityTree(LibraryTree parent) { + super(parent); + } + + TitledEntityTree(LibraryTree parent, int position) { + super(parent, position); + } + + protected abstract TitledEntity getTitledEntity(); + + @Override + public int compareTo(FBTree tree) { + if (tree instanceof TitledEntityTree) { + return getTitledEntity().compareTo(((TitledEntityTree)tree).getTitledEntity()); + } + return super.compareTo(tree); + } +} diff --git a/src/org/geometerplus/fbreader/sort/Title.java b/src/org/geometerplus/fbreader/sort/TitledEntity.java similarity index 90% rename from src/org/geometerplus/fbreader/sort/Title.java rename to src/org/geometerplus/fbreader/sort/TitledEntity.java index ffbcf5cf7..7510f1c6b 100644 --- a/src/org/geometerplus/fbreader/sort/Title.java +++ b/src/org/geometerplus/fbreader/sort/TitledEntity.java @@ -26,38 +26,33 @@ import java.util.Map; import android.annotation.TargetApi; import android.os.Build; -public class Title { - private String myText; - private String myLanguage; +public abstract class TitledEntity implements Comparable<TitledEntity> { + private String myTitle; private String mySortKey; - public Title(String title, String language) { - myText = title; - myLanguage = language; - } - - public void setTitle(String title) { - myText = title; - mySortKey = null; - } - - public void setLanguage(String language) { - myLanguage = language; - mySortKey = null; + public TitledEntity(String title) { + myTitle = title; } public String getTitle() { - return myText; + return myTitle; } - public String getLanguage() { - return myLanguage; + public void setTitle(String title) { + myTitle = title; + mySortKey = null; } + + protected void resetSortKey() { + mySortKey = null; + } + + public abstract String getLanguage(); public String getSortKey() { if (null == mySortKey) { - mySortKey = trim(myText, myLanguage); - } + mySortKey = trim(myTitle, getLanguage()); + } return mySortKey; } @@ -65,12 +60,12 @@ public class Title { // English articles private final static String[] EN_ARTICLES = new String[] { "the ", "a ", "an " - }; + }; // French articles private final static String[] FR_ARTICLES = new String[] { "un ", "une ", "le ", "la ", "les ", "du ", "de ", "des ", "de la", "l ", "de l " - }; + }; // German articles private final static String[] GE_ARTICLES = new String[] { "das ", "des ", "dem ", "die ", "der ", "den ", @@ -155,4 +150,8 @@ public class Title { private static String normalize(String s) { return Normalizer.normalize(s, Normalizer.Form.NFKD); } + + public int compareTo(TitledEntity entity) { + return getSortKey().compareTo(entity.getSortKey()); + } }