From ced80be1aea975b59db5a0e6dd14acb054e7910e Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 16 Sep 2012 13:25:28 +0400 Subject: [PATCH] initial --- AndroidManifest.xml | 29 +- res/layout-sw600dp-port/headlines.xml | 48 + res/layout-sw600dp/feeds.xml | 47 + res/layout-sw600dp/headlines.xml | 48 + res/layout/feeds.xml | 27 + res/layout/headlines.xml | 27 + res/layout/online.xml | 21 + ...es_menu.xml => headlines_context_menu.xml} | 0 res/menu/main_menu.xml | 35 - res/menu/online_menu.xml | 29 + src/org/fox/ttrss/ArticleEventListener.java | 9 + src/org/fox/ttrss/ArticleFragment.java | 4 +- src/org/fox/ttrss/ArticlePager.java | 8 +- src/org/fox/ttrss/CommonActivity.java | 11 + src/org/fox/ttrss/FeedCategoriesFragment.java | 76 +- src/org/fox/ttrss/FeedsActivity.java | 212 ++ src/org/fox/ttrss/FeedsEventListener.java | 5 + src/org/fox/ttrss/FeedsFragment.java | 57 +- src/org/fox/ttrss/HeadlinesActivity.java | 160 ++ src/org/fox/ttrss/HeadlinesEventListener.java | 14 + src/org/fox/ttrss/HeadlinesFragment.java | 166 +- src/org/fox/ttrss/MainActivity.java | 2313 ----------------- src/org/fox/ttrss/OnlineActivity.java | 526 ++++ src/org/fox/ttrss/OnlineServices.java | 32 - .../fox/ttrss/offline/OfflineActivity.java | 1523 ----------- .../ttrss/offline/OfflineArticleFragment.java | 238 -- .../ttrss/offline/OfflineArticlePager.java | 109 - .../ttrss/offline/OfflineDownloadService.java | 452 ---- .../OfflineFeedCategoriesFragment.java | 262 -- .../ttrss/offline/OfflineFeedsFragment.java | 306 --- .../offline/OfflineHeadlinesFragment.java | 527 ---- .../fox/ttrss/offline/OfflineServices.java | 22 - .../ttrss/offline/OfflineUploadService.java | 264 -- src/org/fox/ttrss/util/ApiRequest.java | 257 ++ src/org/fox/ttrss/util/ImageCacheService.java | 208 -- 35 files changed, 1711 insertions(+), 6361 deletions(-) create mode 100644 res/layout-sw600dp-port/headlines.xml create mode 100644 res/layout-sw600dp/feeds.xml create mode 100644 res/layout-sw600dp/headlines.xml create mode 100644 res/layout/feeds.xml create mode 100644 res/layout/headlines.xml create mode 100644 res/layout/online.xml rename res/menu/{headlines_menu.xml => headlines_context_menu.xml} (100%) create mode 100644 res/menu/online_menu.xml create mode 100644 src/org/fox/ttrss/ArticleEventListener.java create mode 100644 src/org/fox/ttrss/FeedsActivity.java create mode 100644 src/org/fox/ttrss/FeedsEventListener.java create mode 100644 src/org/fox/ttrss/HeadlinesActivity.java create mode 100644 src/org/fox/ttrss/HeadlinesEventListener.java delete mode 100644 src/org/fox/ttrss/MainActivity.java create mode 100644 src/org/fox/ttrss/OnlineActivity.java delete mode 100644 src/org/fox/ttrss/OnlineServices.java delete mode 100644 src/org/fox/ttrss/offline/OfflineActivity.java delete mode 100644 src/org/fox/ttrss/offline/OfflineArticleFragment.java delete mode 100644 src/org/fox/ttrss/offline/OfflineArticlePager.java delete mode 100644 src/org/fox/ttrss/offline/OfflineDownloadService.java delete mode 100644 src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java delete mode 100644 src/org/fox/ttrss/offline/OfflineFeedsFragment.java delete mode 100644 src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java delete mode 100644 src/org/fox/ttrss/offline/OfflineServices.java delete mode 100644 src/org/fox/ttrss/offline/OfflineUploadService.java create mode 100644 src/org/fox/ttrss/util/ApiRequest.java delete mode 100644 src/org/fox/ttrss/util/ImageCacheService.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 94bfd20c..e4e00753 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="100" + android:versionName="0.8.0" > - - - - @@ -40,6 +32,21 @@ android:label="@string/preferences" > + + + + + + + + + diff --git a/res/layout-sw600dp-port/headlines.xml b/res/layout-sw600dp-port/headlines.xml new file mode 100644 index 00000000..84d8d654 --- /dev/null +++ b/res/layout-sw600dp-port/headlines.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout-sw600dp/feeds.xml b/res/layout-sw600dp/feeds.xml new file mode 100644 index 00000000..1bc48b2b --- /dev/null +++ b/res/layout-sw600dp/feeds.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout-sw600dp/headlines.xml b/res/layout-sw600dp/headlines.xml new file mode 100644 index 00000000..1d9addbc --- /dev/null +++ b/res/layout-sw600dp/headlines.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/feeds.xml b/res/layout/feeds.xml new file mode 100644 index 00000000..c3f7be59 --- /dev/null +++ b/res/layout/feeds.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/headlines.xml b/res/layout/headlines.xml new file mode 100644 index 00000000..60c24b91 --- /dev/null +++ b/res/layout/headlines.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/online.xml b/res/layout/online.xml new file mode 100644 index 00000000..d94aa147 --- /dev/null +++ b/res/layout/online.xml @@ -0,0 +1,21 @@ + + + + + + + + \ No newline at end of file diff --git a/res/menu/headlines_menu.xml b/res/menu/headlines_context_menu.xml similarity index 100% rename from res/menu/headlines_menu.xml rename to res/menu/headlines_context_menu.xml diff --git a/res/menu/main_menu.xml b/res/menu/main_menu.xml index c6e49511..68625729 100644 --- a/res/menu/main_menu.xml +++ b/res/menu/main_menu.xml @@ -2,41 +2,6 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/org/fox/ttrss/ArticleEventListener.java b/src/org/fox/ttrss/ArticleEventListener.java new file mode 100644 index 00000000..688c10f1 --- /dev/null +++ b/src/org/fox/ttrss/ArticleEventListener.java @@ -0,0 +1,9 @@ +package org.fox.ttrss; + +public interface ArticleEventListener { + + void copyToClipboard(String content_url); + + boolean isSmallScreen(); + +} diff --git a/src/org/fox/ttrss/ArticleFragment.java b/src/org/fox/ttrss/ArticleFragment.java index c3d83dd0..18569670 100644 --- a/src/org/fox/ttrss/ArticleFragment.java +++ b/src/org/fox/ttrss/ArticleFragment.java @@ -44,7 +44,7 @@ public class ArticleFragment extends Fragment { private SharedPreferences m_prefs; private Article m_article; - private OnlineServices m_onlineServices; + private ArticleEventListener m_onlineServices; //private Article m_nextArticle; //private Article m_prevArticle; @@ -296,7 +296,7 @@ public class ArticleFragment extends Fragment { super.onAttach(activity); m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - m_onlineServices = (OnlineServices)activity; + m_onlineServices = (ArticleEventListener)activity; //m_article = m_onlineServices.getSelectedArticle(); } diff --git a/src/org/fox/ttrss/ArticlePager.java b/src/org/fox/ttrss/ArticlePager.java index 3027d61b..9818e08c 100644 --- a/src/org/fox/ttrss/ArticlePager.java +++ b/src/org/fox/ttrss/ArticlePager.java @@ -16,7 +16,7 @@ public class ArticlePager extends Fragment { private final String TAG = "ArticlePager"; private PagerAdapter m_adapter; - private OnlineServices m_onlineServices; + private HeadlinesEventListener m_onlineServices; private HeadlinesFragment m_hf; private Article m_article; @@ -85,7 +85,7 @@ public class ArticlePager extends Fragment { article.unread = false; m_onlineServices.saveArticleUnread(article); } - m_onlineServices.setSelectedArticle(article); + m_onlineServices.onArticleSelected(article, false); //Log.d(TAG, "Page #" + position + "/" + m_adapter.getCount()); @@ -104,8 +104,8 @@ public class ArticlePager extends Fragment { public void onAttach(Activity activity) { super.onAttach(activity); - m_hf = (HeadlinesFragment) getActivity().getSupportFragmentManager().findFragmentByTag(MainActivity.FRAG_HEADLINES); - m_onlineServices = (OnlineServices)activity; + m_hf = (HeadlinesFragment) getActivity().getSupportFragmentManager().findFragmentByTag(CommonActivity.FRAG_HEADLINES); + m_onlineServices = (HeadlinesEventListener)activity; } } diff --git a/src/org/fox/ttrss/CommonActivity.java b/src/org/fox/ttrss/CommonActivity.java index d88775b3..9f67e49d 100644 --- a/src/org/fox/ttrss/CommonActivity.java +++ b/src/org/fox/ttrss/CommonActivity.java @@ -9,6 +9,7 @@ import android.util.DisplayMetrics; import android.util.FloatMath; import android.util.Log; import android.view.Display; +import android.widget.TextView; import android.widget.Toast; public class CommonActivity extends FragmentActivity { @@ -31,6 +32,16 @@ public class CommonActivity extends FragmentActivity { m_smallScreenMode = smallScreen; } + protected void setLoadingStatus(int status, boolean showProgress) { + TextView tv = (TextView) findViewById(R.id.loading_message); + + if (tv != null) { + tv.setText(status); + } + + setProgressBarIndeterminateVisibility(showProgress); + } + public void toast(int msgId) { Toast toast = Toast.makeText(CommonActivity.this, msgId, Toast.LENGTH_SHORT); toast.show(); diff --git a/src/org/fox/ttrss/FeedCategoriesFragment.java b/src/org/fox/ttrss/FeedCategoriesFragment.java index 055659ca..9af914b9 100644 --- a/src/org/fox/ttrss/FeedCategoriesFragment.java +++ b/src/org/fox/ttrss/FeedCategoriesFragment.java @@ -7,6 +7,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; +import org.fox.ttrss.types.Feed; import org.fox.ttrss.types.FeedCategory; import org.fox.ttrss.types.FeedCategoryList; @@ -17,9 +18,11 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v4.app.Fragment; +import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; @@ -42,7 +45,7 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe private FeedCategoryListAdapter m_adapter; private FeedCategoryList m_cats = new FeedCategoryList(); private FeedCategory m_selectedCat; - private OnlineServices m_onlineServices; + private FeedsActivity m_activity; class CatUnreadComparator implements Comparator { @Override @@ -82,6 +85,45 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe } + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo) item + .getMenuInfo(); + + switch (item.getItemId()) { + case R.id.browse_articles: + if (true) { + FeedCategory cat = getCategoryAtPosition(info.position); + if (cat != null) { + m_activity.onCatSelected(cat, true); + //setSelectedCategory(cat); + } + } + return true; + case R.id.browse_feeds: + if (true) { + FeedCategory cat = getCategoryAtPosition(info.position); + if (cat != null) { + m_activity.onCatSelected(cat, false); + //cf.setSelectedCategory(cat); + } + } + return true; + case R.id.catchup_category: + if (true) { + FeedCategory cat = getCategoryAtPosition(info.position); + if (cat != null) { + m_activity.catchupFeed(new Feed(cat.id, cat.title, true)); + } + } + return true; + + default: + Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); + return super.onContextItemSelected(item); + } + } + @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { @@ -117,11 +159,6 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe list.setOnItemClickListener(this); registerForContextMenu(list); - if (m_cats == null || m_cats.size() == 0) - refresh(false); - else - getActivity().setProgressBarIndeterminateVisibility(false); - return view; } @@ -129,11 +166,20 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe public void onAttach(Activity activity) { super.onAttach(activity); - m_onlineServices = (OnlineServices)activity; + m_activity = (FeedsActivity)activity; m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); m_prefs.registerOnSharedPreferenceChangeListener(this); + + } + + @Override + public void onResume() { + super.onResume(); + refresh(false); + + m_activity.initMenu(); } @Override @@ -161,8 +207,8 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe public void refresh(boolean background) { CatsRequest req = new CatsRequest(getActivity().getApplicationContext()); - final String sessionId = m_onlineServices.getSessionId(); - final boolean unreadOnly = m_onlineServices.getUnreadOnly(); + final String sessionId = m_activity.getSessionId(); + final boolean unreadOnly = m_activity.getUnreadOnly(); if (sessionId != null) { @@ -205,7 +251,7 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe m_cats.clear(); - int apiLevel = m_onlineServices.getApiLevel(); + int apiLevel = m_activity.getApiLevel(); // virtual cats implemented in getCategories since api level 1 if (apiLevel == 0) { @@ -233,7 +279,7 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe } if (m_lastError == ApiError.LOGIN_FAILED) { - m_onlineServices.login(); + m_activity.login(); } else { setLoadingStatus(getErrorMessage(), false); } @@ -247,7 +293,7 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe if (m_prefs.getBoolean("sort_feeds_by_unread", false)) { cmp = new CatUnreadComparator(); } else { - if (m_onlineServices.getApiLevel() >= 3) { + if (m_activity.getApiLevel() >= 3) { cmp = new CatOrderComparator(); } else { cmp = new CatTitleComparator(); @@ -280,7 +326,7 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe public int getItemViewType(int position) { FeedCategory cat = items.get(position); - if (!m_onlineServices.isSmallScreen() && m_selectedCat != null && cat.id == m_selectedCat.id) { + if (!m_activity.isSmallScreen() && m_selectedCat != null && cat.id == m_selectedCat.id) { return VIEW_SELECTED; } else { return VIEW_NORMAL; @@ -344,9 +390,9 @@ public class FeedCategoriesFragment extends Fragment implements OnItemClickListe if (list != null) { FeedCategory cat = (FeedCategory)list.getItemAtPosition(position); - m_onlineServices.onCatSelected(cat); + m_activity.onCatSelected(cat); - if (!m_onlineServices.isSmallScreen()) + if (!m_activity.isSmallScreen()) m_selectedCat = cat; m_adapter.notifyDataSetChanged(); diff --git a/src/org/fox/ttrss/FeedsActivity.java b/src/org/fox/ttrss/FeedsActivity.java new file mode 100644 index 00000000..5cc1d176 --- /dev/null +++ b/src/org/fox/ttrss/FeedsActivity.java @@ -0,0 +1,212 @@ +package org.fox.ttrss; + +import java.util.HashMap; + +import org.fox.ttrss.types.Article; +import org.fox.ttrss.types.ArticleList; +import org.fox.ttrss.types.Feed; +import org.fox.ttrss.types.FeedCategory; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; + +public class FeedsActivity extends OnlineActivity implements HeadlinesEventListener, ArticleEventListener { + private final String TAG = this.getClass().getSimpleName(); + + protected SharedPreferences m_prefs; + + private boolean m_unreadOnly = true; + private boolean m_unreadArticlesOnly = true; + + @Override + public void onCreate(Bundle savedInstanceState) { + m_prefs = PreferenceManager + .getDefaultSharedPreferences(getApplicationContext()); + + if (m_prefs.getString("theme", "THEME_DARK").equals("THEME_DARK")) { + setTheme(R.style.DarkTheme); + } else { + setTheme(R.style.LightTheme); + } + + super.onCreate(savedInstanceState); + + setContentView(R.layout.feeds); + + setSmallScreen(findViewById(R.id.headlines_fragment) == null); + + if (savedInstanceState == null) { + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + + if (m_prefs.getBoolean("enable_cats", false)) { + ft.replace(R.id.feeds_fragment, new FeedCategoriesFragment(), FRAG_CATS); + } else { + ft.replace(R.id.feeds_fragment, new FeedsFragment(), FRAG_FEEDS); + } + + ft.commit(); + } else if (isSmallScreen()) { + Fragment frag = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + if (frag != null) { + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + ft.remove(frag); + ft.commit(); + } + } + } + + public boolean getUnreadOnly() { + return m_unreadOnly; + } + + @Override + protected void initMenu() { + super.initMenu(); + if (m_menu != null) { + Fragment ff = getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); + Fragment cf = getSupportFragmentManager().findFragmentByTag(FRAG_CATS); + Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + + m_menu.setGroupVisible(R.id.menu_group_feeds, ff != null || cf != null); + + m_menu.setGroupVisible(R.id.menu_group_article, af != null); + + HeadlinesFragment hf = (HeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); + + m_menu.setGroupVisible(R.id.menu_group_headlines, hf != null && hf.getSelectedArticles().size() == 0); + m_menu.setGroupVisible(R.id.menu_group_headlines_selection, hf != null && hf.getSelectedArticles().size() != 0); + } + } + + + public void onFeedSelected(Feed feed) { + FragmentTransaction ft = getSupportFragmentManager() + .beginTransaction(); + + HeadlinesFragment hf = new HeadlinesFragment(feed); + + if (isSmallScreen()) { + ft.replace(R.id.feeds_fragment, hf, FRAG_HEADLINES); + ft.addToBackStack(null); + } else { + ft.replace(R.id.headlines_fragment, hf, FRAG_HEADLINES); + } + ft.commit(); + } + + public void onCatSelected(FeedCategory cat, boolean openAsFeed) { + + FragmentTransaction ft = getSupportFragmentManager() + .beginTransaction(); + + if (!openAsFeed) { + FeedsFragment ff = new FeedsFragment(cat); + + ft.replace(R.id.feeds_fragment, ff, FRAG_FEEDS); + } else { + Feed feed = new Feed(cat.id, cat.title, true); + onFeedSelected(feed); + } + + ft.addToBackStack(null); + + ft.commit(); + } + + public void onCatSelected(FeedCategory cat) { + onCatSelected(cat, m_prefs.getBoolean("browse_cats_like_feeds", false)); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + default: + Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId()); + return super.onOptionsItemSelected(item); + } + } + + @Override + protected void loginSuccess() { + setLoadingStatus(R.string.blank, false); + findViewById(R.id.loading_container).setVisibility(View.GONE); + + } + + @Override + public void onSaveInstanceState(Bundle out) { + super.onSaveInstanceState(out); + + } + + @Override + public void onResume() { + super.onResume(); + } + + @Override + public boolean getUnreadArticlesOnly() { + return m_unreadArticlesOnly; + } + + @Override + public void onArticleListSelectionChange(ArticleList m_selectedArticles) { + initMenu(); + } + + public void onArticleSelected(Article article, boolean open) { + if (article.unread) { + article.unread = false; + saveArticleUnread(article); + } + + if (open) { + if (isSmallScreen()) { + FragmentTransaction ft = getSupportFragmentManager() + .beginTransaction(); + + Fragment frag = new ArticlePager(article); + + ft.hide(getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES)); + ft.add(R.id.feeds_fragment, frag, FRAG_ARTICLE); + ft.addToBackStack(null); + + ft.commit(); + } else { + Intent intent = new Intent(FeedsActivity.this, HeadlinesActivity.class); + intent.putExtra("sessionId", m_sessionId); + intent.putExtra("apiLevel", m_apiLevel); + + HeadlinesFragment hf = (HeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); + + intent.putExtra("feed", hf.getFeed()); + intent.putParcelableArrayListExtra("articles", hf.getAllArticles()); + intent.putExtra("activeArticle", article); + intent.putExtra("article", article); + + //intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + + startActivityForResult(intent, 0); + } + } else { + HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); + if (hf != null) hf.setActiveArticle(article); + } + } + + @Override + public void onArticleSelected(Article article) { + onArticleSelected(article, true); + } + +} diff --git a/src/org/fox/ttrss/FeedsEventListener.java b/src/org/fox/ttrss/FeedsEventListener.java new file mode 100644 index 00000000..8e6b7bce --- /dev/null +++ b/src/org/fox/ttrss/FeedsEventListener.java @@ -0,0 +1,5 @@ +package org.fox.ttrss; + +public interface FeedsEventListener { + +} diff --git a/src/org/fox/ttrss/FeedsFragment.java b/src/org/fox/ttrss/FeedsFragment.java index 030005fe..1153172c 100644 --- a/src/org/fox/ttrss/FeedsFragment.java +++ b/src/org/fox/ttrss/FeedsFragment.java @@ -45,6 +45,7 @@ import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; @@ -65,7 +66,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh private SharedPreferences m_prefs; private FeedListAdapter m_adapter; private FeedList m_feeds = new FeedList(); - private OnlineServices m_onlineServices; + private FeedsActivity m_activity; private Feed m_selectedFeed; private FeedCategory m_activeCategory; private static final String ICON_PATH = "/data/org.fox.ttrss/icons/"; @@ -120,6 +121,26 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh } } + + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo) item + .getMenuInfo(); + switch (item.getItemId()) { + case R.id.catchup_feed: + if (true) { + Feed feed = getFeedAtPosition(info.position); + if (feed != null) { + m_activity.catchupFeed(feed); + } + } + return true; + + default: + Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); + return super.onContextItemSelected(item); + } + } @Override public void onCreateContextMenu(ContextMenu menu, View v, @@ -159,11 +180,6 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh m_enableFeedIcons = m_prefs.getBoolean("download_feed_icons", false); - if (m_feeds == null || m_feeds.size() == 0) - refresh(false); - else - getActivity().setProgressBarIndeterminateVisibility(false); - return view; } @@ -179,11 +195,18 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); m_prefs.registerOnSharedPreferenceChangeListener(this); - m_onlineServices = (OnlineServices)activity; - - //m_selectedFeed = m_onlineServices.getActiveFeed(); + m_activity = (FeedsActivity)activity; } + @Override + public void onResume() { + super.onResume(); + + refresh(false); + + m_activity.initMenu(); + } + @Override public void onSaveInstanceState (Bundle out) { super.onSaveInstanceState(out); @@ -200,9 +223,9 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh if (list != null) { Feed feed = (Feed)list.getItemAtPosition(position); - m_onlineServices.onFeedSelected(feed); + m_activity.onFeedSelected(feed); - if (!m_onlineServices.isSmallScreen()) + if (!m_activity.isSmallScreen()) m_selectedFeed = feed; m_adapter.notifyDataSetChanged(); @@ -215,8 +238,8 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh final int catId = (m_activeCategory != null) ? m_activeCategory.id : -4; - final String sessionId = m_onlineServices.getSessionId(); - final boolean unreadOnly = m_onlineServices.getUnreadOnly(); + final String sessionId = m_activity.getSessionId(); + final boolean unreadOnly = m_activity.getUnreadOnly(); FeedsRequest req = new FeedsRequest(getActivity().getApplicationContext(), catId); @@ -292,7 +315,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh } }; - final String sessionId = m_onlineServices.getSessionId(); + final String sessionId = m_activity.getSessionId(); HashMap map = new HashMap() { { @@ -347,7 +370,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh } if (m_lastError == ApiError.LOGIN_FAILED) { - m_onlineServices.login(); + m_activity.login(); } else { setLoadingStatus(getErrorMessage(), false); } @@ -375,7 +398,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh public int getItemViewType(int position) { Feed feed = items.get(position); - if (!m_onlineServices.isSmallScreen() && m_selectedFeed != null && feed.id == m_selectedFeed.id) { + if (!m_activity.isSmallScreen() && m_selectedFeed != null && feed.id == m_selectedFeed.id) { return VIEW_SELECTED; } else { return VIEW_NORMAL; @@ -449,7 +472,7 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh if (m_prefs.getBoolean("sort_feeds_by_unread", false)) { cmp = new FeedUnreadComparator(); } else { - if (m_onlineServices.getApiLevel() >= 3) { + if (m_activity.getApiLevel() >= 3) { cmp = new FeedOrderComparator(); } else { cmp = new FeedTitleComparator(); diff --git a/src/org/fox/ttrss/HeadlinesActivity.java b/src/org/fox/ttrss/HeadlinesActivity.java new file mode 100644 index 00000000..dd2a5a8c --- /dev/null +++ b/src/org/fox/ttrss/HeadlinesActivity.java @@ -0,0 +1,160 @@ +package org.fox.ttrss; + +import java.util.ArrayList; + +import org.fox.ttrss.types.Article; +import org.fox.ttrss.types.ArticleList; +import org.fox.ttrss.types.Feed; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; + +public class HeadlinesActivity extends OnlineActivity implements HeadlinesEventListener, ArticleEventListener { +private final String TAG = this.getClass().getSimpleName(); + + protected SharedPreferences m_prefs; + + @Override + public void onCreate(Bundle savedInstanceState) { + m_prefs = PreferenceManager + .getDefaultSharedPreferences(getApplicationContext()); + + if (m_prefs.getString("theme", "THEME_DARK").equals("THEME_DARK")) { + setTheme(R.style.DarkTheme); + } else { + setTheme(R.style.LightTheme); + } + + super.onCreate(savedInstanceState); + + setContentView(R.layout.headlines); + + if (!isCompatMode()) { + getActionBar().setDisplayHomeAsUpEnabled(true); + } + + setSmallScreen(findViewById(R.id.headlines_fragment) == null); + + if (savedInstanceState == null) { + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + + Intent i = getIntent(); + + if (i.getExtras() != null) { + Feed feed = i.getParcelableExtra("feed"); + Article activeArticle = i.getParcelableExtra("activeArticle"); + Article article = i.getParcelableExtra("article"); + + ArrayList
alist = i.getParcelableArrayListExtra("articles"); + ArticleList articles = new ArticleList(); + + for (Article a : alist) + articles.add(a); + + HeadlinesFragment hf = new HeadlinesFragment(feed, activeArticle, articles); + + ft.replace(R.id.headlines_fragment, hf, FRAG_HEADLINES); + + ArticlePager af = new ArticlePager(article); + + ft.replace(R.id.article_fragment, af, FRAG_ARTICLE); + } + + ft.commit(); + } + } + + @Override + protected void loginSuccess() { + Log.d(TAG, "loginSuccess"); + + setLoadingStatus(R.string.blank, false); + findViewById(R.id.loading_container).setVisibility(View.GONE); + + } + + @Override + public void onSaveInstanceState(Bundle out) { + super.onSaveInstanceState(out); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + default: + Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId()); + return super.onOptionsItemSelected(item); + } + } + + @Override + public void onResume() { + super.onResume(); + } + + @Override + public boolean getUnreadArticlesOnly() { + // TODO Auto-generated method stub + return true; + } + + @Override + protected void initMenu() { + super.initMenu(); + + if (m_menu != null) { + m_menu.setGroupVisible(R.id.menu_group_feeds, false); + + HeadlinesFragment hf = (HeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); + + m_menu.setGroupVisible(R.id.menu_group_headlines, hf != null && hf.getSelectedArticles().size() == 0); + m_menu.setGroupVisible(R.id.menu_group_headlines_selection, hf != null && hf.getSelectedArticles().size() != 0); + + Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + + m_menu.setGroupVisible(R.id.menu_group_article, af != null); + } + } + + @Override + public void onArticleListSelectionChange(ArticleList m_selectedArticles) { + initMenu(); + } + + @Override + public void onArticleSelected(Article article) { + onArticleSelected(article, true); + } + + @Override + public void onArticleSelected(Article article, boolean open) { + + if (open) { + FragmentTransaction ft = getSupportFragmentManager() + .beginTransaction(); + + Fragment frag = new ArticlePager(article); + + ft.replace(R.id.article_fragment, frag, FRAG_ARTICLE); + //ft.addToBackStack(null); + + ft.commit(); + } else { + HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); + if (hf != null) hf.setActiveArticle(article); + } + + } +} diff --git a/src/org/fox/ttrss/HeadlinesEventListener.java b/src/org/fox/ttrss/HeadlinesEventListener.java new file mode 100644 index 00000000..14f0ef92 --- /dev/null +++ b/src/org/fox/ttrss/HeadlinesEventListener.java @@ -0,0 +1,14 @@ +package org.fox.ttrss; + +import org.fox.ttrss.types.Article; +import org.fox.ttrss.types.ArticleList; + +public interface HeadlinesEventListener { + + boolean getUnreadArticlesOnly(); + void onArticleListSelectionChange(ArticleList m_selectedArticles); + void onArticleSelected(Article article); + void saveArticleUnread(Article article); + void onArticleSelected(Article article, boolean b); + +} diff --git a/src/org/fox/ttrss/HeadlinesFragment.java b/src/org/fox/ttrss/HeadlinesFragment.java index 4cb77858..9534db66 100644 --- a/src/org/fox/ttrss/HeadlinesFragment.java +++ b/src/org/fox/ttrss/HeadlinesFragment.java @@ -34,6 +34,7 @@ import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; @@ -70,14 +71,16 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, private boolean m_canLoadMore = false; private boolean m_combinedMode = true; private String m_searchQuery = ""; + private boolean m_noRefresh = false; private SharedPreferences m_prefs; private ArticleListAdapter m_adapter; private ArticleList m_articles = new ArticleList(); private ArticleList m_selectedArticles = new ArticleList(); + private HeadlinesEventListener m_listener; - private OnlineServices m_onlineServices; + private OnlineActivity m_activity; private ImageGetter m_dummyGetter = new ImageGetter() { @@ -87,7 +90,6 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } }; - public ArticleList getSelectedArticles() { return m_selectedArticles; } @@ -96,15 +98,125 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, m_feed = feed; } + public HeadlinesFragment(Feed feed, Article activeArticle, ArticleList articles) { + m_feed = feed; + m_activeArticle = activeArticle; + m_articles = articles; + m_noRefresh = true; + } + public HeadlinesFragment() { // } + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo) item + .getMenuInfo(); + + switch (item.getItemId()) { + case R.id.selection_toggle_marked: + if (true) { + ArticleList selected = getSelectedArticles(); + + if (selected.size() > 0) { + for (Article a : selected) + a.marked = !a.marked; + + m_activity.toggleArticlesMarked(selected); + //updateHeadlines(); + } else { + Article article = getArticleAtPosition(info.position); + if (article != null) { + article.marked = !article.marked; + m_activity.saveArticleMarked(article); + //updateHeadlines(); + } + } + m_adapter.notifyDataSetChanged(); + } + return true; + case R.id.selection_toggle_published: + if (true) { + ArticleList selected = getSelectedArticles(); + + if (selected.size() > 0) { + for (Article a : selected) + a.published = !a.published; + + m_activity.toggleArticlesPublished(selected); + //updateHeadlines(); + } else { + Article article = getArticleAtPosition(info.position); + if (article != null) { + article.published = !article.published; + m_activity.saveArticlePublished(article); + //updateHeadlines(); + } + } + m_adapter.notifyDataSetChanged(); + } + return true; + case R.id.selection_toggle_unread: + if (true) { + ArticleList selected = getSelectedArticles(); + + if (selected.size() > 0) { + for (Article a : selected) + a.unread = !a.unread; + + m_activity.toggleArticlesUnread(selected); + //updateHeadlines(); + } else { + Article article = getArticleAtPosition(info.position); + if (article != null) { + article.unread = !article.unread; + m_activity.saveArticleUnread(article); + //updateHeadlines(); + } + } + m_adapter.notifyDataSetChanged(); + } + return true; + case R.id.share_article: + if (true) { + Article article = getArticleAtPosition(info.position); + if (article != null) + m_activity.shareArticle(article); + } + return true; + case R.id.catchup_above: + if (true) { + Article article = getArticleAtPosition(info.position); + if (article != null) { + ArticleList articles = getAllArticles(); + ArticleList tmp = new ArticleList(); + for (Article a : articles) { + a.unread = false; + tmp.add(a); + if (article.id == a.id) + break; + } + if (tmp.size() > 0) { + m_activity.toggleArticlesUnread(tmp); + //updateHeadlines(); + } + } + m_adapter.notifyDataSetChanged(); + } + return true; + default: + Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); + return super.onContextItemSelected(item); + } + } + + @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - getActivity().getMenuInflater().inflate(R.menu.headlines_menu, menu); + getActivity().getMenuInflater().inflate(R.menu.headlines_context_menu, menu); if (m_selectedArticles.size() > 0) { menu.setHeaderTitle(R.string.headline_context_multiple); @@ -116,8 +228,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, menu.setGroupVisible(R.id.menu_group_single_article, true); } - menu.findItem(R.id.set_labels).setEnabled(m_onlineServices.getApiLevel() >= 1); - menu.findItem(R.id.article_set_note).setEnabled(m_onlineServices.getApiLevel() >= 1); + menu.findItem(R.id.set_labels).setEnabled(m_activity.getApiLevel() >= 1); + menu.findItem(R.id.article_set_note).setEnabled(m_activity.getApiLevel() >= 1); super.onCreateContextMenu(menu, v, menuInfo); @@ -146,24 +258,32 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, //list.setEmptyView(view.findViewById(R.id.no_headlines)); registerForContextMenu(list); - if (m_onlineServices.isSmallScreen() || m_onlineServices.isPortrait()) + if (m_activity.isSmallScreen() || m_activity.isPortrait()) view.findViewById(R.id.headlines_fragment).setPadding(0, 0, 0, 0); Log.d(TAG, "onCreateView, feed=" + m_feed); - if (m_feed != null && (m_articles == null || m_articles.size() == 0)) - refresh(false); - else - getActivity().setProgressBarIndeterminateVisibility(false); - return view; } + @Override + public void onResume() { + super.onResume(); + + if (!m_noRefresh) { + refresh(false); + m_noRefresh = false; + } + + m_activity.initMenu(); + } + @Override public void onAttach(Activity activity) { super.onAttach(activity); m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - m_onlineServices = (OnlineServices) activity; + m_activity = (OnlineActivity) activity; + m_listener = (HeadlinesEventListener) activity; m_combinedMode = m_prefs.getBoolean("combined_mode", false); } @@ -179,9 +299,9 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, if (article.id >= 0) { if (m_combinedMode) { article.unread = false; - m_onlineServices.saveArticleUnread(article); + m_activity.saveArticleUnread(article); } else { - m_onlineServices.onArticleSelected(article); + m_listener.onArticleSelected(article); } m_activeArticle = article; @@ -196,8 +316,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, HeadlinesRequest req = new HeadlinesRequest(getActivity().getApplicationContext()); - final String sessionId = m_onlineServices.getSessionId(); - final boolean showUnread = m_onlineServices.getUnreadArticlesOnly(); + final String sessionId = m_activity.getSessionId(); + final boolean showUnread = m_listener.getUnreadArticlesOnly(); final boolean isCat = m_feed.is_cat; int skip = 0; @@ -319,7 +439,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } if (m_lastError == ApiError.LOGIN_FAILED) { - m_onlineServices.login(); + m_activity.login(); } else { setLoadingStatus(getErrorMessage(), false); } @@ -428,7 +548,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, article.marked = !article.marked; m_adapter.notifyDataSetChanged(); - m_onlineServices.saveArticleMarked(article); + m_activity.saveArticleMarked(article); } }); } @@ -445,7 +565,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, article.published = !article.published; m_adapter.notifyDataSetChanged(); - m_onlineServices.saveArticlePublished(article); + m_activity.saveArticlePublished(article); } }); } @@ -533,7 +653,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, Attachment attachment = (Attachment) spinner.getSelectedItem(); if (attachment != null) { - m_onlineServices.copyToClipboard(attachment.content_url); + m_activity.copyToClipboard(attachment.content_url); } } }); @@ -590,7 +710,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, m_selectedArticles.remove(article); } - m_onlineServices.onArticleListSelectionChange(m_selectedArticles); + m_listener.onArticleListSelectionChange(m_selectedArticles); Log.d(TAG, "num selected: " + m_selectedArticles.size()); } @@ -710,5 +830,9 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } } + public Feed getFeed() { + return m_feed; + } + } diff --git a/src/org/fox/ttrss/MainActivity.java b/src/org/fox/ttrss/MainActivity.java deleted file mode 100644 index 1ac736e2..00000000 --- a/src/org/fox/ttrss/MainActivity.java +++ /dev/null @@ -1,2313 +0,0 @@ -package org.fox.ttrss; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; - -import org.fox.ttrss.offline.OfflineActivity; -import org.fox.ttrss.offline.OfflineDownloadService; -import org.fox.ttrss.offline.OfflineUploadService; -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; -import org.fox.ttrss.types.Feed; -import org.fox.ttrss.types.FeedCategory; -import org.fox.ttrss.types.Label; -import org.fox.ttrss.util.AppRater; - -import android.animation.LayoutTransition; -import android.annotation.SuppressLint; -import android.app.ActionBar; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.DialogInterface.OnMultiChoiceClickListener; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentTransaction; -import android.util.Log; -import android.view.ActionMode; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.SearchView; -import android.widget.ShareActionProvider; -import android.widget.TextView; -import android.widget.Toast; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.reflect.TypeToken; - -public class MainActivity extends CommonActivity implements OnlineServices { - private final String TAG = this.getClass().getSimpleName(); - - private SharedPreferences m_prefs; - private String m_themeName = ""; - private String m_sessionId; - private Article m_selectedArticle; - private Feed m_activeFeed; - private FeedCategory m_activeCategory; - private Timer m_refreshTimer; - private RefreshTask m_refreshTask; - private Menu m_menu; - private boolean m_unreadOnly = true; - private boolean m_unreadArticlesOnly = true; - private boolean m_enableCats = false; - private int m_apiLevel = 0; - private boolean m_isLoggingIn = false; - private boolean m_isOffline = false; - private int m_offlineModeStatus = 0; - private int m_selectedProduct = -1; - private long m_lastRefresh = 0; - - private ActionMode m_headlinesActionMode; - private HeadlinesActionModeCallback m_headlinesActionModeCallback; - private NavigationListener m_navigationListener; - private NavigationAdapter m_navigationAdapter; - private ArrayList m_navigationEntries = new ArrayList(); - - private class NavigationListener implements ActionBar.OnNavigationListener { - @Override - public boolean onNavigationItemSelected(int itemPosition, long itemId) { - Log.d(TAG, "onNavigationItemSelected: " + itemPosition); - - NavigationEntry entry = m_navigationAdapter.getItem(itemPosition); - entry._onItemSelected(itemPosition, m_navigationAdapter.getCount()-1); - - return false; - } - } - - private class ArticleNavigationEntry extends NavigationEntry { - public ArticleNavigationEntry(Article article) { - super(article.title); - } - - @Override - public void onItemSelected() { - - } - } - - private class RootNavigationEntry extends NavigationEntry { - public RootNavigationEntry(String title) { - super(title); - } - - @Override - public void onItemSelected() { - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - m_activeFeed = null; - m_selectedArticle = null; - m_activeCategory = null; - - if (isSmallScreen()) { - - if (m_enableCats) { - ft.replace(R.id.fragment_container, new FeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.fragment_container, new FeedsFragment(), FRAG_FEEDS); - } - - Fragment hf = getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - if (hf != null) ft.remove(hf); - - Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - if (af != null) ft.remove(af); - - } else { - if (m_enableCats) { - ft.replace(R.id.feeds_fragment, new FeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.feeds_fragment, new FeedsFragment(), FRAG_FEEDS); - } - - findViewById(R.id.article_fragment).setVisibility(View.GONE); - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - } - - ft.commit(); - initMainMenu(); - } - } - - private class CategoryNavigationEntry extends NavigationEntry { - FeedCategory m_category = null; - - public CategoryNavigationEntry(FeedCategory category) { - super(category.title); - - m_category = category; - } - - @Override - public void onItemSelected() { - m_selectedArticle = null; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (isSmallScreen()) { - - Fragment hf = getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - if (hf != null) ft.remove(hf); - - Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - if (af != null) ft.remove(af); - - if (m_activeFeed.is_cat) { - FeedCategoriesFragment cats = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - - if (cats != null) { - ft.show(cats); - cats.setSelectedCategory(null); - } - } else { - FeedsFragment feeds = (FeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - - if (feeds != null) { - ft.show(feeds); - feeds.setSelectedFeed(null); - } - } - - } else { - findViewById(R.id.article_fragment).setVisibility(View.GONE); - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - - updateHeadlines(); - - //ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - } - ft.commit(); - - m_activeFeed = null; - refresh(); - initMainMenu(); - } - } - - private class FeedNavigationEntry extends NavigationEntry { - Feed m_feed = null; - - public FeedNavigationEntry(Feed feed) { - super(feed.title); - - m_feed = feed; - } - - @Override - public void onItemSelected() { - - m_selectedArticle = null; - - if (!isSmallScreen()) - findViewById(R.id.article_fragment).setVisibility(View.GONE); - - viewFeed(m_feed, false); - } - } - - private abstract class NavigationEntry { - private String title = null; - private int timesCalled = 0; - - public void _onItemSelected(int position, int size) { - Log.d(TAG, "_onItemSelected; TC=" + timesCalled + " P/S=" + position + "/" + size); - - if (position == size && timesCalled == 0) { - ++timesCalled; - } else { - onItemSelected(); - } - } - - public NavigationEntry(String title) { - this.title = title; - } - - public String toString() { - return title; - } - - public abstract void onItemSelected(); - } - - private class NavigationAdapter extends ArrayAdapter { - public NavigationAdapter(Context context, int textViewResourceId, ArrayList items) { - super(context, textViewResourceId, items); - } - } - - private class HeadlinesActionModeCallback implements ActionMode.Callback { - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return false; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - deselectAllArticles(); - m_headlinesActionMode = null; - } - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.headlines_action_menu, menu); - - return true; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - onOptionsItemSelected(item); - return false; - } - }; - - private BroadcastReceiver m_broadcastReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(Context content, Intent intent) { - - if (intent.getAction().equals(OfflineDownloadService.INTENT_ACTION_SUCCESS)) { - - m_offlineModeStatus = 2; - - switchOffline(); - - } else if (intent.getAction().equals(OfflineUploadService.INTENT_ACTION_SUCCESS)) { - //Log.d(TAG, "offline upload service reports success"); - - refresh(); - - toast(R.string.offline_sync_success); - } - - } - }; - - public void updateHeadlines() { - HeadlinesFragment frag = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - if (frag != null) { - frag.setActiveArticle(m_selectedArticle); - } - } - - @Override - public int getApiLevel() { - return m_apiLevel; - } - - private boolean hasPendingOfflineData() { - try { - Cursor c = getReadableDb().query("articles", - new String[] { "COUNT(*)" }, "modified = 1", null, null, null, - null); - if (c.moveToFirst()) { - int modified = c.getInt(0); - c.close(); - - return modified > 0; - } - } catch (IllegalStateException e) { - // db is closed? ugh - } - - return false; - } - - private boolean hasOfflineData() { - try { - Cursor c = getReadableDb().query("articles", - new String[] { "COUNT(*)" }, null, null, null, null, null); - if (c.moveToFirst()) { - int modified = c.getInt(0); - c.close(); - - return modified > 0; - } - } catch (IllegalStateException e) { - // db is closed? - } - - return false; - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticleUnread(final Article article) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", article.unread ? "1" : "0"); - put("field", "2"); - } - }; - - req.execute(map); - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticleMarked(final Article article) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - toast(article.marked ? R.string.notify_article_marked : R.string.notify_article_unmarked); - } - }; - - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", article.marked ? "1" : "0"); - put("field", "0"); - } - }; - - req.execute(map); - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticlePublished(final Article article) { - - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - toast(article.published ? R.string.notify_article_published : R.string.notify_article_unpublished); - } - }; - - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", article.published ? "1" : "0"); - put("field", "1"); - } - }; - - req.execute(map); - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticleNote(final Article article, final String note) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - toast(R.string.notify_article_note_set); - } - }; - - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", "1"); - put("data", note); - put("field", "3"); - } - }; - - req.execute(map); - } - - public static String articlesToIdString(ArticleList articles) { - String tmp = ""; - - for (Article a : articles) - tmp += String.valueOf(a.id) + ","; - - return tmp.replaceAll(",$", ""); - } - - @SuppressWarnings("unchecked") - public void catchupFeed(final Feed feed) { - Log.d(TAG, "catchupFeed=" + feed); - - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - refresh(); - } - - }; - - @SuppressWarnings("serial") - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "catchupFeed"); - put("feed_id", String.valueOf(feed.id)); - if (feed.is_cat) - put("is_cat", "1"); - } - }; - - req.execute(map); - } - - @SuppressWarnings("unchecked") - private void toggleArticlesMarked(final ArticleList articles) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - @SuppressWarnings("serial") - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", articlesToIdString(articles)); - put("mode", "2"); - put("field", "0"); - } - }; - - req.execute(map); - } - - @SuppressWarnings("unchecked") - private void toggleArticlesUnread(final ArticleList articles) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - @SuppressWarnings("serial") - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", articlesToIdString(articles)); - put("mode", "2"); - put("field", "2"); - } - }; - - req.execute(map); - refresh(); - } - - @SuppressWarnings("unchecked") - private void toggleArticlesPublished(final ArticleList articles) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - @SuppressWarnings("serial") - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", articlesToIdString(articles)); - put("mode", "2"); - put("field", "1"); - } - }; - - req.execute(map); - } - - private class RefreshTask extends TimerTask { - - @Override - public void run() { - ConnectivityManager cm = (ConnectivityManager) getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); - - if (cm.getBackgroundDataSetting()) { - NetworkInfo networkInfo = cm.getActiveNetworkInfo(); - if (networkInfo != null && networkInfo.isAvailable() - && networkInfo.isConnected()) { - - runOnUiThread(new Runnable() { - @Override - public void run() { - refresh(); - } - }); - - } - } - } - } - - private synchronized void refresh() { - Date date = new Date(); - - if (m_sessionId != null && date.getTime() - m_lastRefresh > 5000) { - - FeedsFragment ff = (FeedsFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_FEEDS); - - if (ff != null) { - Log.d(TAG, "Refreshing feeds/" + m_activeFeed); - ff.refresh(true); - } - - FeedCategoriesFragment cf = (FeedCategoriesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_CATS); - - if (cf != null) { - Log.d(TAG, "Refreshing categories/" + m_activeCategory); - cf.refresh(true); - } - - m_lastRefresh = date.getTime(); - } - } - - /* private synchronized void refreshHeadlines() { - if (m_sessionId != null) { - HeadlinesFragment frag = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - Log.d(TAG, "Refreshing headlines..."); - - if (frag != null) { - frag.refresh(true); - } - } - } */ - - private void setUnreadOnly(boolean unread) { - m_unreadOnly = unread; - m_lastRefresh = 0; - refresh(); - } - - @Override - public boolean getUnreadOnly() { - return m_unreadOnly; - } - - @Override - public boolean getUnreadArticlesOnly() { - return m_unreadArticlesOnly; - } - - @Override - public String getSessionId() { - return m_sessionId; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - if (m_prefs.getString("theme", "THEME_DARK").equals("THEME_DARK")) { - setTheme(R.style.DarkTheme); - } else { - setTheme(R.style.LightTheme); - } - - super.onCreate(savedInstanceState); - - if (OfflineDownloadService.INTENT_ACTION_CANCEL.equals(getIntent().getAction())) { - cancelOfflineSync(); - } - - //Log.d(TAG, "started with intent action=" + intentAction); - - requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); - - m_themeName = m_prefs.getString("theme", "THEME_DARK"); - - if (savedInstanceState != null) { - m_sessionId = savedInstanceState.getString("sessionId"); - m_unreadOnly = savedInstanceState.getBoolean("unreadOnly"); - m_activeFeed = savedInstanceState.getParcelable("activeFeed"); - m_selectedArticle = savedInstanceState - .getParcelable("selectedArticle"); - m_unreadArticlesOnly = savedInstanceState - .getBoolean("unreadArticlesOnly"); - m_activeCategory = savedInstanceState - .getParcelable("activeCategory"); - m_apiLevel = savedInstanceState.getInt("apiLevel"); - m_offlineModeStatus = savedInstanceState.getInt("offlineModeStatus"); - } - - m_enableCats = m_prefs.getBoolean("enable_cats", false); - - setContentView(R.layout.main); - - setSmallScreen(findViewById(R.id.headlines_fragment) == null); - - IntentFilter filter = new IntentFilter(); - filter.addAction(OfflineDownloadService.INTENT_ACTION_SUCCESS); - filter.addAction(OfflineUploadService.INTENT_ACTION_SUCCESS); - filter.addCategory(Intent.CATEGORY_DEFAULT); - - registerReceiver(m_broadcastReceiver, filter); - - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - - m_isOffline = localPrefs.getBoolean("offline_mode_active", false); - - Log.d(TAG, "m_isOffline=" + m_isOffline); - - if (!isCompatMode()) { - - if (!isSmallScreen()) { - findViewById(R.id.feeds_fragment).setVisibility(m_selectedArticle != null && (isPortrait() || isSmallTablet()) ? View.GONE : View.VISIBLE); - findViewById(R.id.article_fragment).setVisibility(m_selectedArticle != null ? View.VISIBLE : View.GONE); - } - - LayoutTransition transitioner = new LayoutTransition(); - ((ViewGroup) findViewById(R.id.fragment_container)).setLayoutTransition(transitioner); - - m_navigationAdapter = new NavigationAdapter(this, android.R.layout.simple_spinner_dropdown_item, m_navigationEntries); - - m_headlinesActionModeCallback = new HeadlinesActionModeCallback(); - m_navigationListener = new NavigationListener(); - - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); - getActionBar().setListNavigationCallbacks(m_navigationAdapter, m_navigationListener); - } - - if (isSmallScreen()) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - // temporary workaround against viewpager going a bit crazy when restoring after rotation - if (m_selectedArticle != null) { - ft.remove(getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE)); - m_selectedArticle = null; - } - - if (m_activeFeed != null) { - if (m_activeFeed.is_cat) { - ft.hide(getSupportFragmentManager().findFragmentByTag(FRAG_CATS)); - } else { - ft.hide(getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS)); - } - } - ft.commit(); - } - - if (m_isOffline) { - Intent offline = new Intent(MainActivity.this, - OfflineActivity.class); - startActivity(offline); - finish(); - } else { - //AppRater.showRateDialog(this, null); - AppRater.appLaunched(this); - - if (m_sessionId != null) { - loginSuccess(); - } else { - //login(); -- handled in onResume() - } - } - } - - private void switchOffline() { - if (m_offlineModeStatus == 2) { - - AlertDialog.Builder builder = new AlertDialog.Builder( - MainActivity.this) - .setMessage(R.string.dialog_offline_success) - .setPositiveButton(R.string.dialog_offline_go, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - m_offlineModeStatus = 0; - - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = localPrefs.edit(); - editor.putBoolean("offline_mode_active", true); - editor.commit(); - - Intent refresh = new Intent( - MainActivity.this, - OfflineActivity.class); - startActivity(refresh); - finish(); - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - m_offlineModeStatus = 0; - - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - - } else if (m_offlineModeStatus == 0) { - - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setMessage(R.string.dialog_offline_switch_prompt) - .setPositiveButton(R.string.dialog_offline_go, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - if (m_sessionId != null) { - Log.d(TAG, "offline: starting"); - - m_offlineModeStatus = 1; - - Intent intent = new Intent( - MainActivity.this, - OfflineDownloadService.class); - intent.putExtra("sessionId", m_sessionId); - - startService(intent); - } - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - // - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } else if (m_offlineModeStatus == 1) { - cancelOfflineSync(); - } - } - - private void cancelOfflineSync() { - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setMessage(R.string.dialog_offline_sync_in_progress) - .setNegativeButton(R.string.dialog_offline_sync_stop, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - if (m_sessionId != null) { - Log.d(TAG, "offline: stopping"); - - m_offlineModeStatus = 0; - - Intent intent = new Intent( - MainActivity.this, - OfflineDownloadService.class); - - stopService(intent); - - dialog.dismiss(); - - restart(); - } - } - }) - .setPositiveButton(R.string.dialog_offline_sync_continue, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - dialog.dismiss(); - - restart(); - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } - - private void switchOfflineSuccess() { - logout(); - // setLoadingStatus(R.string.blank, false); - - SharedPreferences.Editor editor = m_prefs.edit(); - editor.putBoolean("offline_mode_active", true); - editor.commit(); - - Intent offline = new Intent(MainActivity.this, OfflineActivity.class); - startActivity(offline); - finish(); - - } - - private void setLoadingStatus(int status, boolean showProgress) { - TextView tv = (TextView) findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(status); - } - - setProgressBarIndeterminateVisibility(showProgress); - } - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - out.putString("sessionId", m_sessionId); - out.putBoolean("unreadOnly", m_unreadOnly); - out.putParcelable("activeFeed", m_activeFeed); - out.putParcelable("selectedArticle", m_selectedArticle); - out.putBoolean("unreadArticlesOnly", m_unreadArticlesOnly); - out.putParcelable("activeCategory", m_activeCategory); - out.putInt("apiLevel", m_apiLevel); - out.putInt("offlineModeStatus", m_offlineModeStatus); - } - - @Override - public void onResume() { - super.onResume(); - - boolean needRefresh = !m_prefs.getString("theme", "THEME_DARK").equals( - m_themeName) - || m_prefs.getBoolean("enable_cats", false) != m_enableCats; - - if (needRefresh) { - restart(); - } else if (m_sessionId != null) { - m_refreshTask = new RefreshTask(); - m_refreshTimer = new Timer("Refresh"); - - m_refreshTimer.schedule(m_refreshTask, 60 * 1000L, 120 * 1000L); - } else { - if (!m_isLoggingIn) { - login(); - } - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.main_menu, menu); - - m_menu = menu; - - initMainMenu(); - - MenuItem item = menu.findItem(R.id.show_feeds); - - if (getUnreadOnly()) { - item.setTitle(R.string.menu_all_feeds); - } else { - item.setTitle(R.string.menu_unread_feeds); - } - - /* - * item = menu.findItem(R.id.show_all_articles); - * - * if (getUnreadArticlesOnly()) { - * item.setTitle(R.string.show_all_articles); } else { - * item.setTitle(R.string.show_unread_articles); } - */ - - return true; - } - - private void setMenuLabel(int id, int labelId) { - MenuItem mi = m_menu.findItem(id); - - if (mi != null) { - mi.setTitle(labelId); - } - } - - @Override - public void onBackPressed() { - goBack(true); - } - - private void closeCategory() { - m_activeCategory = null; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, new FeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.feeds_fragment, new FeedCategoriesFragment(), FRAG_CATS); - } - ft.commit(); - - initMainMenu(); - refresh(); - } - - private void deselectAllArticles() { - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - if (selected.size() > 0) { - selected.clear(); - initMainMenu(); - updateHeadlines(); - } - } - } - - private void goBack(boolean allowQuit) { - if (isSmallScreen()) { - if (m_selectedArticle != null) { - closeArticle(); - } else if (m_activeFeed != null) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - if (m_activeFeed.is_cat) { - - Fragment headlines = getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - FeedCategoriesFragment cats = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - - ft.show(cats); - ft.remove(headlines); - - } else { - Fragment headlines = getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - FeedsFragment feeds = (FeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - - ft.show(feeds); - ft.remove(headlines); - } - ft.commit(); - - m_activeFeed = null; - - refresh(); - - initMainMenu(); - - } else if (m_activeCategory != null) { - closeCategory(); - } else if (allowQuit) { - finish(); - } - } else { - if (m_selectedArticle != null) { - closeArticle(); - refresh(); - } else if (m_activeFeed != null) { - closeFeed(); - } else if (m_activeCategory != null) { - closeCategory(); - } else if (allowQuit) { - finish(); - } - } - } - - - private void closeFeed() { - if (m_activeFeed != null) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - ft.commit(); - - if (m_activeFeed.is_cat) { - FeedCategoriesFragment cats = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - if (cats != null) { - cats.setSelectedCategory(null); - } - } else { - FeedsFragment feeds = (FeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - if (feeds != null) { - feeds.setSelectedFeed(null); - } - } - - m_activeFeed = null; - - initMainMenu(); - } - } - - - @SuppressWarnings("unchecked") - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - switch (item.getItemId()) { - case R.id.close_feed: - if (m_activeFeed != null) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - ft.commit(); - - if (m_activeFeed.is_cat) { - FeedCategoriesFragment cats = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - cats.setSelectedCategory(null); - } else { - FeedsFragment feeds = (FeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - feeds.setSelectedFeed(null); - } - - m_activeFeed = null; - - initMainMenu(); - } - return true; - case R.id.close_article: - closeArticle(); - return true; - case android.R.id.home: - goBack(false); - return true; - case R.id.search: - if (hf != null && isCompatMode()) { - Dialog dialog = new Dialog(this); - - final EditText edit = new EditText(this); - - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setTitle(R.string.search) - .setPositiveButton(getString(R.string.search), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - - String query = edit.getText().toString().trim(); - - hf.setSearchQuery(query); - - } - }) - .setNegativeButton(getString(R.string.cancel), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - - // - - } - }).setView(edit); - - dialog = builder.create(); - dialog.show(); - } - - return true; - case R.id.preferences: - Intent intent = new Intent(MainActivity.this, - PreferencesActivity.class); - startActivityForResult(intent, 0); - return true; - case R.id.update_feeds: - m_lastRefresh = 0; - refresh(); - return true; - case R.id.logout: - logout(); - return true; - case R.id.login: - login(); - return true; - case R.id.go_offline: - switchOffline(); - return true; - case R.id.article_set_note: - if (m_selectedArticle != null) { - editArticleNote(m_selectedArticle); - } - return true; - case R.id.headlines_select: - if (hf != null) { - Dialog dialog = new Dialog(this); - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setTitle(R.string.headlines_select_dialog) - .setSingleChoiceItems( - new String[] { - getString(R.string.headlines_select_all), - getString(R.string.headlines_select_unread), - getString(R.string.headlines_select_none) }, - 0, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, - int which) { - switch (which) { - case 0: - hf.setSelection(HeadlinesFragment.ArticlesSelection.ALL); - break; - case 1: - hf.setSelection(HeadlinesFragment.ArticlesSelection.UNREAD); - break; - case 2: - hf.setSelection(HeadlinesFragment.ArticlesSelection.NONE); - break; - } - dialog.cancel(); - initMainMenu(); - } - }); - - dialog = builder.create(); - dialog.show(); - } - return true; - case R.id.headlines_mark_as_read: - if (hf != null) { - ArticleList articles = hf.getUnreadArticles(); - - for (Article a : articles) - a.unread = false; - - updateHeadlines(); - - ApiRequest req = new ApiRequest(getApplicationContext()); - - final String articleIds = articlesToIdString(articles); - - @SuppressWarnings("serial") - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", articleIds); - put("mode", "0"); - put("field", "2"); - } - }; - - req.execute(map); - refresh(); - } - return true; - case R.id.share_article: - if (android.os.Build.VERSION.SDK_INT < 14) { - shareArticle(m_selectedArticle); - } - return true; - case R.id.toggle_marked: - if (m_selectedArticle != null) { - m_selectedArticle.marked = !m_selectedArticle.marked; - saveArticleMarked(m_selectedArticle); - updateHeadlines(); - } - return true; - case R.id.selection_select_none: - deselectAllArticles(); - return true; - case R.id.selection_toggle_unread: - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.unread = !a.unread; - - toggleArticlesUnread(selected); - updateHeadlines(); - } - refresh(); - } - return true; - case R.id.selection_toggle_marked: - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.marked = !a.marked; - - toggleArticlesMarked(selected); - updateHeadlines(); - } - } - return true; - case R.id.selection_toggle_published: - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.published = !a.published; - - toggleArticlesPublished(selected); - updateHeadlines(); - } - } - return true; - case R.id.toggle_published: - if (m_selectedArticle != null) { - m_selectedArticle.published = !m_selectedArticle.published; - saveArticlePublished(m_selectedArticle); - updateHeadlines(); - } - return true; - case R.id.catchup_above: - if (hf != null) { - if (m_selectedArticle != null) { - ArticleList articles = hf.getAllArticles(); - ArticleList tmp = new ArticleList(); - for (Article a : articles) { - a.unread = false; - tmp.add(a); - if (m_selectedArticle.id == a.id) - break; - } - if (tmp.size() > 0) { - toggleArticlesUnread(tmp); - updateHeadlines(); - } - } - } - return true; - case R.id.set_unread: - if (m_selectedArticle != null) { - m_selectedArticle.unread = true; - saveArticleUnread(m_selectedArticle); - updateHeadlines(); - } - return true; - case R.id.show_feeds: - setUnreadOnly(!getUnreadOnly()); - - if (getUnreadOnly()) { - item.setTitle(R.string.menu_all_feeds); - } else { - item.setTitle(R.string.menu_unread_feeds); - } - - return true; - case R.id.set_labels: - if (m_selectedArticle != null) { - editArticleLabels(m_selectedArticle); - } - return true; - default: - Log.d(TAG, - "onOptionsItemSelected, unhandled id=" + item.getItemId()); - return super.onOptionsItemSelected(item); - } - } - - private void editArticleNote(final Article article) { - String note = ""; - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(article.title); - final EditText topicEdit = new EditText(this); - topicEdit.setText(note); - builder.setView(topicEdit); - - builder.setPositiveButton(R.string.article_set_note, new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - saveArticleNote(article, topicEdit.getText().toString().trim()); - article.published = true; - saveArticlePublished(article); - updateHeadlines(); - } - }); - - builder.setNegativeButton(R.string.dialog_cancel, new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // - } - }); - - AlertDialog dialog = builder.create(); - dialog.show(); - } - - private void editArticleLabels(Article article) { - final int articleId = article.id; - - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - protected void onPostExecute(JsonElement result) { - if (result != null) { - Type listType = new TypeToken>() {}.getType(); - final List