mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-03 17:59:33 +02:00
hightlighting style from db
This commit is contained in:
parent
03c7137db6
commit
3991c59ce1
15 changed files with 241 additions and 16 deletions
|
@ -2,7 +2,7 @@ DONE highlight bookmarks
|
|||
* show highlights in footnote view
|
||||
* don't draw all bookmarks, filter by position
|
||||
* restore end position for old bookmarks
|
||||
* save bookmark style
|
||||
DONE save bookmark style
|
||||
* change style (color) for bookmarks: user interface
|
||||
DONE watch bookmark changes
|
||||
DONE fix selection bookmark range
|
||||
|
|
|
@ -416,6 +416,28 @@ public class BookCollectionShadow extends AbstractBookCollection implements Serv
|
|||
}
|
||||
}
|
||||
|
||||
public HighlightingStyle getHighlightingStyle(int styleId) {
|
||||
if (myInterface == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return SerializerUtil.deserializeStyle(myInterface.getHighlightingStyle(styleId));
|
||||
} catch (RemoteException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<HighlightingStyle> highlightingStyles() {
|
||||
if (myInterface == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
try {
|
||||
return SerializerUtil.deserializeStyleList(myInterface.highlightingStyles());
|
||||
} catch (RemoteException e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
// method from ServiceConnection interface
|
||||
public synchronized void onServiceConnected(ComponentName name, IBinder service) {
|
||||
myInterface = LibraryInterface.Stub.asInterface(service);
|
||||
|
|
|
@ -44,4 +44,7 @@ interface LibraryInterface {
|
|||
List<String> bookmarks(in String query);
|
||||
String saveBookmark(in String bookmark);
|
||||
void deleteBookmark(in String bookmark);
|
||||
|
||||
String getHighlightingStyle(in int styleId);
|
||||
List<String> highlightingStyles();
|
||||
}
|
||||
|
|
|
@ -261,6 +261,14 @@ public class LibraryService extends Service {
|
|||
public void deleteBookmark(String serialized) {
|
||||
myCollection.deleteBookmark(SerializerUtil.deserializeBookmark(serialized));
|
||||
}
|
||||
|
||||
public String getHighlightingStyle(int styleId) {
|
||||
return SerializerUtil.serialize(myCollection.getHighlightingStyle(styleId));
|
||||
}
|
||||
|
||||
public List<String> highlightingStyles() {
|
||||
return SerializerUtil.serializeStyleList(myCollection.highlightingStyles());
|
||||
}
|
||||
}
|
||||
|
||||
private volatile LibraryImplementation myLibrary;
|
||||
|
|
|
@ -878,6 +878,18 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
|||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<HighlightingStyle> loadStyles() {
|
||||
final LinkedList<HighlightingStyle> list = new LinkedList<HighlightingStyle>();
|
||||
final String sql = "SELECT style_id,bg_color FROM HighlightingStyle";
|
||||
final Cursor cursor = myDatabase.rawQuery(sql, null);
|
||||
while (cursor.moveToNext()) {
|
||||
list.add(createStyle((int)cursor.getLong(0), (int)cursor.getLong(1)));
|
||||
}
|
||||
cursor.close();
|
||||
return list;
|
||||
}
|
||||
|
||||
private SQLiteStatement myInsertBookmarkStatement;
|
||||
private SQLiteStatement myUpdateBookmarkStatement;
|
||||
@Override
|
||||
|
@ -1397,9 +1409,9 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
|||
"style_id INTEGER PRIMARY KEY," +
|
||||
"name TEXT," +
|
||||
"bg_color INTEGER NOT NULL)");
|
||||
myDatabase.execSQL("INSERT INTO HighlightingStyle (style_id, name, bg_color) VALUES (1, 'default', 136*256*256 + 138*256 + 133)"); // #888a85
|
||||
myDatabase.execSQL("INSERT INTO HighlightingStyle (style_id, name, bg_color) VALUES (2, 'orange', 245*256*256 + 121*256 + 0)"); // #f57900
|
||||
myDatabase.execSQL("INSERT INTO HighlightingStyle (style_id, name, bg_color) VALUES (3, 'blue', 114*160*256 + 159*256 + 207)"); // #729fcf
|
||||
myDatabase.execSQL("INSERT OR REPLACE INTO HighlightingStyle (style_id, name, bg_color) VALUES (1, 'default', 136*256*256 + 138*256 + 133)"); // #888a85
|
||||
myDatabase.execSQL("INSERT OR REPLACE INTO HighlightingStyle (style_id, name, bg_color) VALUES (2, 'orange', 245*256*256 + 121*256 + 0)"); // #f57900
|
||||
myDatabase.execSQL("INSERT OR REPLACE INTO HighlightingStyle (style_id, name, bg_color) VALUES (3, 'blue', 114*160*256 + 159*256 + 207)"); // #729fcf
|
||||
myDatabase.execSQL("ALTER TABLE Bookmarks ADD COLUMN style_id INTEGER NOT NULL REFERENCES HighlightingStyle(style_id) DEFAULT 1");
|
||||
myDatabase.execSQL("UPDATE Bookmarks SET end_paragraph = LENGTH(bookmark_text)");
|
||||
}
|
||||
|
|
|
@ -31,4 +31,7 @@ abstract class AbstractSerializer {
|
|||
|
||||
public abstract String serialize(Bookmark bookmark);
|
||||
public abstract Bookmark deserializeBookmark(String data);
|
||||
|
||||
public abstract String serialize(HighlightingStyle style);
|
||||
public abstract HighlightingStyle deserializeStyle(String data);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,9 @@ public class BookCollection extends AbstractBookCollection {
|
|||
|
||||
private volatile Status myStatus = Status.NotStarted;
|
||||
|
||||
private final Map<Integer,HighlightingStyle> myStyles =
|
||||
Collections.synchronizedMap(new TreeMap<Integer,HighlightingStyle>());
|
||||
|
||||
public BookCollection(BooksDatabase db, List<String> bookDirectories) {
|
||||
myDatabase = db;
|
||||
BookDirectories = Collections.unmodifiableList(new ArrayList<String>(bookDirectories));
|
||||
|
@ -653,4 +656,22 @@ public class BookCollection extends AbstractBookCollection {
|
|||
public void markHyperlinkAsVisited(Book book, String linkId) {
|
||||
book.markHyperlinkAsVisited(myDatabase, linkId);
|
||||
}
|
||||
|
||||
private synchronized void initStylesTable() {
|
||||
if (myStyles.isEmpty()) {
|
||||
for (HighlightingStyle style : myDatabase.loadStyles()) {
|
||||
myStyles.put(style.Id, style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HighlightingStyle getHighlightingStyle(int styleId) {
|
||||
initStylesTable();
|
||||
return myStyles.get(styleId);
|
||||
}
|
||||
|
||||
public List<HighlightingStyle> highlightingStyles() {
|
||||
initStylesTable();
|
||||
return new ArrayList<HighlightingStyle>(myStyles.values());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.geometerplus.fbreader.book;
|
|||
import java.util.*;
|
||||
|
||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||
import org.geometerplus.zlibrary.core.util.ZLColor;
|
||||
|
||||
import org.geometerplus.zlibrary.text.view.ZLTextPosition;
|
||||
|
||||
|
@ -110,6 +111,11 @@ public abstract class BooksDatabase {
|
|||
protected abstract long saveBookmark(Bookmark bookmark);
|
||||
protected abstract void deleteBookmark(Bookmark bookmark);
|
||||
|
||||
protected HighlightingStyle createStyle(int id, int color) {
|
||||
return new HighlightingStyle(id, new ZLColor(color));
|
||||
}
|
||||
protected abstract List<HighlightingStyle> loadStyles();
|
||||
|
||||
protected abstract ZLTextPosition getStoredPosition(long bookId);
|
||||
protected abstract void storePosition(long bookId, ZLTextPosition position);
|
||||
|
||||
|
|
35
src/org/geometerplus/fbreader/book/HighlightingStyle.java
Normal file
35
src/org/geometerplus/fbreader/book/HighlightingStyle.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2007-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.book;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.geometerplus.zlibrary.core.util.ZLColor;
|
||||
|
||||
public class HighlightingStyle {
|
||||
public final int Id;
|
||||
public final ZLColor BackgroundColor;
|
||||
|
||||
HighlightingStyle(int id, ZLColor bgColor) {
|
||||
Id = id;
|
||||
BackgroundColor = bgColor;
|
||||
}
|
||||
}
|
|
@ -82,4 +82,7 @@ public interface IBookCollection {
|
|||
List<Bookmark> bookmarks(BookmarkQuery query);
|
||||
void saveBookmark(Bookmark bookmark);
|
||||
void deleteBookmark(Bookmark bookmark);
|
||||
|
||||
HighlightingStyle getHighlightingStyle(int styleId);
|
||||
List<HighlightingStyle> highlightingStyles();
|
||||
}
|
||||
|
|
|
@ -51,14 +51,6 @@ public abstract class SerializerUtil {
|
|||
return xml != null ? defaultSerializer.deserializeBook(xml) : null;
|
||||
}
|
||||
|
||||
public static String serialize(Bookmark bookmark) {
|
||||
return bookmark != null ? defaultSerializer.serialize(bookmark) : null;
|
||||
}
|
||||
|
||||
public static Bookmark deserializeBookmark(String xml) {
|
||||
return xml != null ? defaultSerializer.deserializeBookmark(xml) : null;
|
||||
}
|
||||
|
||||
public static List<String> serializeBookList(List<Book> books) {
|
||||
final List<String> serialized = new ArrayList<String>(books.size());
|
||||
for (Book b : books) {
|
||||
|
@ -78,6 +70,14 @@ public abstract class SerializerUtil {
|
|||
return books;
|
||||
}
|
||||
|
||||
public static String serialize(Bookmark bookmark) {
|
||||
return bookmark != null ? defaultSerializer.serialize(bookmark) : null;
|
||||
}
|
||||
|
||||
public static Bookmark deserializeBookmark(String xml) {
|
||||
return xml != null ? defaultSerializer.deserializeBookmark(xml) : null;
|
||||
}
|
||||
|
||||
public static List<String> serializeBookmarkList(List<Bookmark> bookmarks) {
|
||||
final List<String> serialized = new ArrayList<String>(bookmarks.size());
|
||||
for (Bookmark b : bookmarks) {
|
||||
|
@ -96,4 +96,31 @@ public abstract class SerializerUtil {
|
|||
}
|
||||
return bookmarks;
|
||||
}
|
||||
|
||||
public static String serialize(HighlightingStyle style) {
|
||||
return style != null ? defaultSerializer.serialize(style) : null;
|
||||
}
|
||||
|
||||
public static HighlightingStyle deserializeStyle(String xml) {
|
||||
return xml != null ? defaultSerializer.deserializeStyle(xml) : null;
|
||||
}
|
||||
|
||||
public static List<String> serializeStyleList(List<HighlightingStyle> styles) {
|
||||
final List<String> serialized = new ArrayList<String>(styles.size());
|
||||
for (HighlightingStyle s : styles) {
|
||||
serialized.add(defaultSerializer.serialize(s));
|
||||
}
|
||||
return serialized;
|
||||
}
|
||||
|
||||
public static List<HighlightingStyle> deserializeStyleList(List<String> xmlList) {
|
||||
final List<HighlightingStyle> styles = new ArrayList<HighlightingStyle>(xmlList.size());
|
||||
for (String xml : xmlList) {
|
||||
final HighlightingStyle s = defaultSerializer.deserializeStyle(xml);
|
||||
if (s != null) {
|
||||
styles.add(s);
|
||||
}
|
||||
}
|
||||
return styles;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.text.ParseException;
|
|||
|
||||
import org.geometerplus.zlibrary.core.constants.XMLNamespaces;
|
||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||
import org.geometerplus.zlibrary.core.util.ZLColor;
|
||||
|
||||
import org.geometerplus.zlibrary.text.view.ZLTextPosition;
|
||||
|
||||
|
@ -305,6 +306,32 @@ class XMLSerializer extends AbstractSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serialize(HighlightingStyle style) {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
appendTag(buffer, "style", false,
|
||||
"id", String.valueOf(style.Id)
|
||||
);
|
||||
appendTag(buffer, "bg-color", true,
|
||||
"value", String.valueOf(style.BackgroundColor.getIntValue())
|
||||
);
|
||||
closeTag(buffer, "style");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HighlightingStyle deserializeStyle(String xml) {
|
||||
try {
|
||||
final StyleDeserializer deserializer = new StyleDeserializer();
|
||||
Xml.parse(xml, deserializer);
|
||||
return deserializer.getStyle();
|
||||
} catch (SAXException e) {
|
||||
System.err.println(xml);
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static DateFormat ourDateFormatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.FULL, Locale.ENGLISH);
|
||||
private static String formatDate(Date date) {
|
||||
return date != null ? ourDateFormatter.format(date) : null;
|
||||
|
@ -930,4 +957,45 @@ class XMLSerializer extends AbstractSerializer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class StyleDeserializer extends DefaultHandler {
|
||||
private HighlightingStyle myStyle;
|
||||
|
||||
private int myId = -1;
|
||||
private int myColor;
|
||||
|
||||
public HighlightingStyle getStyle() {
|
||||
return myStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startDocument() {
|
||||
myStyle = null;
|
||||
myId = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endDocument() {
|
||||
if (myId != -1) {
|
||||
myStyle = new HighlightingStyle(myId, new ZLColor(myColor));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
if ("style".equals(localName)) {
|
||||
try {
|
||||
myId = Integer.parseInt(attributes.getValue("id"));
|
||||
} catch (Exception e) {
|
||||
throw new SAXException("XML parsing error", e);
|
||||
}
|
||||
} else if ("bg-color".equals(localName)) {
|
||||
try {
|
||||
myColor = Integer.parseInt(attributes.getValue("value"));
|
||||
} catch (Exception e) {
|
||||
throw new SAXException("XML parsing error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,12 @@ import org.geometerplus.zlibrary.core.util.ZLColor;
|
|||
|
||||
import org.geometerplus.zlibrary.text.view.*;
|
||||
|
||||
import org.geometerplus.fbreader.book.Bookmark;
|
||||
import org.geometerplus.fbreader.book.*;
|
||||
|
||||
public final class BookmarkHighlighting extends ZLTextSimpleHighlighting {
|
||||
final IBookCollection myCollection;
|
||||
final Bookmark myBookmark;
|
||||
|
||||
private static ZLTextPosition endPosition(Bookmark bookmark) {
|
||||
final ZLTextPosition end = bookmark.getEnd();
|
||||
if (end != null) {
|
||||
|
@ -35,12 +38,15 @@ public final class BookmarkHighlighting extends ZLTextSimpleHighlighting {
|
|||
return bookmark;
|
||||
}
|
||||
|
||||
BookmarkHighlighting(ZLTextView view, Bookmark bookmark) {
|
||||
BookmarkHighlighting(ZLTextView view, IBookCollection collection, Bookmark bookmark) {
|
||||
super(view, bookmark, endPosition(bookmark));
|
||||
myCollection = collection;
|
||||
myBookmark = bookmark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZLColor getBackgroundColor() {
|
||||
return new ZLColor(0x888A85);
|
||||
final HighlightingStyle bmStyle = myCollection.getHighlightingStyle(myBookmark.getStyleId());
|
||||
return bmStyle != null ? bmStyle.BackgroundColor : new ZLColor(255, 255, 255);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@ public final class FBReaderApp extends ZLApplication {
|
|||
}
|
||||
for (Bookmark b : bookmarks) {
|
||||
if (b.ModelId == null) {
|
||||
BookTextView.addHighlighting(new BookmarkHighlighting(BookTextView, b));
|
||||
BookTextView.addHighlighting(new BookmarkHighlighting(BookTextView, Collection, b));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ public final class ZLColor {
|
|||
return (Red << 16) + (Green << 8) + Blue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
|
@ -57,7 +58,17 @@ public final class ZLColor {
|
|||
return (color.Red == Red) && (color.Green == Green) && (color.Blue == Blue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getIntValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("ZLColor(")
|
||||
.append(String.valueOf(Red)).append(", ")
|
||||
.append(String.valueOf(Green)).append(", ")
|
||||
.append(String.valueOf(Blue)).append(")")
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue