package com.newsrob.activities;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Animation.AnimationListener;
import android.widget.AbsoluteLayout;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.newsrob.DBQuery;
import com.newsrob.DashboardListActivity;
import com.newsrob.EntryManager;
import com.newsrob.IEntryModelUpdateListener;
import com.newsrob.NewsRob;
import com.newsrob.PL;
import com.newsrob.jobs.ClearModelSucceeded;
import com.newsrob.jobs.EntryUpdateSucceeded;
import com.newsrob.jobs.Job;
import com.newsrob.jobs.ModelUpdateResult;
import com.newsrob.jobs.SynchronizeModelSucceeded;
import com.newsrob.storage.SdCardStorageAdapter;
import com.newsrob.threetosix.R;
import com.newsrob.util.FlurryUtil;
import com.newsrob.util.GoogleAdsUtil;
import com.newsrob.util.SDKVersionUtil;
import com.newsrob.util.Timing;
import com.newsrob.util.U;
public abstract class AbstractNewsRobListActivity extends ListActivity implements IEntryModelUpdateListener,
View.OnLongClickListener {
private static final String TAG = AbstractNewsRobListActivity.class.getSimpleName();
private static final int MENU_ITEM_REFRESH_ID = 1;
private static final int MENU_ITEM_SETTINGS_ID = 2;
private static final int MENU_ITEM_CLEAR_CACHE_ID = 3;
private static final int MENU_ITEM_LOGOUT_ID = 4;
private static final int MENU_ITEM_HIDE_ID = 5;
private static final int MENU_ITEM_CANCEL_ID = 6;
protected static final int MENU_ITEM_MARK_ALL_READ_ID = 7;
protected static final int MENU_ITEM_MANAGE_FEED_ID = 8;
protected static final int MENU_ITEM_SUBSCRIBE_FEED_ID = 15;
protected static final int MENU_ITEM_SEARCH_ID = 9;
protected static final int MENU_ITEM_FAQ_ID = 10;
protected static final int MENU_ITEM_TOGGLE_THEME_ID = 11;
protected static final int MENU_ITEM_SORT_ID = 17;
protected static final int MENU_ITEM_SHOW_FILTER_ID = 18;
private static final int DIALOG_SD_CARD_ADVISABLE_ID = 0;
private static final int DIALOG_CLEAR_CACHE = 1;
private static final int DIALOG_SHOW_FILTER_INFO_ID = 2;
static final int MENU_ITEM_BUY_NEWSROB_PRO = 199;
Handler handler = new Handler();
private EntryManager entryManager;
private Runnable refreshUIRunnable;
private int positionOfSelectedItemOnLongPress;
private ImageButton refreshButton;
private ImageButton showHideButton;
private ImageButton markAllReadButton;
private ImageButton toggleOrderButton;
private int currentTheme;
private String currentActionBarLocation;
private View progressIndicator;
private ProgressBar progressBar;
private TextView progressDescription;
private LinearLayout progressContainer;
private GoogleAdsUtil googleAdsUtil;
protected SharedPreferences getSharedPreferences() {
return getEntryManager().getSharedPreferences();
}
protected EntryManager getEntryManager() {
if (entryManager == null)
entryManager = EntryManager.getInstance(this);
return entryManager;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
getEntryManager();
setTheme(getEntryManager().getCurrentThemeResourceId());
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
requestWindowFeature(Window.FEATURE_NO_TITLE);
googleAdsUtil = new GoogleAdsUtil(entryManager);
/*
* WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
* lp.copyFrom(getWindow().getAttributes()); lp.format =
* PixelFormat.RGBA_8888; getWindow().setAttributes(lp);
*/
// setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
super.onCreate(savedInstanceState);
/*
* if ("com.newsrob.VIEW".equals(getIntent().getAction())) { Intent i =
* new Intent(this, ShowArticleActivity.class); i.putExtra("atomId",
* getIntent().getDataString()); startActivity(i); finish(); } else {
*/
refreshUIRunnable = new Runnable() {
public void run() {
refreshUI();
}
};
getEntryManager().updateLastUsed();
if (NewsRob.isDebuggingEnabled(this))
PL.log("onCreate called on " + getClass().getSimpleName(), this);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
if (!shouldActionBarBeHidden()) {
findViewById(R.id.control_panel_stub).setVisibility(View.VISIBLE);
setupButtons();
}
// getLayoutInflater().inflate(R.layout.control_panel, parent);
final ViewGroup parent = (ViewGroup) findViewById(R.id.ad_parent);
final View controlPanel = findViewById(R.id.control_panel);
final View statusBar = findViewById(R.id.status_bar);
if (EntryManager.ACTION_BAR_BOTTOM.equals(getEntryManager().getActionBarLocation())) {
// put the toolbar at the bottom
parent.removeView(controlPanel);
parent.addView(controlPanel);
// show the status bar
statusBar.setVisibility(View.VISIBLE);
} else if (shouldActionBarBeHidden()) {
// show the status bar
statusBar.setVisibility(View.VISIBLE);
if (controlPanel != null)
controlPanel.setVisibility(View.GONE);
}
// RelativeLayout.LayoutParams lp = new
// RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,
// LayoutParams.WRAP_CONTENT);
// lp.addRule(RelativeLayout.BELOW, R.id.action_bar)
if (!shouldActionBarBeHidden()) {
progressIndicator = findViewById(R.id.background_progress);
progressIndicator.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toggleProgressBarVisibility();
progressIndicator.postInvalidateDelayed(150);
}
});
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
progressDescription = (TextView) findViewById(R.id.status_text);
progressContainer = (LinearLayout) findViewById(R.id.progress_container);
boolean isLightTheme = getEntryManager().isLightColorSchemeSelected();
findViewById(com.newsrob.threetosix.R.id.control_panel).setBackgroundResource(
isLightTheme ? R.drawable.list_header_background : R.drawable.list_header_background_dark);
findViewById(R.id.action_bar).setBackgroundResource(
isLightTheme ? R.drawable.label_background : R.drawable.label_background_dark);
findViewById(R.id.status_bar).setBackgroundResource(
isLightTheme ? R.drawable.label_background : R.drawable.label_background_dark);
}
getListView().setOnCreateContextMenuListener(this);
signalBackgroundDataIsTurnedOffOrInAirplaneMode();
getEntryManager().showReleaseNotes();
currentTheme = getEntryManager().getCurrentThemeResourceId();
currentActionBarLocation = getEntryManager().getActionBarLocation();
if (SDKVersionUtil.getVersion() > 3) {
Drawable d = getResources().getDrawable(R.drawable.progress_small_white);
((ProgressBar) findViewById(R.id.progress_status_bar)).setIndeterminateDrawable(d);
}
TextView controlPanelText = (TextView) findViewById(R.id.control_panel_text);
if (controlPanelText != null) {
controlPanelText.setText(getDefaultControlPanelTitle());
controlPanelText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(AbstractNewsRobListActivity.this, getToastMessage(), Toast.LENGTH_LONG).show();
}
});
}
View newsRobLogo = findViewById(R.id.newsrob_logo);
if (newsRobLogo != null)
newsRobLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(AbstractNewsRobListActivity.this, "-> Home", Toast.LENGTH_SHORT).show();
Intent i = new Intent(AbstractNewsRobListActivity.this, DashboardListActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("skip", false);
finish();
startActivity(i);
}
});
googleAdsUtil.showAds(this);
if (getIntent().hasExtra("showProgress") && getIntent().getBooleanExtra("showProgress", false))
showProgressBar();
}
protected abstract CharSequence getToastMessage();
protected void toggleProgressBarVisibility() {
if (progressContainer.getVisibility() == View.VISIBLE)
hideProgressBar();
else
showProgressBar();
}
protected void showProgressBar() {
if (shouldActionBarBeHidden())
return;
getEntryManager().updateProgressReportBeenOpened();
Animation inAnimation = AnimationUtils.loadAnimation(this, R.anim.push_up_in);
progressContainer.setVisibility(View.VISIBLE);
progressContainer.startAnimation(inAnimation);
}
protected void hideProgressBar() {
if (shouldActionBarBeHidden())
return;
if (progressContainer == null)
return;
if (progressContainer.getVisibility() == View.GONE)
return;
Animation outAnimation = AnimationUtils.loadAnimation(this, R.anim.push_up_out);
progressContainer.startAnimation(outAnimation);
progressContainer.setVisibility(View.GONE);
}
/**
* Signal to the user that background data is turned off, if s/he has
* auto-sync enabled and this is the entry point (task root) Also signal if
* Airplane mode is on.
*/
private void signalBackgroundDataIsTurnedOffOrInAirplaneMode() {
if (getEntryManager().isAutoSyncEnabled()) {
long minutesSinceLastSignalling = (System.currentTimeMillis() - getEntryManager()
.getLastShownThatSyncIsNotPossible()) / 1000 / 60;
if (minutesSinceLastSignalling > 60) {
String message = null;
if (getEntryManager().isInAirplaneMode())
message = "You are in Airplane mode.\nSyncing and downloading of articles won't work.";
else if (!getEntryManager().isBackgroundDataEnabled())
message = "The 'Background Data' setting is turned off.\nNo auto-sync will occur. You can sync manually though.";
else if (!getEntryManager().isSystemwideSyncEnabled())
message = "The Android 'Auto-Sync' setting is turned off.\nNo auto-sync will occur. You can sync manually though.";
if (message != null) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
getEntryManager().updateLastShownThatSyncIsNotPossible();
}
}
}
}
protected void hideSortOrderToggle() {
if (shouldActionBarBeHidden())
return;
findViewById(R.id.toggle_order_button).setVisibility(View.GONE);
findViewById(R.id.toggle_order_divider).setVisibility(View.GONE);
}
private void setupButtons() {
if (shouldActionBarBeHidden())
return;
// In Progress Cancel Sync Button
Button cancelSyncButton = (Button) findViewById(R.id.cancel_sync);
if (cancelSyncButton != null) {
cancelSyncButton.setBackgroundResource(R.drawable.custom_button);
cancelSyncButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
entryManager.cancel();
}
});
}
refreshButton = (ImageButton) findViewById(R.id.refresh);
if (refreshButton == null)
return;
refreshButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if ("Refresh".equals(v.getTag())) {
requestRefresh();
Toast.makeText(AbstractNewsRobListActivity.this, "Refresh", Toast.LENGTH_SHORT).show();
}
}
});
showHideButton = (ImageButton) findViewById(R.id.show_hide_button);
showHideButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
requestToggleHideItems();
String toastText = getDbQuery().shouldHideReadItems() ? "Unread Articles only" : "All Articles";
Toast.makeText(AbstractNewsRobListActivity.this, toastText, Toast.LENGTH_SHORT).show();
}
});
markAllReadButton = (ImageButton) findViewById(R.id.mark_all_read_button);
markAllReadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AbstractNewsRobListActivity.this.instantiateMarkAllReadDialog();
}
});
toggleOrderButton = (ImageButton) findViewById(R.id.toggle_order_button);
toggleOrderButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
requestToggleSortOrder();
String toastText = getDbQuery().isSortOrderAscending() ? "Oldest first" : "Newest first";
Toast.makeText(AbstractNewsRobListActivity.this, toastText, Toast.LENGTH_SHORT).show();
}
});
updateButtons();
}
protected void updateButtons() {
if (EntryManager.ACTION_BAR_GONE.equals(getEntryManager().getActionBarLocation())) {
ProgressBar progressStatusBar = (ProgressBar) findViewById(R.id.progress_status_bar);
progressStatusBar.setVisibility(entryManager.isModelCurrentlyUpdated() ? View.VISIBLE : View.INVISIBLE);
}
if (shouldActionBarBeHidden())
return;
if (refreshButton == null)
setupButtons();
if (refreshButton == null)
return;
View cancelButton = (View) findViewById(R.id.cancel_sync);
if (cancelButton != null)
cancelButton.setEnabled(entryManager.isModelCurrentlyUpdated() && !entryManager.isCancelRequested());
refreshButton.setTag("Refresh");
refreshButton.setImageResource(R.drawable.gen_toolbar_icon_sync);
refreshButton.setEnabled(shouldRefreshButtonBeEnabled());
refreshButton.setFocusable(refreshButton.isEnabled());
DBQuery dbq = getDbQuery();
boolean shouldHideReadItems = dbq.shouldHideReadItems();
showHideButton.setImageResource(shouldHideReadItems ? R.drawable.gen_toolbar_icon_show
: R.drawable.gen_toolbar_icon_hide);
toggleOrderButton
.setImageResource(getDbQuery().isSortOrderAscending() ? R.drawable.gen_toolbar_icon_sort_order_ascending
: R.drawable.gen_toolbar_icon_sort_order_descending);
markAllReadButton.setEnabled(shouldMarkAllReadButtonBeEnabled());
markAllReadButton.setFocusable(markAllReadButton.isEnabled());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean result = super.onCreateOptionsMenu(menu);
// if the action bar is not shown the actions that would go into the bar
// need to be shown in the menu
if (EntryManager.ACTION_BAR_GONE.equals(getEntryManager().getActionBarLocation())) {
menu.add(0, MENU_ITEM_REFRESH_ID, 0, R.string.menu_refresh).setIcon(android.R.drawable.ic_menu_rotate)
.setShortcut('1', 'r');
menu.add(0, MENU_ITEM_CANCEL_ID, 0, R.string.menu_cancel).setIcon(
android.R.drawable.ic_menu_close_clear_cancel);
menu.add(0, MENU_ITEM_MARK_ALL_READ_ID, 0, R.string.menu_item_mark_all_read).setShortcut('3', 'm').setIcon(
android.R.drawable.ic_menu_agenda);
menu.add(0, MENU_ITEM_HIDE_ID, 0, "").setShortcut('4', 'h');
menu.add(0, MENU_ITEM_SORT_ID, 0, "").setShortcut('5', 'o')
.setIcon(android.R.drawable.ic_menu_sort_by_size);
}
/*
* menu.add(0, MENU_ITEM_SEARCH_ID, 0, R.string.menu_item_search)
* .setIcon(android.R.drawable.ic_search_category_default)
* .setAlphabeticShortcut(SearchManager.MENU_KEY);
*/
Intent intent = new Intent();
intent.setClass(this, SubscribeFeedActivity.class);
menu.add(0, MENU_ITEM_SUBSCRIBE_FEED_ID, 0, "Subscribe Feed").setIcon(android.R.drawable.ic_menu_add)
.setShortcut('4', 'f').setIntent(intent);
boolean isProVersion = getEntryManager().isProVersion();
if (isProVersion)
menu.add(0, MENU_ITEM_TOGGLE_THEME_ID, 0, R.string.menu_toggle_theme).setIcon(
android.R.drawable.ic_menu_slideshow).setShortcut('6', 't');
menu.add(0, MENU_ITEM_SETTINGS_ID, 0, R.string.menu_settings).setIcon(android.R.drawable.ic_menu_preferences)
.setShortcut('7', 's');
menu.add(0, MENU_ITEM_CLEAR_CACHE_ID, 0, R.string.menu_clear_cache).setIcon(android.R.drawable.ic_menu_delete)
.setShortcut('8', 'c');
menu.add(0, MENU_ITEM_LOGOUT_ID, 0, R.string.menu_logout).setIcon(android.R.drawable.ic_lock_power_off)
.setShortcut('9', 'l').setTitleCondensed("Logout");
if (NewsRob.isDebuggingEnabled(this))
menu.add(0, MENU_ITEM_SHOW_FILTER_ID, 99, "Show Filter (Debug)").setIcon(
android.R.drawable.ic_menu_info_details).setShortcut('8', 'c');
//
Uri uri = Uri.parse("http://bit.ly/nrfaq");
// Uri uri =
// Uri.parse("http://groups.google.com/group/newsrob/web/frequently-asked-questions");
menu.add(0, MENU_ITEM_FAQ_ID, 0, R.string.menu_faq).setIcon(android.R.drawable.ic_menu_help).setTitleCondensed(
"FAQ").setIntent(new Intent(Intent.ACTION_VIEW, uri));
if (!isProVersion && entryManager.isAndroidMarketInstalled()) {
final Intent viewIntent = new Intent(Intent.ACTION_VIEW);
viewIntent.setData(Uri.parse("market://details?id=" + EntryManager.PRO_PACKAGE_NAME));
menu.add(0, MENU_ITEM_BUY_NEWSROB_PRO, 30, "Buy NewsRob Pro!").setIntent(viewIntent).setTitleCondensed(
"Buy").setIcon(R.drawable.gen_auto_app_icon);
}
return result;
}
protected boolean shouldRefreshButtonBeEnabled() {
return getEntryManager().canRefresh();
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
boolean canRefresh = getEntryManager().canRefresh();
if (EntryManager.ACTION_BAR_GONE.equals(getEntryManager().getActionBarLocation())) {
menu.findItem(MENU_ITEM_REFRESH_ID).setEnabled(canRefresh);
menu.findItem(MENU_ITEM_MARK_ALL_READ_ID).setEnabled(shouldMarkAllReadButtonBeEnabled());
MenuItem hideMenuItem = menu.findItem(MENU_ITEM_HIDE_ID);
menu.findItem(MENU_ITEM_CANCEL_ID).setEnabled(
!getEntryManager().isCancelRequested() && getEntryManager().isModelCurrentlyUpdated());
if (getDbQuery().shouldHideReadItems()) {
hideMenuItem.setTitle("Show Read Articles");
hideMenuItem.setTitleCondensed("Show Read Articles");
hideMenuItem.setIcon(android.R.drawable.ic_lock_silent_mode_off);
} else {
hideMenuItem.setTitle("Hide Read Articles");
hideMenuItem.setTitleCondensed("Hide Read Articles"); // I18N
hideMenuItem.setIcon(android.R.drawable.ic_lock_silent_mode);
}
MenuItem sortMenuItem = menu.findItem(MENU_ITEM_SORT_ID);
if (getDbQuery().isSortOrderAscending()) {
sortMenuItem.setTitle("Newest first");
} else {
sortMenuItem.setTitle("Oldest first");
}
}
menu.findItem(MENU_ITEM_CLEAR_CACHE_ID).setEnabled(canRefresh);
menu.findItem(MENU_ITEM_LOGOUT_ID).setEnabled(!getEntryManager().needsSession() && canRefresh);
return super.onPrepareOptionsMenu(menu);
}
private boolean shouldActionBarBeHidden() {
return EntryManager.ACTION_BAR_GONE.equals(getEntryManager().getActionBarLocation());
}
protected boolean shouldMarkAllReadButtonBeEnabled() {
DBQuery dbq = new DBQuery(getDbQuery());
dbq.setShouldHideReadItemsWithoutUpdatingThePreference(true);
return getEntryManager().isMarkAllReadPossible(dbq);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// AdUtil.onConfigurationChanged(this, newConfig);
googleAdsUtil.showAds(this);
refreshUI();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ITEM_SETTINGS_ID:
if (false) {
Intent intent = new Intent();
intent.setClassName("com.newsrob", "com.newsrob.activities.ArticleListActivity");
intent.putExtra("FEED_URL", "xxx"); // http://www.spiegel.de/schlagzeilen/index.rss
startActivity(intent);
return true;
} else {
Intent i = new Intent().setClass(this, SettingsActivity.class);
this.startActivity(i);
return true;
}
case MENU_ITEM_CLEAR_CACHE_ID:
showConfirmationDialog("Clear the Cache?", new Runnable() {
@Override
public void run() {
getEntryManager().requestClearCache(handler);
}
});
return true;
case MENU_ITEM_LOGOUT_ID:
// final ProgressDialog dialog2 = ProgressDialog.show(this,
// U.t(this,
// R.string.logout_and_clear_cache_dialog_title), U.t(this,
// R.string.logout_and_clear_cache_dialog_message), true);
showConfirmationDialog("Logout and Clear Cache?", new Runnable() {
public void run() {
Log.d(TAG, "Logging out ...");
getEntryManager().logout();
getEntryManager().requestClearCache(handler);
// dialog2.dismiss();
}
});
return true;
case MENU_ITEM_HIDE_ID:
requestToggleHideItems();
return true;
case MENU_ITEM_REFRESH_ID:
requestRefresh();
// refreshButton.performClick();
return true;
case MENU_ITEM_CANCEL_ID:
getEntryManager().cancel();
return true;
case MENU_ITEM_MARK_ALL_READ_ID:
instantiateMarkAllReadDialog();
return true;
case MENU_ITEM_TOGGLE_THEME_ID:
getEntryManager().toggleTheme();
reopenIfThemeOrActionBarLocationChanged();
return true;
case MENU_ITEM_SORT_ID:
requestToggleSortOrder();
return true;
case MENU_ITEM_SEARCH_ID:
onSearchRequested();
return true;
case MENU_ITEM_SHOW_FILTER_ID:
showDialog(DIALOG_SHOW_FILTER_INFO_ID);
return true;
}
return super.onOptionsItemSelected(item);
}
protected void instantiateMarkAllReadDialog() {
instantiateMarkAllReadDialog(getDbQuery());
}
protected void requestToggleHideItems() {
getDbQuery().toggleHideItems();
modelUpdated();
}
protected void requestToggleSortOrder() {
getDbQuery().toggleSortOrder();
modelUpdated();
}
protected void requestRefresh() {
if (NewsRob.isDebuggingEnabled(this))
PL.log("User requested refresh manually.", this);
if (getEntryManager().needsSession())
this.startActivity(new Intent().setClass(this, LoginActivity.class));
else
getEntryManager().requestSynchronization(false);
}
protected void instantiateMarkAllReadDialog(DBQuery dbq) {
instantiateMarkAllReadDialog(dbq.getFilterLabel(), dbq.getFilterFeedId(), dbq.getStartDate(), dbq
.getDateLimit(), dbq.isSortOrderAscending(), dbq.getLimit());
}
protected void instantiateMarkAllReadDialog(final String filterLabel, final Long filterFeedId,
final long startDate, final long dateLimit, boolean sortDateAscending, int limit) {
final DBQuery dbq = new DBQuery(getEntryManager(), filterLabel, filterFeedId);
dbq.setStartDate(startDate);
dbq.setDateLimit(dateLimit);
dbq.setSortOrderAscending(sortDateAscending);
dbq.setShouldHideReadItemsWithoutUpdatingThePreference(true);
final long noOfArticlesMarkedAsRead = getEntryManager().getMarkAllReadCount(dbq);
final Runnable action = new Runnable() {
public void run() {
Toast.makeText(
AbstractNewsRobListActivity.this,
noOfArticlesMarkedAsRead + " article" + (noOfArticlesMarkedAsRead > 1 ? "s" : "")
+ " marked as read.", Toast.LENGTH_LONG).show();
if (getEntryManager().shouldHideReadItems())
getListView().setSelection(0);
getEntryManager().requestMarkAllAsRead(dbq);
}
};
if (noOfArticlesMarkedAsRead >= getEntryManager().getMarkAllReadConfirmationDialogThreshold()) {
boolean pl = noOfArticlesMarkedAsRead > 1;
String message = "Mark " + (pl ? "all " : "") + noOfArticlesMarkedAsRead + " article" + (pl ? "s" : "")
+ " read?";
showConfirmationDialog(message, action);
} else
action.run();
}
void showConfirmationDialog(String message, final Runnable action) {
AlertDialog dialog = new AlertDialog(this) {
};
dialog.setMessage(message);
dialog.setButton(getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
action.run();
}
});
dialog.setButton2(getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
dialog.setTitle("Please Confirm!");
dialog.setIcon(android.R.drawable.ic_dialog_alert);
dialog.show();
}
public boolean onLongClick(View v) {
try {
positionOfSelectedItemOnLongPress = getListView().getPositionForView(v);
if (positionOfSelectedItemOnLongPress > -1)
openContextMenu(getListView());
return true;
} catch (NullPointerException npe) {
//
}
return false;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
if (menuInfo != null && menuInfo instanceof AdapterView.AdapterContextMenuInfo) {
AdapterView.AdapterContextMenuInfo mi = (AdapterView.AdapterContextMenuInfo) menuInfo;
positionOfSelectedItemOnLongPress = mi.position;
}
if (positionOfSelectedItemOnLongPress > -1)
onCreateContextMenu(menu, v, menuInfo, positionOfSelectedItemOnLongPress);
super.onCreateContextMenu(menu, v, menuInfo);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
if (positionOfSelectedItemOnLongPress > -1 && onContextItemSelected(item, positionOfSelectedItemOnLongPress))
return true;
return super.onContextItemSelected(item);
}
protected abstract boolean onContextItemSelected(MenuItem item, int positionOfSelectedItemOnLongPress);
protected abstract void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo,
int positionOfSelectedItemOnLongPress);
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_SD_CARD_ADVISABLE_ID:
return new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setMessage(
R.string.advise_sdcard_read_only).setTitle(R.string.advise_sdcard_read_only_title)
.setPositiveButton(android.R.string.ok, null).create();
case DIALOG_CLEAR_CACHE:
ProgressDialog pd = new ProgressDialog(this);
pd.setTitle(R.string.clear_cache_dialog_title);
pd.setMessage(U.t(this, R.string.clear_cache_dialog_message));
pd.setIndeterminate(true);
return pd;
case DIALOG_SHOW_FILTER_INFO_ID:
return new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setMessage(
getDbQuery().toString()).setTitle("Current Filter").setPositiveButton(android.R.string.ok, null)
.create();
}
return super.onCreateDialog(id);
}
protected void deactivateProgressIndicator() {
if (progressIndicator == null)
return;
if (!shouldActionBarBeHidden()) {
progressIndicator.setVisibility(View.GONE);
if (refreshButton != null)
refreshButton.setVisibility(View.VISIBLE);
}
setTitle(getDefaultStatusBarTitle());
hideProgressBar();
}
public abstract String getDefaultStatusBarTitle();
public abstract String getDefaultControlPanelTitle();
protected void activateProgressIndicator() {
if (shouldActionBarBeHidden())
return;
if (progressIndicator != null)
progressIndicator.setVisibility(View.VISIBLE);
if (refreshButton != null)
refreshButton.setVisibility(View.GONE);
String status = "Backgroud Operation In Progress";
Job runningJob = entryManager.getCurrentRunningJob();
if (runningJob != null) {
status = runningJob.getJobDescription();
if (runningJob.isProgressMeassurable()) {
int[] progress = runningJob.getProgress();
int currentArticle = progress[0];
int allArticles = progress[1];
progressBar.setMax(allArticles);
progressBar.setProgress(currentArticle);
progressBar.setIndeterminate(false);
progressBar.setVisibility(View.VISIBLE);
status = runningJob.getJobDescription() + " (" + currentArticle + "/" + allArticles + ")";
} else {
progressBar.setMax(0);
progressBar.setProgress(0);
progressBar.setIndeterminate(true);
}
} else {
progressBar.setMax(0);
progressBar.setProgress(0);
progressBar.setIndeterminate(true);
}
progressDescription.setText(status);
// progressBar.set
/*
*
* Job runningJob = getEntryManager().getCurrentRunningJob(); if
* (runningJob == null) { setTitle(getDefaultStatusBarTitle()); return;
* }
*
* if (runningJob.isProgressMeassurable()) { int[] progress =
* runningJob.getProgress(); int currentArticle = progress[0]; int
* allArticles = progress[1]; setTitle(runningJob.getJobDescription() +
* " (" + currentArticle + "/" + allArticles + ")"); } else {
* setTitle(runningJob.getJobDescription()); }
*/
}
protected void refreshProgressBar() {
if (entryManager.getCurrentRunningJob() != null || entryManager.isModelCurrentlyUpdated())
activateProgressIndicator();
else
deactivateProgressIndicator();
}
public void modelUpdateFinished(final ModelUpdateResult result) {
handler.post(new Runnable() {
public void run() {
updateButtons();
deactivateProgressIndicator();
if (result instanceof SynchronizeModelSucceeded) {
SynchronizeModelSucceeded succeeded = (SynchronizeModelSucceeded) result;
if (succeeded.getNoOfEntriesUpdated() > 0)
refreshUI();
// Toast.makeText(AbstractNewsRobListActivity.this,
// succeeded.getMessage(),
// Toast.LENGTH_LONG).show(); // I18N
} else if (result instanceof ClearModelSucceeded) {
ClearModelSucceeded succeeded = (ClearModelSucceeded) result;
// Toast.makeText(AbstractNewsRobListActivity.this,
// succeeded.getMessage(),
// Toast.LENGTH_LONG).show(); // I18N
if (succeeded.noOfEntriesDeleted > 0)
refreshUI();
} else if (result instanceof EntryUpdateSucceeded) {
refreshUI();
} else {
refreshUI();
Toast.makeText(AbstractNewsRobListActivity.this, result.getMessage(), Toast.LENGTH_LONG).show(); // I18N
}
}
});
}
public void modelUpdateStarted(boolean fastSyncOnly) {
runOnUiThread(refreshUIRunnable);
if (!fastSyncOnly && EntryManager.ACTION_BAR_TOP.equals(entryManager.getActionBarLocation())
&& View.VISIBLE != progressContainer.getVisibility() && !entryManager.hasProgressReportBeenOpened()) {
refreshButton.postDelayed(new Runnable() {
@Override
public void run() {
Animation inAnimation = AnimationUtils.loadAnimation(AbstractNewsRobListActivity.this,
R.anim.bouncing);
final ImageView arrow = (ImageView) findViewById(R.id.bouncing_arrow);
final View hint = findViewById(R.id.show_open_progress_hint);
if (arrow != null) {
arrow.setImageResource(R.drawable.gen_arrow_up); // Cupcake
inAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
int[] loc = new int[2];
refreshButton.getLocationOnScreen(loc);
int y = (loc[0] + refreshButton.getWidth() / 2) - arrow.getWidth() / 2;
AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, y, 0);
arrow.setLayoutParams(lp);
// findViewById(R.id.list_parent).requestLayout();
arrow.setVisibility(View.VISIBLE);
hint.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
arrow.postDelayed(new Runnable() {
@Override
public void run() {
arrow.setVisibility(View.INVISIBLE);
hint.setVisibility(View.INVISIBLE);
}
}, 6000);
}
});
arrow.startAnimation(inAnimation);
}
}
}, 2500);
}
}
public void modelUpdated() {
final String className = getClass().getSimpleName();
new Thread(new Runnable() {
@Override
public void run() {
showDataUpdateProgressMonitor();
try {
Timing t = new Timing(className + "::modelUpdated", AbstractNewsRobListActivity.this);
Cursor newCursor = createCursorFromQuery(getDbQuery());
// force the cursor to be loaded,
// so
// that this needn't be done on the UI
// thread
newCursor.moveToFirst();
newCursor(newCursor, (CursorAdapter) getListAdapter());
runOnUiThread(refreshUIRunnable);
t.stop();
} finally {
hideDataUpdateProgressMonitor();
}
}
}).start();
runOnUiThread(refreshUIRunnable);
}
void showDataUpdateProgressMonitor() {
if (true)
return;
runOnUiThread(new Runnable() {
@Override
public void run() {
ProgressBar pb = (ProgressBar) findViewById(R.id.data_update_progress);
pb.setVisibility(View.VISIBLE);
}
});
}
void hideDataUpdateProgressMonitor() {
if (true)
return;
runOnUiThread(new Runnable() {
@Override
public void run() {
findViewById(R.id.data_update_progress).setVisibility(View.INVISIBLE);
}
});
}
void refreshUI() {
// ((BaseAdapter) getListAdapter()).notifyDataSetChanged(); // TODO what
// is
// this good
// for?
updateButtons();
updateControlPanelTitle();
refreshProgressBar();
}
public void statusUpdated() {
runOnUiThread(new Runnable() {
public void run() {
refreshProgressBar();
updateButtons();
}
});
}
@Override
protected void onPause() {
hideProgressBar();
getEntryManager().removeListener(this);
googleAdsUtil.hideAds(this);
UIHelper.pauseWebViews(this);
super.onPause();
}
@Override
protected void onResume() {
NewsRob.lastActivity = this;
super.onResume();
UIHelper.resumeWebViews(this);
getEntryManager().addListener(this);
if (!reopenIfThemeOrActionBarLocationChanged()) {
getDbQuery().updateShouldHideReadItems();
modelUpdated();
refreshUI(); // LATER Maybe I should maintain and check lastModified
// and
// conditionally do refreshUI();
checkIfSDCardAccessible();
// AdUtil.publishAd(this);
googleAdsUtil.showAds(this);
}
}
private void updateControlPanelTitle() {
TextView controlPanelTitle = (TextView) findViewById(R.id.control_panel_title);
controlPanelTitle.setText(getDefaultStatusBarTitle());
}
private boolean reopenIfThemeOrActionBarLocationChanged() {
if (currentTheme != getEntryManager().getCurrentThemeResourceId()
|| !getEntryManager().getActionBarLocation().equals(currentActionBarLocation)) {
finish();
PL.log("AbstractNewsRobListActivity. Change detected that makes a relaunch necessary.", this);
startActivity(getIntent());
return true;
}
return false;
}
private void checkIfSDCardAccessible() {
if (entryManager.getStorageAdapter() instanceof SdCardStorageAdapter)
if (isTaskRoot() && !entryManager.getStorageAdapter().canWrite())
showDialog(DIALOG_SD_CARD_ADVISABLE_ID);
}
protected void startShowEntryActivityForPosition(int position, DBQuery dbq) {
Intent i = new Intent(AbstractNewsRobListActivity.this, ShowArticleActivity.class);
i.putExtra(UIHelper.EXTRA_KEY_POSITION, position);
UIHelper.addExtrasFromDBQuery(i, dbq);
startActivity(i);
}
abstract protected DBQuery getDbQuery();
@Override
protected void onStart() {
super.onStart();
FlurryUtil.onStart(this);
}
@Override
protected void onStop() {
super.onStop();
FlurryUtil.onStop(this);
}
abstract protected Cursor createCursorFromQuery(DBQuery dbq);
/** This will run on the UI Thread */
protected void newCursor(final Cursor newCursor, final CursorAdapter adapter) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Timing t = new Timing(this.getClass().getSimpleName() + "::newCursor()",
AbstractNewsRobListActivity.this);
Timing t2 = new Timing("CursorAdapter::changeCursor", AbstractNewsRobListActivity.this);
Cursor existingCursor = adapter.getCursor();
adapter.changeCursor(newCursor);
t2.stop();
startManagingCursor(newCursor);
if (existingCursor != null) {
stopManagingCursor(existingCursor);
existingCursor.close();
}
t.stop();
}
});
}
}