1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-04 18:29:23 +02:00

store end position in bookmarks; set end position for new bookmarks

This commit is contained in:
Nikolay Pultsin 2013-04-30 00:26:44 +02:00
parent 7f5257d2fc
commit bc3f86c3fe
6 changed files with 213 additions and 109 deletions

View file

@ -646,6 +646,7 @@ public final class FBReader extends Activity {
myFBReaderApp.Model.Book,
fbView.getModel().getId(),
fbView.getSelectionStartPosition(),
fbView.getSelectionEndPosition(),
text,
true
);

View file

@ -839,7 +839,8 @@ final class SQLiteBooksDatabase extends BooksDatabase {
final StringBuilder sql = new StringBuilder("SELECT")
.append(" bm.bookmark_id,bm.book_id,b.title,bm.bookmark_text,")
.append("bm.creation_time,bm.modification_time,bm.access_time,bm.access_counter,")
.append("bm.model_id,bm.paragraph,bm.word,bm.char")
.append("bm.model_id,bm.paragraph,bm.word,bm.char,")
.append("bm.end_paragraph,bm.end_word,bm.end_character,")
.append(" FROM Bookmarks AS bm INNER JOIN Books AS b ON b.book_id = bm.book_id")
.append(" WHERE");
if (query.Book != null) {
@ -864,7 +865,10 @@ final class SQLiteBooksDatabase extends BooksDatabase {
(int)cursor.getLong(9),
(int)cursor.getLong(10),
(int)cursor.getLong(11),
true
(int)cursor.getLong(12),
cursor.isNull(13) ? -1 : (int)cursor.getLong(13),
cursor.isNull(14) ? -1 : (int)cursor.getLong(14),
query.Visible
));
}
cursor.close();

View file

