mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-05 10:49:24 +02:00
bookmarks improvements
mobipocket support (in progress) misc fixes git-svn-id: https://only.mawhrin.net/repos/FBReaderJ/trunk@967 6a642e6f-84f6-412e-ac94-c4a38d5a04b0
This commit is contained in:
parent
b346321526
commit
1f14fd2b58
57 changed files with 897 additions and 1242 deletions
|
@ -221,10 +221,14 @@
|
||||||
</group>
|
</group>
|
||||||
<group name="Unicode">
|
<group name="Unicode">
|
||||||
<encoding region="Unicode" name="UTF-8">
|
<encoding region="Unicode" name="UTF-8">
|
||||||
|
<code number="65001"/>
|
||||||
</encoding>
|
</encoding>
|
||||||
<encoding region="Unicode" name="UTF-7">
|
<encoding region="Unicode" name="UTF-7">
|
||||||
|
<code number="65000"/>
|
||||||
</encoding>
|
</encoding>
|
||||||
<encoding region="Unicode" name="UTF-16">
|
<encoding region="Unicode" name="UTF-16">
|
||||||
</encoding>
|
</encoding>
|
||||||
|
<encoding region="Unicode" name="UTF-16BE">
|
||||||
|
</encoding>
|
||||||
</group>
|
</group>
|
||||||
</known-encodings>
|
</known-encodings>
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
<data android:pathPattern=".*\\.epub" />
|
<data android:pathPattern=".*\\.epub" />
|
||||||
<data android:pathPattern=".*\\.oeb" />
|
<data android:pathPattern=".*\\.oeb" />
|
||||||
<data android:pathPattern=".*\\.fb2" />
|
<data android:pathPattern=".*\\.fb2" />
|
||||||
|
<data android:pathPattern=".*\\.mobi" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 177 B |
|
@ -12,14 +12,33 @@
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
/>
|
/>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
|
android:paddingLeft="5dip"
|
||||||
|
android:layout_marginTop="5dip"
|
||||||
|
android:layout_marginBottom="5dip"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center_vertical|left"
|
||||||
|
>
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/bookmark_item_text"
|
android:id="@+id/bookmark_item_text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="5dip"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_marginTop="5dip"
|
android:singleLine="false"
|
||||||
android:layout_marginBottom="5dip"
|
|
||||||
android:gravity="center_vertical|left"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:gravity="center_vertical|left"
|
||||||
/>
|
/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/bookmark_item_booktitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="7dip"
|
||||||
|
android:layout_below="@id/bookmark_item_text"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="5dip"
|
android:paddingTop="5dip"
|
||||||
/>
|
/>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
|
|
|
@ -68,7 +68,8 @@ public class BookDownloader extends Activity {
|
||||||
ourFileName = path.get(path.size() - 1);
|
ourFileName = path.get(path.size() - 1);
|
||||||
if (!ourFileName.endsWith(".fb2.zip") &&
|
if (!ourFileName.endsWith(".fb2.zip") &&
|
||||||
!ourFileName.endsWith(".fb2") &&
|
!ourFileName.endsWith(".fb2") &&
|
||||||
!ourFileName.endsWith(".epub")) {
|
!ourFileName.endsWith(".epub") &&
|
||||||
|
!ourFileName.endsWith(".mobi")) {
|
||||||
startNextMatchingActivity(intent);
|
startNextMatchingActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
|
@ -126,6 +127,10 @@ public class BookDownloader extends Activity {
|
||||||
|
|
||||||
private void runFBReader(final File file) {
|
private void runFBReader(final File file) {
|
||||||
finish();
|
finish();
|
||||||
|
final Activity oldActivity = org.geometerplus.android.fbreader.FBReader.Instance;
|
||||||
|
if (oldActivity != null) {
|
||||||
|
oldActivity.finish();
|
||||||
|
}
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.fromFile(file), this, FBReader.class));
|
startActivity(new Intent(Intent.ACTION_VIEW, Uri.fromFile(file), this, FBReader.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,16 +28,27 @@ import android.content.Context;
|
||||||
import org.geometerplus.zlibrary.ui.android.R;
|
import org.geometerplus.zlibrary.ui.android.R;
|
||||||
|
|
||||||
class SimpleContainer extends ViewGroup {
|
class SimpleContainer extends ViewGroup {
|
||||||
private final View myChild;
|
private final View myEditText;
|
||||||
|
private final Button myOkButton;
|
||||||
|
private final Button myCancelButton;
|
||||||
|
|
||||||
SimpleContainer(Context context, View child) {
|
SimpleContainer(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
myChild = child;
|
myEditText = new EditText(context);
|
||||||
addView(child);
|
myOkButton = new Button(context);
|
||||||
|
myOkButton.setText("ok");
|
||||||
|
myCancelButton = new Button(context);
|
||||||
|
myCancelButton.setText("cancel");
|
||||||
|
addView(myOkButton);
|
||||||
|
addView(myCancelButton);
|
||||||
|
addView(myEditText);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||||
myChild.layout(left + 5, top + 5, right - 5, bottom - 5);
|
final int buttonHeight = Math.max(54, Math.max(myOkButton.getHeight(), myCancelButton.getHeight()));
|
||||||
|
myEditText.layout(left + 8, top + 8, right - 8, bottom - buttonHeight - 16);
|
||||||
|
myOkButton.layout(left + 8, bottom - buttonHeight - 8, (left + right) / 2 - 4, bottom - 8);
|
||||||
|
myCancelButton.layout((left + right) / 2 + 4, bottom - buttonHeight - 8, right - 8, bottom - 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,21 +57,7 @@ public class BookmarkEditActivity extends Activity {
|
||||||
public void onCreate(Bundle bundle) {
|
public void onCreate(Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
final LinearLayout v = new LinearLayout(this);
|
final SimpleContainer container = new SimpleContainer(this);
|
||||||
v.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
v.addView(new EditText(this));
|
|
||||||
/*
|
|
||||||
final LinearLayout h = new LinearLayout(this);
|
|
||||||
v.addView(h);
|
|
||||||
final Button okButton = new Button(this);
|
|
||||||
okButton.setText("ok");
|
|
||||||
h.addView(okButton);
|
|
||||||
final Button cancelButton = new Button(this);
|
|
||||||
cancelButton.setText("cancel");
|
|
||||||
h.addView(cancelButton);
|
|
||||||
*/
|
|
||||||
final SimpleContainer container = new SimpleContainer(this, v);
|
|
||||||
//final SimpleContainer container = new SimpleContainer(this, new EditText(this));
|
|
||||||
setContentView(container);
|
setContentView(container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,10 @@ public class BookmarksActivity extends TabActivity implements MenuItem.OnMenuIte
|
||||||
|
|
||||||
AllBooksBookmarks = Bookmark.bookmarks();
|
AllBooksBookmarks = Bookmark.bookmarks();
|
||||||
Collections.sort(AllBooksBookmarks, new Bookmark.ByTimeComparator());
|
Collections.sort(AllBooksBookmarks, new Bookmark.ByTimeComparator());
|
||||||
final long bookId = ((FBReader)FBReader.Instance()).Model.Book.getId();
|
final FBReader fbreader = (FBReader)FBReader.Instance();
|
||||||
|
|
||||||
|
if (fbreader.Model != null) {
|
||||||
|
final long bookId = fbreader.Model.Book.getId();
|
||||||
for (Bookmark bookmark : AllBooksBookmarks) {
|
for (Bookmark bookmark : AllBooksBookmarks) {
|
||||||
if (bookmark.getBookId() == bookId) {
|
if (bookmark.getBookId() == bookId) {
|
||||||
myThisBookBookmarks.add(bookmark);
|
myThisBookBookmarks.add(bookmark);
|
||||||
|
@ -83,6 +86,9 @@ public class BookmarksActivity extends TabActivity implements MenuItem.OnMenuIte
|
||||||
|
|
||||||
myThisBookView = createTab("thisBook", R.id.this_book);
|
myThisBookView = createTab("thisBook", R.id.this_book);
|
||||||
new BookmarksAdapter(myThisBookView, myThisBookBookmarks, true);
|
new BookmarksAdapter(myThisBookView, myThisBookBookmarks, true);
|
||||||
|
} else {
|
||||||
|
findViewById(R.id.this_book).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
myAllBooksView = createTab("allBooks", R.id.all_books);
|
myAllBooksView = createTab("allBooks", R.id.all_books);
|
||||||
new BookmarksAdapter(myAllBooksView, AllBooksBookmarks, false);
|
new BookmarksAdapter(myAllBooksView, AllBooksBookmarks, false);
|
||||||
|
@ -196,25 +202,52 @@ public class BookmarksActivity extends TabActivity implements MenuItem.OnMenuIte
|
||||||
|
|
||||||
final ZLTextPosition position = new ZLTextPosition(cursor);
|
final ZLTextPosition position = new ZLTextPosition(cursor);
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
int wordCounter = 0;
|
final StringBuilder sentenceBuilder = new StringBuilder();
|
||||||
cursor = new ZLTextWordCursor(cursor);
|
cursor = new ZLTextWordCursor(cursor);
|
||||||
|
|
||||||
|
int wordCounter = 0;
|
||||||
|
int sentenceCounter = 0;
|
||||||
|
int storedWordCounter = 0;
|
||||||
|
boolean lineIsNonEmpty = false;
|
||||||
mainLoop:
|
mainLoop:
|
||||||
do {
|
while ((wordCounter < 20) && (sentenceCounter < 3)) {
|
||||||
for (; !cursor.isEndOfParagraph(); cursor.nextWord()) {
|
while (cursor.isEndOfParagraph()) {
|
||||||
|
if (!cursor.nextParagraph()) {
|
||||||
|
break mainLoop;
|
||||||
|
}
|
||||||
|
if (sentenceBuilder.length() > 0) {
|
||||||
|
builder.append(sentenceBuilder);
|
||||||
|
builder.append("\n");
|
||||||
|
sentenceBuilder.delete(0, sentenceBuilder.length());
|
||||||
|
++sentenceCounter;
|
||||||
|
storedWordCounter = wordCounter;
|
||||||
|
lineIsNonEmpty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
final ZLTextElement element = cursor.getElement();
|
final ZLTextElement element = cursor.getElement();
|
||||||
if (element instanceof ZLTextWord) {
|
if (element instanceof ZLTextWord) {
|
||||||
final ZLTextWord word = (ZLTextWord)element;
|
final ZLTextWord word = (ZLTextWord)element;
|
||||||
if (builder.length() > 0) {
|
if (lineIsNonEmpty) {
|
||||||
builder.append(" ");
|
sentenceBuilder.append(" ");
|
||||||
}
|
}
|
||||||
builder.append(word.Data, word.Offset, word.Length);
|
sentenceBuilder.append(word.Data, word.Offset, word.Length);
|
||||||
if (++wordCounter >= 10) {
|
++wordCounter;
|
||||||
break mainLoop;
|
lineIsNonEmpty = true;
|
||||||
|
switch (word.Data[word.Offset + word.Length - 1]) {
|
||||||
|
case '.':
|
||||||
|
case '!':
|
||||||
|
case '?':
|
||||||
|
builder.append(sentenceBuilder);
|
||||||
|
sentenceBuilder.delete(0, sentenceBuilder.length());
|
||||||
|
++sentenceCounter;
|
||||||
|
storedWordCounter = wordCounter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cursor.nextWord();
|
||||||
|
}
|
||||||
|
if (storedWordCounter < 4) {
|
||||||
|
builder.append(sentenceBuilder);
|
||||||
}
|
}
|
||||||
} while ((builder.length() == 0) && cursor.nextParagraph());
|
|
||||||
|
|
||||||
// TODO: text edit dialog
|
// TODO: text edit dialog
|
||||||
final Bookmark bookmark = new Bookmark(fbreader.Model.Book, builder.toString(), position);
|
final Bookmark bookmark = new Bookmark(fbreader.Model.Book, builder.toString(), position);
|
||||||
|
@ -227,7 +260,7 @@ mainLoop:
|
||||||
bookmark.onOpen();
|
bookmark.onOpen();
|
||||||
final FBReader fbreader = (FBReader)FBReader.Instance();
|
final FBReader fbreader = (FBReader)FBReader.Instance();
|
||||||
final long bookId = bookmark.getBookId();
|
final long bookId = bookmark.getBookId();
|
||||||
if (fbreader.Model.Book.getId() != bookId) {
|
if ((fbreader.Model == null) || (fbreader.Model.Book.getId() != bookId)) {
|
||||||
final Book book = Book.getById(bookId);
|
final Book book = Book.getById(bookId);
|
||||||
if (book != null) {
|
if (book != null) {
|
||||||
finish();
|
finish();
|
||||||
|
@ -247,11 +280,11 @@ mainLoop:
|
||||||
|
|
||||||
private final class BookmarksAdapter extends BaseAdapter implements AdapterView.OnItemClickListener, View.OnCreateContextMenuListener {
|
private final class BookmarksAdapter extends BaseAdapter implements AdapterView.OnItemClickListener, View.OnCreateContextMenuListener {
|
||||||
private final List<Bookmark> myBookmarks;
|
private final List<Bookmark> myBookmarks;
|
||||||
private final boolean myShowAddBookmarkButton;
|
private final boolean myCurrentBook;
|
||||||
|
|
||||||
BookmarksAdapter(ListView listView, List<Bookmark> bookmarks, boolean showAddBookmarkButton) {
|
BookmarksAdapter(ListView listView, List<Bookmark> bookmarks, boolean currentBook) {
|
||||||
myBookmarks = bookmarks;
|
myBookmarks = bookmarks;
|
||||||
myShowAddBookmarkButton = showAddBookmarkButton;
|
myCurrentBook = currentBook;
|
||||||
listView.setAdapter(this);
|
listView.setAdapter(this);
|
||||||
listView.setOnItemClickListener(this);
|
listView.setOnItemClickListener(this);
|
||||||
listView.setOnCreateContextMenuListener(this);
|
listView.setOnCreateContextMenuListener(this);
|
||||||
|
@ -259,11 +292,11 @@ mainLoop:
|
||||||
|
|
||||||
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
|
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
|
||||||
final int position = ((AdapterView.AdapterContextMenuInfo)menuInfo).position;
|
final int position = ((AdapterView.AdapterContextMenuInfo)menuInfo).position;
|
||||||
if (position > 0) {
|
if (getItem(position) != null) {
|
||||||
menu.setHeaderTitle(getItem(position).getText());
|
menu.setHeaderTitle(getItem(position).getText());
|
||||||
final ZLResource resource = ZLResource.resource("bookmarksView");
|
final ZLResource resource = ZLResource.resource("bookmarksView");
|
||||||
menu.add(0, OPEN_ITEM_ID, 0, resource.getResource("open").getValue());
|
menu.add(0, OPEN_ITEM_ID, 0, resource.getResource("open").getValue());
|
||||||
menu.add(0, EDIT_ITEM_ID, 0, resource.getResource("edit").getValue());
|
//menu.add(0, EDIT_ITEM_ID, 0, resource.getResource("edit").getValue());
|
||||||
menu.add(0, DELETE_ITEM_ID, 0, resource.getResource("delete").getValue());
|
menu.add(0, DELETE_ITEM_ID, 0, resource.getResource("delete").getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,7 +304,27 @@ mainLoop:
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
final View view = (convertView != null) ? convertView :
|
final View view = (convertView != null) ? convertView :
|
||||||
LayoutInflater.from(parent.getContext()).inflate(R.layout.bookmark_item, parent, false);
|
LayoutInflater.from(parent.getContext()).inflate(R.layout.bookmark_item, parent, false);
|
||||||
|
final ImageView imageView = (ImageView)view.findViewById(R.id.bookmark_item_icon);
|
||||||
|
final TextView textView = (TextView)view.findViewById(R.id.bookmark_item_text);
|
||||||
|
final TextView bookTitleView = (TextView)view.findViewById(R.id.bookmark_item_booktitle);
|
||||||
|
|
||||||
final Bookmark bookmark = getItem(position);
|
final Bookmark bookmark = getItem(position);
|
||||||
|
if (bookmark == null) {
|
||||||
|
imageView.setVisibility(View.VISIBLE);
|
||||||
|
imageView.setImageResource(R.drawable.tree_icon_plus);
|
||||||
|
textView.setText(ZLResource.resource("bookmarksView").getResource("new").getValue());
|
||||||
|
bookTitleView.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
imageView.setVisibility(View.GONE);
|
||||||
|
textView.setText(bookmark.getText());
|
||||||
|
if (myCurrentBook) {
|
||||||
|
bookTitleView.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
bookTitleView.setVisibility(View.VISIBLE);
|
||||||
|
bookTitleView.setText(bookmark.getBookTitle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
((ImageView)view.findViewById(R.id.bookmark_item_icon)).setImageResource(
|
((ImageView)view.findViewById(R.id.bookmark_item_icon)).setImageResource(
|
||||||
(bookmark != null) ? R.drawable.tree_icon_strut : R.drawable.tree_icon_plus
|
(bookmark != null) ? R.drawable.tree_icon_strut : R.drawable.tree_icon_plus
|
||||||
);
|
);
|
||||||
|
@ -280,6 +333,7 @@ mainLoop:
|
||||||
bookmark.getText() :
|
bookmark.getText() :
|
||||||
ZLResource.resource("bookmarksView").getResource("new").getValue()
|
ZLResource.resource("bookmarksView").getResource("new").getValue()
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,14 +350,14 @@ mainLoop:
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Bookmark getItem(int position) {
|
public final Bookmark getItem(int position) {
|
||||||
if (myShowAddBookmarkButton) {
|
if (myCurrentBook) {
|
||||||
--position;
|
--position;
|
||||||
}
|
}
|
||||||
return (position >= 0) ? myBookmarks.get(position) : null;
|
return (position >= 0) ? myBookmarks.get(position) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int getCount() {
|
public final int getCount() {
|
||||||
return myShowAddBookmarkButton ? myBookmarks.size() + 1 : myBookmarks.size();
|
return myCurrentBook ? myBookmarks.size() + 1 : myBookmarks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void onItemClick(AdapterView parent, View view, int position, long id) {
|
public final void onItemClick(AdapterView parent, View view, int position, long id) {
|
||||||
|
|
|
@ -54,9 +54,9 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
|
||||||
final TabHost host = getTabHost();
|
final TabHost host = getTabHost();
|
||||||
LayoutInflater.from(this).inflate(R.layout.library, host.getTabContentView(), true);
|
LayoutInflater.from(this).inflate(R.layout.library, host.getTabContentView(), true);
|
||||||
|
|
||||||
new LibraryAdapter(createTab("byAuthor", R.id.by_author), Library.Instance().byAuthor());
|
new LibraryAdapter(createTab("byAuthor", R.id.by_author), Library.Instance().byAuthor(), false);
|
||||||
new LibraryAdapter(createTab("byTag", R.id.by_tag), Library.Instance().byTag());
|
new LibraryAdapter(createTab("byTag", R.id.by_tag), Library.Instance().byTag(), false);
|
||||||
new LibraryAdapter(createTab("recent", R.id.recent), Library.Instance().recentBooks());
|
new LibraryAdapter(createTab("recent", R.id.recent), Library.Instance().recentBooks(), true);
|
||||||
findViewById(R.id.search_results).setVisibility(View.GONE);
|
findViewById(R.id.search_results).setVisibility(View.GONE);
|
||||||
|
|
||||||
host.setCurrentTabByTag(mySelectedTabOption.getValue());
|
host.setCurrentTabByTag(mySelectedTabOption.getValue());
|
||||||
|
@ -66,7 +66,7 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
|
||||||
void showSearchResultsTab(LibraryTree tree) {
|
void showSearchResultsTab(LibraryTree tree) {
|
||||||
if (mySearchResultsAdapter == null) {
|
if (mySearchResultsAdapter == null) {
|
||||||
mySearchResultsAdapter =
|
mySearchResultsAdapter =
|
||||||
new LibraryAdapter(createTab("searchResults", R.id.search_results), tree);
|
new LibraryAdapter(createTab("searchResults", R.id.search_results), tree, true);
|
||||||
} else {
|
} else {
|
||||||
mySearchResultsAdapter.resetTree(tree);
|
mySearchResultsAdapter.resetTree(tree);
|
||||||
}
|
}
|
||||||
|
@ -125,17 +125,24 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
|
||||||
|
|
||||||
private final class LibraryAdapter extends ZLTreeAdapter {
|
private final class LibraryAdapter extends ZLTreeAdapter {
|
||||||
private final LibraryTree myLibraryTree;
|
private final LibraryTree myLibraryTree;
|
||||||
|
private final boolean myIsFlat;
|
||||||
|
|
||||||
LibraryAdapter(ListView view, LibraryTree tree) {
|
LibraryAdapter(ListView view, LibraryTree tree, boolean isFlat) {
|
||||||
super(view, tree);
|
super(view, tree);
|
||||||
myLibraryTree = tree;
|
myLibraryTree = tree;
|
||||||
|
myIsFlat = isFlat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
final View view = (convertView != null) ? convertView :
|
final View view = (convertView != null) ? convertView :
|
||||||
LayoutInflater.from(parent.getContext()).inflate(R.layout.library_tree_item, parent, false);
|
LayoutInflater.from(parent.getContext()).inflate(R.layout.library_tree_item, parent, false);
|
||||||
final LibraryTree tree = (LibraryTree)getItem(position);
|
final LibraryTree tree = (LibraryTree)getItem(position);
|
||||||
setIcon((ImageView)view.findViewById(R.id.library_tree_item_icon), tree);
|
final ImageView iconView = (ImageView)view.findViewById(R.id.library_tree_item_icon);
|
||||||
|
if (myIsFlat) {
|
||||||
|
iconView.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
setIcon(iconView, tree);
|
||||||
|
}
|
||||||
((TextView)view.findViewById(R.id.library_tree_item_name)).setText(tree.getName());
|
((TextView)view.findViewById(R.id.library_tree_item_name)).setText(tree.getName());
|
||||||
((TextView)view.findViewById(R.id.library_tree_item_childrenlist)).setText(tree.getSecondString());
|
((TextView)view.findViewById(R.id.library_tree_item_childrenlist)).setText(tree.getSecondString());
|
||||||
return view;
|
return view;
|
||||||
|
@ -147,7 +154,10 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
final FBReader fbreader = (FBReader)FBReader.Instance();
|
final FBReader fbreader = (FBReader)FBReader.Instance();
|
||||||
fbreader.openBook(((BookTree)tree).Book, null);
|
final Book book = ((BookTree)tree).Book;
|
||||||
|
if ((fbreader.Model == null) || (fbreader.Model.Book.getId() != book.getId())) {
|
||||||
|
fbreader.openBook(book, null);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ import android.database.Cursor;
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
import org.geometerplus.zlibrary.core.dialogs.ZLDialogManager;
|
import org.geometerplus.zlibrary.core.dialogs.ZLDialogManager;
|
||||||
import org.geometerplus.zlibrary.core.options.ZLStringOption;
|
import org.geometerplus.zlibrary.core.options.ZLStringOption;
|
||||||
|
import org.geometerplus.zlibrary.core.options.ZLIntegerOption;
|
||||||
|
import org.geometerplus.zlibrary.core.config.ZLConfig;
|
||||||
import org.geometerplus.zlibrary.text.view.ZLTextPosition;
|
import org.geometerplus.zlibrary.text.view.ZLTextPosition;
|
||||||
import org.geometerplus.zlibrary.ui.android.library.ZLAndroidApplication;
|
import org.geometerplus.zlibrary.ui.android.library.ZLAndroidApplication;
|
||||||
|
|
||||||
|
@ -43,6 +45,16 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
||||||
migrate();
|
migrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void executeAsATransaction(Runnable actions) {
|
||||||
|
myDatabase.beginTransaction();
|
||||||
|
try {
|
||||||
|
actions.run();
|
||||||
|
myDatabase.setTransactionSuccessful();
|
||||||
|
} finally {
|
||||||
|
myDatabase.endTransaction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void migrate() {
|
private void migrate() {
|
||||||
final int version = myDatabase.getVersion();
|
final int version = myDatabase.getVersion();
|
||||||
if (version >= 6) {
|
if (version >= 6) {
|
||||||
|
@ -77,16 +89,6 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void executeAsATransaction(Runnable actions) {
|
|
||||||
myDatabase.beginTransaction();
|
|
||||||
try {
|
|
||||||
actions.run();
|
|
||||||
myDatabase.setTransactionSuccessful();
|
|
||||||
} finally {
|
|
||||||
myDatabase.endTransaction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void bindString(SQLiteStatement statement, int index, String value) {
|
private static void bindString(SQLiteStatement statement, int index, String value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
statement.bindString(index, value);
|
statement.bindString(index, value);
|
||||||
|
@ -484,6 +486,7 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
||||||
myDatabase.delete("BookSeries", myBookIdWhereClause, parameters);
|
myDatabase.delete("BookSeries", myBookIdWhereClause, parameters);
|
||||||
myDatabase.delete("BookTag", myBookIdWhereClause, parameters);
|
myDatabase.delete("BookTag", myBookIdWhereClause, parameters);
|
||||||
myDatabase.delete("Bookmarks", myBookIdWhereClause, parameters);
|
myDatabase.delete("Bookmarks", myBookIdWhereClause, parameters);
|
||||||
|
myDatabase.delete("BookState", myBookIdWhereClause, parameters);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -631,20 +634,21 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
||||||
protected List<Bookmark> listBookmarks(long bookId) {
|
protected List<Bookmark> listBookmarks(long bookId) {
|
||||||
LinkedList<Bookmark> list = new LinkedList<Bookmark>();
|
LinkedList<Bookmark> list = new LinkedList<Bookmark>();
|
||||||
Cursor cursor = myDatabase.rawQuery(
|
Cursor cursor = myDatabase.rawQuery(
|
||||||
"SELECT bookmark_id,book_id,bookmark_text,creation_time,modification_time,access_time,access_counter,paragraph,word,char FROM Bookmarks WHERE book_id = ?", new String[] { "" + bookId }
|
"SELECT Bookmarks.bookmark_id,Bookmarks.book_id,Books.title,Bookmarks.bookmark_text,Bookmarks.creation_time,Bookmarks.modification_time,Bookmarks.access_time,Bookmarks.access_counter,Bookmarks.paragraph,Bookmarks.word,Bookmarks.char FROM Bookmarks INNER JOIN Books ON Books.book_id = Bookmarks.book_id WHERE book_id = ?", new String[] { "" + bookId }
|
||||||
);
|
);
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
list.add(createBookmark(
|
list.add(createBookmark(
|
||||||
cursor.getLong(0),
|
cursor.getLong(0),
|
||||||
cursor.getLong(1),
|
cursor.getLong(1),
|
||||||
cursor.getString(2),
|
cursor.getString(2),
|
||||||
getDate(cursor, 3),
|
cursor.getString(3),
|
||||||
getDate(cursor, 4),
|
getDate(cursor, 4),
|
||||||
getDate(cursor, 5),
|
getDate(cursor, 5),
|
||||||
(int)cursor.getLong(6),
|
getDate(cursor, 6),
|
||||||
(int)cursor.getLong(7),
|
(int)cursor.getLong(7),
|
||||||
(int)cursor.getLong(8),
|
(int)cursor.getLong(8),
|
||||||
(int)cursor.getLong(9)
|
(int)cursor.getLong(9),
|
||||||
|
(int)cursor.getLong(10)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
@ -653,21 +657,23 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
||||||
|
|
||||||
protected List<Bookmark> listAllBookmarks() {
|
protected List<Bookmark> listAllBookmarks() {
|
||||||
LinkedList<Bookmark> list = new LinkedList<Bookmark>();
|
LinkedList<Bookmark> list = new LinkedList<Bookmark>();
|
||||||
|
myDatabase.execSQL("DELETE FROM Bookmarks WHERE book_id = -1");
|
||||||
Cursor cursor = myDatabase.rawQuery(
|
Cursor cursor = myDatabase.rawQuery(
|
||||||
"SELECT bookmark_id,book_id,bookmark_text,creation_time,modification_time,access_time,access_counter,paragraph,word,char FROM Bookmarks", null
|
"SELECT Bookmarks.bookmark_id,Bookmarks.book_id,Books.title,Bookmarks.bookmark_text,Bookmarks.creation_time,Bookmarks.modification_time,Bookmarks.access_time,Bookmarks.access_counter,Bookmarks.paragraph,Bookmarks.word,Bookmarks.char FROM Bookmarks INNER JOIN Books ON Books.book_id = Bookmarks.book_id", null
|
||||||
);
|
);
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
list.add(createBookmark(
|
list.add(createBookmark(
|
||||||
cursor.getLong(0),
|
cursor.getLong(0),
|
||||||
cursor.getLong(1),
|
cursor.getLong(1),
|
||||||
cursor.getString(2),
|
cursor.getString(2),
|
||||||
getDate(cursor, 3),
|
cursor.getString(3),
|
||||||
getDate(cursor, 4),
|
getDate(cursor, 4),
|
||||||
getDate(cursor, 5),
|
getDate(cursor, 5),
|
||||||
(int)cursor.getLong(6),
|
getDate(cursor, 6),
|
||||||
(int)cursor.getLong(7),
|
(int)cursor.getLong(7),
|
||||||
(int)cursor.getLong(8),
|
(int)cursor.getLong(8),
|
||||||
(int)cursor.getLong(9)
|
(int)cursor.getLong(9),
|
||||||
|
(int)cursor.getLong(10)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
@ -726,6 +732,32 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
||||||
myDeleteBookmarkStatement.execute();
|
myDeleteBookmarkStatement.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ZLTextPosition getStoredPosition(long bookId) {
|
||||||
|
ZLTextPosition position = null;
|
||||||
|
Cursor cursor = myDatabase.rawQuery(
|
||||||
|
"SELECT paragraph,word,char FROM BookState WHERE book_id = " + bookId, null
|
||||||
|
);
|
||||||
|
if (cursor.moveToNext()) {
|
||||||
|
position = new ZLTextPosition((int)cursor.getLong(0), (int)cursor.getLong(1), (int)cursor.getLong(2));
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SQLiteStatement myStorePositionStatement;
|
||||||
|
protected void storePosition(long bookId, ZLTextPosition position) {
|
||||||
|
if (myStorePositionStatement == null) {
|
||||||
|
myStorePositionStatement = myDatabase.compileStatement(
|
||||||
|
"INSERT OR REPLACE INTO BookState (book_id,paragraph,word,char) VALUES (?,?,?,?)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
myStorePositionStatement.bindLong(1, bookId);
|
||||||
|
myStorePositionStatement.bindLong(2, position.ParagraphIndex);
|
||||||
|
myStorePositionStatement.bindLong(3, position.WordIndex);
|
||||||
|
myStorePositionStatement.bindLong(4, position.CharIndex);
|
||||||
|
myStorePositionStatement.execute();
|
||||||
|
}
|
||||||
|
|
||||||
private void createTables() {
|
private void createTables() {
|
||||||
myDatabase.execSQL(
|
myDatabase.execSQL(
|
||||||
"CREATE TABLE Books(" +
|
"CREATE TABLE Books(" +
|
||||||
|
@ -848,6 +880,34 @@ final class SQLiteBooksDatabase extends BooksDatabase {
|
||||||
"paragraph INTEGER NOT NULL," +
|
"paragraph INTEGER NOT NULL," +
|
||||||
"word INTEGER NOT NULL," +
|
"word INTEGER NOT NULL," +
|
||||||
"char INTEGER NOT NULL)");
|
"char INTEGER NOT NULL)");
|
||||||
|
|
||||||
|
myDatabase.execSQL(
|
||||||
|
"CREATE TABLE BookState(" +
|
||||||
|
"book_id INTEGER UNIQUE NOT NULL REFERENCES Books(book_id)," +
|
||||||
|
"paragraph INTEGER NOT NULL," +
|
||||||
|
"word INTEGER NOT NULL," +
|
||||||
|
"char INTEGER NOT NULL)");
|
||||||
|
Cursor cursor = myDatabase.rawQuery(
|
||||||
|
"SELECT book_id,file_name FROM Books", null
|
||||||
|
);
|
||||||
|
final SQLiteStatement statement = myDatabase.compileStatement("INSERT INTO BookState (book_id,paragraph,word,char) VALUES (?,?,?,?)");
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
final long bookId = cursor.getLong(0);
|
||||||
|
final String fileName = cursor.getString(1);
|
||||||
|
final int position = new ZLIntegerOption(fileName, "PositionInBuffer", 0).getValue();
|
||||||
|
final int paragraph = new ZLIntegerOption(fileName, "Paragraph_" + position, 0).getValue();
|
||||||
|
final int word = new ZLIntegerOption(fileName, "Word_" + position, 0).getValue();
|
||||||
|
final int chr = new ZLIntegerOption(fileName, "Char_" + position, 0).getValue();
|
||||||
|
if ((paragraph != 0) || (word != 0) || (chr != 0)) {
|
||||||
|
statement.bindLong(1, bookId);
|
||||||
|
statement.bindLong(2, paragraph);
|
||||||
|
statement.bindLong(3, word);
|
||||||
|
statement.bindLong(4, chr);
|
||||||
|
statement.execute();
|
||||||
|
}
|
||||||
|
ZLConfig.Instance().removeGroup(fileName);
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTables6() {
|
private void updateTables6() {
|
||||||
|
|
|
@ -70,23 +70,11 @@ public final class ZLSQLiteConfig extends ZLConfig {
|
||||||
myUnsetValueStatement = myDatabase.compileStatement("DELETE FROM config WHERE groupName = ? AND name = ?");
|
myUnsetValueStatement = myDatabase.compileStatement("DELETE FROM config WHERE groupName = ? AND name = ?");
|
||||||
myDeleteGroupStatement = myDatabase.compileStatement("DELETE FROM config WHERE groupName = ?");
|
myDeleteGroupStatement = myDatabase.compileStatement("DELETE FROM config WHERE groupName = ?");
|
||||||
|
|
||||||
/*
|
|
||||||
final Cursor cursor = myDatabase.rawQuery("SELECT name FROM config WHERE groupName LIKE ? GROUP BY name", new String[] { "/%" });
|
final Cursor cursor = myDatabase.rawQuery("SELECT name FROM config WHERE groupName LIKE ? GROUP BY name", new String[] { "/%" });
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
System.err.println(" = " + cursor.getString(0));
|
System.err.println(" = " + cursor.getString(0));
|
||||||
}
|
}
|
||||||
cursor.close();
|
cursor.close();
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized public void executeAsATransaction(Runnable actions) {
|
|
||||||
myDatabase.beginTransaction();
|
|
||||||
try {
|
|
||||||
actions.run();
|
|
||||||
myDatabase.setTransactionSuccessful();
|
|
||||||
} finally {
|
|
||||||
myDatabase.endTransaction();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public void removeGroup(String name) {
|
synchronized public void removeGroup(String name) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.io.*;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.AssetFileDescriptor;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
|
@ -97,12 +98,36 @@ public final class ZLAndroidLibrary extends ZLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean exists() {
|
public boolean exists() {
|
||||||
return myExists;
|
return myExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getInputStream() {
|
@Override
|
||||||
return myExists ? myApplication.getResources().openRawResource(myResourceId) : null;
|
public long size() {
|
||||||
|
try {
|
||||||
|
AssetFileDescriptor descriptor =
|
||||||
|
myApplication.getResources().openRawResourceFd(myResourceId);
|
||||||
|
long length = descriptor.getLength();
|
||||||
|
descriptor.close();
|
||||||
|
return length;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return 0;
|
||||||
|
} catch (Resources.NotFoundException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
if (!myExists) {
|
||||||
|
throw new IOException("No such file: " + getPath());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return myApplication.getResources().openRawResource(myResourceId);
|
||||||
|
} catch (Resources.NotFoundException e) {
|
||||||
|
throw new IOException(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,10 +144,10 @@ public final class ZipFile {
|
||||||
return createZipInputStream(header);
|
return createZipInputStream(header);
|
||||||
}
|
}
|
||||||
if (myAllFilesAreRead) {
|
if (myAllFilesAreRead) {
|
||||||
return null;
|
throw new ZipException("Entry " + entryName + " is not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ready to read fileheader
|
// ready to read file header
|
||||||
MyBufferedInputStream baseStream = getBaseStream();
|
MyBufferedInputStream baseStream = getBaseStream();
|
||||||
baseStream.setPosition(0);
|
baseStream.setPosition(0);
|
||||||
try {
|
try {
|
||||||
|
@ -165,14 +165,11 @@ public final class ZipFile {
|
||||||
} while (!readFileHeader(baseStream, entryName));
|
} while (!readFileHeader(baseStream, entryName));
|
||||||
LocalFileHeader header = myFileHeaders.get(entryName);
|
LocalFileHeader header = myFileHeaders.get(entryName);
|
||||||
if (header != null) {
|
if (header != null) {
|
||||||
try {
|
|
||||||
return createZipInputStream(header);
|
return createZipInputStream(header);
|
||||||
} catch (ZipException e) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
storeBaseStream(baseStream);
|
storeBaseStream(baseStream);
|
||||||
}
|
}
|
||||||
return null;
|
throw new ZipException("Entry " + entryName + " is not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,18 @@ import org.geometerplus.fbreader.library.Book;
|
||||||
import org.geometerplus.fbreader.formats.*;
|
import org.geometerplus.fbreader.formats.*;
|
||||||
|
|
||||||
public final class BookModel {
|
public final class BookModel {
|
||||||
|
public static BookModel createModel(Book book) {
|
||||||
|
FormatPlugin plugin = PluginCollection.instance().getPlugin(book.File);
|
||||||
|
if (plugin == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
BookModel model = new BookModel(book);
|
||||||
|
if (plugin.readModel(model)) {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public final Book Book;
|
public final Book Book;
|
||||||
public final ZLTextPlainModel BookTextModel = new ZLTextPlainModel(65536, "/sdcard/Books/.FBReader", "cache");
|
public final ZLTextPlainModel BookTextModel = new ZLTextPlainModel(65536, "/sdcard/Books/.FBReader", "cache");
|
||||||
public final TOCTree TOCTree = new TOCTree();
|
public final TOCTree TOCTree = new TOCTree();
|
||||||
|
@ -49,12 +61,8 @@ public final class BookModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BookModel(final Book book) {
|
private BookModel(Book book) {
|
||||||
Book = book;
|
Book = book;
|
||||||
FormatPlugin plugin = PluginCollection.instance().getPlugin(book.File);
|
|
||||||
if (plugin != null) {
|
|
||||||
plugin.readModel(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZLTextPlainModel getFootnoteModel(String id) {
|
ZLTextPlainModel getFootnoteModel(String id) {
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.encoding;
|
|
||||||
|
|
||||||
public class DummyEncodingConverterProvider extends ZLEncodingConverterProvider {
|
|
||||||
|
|
||||||
public ZLEncodingConverter createConverter() {
|
|
||||||
return new DummyEncodingConverter();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZLEncodingConverter createConverter(String encoding) {
|
|
||||||
return createConverter();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean providesConverter(String encoding) {
|
|
||||||
final String lowerCasedEncoding = encoding.toLowerCase();
|
|
||||||
return ("utf-8".equals(lowerCasedEncoding)) || ("us-ascii".equals(lowerCasedEncoding));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class DummyEncodingConverter extends ZLEncodingConverter {
|
|
||||||
|
|
||||||
private DummyEncodingConverter() {}
|
|
||||||
|
|
||||||
public boolean fillTable(int[] map) {
|
|
||||||
for (int i = 0; i < 255; ++i) {
|
|
||||||
map[i] = i;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {}
|
|
||||||
|
|
||||||
//size=end-start
|
|
||||||
public String convert(char [] src, int start, int end) {
|
|
||||||
return new String(src, start, end - start);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,169 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.encoding;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.geometerplus.zlibrary.core.config.ZLConfig;
|
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLResourceFile;
|
|
||||||
import org.geometerplus.zlibrary.core.library.ZLibrary;
|
|
||||||
import org.geometerplus.zlibrary.core.options.ZLBooleanOption;
|
|
||||||
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
|
|
||||||
import org.geometerplus.zlibrary.core.xml.ZLXMLReaderAdapter;
|
|
||||||
|
|
||||||
public class ZLEncodingCollection {
|
|
||||||
private static ZLEncodingCollection ourInstance;
|
|
||||||
|
|
||||||
private final ArrayList/*<ZLEncodingSet>*/ mySets = new ArrayList();
|
|
||||||
private final HashMap/*<String,ZLEncodingConverterInfo>*/ myInfosByName = new HashMap();
|
|
||||||
private final ArrayList/*<ZLEncodingConverterProvider>*/ myProviders = new ArrayList();
|
|
||||||
|
|
||||||
private ZLEncodingCollection() {
|
|
||||||
registerProvider(new DummyEncodingConverterProvider());
|
|
||||||
// registerProvider(new MyEncodingConverterProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ZLEncodingCollection instance() {
|
|
||||||
if (ourInstance == null) {
|
|
||||||
ourInstance = new ZLEncodingCollection();
|
|
||||||
}
|
|
||||||
return ourInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ZLResourceFile encodingDescriptionFile() {
|
|
||||||
return ZLResourceFile.createResourceFile("data/encodings/Encodings.xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<ZLEncodingSet> sets() {
|
|
||||||
init();
|
|
||||||
return mySets;
|
|
||||||
}
|
|
||||||
public ZLEncodingConverterInfo info(String name) {
|
|
||||||
init();
|
|
||||||
String lowerCaseName = name.toLowerCase();
|
|
||||||
if (lowerCaseName == "iso-8859-1") {
|
|
||||||
lowerCaseName = "windows-1252";
|
|
||||||
}
|
|
||||||
return (ZLEncodingConverterInfo)myInfosByName.get(lowerCaseName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZLEncodingConverterInfo info(int code) {
|
|
||||||
String name = "" + code;
|
|
||||||
return info(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZLEncodingConverter defaultConverter() {
|
|
||||||
return new DummyEncodingConverterProvider().createConverter();
|
|
||||||
}
|
|
||||||
public void registerProvider(ZLEncodingConverterProvider provider) {
|
|
||||||
myProviders.add(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
// private void addInfo(ZLEncodingConverterInfo info) {}
|
|
||||||
|
|
||||||
ArrayList/*<ZLEncodingConverterProvider>*/ providers() {
|
|
||||||
return myProviders;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
if (mySets.isEmpty()) {
|
|
||||||
// String prefix = encodingDescriptionPath() + File.separator;
|
|
||||||
// System.out.println("trying to read " + prefix + "Encodings.xml");
|
|
||||||
new ZLEncodingCollectionReader(this).read(encodingDescriptionFile());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ZLEncodingCollectionReader extends ZLXMLReaderAdapter {
|
|
||||||
private final ZLEncodingCollection myCollection;
|
|
||||||
private ZLEncodingSet myCurrentSet;
|
|
||||||
private ZLEncodingConverterInfo myCurrentInfo;
|
|
||||||
private final ArrayList/*<String>*/ myNames = new ArrayList();
|
|
||||||
|
|
||||||
private static final String GROUP = "group";
|
|
||||||
private static final String ENCODING = "encoding";
|
|
||||||
private static final String NAME = "name";
|
|
||||||
private static final String REGION = "region";
|
|
||||||
private static final String ALIAS = "alias";
|
|
||||||
private static final String CODE = "code";
|
|
||||||
private static final String NUMBER = "number";
|
|
||||||
|
|
||||||
public ZLEncodingCollectionReader(ZLEncodingCollection collection) {
|
|
||||||
myCollection = collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean dontCacheAttributeValues() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean endElementHandler(String tag) {
|
|
||||||
if (myCurrentInfo != null && (ENCODING.equals(tag))) {
|
|
||||||
if (myCurrentInfo.canCreateConverter()) {
|
|
||||||
myCurrentSet.addInfo(myCurrentInfo);
|
|
||||||
final int size = myNames.size();
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
myCollection.myInfosByName.put(((String) myNames.get(i)).toLowerCase(), myCurrentInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
myCurrentInfo = null;
|
|
||||||
myNames.clear();
|
|
||||||
} else if (myCurrentSet != null && (GROUP.equals(tag))) {
|
|
||||||
if (!myCurrentSet.infos().isEmpty()) {
|
|
||||||
myCollection.mySets.add(myCurrentSet);
|
|
||||||
}
|
|
||||||
myCurrentSet = null;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean startElementHandler(String tag, ZLStringMap attributes) {
|
|
||||||
if (GROUP.equals(tag)) {
|
|
||||||
final String name = attributes.getValue(NAME);
|
|
||||||
if (name != null) {
|
|
||||||
myCurrentSet = new ZLEncodingSet(name);
|
|
||||||
}
|
|
||||||
} else if (myCurrentSet != null) {
|
|
||||||
if (ENCODING.equals(tag)) {
|
|
||||||
final String name = attributes.getValue(NAME);
|
|
||||||
final String region = attributes.getValue(REGION);
|
|
||||||
if ((name != null) && (region != null)) {
|
|
||||||
final String sName = name;
|
|
||||||
myCurrentInfo = new ZLEncodingConverterInfo(sName, region);
|
|
||||||
myNames.add(sName);
|
|
||||||
}
|
|
||||||
} else if (myCurrentInfo != null) {
|
|
||||||
String name = null;
|
|
||||||
if (CODE.equals(tag)) {
|
|
||||||
name = attributes.getValue(NUMBER);
|
|
||||||
} else if (ALIAS.equals(tag)) {
|
|
||||||
name = attributes.getValue(NAME);
|
|
||||||
}
|
|
||||||
if (name != null) {
|
|
||||||
final String sName = name;
|
|
||||||
myCurrentInfo.addAlias(sName);
|
|
||||||
myNames.add(sName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.encoding;
|
|
||||||
|
|
||||||
public abstract class ZLEncodingConverter {
|
|
||||||
protected ZLEncodingConverter() {}
|
|
||||||
|
|
||||||
//abstract public void convert(String dst, const char *srcStart, const char *srcEnd);
|
|
||||||
abstract public String convert(char [] src, int start, int end);
|
|
||||||
//convert(dst, src.toCharArray(), src.data() + src.length());
|
|
||||||
public abstract void reset();
|
|
||||||
public abstract boolean fillTable(int[] map);
|
|
||||||
|
|
||||||
//private ZLEncodingConverter(ZLEncodingConverter zl);
|
|
||||||
//private ZLEncodingConverter &operator=(ZLEncodingConverter zl);
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.encoding;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
public class ZLEncodingConverterInfo {
|
|
||||||
private String myName = "";
|
|
||||||
private String myVisibleName = "";
|
|
||||||
private ArrayList/*<String>*/ myAliases = new ArrayList();
|
|
||||||
|
|
||||||
public ZLEncodingConverterInfo(String name, String region) {
|
|
||||||
myName = name;
|
|
||||||
myVisibleName = region + " (" + name + ")";
|
|
||||||
addAlias(myName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAlias(String alias) {
|
|
||||||
myAliases.add(alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name() {
|
|
||||||
return myName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String visibleName() {
|
|
||||||
return myVisibleName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZLEncodingConverter createConverter() {
|
|
||||||
ZLEncodingCollection collection = ZLEncodingCollection.instance();
|
|
||||||
ArrayList<ZLEncodingConverterProvider> providers = collection.providers();
|
|
||||||
for (Iterator it = providers.iterator(); it.hasNext(); ) {
|
|
||||||
for (Iterator jt = myAliases.iterator(); jt.hasNext(); ) {
|
|
||||||
ZLEncodingConverterProvider itp = (ZLEncodingConverterProvider)it.next();
|
|
||||||
String str = (String)jt.next();
|
|
||||||
if (itp.providesConverter(str)) {
|
|
||||||
return itp.createConverter(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ZLEncodingCollection.instance().defaultConverter();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canCreateConverter() {
|
|
||||||
ZLEncodingCollection collection = ZLEncodingCollection.instance();
|
|
||||||
ArrayList<ZLEncodingConverterProvider> providers = collection.providers();
|
|
||||||
for (Iterator it = providers.iterator(); it.hasNext();) {
|
|
||||||
final ZLEncodingConverterProvider privider = (ZLEncodingConverterProvider)it.next();
|
|
||||||
for (Iterator jt = myAliases.iterator(); jt.hasNext(); ) {
|
|
||||||
if (privider.providesConverter((String)jt.next())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//private ZLEncodingConverterInfo(const ZLEncodingConverterInfo&);
|
|
||||||
//private ZLEncodingConverterInfo &operator=(const ZLEncodingConverterInfo&);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.encoding;
|
|
||||||
|
|
||||||
public abstract class ZLEncodingConverterProvider {
|
|
||||||
protected ZLEncodingConverterProvider() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean providesConverter(String encoding);
|
|
||||||
public abstract ZLEncodingConverter createConverter(String encoding);
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.encoding;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class ZLEncodingSet {
|
|
||||||
private String myName = "";
|
|
||||||
private ArrayList/*<ZLEncodingConverterInfo>*/ myInfos = new ArrayList();
|
|
||||||
|
|
||||||
public ZLEncodingSet(String name) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addInfo(ZLEncodingConverterInfo info) {
|
|
||||||
myInfos.add(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name() {
|
|
||||||
return myName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList/*<ZLEncodingConverterInfo>*/ infos() {
|
|
||||||
return myInfos;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.encodingOption;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.geometerplus.fbreader.encoding.ZLEncodingCollection;
|
|
||||||
import org.geometerplus.fbreader.encoding.ZLEncodingConverterInfo;
|
|
||||||
import org.geometerplus.fbreader.encoding.ZLEncodingSet;
|
|
||||||
import org.geometerplus.zlibrary.core.options.ZLStringOption;
|
|
||||||
import org.geometerplus.zlibrary.core.util.*;
|
|
||||||
|
|
||||||
import org.geometerplus.zlibrary.core.dialogs.ZLComboOptionEntry;
|
|
||||||
|
|
||||||
public class EncodingEntry extends ZLComboOptionEntry {
|
|
||||||
private static final String AUTO = "auto";
|
|
||||||
private static ArrayList/*<String>*/ AUTO_ENCODING;
|
|
||||||
final ArrayList/*<std::string>*/ mySetNames = new ArrayList();
|
|
||||||
private final HashMap/*<String, ArrayList<String>>*/ myValues = new HashMap();
|
|
||||||
private final HashMap/*<String,String>*/ myInitialValues = new HashMap();
|
|
||||||
private final HashMap/*<String,String>*/ myValueByName = new HashMap();
|
|
||||||
private ZLStringOption myEncodingOption;
|
|
||||||
String myInitialSetName = "";
|
|
||||||
|
|
||||||
public EncodingEntry(ZLStringOption encodingOption) {
|
|
||||||
myEncodingOption = encodingOption;
|
|
||||||
final String value = myEncodingOption.getValue();
|
|
||||||
if (AUTO.equals(value)) {
|
|
||||||
myInitialSetName = value;
|
|
||||||
myInitialValues.put(value, value);
|
|
||||||
setActive(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final ArrayList/*<ZLEncodingSet>*/ sets = ZLEncodingCollection.instance().sets();
|
|
||||||
|
|
||||||
System.out.println("sets size = " + sets.size());
|
|
||||||
|
|
||||||
for (int i = 0; i < sets.size(); i++) {
|
|
||||||
ZLEncodingSet es = (ZLEncodingSet) sets.get(i);
|
|
||||||
final ArrayList/*<ZLEncodingConverterInfo>*/ infos = es.infos();
|
|
||||||
// System.out.println(es.name());
|
|
||||||
mySetNames.add(es.name());
|
|
||||||
ArrayList/*<String>*/ names = new ArrayList();
|
|
||||||
for (int j = 0; j < infos.size(); j++) {
|
|
||||||
ZLEncodingConverterInfo eci = (ZLEncodingConverterInfo) infos.get(j);
|
|
||||||
if (eci.name().equals(value)) {
|
|
||||||
myInitialSetName = es.name();
|
|
||||||
myInitialValues.put(myInitialSetName, eci.visibleName());
|
|
||||||
}
|
|
||||||
names.add(eci.visibleName());
|
|
||||||
myValueByName.put(eci.visibleName(), eci.name());
|
|
||||||
}
|
|
||||||
myValues.put(es.name(), names);
|
|
||||||
}
|
|
||||||
//TODO:
|
|
||||||
if (myInitialSetName.length() == 0 && !mySetNames.isEmpty()) {
|
|
||||||
myInitialSetName = (String) mySetNames.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList getValues() {
|
|
||||||
if (AUTO.equals(initialValue())) {
|
|
||||||
if (AUTO_ENCODING == null) {
|
|
||||||
AUTO_ENCODING = new ArrayList();
|
|
||||||
AUTO_ENCODING.add(AUTO);
|
|
||||||
}
|
|
||||||
return AUTO_ENCODING;
|
|
||||||
}
|
|
||||||
return (ArrayList) myValues.get(myInitialSetName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String initialValue() {
|
|
||||||
if ( myInitialValues.get(myInitialSetName) == null) {
|
|
||||||
myInitialValues.put(myInitialSetName, ((ArrayList) myValues.get(myInitialSetName)).get(0));
|
|
||||||
}
|
|
||||||
return (String) myInitialValues.get(myInitialSetName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onAccept(String value) {
|
|
||||||
if (!AUTO.equals(initialValue())) {
|
|
||||||
myEncodingOption.setValue((String) myValueByName.get(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onValueSelected(int index) {
|
|
||||||
myInitialValues.put(myInitialSetName, getValues().get(index));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.encodingOption;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.geometerplus.zlibrary.core.dialogs.ZLComboOptionEntry;
|
|
||||||
|
|
||||||
public class EncodingSetEntry extends ZLComboOptionEntry {
|
|
||||||
private EncodingEntry myEncodingEntry;
|
|
||||||
|
|
||||||
public EncodingSetEntry(EncodingEntry encodingEntry) {
|
|
||||||
myEncodingEntry = encodingEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList getValues() {
|
|
||||||
return myEncodingEntry.mySetNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String initialValue() {
|
|
||||||
return myEncodingEntry.myInitialSetName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onAccept(String value) {}
|
|
||||||
|
|
||||||
public void onValueSelected(int index) {
|
|
||||||
myEncodingEntry.myInitialSetName = (String) getValues().get(index);
|
|
||||||
myEncodingEntry.resetView();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,8 +24,6 @@ public interface ActionCode {
|
||||||
String SHOW_OPTIONS = "preferences-old";
|
String SHOW_OPTIONS = "preferences-old";
|
||||||
String SHOW_PREFERENCES = "preferences";
|
String SHOW_PREFERENCES = "preferences";
|
||||||
String SHOW_BOOK_INFO = "bookInfo";
|
String SHOW_BOOK_INFO = "bookInfo";
|
||||||
String UNDO = "undo";
|
|
||||||
String REDO = "redo";
|
|
||||||
String SHOW_CONTENTS = "toc";
|
String SHOW_CONTENTS = "toc";
|
||||||
String SHOW_BOOKMARKS = "bookmarks";
|
String SHOW_BOOKMARKS = "bookmarks";
|
||||||
String SEARCH = "search";
|
String SEARCH = "search";
|
||||||
|
|
|
@ -28,6 +28,10 @@ class BookInfoAction extends FBAction {
|
||||||
super(fbreader);
|
super(fbreader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isVisible() {
|
||||||
|
return Reader.Model != null;
|
||||||
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
final ZLAndroidDialogManager dialogManager =
|
final ZLAndroidDialogManager dialogManager =
|
||||||
(ZLAndroidDialogManager)ZLAndroidDialogManager.Instance();
|
(ZLAndroidDialogManager)ZLAndroidDialogManager.Instance();
|
||||||
|
|
|
@ -33,63 +33,10 @@ import org.geometerplus.zlibrary.text.view.ZLTextPosition;
|
||||||
import org.geometerplus.zlibrary.text.view.impl.*;
|
import org.geometerplus.zlibrary.text.view.impl.*;
|
||||||
|
|
||||||
public class BookTextView extends FBView {
|
public class BookTextView extends FBView {
|
||||||
private static final String BUFFER_SIZE = "UndoBufferSize";
|
|
||||||
private static final String POSITION_IN_BUFFER = "PositionInBuffer";
|
|
||||||
private static final String PARAGRAPH_PREFIX = "Paragraph_";
|
|
||||||
private static final String WORD_PREFIX = "Word_";
|
|
||||||
private static final String CHAR_PREFIX = "Char_";
|
|
||||||
// private static final String MODEL_PREFIX = "Model_";
|
|
||||||
|
|
||||||
private static final int MAX_UNDO_STACK_SIZE = 20;
|
|
||||||
|
|
||||||
private ZLIntegerOption myParagraphIndexOption;
|
|
||||||
private ZLIntegerOption myWordIndexOption;
|
|
||||||
private ZLIntegerOption myCharIndexOption;
|
|
||||||
|
|
||||||
private ArrayList<ZLTextPosition> myPositionStack = new ArrayList<ZLTextPosition>();
|
|
||||||
private int myCurrentPointInStack;
|
|
||||||
|
|
||||||
private String myFileName;
|
|
||||||
|
|
||||||
BookTextView(ZLPaintContext context) {
|
BookTextView(ZLPaintContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setModel(ZLTextModel model, String fileName) {
|
|
||||||
super.setModel(model);
|
|
||||||
|
|
||||||
myFileName = fileName;
|
|
||||||
|
|
||||||
myPositionStack.clear();
|
|
||||||
|
|
||||||
final int stackSize = new ZLIntegerRangeOption(fileName, BUFFER_SIZE, 0, MAX_UNDO_STACK_SIZE, 0).getValue();
|
|
||||||
myCurrentPointInStack = new ZLIntegerRangeOption(fileName, POSITION_IN_BUFFER, 0, (stackSize == 0) ? 0 : (stackSize - 1), 0).getValue();
|
|
||||||
|
|
||||||
if (model != null) {
|
|
||||||
final ZLIntegerOption option = new ZLIntegerOption(fileName, "", 0);
|
|
||||||
for (int i = 0; i < stackSize; ++i) {
|
|
||||||
option.changeName(PARAGRAPH_PREFIX + i);
|
|
||||||
int paragraphIndex = option.getValue();
|
|
||||||
option.changeName(WORD_PREFIX + i);
|
|
||||||
final int wordIndex = option.getValue();
|
|
||||||
option.changeName(CHAR_PREFIX + i);
|
|
||||||
final int charIndex = option.getValue();
|
|
||||||
myPositionStack.add(new ZLTextPosition(paragraphIndex, wordIndex, charIndex));
|
|
||||||
}
|
|
||||||
if (!myPositionStack.isEmpty()) {
|
|
||||||
gotoPosition(myPositionStack.get(myCurrentPointInStack));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onPaintInfoPrepared() {
|
|
||||||
if (myPositionStack.isEmpty()) {
|
|
||||||
myPositionStack.add(new ZLTextPosition(getStartCursor()));
|
|
||||||
} else {
|
|
||||||
myPositionStack.get(myCurrentPointInStack).set(getStartCursor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void scrollToHome() {
|
void scrollToHome() {
|
||||||
final ZLTextWordCursor cursor = getStartCursor();
|
final ZLTextWordCursor cursor = getStartCursor();
|
||||||
if (!cursor.isNull() && cursor.isStartOfParagraph() && cursor.getParagraphCursor().Index == 0) {
|
if (!cursor.isNull() && cursor.isStartOfParagraph() && cursor.getParagraphCursor().Index == 0) {
|
||||||
|
@ -97,9 +44,8 @@ public class BookTextView extends FBView {
|
||||||
}
|
}
|
||||||
final ZLTextPosition position = new ZLTextPosition(cursor);
|
final ZLTextPosition position = new ZLTextPosition(cursor);
|
||||||
gotoParagraph(0, false);
|
gotoParagraph(0, false);
|
||||||
gotoPosition(0, 0, 0);
|
gotoPosition(new ZLTextPosition(0, 0, 0));
|
||||||
preparePaintInfo();
|
preparePaintInfo();
|
||||||
savePosition(position, getStartCursor());
|
|
||||||
ZLApplication.Instance().repaintView();
|
ZLApplication.Instance().repaintView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +56,6 @@ public class BookTextView extends FBView {
|
||||||
final ZLTextPosition position = new ZLTextPosition(cursor);
|
final ZLTextPosition position = new ZLTextPosition(cursor);
|
||||||
gotoParagraph(paragraphIndex, false);
|
gotoParagraph(paragraphIndex, false);
|
||||||
preparePaintInfo();
|
preparePaintInfo();
|
||||||
savePosition(position, getStartCursor());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,76 +104,4 @@ public class BookTextView extends FBView {
|
||||||
|
|
||||||
return super.onStylusPress(x, y);
|
return super.onStylusPress(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFileName() {
|
|
||||||
return this.myFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void savePosition(ZLTextPosition position) {
|
|
||||||
if (myPositionStack.isEmpty()) {
|
|
||||||
preparePaintInfo();
|
|
||||||
}
|
|
||||||
final ZLTextPosition currentPosition = myPositionStack.get(myCurrentPointInStack);
|
|
||||||
while (myPositionStack.size() > myCurrentPointInStack) {
|
|
||||||
myPositionStack.remove(myPositionStack.size() - 1);
|
|
||||||
}
|
|
||||||
myPositionStack.add(position);
|
|
||||||
myPositionStack.add(currentPosition);
|
|
||||||
while (myPositionStack.size() >= MAX_UNDO_STACK_SIZE) {
|
|
||||||
myPositionStack.remove(0);
|
|
||||||
}
|
|
||||||
myCurrentPointInStack = myPositionStack.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveState() {
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
ZLConfig.Instance().executeAsATransaction(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
saveStateInternal();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveStateInternal() {
|
|
||||||
if (getModel() == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String group = getFileName();
|
|
||||||
|
|
||||||
new ZLIntegerOption(group, BUFFER_SIZE, 0).setValue(myPositionStack.size());
|
|
||||||
new ZLIntegerOption(group, POSITION_IN_BUFFER, 0).setValue(myCurrentPointInStack);
|
|
||||||
|
|
||||||
final ZLIntegerOption option = new ZLIntegerOption(group, "", 0);
|
|
||||||
for (int i = 0; i < myPositionStack.size(); ++i) {
|
|
||||||
final ZLTextPosition position = myPositionStack.get(i);
|
|
||||||
option.changeName(PARAGRAPH_PREFIX + i);
|
|
||||||
option.setValue(position.ParagraphIndex);
|
|
||||||
option.changeName(CHAR_PREFIX + i);
|
|
||||||
option.setValue(position.CharIndex);
|
|
||||||
option.changeName(WORD_PREFIX + i);
|
|
||||||
option.setValue(position.WordIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean canUndoPageMove() {
|
|
||||||
return myCurrentPointInStack > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void undoPageMove() {
|
|
||||||
gotoPosition(myPositionStack.get(--myCurrentPointInStack));
|
|
||||||
ZLApplication.Instance().repaintView();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean canRedoPageMove() {
|
|
||||||
return myCurrentPointInStack < myPositionStack.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void redoPageMove() {
|
|
||||||
gotoPosition(myPositionStack.get(++myCurrentPointInStack));
|
|
||||||
ZLApplication.Instance().repaintView();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,9 +80,6 @@ public final class FBReader extends ZLApplication {
|
||||||
addAction(ActionCode.QUIT, new QuitAction(this));
|
addAction(ActionCode.QUIT, new QuitAction(this));
|
||||||
addAction(ActionCode.ROTATE_SCREEN, new ZLApplication.RotationAction());
|
addAction(ActionCode.ROTATE_SCREEN, new ZLApplication.RotationAction());
|
||||||
|
|
||||||
addAction(ActionCode.UNDO, new UndoAction(this));
|
|
||||||
addAction(ActionCode.REDO, new RedoAction(this));
|
|
||||||
|
|
||||||
addAction(ActionCode.INCREASE_FONT, new ChangeFontSizeAction(this, +2));
|
addAction(ActionCode.INCREASE_FONT, new ChangeFontSizeAction(this, +2));
|
||||||
addAction(ActionCode.DECREASE_FONT, new ChangeFontSizeAction(this, -2));
|
addAction(ActionCode.DECREASE_FONT, new ChangeFontSizeAction(this, -2));
|
||||||
|
|
||||||
|
@ -215,23 +212,25 @@ public final class FBReader extends ZLApplication {
|
||||||
if (book != null) {
|
if (book != null) {
|
||||||
onViewChanged();
|
onViewChanged();
|
||||||
|
|
||||||
BookTextView.saveState();
|
if (Model != null) {
|
||||||
BookTextView.setModel(null, "");
|
Model.Book.storePosition(new ZLTextPosition(BookTextView.getStartCursor()));
|
||||||
|
}
|
||||||
|
BookTextView.setModel(null);
|
||||||
|
FootnoteView.setModel(null);
|
||||||
|
|
||||||
Model = null;
|
Model = null;
|
||||||
Model = new BookModel(book);
|
System.gc();
|
||||||
|
System.gc();
|
||||||
|
Model = BookModel.createModel(book);
|
||||||
|
if (Model != null) {
|
||||||
final String fileName = book.File.getPath();
|
final String fileName = book.File.getPath();
|
||||||
myBookNameOption.setValue(fileName);
|
myBookNameOption.setValue(fileName);
|
||||||
ZLTextHyphenator.Instance().load(book.getLanguage());
|
ZLTextHyphenator.Instance().load(book.getLanguage());
|
||||||
BookTextView.setModel(Model.BookTextModel, fileName);
|
BookTextView.setModel(Model.BookTextModel);
|
||||||
BookTextView.setCaption(book.getTitle());
|
BookTextView.gotoPosition((position != null) ? position : book.getStoredPosition());
|
||||||
if (position != null) {
|
|
||||||
BookTextView.gotoPosition(position);
|
|
||||||
}
|
|
||||||
FootnoteView.setModel(null);
|
|
||||||
FootnoteView.setCaption(book.getTitle());
|
|
||||||
Library.Instance().addBookToRecentList(book);
|
Library.Instance().addBookToRecentList(book);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
repaintView();
|
repaintView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,8 +269,8 @@ main:
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onWindowClosing() {
|
public void onWindowClosing() {
|
||||||
if (BookTextView != null) {
|
if ((Model != null) && (BookTextView != null)) {
|
||||||
BookTextView.saveState();
|
Model.Book.storePosition(new ZLTextPosition(BookTextView.getStartCursor()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,6 @@ public abstract class FBView extends ZLTextViewImpl {
|
||||||
|
|
||||||
private static ZLBooleanOption ourSelectionOption;
|
private static ZLBooleanOption ourSelectionOption;
|
||||||
|
|
||||||
private String myCaption;
|
|
||||||
|
|
||||||
private static ZLIntegerRangeOption createMarginOption(String name, int defaultValue) {
|
private static ZLIntegerRangeOption createMarginOption(String name, int defaultValue) {
|
||||||
return new ZLIntegerRangeOption(
|
return new ZLIntegerRangeOption(
|
||||||
"Options", name, 0, 1000, defaultValue
|
"Options", name, 0, 1000, defaultValue
|
||||||
|
@ -226,14 +224,6 @@ public abstract class FBView extends ZLTextViewImpl {
|
||||||
return getBottomMarginOption().getValue();
|
return getBottomMarginOption().getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCaption() {
|
|
||||||
return myCaption;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCaption(String caption) {
|
|
||||||
myCaption = caption;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ZLBooleanOption selectionOption() {
|
public static ZLBooleanOption selectionOption() {
|
||||||
if (ourSelectionOption == null) {
|
if (ourSelectionOption == null) {
|
||||||
ourSelectionOption = new ZLBooleanOption("Options", "IsSelectionEnabled", true);
|
ourSelectionOption = new ZLBooleanOption("Options", "IsSelectionEnabled", true);
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.fbreader;
|
|
||||||
|
|
||||||
class RedoAction extends FBAction {
|
|
||||||
RedoAction(FBReader fbreader) {
|
|
||||||
super(fbreader);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isVisible() {
|
|
||||||
return Reader.getMode() == FBReader.ViewMode.BOOK_TEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return isVisible() && Reader.BookTextView.canRedoPageMove();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
Reader.BookTextView.redoPageMove();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -26,6 +26,10 @@ class SearchAction extends FBAction {
|
||||||
super(fbreader);
|
super(fbreader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isVisible() {
|
||||||
|
return Reader.Model != null;
|
||||||
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
ZLDialogManager.Instance().startSearch();
|
ZLDialogManager.Instance().startSearch();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.fbreader;
|
|
||||||
|
|
||||||
class UndoAction extends FBAction {
|
|
||||||
UndoAction(FBReader fbreader) {
|
|
||||||
super(fbreader);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isVisible() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return Reader.getMode() != FBReader.ViewMode.BOOK_TEXT ||
|
|
||||||
Reader.BookTextView.canUndoPageMove();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
if (Reader.getMode() == FBReader.ViewMode.BOOK_TEXT) {
|
|
||||||
Reader.BookTextView.undoPageMove();
|
|
||||||
} else {
|
|
||||||
Reader.restorePreviousMode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007-2009 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.formats;
|
|
||||||
|
|
||||||
import org.geometerplus.fbreader.encoding.ZLEncodingCollection;
|
|
||||||
import org.geometerplus.fbreader.encoding.ZLEncodingConverter;
|
|
||||||
import org.geometerplus.fbreader.encoding.ZLEncodingConverterInfo;
|
|
||||||
|
|
||||||
public class EncodedTextReader {
|
|
||||||
private ZLEncodingConverter myConverter;
|
|
||||||
//?static
|
|
||||||
public EncodedTextReader(final String encoding) {
|
|
||||||
ZLEncodingCollection collection = ZLEncodingCollection.instance();
|
|
||||||
ZLEncodingConverterInfo info = collection.info(encoding);
|
|
||||||
myConverter = (info != null) ? info.createConverter() : collection.defaultConverter();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZLEncodingConverter getConverter() {
|
|
||||||
return myConverter;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -27,7 +27,7 @@ import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
import org.geometerplus.fbreader.formats.fb2.FB2Plugin;
|
import org.geometerplus.fbreader.formats.fb2.FB2Plugin;
|
||||||
import org.geometerplus.fbreader.formats.html.HtmlPlugin;
|
import org.geometerplus.fbreader.formats.html.HtmlPlugin;
|
||||||
import org.geometerplus.fbreader.formats.oeb.OEBPlugin;
|
import org.geometerplus.fbreader.formats.oeb.OEBPlugin;
|
||||||
import org.geometerplus.fbreader.formats.plucker.PluckerPlugin;
|
import org.geometerplus.fbreader.formats.pdb.MobipocketPlugin;
|
||||||
|
|
||||||
public class PluginCollection {
|
public class PluginCollection {
|
||||||
private static PluginCollection ourInstance;
|
private static PluginCollection ourInstance;
|
||||||
|
@ -44,13 +44,12 @@ public class PluginCollection {
|
||||||
//ourInstance.myPlugins.add(new PluckerPlugin());
|
//ourInstance.myPlugins.add(new PluckerPlugin());
|
||||||
//ourInstance->myPlugins.push_back(new DocBookPlugin());
|
//ourInstance->myPlugins.push_back(new DocBookPlugin());
|
||||||
//ourInstance.myPlugins.add(new HtmlPlugin());
|
//ourInstance.myPlugins.add(new HtmlPlugin());
|
||||||
/*ourInstance.myPlugins.add(new TxtPlugin());
|
//ourInstance.myPlugins.add(new TxtPlugin());
|
||||||
ourInstance.myPlugins.add(new PalmDocPlugin());
|
//ourInstance.myPlugins.add(new PalmDocPlugin());
|
||||||
ourInstance.myPlugins.add(new MobipocketPlugin());
|
ourInstance.myPlugins.add(new MobipocketPlugin());
|
||||||
ourInstance.myPlugins.add(new ZTXTPlugin());
|
//ourInstance.myPlugins.add(new ZTXTPlugin());
|
||||||
ourInstance.myPlugins.add(new TcrPlugin());
|
//ourInstance.myPlugins.add(new TcrPlugin());
|
||||||
ourInstance.myPlugins.add(new CHMPlugin());
|
//ourInstance.myPlugins.add(new CHMPlugin());
|
||||||
*/
|
|
||||||
ourInstance.myPlugins.add(new OEBPlugin());
|
ourInstance.myPlugins.add(new OEBPlugin());
|
||||||
//ourInstance.myPlugins.add(new RtfPlugin());
|
//ourInstance.myPlugins.add(new RtfPlugin());
|
||||||
//ourInstance.myPlugins.add(new OpenReaderPlugin());
|
//ourInstance.myPlugins.add(new OpenReaderPlugin());
|
||||||
|
|
|
@ -50,7 +50,6 @@ public abstract class DocDecompressor {
|
||||||
|
|
||||||
if (stream.read(sourceBuffer, 0, compressedSize) == compressedSize) {
|
if (stream.read(sourceBuffer, 0, compressedSize) == compressedSize) {
|
||||||
byte token;
|
byte token;
|
||||||
int shiftedIndex;
|
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
while ((sourceIndex < compressedSize) && (targetIndex < maxUncompressedSize)) {
|
while ((sourceIndex < compressedSize) && (targetIndex < maxUncompressedSize)) {
|
||||||
|
@ -79,17 +78,17 @@ loop:
|
||||||
if (sourceIndex + 1 > compressedSize) {
|
if (sourceIndex + 1 > compressedSize) {
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
int N = 256 * (token & 0xFF) + (sourceBuffer[sourceIndex++] & 0xFF);
|
final int N = ((token & 0xFF) << 16) + (sourceBuffer[sourceIndex++] & 0xFF);
|
||||||
int copyLength = (N & 7) + 3;
|
final int copyLength = (N & 7) + 3;
|
||||||
if (targetIndex + copyLength > maxUncompressedSize) {
|
if (targetIndex + copyLength > maxUncompressedSize) {
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
shiftedIndex = targetIndex - (N & 0x3fff) / 8;
|
final int srcIndex = targetIndex - (N & 0x3fff) / 8;
|
||||||
if (shiftedIndex >= 0) {
|
if (srcIndex < 0) {
|
||||||
for (int i = 0; i < copyLength; i++) {
|
break;
|
||||||
targetBuffer[targetIndex++] = targetBuffer[shiftedIndex++];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
System.arraycopy(targetBuffer, srcIndex, targetBuffer, targetIndex, copyLength);
|
||||||
|
targetIndex += copyLength;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
128
src/org/geometerplus/fbreader/formats/pdb/MobipocketPlugin.java
Normal file
128
src/org/geometerplus/fbreader/formats/pdb/MobipocketPlugin.java
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2009 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.formats.pdb;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
|
import org.geometerplus.zlibrary.core.encoding.ZLEncodingCollection;
|
||||||
|
import org.geometerplus.zlibrary.core.util.ZLLanguageUtil;
|
||||||
|
|
||||||
|
import org.geometerplus.fbreader.library.Book;
|
||||||
|
import org.geometerplus.fbreader.bookmodel.BookModel;
|
||||||
|
|
||||||
|
public class MobipocketPlugin extends PdbPlugin {
|
||||||
|
@Override
|
||||||
|
public boolean acceptsFile(ZLFile file) {
|
||||||
|
return super.acceptsFile(file) && (fileType(file) == "BOOKMOBI");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean readMetaInfo(Book book) {
|
||||||
|
InputStream stream = null;
|
||||||
|
try {
|
||||||
|
stream = book.File.getInputStream();
|
||||||
|
final PdbHeader header = new PdbHeader(stream);
|
||||||
|
PdbUtil.skip(stream, header.Offsets[0] + 16 - header.length());
|
||||||
|
if (PdbUtil.readInt(stream) != 0x4D4F4249) /* "MOBI" */ {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final int length = (int)PdbUtil.readInt(stream);
|
||||||
|
PdbUtil.skip(stream, 4);
|
||||||
|
final int encodingCode = (int)PdbUtil.readInt(stream);
|
||||||
|
String encodingName = ZLEncodingCollection.Instance().getEncodingName(encodingCode);
|
||||||
|
book.setEncoding(encodingName);
|
||||||
|
if (encodingName == null) {
|
||||||
|
encodingName = "utf-8";
|
||||||
|
}
|
||||||
|
PdbUtil.skip(stream, 52);
|
||||||
|
final int fullNameOffset = (int)PdbUtil.readInt(stream);
|
||||||
|
final int fullNameLength = (int)PdbUtil.readInt(stream);
|
||||||
|
final int languageCode = (int)PdbUtil.readInt(stream);
|
||||||
|
book.setLanguage(ZLLanguageUtil.languageByCode(languageCode & 0xFF, (languageCode >> 8) & 0xFF));
|
||||||
|
PdbUtil.skip(stream, 32);
|
||||||
|
int offset = 132;
|
||||||
|
if ((PdbUtil.readInt(stream) & 0x40) != 0) {
|
||||||
|
PdbUtil.skip(stream, length - 116);
|
||||||
|
offset = length + 20;
|
||||||
|
if (PdbUtil.readInt(stream) == 0x45585448) /* "EXTH" */ {
|
||||||
|
PdbUtil.skip(stream, 4);
|
||||||
|
final int recordsNumber = (int)PdbUtil.readInt(stream);
|
||||||
|
offset += 8;
|
||||||
|
for (int i = 0; i < recordsNumber; ++i) {
|
||||||
|
final int type = (int)PdbUtil.readInt(stream);
|
||||||
|
final int size = (int)PdbUtil.readInt(stream);
|
||||||
|
offset += size;
|
||||||
|
if (size <= 8) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (type) {
|
||||||
|
default:
|
||||||
|
PdbUtil.skip(stream, size - 8);
|
||||||
|
break;
|
||||||
|
case 100:
|
||||||
|
{
|
||||||
|
final byte[] buffer = new byte[size - 8];
|
||||||
|
stream.read(buffer);
|
||||||
|
String author = new String(buffer, encodingName);
|
||||||
|
final int index = author.indexOf(',');
|
||||||
|
if (index != -1) {
|
||||||
|
author = author.substring(index + 1).trim() +
|
||||||
|
' ' +
|
||||||
|
author.substring(0, index).trim();
|
||||||
|
} else {
|
||||||
|
author = author.trim();
|
||||||
|
}
|
||||||
|
book.addAuthor(author);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 105:
|
||||||
|
{
|
||||||
|
final byte[] buffer = new byte[size - 8];
|
||||||
|
stream.read(buffer);
|
||||||
|
book.addTag(new String(buffer, encodingName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PdbUtil.skip(stream, fullNameOffset - offset);
|
||||||
|
final byte[] titleBuffer = new byte[fullNameLength];
|
||||||
|
stream.read(titleBuffer);
|
||||||
|
book.setTitle(new String(titleBuffer, encodingName));
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
if (stream != null) {
|
||||||
|
try {
|
||||||
|
stream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean readModel(BookModel model) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,18 +17,37 @@
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geometerplus.fbreader.encoding;
|
package org.geometerplus.fbreader.formats.pdb;
|
||||||
|
|
||||||
public class MyEncodingConverterProvider extends ZLEncodingConverterProvider {
|
import java.io.IOException;
|
||||||
|
|
||||||
public ZLEncodingConverter createConverter(String encoding) {
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
class MobipocketStream extends PdbStream {
|
||||||
|
private final long myFileSize;
|
||||||
|
private final boolean myIsCompressed;
|
||||||
|
|
||||||
|
MobipocketStream(ZLFile file) throws IOException {
|
||||||
|
super(file);
|
||||||
|
myFileSize = file.size();
|
||||||
|
|
||||||
|
final int version = PdbUtil.readShort(myBase);
|
||||||
|
switch (version) {
|
||||||
|
case 1:
|
||||||
|
myIsCompressed = false;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
myIsCompressed = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IOException("Unsupported compression type: " + version);
|
||||||
|
}
|
||||||
|
PdbUtil.skip(myBase, 6);
|
||||||
|
// TODO: implement
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean providesConverter(String encoding) {
|
protected boolean fillBuffer() {
|
||||||
// TODO Auto-generated method stub
|
// TODO: implement
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,7 +21,6 @@ package org.geometerplus.fbreader.formats.pdb;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class PdbHeader {
|
public class PdbHeader {
|
||||||
static public String DocName;
|
static public String DocName;
|
||||||
|
@ -29,41 +28,36 @@ public class PdbHeader {
|
||||||
static public String Id;
|
static public String Id;
|
||||||
static public int[] Offsets;
|
static public int[] Offsets;
|
||||||
|
|
||||||
public boolean read(InputStream stream) throws IOException {
|
public PdbHeader(InputStream stream) throws IOException {
|
||||||
final byte[] buffer = new byte[32];
|
final byte[] buffer = new byte[32];
|
||||||
if (stream.read(buffer, 0, 32) != 32) {
|
if (stream.read(buffer, 0, 32) != 32) {
|
||||||
System.err.println("way 0");
|
throw new IOException("PdbHeader: cannot reader document name");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
DocName = new String(buffer);
|
DocName = new String(buffer);
|
||||||
Flags = PdbUtil.readShort(stream);
|
Flags = PdbUtil.readShort(stream);
|
||||||
|
|
||||||
stream.skip(26);
|
PdbUtil.skip(stream, 26);
|
||||||
|
|
||||||
if (stream.read(buffer, 0, 8) != 8) {
|
if (stream.read(buffer, 0, 8) != 8) {
|
||||||
System.err.println("way 1");
|
throw new IOException("PdbHeader: cannot reader palm id");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
Id = new String(buffer, 0, 8);
|
Id = new String(buffer, 0, 8);
|
||||||
|
|
||||||
stream.skip(8);
|
PdbUtil.skip(stream, 8);
|
||||||
|
|
||||||
int numRecords = PdbUtil.readShort(stream);
|
int numRecords = PdbUtil.readShort(stream);
|
||||||
if (numRecords <= 0) {
|
if (numRecords <= 0) {
|
||||||
System.err.println(numRecords);
|
throw new IOException("PdbHeader: record number = " + numRecords);
|
||||||
System.err.println("way 2");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
Offsets = new int[numRecords];
|
Offsets = new int[numRecords];
|
||||||
|
|
||||||
for (int i = 0; i < numRecords; ++i) {
|
for (int i = 0; i < numRecords; ++i) {
|
||||||
Offsets[i] = PdbUtil.readInt(stream);
|
Offsets[i] = (int)PdbUtil.readInt(stream);
|
||||||
if (stream.skip(4) != 4) {
|
PdbUtil.skip(stream, 4);
|
||||||
System.err.println("way 3");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
public final int length() {
|
||||||
|
return 78 + Offsets.length * 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,25 +22,25 @@ package org.geometerplus.fbreader.formats.pdb;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
//import org.geometerplus.fbreader.collection.BookDescriptionUtil;
|
|
||||||
import org.geometerplus.fbreader.formats.FormatPlugin;
|
|
||||||
import org.geometerplus.fbreader.formats.plucker.PluckerTextStream;
|
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
import org.geometerplus.zlibrary.core.options.ZLStringOption;
|
import org.geometerplus.zlibrary.core.options.ZLStringOption;
|
||||||
|
|
||||||
|
import org.geometerplus.fbreader.formats.FormatPlugin;
|
||||||
|
|
||||||
public abstract class PdbPlugin extends FormatPlugin {
|
public abstract class PdbPlugin extends FormatPlugin {
|
||||||
protected static String fileType(final ZLFile file) {
|
@Override
|
||||||
final String extension = file.getExtension().toLowerCase().intern();
|
public boolean acceptsFile(ZLFile file) {
|
||||||
if ((extension != "prc") && (extension != "pdb") && (extension != "mobi")) {
|
final String extension = file.getExtension();
|
||||||
return null;
|
return (extension == "prc") || (extension == "pdb") || (extension == "mobi");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static String fileType(final ZLFile file) {
|
||||||
ZLFile baseFile = file.getPhysicalFile();
|
ZLFile baseFile = file.getPhysicalFile();
|
||||||
boolean upToDate = true;//BookDescriptionUtil.checkInfo(baseFile);
|
|
||||||
|
|
||||||
|
// TODO: use database instead of option (?)
|
||||||
ZLStringOption palmTypeOption = new ZLStringOption(file.getPath(), "PalmType", "");
|
ZLStringOption palmTypeOption = new ZLStringOption(file.getPath(), "PalmType", "");
|
||||||
String palmType = palmTypeOption.getValue();
|
String palmType = palmTypeOption.getValue();
|
||||||
if ((palmType.length() != 8) || !upToDate) {
|
if (palmType.length() != 8) {
|
||||||
byte[] id = new byte[8];
|
byte[] id = new byte[8];
|
||||||
try {
|
try {
|
||||||
final InputStream stream = file.getInputStream();
|
final InputStream stream = file.getInputStream();
|
||||||
|
@ -48,18 +48,13 @@ public abstract class PdbPlugin extends FormatPlugin {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
stream.skip(60);
|
stream.skip(60);
|
||||||
stream.read(id, 0, 8);
|
stream.read(id);
|
||||||
stream.close();
|
stream.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
palmType = new String(id);
|
|
||||||
if (!upToDate) {
|
|
||||||
//BookDescriptionUtil.saveInfo(baseFile);
|
|
||||||
}
|
}
|
||||||
|
palmType = new String(id).intern();
|
||||||
palmTypeOption.setValue(palmType);
|
palmTypeOption.setValue(palmType);
|
||||||
}
|
}
|
||||||
return palmType;
|
return palmType.intern();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,22 +26,28 @@ import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
|
|
||||||
public abstract class PdbStream extends InputStream {
|
public abstract class PdbStream extends InputStream {
|
||||||
protected final InputStream myBase;
|
protected final InputStream myBase;
|
||||||
private int myOffset;
|
public PdbHeader myHeader;
|
||||||
public final PdbHeader myHeader = new PdbHeader();
|
|
||||||
protected byte[] myBuffer;
|
protected byte[] myBuffer;
|
||||||
|
|
||||||
protected short myBufferLength;
|
protected short myBufferLength;
|
||||||
protected short myBufferOffset;
|
protected short myBufferOffset;
|
||||||
|
|
||||||
public PdbStream(ZLFile file) {
|
public PdbStream(ZLFile file) throws IOException {
|
||||||
InputStream base;
|
myBase = file.getInputStream();
|
||||||
try {
|
|
||||||
base = file.getInputStream();
|
myHeader = new PdbHeader(myBase);
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
myBase.skip(myHeader.Offsets[0] - myHeader.length());
|
||||||
base = null;
|
|
||||||
|
myBufferLength = 0;
|
||||||
|
myBufferOffset = 0;
|
||||||
}
|
}
|
||||||
myBase = base;
|
|
||||||
|
public int read() {
|
||||||
|
if (!fillBuffer()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return myBuffer[myBufferOffset++];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int read(byte[] buffer,int offset, int maxSize) {
|
public int read(byte[] buffer,int offset, int maxSize) {
|
||||||
|
@ -57,45 +63,8 @@ public abstract class PdbStream extends InputStream {
|
||||||
myBufferOffset += size;
|
myBufferOffset += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myOffset += realSize;
|
|
||||||
return realSize;
|
return realSize;
|
||||||
}
|
}
|
||||||
/*public int read(byte[] buffer,int offset, int maxSize) {
|
|
||||||
int realSize = 0;
|
|
||||||
while (realSize < maxSize) {
|
|
||||||
if (!fillBuffer()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int size = Math.min((maxSize - realSize), (myBufferLength - myBufferOffset));
|
|
||||||
if (size > 0) {
|
|
||||||
if (buffer != null) {
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
myBuffer[myBufferOffset+i] = buffer[realSize+i];
|
|
||||||
}
|
|
||||||
//memcpy(buffer + realSize, myBuffer + myBufferOffset, size);
|
|
||||||
}
|
|
||||||
realSize += size;
|
|
||||||
myBufferOffset += size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
myOffset += realSize;
|
|
||||||
return realSize;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public boolean open() throws IOException {
|
|
||||||
if ((myBase == null) || !myHeader.read(myBase)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
myBase.skip(myHeader.Offsets[0] - 78 - 8 * myHeader.Offsets.length);
|
|
||||||
|
|
||||||
myBufferLength = 0;
|
|
||||||
myBufferOffset = 0;
|
|
||||||
|
|
||||||
myOffset = 0;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (myBase != null) {
|
if (myBase != null) {
|
||||||
|
@ -109,23 +78,10 @@ public abstract class PdbStream extends InputStream {
|
||||||
public void skip(int offset) throws IOException {
|
public void skip(int offset) throws IOException {
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
read(null, 0, offset);
|
read(null, 0, offset);
|
||||||
} else if (offset < 0) {
|
} else {
|
||||||
offset += this.offset();
|
throw new IOException("Cannot skip: " + offset + " bytes");
|
||||||
open();
|
|
||||||
if (offset >= 0) {
|
|
||||||
read(null, 0, offset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public int offset() {
|
|
||||||
return myOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int sizeOfOpened() {
|
|
||||||
// TODO: implement
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract boolean fillBuffer();
|
protected abstract boolean fillBuffer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,31 +21,28 @@ package org.geometerplus.fbreader.formats.pdb;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
public class PdbUtil {
|
public abstract class PdbUtil {
|
||||||
public static int readShort(InputStream stream) {
|
public static void skip(InputStream stream, int numBytes) throws IOException {
|
||||||
final byte[] tmp = new byte[2];
|
numBytes -= stream.skip(numBytes);
|
||||||
try {
|
for (; numBytes > 0; --numBytes) {
|
||||||
stream.read(tmp, 0, 2);
|
if (stream.read() == -1) {
|
||||||
} catch (IOException e) {
|
throw new IOException("Unexpected end of stream");
|
||||||
return -1;
|
}
|
||||||
}
|
}
|
||||||
// int i = ((tmp[1] & 0xFF) + ((tmp[0] & 0xFF) << 8));
|
|
||||||
// if (i > Short.MAX_VALUE)
|
|
||||||
// System.out.println("i = " + i);
|
|
||||||
return ((tmp[1] & 0xFF) + ((tmp[0] & 0xFF) << 8));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//? long
|
public static int readShort(InputStream stream) throws IOException {
|
||||||
public static int readInt(InputStream stream) {
|
final byte[] tmp = new byte[2];
|
||||||
final byte[] tmp = new byte[4];
|
stream.read(tmp, 0, 2);
|
||||||
try {
|
return (tmp[1] & 0xFF) + ((tmp[0] & 0xFF) << 8);
|
||||||
stream.read(tmp, 0, 4);
|
|
||||||
} catch (IOException e) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
return (tmp[0] << 24) +
|
|
||||||
((tmp[1] & 0xFF) << 16) +
|
public static long readInt(InputStream stream) throws IOException {
|
||||||
((tmp[2] & 0xFF) << 8) +
|
final byte[] tmp = new byte[4];
|
||||||
(tmp[3] & 0xFF);
|
stream.read(tmp, 0, 4);
|
||||||
|
return (((long)(tmp[0] & 0xFF)) << 24) +
|
||||||
|
+ ((tmp[1] & 0xFF) << 16) +
|
||||||
|
+ ((tmp[2] & 0xFF) << 8) +
|
||||||
|
+ (tmp[3] & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,6 @@ import org.geometerplus.zlibrary.core.image.*;
|
||||||
import org.geometerplus.zlibrary.text.model.*;
|
import org.geometerplus.zlibrary.text.model.*;
|
||||||
|
|
||||||
import org.geometerplus.fbreader.bookmodel.*;
|
import org.geometerplus.fbreader.bookmodel.*;
|
||||||
import org.geometerplus.fbreader.encoding.ZLEncodingConverter;
|
|
||||||
import org.geometerplus.fbreader.formats.EncodedTextReader;
|
|
||||||
import org.geometerplus.fbreader.formats.pdb.*;
|
import org.geometerplus.fbreader.formats.pdb.*;
|
||||||
|
|
||||||
public class PluckerBookReader extends BookReader {
|
public class PluckerBookReader extends BookReader {
|
||||||
|
@ -51,11 +49,9 @@ public class PluckerBookReader extends BookReader {
|
||||||
private ArrayList/*<Integer, Integer>*/ myParagraphVector = new ArrayList(); //<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
private ArrayList/*<Integer, Integer>*/ myParagraphVector = new ArrayList(); //<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
private boolean myParagraphStored;
|
private boolean myParagraphStored;
|
||||||
|
|
||||||
private final ZLEncodingConverter myConverter;
|
|
||||||
|
|
||||||
public PluckerBookReader(ZLFile file, BookModel model, String encoding){
|
public PluckerBookReader(ZLFile file, BookModel model, String encoding){
|
||||||
super(model);
|
super(model);
|
||||||
myConverter = new EncodedTextReader(encoding).getConverter();
|
//myConverter = new EncodedTextReader(encoding).getConverter();
|
||||||
myFile = file;
|
myFile = file;
|
||||||
//System.out.println(filePath + " " + encoding);
|
//System.out.println(filePath + " " + encoding);
|
||||||
myFont = FontType.FT_REGULAR;
|
myFont = FontType.FT_REGULAR;
|
||||||
|
@ -63,14 +59,11 @@ public class PluckerBookReader extends BookReader {
|
||||||
myForcedEntry = null;
|
myForcedEntry = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean readDocument() throws IOException {
|
public boolean readDocument() {
|
||||||
|
try {
|
||||||
myStream = new PdbInputStream(myFile);
|
myStream = new PdbInputStream(myFile);
|
||||||
|
|
||||||
PdbHeader header = new PdbHeader();
|
PdbHeader header = new PdbHeader(myStream);
|
||||||
if (!header.read(myStream)) {
|
|
||||||
myStream.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
setMainTextModel();
|
setMainTextModel();
|
||||||
myFont = FontType.FT_REGULAR;
|
myFont = FontType.FT_REGULAR;
|
||||||
|
@ -91,6 +84,9 @@ public class PluckerBookReader extends BookReader {
|
||||||
readRecord(recordSize);
|
readRecord(recordSize);
|
||||||
}
|
}
|
||||||
myStream.close();
|
myStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (Iterator it = myReferencedParagraphs.iterator(); it.hasNext();) {
|
for (Iterator it = myReferencedParagraphs.iterator(); it.hasNext();) {
|
||||||
Pair pair = (Pair)it.next();
|
Pair pair = (Pair)it.next();
|
||||||
|
@ -285,7 +281,7 @@ public class PluckerBookReader extends BookReader {
|
||||||
if (ptr > textStart) {
|
if (ptr > textStart) {
|
||||||
safeBeginParagraph();
|
safeBeginParagraph();
|
||||||
// myConvertedTextBuffer = "";//.erase();
|
// myConvertedTextBuffer = "";//.erase();
|
||||||
myConvertedTextBuffer = myConverter.convert(data, textStart, ptr);
|
myConvertedTextBuffer = "";//myConverter.convert(data, textStart, ptr);
|
||||||
addData(myConvertedTextBuffer.toCharArray());
|
addData(myConvertedTextBuffer.toCharArray());
|
||||||
myBufferIsEmpty = false;
|
myBufferIsEmpty = false;
|
||||||
}
|
}
|
||||||
|
@ -315,7 +311,7 @@ public class PluckerBookReader extends BookReader {
|
||||||
if (end > textStart) {
|
if (end > textStart) {
|
||||||
safeBeginParagraph();
|
safeBeginParagraph();
|
||||||
// myConvertedTextBuffer = "";//erase();
|
// myConvertedTextBuffer = "";//erase();
|
||||||
myConvertedTextBuffer = myConverter.convert(data, textStart, end);
|
myConvertedTextBuffer = "";//myConverter.convert(data, textStart, end);
|
||||||
addData(myConvertedTextBuffer.toCharArray());
|
addData(myConvertedTextBuffer.toCharArray());
|
||||||
myBufferIsEmpty = false;
|
myBufferIsEmpty = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class PluckerPlugin extends PdbPlugin {
|
||||||
@Override
|
@Override
|
||||||
public boolean readMetaInfo(Book book) {
|
public boolean readMetaInfo(Book book) {
|
||||||
try {
|
try {
|
||||||
PdbStream stream = new PluckerTextStream(book.File);
|
PluckerTextStream stream = new PluckerTextStream(book.File);
|
||||||
if (stream.open()) {
|
if (stream.open()) {
|
||||||
//detectEncodingAndLanguage(book, stream);
|
//detectEncodingAndLanguage(book, stream);
|
||||||
stream.close();
|
stream.close();
|
||||||
|
@ -53,12 +53,6 @@ public class PluckerPlugin extends PdbPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean readModel(BookModel model) {
|
public boolean readModel(BookModel model) {
|
||||||
try {
|
|
||||||
return new PluckerBookReader(model.Book.File, model, model.Book.getEncoding()).readDocument();
|
return new PluckerBookReader(model.Book.File, model, model.Book.getEncoding()).readDocument();
|
||||||
} catch (IOException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class PluckerTextStream extends PdbStream {
|
||||||
private byte[] myFullBuffer;
|
private byte[] myFullBuffer;
|
||||||
private int myRecordIndex;
|
private int myRecordIndex;
|
||||||
|
|
||||||
public PluckerTextStream(ZLFile file) {
|
public PluckerTextStream(ZLFile file) throws IOException {
|
||||||
super(file);
|
super(file);
|
||||||
myFullBuffer = null;
|
myFullBuffer = null;
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,9 @@ public class PluckerTextStream extends PdbStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean open() throws IOException {
|
public boolean open() throws IOException {
|
||||||
if (!super.open()) {
|
//if (!super.open()) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
//}
|
||||||
|
|
||||||
myCompressionVersion = (short) PdbUtil.readShort(myBase);
|
myCompressionVersion = (short) PdbUtil.readShort(myBase);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.util.*;
|
||||||
import org.geometerplus.zlibrary.core.util.ZLMiscUtil;
|
import org.geometerplus.zlibrary.core.util.ZLMiscUtil;
|
||||||
import org.geometerplus.zlibrary.core.filesystem.*;
|
import org.geometerplus.zlibrary.core.filesystem.*;
|
||||||
|
|
||||||
|
import org.geometerplus.zlibrary.text.view.ZLTextPosition;
|
||||||
|
|
||||||
import org.geometerplus.fbreader.formats.*;
|
import org.geometerplus.fbreader.formats.*;
|
||||||
|
|
||||||
public class Book {
|
public class Book {
|
||||||
|
@ -77,7 +79,11 @@ public class Book {
|
||||||
if (book == null) {
|
if (book == null) {
|
||||||
book = new Book(bookFile);
|
book = new Book(bookFile);
|
||||||
}
|
}
|
||||||
return book.readMetaInfo() ? book : null;
|
if (book.readMetaInfo()) {
|
||||||
|
book.save();
|
||||||
|
return book;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ZLFile File;
|
public final ZLFile File;
|
||||||
|
@ -320,4 +326,14 @@ public class Book {
|
||||||
myIsSaved = true;
|
myIsSaved = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ZLTextPosition getStoredPosition() {
|
||||||
|
return BooksDatabase.Instance().getStoredPosition(myId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void storePosition(ZLTextPosition position) {
|
||||||
|
if (myId != -1) {
|
||||||
|
BooksDatabase.Instance().storePosition(myId, position);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,8 @@ public class Bookmark {
|
||||||
}
|
}
|
||||||
|
|
||||||
private long myId;
|
private long myId;
|
||||||
private long myBookId;
|
private final long myBookId;
|
||||||
|
private final String myBookTitle;
|
||||||
private String myText;
|
private String myText;
|
||||||
private final Date myCreationDate;
|
private final Date myCreationDate;
|
||||||
private Date myModificationDate;
|
private Date myModificationDate;
|
||||||
|
@ -45,9 +46,10 @@ public class Bookmark {
|
||||||
|
|
||||||
private boolean myIsChanged;
|
private boolean myIsChanged;
|
||||||
|
|
||||||
Bookmark(long id, long bookId, String text, Date creationDate, Date modificationDate, Date accessDate, int accessCount, int paragraphIndex, int wordIndex, int charIndex) {
|
Bookmark(long id, long bookId, String bookTitle, String text, Date creationDate, Date modificationDate, Date accessDate, int accessCount, int paragraphIndex, int wordIndex, int charIndex) {
|
||||||
myId = id;
|
myId = id;
|
||||||
myBookId = bookId;
|
myBookId = bookId;
|
||||||
|
myBookTitle = bookTitle;
|
||||||
myText = text;
|
myText = text;
|
||||||
myCreationDate = creationDate;
|
myCreationDate = creationDate;
|
||||||
myModificationDate = modificationDate;
|
myModificationDate = modificationDate;
|
||||||
|
@ -66,6 +68,7 @@ public class Bookmark {
|
||||||
public Bookmark(Book book, String text, ZLTextPosition position) {
|
public Bookmark(Book book, String text, ZLTextPosition position) {
|
||||||
myId = -1;
|
myId = -1;
|
||||||
myBookId = book.getId();
|
myBookId = book.getId();
|
||||||
|
myBookTitle = book.getTitle();
|
||||||
myText = text;
|
myText = text;
|
||||||
myCreationDate = new Date();
|
myCreationDate = new Date();
|
||||||
myPosition = position;
|
myPosition = position;
|
||||||
|
@ -84,6 +87,10 @@ public class Bookmark {
|
||||||
return myText;
|
return myText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getBookTitle() {
|
||||||
|
return myBookTitle;
|
||||||
|
}
|
||||||
|
|
||||||
public ZLTextPosition getPosition() {
|
public ZLTextPosition getPosition() {
|
||||||
return myPosition;
|
return myPosition;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ import java.util.*;
|
||||||
|
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
|
|
||||||
|
import org.geometerplus.zlibrary.text.view.ZLTextPosition;
|
||||||
|
|
||||||
public abstract class BooksDatabase {
|
public abstract class BooksDatabase {
|
||||||
private static BooksDatabase ourInstance;
|
private static BooksDatabase ourInstance;
|
||||||
|
|
||||||
|
@ -75,12 +77,15 @@ public abstract class BooksDatabase {
|
||||||
protected abstract List<Long> listRecentBookIds();
|
protected abstract List<Long> listRecentBookIds();
|
||||||
protected abstract void saveRecentBookIds(final List<Long> ids);
|
protected abstract void saveRecentBookIds(final List<Long> ids);
|
||||||
|
|
||||||
protected Bookmark createBookmark(long id, long bookId, String text, Date creationDate, Date modificationDate, Date accessDate, int accessCounter, int paragraphIndex, int wordIndex, int charIndex) {
|
protected Bookmark createBookmark(long id, long bookId, String bookTitle, String text, Date creationDate, Date modificationDate, Date accessDate, int accessCounter, int paragraphIndex, int wordIndex, int charIndex) {
|
||||||
return new Bookmark(id, bookId, text, creationDate, modificationDate, accessDate, accessCounter, paragraphIndex, wordIndex, charIndex);
|
return new Bookmark(id, bookId, bookTitle, text, creationDate, modificationDate, accessDate, accessCounter, paragraphIndex, wordIndex, charIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract List<Bookmark> listBookmarks(long bookId);
|
protected abstract List<Bookmark> listBookmarks(long bookId);
|
||||||
protected abstract List<Bookmark> listAllBookmarks();
|
protected abstract List<Bookmark> listAllBookmarks();
|
||||||
protected abstract long saveBookmark(Bookmark bookmark);
|
protected abstract long saveBookmark(Bookmark bookmark);
|
||||||
protected abstract void deleteBookmark(Bookmark bookmark);
|
protected abstract void deleteBookmark(Bookmark bookmark);
|
||||||
|
|
||||||
|
protected abstract ZLTextPosition getStoredPosition(long bookId);
|
||||||
|
protected abstract void storePosition(long bookId, ZLTextPosition position);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,6 @@ import org.geometerplus.zlibrary.core.resources.ZLResource;
|
||||||
import org.geometerplus.zlibrary.core.view.ZLViewWidget;
|
import org.geometerplus.zlibrary.core.view.ZLViewWidget;
|
||||||
import org.geometerplus.zlibrary.text.view.style.*;
|
import org.geometerplus.zlibrary.text.view.style.*;
|
||||||
|
|
||||||
import org.geometerplus.fbreader.encoding.ZLEncodingCollection;
|
|
||||||
import org.geometerplus.fbreader.encodingOption.*;
|
|
||||||
import org.geometerplus.fbreader.fbreader.*;
|
import org.geometerplus.fbreader.fbreader.*;
|
||||||
import org.geometerplus.fbreader.formats.PluginCollection;
|
import org.geometerplus.fbreader.formats.PluginCollection;
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,6 @@ public abstract class ZLConfig {
|
||||||
ourInstance = this;
|
ourInstance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void executeAsATransaction(Runnable actions);
|
|
||||||
|
|
||||||
public abstract String getValue(String group, String name, String defaultValue);
|
public abstract String getValue(String group, String name, String defaultValue);
|
||||||
public abstract void setValue(String group, String name, String value);
|
public abstract void setValue(String group, String name, String value);
|
||||||
public abstract void unsetValue(String group, String name);
|
public abstract void unsetValue(String group, String name);
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2009 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.zlibrary.core.encoding;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.geometerplus.zlibrary.core.filesystem.ZLResourceFile;
|
||||||
|
import org.geometerplus.zlibrary.core.library.ZLibrary;
|
||||||
|
import org.geometerplus.zlibrary.core.xml.ZLStringMap;
|
||||||
|
import org.geometerplus.zlibrary.core.xml.ZLXMLReaderAdapter;
|
||||||
|
|
||||||
|
public final class ZLEncodingCollection {
|
||||||
|
private static ZLEncodingCollection ourInstance;
|
||||||
|
|
||||||
|
public static ZLEncodingCollection Instance() {
|
||||||
|
if (ourInstance == null) {
|
||||||
|
ourInstance = new ZLEncodingCollection();
|
||||||
|
}
|
||||||
|
return ourInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final HashMap<String,String> myEncodingByAlias = new HashMap<String,String>();
|
||||||
|
|
||||||
|
private ZLEncodingCollection() {
|
||||||
|
new ZLEncodingCollectionReader().read(
|
||||||
|
ZLResourceFile.createResourceFile("data/encodings/Encodings.xml")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEncodingName(String alias) {
|
||||||
|
final String name = myEncodingByAlias.get(alias);
|
||||||
|
return (name != null) ? name : alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEncodingName(int code) {
|
||||||
|
return myEncodingByAlias.get("" + code);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ZLEncodingCollectionReader extends ZLXMLReaderAdapter {
|
||||||
|
private String myCurrentEncodingName;
|
||||||
|
|
||||||
|
public ZLEncodingCollectionReader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean dontCacheAttributeValues() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String ENCODING = "encoding";
|
||||||
|
private static final String NAME = "name";
|
||||||
|
private static final String ALIAS = "alias";
|
||||||
|
private static final String CODE = "code";
|
||||||
|
private static final String NUMBER = "number";
|
||||||
|
|
||||||
|
public boolean startElementHandler(String tag, ZLStringMap attributes) {
|
||||||
|
if (ENCODING == tag) {
|
||||||
|
myCurrentEncodingName = attributes.getValue(NAME);
|
||||||
|
} else if (myCurrentEncodingName != null) {
|
||||||
|
String alias = null;
|
||||||
|
if (ALIAS == tag) {
|
||||||
|
alias = attributes.getValue(NAME);
|
||||||
|
} else if (CODE == tag) {
|
||||||
|
alias = attributes.getValue(NUMBER);
|
||||||
|
}
|
||||||
|
if (alias != null) {
|
||||||
|
myEncodingByAlias.put(alias, myCurrentEncodingName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean endElementHandler(String tag) {
|
||||||
|
if (ENCODING == tag) {
|
||||||
|
myCurrentEncodingName = null;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,18 +56,22 @@ public abstract class ZLArchiveEntryFile extends ZLFile {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean exists() {
|
public boolean exists() {
|
||||||
return myParent.exists();
|
return myParent.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isDirectory() {
|
public boolean isDirectory() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return myParent.getPath() + ":" + myName;
|
return myParent.getPath() + ":" + myName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getNameWithExtension() {
|
public String getNameWithExtension() {
|
||||||
if (myShortName == null) {
|
if (myShortName == null) {
|
||||||
final String name = myName;
|
final String name = myName;
|
||||||
|
@ -81,10 +85,12 @@ public abstract class ZLArchiveEntryFile extends ZLFile {
|
||||||
return myShortName;
|
return myShortName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ZLFile getParent() {
|
public ZLFile getParent() {
|
||||||
return myParent;
|
return myParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ZLPhysicalFile getPhysicalFile() {
|
public ZLPhysicalFile getPhysicalFile() {
|
||||||
ZLFile ancestor = myParent;
|
ZLFile ancestor = myParent;
|
||||||
while ((ancestor != null) && !(ancestor instanceof ZLPhysicalFile)) {
|
while ((ancestor != null) && !(ancestor instanceof ZLPhysicalFile)) {
|
||||||
|
|
|
@ -94,6 +94,7 @@ public abstract class ZLFile {
|
||||||
return new ZLPhysicalFile(path);
|
return new ZLPhysicalFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract long size();
|
||||||
public abstract boolean exists();
|
public abstract boolean exists();
|
||||||
public abstract boolean isDirectory();
|
public abstract boolean isDirectory();
|
||||||
public abstract String getPath();
|
public abstract String getPath();
|
||||||
|
@ -118,53 +119,6 @@ public abstract class ZLFile {
|
||||||
return myExtension;
|
return myExtension;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
public InputStream getInputStream() throws IOException {
|
|
||||||
InputStream stream = null;
|
|
||||||
int index = ZLFSUtil.findArchiveFileNameDelimiter(myPath);
|
|
||||||
if (index == -1) {
|
|
||||||
stream = ZLibrary.Instance().getInputStream(myPath);
|
|
||||||
} else {
|
|
||||||
ZLFile baseFile = new ZLFile(myPath.substring(0, index));
|
|
||||||
InputStream base = baseFile.getInputStream();
|
|
||||||
if (base != null) {
|
|
||||||
if (0 != (baseFile.myArchiveType & ArchiveType.ZIP)) {
|
|
||||||
ZipFile zf = getZipFile(myPath.substring(0, index));
|
|
||||||
/*
|
|
||||||
ZipEntry entry = zf.getEntry(myPath.substring(index+1));
|
|
||||||
stream = zf.getInputStream(entry);
|
|
||||||
* /
|
|
||||||
final String entryName = myPath.substring(index + 1);
|
|
||||||
stream = zf.getInputStream(entryName);
|
|
||||||
/*
|
|
||||||
while (true) {
|
|
||||||
ZipEntry entry = zipStream.getNextEntry();
|
|
||||||
if (entry == null) {
|
|
||||||
break;
|
|
||||||
} else if (entryName.equals(entry.getName())) {
|
|
||||||
stream = zipStream;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
* /
|
|
||||||
} else if (0 != (baseFile.myArchiveType & ArchiveType.TAR)) {
|
|
||||||
stream = new ZLTarInputStream(base, myPath.substring(index + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream != null) {
|
|
||||||
if (0 != (myArchiveType & ArchiveType.GZIP)) {
|
|
||||||
return new java.util.zip.GZIPInputStream(stream, 8192);
|
|
||||||
}
|
|
||||||
//if (0 != (myArchiveType & ArchiveType.BZIP2)) {
|
|
||||||
//return new ZLBzip2InputStream(stream);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
protected List<ZLFile> directoryEntries() {
|
protected List<ZLFile> directoryEntries() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,39 +36,46 @@ public final class ZLPhysicalFile extends ZLFile {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean exists() {
|
public boolean exists() {
|
||||||
return myFile.exists();
|
return myFile.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long size() {
|
public long size() {
|
||||||
return myFile.length();
|
return myFile.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isDirectory() {
|
public boolean isDirectory() {
|
||||||
return myFile.isDirectory();
|
return myFile.isDirectory();
|
||||||
//return myFile.length() == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean remove() {
|
public boolean remove() {
|
||||||
return myFile.delete();
|
return myFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return myFile.getPath();
|
return myFile.getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getNameWithExtension() {
|
public String getNameWithExtension() {
|
||||||
return myFile.getName();
|
return myFile.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ZLFile getParent() {
|
public ZLFile getParent() {
|
||||||
return isDirectory() ? null : new ZLPhysicalFile(myFile.getParent());
|
return isDirectory() ? null : new ZLPhysicalFile(myFile.getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ZLPhysicalFile getPhysicalFile() {
|
public ZLPhysicalFile getPhysicalFile() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public InputStream getInputStream() throws IOException {
|
public InputStream getInputStream() throws IOException {
|
||||||
return new FileInputStream(myFile);
|
return new FileInputStream(myFile);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,12 @@ final class ZLZipEntryFile extends ZLArchiveEntryFile {
|
||||||
super(parent, name);
|
super(parent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long size() {
|
||||||
|
throw new RuntimeException("Not implemented yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public InputStream getInputStream() throws IOException {
|
public InputStream getInputStream() throws IOException {
|
||||||
return getZipFile(myParent).getInputStream(myName);
|
return getZipFile(myParent).getInputStream(myName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,11 +56,13 @@ public final class ZLTarEntryFile extends ZLArchiveEntryFile {
|
||||||
super(parent, name);
|
super(parent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getInputStream() throws IOException {
|
@Override
|
||||||
InputStream base = myParent.getInputStream();
|
public long size() {
|
||||||
if (base != null) {
|
throw new RuntimeException("Not implemented yet.");
|
||||||
return new ZLTarInputStream(base, myName);
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return new ZLTarInputStream(myParent.getInputStream(), myName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,6 @@ public final class ZLIntegerOption extends ZLOption {
|
||||||
myValue = defaultValue;
|
myValue = defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeName(String optionName) {
|
|
||||||
super.changeName(optionName);
|
|
||||||
myValue = myDefaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getValue() {
|
public int getValue() {
|
||||||
if (!myIsSynchronized) {
|
if (!myIsSynchronized) {
|
||||||
String value = getConfigValue(null);
|
String value = getConfigValue(null);
|
||||||
|
|
157
src/org/geometerplus/zlibrary/core/util/ZLLanguageUtil.java
Normal file
157
src/org/geometerplus/zlibrary/core/util/ZLLanguageUtil.java
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008-2009 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.zlibrary.core.util;
|
||||||
|
|
||||||
|
public abstract class ZLLanguageUtil {
|
||||||
|
public static String languageByCode(int languageCode, int subLanguageCode) {
|
||||||
|
switch (languageCode) {
|
||||||
|
default: return null;
|
||||||
|
case 0x01: return "ar"; // Arabic
|
||||||
|
case 0x02: return "bg"; // Bulgarian
|
||||||
|
case 0x03: return "ca"; // Catalan
|
||||||
|
case 0x04: return "zh"; // Chinese
|
||||||
|
case 0x05: return "cs"; // Czech
|
||||||
|
case 0x06: return "da"; // Danish
|
||||||
|
case 0x07: return "de"; // German
|
||||||
|
case 0x08: return "el"; // Greek
|
||||||
|
case 0x09: return "en"; // English
|
||||||
|
case 0x0A: return "es"; // Spanish
|
||||||
|
case 0x0B: return "fi"; // Finnish
|
||||||
|
case 0x0C: return "fr"; // French
|
||||||
|
case 0x0D: return "he"; // Hebrew
|
||||||
|
case 0x0E: return "hu"; // Hungarian
|
||||||
|
case 0x0F: return "is"; // Icelandic
|
||||||
|
case 0x10: return "it"; // Italian
|
||||||
|
case 0x11: return "ja"; // Japanese
|
||||||
|
case 0x12: return "ko"; // Korean
|
||||||
|
case 0x13: return "nl"; // Dutch
|
||||||
|
case 0x14: return "no"; // Norwegian
|
||||||
|
case 0x15: return "pl"; // Polish
|
||||||
|
case 0x16: return "pt"; // Portuguese
|
||||||
|
case 0x17: return "rm"; // Romansh
|
||||||
|
case 0x18: return "ro"; // Romanian
|
||||||
|
case 0x19: return "ru"; // Russian
|
||||||
|
case 0x1A:
|
||||||
|
switch (subLanguageCode) {
|
||||||
|
default: return "sr"; // Serbian
|
||||||
|
case 0x04:
|
||||||
|
case 0x10: return "hr"; // Croatian
|
||||||
|
case 0x14:
|
||||||
|
case 0x20:
|
||||||
|
case 0x78: return "bs"; // Bosnian
|
||||||
|
}
|
||||||
|
case 0x1B: return "sk"; // Slovak
|
||||||
|
case 0x1C: return "sq"; // Albanian
|
||||||
|
case 0x1D: return "sv"; // Swedish
|
||||||
|
case 0x1E: return "th"; // Thai
|
||||||
|
case 0x1F: return "tr"; // Turkish
|
||||||
|
case 0x20: return "ur"; // Urdu
|
||||||
|
case 0x21: return "id"; // Indonesian
|
||||||
|
case 0x22: return "uk"; // Ukrainian
|
||||||
|
case 0x23: return "be"; // Belarusian
|
||||||
|
case 0x24: return "sl"; // Slovenian
|
||||||
|
case 0x25: return "et"; // Estonian
|
||||||
|
case 0x26: return "lv"; // Latvian
|
||||||
|
case 0x27: return "lt"; // Lithuanian
|
||||||
|
case 0x28: return "tg"; // Tajik
|
||||||
|
case 0x29: return "fa"; // Persian (Farsi)
|
||||||
|
case 0x2A: return "vi"; // Vietnamese
|
||||||
|
case 0x2B: return "hy"; // Armenian
|
||||||
|
case 0x2C: return "az"; // Azeri
|
||||||
|
case 0x2D: return "eu"; // Basque
|
||||||
|
case 0x2E: return (subLanguageCode == 0x08)
|
||||||
|
? "dsb" // Lower Sorbian
|
||||||
|
: "wen"; // Upper Sorbian
|
||||||
|
case 0x2F: return "mk"; // Makedonian
|
||||||
|
case 0x32: return "tn"; // Setswana/Tswana
|
||||||
|
case 0x34: return "xh"; // Xhosa/isiXhosa
|
||||||
|
case 0x35: return "zu"; // Zulu/isiZulu
|
||||||
|
case 0x36: return "af"; // Afrikaans
|
||||||
|
case 0x37: return "ka"; // Georgian
|
||||||
|
case 0x38: return "fo"; // Faeroese
|
||||||
|
case 0x39: return "hi"; // Hindi
|
||||||
|
case 0x3A: return "mt"; // Maltese
|
||||||
|
case 0x3B: return "se"; // Sami
|
||||||
|
case 0x3C: return "ga"; // Irish
|
||||||
|
case 0x3E: return "ms"; // Malay
|
||||||
|
case 0x3F: return "kk"; // Kazak
|
||||||
|
case 0x40: return "ky"; // Kyrgyz
|
||||||
|
case 0x41: return "sw"; // Swahili
|
||||||
|
case 0x42: return "tk"; // Turkmen
|
||||||
|
case 0x43: return "uz"; // Uzbek
|
||||||
|
case 0x44: return "tt"; // Tatar
|
||||||
|
case 0x45: return "bn"; // Bengali
|
||||||
|
case 0x46: return "pa"; // Punjabi
|
||||||
|
case 0x47: return "gu"; // Gujaratu
|
||||||
|
case 0x48: return "or"; // Oriya
|
||||||
|
case 0x49: return "ta"; // Tamil
|
||||||
|
case 0x4A: return "te"; // Telugi
|
||||||
|
case 0x4B: return "kn"; // Kannada
|
||||||
|
case 0x4C: return "ml"; // Malayalam
|
||||||
|
case 0x4D: return "as"; // Assamese
|
||||||
|
case 0x4E: return "mr"; // Marathi
|
||||||
|
case 0x4F: return "sa"; // Sanskrit
|
||||||
|
case 0x50: return "mn"; // Mongolian
|
||||||
|
case 0x51: return "bo"; // Tibetian
|
||||||
|
case 0x52: return "cy"; // Welsh
|
||||||
|
case 0x53: return "kh"; // Khmer
|
||||||
|
case 0x54: return "lo"; // Lao
|
||||||
|
case 0x56: return "gl"; // Galician
|
||||||
|
case 0x57: return "kok"; // Konkani
|
||||||
|
case 0x58: return "mni"; // Manipuri
|
||||||
|
case 0x59: return "sd"; // Sindhi
|
||||||
|
case 0x5A: return "syr"; // Syriac
|
||||||
|
case 0x5B: return "si"; // Sinhala
|
||||||
|
case 0x5D: return "iu"; // Inuktitut
|
||||||
|
case 0x5E: return "am"; // Amharic
|
||||||
|
case 0x5F: return "tzm"; // Tamazight
|
||||||
|
case 0x60: return "ks"; // Kashmiri
|
||||||
|
case 0x61: return "ne"; // Nepali
|
||||||
|
case 0x62: return "fy"; // Frisian
|
||||||
|
case 0x63: return "ps"; // Pashto
|
||||||
|
case 0x64: return "fil"; // Filipino
|
||||||
|
case 0x65: return "dv"; // Divehi
|
||||||
|
case 0x68: return "ha"; // Hausa
|
||||||
|
case 0x6A: return "yo"; // Yoruba
|
||||||
|
case 0x6B: return "quz"; // Quechua
|
||||||
|
case 0x6C: return "ns"; // Northern Sotho
|
||||||
|
case 0x6D: return "ba"; // Bashkir
|
||||||
|
case 0x6E: return "lb"; // Luxemburgish
|
||||||
|
case 0x6F: return "kl"; // Greenlandic
|
||||||
|
case 0x70: return "ig"; // Igbo
|
||||||
|
case 0x73: return "ti"; // Tigrinya
|
||||||
|
case 0x78: return "yi"; // Yi
|
||||||
|
case 0x7A: return "arn"; // Mapudungun
|
||||||
|
case 0x7C: return "moh"; // Mohawk
|
||||||
|
case 0x7E: return "be"; // Breton
|
||||||
|
case 0x80: return "ug"; // Uighur
|
||||||
|
case 0x81: return "mi"; // Maori
|
||||||
|
case 0x82: return "oc"; // Occitan
|
||||||
|
case 0x83: return "co"; // Corsican
|
||||||
|
case 0x84: return "gsw"; // Alsatian
|
||||||
|
case 0x85: return "sah"; // Yakut
|
||||||
|
case 0x86: return "qut"; // K'iche
|
||||||
|
case 0x87: return "rw"; // Kinyarwanda
|
||||||
|
case 0x88: return "wo"; // Wolof
|
||||||
|
case 0x8C: return "prs"; // Dari
|
||||||
|
case 0x8D: return "mg"; // Malagasy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,8 +28,6 @@ abstract public class ZLView {
|
||||||
Context = context;
|
Context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public String getCaption();
|
|
||||||
|
|
||||||
public static final int PAGE_CENTRAL = 0;
|
public static final int PAGE_CENTRAL = 0;
|
||||||
public static final int PAGE_LEFT = 1;
|
public static final int PAGE_LEFT = 1;
|
||||||
public static final int PAGE_RIGHT = 2;
|
public static final int PAGE_RIGHT = 2;
|
||||||
|
|
|
@ -263,24 +263,10 @@ public abstract class ZLTextViewImpl extends ZLTextView {
|
||||||
if (myCurrentPage.StartCursor.isNull()) {
|
if (myCurrentPage.StartCursor.isNull()) {
|
||||||
preparePaintInfo(myCurrentPage);
|
preparePaintInfo(myCurrentPage);
|
||||||
}
|
}
|
||||||
/* if (!position.equalsToCursor(myCurrentPage.StartCursor)) {
|
|
||||||
savePosition(position);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
savePosition(position, myCurrentPage.StartCursor);
|
|
||||||
ZLApplication.Instance().repaintView();
|
ZLApplication.Instance().repaintView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void savePosition(ZLTextPosition position) {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final void savePosition(ZLTextPosition position, ZLTextWordCursor cursorToCheck) {
|
|
||||||
if (!position.equalsToCursor(cursorToCheck)) {
|
|
||||||
savePosition(position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int search(final String text, boolean ignoreCase, boolean wholeText, boolean backward, boolean thisSectionOnly) {
|
public int search(final String text, boolean ignoreCase, boolean wholeText, boolean backward, boolean thisSectionOnly) {
|
||||||
if (text.length() == 0) {
|
if (text.length() == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -383,9 +369,6 @@ public abstract class ZLTextViewImpl extends ZLTextView {
|
||||||
myNextPage.StartCursor.setCursor(myCurrentPage.EndCursor);
|
myNextPage.StartCursor.setCursor(myCurrentPage.EndCursor);
|
||||||
myNextPage.PaintState = PaintStateEnum.START_IS_KNOWN;
|
myNextPage.PaintState = PaintStateEnum.START_IS_KNOWN;
|
||||||
}
|
}
|
||||||
if (myCurrentPage.PaintState == PaintStateEnum.READY) {
|
|
||||||
onPaintInfoPrepared();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PAGE_RIGHT:
|
case PAGE_RIGHT:
|
||||||
|
@ -401,9 +384,6 @@ public abstract class ZLTextViewImpl extends ZLTextView {
|
||||||
myCurrentPage.StartCursor.setCursor(myNextPage.EndCursor);
|
myCurrentPage.StartCursor.setCursor(myNextPage.EndCursor);
|
||||||
myCurrentPage.PaintState = PaintStateEnum.START_IS_KNOWN;
|
myCurrentPage.PaintState = PaintStateEnum.START_IS_KNOWN;
|
||||||
}
|
}
|
||||||
if (myCurrentPage.PaintState == PaintStateEnum.READY) {
|
|
||||||
onPaintInfoPrepared();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -487,14 +467,14 @@ public abstract class ZLTextViewImpl extends ZLTextView {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int getScrollbarFullSize() {
|
public final int getScrollbarFullSize() {
|
||||||
if ((myTextSize == null) || (myTextSize.length == 0)) {
|
if ((myModel == null) || (myTextSize == null) || (myTextSize.length == 0)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return myTextSize[myTextSize.length - 1];
|
return myTextSize[myTextSize.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int getScrollbarThumbPosition(int viewPage) {
|
public final int getScrollbarThumbPosition(int viewPage) {
|
||||||
if ((myTextSize == null) || (myTextSize.length == 0)) {
|
if ((myModel == null) || (myTextSize == null) || (myTextSize.length == 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ZLTextPage page = getPage(viewPage);
|
ZLTextPage page = getPage(viewPage);
|
||||||
|
@ -503,7 +483,7 @@ public abstract class ZLTextViewImpl extends ZLTextView {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int getScrollbarThumbLength(int viewPage) {
|
public final int getScrollbarThumbLength(int viewPage) {
|
||||||
if ((myTextSize == null) || (myTextSize.length == 0)) {
|
if ((myModel == null) || (myTextSize == null) || (myTextSize.length == 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ZLTextPage page = getPage(viewPage);
|
ZLTextPage page = getPage(viewPage);
|
||||||
|
@ -1042,10 +1022,12 @@ public abstract class ZLTextViewImpl extends ZLTextView {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void gotoPosition(ZLTextPosition position) {
|
public final void gotoPosition(ZLTextPosition position) {
|
||||||
|
if (position != null) {
|
||||||
gotoPosition(position.ParagraphIndex, position.WordIndex, position.CharIndex);
|
gotoPosition(position.ParagraphIndex, position.WordIndex, position.CharIndex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final void gotoPosition(int paragraphIndex, int wordIndex, int charIndex) {
|
private void gotoPosition(int paragraphIndex, int wordIndex, int charIndex) {
|
||||||
final int maxParagraphIndex = myModel.getParagraphsNumber() - 1;
|
final int maxParagraphIndex = myModel.getParagraphsNumber() - 1;
|
||||||
if (paragraphIndex > maxParagraphIndex) {
|
if (paragraphIndex > maxParagraphIndex) {
|
||||||
paragraphIndex = maxParagraphIndex;
|
paragraphIndex = maxParagraphIndex;
|
||||||
|
@ -1216,13 +1198,9 @@ public abstract class ZLTextViewImpl extends ZLTextView {
|
||||||
if (page == myCurrentPage) {
|
if (page == myCurrentPage) {
|
||||||
myPreviousPage.reset();
|
myPreviousPage.reset();
|
||||||
myNextPage.reset();
|
myNextPage.reset();
|
||||||
onPaintInfoPrepared();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onPaintInfoPrepared() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearCaches() {
|
public void clearCaches() {
|
||||||
rebuildPaintInfo();
|
rebuildPaintInfo();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue