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

a refactoring: soul is extracted

This commit is contained in:
Nikolay Pultsin 2011-06-10 14:04:29 +02:00
parent 8badfdeeb9
commit 95d78d3c6d
9 changed files with 186 additions and 154 deletions

View file

@ -33,7 +33,8 @@ import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.xml.ZLXMLReaderAdapter;
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
import org.geometerplus.zlibrary.text.view.ZLTextWordRegion;
import org.geometerplus.zlibrary.text.view.ZLTextRegion;
import org.geometerplus.zlibrary.text.view.ZLTextWord;
import org.geometerplus.zlibrary.ui.android.library.ZLAndroidApplication;
@ -178,8 +179,8 @@ public abstract class DictionaryUtil {
}
}
public static void openWordInDictionary(Activity activity, ZLTextWordRegion region) {
final String text = region.Word.toString();
public static void openWordInDictionary(Activity activity, ZLTextWord word, ZLTextRegion region) {
final String text = word.toString();
int start = 0;
int end = text.length();
for (; start < end && !Character.isLetterOrDigit(text.charAt(start)); ++start);

View file

@ -48,10 +48,15 @@ class ProcessHyperlinkAction extends FBAndroidAction {
public void run() {
final ZLTextRegion region = Reader.getTextView().getSelectedRegion();
if (region instanceof ZLTextHyperlinkRegion) {
if (region == null) {
return;
}
final ZLTextRegion.Soul soul = region.getSoul();
if (soul instanceof ZLTextHyperlinkRegionSoul) {
Reader.getTextView().hideSelectedRegionBorder();
Reader.getViewWidget().repaint();
final ZLTextHyperlink hyperlink = ((ZLTextHyperlinkRegion)region).Hyperlink;
final ZLTextHyperlink hyperlink = ((ZLTextHyperlinkRegionSoul)soul).Hyperlink;
switch (hyperlink.Type) {
case FBHyperlinkType.EXTERNAL:
if (hyperlink.Id.startsWith(ACTION_LINK_PREFIX)) {
@ -65,10 +70,10 @@ class ProcessHyperlinkAction extends FBAndroidAction {
Reader.tryOpenFootnote(hyperlink.Id);
break;
}
} else if (region instanceof ZLTextImageRegion) {
} else if (soul instanceof ZLTextImageRegionSoul) {
Reader.getTextView().hideSelectedRegionBorder();
Reader.getViewWidget().repaint();
final String uriString = ((ZLTextImageRegion)region).ImageElement.URI;
final String uriString = ((ZLTextImageRegionSoul)soul).ImageElement.URI;
if (uriString != null) {
try {
final Intent intent = new Intent();
@ -83,9 +88,9 @@ class ProcessHyperlinkAction extends FBAndroidAction {
e.printStackTrace();
}
}
} else if (region instanceof ZLTextWordRegion) {
} else if (soul instanceof ZLTextWordRegionSoul) {
DictionaryUtil.openWordInDictionary(
BaseActivity, (ZLTextWordRegion)region
BaseActivity, ((ZLTextWordRegionSoul)soul).Word, region
);
}
}

View file

@ -210,8 +210,10 @@ public final class FBView extends ZLTextView {
}
final ZLTextRegion region = findRegion(x, y, MAX_SELECTION_DISTANCE, ZLTextRegion.AnyRegionFilter);
if (region != null) {
final ZLTextRegion.Soul soul = region.getSoul();
boolean doSelectRegion = false;
if (region instanceof ZLTextWordRegion) {
if (soul instanceof ZLTextWordRegionSoul) {
switch (myReader.WordTappingActionOption.getValue()) {
case startSelecting:
myReader.doAction(ActionCode.SELECTION_HIDE_PANEL);
@ -226,11 +228,11 @@ public final class FBView extends ZLTextView {
doSelectRegion = true;
break;
}
} else if (region instanceof ZLTextImageRegion) {
} else if (soul instanceof ZLTextImageRegionSoul) {
doSelectRegion =
myReader.ImageTappingActionOption.getValue() !=
FBReaderApp.ImageTappingAction.doNothing;
} else if (region instanceof ZLTextHyperlinkRegion) {
} else if (soul instanceof ZLTextHyperlinkRegionSoul) {
doSelectRegion = true;
}
@ -240,6 +242,7 @@ public final class FBView extends ZLTextView {
myReader.getViewWidget().repaint();
return true;
}
}
return false;
}
@ -255,19 +258,26 @@ public final class FBView extends ZLTextView {
return true;
}
final ZLTextRegion selectedRegion = getSelectedRegion();
if (selectedRegion instanceof ZLTextHyperlinkRegion ||
selectedRegion instanceof ZLTextWordRegion) {
ZLTextRegion region = getSelectedRegion();
if (region != null) {
ZLTextRegion.Soul soul = region.getSoul();
if (soul instanceof ZLTextHyperlinkRegionSoul ||
soul instanceof ZLTextWordRegionSoul) {
if (myReader.WordTappingActionOption.getValue() !=
FBReaderApp.WordTappingAction.doNothing) {
final ZLTextRegion region = findRegion(x, y, MAX_SELECTION_DISTANCE, ZLTextRegion.AnyRegionFilter);
if (region instanceof ZLTextHyperlinkRegion || region instanceof ZLTextWordRegion) {
region = findRegion(x, y, MAX_SELECTION_DISTANCE, ZLTextRegion.AnyRegionFilter);
if (region != null) {
soul = region.getSoul();
if (soul instanceof ZLTextHyperlinkRegionSoul
|| soul instanceof ZLTextWordRegionSoul) {
selectRegion(region);
myReader.getViewWidget().reset();
myReader.getViewWidget().repaint();
}
}
}
}
}
return true;
}
@ -282,13 +292,16 @@ public final class FBView extends ZLTextView {
return true;
}
boolean doRunAction = false;
final ZLTextRegion region = getSelectedRegion();
if (region instanceof ZLTextWordRegion) {
if (region != null) {
final ZLTextRegion.Soul soul = region.getSoul();
boolean doRunAction = false;
if (soul instanceof ZLTextWordRegionSoul) {
doRunAction =
myReader.WordTappingActionOption.getValue() ==
FBReaderApp.WordTappingAction.openDictionary;
} else if (region instanceof ZLTextImageRegion) {
} else if (soul instanceof ZLTextImageRegionSoul) {
doRunAction =
myReader.ImageTappingActionOption.getValue() ==
FBReaderApp.ImageTappingAction.openImageView;
@ -298,6 +311,7 @@ public final class FBView extends ZLTextView {
myReader.doAction(ActionCode.PROCESS_HYPERLINK);
return true;
}
}
return false;
}
@ -311,9 +325,10 @@ public final class FBView extends ZLTextView {
(diffY > 0 ? Direction.down : Direction.up) :
(diffX > 0 ? Direction.leftToRight : Direction.rightToLeft);
ZLTextRegion region = currentRegion();
ZLTextRegion region = getSelectedRegion();
final ZLTextRegion.Filter filter =
region instanceof ZLTextWordRegion || myReader.NavigateAllWordsOption.getValue()
(region != null && region.getSoul() instanceof ZLTextWordRegionSoul)
|| myReader.NavigateAllWordsOption.getValue()
? ZLTextRegion.AnyRegionFilter : ZLTextRegion.ImageOrHyperlinkFilter;
region = nextRegion(direction, filter);
if (region != null) {

View file

@ -19,47 +19,43 @@
package org.geometerplus.zlibrary.text.view;
import java.util.ArrayList;
import java.util.*;
final class ZLTextElementAreaVector extends ArrayList<ZLTextElementArea> {
private static final long serialVersionUID = -7880472347947563506L;
final ArrayList<ZLTextRegion> ElementRegions = new ArrayList<ZLTextRegion>();
private final ArrayList<ZLTextRegion> myElementRegions = new ArrayList<ZLTextRegion>();
private ZLTextRegion myCurrentElementRegion;
@Override
public void clear() {
ElementRegions.clear();
myElementRegions.clear();
myCurrentElementRegion = null;
super.clear();
}
@Override
public boolean add(ZLTextElementArea area) {
if (myCurrentElementRegion != null
&& myCurrentElementRegion.getSoul().accepts(area)) {
myCurrentElementRegion.extend();
} else {
ZLTextRegion.Soul soul = null;
final ZLTextHyperlink hyperlink = area.Style.Hyperlink;
if (hyperlink.Id != null) {
if (!(myCurrentElementRegion instanceof ZLTextHyperlinkRegion) ||
((ZLTextHyperlinkRegion)myCurrentElementRegion).Hyperlink != hyperlink) {
myCurrentElementRegion = new ZLTextHyperlinkRegion(hyperlink, this, size());
ElementRegions.add(myCurrentElementRegion);
} else {
myCurrentElementRegion.extend();
}
soul = new ZLTextHyperlinkRegionSoul(hyperlink);
} else if (area.Element instanceof ZLTextImageElement) {
ElementRegions.add(new ZLTextImageRegion((ZLTextImageElement)area.Element, this, size()));
myCurrentElementRegion = null;
soul = new ZLTextImageRegionSoul((ZLTextImageElement)area.Element);
} else if (area.Element instanceof ZLTextWord && ((ZLTextWord)area.Element).isAWord()) {
if (!(myCurrentElementRegion instanceof ZLTextWordRegion) ||
((ZLTextWordRegion)myCurrentElementRegion).Word != area.Element) {
myCurrentElementRegion =
new ZLTextWordRegion((ZLTextWord)area.Element, this, size());
ElementRegions.add(myCurrentElementRegion);
} else {
myCurrentElementRegion.extend();
soul = new ZLTextWordRegionSoul((ZLTextWord)area.Element);
}
if (soul != null) {
myCurrentElementRegion = new ZLTextRegion(soul, this, size());
myElementRegions.add(myCurrentElementRegion);
} else {
myCurrentElementRegion = null;
}
}
return super.add(area);
}
@ -83,4 +79,20 @@ final class ZLTextElementAreaVector extends ArrayList<ZLTextElementArea> {
}
return null;
}
List<ZLTextRegion> elementRegions() {
return Collections.unmodifiableList(myElementRegions);
}
ZLTextRegion getRegion(ZLTextRegion.Soul soul) {
if (soul == null) {
return null;
}
for (ZLTextRegion region : myElementRegions) {
if (soul.equals(region.getSoul())) {
return region;
}
}
return null;
}
}

View file

@ -19,21 +19,23 @@
package org.geometerplus.zlibrary.text.view;
import java.util.List;
public class ZLTextHyperlinkRegion extends ZLTextRegion {
public class ZLTextHyperlinkRegionSoul extends ZLTextRegion.Soul {
public final ZLTextHyperlink Hyperlink;
ZLTextHyperlinkRegion(ZLTextHyperlink hyperlink, List<ZLTextElementArea> list, int fromIndex) {
super(list, fromIndex);
ZLTextHyperlinkRegionSoul(ZLTextHyperlink hyperlink) {
Hyperlink = hyperlink;
}
@Override
boolean accepts(ZLTextElementArea area) {
return Hyperlink == area.Style.Hyperlink;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ZLTextHyperlinkRegion)) {
if (!(other instanceof ZLTextHyperlinkRegionSoul)) {
return false;
}
return Hyperlink == ((ZLTextHyperlinkRegion)other).Hyperlink;
return Hyperlink == ((ZLTextHyperlinkRegionSoul)other).Hyperlink;
}
}

View file

@ -19,21 +19,23 @@
package org.geometerplus.zlibrary.text.view;
import java.util.List;
public class ZLTextImageRegion extends ZLTextRegion {
public class ZLTextImageRegionSoul extends ZLTextRegion.Soul {
public final ZLTextImageElement ImageElement;
ZLTextImageRegion(ZLTextImageElement imageElement, List<ZLTextElementArea> list, int fromIndex) {
super(list, fromIndex);
ZLTextImageRegionSoul(ZLTextImageElement imageElement) {
ImageElement = imageElement;
}
@Override
boolean accepts(ZLTextElementArea area) {
return ImageElement == area.Element;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ZLTextImageRegion)) {
if (!(other instanceof ZLTextImageRegionSoul)) {
return false;
}
return ImageElement == ((ZLTextImageRegion)other).ImageElement;
return ImageElement == ((ZLTextImageRegionSoul)other).ImageElement;
}
}

View file

@ -23,7 +23,14 @@ import java.util.*;
import org.geometerplus.zlibrary.core.view.ZLPaintContext;
public abstract class ZLTextRegion implements Comparable<ZLTextRegion> {
public final class ZLTextRegion implements Comparable<ZLTextRegion> {
public static abstract class Soul {
abstract boolean accepts(ZLTextElementArea area);
@Override
public abstract boolean equals(Object other);
}
public static interface Filter {
boolean accepts(ZLTextRegion region);
}
@ -36,24 +43,27 @@ public abstract class ZLTextRegion implements Comparable<ZLTextRegion> {
public static Filter HyperlinkFilter = new Filter() {
public boolean accepts(ZLTextRegion region) {
return region instanceof ZLTextHyperlinkRegion;
return region.getSoul() instanceof ZLTextHyperlinkRegionSoul;
}
};
public static Filter ImageOrHyperlinkFilter = new Filter() {
public boolean accepts(ZLTextRegion region) {
final Soul soul = region.getSoul();
return
region instanceof ZLTextImageRegion ||
region instanceof ZLTextHyperlinkRegion;
soul instanceof ZLTextImageRegionSoul ||
soul instanceof ZLTextHyperlinkRegionSoul;
}
};
private final Soul mySoul;
private final List<ZLTextElementArea> myList;
private final int myFromIndex;
private int myToIndex;
private ZLTextHorizontalConvexHull myHull;
ZLTextRegion(List<ZLTextElementArea> list, int fromIndex) {
ZLTextRegion(Soul soul, List<ZLTextElementArea> list, int fromIndex) {
mySoul = soul;
myList = list;
myFromIndex = fromIndex;
myToIndex = fromIndex + 1;
@ -64,6 +74,10 @@ public abstract class ZLTextRegion implements Comparable<ZLTextRegion> {
myHull = null;
}
public Soul getSoul() {
return mySoul;
}
private List<ZLTextElementArea> textAreas() {
return myList.subList(myFromIndex, myToIndex);
}
@ -141,9 +155,6 @@ public abstract class ZLTextRegion implements Comparable<ZLTextRegion> {
return other == null || other.isExactlyUnder(this);
}
@Override
public abstract boolean equals(Object other);
public int compareTo(ZLTextRegion other) {
if (myFromIndex != other.myFromIndex) {
return myFromIndex < other.myFromIndex ? -1 : 1;

View file

@ -430,7 +430,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
++index;
}
final ZLTextRegion selectedElementRegion = getCurrentElementRegion(page);
final ZLTextRegion selectedElementRegion = getSelectedRegion(page);
if (selectedElementRegion != null && myHighlightSelectedRegion) {
selectedElementRegion.draw(context);
}
@ -1348,7 +1348,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
return false;
}
private ZLTextRegion mySelectedRegion;
private ZLTextRegion.Soul mySelectedRegionSoul;
private ZLTextSelection mySelection;
private boolean myHighlightSelectedRegion = true;
@ -1357,17 +1357,12 @@ public abstract class ZLTextView extends ZLTextViewBase {
Application.getViewWidget().reset();
}
private ZLTextRegion getCurrentElementRegion(ZLTextPage page) {
final ArrayList<ZLTextRegion> elementRegions = page.TextElementMap.ElementRegions;
final int index = elementRegions.indexOf(mySelectedRegion);
if (index == -1) {
return null;
}
return elementRegions.get(index);
private ZLTextRegion getSelectedRegion(ZLTextPage page) {
return page.TextElementMap.getRegion(mySelectedRegionSoul);
}
public ZLTextRegion getSelectedRegion() {
return getCurrentElementRegion(myCurrentPage);
return getSelectedRegion(myCurrentPage);
}
protected ZLTextRegion findRegion(int x, int y, ZLTextRegion.Filter filter) {
@ -1377,7 +1372,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
protected ZLTextRegion findRegion(int x, int y, int maxDistance, ZLTextRegion.Filter filter) {
ZLTextRegion bestRegion = null;
int distance = maxDistance + 1;
for (ZLTextRegion region : myCurrentPage.TextElementMap.ElementRegions) {
for (ZLTextRegion region : myCurrentPage.TextElementMap.elementRegions()) {
if (filter.accepts(region)) {
final int d = region.distanceTo(x, y);
if (d < distance) {
@ -1390,10 +1385,11 @@ public abstract class ZLTextView extends ZLTextViewBase {
}
protected void selectRegion(ZLTextRegion region) {
if (region == null || !region.equals(mySelectedRegion)) {
final ZLTextRegion.Soul soul = region != null ? region.getSoul() : null;
if (soul == null || !soul.equals(mySelectedRegionSoul)) {
myHighlightSelectedRegion = true;
}
mySelectedRegion = region;
mySelectedRegionSoul = soul;
}
protected boolean initSelection(int x, int y) {
@ -1464,32 +1460,18 @@ public abstract class ZLTextView extends ZLTextViewBase {
}
public void resetRegionPointer() {
mySelectedRegion = null;
mySelectedRegionSoul = null;
myHighlightSelectedRegion = true;
}
protected ZLTextRegion currentRegion() {
if (mySelectedRegion == null) {
return null;
}
final ArrayList<ZLTextRegion> elementRegions =
myCurrentPage.TextElementMap.ElementRegions;
if (elementRegions.isEmpty()) {
return null;
}
final int index = elementRegions.indexOf(mySelectedRegion);
return index >= 0 ? elementRegions.get(index) : null;
}
protected ZLTextRegion nextRegion(Direction direction, ZLTextRegion.Filter filter) {
final ArrayList<ZLTextRegion> elementRegions =
myCurrentPage.TextElementMap.ElementRegions;
final List<ZLTextRegion> elementRegions = myCurrentPage.TextElementMap.elementRegions();
if (elementRegions.isEmpty()) {
return null;
}
int index = elementRegions.indexOf(mySelectedRegion);
mySelectedRegion = index >= 0 ? elementRegions.get(index) : null;
final ZLTextRegion selectedRegion = getSelectedRegion();
int index = selectedRegion != null ? elementRegions.indexOf(selectedRegion) : -1;
switch (direction) {
case rightToLeft:
@ -1516,7 +1498,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
case rightToLeft:
for (; index >= 0; --index) {
final ZLTextRegion candidate = elementRegions.get(index);
if (filter.accepts(candidate) && candidate.isAtLeftOf(mySelectedRegion)) {
if (filter.accepts(candidate) && candidate.isAtLeftOf(selectedRegion)) {
return candidate;
}
}
@ -1524,7 +1506,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
case leftToRight:
for (; index < elementRegions.size(); ++index) {
final ZLTextRegion candidate = elementRegions.get(index);
if (filter.accepts(candidate) && candidate.isAtRightOf(mySelectedRegion)) {
if (filter.accepts(candidate) && candidate.isAtRightOf(selectedRegion)) {
return candidate;
}
}
@ -1537,10 +1519,10 @@ public abstract class ZLTextView extends ZLTextViewBase {
if (!filter.accepts(candidate)) {
continue;
}
if (candidate.isExactlyUnder(mySelectedRegion)) {
if (candidate.isExactlyUnder(selectedRegion)) {
return candidate;
}
if (firstCandidate == null && candidate.isUnder(mySelectedRegion)) {
if (firstCandidate == null && candidate.isUnder(selectedRegion)) {
firstCandidate = candidate;
}
}
@ -1556,10 +1538,10 @@ public abstract class ZLTextView extends ZLTextViewBase {
if (!filter.accepts(candidate)) {
continue;
}
if (candidate.isExactlyOver(mySelectedRegion)) {
if (candidate.isExactlyOver(selectedRegion)) {
return candidate;
}
if (firstCandidate == null && candidate.isOver(mySelectedRegion)) {
if (firstCandidate == null && candidate.isOver(selectedRegion)) {
firstCandidate = candidate;
}
}

View file

@ -19,21 +19,23 @@
package org.geometerplus.zlibrary.text.view;
import java.util.List;
public class ZLTextWordRegion extends ZLTextRegion {
public class ZLTextWordRegionSoul extends ZLTextRegion.Soul {
public final ZLTextWord Word;
ZLTextWordRegion(ZLTextWord word, List<ZLTextElementArea> list, int fromIndex) {
super(list, fromIndex);
ZLTextWordRegionSoul(ZLTextWord word) {
Word = word;
}
@Override
boolean accepts(ZLTextElementArea area) {
return Word == area.Element;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ZLTextWordRegion)) {
if (!(other instanceof ZLTextWordRegionSoul)) {
return false;
}
return Word == ((ZLTextWordRegion)other).Word;
return Word == ((ZLTextWordRegionSoul)other).Word;
}
}