/* * Copyright (C) 2010-2011 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.android.fbreader.network; import java.util.*; import android.app.Activity; import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.os.Bundle; import android.text.method.LinkMovementMethod; import android.util.DisplayMetrics; import android.view.*; import android.widget.*; import org.geometerplus.zlibrary.ui.android.R; import org.geometerplus.zlibrary.core.image.ZLImage; import org.geometerplus.zlibrary.core.image.ZLLoadableImage; import org.geometerplus.zlibrary.core.resources.ZLResource; import org.geometerplus.zlibrary.core.util.MimeType; import org.geometerplus.zlibrary.ui.android.image.ZLAndroidImageManager; import org.geometerplus.zlibrary.ui.android.image.ZLAndroidImageData; import org.geometerplus.zlibrary.ui.android.network.SQLiteCookieDatabase; import org.geometerplus.fbreader.network.*; import org.geometerplus.fbreader.network.tree.NetworkBookTree; import org.geometerplus.fbreader.network.urlInfo.*; public class NetworkBookInfoActivity extends Activity implements NetworkView.EventListener { private NetworkBookItem myBook; private View myMainView; private final ZLResource myResource = ZLResource.resource("networkBookView"); private BookDownloaderServiceConnection myConnection; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); Thread.setDefaultUncaughtExceptionHandler(new org.geometerplus.zlibrary.ui.android.library.UncaughtExceptionHandler(this)); SQLiteCookieDatabase.init(this); myMainView = getLayoutInflater().inflate(R.layout.network_book, null, false); setContentView(myMainView); } @Override protected void onResume() { super.onResume(); if (!NetworkView.Instance().isInitialized()) { if (NetworkInitializer.Instance == null) { new NetworkInitializer(null); NetworkInitializer.Instance.start(); } else { NetworkInitializer.Instance.setActivity(null); } } if (myBook == null) { final NetworkTree tree = Util.getTreeFromIntent(getIntent()); if (!(tree instanceof NetworkBookTree)) { finish(); return; } myBook = ((NetworkBookTree)tree).Book; myConnection = new BookDownloaderServiceConnection(); bindService( new Intent(getApplicationContext(), BookDownloaderService.class), myConnection, BIND_AUTO_CREATE ); setTitle(myBook.Title); setupDescription(); setupExtraLinks(); setupInfo(); setupCover(); setupButtons(); } } View getMainView() { return myMainView; } private void setTextById(int id, CharSequence text) { ((TextView)findViewById(id)).setText(text); } private void setTextFromResource(int id, String resourceKey) { setTextById(id, myResource.getResource(resourceKey).getValue()); } @Override public void onDestroy() { if (!NetworkView.Instance().isInitialized() && NetworkInitializer.Instance != null) { NetworkInitializer.Instance.setActivity(null); } if (myConnection != null) { unbindService(myConnection); myConnection = null; } super.onDestroy(); } @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { NetworkView.Instance().getTopupActions().buildContextMenu(this, menu, myBook.Link); unregisterForContextMenu(view); } @Override public boolean onContextItemSelected(MenuItem item) { TopupActions.runAction(this, myBook.Link, item.getItemId()); return true; } private final void setupDescription() { setTextFromResource(R.id.network_book_description_title, "description"); CharSequence description = myBook.getSummary(); if (description == null) { description = myResource.getResource("noDescription").getValue(); } final TextView descriptionView = (TextView)findViewById(R.id.network_book_description); descriptionView.setText(description); descriptionView.setMovementMethod(new LinkMovementMethod()); descriptionView.setTextColor( ColorStateList.valueOf(descriptionView.getTextColors().getDefaultColor()) ); } private final void setupExtraLinks() { final List<UrlInfo> extraLinks = myBook.getAllInfos(UrlInfo.Type.Related); if (extraLinks.isEmpty()) { findViewById(R.id.network_book_extra_links_title).setVisibility(View.GONE); findViewById(R.id.network_book_extra_links).setVisibility(View.GONE); } else { setTextFromResource(R.id.network_book_extra_links_title, "extraLinks"); final LinearLayout extraLinkSection = (LinearLayout)findViewById(R.id.network_book_extra_links); final LayoutInflater inflater = getLayoutInflater(); View linkView = null; for (UrlInfo info : extraLinks) { if (!(info instanceof RelatedUrlInfo)) { continue; } final RelatedUrlInfo relatedInfo = (RelatedUrlInfo)info; linkView = inflater.inflate(R.layout.extra_link_item, extraLinkSection, false); linkView.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { final NetworkCatalogItem catalogItem = myBook.createRelatedCatalogItem(relatedInfo); if (catalogItem != null) { NetworkCatalogActions.doExpandCatalog( NetworkBookInfoActivity.this, NetworkLibrary.Instance().getFakeCatalogTree(catalogItem) ); } else if (MimeType.TEXT_HTML.equals(relatedInfo.Mime)) { Util.openInBrowser(NetworkBookInfoActivity.this, relatedInfo.Url); } } }); ((TextView)linkView.findViewById(R.id.extra_link_title)).setText(relatedInfo.Title); extraLinkSection.addView(linkView); } linkView.findViewById(R.id.extra_link_divider).setVisibility(View.GONE); } } private void setPairLabelTextFromResource(int id, String resourceKey) { final LinearLayout layout = (LinearLayout)findViewById(id); ((TextView)layout.findViewById(R.id.book_info_key)) .setText(myResource.getResource(resourceKey).getValue()); } private void setPairValueText(int id, CharSequence text) { final LinearLayout layout = (LinearLayout)findViewById(id); ((TextView)layout.findViewById(R.id.book_info_value)).setText(text); } private void setupInfo() { setTextFromResource(R.id.network_book_info_title, "bookInfo"); setPairLabelTextFromResource(R.id.network_book_title, "title"); setPairLabelTextFromResource(R.id.network_book_authors, "authors"); setPairLabelTextFromResource(R.id.network_book_series_title, "series"); setPairLabelTextFromResource(R.id.network_book_series_index, "indexInSeries"); setPairLabelTextFromResource(R.id.network_book_tags, "tags"); setPairLabelTextFromResource(R.id.network_book_catalog, "catalog"); setPairValueText(R.id.network_book_title, myBook.Title); if (myBook.Authors.size() > 0) { findViewById(R.id.network_book_authors).setVisibility(View.VISIBLE); final StringBuilder authorsText = new StringBuilder(); for (NetworkBookItem.AuthorData author : myBook.Authors) { if (authorsText.length() > 0) { authorsText.append(", "); } authorsText.append(author.DisplayName); } setPairValueText(R.id.network_book_authors, authorsText); } else { findViewById(R.id.network_book_authors).setVisibility(View.GONE); } if (myBook.SeriesTitle != null) { findViewById(R.id.network_book_series_title).setVisibility(View.VISIBLE); setPairValueText(R.id.network_book_series_title, myBook.SeriesTitle); final float indexInSeries = myBook.IndexInSeries; if (indexInSeries > 0) { final String seriesIndexString; if (Math.abs(indexInSeries - Math.round(indexInSeries)) < 0.01) { seriesIndexString = String.valueOf(Math.round(indexInSeries)); } else { seriesIndexString = String.format("%.1f", indexInSeries); } setPairValueText(R.id.network_book_series_index, seriesIndexString); findViewById(R.id.network_book_series_index).setVisibility(View.VISIBLE); } else { findViewById(R.id.network_book_series_index).setVisibility(View.GONE); } } else { findViewById(R.id.network_book_series_title).setVisibility(View.GONE); findViewById(R.id.network_book_series_index).setVisibility(View.GONE); } if (myBook.Tags.size() > 0) { findViewById(R.id.network_book_tags).setVisibility(View.VISIBLE); final StringBuilder tagsText = new StringBuilder(); for (String tag : myBook.Tags) { if (tagsText.length() > 0) { tagsText.append(", "); } tagsText.append(tag); } setPairValueText(R.id.network_book_tags, tagsText); } else { findViewById(R.id.network_book_tags).setVisibility(View.GONE); } setPairValueText(R.id.network_book_catalog, myBook.Link.getTitle()); } private final void setupCover() { final View rootView = findViewById(R.id.network_book_root); final ImageView coverView = (ImageView)findViewById(R.id.network_book_cover); final DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); final int maxHeight = metrics.heightPixels * 2 / 3; final int maxWidth = maxHeight * 2 / 3; Bitmap coverBitmap = null; final ZLImage cover = NetworkTree.createCover(myBook); if (cover != null) { ZLAndroidImageData data = null; final ZLAndroidImageManager mgr = (ZLAndroidImageManager)ZLAndroidImageManager.Instance(); if (cover instanceof ZLLoadableImage) { final ZLLoadableImage img = (ZLLoadableImage)cover; img.startSynchronization(new Runnable() { public void run() { img.synchronizeFast(); final ZLAndroidImageData data = mgr.getImageData(img); if (data != null) { final Bitmap coverBitmap = data.getBitmap(maxWidth, maxHeight); if (coverBitmap != null) { coverView.setImageBitmap(coverBitmap); coverView.setVisibility(View.VISIBLE); rootView.invalidate(); rootView.requestLayout(); } } } }); } else { data = mgr.getImageData(cover); } if (data != null) { coverBitmap = data.getBitmap(maxWidth, maxHeight); } } if (coverBitmap != null) { coverView.setImageBitmap(coverBitmap); coverView.setVisibility(View.VISIBLE); } else { coverView.setVisibility(View.GONE); } } private final void setupButtons() { final ZLResource resource = NetworkLibrary.resource(); final int buttons[] = new int[] { R.id.network_book_button0, R.id.network_book_button1, R.id.network_book_button2, R.id.network_book_button3, }; final Set<NetworkBookActions.Action> actions = NetworkBookActions.getContextMenuActions(myBook, myConnection); final boolean skipSecondButton = actions.size() < buttons.length && actions.size() % 2 == 1; int buttonNumber = 0; for (final NetworkBookActions.Action a : actions) { if (skipSecondButton && buttonNumber == 1) { ++buttonNumber; } if (buttonNumber >= buttons.length) { break; } final String text; if (a.Arg == null) { text = resource.getResource(a.Key).getValue(); } else { text = resource.getResource(a.Key).getValue().replace("%s", a.Arg); } final int buttonId = buttons[buttonNumber++]; TextView button = (TextView)findViewById(buttonId); button.setText(text); button.setVisibility(View.VISIBLE); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { NetworkBookActions.runActionStatic(NetworkBookInfoActivity.this, myBook, a.Id); NetworkBookInfoActivity.this.updateView(); } }); button.setEnabled(a.Id != NetworkTreeActions.TREE_NO_ACTION); } findViewById(R.id.network_book_left_spacer).setVisibility(skipSecondButton ? View.VISIBLE : View.GONE); findViewById(R.id.network_book_right_spacer).setVisibility(skipSecondButton ? View.VISIBLE : View.GONE); if (skipSecondButton) { final int buttonId = buttons[1]; View button = findViewById(buttonId); button.setVisibility(View.GONE); button.setOnClickListener(null); } while (buttonNumber < buttons.length) { final int buttonId = buttons[buttonNumber++]; View button = findViewById(buttonId); button.setVisibility(View.GONE); button.setOnClickListener(null); } } private void updateView() { setupButtons(); final View rootView = findViewById(R.id.network_book_root); rootView.invalidate(); rootView.requestLayout(); } @Override protected void onStart() { super.onStart(); NetworkView.Instance().addEventListener(this); } @Override protected void onStop() { NetworkView.Instance().removeEventListener(this); super.onStop(); } public void onModelChanged() { runOnUiThread(new Runnable() { public void run() { updateView(); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case NetworkBaseActivity.CUSTOM_AUTHENTICATION_CODE: Util.processCustomAuthentication(this, myBook.Link, resultCode, data); break; case NetworkBaseActivity.SIGNUP_CODE: Util.processSignup(myBook.Link, resultCode, data); break; } } }