From 8e3e5add776ddb8bcc9e6b349d4eb470e93d15e0 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Mon, 17 Sep 2012 18:44:43 +0400 Subject: [PATCH] implement most of offline menus --- res/layout-sw600dp-port/main.xml | 61 ---------- res/layout-sw600dp/main.xml | 55 --------- res/layout/{online.xml => login.xml} | 2 +- res/layout/main.xml | 27 ----- res/menu/offline_menu.xml | 4 +- res/values-v11/style.xml | 2 +- src/org/fox/ttrss/ArticlePager.java | 2 +- src/org/fox/ttrss/HeadlinesEventListener.java | 4 - src/org/fox/ttrss/HeadlinesFragment.java | 3 +- src/org/fox/ttrss/OnlineActivity.java | 2 +- .../fox/ttrss/offline/OfflineActivity.java | 112 +++++++++++++++++- .../ttrss/offline/OfflineArticlePager.java | 4 +- .../ttrss/offline/OfflineDownloadService.java | 2 +- .../ttrss/offline/OfflineFeedsActivity.java | 2 + .../OfflineHeadlinesEventListener.java | 9 -- .../offline/OfflineHeadlinesFragment.java | 101 ++++++++++++---- 16 files changed, 193 insertions(+), 199 deletions(-) delete mode 100644 res/layout-sw600dp-port/main.xml delete mode 100644 res/layout-sw600dp/main.xml rename res/layout/{online.xml => login.xml} (91%) delete mode 100644 res/layout/main.xml diff --git a/res/layout-sw600dp-port/main.xml b/res/layout-sw600dp-port/main.xml deleted file mode 100644 index 02732ba4..00000000 --- a/res/layout-sw600dp-port/main.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/res/layout-sw600dp/main.xml b/res/layout-sw600dp/main.xml deleted file mode 100644 index 9df4e048..00000000 --- a/res/layout-sw600dp/main.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/res/layout/online.xml b/res/layout/login.xml similarity index 91% rename from res/layout/online.xml rename to res/layout/login.xml index d94aa147..d144df96 100644 --- a/res/layout/online.xml +++ b/res/layout/login.xml @@ -1,5 +1,5 @@ diff --git a/res/layout/main.xml b/res/layout/main.xml deleted file mode 100644 index eb06058c..00000000 --- a/res/layout/main.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/res/menu/offline_menu.xml b/res/menu/offline_menu.xml index ad756aac..069625c5 100644 --- a/res/menu/offline_menu.xml +++ b/res/menu/offline_menu.xml @@ -23,11 +23,11 @@ android:title="@string/menu_all_feeds"/> - + android:visible="false"/> --> @drawable/ics_divider_vertical #303030 @drawable/headlines_dark - @android:color/transparent + @drawable/headlines_dark @android:color/black @drawable/headline_row_selected_dark @color/ics_cyan diff --git a/src/org/fox/ttrss/ArticlePager.java b/src/org/fox/ttrss/ArticlePager.java index a7ecaaa5..a0085989 100644 --- a/src/org/fox/ttrss/ArticlePager.java +++ b/src/org/fox/ttrss/ArticlePager.java @@ -104,7 +104,7 @@ public class ArticlePager extends Fragment { if (article.unread) { article.unread = false; - m_onlineServices.saveArticleUnread(article); + m_activity.saveArticleUnread(article); } m_onlineServices.onArticleSelected(article, false); diff --git a/src/org/fox/ttrss/HeadlinesEventListener.java b/src/org/fox/ttrss/HeadlinesEventListener.java index 024fbfad..d286df17 100644 --- a/src/org/fox/ttrss/HeadlinesEventListener.java +++ b/src/org/fox/ttrss/HeadlinesEventListener.java @@ -4,11 +4,7 @@ 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 open); - } diff --git a/src/org/fox/ttrss/HeadlinesFragment.java b/src/org/fox/ttrss/HeadlinesFragment.java index 031321eb..fae19703 100644 --- a/src/org/fox/ttrss/HeadlinesFragment.java +++ b/src/org/fox/ttrss/HeadlinesFragment.java @@ -78,7 +78,6 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, private ArticleList m_articles = TinyApplication.getInstance().m_loadedArticles; private ArticleList m_selectedArticles = new ArticleList(); private HeadlinesEventListener m_listener; - private OnlineActivity m_activity; private ImageGetter m_dummyGetter = new ImageGetter() { @@ -363,7 +362,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, }; final String sessionId = m_activity.getSessionId(); - final boolean showUnread = m_listener.getUnreadArticlesOnly(); + final boolean showUnread = m_activity.getUnreadArticlesOnly(); final boolean isCat = m_feed.is_cat; int skip = 0; diff --git a/src/org/fox/ttrss/OnlineActivity.java b/src/org/fox/ttrss/OnlineActivity.java index 6c65c43b..e6053aa0 100644 --- a/src/org/fox/ttrss/OnlineActivity.java +++ b/src/org/fox/ttrss/OnlineActivity.java @@ -139,7 +139,7 @@ public class OnlineActivity extends CommonActivity { Log.d(TAG, "m_isOffline=" + isOffline); - setContentView(R.layout.online); + setContentView(R.layout.login); if (isOffline) { switchOfflineSuccess(); diff --git a/src/org/fox/ttrss/offline/OfflineActivity.java b/src/org/fox/ttrss/offline/OfflineActivity.java index e2ffdb1e..78aca34b 100644 --- a/src/org/fox/ttrss/offline/OfflineActivity.java +++ b/src/org/fox/ttrss/offline/OfflineActivity.java @@ -1,7 +1,5 @@ package org.fox.ttrss.offline; -import javax.crypto.spec.OAEPParameterSpec; - import org.fox.ttrss.CommonActivity; import org.fox.ttrss.PreferencesActivity; import org.fox.ttrss.R; @@ -10,20 +8,23 @@ import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.SharedPreferences; -import android.content.DialogInterface.OnClickListener; import android.database.Cursor; import android.database.sqlite.SQLiteStatement; import android.os.Bundle; import android.preference.PreferenceManager; import android.provider.BaseColumns; import android.util.Log; +import android.view.ActionMode; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.EditText; +import android.widget.SearchView; +import android.widget.ShareActionProvider; public class OfflineActivity extends CommonActivity { private final String TAG = this.getClass().getSimpleName(); @@ -31,6 +32,38 @@ public class OfflineActivity extends CommonActivity { protected SharedPreferences m_prefs; protected Menu m_menu; protected boolean m_unreadOnly; + + private ActionMode m_headlinesActionMode; + private HeadlinesActionModeCallback m_headlinesActionModeCallback; + + 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; + } + }; @Override public void onCreate(Bundle savedInstanceState) { @@ -45,7 +78,7 @@ public class OfflineActivity extends CommonActivity { super.onCreate(savedInstanceState); - setContentView(R.layout.online); + setContentView(R.layout.login); setLoadingStatus(R.string.blank, false); findViewById(R.id.loading_container).setVisibility(View.GONE); @@ -67,6 +100,11 @@ public class OfflineActivity extends CommonActivity { if (savedInstanceState != null) { m_unreadOnly = savedInstanceState.getBoolean("unreadOnly"); } + + if (!isCompatMode()) { + m_headlinesActionModeCallback = new HeadlinesActionModeCallback(); + } + } @Override @@ -198,7 +236,7 @@ public class OfflineActivity extends CommonActivity { } return true; case R.id.share_article: - if (oap != null && android.os.Build.VERSION.SDK_INT < 14) { + if (android.os.Build.VERSION.SDK_INT < 14 && oap != null && android.os.Build.VERSION.SDK_INT < 14) { int articleId = oap.getSelectedArticleId(); shareArticle(articleId); @@ -326,6 +364,68 @@ public class OfflineActivity extends CommonActivity { m_menu.setGroupVisible(R.id.menu_group_headlines_selection, false); m_menu.setGroupVisible(R.id.menu_group_article, false); m_menu.setGroupVisible(R.id.menu_group_feeds, false); + + if (android.os.Build.VERSION.SDK_INT >= 14) { + ShareActionProvider shareProvider = (ShareActionProvider) m_menu.findItem(R.id.share_article).getActionProvider(); + + OfflineArticlePager af = (OfflineArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + + if (af != null) { + Log.d(TAG, "setting up share provider"); + shareProvider.setShareIntent(getShareIntent(getArticleById(af.getSelectedArticleId()))); + + if (!isSmallScreen()) { + m_menu.findItem(R.id.share_article).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + } + } + } + + if (!isCompatMode()) { + MenuItem search = m_menu.findItem(R.id.search); + + OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); + + if (hf != null) { + if (hf.getSelectedArticleCount() > 0 && m_headlinesActionMode == null) { + m_headlinesActionMode = startActionMode(m_headlinesActionModeCallback); + } else if (hf.getSelectedArticleCount() == 0 && m_headlinesActionMode != null) { + m_headlinesActionMode.finish(); + } + } + + SearchView searchView = (SearchView) search.getActionView(); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + private String query = ""; + + @Override + public boolean onQueryTextSubmit(String query) { + OfflineHeadlinesFragment frag = (OfflineHeadlinesFragment) getSupportFragmentManager() + .findFragmentByTag(FRAG_HEADLINES); + + if (frag != null) { + frag.setSearchQuery(query); + this.query = query; + } + + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + if (newText.equals("") && !newText.equals(this.query)) { + OfflineHeadlinesFragment frag = (OfflineHeadlinesFragment) getSupportFragmentManager() + .findFragmentByTag(FRAG_HEADLINES); + + if (frag != null) { + frag.setSearchQuery(newText); + this.query = newText; + } + } + + return false; + } + }); + } } } @@ -398,7 +498,7 @@ public class OfflineActivity extends CommonActivity { Intent intent = getShareIntent(article); startActivity(Intent.createChooser(intent, - getString(R.id.share_article))); + getString(R.string.share_article))); } } diff --git a/src/org/fox/ttrss/offline/OfflineArticlePager.java b/src/org/fox/ttrss/offline/OfflineArticlePager.java index 0516d897..b1e04993 100644 --- a/src/org/fox/ttrss/offline/OfflineArticlePager.java +++ b/src/org/fox/ttrss/offline/OfflineArticlePager.java @@ -38,11 +38,11 @@ public class OfflineArticlePager extends Fragment { } if (m_searchQuery.equals("")) { - return m_listener.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")", + return m_activity.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")", new String[] { "articles."+BaseColumns._ID, "feeds.title AS feed_title" }, feedClause, new String[] { String.valueOf(m_feedId) }, null, null, "updated DESC"); } else { - return m_listener.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")", + return m_activity.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")", new String[] { "articles."+BaseColumns._ID }, feedClause + " AND (articles.title LIKE '%' || ? || '%' OR content LIKE '%' || ? || '%')", new String[] { String.valueOf(m_feedId), m_searchQuery, m_searchQuery }, null, null, "updated DESC"); diff --git a/src/org/fox/ttrss/offline/OfflineDownloadService.java b/src/org/fox/ttrss/offline/OfflineDownloadService.java index 28b803e4..bace2709 100644 --- a/src/org/fox/ttrss/offline/OfflineDownloadService.java +++ b/src/org/fox/ttrss/offline/OfflineDownloadService.java @@ -47,7 +47,7 @@ public class OfflineDownloadService extends Service { public static final String INTENT_ACTION_CANCEL = "org.fox.ttrss.intent.action.Cancel"; private static final int OFFLINE_SYNC_SEQ = 40; - private static final int OFFLINE_SYNC_MAX = 120 /*500*/; + private static final int OFFLINE_SYNC_MAX = 500; private SQLiteDatabase m_writableDb; private SQLiteDatabase m_readableDb; diff --git a/src/org/fox/ttrss/offline/OfflineFeedsActivity.java b/src/org/fox/ttrss/offline/OfflineFeedsActivity.java index 61c13710..075c372a 100644 --- a/src/org/fox/ttrss/offline/OfflineFeedsActivity.java +++ b/src/org/fox/ttrss/offline/OfflineFeedsActivity.java @@ -228,6 +228,8 @@ public class OfflineFeedsActivity extends OfflineActivity implements OfflineHead } else { refresh(); } + + initMenu(); } diff --git a/src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java b/src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java index 392f59ec..aa1ae46f 100644 --- a/src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java +++ b/src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java @@ -3,15 +3,6 @@ package org.fox.ttrss.offline; import android.database.sqlite.SQLiteDatabase; public interface OfflineHeadlinesEventListener { - void onArticleSelected(int articleId, boolean open); void onArticleSelected(int articleId); - - SQLiteDatabase getReadableDb(); - SQLiteDatabase getWritableDb(); - boolean isSmallScreen(); - boolean isPortrait(); - void initMenu(); - - } diff --git a/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java b/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java index 6621105b..4c0ffca8 100644 --- a/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java +++ b/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java @@ -59,6 +59,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis private ArticleListAdapter m_adapter; private OfflineHeadlinesEventListener m_listener; + private OfflineActivity m_activity; private ImageGetter m_dummyGetter = new ImageGetter() { @@ -86,7 +87,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis } public int getSelectedArticleCount() { - Cursor c = m_listener.getReadableDb().query("articles", + Cursor c = m_activity.getReadableDb().query("articles", new String[] { "COUNT(*)" }, "selected = 1", null, null, null, null); c.moveToFirst(); int selected = c.getInt(0); @@ -101,38 +102,82 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis .getMenuInfo(); switch (item.getItemId()) { - case R.id.set_labels: - if (true) { - } - return true; - case R.id.article_set_note: - if (true) { - } - return true; - case R.id.article_link_copy: if (true) { + int articleId = getArticleIdAtPosition(info.position); + + Cursor article = m_activity.getArticleById(articleId); + + if (article != null) { + m_activity.copyToClipboard(article.getString(article.getColumnIndex("link"))); + article.close(); + } } return true; case R.id.selection_toggle_marked: - if (true) { + if (getSelectedArticleCount() > 0) { + SQLiteStatement stmt = m_activity.getWritableDb() + .compileStatement( + "UPDATE articles SET marked = NOT marked WHERE selected = 1"); + stmt.execute(); + stmt.close(); + } else { + int articleId = getArticleIdAtPosition(info.position); + + SQLiteStatement stmt = m_activity.getWritableDb().compileStatement( + "UPDATE articles SET marked = NOT marked WHERE " + + BaseColumns._ID + " = ?"); + stmt.bindLong(1, articleId); + stmt.execute(); + stmt.close(); } + refresh(); return true; case R.id.selection_toggle_published: - if (true) { + if (getSelectedArticleCount() > 0) { + SQLiteStatement stmt = m_activity.getWritableDb() + .compileStatement( + "UPDATE articles SET published = NOT published WHERE selected = 1"); + stmt.execute(); + stmt.close(); + } else { + int articleId = getArticleIdAtPosition(info.position); + + SQLiteStatement stmt = m_activity.getWritableDb().compileStatement( + "UPDATE articles SET published = NOT published WHERE " + + BaseColumns._ID + " = ?"); + stmt.bindLong(1, articleId); + stmt.execute(); + stmt.close(); } + refresh(); return true; case R.id.selection_toggle_unread: - if (true) { + if (getSelectedArticleCount() > 0) { + SQLiteStatement stmt = m_activity.getWritableDb() + .compileStatement( + "UPDATE articles SET unread = NOT unread WHERE selected = 1"); + stmt.execute(); + stmt.close(); + } else { + int articleId = getArticleIdAtPosition(info.position); + + SQLiteStatement stmt = m_activity.getWritableDb().compileStatement( + "UPDATE articles SET unread = NOT unread WHERE " + + BaseColumns._ID + " = ?"); + stmt.bindLong(1, articleId); + stmt.execute(); + stmt.close(); } + refresh(); return true; case R.id.share_article: if (true) { + int articleId = getArticleIdAtPosition(info.position); + m_activity.shareArticle(articleId); } return true; - case R.id.catchup_above: - if (true) { - } + case R.id.catchup_above: return true; default: Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); @@ -155,6 +200,9 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis menu.setHeaderTitle(c.getString(c.getColumnIndex("title"))); //c.close(); menu.setGroupVisible(R.id.menu_group_single_article, true); + + menu.findItem(R.id.set_labels).setVisible(false); + menu.findItem(R.id.article_set_note).setVisible(false); } super.onCreateContextMenu(menu, v, menuInfo); @@ -189,7 +237,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis m_searchQuery = (String) savedInstanceState.getCharSequence("searchQuery"); m_feedIsCat = savedInstanceState.getBoolean("feedIsCat"); } else { - m_listener.getWritableDb().execSQL("UPDATE articles SET selected = 0 "); + m_activity.getWritableDb().execSQL("UPDATE articles SET selected = 0 "); } View view = inflater.inflate(R.layout.headlines_fragment, container, false); @@ -205,7 +253,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis list.setEmptyView(view.findViewById(R.id.no_headlines)); registerForContextMenu(list); - if (m_listener.isSmallScreen() || m_listener.isPortrait()) + if (m_activity.isSmallScreen() || m_activity.isPortrait()) view.findViewById(R.id.headlines_fragment).setPadding(0, 0, 0, 0); getActivity().setProgressBarIndeterminateVisibility(false); @@ -223,11 +271,11 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis } if (m_searchQuery.equals("")) { - return m_listener.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")", + return m_activity.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")", new String[] { "articles.*", "feeds.title AS feed_title" }, feedClause, new String[] { String.valueOf(m_feedId) }, null, null, "updated DESC"); } else { - return m_listener.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")", + return m_activity.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")", new String[] { "articles.*", "feeds.title AS feed_title" }, feedClause + " AND (articles.title LIKE '%' || ? || '%' OR content LIKE '%' || ? || '%')", new String[] { String.valueOf(m_feedId), m_searchQuery, m_searchQuery }, null, null, "updated DESC"); @@ -237,7 +285,8 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis @Override public void onAttach(Activity activity) { super.onAttach(activity); - m_listener = (OfflineHeadlinesEventListener)activity; + m_listener = (OfflineHeadlinesEventListener) activity; + m_activity = (OfflineActivity) activity; m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); m_combinedMode = m_prefs.getBoolean("combined_mode", false); @@ -254,7 +303,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis int articleId = cursor.getInt(0); - if (!m_listener.isSmallScreen()) { + if (!m_activity.isSmallScreen()) { m_activeArticleId = articleId; } @@ -391,7 +440,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis @Override public void onClick(View v) { - SQLiteStatement stmtUpdate = m_listener.getWritableDb().compileStatement("UPDATE articles SET marked = NOT marked " + + SQLiteStatement stmtUpdate = m_activity.getWritableDb().compileStatement("UPDATE articles SET marked = NOT marked " + "WHERE " + BaseColumns._ID + " = ?"); stmtUpdate.bindLong(1, articleId); @@ -412,7 +461,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis @Override public void onClick(View v) { - SQLiteStatement stmtUpdate = m_listener.getWritableDb().compileStatement("UPDATE articles SET published = NOT published " + + SQLiteStatement stmtUpdate = m_activity.getWritableDb().compileStatement("UPDATE articles SET published = NOT published " + "WHERE " + BaseColumns._ID + " = ?"); stmtUpdate.bindLong(1, articleId); @@ -490,7 +539,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis public void onClick(View view) { CheckBox cb = (CheckBox)view; - SQLiteStatement stmtUpdate = m_listener.getWritableDb().compileStatement("UPDATE articles SET selected = ? " + + SQLiteStatement stmtUpdate = m_activity.getWritableDb().compileStatement("UPDATE articles SET selected = ? " + "WHERE " + BaseColumns._ID + " = ?"); stmtUpdate.bindLong(1, cb.isChecked() ? 1 : 0); @@ -500,7 +549,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis refresh(); - m_listener.initMenu(); + m_activity.initMenu(); } });