@ -40,12 +40,21 @@ public final class Bookmark extends ZLTextFixedPosition {
private Date myAccessDate;
private int myAccessCount;
private Date myLatestDate;
private ZLTextFixedPosition myEnd;
private int myLength;
public final String ModelId;
public final boolean IsVisible;
Bookmark(long id, long bookId, String bookTitle, String text, Date creationDate, Date modificationDate, Date accessDate, int accessCount, String modelId, int paragraphIndex, int elementIndex, int charIndex, boolean isVisible) {
super(paragraphIndex, elementIndex, charIndex);
Bookmark(
long id, long bookId, String bookTitle, String text,
Date creationDate, Date modificationDate, Date accessDate, int accessCount,
String modelId,
int start_paragraphIndex, int start_elementIndex, int start_charIndex,
int end_paragraphIndex, int end_elementIndex, int end_charIndex,
boolean isVisible
) {
super(start_paragraphIndex, start_elementIndex, start_charIndex);
myId = id;
myBookId = bookId;
@ -63,14 +72,128 @@ public final class Bookmark extends ZLTextFixedPosition {
myAccessCount = accessCount;
ModelId = modelId;
IsVisible = isVisible;
if (end_charIndex >= 0) {
myEnd = new ZLTextFixedPosition(end_paragraphIndex, end_elementIndex, end_charIndex);
} else {
myLength = end_paragraphIndex;
}
}
private static class Buffer {
final StringBuilder Builder = new StringBuilder();
final ZLTextWordCursor Cursor;
Buffer(ZLTextWordCursor cursor) {
Cursor = new ZLTextWordCursor(cursor);
}
boolean isEmpty() {
return Builder.length() == 0;
}
void append(Buffer buffer) {
Builder.append(buffer.Builder);
Cursor.setCursor(buffer.Cursor);
buffer.Builder.delete(0, buffer.Builder.length());
}
void append(CharSequence data) {
Builder.append(data);
}
}
public static Bookmark createBookmark(Book book, String modelId, ZLTextWordCursor startCursor, int maxWords, boolean isVisible) {
final ZLTextWordCursor cursor = new ZLTextWordCursor(startCursor);
final Buffer buffer = new Buffer(cursor);
final Buffer sentenceBuffer = new Buffer(cursor);
final Buffer phraseBuffer = new Buffer(cursor);
int wordCounter = 0;
int sentenceCounter = 0;
int storedWordCounter = 0;
boolean lineIsNonEmpty = false;
boolean appendLineBreak = false;
mainLoop:
while (wordCounter < maxWords && sentenceCounter < 3) {
while (cursor.isEndOfParagraph()) {
if (!cursor.nextParagraph()) {
break mainLoop;
}
if (!buffer.isEmpty() && cursor.getParagraphCursor().isEndOfSection()) {
break mainLoop;
}
if (!phraseBuffer.isEmpty()) {
sentenceBuffer.append(phraseBuffer);
}
if (!sentenceBuffer.isEmpty()) {
if (appendLineBreak) {
buffer.append("\n");
}
buffer.append(sentenceBuffer);
++sentenceCounter;
storedWordCounter = wordCounter;
}
lineIsNonEmpty = false;
if (!buffer.isEmpty()) {
appendLineBreak = true;
}
}
final ZLTextElement element = cursor.getElement();
if (element instanceof ZLTextWord) {
final ZLTextWord word = (ZLTextWord)element;
if (lineIsNonEmpty) {
phraseBuffer.append(" ");
}
phraseBuffer.Builder.append(word.Data, word.Offset, word.Length);
phraseBuffer.Cursor.setCursor(cursor);
phraseBuffer.Cursor.setCharIndex(word.Length);
++wordCounter;
lineIsNonEmpty = true;
switch (word.Data[word.Offset + word.Length - 1]) {
case ',':
case ':':
case ';':
case ')':
sentenceBuffer.append(phraseBuffer);
break;
case '.':
case '!':
case '?':
++sentenceCounter;
if (appendLineBreak) {
buffer.append("\n");
appendLineBreak = false;
}
sentenceBuffer.append(phraseBuffer);
buffer.append(sentenceBuffer);
storedWordCounter = wordCounter;
break;
}
}
cursor.nextWord();
}
if (storedWordCounter < 4) {
if (sentenceBuffer.isEmpty()) {
sentenceBuffer.append(phraseBuffer);
}
if (appendLineBreak) {
buffer.append("\n");
}
buffer.append(sentenceBuffer);
}
return new Bookmark(book, modelId, startCursor, buffer.Cursor, buffer.Builder.toString(), isVisible);
}
/*
public Bookmark(Book book, String modelId, ZLTextWordCursor cursor, int maxLength, boolean isVisible) {
this(book, modelId, cursor, createBookmarkText(cursor, maxLength), isVisible);
}
*/
public Bookmark(Book book, String modelId, ZLTextPosition position, String text, boolean isVisible) {
super(position);
public Bookmark(Book book, String modelId, ZLTextPosition start, ZLTextPosition end, String text, boolean isVisible) {
super(start);
myId = -1;
myBookId = book.getId();
@ -79,6 +202,7 @@ public final class Bookmark extends ZLTextFixedPosition {
myCreationDate = new Date();
ModelId = modelId;
IsVisible = isVisible;
myEnd = new ZLTextFixedPosition(end);
}
public long getId() {
@ -115,6 +239,14 @@ public final class Bookmark extends ZLTextFixedPosition {
return myAccessCount;
}
public ZLTextPosition getEnd() {
return myEnd;
}
public int getLength() {
return myLength;
}
public void setText(String text) {
if (!text.equals(myText)) {
myText = text;
@ -140,92 +272,6 @@ public final class Bookmark extends ZLTextFixedPosition {
}
}
private static String createBookmarkText(ZLTextWordCursor cursor, int maxWords) {
cursor = new ZLTextWordCursor(cursor);
final StringBuilder builder = new StringBuilder();
final StringBuilder sentenceBuilder = new StringBuilder();
final StringBuilder phraseBuilder = new StringBuilder();
int wordCounter = 0;
int sentenceCounter = 0;
int storedWordCounter = 0;
boolean lineIsNonEmpty = false;
boolean appendLineBreak = false;
mainLoop:
while (wordCounter < maxWords && sentenceCounter < 3) {
while (cursor.isEndOfParagraph()) {
if (!cursor.nextParagraph()) {
break mainLoop;
}
if ((builder.length() > 0) && cursor.getParagraphCursor().isEndOfSection()) {
break mainLoop;
}
if (phraseBuilder.length() > 0) {
sentenceBuilder.append(phraseBuilder);
phraseBuilder.delete(0, phraseBuilder.length());
}
if (sentenceBuilder.length() > 0) {
if (appendLineBreak) {
builder.append("\n");
}
builder.append(sentenceBuilder);
sentenceBuilder.delete(0, sentenceBuilder.length());
++sentenceCounter;
storedWordCounter = wordCounter;
}
lineIsNonEmpty = false;
if (builder.length() > 0) {
appendLineBreak = true;
}
}
final ZLTextElement element = cursor.getElement();
if (element instanceof ZLTextWord) {
final ZLTextWord word = (ZLTextWord)element;
if (lineIsNonEmpty) {
phraseBuilder.append(" ");
}
phraseBuilder.append(word.Data, word.Offset, word.Length);
++wordCounter;
lineIsNonEmpty = true;
switch (word.Data[word.Offset + word.Length - 1]) {
case ',':
case ':':
case ';':
case ')':
sentenceBuilder.append(phraseBuilder);
phraseBuilder.delete(0, phraseBuilder.length());
break;
case '.':
case '!':
case '?':
++sentenceCounter;
if (appendLineBreak) {
builder.append("\n");
appendLineBreak = false;
}
sentenceBuilder.append(phraseBuilder);
phraseBuilder.delete(0, phraseBuilder.length());
builder.append(sentenceBuilder);
sentenceBuilder.delete(0, sentenceBuilder.length());
storedWordCounter = wordCounter;
break;
}
}
cursor.nextWord();
}
if (storedWordCounter < 4) {
if (sentenceBuilder.length() == 0) {
sentenceBuilder.append(phraseBuilder);
}
if (appendLineBreak) {
builder.append("\n");
}
builder.append(sentenceBuilder);
}
return builder.toString();
}
void setId(long id) {
myId = id;
}

View file

@ -86,8 +86,22 @@ public abstract class BooksDatabase {
protected abstract void setLabel(long bookId, String label);
protected abstract void removeLabel(long bookId, String label);
protected Bookmark createBookmark(long id, long bookId, String bookTitle, String text, Date creationDate, Date modificationDate, Date accessDate, int accessCounter, String modelId, int paragraphIndex, int wordIndex, int charIndex, boolean isVisible) {
return new Bookmark(id, bookId, bookTitle, text, creationDate, modificationDate, accessDate, accessCounter, modelId, paragraphIndex, wordIndex, charIndex, isVisible);
protected Bookmark createBookmark(
long id, long bookId, String bookTitle, String text,
Date creationDate, Date modificationDate, Date accessDate, int accessCounter,
String modelId,
int start_paragraphIndex, int start_wordIndex, int start_charIndex,
int end_paragraphIndex, int end_wordIndex, int end_charIndex,
boolean isVisible
) {
return new Bookmark(
id, bookId, bookTitle, text,
creationDate, modificationDate, accessDate, accessCounter,
modelId,
start_paragraphIndex, start_wordIndex, start_charIndex,
end_paragraphIndex, end_wordIndex, end_charIndex,
isVisible
);
}
protected abstract List<Bookmark> loadBookmarks(BookmarkQuery query);

View file

@ -26,6 +26,8 @@ import java.text.ParseException;
import org.geometerplus.zlibrary.core.constants.XMLNamespaces;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
import org.geometerplus.zlibrary.text.view.ZLTextPosition;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
@ -262,12 +264,26 @@ class XMLSerializer extends AbstractSerializer {
"access-count", String.valueOf(bookmark.getAccessCount())
);
appendTag(
buffer, "position", true,
buffer, "start", true,
"model", bookmark.ModelId,
"paragraph", String.valueOf(bookmark.getParagraphIndex()),
"element", String.valueOf(bookmark.getElementIndex()),
"char", String.valueOf(bookmark.getCharIndex())
);
final ZLTextPosition end = bookmark.getEnd();
if (end != null) {
appendTag(
buffer, "end", true,
"paragraph", String.valueOf(end.getParagraphIndex()),
"element", String.valueOf(end.getElementIndex()),
"char", String.valueOf(end.getCharIndex())
);
} else {
appendTag(
buffer, "end", true,
"length", String.valueOf(bookmark.getLength())
);
}
closeTag(buffer, "bookmark");
return buffer.toString();
}
@ -761,9 +777,12 @@ class XMLSerializer extends AbstractSerializer {
private Date myAccessDate;
private int myAccessCount;
private String myModelId;
private int myParagraphIndex;
private int myElementIndex;
private int myCharIndex;
private int myStartParagraphIndex;
private int myStartElementIndex;
private int myStartCharIndex;
private int myEndParagraphIndex;
private int myEndElementIndex;
private int myEndCharIndex;
private boolean myIsVisible;
public Bookmark getBookmark() {
@ -783,9 +802,12 @@ class XMLSerializer extends AbstractSerializer {
myAccessDate = null;
myAccessCount = 0;
myModelId = null;
myParagraphIndex = 0;
myElementIndex = 0;
myCharIndex = 0;
myStartParagraphIndex = 0;
myStartElementIndex = 0;
myStartCharIndex = 0;
myEndParagraphIndex = -1;
myEndElementIndex = -1;
myEndCharIndex = -1;
myIsVisible = false;
myState = State.READ_NOTHING;
@ -799,11 +821,13 @@ class XMLSerializer extends AbstractSerializer {
myBookmark = new Bookmark(
myId, myBookId, myBookTitle, myText.toString(),
myCreationDate, myModificationDate, myAccessDate, myAccessCount,
myModelId, myParagraphIndex, myElementIndex, myCharIndex, myIsVisible
myModelId,
myStartParagraphIndex, myStartElementIndex, myStartCharIndex,
myEndParagraphIndex, myEndElementIndex, myEndCharIndex,
myIsVisible
);
}
//appendTagWithContent(buffer, "text", bookmark.getText());
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
switch (myState) {
@ -838,12 +862,27 @@ class XMLSerializer extends AbstractSerializer {
} catch (Exception e) {
throw new SAXException("XML parsing error", e);
}
} else if ("position".equals(localName)) {
} else if ("start".equals(localName)) {
try {
myModelId = attributes.getValue("model");
myParagraphIndex = Integer.parseInt(attributes.getValue("paragraph"));
myElementIndex = Integer.parseInt(attributes.getValue("element"));
myCharIndex = Integer.parseInt(attributes.getValue("char"));
myStartParagraphIndex = Integer.parseInt(attributes.getValue("paragraph"));
myStartElementIndex = Integer.parseInt(attributes.getValue("element"));
myStartCharIndex = Integer.parseInt(attributes.getValue("char"));
} catch (Exception e) {
throw new SAXException("XML parsing error", e);
}
} else if ("end".equals(localName)) {
try {
final String para = attributes.getValue("paragraph");
if (para != null) {
myEndParagraphIndex = Integer.parseInt(para);
myEndElementIndex = Integer.parseInt(attributes.getValue("element"));
myEndCharIndex = Integer.parseInt(attributes.getValue("char"));
} else {
myEndParagraphIndex = Integer.parseInt(attributes.getValue("length"));
myEndElementIndex = -1;
myEndCharIndex = -1;
}
} catch (Exception e) {
throw new SAXException("XML parsing error", e);
}

View file

@ -478,7 +478,7 @@ public final class FBReaderApp extends ZLApplication {
public void addInvisibleBookmark(ZLTextWordCursor cursor) {
if (cursor != null && Model != null && Model.Book != null && getTextView() == BookTextView) {
updateInvisibleBookmarksList(new Bookmark(
updateInvisibleBookmarksList(Bookmark.createBookmark(
Model.Book,
getTextView().getModel().getId(),
cursor,
@ -502,7 +502,7 @@ public final class FBReaderApp extends ZLApplication {
return null;
}
return new Bookmark(
return Bookmark.createBookmark(
Model.Book,
view.getModel().getId(),
cursor,