/* * Copyright (C) 2010 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.ArrayList; import android.os.Bundle; import android.view.*; import android.widget.BaseAdapter; import android.content.Intent; import org.geometerplus.zlibrary.core.network.ZLNetworkException; import org.geometerplus.fbreader.network.NetworkTree; import org.geometerplus.fbreader.network.NetworkCatalogItem; import org.geometerplus.fbreader.network.tree.*; public class NetworkCatalogActivity extends NetworkBaseActivity implements UserRegistrationConstants { public static final String CATALOG_LEVEL_KEY = "org.geometerplus.android.fbreader.network.CatalogLevel"; public static final String CATALOG_KEY_KEY = "org.geometerplus.android.fbreader.network.CatalogKey"; private NetworkTree myTree; private String myCatalogKey; private boolean myInProgress; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); final NetworkView networkView = NetworkView.Instance(); if (!networkView.isInitialized()) { finish(); return; } final Intent intent = getIntent(); final int level = intent.getIntExtra(CATALOG_LEVEL_KEY, -1); if (level == -1) { throw new RuntimeException("Catalog's Level was not specified!!!"); } myCatalogKey = intent.getStringExtra(CATALOG_KEY_KEY); if (myCatalogKey == null) { throw new RuntimeException("Catalog's Key was not specified!!!"); } myTree = networkView.getOpenedTree(level); networkView.setOpenedActivity(myCatalogKey, this); setListAdapter(new CatalogAdapter()); getListView().invalidateViews(); setupTitle(); if (myTree instanceof NetworkCatalogTree && Util.isAccountRefillingSupported(this, ((NetworkCatalogTree)myTree).Item.Link)) { setDefaultTree(new RefillAccountTree((NetworkCatalogTree)myTree)); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case USER_REGISTRATION_REQUEST_CODE: if (myTree instanceof NetworkCatalogTree && resultCode == RESULT_OK && data != null) { try { Util.runAfterRegistration( ((NetworkCatalogTree)myTree).Item.Link.authenticationManager(), data ); } catch (ZLNetworkException e) { // TODO: show an error message } } break; } } private final void setupTitle() { String title = null; final NetworkView networkView = NetworkView.Instance(); if (networkView.isInitialized()) { final NetworkTreeActions actions = networkView.getActions(myTree); if (actions != null) { title = actions.getTreeTitle(myTree); } } if (title == null) { title = myTree.getName(); } setTitle(title); setProgressBarIndeterminateVisibility(myInProgress); } private static String getNetworkTreeKey(NetworkTree tree, boolean recursive) { if (tree instanceof NetworkCatalogTree) { return ((NetworkCatalogTree) tree).Item.URLByType.get(NetworkCatalogItem.URL_CATALOG); } else if (tree instanceof SearchItemTree) { return NetworkSearchActivity.SEARCH_RUNNABLE_KEY; } else if (recursive && tree.Parent instanceof NetworkTree) { if (tree instanceof NetworkAuthorTree || tree instanceof NetworkSeriesTree) { return getNetworkTreeKey((NetworkTree) tree.Parent, true); } } return null; } @Override public void onDestroy() { if (myTree != null && myCatalogKey != null && NetworkView.Instance().isInitialized()) { NetworkView.Instance().setOpenedActivity(myCatalogKey, null); } super.onDestroy(); } @Override public void onResume() { super.onResume(); } private final class CatalogAdapter extends BaseAdapter { private ArrayList<NetworkTree> mySpecialItems; public CatalogAdapter() { if (myTree instanceof NetworkCatalogRootTree) { final NetworkCatalogRootTree rootTree = (NetworkCatalogRootTree)myTree; mySpecialItems = new ArrayList<NetworkTree>(); if (Util.isAccountRefillingSupported(NetworkCatalogActivity.this, rootTree.Item.Link)) { mySpecialItems.add(new RefillAccountTree(rootTree)); } if (mySpecialItems.size() > 0) { mySpecialItems.trimToSize(); } else { mySpecialItems = null; } } } public final int getCount() { return myTree.subTrees().size() + ((mySpecialItems != null && !myInProgress) ? mySpecialItems.size() : 0); } public final NetworkTree getItem(int position) { if (position < 0) { return null; } if (position < myTree.subTrees().size()) { return (NetworkTree) myTree.subTrees().get(position); } if (myInProgress) { return null; } position -= myTree.subTrees().size(); if (mySpecialItems != null && position < mySpecialItems.size()) { return mySpecialItems.get(position); } return null; } public final long getItemId(int position) { return position; } public View getView(int position, View convertView, final ViewGroup parent) { final NetworkTree tree = getItem(position); return setupNetworkTreeItemView(convertView, parent, tree); } void onModelChanged() { notifyDataSetChanged(); if (mySpecialItems != null) { for (NetworkTree tree: mySpecialItems) { tree.invalidateChildren(); // call to update secondString } } } } @Override public void onModelChanged() { final NetworkView networkView = NetworkView.Instance(); final String key = getNetworkTreeKey(myTree, true); myInProgress = key != null && networkView.isInitialized() && networkView.containsItemsLoadingRunnable(key); getListView().invalidateViews(); /* * getListAdapter() always returns CatalogAdapter because onModelChanged() * can be called only after Activity's onStart() method (where NetworkView's * addEventListener() is called). Therefore CatalogAdapter will be set as * adapter in onCreate() method before any calls to onModelChanged(). */ ((CatalogAdapter) getListAdapter()).onModelChanged(); setupTitle(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { doStopLoading(); } return super.onKeyDown(keyCode, event); } private void doStopLoading() { final String key = getNetworkTreeKey(myTree, false); if (key != null && NetworkView.Instance().isInitialized()) { final ItemsLoadingRunnable runnable = NetworkView.Instance().getItemsLoadingRunnable(key); if (runnable != null) { runnable.interruptLoading(); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); return NetworkView.Instance().createOptionsMenu(menu, myTree); } @Override public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); return NetworkView.Instance().prepareOptionsMenu(this, menu, myTree); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (NetworkView.Instance().runOptionsMenu(this, item, myTree)) { return true; } return super.onOptionsItemSelected(item); } }