diff options
| author | Andrew Dolgov <fox@fakecake.org> | 2012-09-19 23:49:03 +0400 |
|---|---|---|
| committer | Andrew Dolgov <fox@fakecake.org> | 2012-09-19 23:49:03 +0400 |
| commit | d361b0fec497911de1e8616cb4d0768601e07171 (patch) | |
| tree | f5f92112ca8451d255e765b9f5d1670a79b6850a /src/org/fox/ttrss/offline | |
| parent | 71fb6880f565ff417ccd5ac387263dfb8bd05826 (diff) | |
| parent | 45992f20f25bc94f2f81df2392df26b6c6f8cea7 (diff) | |
merge separate-activities
Diffstat (limited to 'src/org/fox/ttrss/offline')
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineActivity.java | 2112 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineArticleFragment.java | 79 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineArticlePager.java | 158 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineDownloadService.java | 118 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java | 59 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineFeedsActivity.java | 253 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineFeedsFragment.java | 42 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineHeadlinesActivity.java | 142 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java | 7 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java | 222 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineServices.java | 22 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineUploadService.java | 5 |
12 files changed, 1543 insertions, 1676 deletions
diff --git a/src/org/fox/ttrss/offline/OfflineActivity.java b/src/org/fox/ttrss/offline/OfflineActivity.java index 4e48a4da..42f3effc 100644 --- a/src/org/fox/ttrss/offline/OfflineActivity.java +++ b/src/org/fox/ttrss/offline/OfflineActivity.java @@ -1,1523 +1,589 @@ -package org.fox.ttrss.offline; - -import java.util.ArrayList; - -import org.fox.ttrss.CommonActivity; -import org.fox.ttrss.DummyFragment; -import org.fox.ttrss.FeedCategoriesFragment; -import org.fox.ttrss.FeedsFragment; -import org.fox.ttrss.MainActivity; -import org.fox.ttrss.OnlineServices; -import org.fox.ttrss.OnlineServices.RelativeArticle; -import org.fox.ttrss.PreferencesActivity; -import org.fox.ttrss.R; - -import android.animation.LayoutTransition; -import android.app.ActionBar; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.NotificationManager; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.database.sqlite.SQLiteStatement; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.provider.BaseColumns; -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.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.SearchView; -import android.widget.ShareActionProvider; -import android.widget.Toast; - -public class OfflineActivity extends CommonActivity implements - OfflineServices { - private final String TAG = this.getClass().getSimpleName(); - - private SharedPreferences m_prefs; - private String m_themeName = ""; - private Menu m_menu; - private boolean m_unreadOnly = true; - private boolean m_unreadArticlesOnly = true; - private boolean m_enableCats = false; - - private int m_activeFeedId = 0; - private boolean m_activeFeedIsCat = false; - private int m_activeCatId = -1; - private int m_selectedArticleId = 0; - - private ActionMode m_headlinesActionMode; - private HeadlinesActionModeCallback m_headlinesActionModeCallback; - private NavigationListener m_navigationListener; - private NavigationAdapter m_navigationAdapter; - private ArrayList<NavigationEntry> m_navigationEntries = new ArrayList<NavigationEntry>(); - - private class RootNavigationEntry extends NavigationEntry { - public RootNavigationEntry(String title) { - super(title); - } - - @Override - public void onItemSelected() { - - m_activeFeedId = 0; - m_selectedArticleId = 0; - m_activeCatId = -1; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (isSmallScreen()) { - - if (m_enableCats) { - ft.replace(R.id.fragment_container, new OfflineFeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.fragment_container, new OfflineFeedsFragment(), 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 OfflineFeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.feeds_fragment, new OfflineFeedsFragment(), FRAG_FEEDS); - } - - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - //findViewById(R.id.article_fragment).setVisibility(View.GONE); - - ft.replace(R.id.article_fragment, new DummyFragment(), ""); - } - - ft.commit(); - - initMainMenu(); - } - } - - private class CategoryNavigationEntry extends NavigationEntry { - int m_category = -1; - - public CategoryNavigationEntry(int category, String title) { - super(title); - - m_category = category; - } - - @Override - public void onItemSelected() { - m_selectedArticleId = 0; - m_activeFeedId = 0; - - 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_activeFeedIsCat) { - ft.replace(R.id.fragment_container, new OfflineFeedCategoriesFragment()); - } else { - ft.replace(R.id.fragment_container, new OfflineFeedsFragment(m_category)); - } - - } else { - ft.replace(R.id.article_fragment, new DummyFragment(), ""); - - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - //findViewById(R.id.article_fragment).setVisibility(View.GONE); - - //ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - } - - ft.commit(); - - m_activeFeedId = 0; - refreshViews(); - initMainMenu(); - } - } - - - private class FeedNavigationEntry extends NavigationEntry { - int m_feed = 0; - - public FeedNavigationEntry(int feed, String title) { - super(title); - - m_feed = feed; - } - - @Override - public void onItemSelected() { - - m_selectedArticleId = 0; - - 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<NavigationEntry> { - public NavigationAdapter(Context context, int textViewResourceId, ArrayList<NavigationEntry> items) { - super(context, textViewResourceId, items); - } - } - - 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 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) { - 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); - - //requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); - - NotificationManager nmgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - nmgr.cancel(OfflineDownloadService.NOTIFY_DOWNLOADING); - - m_themeName = m_prefs.getString("theme", "THEME_DARK"); - - if (savedInstanceState != null) { - m_unreadOnly = savedInstanceState.getBoolean("unreadOnly"); - m_unreadArticlesOnly = savedInstanceState - .getBoolean("unreadArticlesOnly"); - m_activeFeedId = savedInstanceState.getInt("offlineActiveFeedId"); - m_selectedArticleId = savedInstanceState.getInt("offlineArticleId"); - m_activeFeedIsCat = savedInstanceState.getBoolean("activeFeedIsCat"); - m_activeCatId = savedInstanceState.getInt("activeCatId"); - } - - m_enableCats = m_prefs.getBoolean("enable_cats", false); - - setContentView(R.layout.main); - - setSmallScreen(findViewById(R.id.headlines_fragment) == null); - - if (!isCompatMode()) { - if (!isSmallScreen()) { - findViewById(R.id.feeds_fragment).setVisibility(m_selectedArticleId != 0 && (isPortrait() || isSmallTablet()) ? View.GONE : View.VISIBLE); - findViewById(R.id.article_fragment).setVisibility(m_selectedArticleId != 0 ? 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); - - m_headlinesActionModeCallback = new HeadlinesActionModeCallback(); - } - - initMainMenu(); - - findViewById(R.id.loading_container).setVisibility(View.GONE); - - if (isSmallScreen()) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - // temporary workaround against viewpager going a bit crazy when restoring after rotation - if (m_selectedArticleId != 0) { - ft.remove(getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE)); - m_selectedArticleId = 0; - } - ft.commit(); - } - - if (m_activeFeedId == 0 && !m_activeFeedIsCat) { - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - Fragment frag = null; - String tag = null; - - if (m_enableCats) { - frag = new OfflineFeedCategoriesFragment(); - tag = FRAG_CATS; - } else { - frag = new OfflineFeedsFragment(); - tag = FRAG_FEEDS; - } - - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, frag, tag); - } else { - ft.replace(R.id.feeds_fragment, frag, tag); - } - - ft.commit(); - } - - - } - - private void switchOnline() { - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = localPrefs.edit(); - editor.putBoolean("offline_mode_active", false); - editor.commit(); - - Intent refresh = new Intent(this, MainActivity.class); - startActivity(refresh); - finish(); - } - - @Override - public int getActiveFeedId() { - return m_activeFeedId; - } - - /* 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.putBoolean("unreadOnly", m_unreadOnly); - out.putBoolean("unreadArticlesOnly", m_unreadArticlesOnly); - out.putInt("offlineActiveFeedId", m_activeFeedId); - out.putInt("offlineArticleId", m_selectedArticleId); - out.putBoolean("activeFeedIsCat", m_activeFeedIsCat); - out.putInt("activeCatId", m_activeCatId); - } - - private void setUnreadOnly(boolean unread) { - m_unreadOnly = unread; - - refreshViews(); - - /* - * if (!m_enableCats || m_activeCategory != null ) refreshFeeds(); else - * refreshCategories(); - */ - } - - @Override - public boolean getUnreadOnly() { - return m_unreadOnly; - } - - @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) { - Intent refresh = new Intent(this, OfflineActivity.class); - startActivity(refresh); - finish(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.offline_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); - } - - return true; - } - - private void goBack(boolean allowQuit) { - if (isSmallScreen()) { - if (m_selectedArticleId != 0) { - closeArticle(); - } else if (m_activeFeedId != 0) { - m_activeFeedId = 0; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (m_activeFeedIsCat) { - ft.replace(R.id.fragment_container, new OfflineFeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.fragment_container, new OfflineFeedsFragment(m_activeCatId), FRAG_FEEDS); - } - ft.commit(); - - refreshViews(); - initMainMenu(); - } else if (m_activeCatId != -1) { - closeCategory(); - } else if (allowQuit) { - finish(); - } - } else { - if (m_selectedArticleId != 0) { - closeArticle(); - /* } else if (m_activeFeedId != 0) { - m_activeFeedId = 0; - - OfflineFeedsFragment ff = (OfflineFeedsFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_FEEDS); - - OfflineFeedCategoriesFragment cf = (OfflineFeedCategoriesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_CATS); - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - ft.commit(); - - if (ff != null) { - ff.setSelectedFeedId(0); - } - - if (cf != null) { - cf.setSelectedFeedId(-1); - } - - refreshViews(); - initMainMenu(); */ - } else if (m_activeCatId != -1) { - closeCategory(); - } else if (allowQuit) { - finish(); - } - } - } - - @Override - public void onBackPressed() { - goBack(true); - } - - /* - * @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if - * (keyCode == KeyEvent.KEYCODE_BACK) { - * - * if (isSmallScreen()) { if (m_selectedArticleId != 0) { closeArticle(); - * } else if (m_activeFeedId != 0) { if (isCompatMode()) { - * findViewById(R.id.main).setAnimation(AnimationUtils.loadAnimation(this, - * R.anim.slide_right)); } - */ - - /* - * if (m_activeFeed != null && m_activeFeed.is_cat) { - * findViewById(R.id.headlines_fragment).setVisibility(View.GONE); - * findViewById(R.id.cats_fragment).setVisibility(View.VISIBLE); - * - * refreshCategories(); } else { - *//* - * findViewById(R.id.headlines_fragment).setVisibility(View.GONE); - * findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); //} - * m_activeFeedId = 0; refreshViews(); initMainMenu(); - * - * } else { finish(); } } else { if (m_selectedArticleId != 0) { - * closeArticle(); } else { finish(); } } - * - * return false; } return super.onKeyDown(keyCode, event); } - */ - - private Cursor getArticleById(int articleId) { - Cursor c = getReadableDb().query("articles", null, - BaseColumns._ID + "=?", - new String[] { String.valueOf(articleId) }, null, null, null); - - c.moveToFirst(); - - return c; - } - - private Cursor getFeedById(int feedId) { - Cursor c = getReadableDb().query("feeds", null, - BaseColumns._ID + "=?", - new String[] { String.valueOf(feedId) }, null, null, null); - - c.moveToFirst(); - - return c; - } - - private Cursor getCatById(int catId) { - Cursor c = getReadableDb().query("categories", null, - BaseColumns._ID + "=?", - new String[] { String.valueOf(catId) }, null, null, null); - - c.moveToFirst(); - - return c; - } - - private Intent getShareIntent(Cursor article) { - String title = article.getString(article.getColumnIndex("title")); - String link = article.getString(article.getColumnIndex("link")); - - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_SUBJECT, title); - intent.putExtra(Intent.EXTRA_TEXT, link); - - return intent; - } - - private void shareArticle(int articleId) { - - Cursor article = getArticleById(articleId); - - if (article != null) { - shareArticle(article); - article.close(); - } - } - - private void shareArticle(Cursor article) { - if (article != null) { - Intent intent = getShareIntent(article); - - startActivity(Intent.createChooser(intent, - getString(R.id.share_article))); - } - } - - private void refreshHeadlines() { - OfflineHeadlinesFragment ohf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (ohf != null) { - ohf.refresh(); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final OfflineHeadlinesFragment ohf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - switch (item.getItemId()) { - case R.id.close_feed: - if (m_activeFeedId != 0 || m_activeFeedIsCat) { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - ft.replace(R.id.headlines_fragment, new DummyFragment(), ""); - ft.commit(); - - if (m_activeFeedIsCat) { - OfflineFeedCategoriesFragment cats = (OfflineFeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - cats.setSelectedFeedId(-1); - } else { - OfflineFeedsFragment feeds = (OfflineFeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - feeds.setSelectedFeedId(0); - } - - m_activeFeedId = 0; - - 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 (ohf != 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(); - - ohf.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(this, PreferencesActivity.class); - startActivityForResult(intent, 0); - return true; - case R.id.go_online: - switchOnline(); - return true; - case R.id.headlines_select: - if (ohf != null) { - Dialog dialog = new Dialog(this); - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.headlines_select_dialog); - - builder.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: - SQLiteStatement stmtSelectAll = getWritableDb() - .compileStatement( - "UPDATE articles SET selected = 1 WHERE feed_id = ?"); - stmtSelectAll.bindLong(1, m_activeFeedId); - stmtSelectAll.execute(); - stmtSelectAll.close(); - break; - case 1: - SQLiteStatement stmtSelectUnread = getWritableDb() - .compileStatement( - "UPDATE articles SET selected = 1 WHERE feed_id = ? AND unread = 1"); - stmtSelectUnread - .bindLong(1, m_activeFeedId); - stmtSelectUnread.execute(); - stmtSelectUnread.close(); - break; - case 2: - deselectAllArticles(); - break; - } - - refreshViews(); - initMainMenu(); - - dialog.cancel(); - } - }); - - dialog = builder.create(); - dialog.show(); - } - return true; - case R.id.headlines_mark_as_read: - if (m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 WHERE feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.share_article: - if (android.os.Build.VERSION.SDK_INT < 14) { - shareArticle(m_selectedArticleId); - } - return true; - case R.id.toggle_marked: - if (m_selectedArticleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET marked = NOT marked WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, m_selectedArticleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.selection_select_none: - deselectAllArticles(); - return true; - case R.id.selection_toggle_unread: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET unread = NOT unread WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.selection_toggle_marked: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET marked = NOT marked WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.selection_toggle_published: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET published = NOT published WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.toggle_published: - if (m_selectedArticleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET published = NOT published WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, m_selectedArticleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.catchup_above: - if (m_selectedArticleId != 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 WHERE updated >= " - + "(SELECT updated FROM articles WHERE " - + BaseColumns._ID + " = ?) AND feed_id = ?"); - stmt.bindLong(1, m_selectedArticleId); - stmt.bindLong(2, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.set_unread: - if (m_selectedArticleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 1 WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, m_selectedArticleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - 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; - default: - Log.d(TAG, - "onOptionsItemSelected, unhandled id=" + item.getItemId()); - return super.onOptionsItemSelected(item); - } - } - - private void refreshFeeds() { - OfflineFeedsFragment frag = (OfflineFeedsFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_FEEDS); - - if (frag != null) { - frag.refresh(); - } - } - - private void refreshCats() { - OfflineFeedCategoriesFragment frag = (OfflineFeedCategoriesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_CATS); - - if (frag != null) { - frag.refresh(); - } - } - - private void closeArticle() { - m_selectedArticleId = 0; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (isSmallScreen()) { - ft.remove(getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE)); - ft.show(getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES)); - } else { - findViewById(R.id.feeds_fragment).setVisibility(View.VISIBLE); - findViewById(R.id.article_fragment).setVisibility(View.GONE); - ft.replace(R.id.article_fragment, new DummyFragment(), FRAG_ARTICLE); - } - ft.commit(); - - initMainMenu(); - - refreshViews(); - } - - private int getSelectedArticleCount() { - Cursor c = getReadableDb().query("articles", - new String[] { "COUNT(*)" }, "selected = 1", null, null, null, - null); - c.moveToFirst(); - int selected = c.getInt(0); - c.close(); - - return selected; - } - - @Override - public void initMainMenu() { - if (m_menu != null) { - int numSelected = getSelectedArticleCount(); - - m_menu.setGroupVisible(R.id.menu_group_feeds, false); - m_menu.setGroupVisible(R.id.menu_group_headlines, false); - m_menu.setGroupVisible(R.id.menu_group_headlines_selection, false); - m_menu.setGroupVisible(R.id.menu_group_article, false); - - if (numSelected != 0) { - if (isCompatMode()) { - m_menu.setGroupVisible(R.id.menu_group_headlines_selection, true); - } else { - if (m_headlinesActionMode == null) - m_headlinesActionMode = startActionMode(m_headlinesActionModeCallback); - } - } else if (m_selectedArticleId != 0) { - m_menu.setGroupVisible(R.id.menu_group_article, true); - m_menu.findItem(R.id.close_article).setVisible(!isSmallScreen()); - - if (android.os.Build.VERSION.SDK_INT >= 14) { - ShareActionProvider shareProvider = (ShareActionProvider) m_menu.findItem(R.id.share_article).getActionProvider(); - - if (m_selectedArticleId != 0) { - Log.d(TAG, "setting up share provider"); - shareProvider.setShareIntent(getShareIntent(getArticleById(m_selectedArticleId))); - - if (!m_prefs.getBoolean("tablet_article_swipe", false) && !isSmallScreen()) { - m_menu.findItem(R.id.share_article).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - } - } - } - } else if (m_activeFeedId != 0) { - m_menu.setGroupVisible(R.id.menu_group_headlines, true); - m_menu.findItem(R.id.close_feed).setVisible(!isSmallScreen()); - - MenuItem search = m_menu.findItem(R.id.search); - - if (!isCompatMode()) { - 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; - } - }); - } - - } else { - m_menu.setGroupVisible(R.id.menu_group_feeds, true); - } - - if (numSelected == 0 && m_headlinesActionMode != null) { - m_headlinesActionMode.finish(); - } - } - - updateTitle(); - } - - @Override - public void onPause() { - super.onPause(); - - } - - @Override - public void onDestroy() { - super.onDestroy(); - } - - private void refreshViews() { - refreshFeeds(); - refreshCats(); - refreshHeadlines(); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo) item - .getMenuInfo(); - - OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - OfflineFeedsFragment ff = (OfflineFeedsFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_FEEDS); - OfflineFeedCategoriesFragment cf = (OfflineFeedCategoriesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_CATS); - - switch (item.getItemId()) { - case R.id.article_link_copy: - if (m_selectedArticleId != 0) { - Cursor article = null; - - if (m_selectedArticleId != 0) { - article = getArticleById(m_selectedArticleId); - } else if (info != null) { - article = hf.getArticleAtPosition(info.position); - } - - if (article != null) { - copyToClipboard(article.getString(article.getColumnIndex("link"))); - article.close(); - } - } - return true; - case R.id.article_link_share: - if (m_selectedArticleId != 0) { - shareArticle(m_selectedArticleId); - } - return true; - - case R.id.browse_articles: - if (cf != null) { - int catId = cf.getCatIdAtPosition(info.position); - viewFeed(catId, true); - } - return true; - case R.id.browse_feeds: - if (cf != null) { - int catId = cf.getCatIdAtPosition(info.position); - viewCategory(catId, false); - } - return true; - case R.id.catchup_category: - if (cf != null) { - int catId = cf.getCatIdAtPosition(info.position); - - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 WHERE feed_id IN (SELECT "+ - BaseColumns._ID+" FROM feeds WHERE cat_id = ?)"); - stmt.bindLong(1, catId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - case R.id.catchup_feed: - if (ff != null) { - int feedId = ff.getFeedIdAtPosition(info.position); - - if (feedId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 WHERE feed_id = ?"); - stmt.bindLong(1, feedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - } - return true; - case R.id.selection_toggle_unread: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET unread = NOT unread WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } else { - int articleId = hf.getArticleIdAtPosition(info.position); - if (articleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = NOT unread WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - } - return true; - case R.id.selection_toggle_marked: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET marked = NOT marked WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } else { - int articleId = hf.getArticleIdAtPosition(info.position); - if (articleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET marked = NOT marked WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - } - return true; - case R.id.selection_toggle_published: - if (getSelectedArticleCount() > 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET published = NOT published WHERE selected = 1 AND feed_id = ?"); - stmt.bindLong(1, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } else { - int articleId = hf.getArticleIdAtPosition(info.position); - if (articleId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET published = NOT published WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - } - return true; - case R.id.share_article: - Cursor article = hf.getArticleAtPosition(info.position); - - if (article != null) { - shareArticle(article); - } - return true; - case R.id.catchup_above: - int articleId = hf.getArticleIdAtPosition(info.position); - - if (articleId != 0 && m_activeFeedId != 0) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 WHERE updated >= " - + "(SELECT updated FROM articles WHERE " - + BaseColumns._ID + " = ?) AND feed_id = ?"); - stmt.bindLong(1, articleId); - stmt.bindLong(2, m_activeFeedId); - stmt.execute(); - stmt.close(); - refreshViews(); - } - return true; - default: - Log.d(TAG, - "onContextItemSelected, unhandled id=" + item.getItemId()); - return super.onContextItemSelected(item); - } - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - int action = event.getAction(); - int keyCode = event.getKeyCode(); - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_DOWN: - if (action == KeyEvent.ACTION_DOWN) { - - OfflineHeadlinesFragment ohf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - int nextId = getRelativeArticleId(m_selectedArticleId, - m_activeFeedId, RelativeArticle.AFTER); - - if (nextId != 0 && ohf != null) { - if (m_prefs.getBoolean("combined_mode", false)) { - ohf.setActiveArticleId(nextId); - - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET unread = 0 " - + "WHERE " + BaseColumns._ID - + " = ?"); - - stmt.bindLong(1, nextId); - stmt.execute(); - stmt.close(); - - } else { - openArticle(nextId, 0); - } - } - } - return true; - case KeyEvent.KEYCODE_VOLUME_UP: - if (action == KeyEvent.ACTION_UP) { - - OfflineHeadlinesFragment ohf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - int prevId = getRelativeArticleId(m_selectedArticleId, - m_activeFeedId, RelativeArticle.BEFORE); - - if (prevId != 0 && ohf != null) { - if (m_prefs.getBoolean("combined_mode", false)) { - ohf.setActiveArticleId(prevId); - - SQLiteStatement stmt = getWritableDb() - .compileStatement( - "UPDATE articles SET unread = 0 " - + "WHERE " + BaseColumns._ID - + " = ?"); - - stmt.bindLong(1, prevId); - stmt.execute(); - stmt.close(); - - } else { - openArticle(prevId, 0); - } - } - } - return true; - default: - return super.dispatchKeyEvent(event); - } - } - - private void deselectAllArticles() { - getWritableDb().execSQL("UPDATE articles SET selected = 0 "); - } - - @Override - public int getRelativeArticleId(int baseId, int feedId, - OnlineServices.RelativeArticle mode) { - - Cursor c; - - /* - * if (baseId == 0) { c = getReadableDb().query("articles", null, - * "feed_id = ?", new String[] { String.valueOf(feedId) }, null, null, - * "updated DESC LIMIT 1"); - * - * if (c.moveToFirst()) { baseId = c.getInt(0); } - * - * c.close(); - * - * return baseId; } - */ - - if (mode == RelativeArticle.BEFORE) { - c = getReadableDb().query( - "articles", - null, - "updated > (SELECT updated FROM articles WHERE " - + BaseColumns._ID + " = ?) AND feed_id = ?", - new String[] { String.valueOf(baseId), - String.valueOf(feedId) }, null, null, - "updated LIMIT 1"); - - } else { - c = getReadableDb().query( - "articles", - null, - "updated < (SELECT updated FROM articles WHERE " - + BaseColumns._ID + " = ?) AND feed_id = ?", - new String[] { String.valueOf(baseId), - String.valueOf(feedId) }, null, null, - "updated DESC LIMIT 1"); - } - - int id = 0; - - if (c.moveToFirst()) { - id = c.getInt(0); - } - - c.close(); - - return id; - } - - public void onCatSelected(int catId) { - Log.d(TAG, "onCatSelected"); - boolean browse = m_prefs.getBoolean("browse_cats_like_feeds", false); - - viewCategory(catId, browse); - } - - public void viewCategory(int cat, boolean openAsFeed) { - - Log.d(TAG, "viewCategory"); - - if (!openAsFeed) { - OfflineFeedsFragment frag = new OfflineFeedsFragment(cat); - - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, frag, FRAG_FEEDS); - } else { - ft.replace(R.id.feeds_fragment, frag, FRAG_FEEDS); - } - ft.commit(); - - m_activeCatId = cat; - - } else { - if (m_menu != null) { - MenuItem search = m_menu.findItem(R.id.search); - - if (search != null && !isCompatMode()) { - SearchView sv = (SearchView) search.getActionView(); - sv.setQuery("", false); - } - } - viewFeed(cat, true); - } - - initMainMenu(); - } - - @Override - public void onFeedSelected(int feedId) { - viewFeed(feedId); - } - - public void viewFeed(int feedId) { - viewFeed(feedId, false); - } - - public void viewFeed(int feedId, boolean isCat) { - m_activeFeedId = feedId; - m_activeFeedIsCat = isCat; - - initMainMenu(); - - deselectAllArticles(); - - if (m_menu != null) { - MenuItem search = m_menu.findItem(R.id.search); - - if (search != null && !isCompatMode()) { - SearchView sv = (SearchView) search.getActionView(); - sv.setQuery("", false); - } - } - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - OfflineHeadlinesFragment frag = new OfflineHeadlinesFragment(feedId, isCat); - - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, frag, FRAG_HEADLINES); - } else { - findViewById(R.id.headlines_fragment).setVisibility(View.VISIBLE); - ft.replace(R.id.headlines_fragment, frag, FRAG_HEADLINES); - } - ft.commit(); - - } - - @Override - public void openArticle(int articleId, int compatAnimation) { - m_selectedArticleId = articleId; - - initMainMenu(); - - /* OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (hf != null) { - hf.setActiveArticleId(articleId); - } */ - - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET unread = 0 " + "WHERE " + BaseColumns._ID - + " = ?"); - - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - - Fragment frag; - - if (isSmallScreen() || m_prefs.getBoolean("tablet_article_swipe", false)) { - frag = new OfflineArticlePager(articleId); - } else { - frag = new OfflineArticleFragment(articleId); - } - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (isSmallScreen()) { - ft.hide(getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES)); - ft.add(R.id.fragment_container, frag, FRAG_ARTICLE); - } else { - findViewById(R.id.feeds_fragment).setVisibility(isPortrait() || isSmallTablet() ? View.GONE : View.VISIBLE); - findViewById(R.id.article_fragment).setVisibility(View.VISIBLE); - ft.replace(R.id.article_fragment, frag, FRAG_ARTICLE); - - refreshViews(); - } - - ft.commit(); - } - - @Override - public int getSelectedArticleId() { - return m_selectedArticleId; - } - - @Override - public void setSelectedArticleId(int articleId) { - m_selectedArticleId = articleId; - initMainMenu(); - refreshViews(); - } - - private void closeCategory() { - m_activeCatId = -1; - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - if (isSmallScreen()) { - ft.replace(R.id.fragment_container, new OfflineFeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.feeds_fragment, new OfflineFeedCategoriesFragment(), FRAG_CATS); - } - ft.commit(); - - initMainMenu(); - - refreshViews(); - } - - @Override - public boolean activeFeedIsCat() { - return m_activeFeedIsCat; - } - - private void updateTitle() { - if (!isCompatMode()) { - - m_navigationAdapter.clear(); - - if (m_activeCatId != -1 || (m_activeFeedId != 0 && (isSmallScreen() || isPortrait()))) { - getActionBar().setDisplayShowTitleEnabled(false); - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); - - m_navigationAdapter.add(new RootNavigationEntry(getString(R.string.app_name))); - - if (m_activeCatId != -1) { - Cursor cat = getCatById(m_activeCatId); - String title = cat.getString(cat.getColumnIndex("title")); - m_navigationAdapter.add(new CategoryNavigationEntry(m_activeCatId, title)); - cat.close(); - } - - if (m_activeFeedId != 0) { - Cursor feed = null; - if (m_activeFeedIsCat) { - feed = getCatById(m_activeFeedId); - } else { - feed = getFeedById(m_activeFeedId); - } - String title = feed.getString(feed.getColumnIndex("title")); - m_navigationAdapter.add(new FeedNavigationEntry(m_activeFeedId, title)); - feed.close(); - } - - //if (m_selectedArticle != null) - // m_navigationAdapter.add(new ArticleNavigationEntry(m_selectedArticle)); - - getActionBar().setSelectedNavigationItem(getActionBar().getNavigationItemCount()); - - } else { - getActionBar().setDisplayShowTitleEnabled(true); - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); - getActionBar().setTitle(R.string.app_name); - } - - if (isSmallScreen()) { - getActionBar().setDisplayHomeAsUpEnabled(m_selectedArticleId != 0 || m_activeFeedId != 0 || m_activeCatId != -1); - } else { - getActionBar().setDisplayHomeAsUpEnabled(m_selectedArticleId != 0 || m_activeCatId != -1); - } - - } else { - if (m_activeFeedId != 0) { - if (!m_activeFeedIsCat) { - Cursor feed = getFeedById(m_activeFeedId); - - if (feed != null) { - setTitle(feed.getString(feed.getColumnIndex("title"))); - feed.close(); - } - } else { - Cursor cat = getCatById(m_activeFeedId); - - if (cat != null) { - setTitle(cat.getString(cat.getColumnIndex("title"))); - cat.close(); - } - } - } else if (m_activeCatId != -1) { - Cursor cat = getCatById(m_activeCatId); - - if (cat != null) { - setTitle(cat.getString(cat.getColumnIndex("title"))); - cat.close(); - } - - } else { - setTitle(R.string.app_name); - } - - } - } -}
\ No newline at end of file +package org.fox.ttrss.offline;
+
+import org.fox.ttrss.CommonActivity;
+import org.fox.ttrss.PreferencesActivity;
+import org.fox.ttrss.R;
+
+import android.annotation.SuppressLint;
+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.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.view.Window;
+import android.widget.EditText;
+import android.widget.SearchView;
+import android.widget.ShareActionProvider;
+
+public class OfflineActivity extends CommonActivity {
+ private final String TAG = this.getClass().getSimpleName();
+
+ protected SharedPreferences m_prefs;
+ protected Menu m_menu;
+
+ private ActionMode m_headlinesActionMode;
+ private HeadlinesActionModeCallback m_headlinesActionModeCallback;
+
+ @SuppressLint("NewApi")
+ 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;
+ initMenu();
+ }
+
+ @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) {
+ 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);
+
+ requestWindowFeature(Window.FEATURE_PROGRESS);
+
+ setProgressBarVisibility(false);
+
+ setContentView(R.layout.login);
+
+ setLoadingStatus(R.string.blank, false);
+ findViewById(R.id.loading_container).setVisibility(View.GONE);
+
+ initMenu();
+
+ Intent intent = getIntent();
+
+ if (intent.getExtras() != null) {
+ if (intent.getBooleanExtra("initial", false)) {
+ intent = new Intent(OfflineActivity.this, OfflineFeedsActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+
+ startActivityForResult(intent, 0);
+ finish();
+ }
+ }
+
+ /* if (savedInstanceState != null) {
+
+ } */
+
+ if (!isCompatMode()) {
+ m_headlinesActionModeCallback = new HeadlinesActionModeCallback();
+ }
+
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle out) {
+ super.onSaveInstanceState(out);
+ }
+
+ protected void selectArticles(int feedId, boolean isCat, int mode) {
+ switch (mode) {
+ case 0:
+ SQLiteStatement stmtSelectAll = null;
+
+ if (isCat) {
+ stmtSelectAll = getWritableDb().compileStatement(
+ "UPDATE articles SET selected = 1 WHERE feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)");
+ } else {
+ stmtSelectAll = getWritableDb().compileStatement(
+ "UPDATE articles SET selected = 1 WHERE feed_id = ?");
+ }
+
+ stmtSelectAll.bindLong(1, feedId);
+ stmtSelectAll.execute();
+ stmtSelectAll.close();
+
+ break;
+ case 1:
+
+ SQLiteStatement stmtSelectUnread = null;
+
+ if (isCat) {
+ stmtSelectUnread = getWritableDb().compileStatement(
+ "UPDATE articles SET selected = 1 WHERE feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?) AND unread = 1");
+ } else {
+ stmtSelectUnread = getWritableDb().compileStatement(
+ "UPDATE articles SET selected = 1 WHERE feed_id = ? AND unread = 1");
+ }
+
+ stmtSelectUnread.bindLong(1, feedId);
+ stmtSelectUnread.execute();
+ stmtSelectUnread.close();
+
+ break;
+ case 2:
+ deselectAllArticles();
+ break;
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ final OfflineHeadlinesFragment ohf = (OfflineHeadlinesFragment) getSupportFragmentManager()
+ .findFragmentByTag(FRAG_HEADLINES);
+
+ /* final OfflineFeedsFragment off = (OfflineFeedsFragment) getSupportFragmentManager()
+ .findFragmentByTag(FRAG_FEEDS); */
+
+ /* final OfflineFeedCategoriesFragment ocf = (OfflineFeedCategoriesFragment) getSupportFragmentManager()
+ .findFragmentByTag(FRAG_CATS); */
+
+ final OfflineArticlePager oap = (OfflineArticlePager) getSupportFragmentManager()
+ .findFragmentByTag(FRAG_ARTICLE);
+
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ case R.id.go_online:
+ switchOnline();
+ return true;
+ case R.id.search:
+ if (ohf != 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();
+
+ ohf.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(this, PreferencesActivity.class);
+ startActivityForResult(intent, 0);
+ return true;
+ case R.id.headlines_select:
+ if (ohf != null) {
+ Dialog dialog = new Dialog(this);
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.headlines_select_dialog);
+
+ builder.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) {
+
+ selectArticles(ohf.getFeedId(), ohf.getFeedIsCat(), which);
+ initMenu();
+ refresh();
+
+ dialog.cancel();
+ }
+ });
+
+ dialog = builder.create();
+ dialog.show();
+ }
+ return true;
+ case R.id.headlines_mark_as_read:
+ if (ohf != null) {
+ int feedId = ohf.getFeedId();
+ boolean isCat = ohf.getFeedIsCat();
+
+ SQLiteStatement stmt = null;
+
+ if (isCat) {
+ stmt = getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 WHERE feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)");
+ } else {
+ stmt = getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 WHERE feed_id = ?");
+ }
+ stmt.bindLong(1, feedId);
+ stmt.execute();
+ stmt.close();
+
+ refresh();
+ }
+ return true;
+ case R.id.share_article:
+ if (android.os.Build.VERSION.SDK_INT < 14 && oap != null && android.os.Build.VERSION.SDK_INT < 14) {
+ int articleId = oap.getSelectedArticleId();
+
+ shareArticle(articleId);
+ }
+ return true;
+ case R.id.toggle_marked:
+ if (oap != null) {
+ int articleId = oap.getSelectedArticleId();
+
+ SQLiteStatement stmt = 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_select_none:
+ deselectAllArticles();
+ return true;
+ case R.id.selection_toggle_unread:
+ if (getSelectedArticleCount() > 0) {
+ SQLiteStatement stmt = getWritableDb()
+ .compileStatement(
+ "UPDATE articles SET unread = NOT unread WHERE selected = 1");
+ stmt.execute();
+ stmt.close();
+
+ refresh();
+ }
+ return true;
+ case R.id.selection_toggle_marked:
+ if (getSelectedArticleCount() > 0) {
+ SQLiteStatement stmt = getWritableDb()
+ .compileStatement(
+ "UPDATE articles SET marked = NOT marked WHERE selected = 1");
+ stmt.execute();
+ stmt.close();
+
+ refresh();
+ }
+ return true;
+ case R.id.selection_toggle_published:
+ if (getSelectedArticleCount() > 0) {
+ SQLiteStatement stmt = getWritableDb()
+ .compileStatement(
+ "UPDATE articles SET published = NOT published WHERE selected = 1");
+ stmt.execute();
+ stmt.close();
+
+ refresh();
+ }
+ return true;
+ case R.id.toggle_published:
+ if (oap != null) {
+ int articleId = oap.getSelectedArticleId();
+
+ SQLiteStatement stmt = 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.catchup_above:
+ if (oap != null) {
+ int articleId = oap.getSelectedArticleId();
+ int feedId = oap.getFeedId();
+ boolean isCat = oap.getFeedIsCat();
+
+ SQLiteStatement stmt = null;
+
+ if (isCat) {
+ stmt = getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 WHERE " +
+ "updated >= (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " +
+ "AND feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)");
+ } else {
+ stmt = getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 WHERE " +
+ "updated >= (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " +
+ "AND feed_id = ?");
+ }
+
+ stmt.bindLong(1, articleId);
+ stmt.bindLong(2, feedId);
+ stmt.execute();
+ stmt.close();
+
+ refresh();
+ }
+ return true;
+ case R.id.set_unread:
+ if (oap != null) {
+ int articleId = oap.getSelectedArticleId();
+
+ SQLiteStatement stmt = getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 1 WHERE "
+ + BaseColumns._ID + " = ?");
+ stmt.bindLong(1, articleId);
+ stmt.execute();
+ stmt.close();
+
+ refresh();
+ }
+ return true;
+ default:
+ Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId());
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.offline_menu, menu);
+
+ m_menu = menu;
+
+ initMenu();
+
+ return true;
+ }
+
+ @SuppressLint("NewApi")
+ protected void initMenu() {
+ if (m_menu != null) {
+ m_menu.setGroupVisible(R.id.menu_group_headlines, false);
+ 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) {
+ 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;
+ }
+ });
+ }
+ }
+ }
+
+ private void switchOnline() {
+ SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = localPrefs.edit();
+ editor.putBoolean("offline_mode_active", false);
+ editor.commit();
+
+ Intent refresh = new Intent(this, org.fox.ttrss.OnlineActivity.class);
+ startActivity(refresh);
+ finish();
+ }
+
+ protected Cursor getArticleById(int articleId) {
+ Cursor c = getReadableDb().query("articles", null,
+ BaseColumns._ID + "=?",
+ new String[] { String.valueOf(articleId) }, null, null, null);
+
+ c.moveToFirst();
+
+ return c;
+ }
+
+ protected Cursor getFeedById(int feedId) {
+ Cursor c = getReadableDb().query("feeds", null,
+ BaseColumns._ID + "=?",
+ new String[] { String.valueOf(feedId) }, null, null, null);
+
+ c.moveToFirst();
+
+ return c;
+ }
+
+ protected Cursor getCatById(int catId) {
+ Cursor c = getReadableDb().query("categories", null,
+ BaseColumns._ID + "=?",
+ new String[] { String.valueOf(catId) }, null, null, null);
+
+ c.moveToFirst();
+
+ return c;
+ }
+
+ protected Intent getShareIntent(Cursor article) {
+ String title = article.getString(article.getColumnIndex("title"));
+ String link = article.getString(article.getColumnIndex("link"));
+
+ Intent intent = new Intent(Intent.ACTION_SEND);
+
+ intent.setType("text/plain");
+ intent.putExtra(Intent.EXTRA_SUBJECT, title);
+ intent.putExtra(Intent.EXTRA_TEXT, link);
+
+ return intent;
+ }
+
+ protected void shareArticle(int articleId) {
+
+ Cursor article = getArticleById(articleId);
+
+ if (article != null) {
+ shareArticle(article);
+ article.close();
+ }
+ }
+
+ private void shareArticle(Cursor article) {
+ if (article != null) {
+ Intent intent = getShareIntent(article);
+
+ startActivity(Intent.createChooser(intent,
+ getString(R.string.share_article)));
+ }
+ }
+
+ protected int getSelectedArticleCount() {
+ Cursor c = getReadableDb().query("articles",
+ new String[] { "COUNT(*)" }, "selected = 1", null, null, null,
+ null);
+ c.moveToFirst();
+ int selected = c.getInt(0);
+ c.close();
+
+ return selected;
+ }
+
+ protected void deselectAllArticles() {
+ getWritableDb().execSQL("UPDATE articles SET selected = 0 ");
+ refresh();
+ }
+
+ protected void refresh() {
+ OfflineFeedsFragment ff = (OfflineFeedsFragment) getSupportFragmentManager()
+ .findFragmentByTag(FRAG_FEEDS);
+
+ if (ff != null) {
+ ff.refresh();
+ }
+
+ OfflineFeedCategoriesFragment cf = (OfflineFeedCategoriesFragment) getSupportFragmentManager()
+ .findFragmentByTag(FRAG_CATS);
+
+ if (cf != null) {
+ cf.refresh();
+ }
+
+ OfflineHeadlinesFragment ohf = (OfflineHeadlinesFragment) getSupportFragmentManager()
+ .findFragmentByTag(FRAG_HEADLINES);
+
+ if (ohf != null) {
+ ohf.refresh();
+ }
+ }
+
+}
diff --git a/src/org/fox/ttrss/offline/OfflineArticleFragment.java b/src/org/fox/ttrss/offline/OfflineArticleFragment.java index ebe11fc8..98ce59f4 100644 --- a/src/org/fox/ttrss/offline/OfflineArticleFragment.java +++ b/src/org/fox/ttrss/offline/OfflineArticleFragment.java @@ -10,34 +10,42 @@ import org.jsoup.nodes.Document; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
+import android.annotation.SuppressLint;
import android.app.Activity;
+import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
+import android.graphics.Paint;
+import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.support.v4.app.Fragment;
import android.text.Html;
import android.text.method.LinkMovementMethod;
+import android.util.Log;
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
+import android.view.View.OnClickListener;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
-import android.webkit.WebView;
import android.webkit.WebSettings.LayoutAlgorithm;
+import android.webkit.WebView;
import android.widget.TextView;
public class OfflineArticleFragment extends Fragment {
- @SuppressWarnings("unused")
private final String TAG = this.getClass().getSimpleName();
private SharedPreferences m_prefs;
private int m_articleId;
+ private boolean m_isCat = false; // FIXME use
private Cursor m_cursor;
- private OfflineServices m_offlineServices;
+ private OfflineActivity m_activity;
public OfflineArticleFragment() {
super();
@@ -48,6 +56,32 @@ public class OfflineArticleFragment extends Fragment { m_articleId = articleId;
}
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ /* AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+ .getMenuInfo(); */
+
+ switch (item.getItemId()) {
+ case R.id.article_link_share:
+ m_activity.shareArticle(m_articleId);
+ return true;
+ case R.id.article_link_copy:
+ if (true) {
+ Cursor article = m_activity.getArticleById(m_articleId);
+
+ if (article != null) {
+ m_activity.copyToClipboard(article.getString(article.getColumnIndex("link")));
+ article.close();
+ }
+ }
+ 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) {
@@ -59,6 +93,7 @@ public class OfflineArticleFragment extends Fragment { }
+ @SuppressLint("NewApi")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -68,7 +103,7 @@ public class OfflineArticleFragment extends Fragment { View view = inflater.inflate(R.layout.article_fragment, container, false);
- m_cursor = m_offlineServices.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")",
+ m_cursor = m_activity.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")",
new String[] { "articles.*", "feeds.title AS feed_title" }, "articles." + BaseColumns._ID + "=?",
new String[] { String.valueOf(m_articleId) }, null, null, null);
@@ -87,8 +122,24 @@ public class OfflineArticleFragment extends Fragment { else
titleStr = m_cursor.getString(m_cursor.getColumnIndex("title"));
- title.setMovementMethod(LinkMovementMethod.getInstance());
- title.setText(Html.fromHtml("<a href=\""+m_cursor.getString(m_cursor.getColumnIndex("link")).trim().replace("\"", "\\\"")+"\">" + titleStr + "</a>"));
+ final String link = m_cursor.getString(m_cursor.getColumnIndex("link"));
+
+ title.setText(titleStr);
+ title.setPaintFlags(title.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
+ title.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ try {
+ Intent intent = new Intent(Intent.ACTION_VIEW,
+ Uri.parse(link.trim()));
+ startActivity(intent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ m_activity.toast(R.string.error_other_error);
+ }
+ }
+ });
+
registerForContextMenu(title);
}
@@ -96,6 +147,16 @@ public class OfflineArticleFragment extends Fragment { if (web != null) {
+ web.setWebChromeClient(new WebChromeClient() {
+ @Override
+ public void onProgressChanged(WebView view, int progress) {
+ m_activity.setProgress(Math.round(((float)progress / 100f) * 10000));
+ if (progress == 100) {
+ m_activity.setProgressBarVisibility(false);
+ }
+ }
+ });
+
String content;
String cssOverride = "";
@@ -199,7 +260,7 @@ public class OfflineArticleFragment extends Fragment { if (tagv != null) {
int feedTitleIndex = m_cursor.getColumnIndex("feed_title");
- if (feedTitleIndex != -1 && m_offlineServices.activeFeedIsCat()) {
+ if (feedTitleIndex != -1 && m_isCat) {
tagv.setText(m_cursor.getString(feedTitleIndex));
} else {
String tagsStr = m_cursor.getString(m_cursor.getColumnIndex("tags"));
@@ -230,8 +291,8 @@ public class OfflineArticleFragment extends Fragment { super.onAttach(activity);
m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
-
- m_offlineServices = (OfflineServices)activity;
+
+ m_activity = (OfflineActivity) activity;
}
diff --git a/src/org/fox/ttrss/offline/OfflineArticlePager.java b/src/org/fox/ttrss/offline/OfflineArticlePager.java index 104d9f4f..3faf3415 100644 --- a/src/org/fox/ttrss/offline/OfflineArticlePager.java +++ b/src/org/fox/ttrss/offline/OfflineArticlePager.java @@ -3,67 +3,126 @@ package org.fox.ttrss.offline; import org.fox.ttrss.R;
import android.app.Activity;
-import android.database.sqlite.SQLiteStatement;
+import android.database.Cursor;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class OfflineArticlePager extends Fragment {
+ private final String TAG = this.getClass().getSimpleName();
private PagerAdapter m_adapter;
- private OfflineServices m_offlineServices;
- private OfflineHeadlinesFragment m_hf;
+ private OfflineActivity m_activity;
+ private OfflineHeadlinesEventListener m_listener;
+ private boolean m_isCat;
+ private int m_feedId;
private int m_articleId;
+ private String m_searchQuery = "";
+ private Cursor m_cursor;
- private class PagerAdapter extends FragmentStatePagerAdapter {
+ public int getFeedId() {
+ return m_feedId;
+ }
+
+ public boolean getFeedIsCat() {
+ return m_isCat;
+ }
+
+ public Cursor createCursor() {
+ String feedClause = null;
+
+ if (m_isCat) {
+ feedClause = "feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)";
+ } else {
+ feedClause = "feed_id = ?";
+ }
+ if (m_searchQuery == null || m_searchQuery.equals("")) {
+ 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_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");
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close();
+ }
+
+ private class PagerAdapter extends FragmentStatePagerAdapter {
public PagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
- int articleId = m_hf.getArticleIdAtPosition(position);
+ Log.d(TAG, "getItem: " + position);
- if (articleId != 0) {
- return new OfflineArticleFragment(articleId);
+ if (m_cursor.moveToPosition(position)) {
+ return new OfflineArticleFragment(m_cursor.getInt(m_cursor.getColumnIndex(BaseColumns._ID)));
}
return null;
}
-
+
@Override
public int getCount() {
- return m_hf.getArticleCount();
+ return m_cursor.getCount();
}
-
}
public OfflineArticlePager() {
super();
}
- public OfflineArticlePager(int articleId) {
+ public OfflineArticlePager(int articleId, int feedId, boolean isCat) {
super();
+ m_feedId = feedId;
+ m_isCat = isCat;
m_articleId = articleId;
+
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.article_pager, container, false);
+ if (savedInstanceState != null) {
+ m_articleId = savedInstanceState.getInt("articleId", 0);
+ m_feedId = savedInstanceState.getInt("feedId", 0);
+ m_isCat = savedInstanceState.getBoolean("isCat", false);
+ }
+
m_adapter = new PagerAdapter(getActivity().getSupportFragmentManager());
- ViewPager pager = (ViewPager) view.findViewById(R.id.article_pager);
+ m_cursor.moveToFirst();
+
+ int position = 0;
- int position = m_hf.getArticleIdPosition(m_articleId);
+ while (!m_cursor.isLast()) {
+ if (m_cursor.getInt(m_cursor.getColumnIndex(BaseColumns._ID)) == m_articleId) {
+ position = m_cursor.getPosition();
+ break;
+ }
+ m_cursor.moveToNext();
+ }
+
+ ViewPager pager = (ViewPager) view.findViewById(R.id.article_pager);
pager.setAdapter(m_adapter);
pager.setCurrentItem(position);
@@ -79,22 +138,17 @@ public class OfflineArticlePager extends Fragment { @Override
public void onPageSelected(int position) {
- int articleId = m_hf.getArticleIdAtPosition(position);
-
- if (articleId != 0) {
- m_offlineServices.setSelectedArticleId(articleId);
+ if (m_cursor.moveToPosition(position)) {
+ int articleId = m_cursor.getInt(m_cursor.getColumnIndex(BaseColumns._ID));
+
+ m_listener.onArticleSelected(articleId, false);
+
+ m_articleId = articleId;
- SQLiteStatement stmt = m_offlineServices.getWritableDb().compileStatement(
- "UPDATE articles SET unread = 0 " + "WHERE " + BaseColumns._ID
- + " = ?");
-
- stmt.bindLong(1, articleId);
- stmt.execute();
- stmt.close();
}
}
});
-
+
return view;
}
@@ -102,8 +156,58 @@ public class OfflineArticlePager extends Fragment { public void onAttach(Activity activity) {
super.onAttach(activity);
- m_hf = (OfflineHeadlinesFragment) getActivity().getSupportFragmentManager().findFragmentByTag(OfflineActivity.FRAG_HEADLINES);
- m_offlineServices = (OfflineServices)activity;
+ m_activity = (OfflineActivity)activity;
+ m_listener = (OfflineHeadlinesEventListener)activity;
+ m_cursor = createCursor();
+
+ }
+
+ public void refresh() {
+ if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close();
+
+ m_cursor = createCursor();
+
+ if (m_cursor != null) {
+ m_adapter.notifyDataSetChanged();
+ }
+ }
+
+ public int getSelectedArticleId() {
+ return m_articleId;
}
+ @Override
+ public void onSaveInstanceState(Bundle out) {
+ super.onSaveInstanceState(out);
+
+ out.putInt("articleId", m_articleId);
+ out.putInt("feedId", m_feedId);
+ out.putBoolean("isCat", m_isCat);
+
+ }
+
+ public void setSearchQuery(String searchQuery) {
+ m_searchQuery = searchQuery;
+ }
+
+ public void setArticleId(int articleId) {
+ m_articleId = articleId;
+
+ m_cursor.moveToFirst();
+
+ int position = 0;
+
+ while (!m_cursor.isLast()) {
+ if (m_cursor.getInt(m_cursor.getColumnIndex(BaseColumns._ID)) == m_articleId) {
+ position = m_cursor.getPosition();
+ break;
+ }
+ m_cursor.moveToNext();
+ }
+
+ ViewPager pager = (ViewPager) getView().findViewById(R.id.article_pager);
+
+ pager.setCurrentItem(position);
+
+ }
}
diff --git a/src/org/fox/ttrss/offline/OfflineDownloadService.java b/src/org/fox/ttrss/offline/OfflineDownloadService.java index b757082f..eb9a802e 100644 --- a/src/org/fox/ttrss/offline/OfflineDownloadService.java +++ b/src/org/fox/ttrss/offline/OfflineDownloadService.java @@ -5,7 +5,7 @@ import java.util.HashMap; import java.util.List;
import org.fox.ttrss.ApiRequest;
-import org.fox.ttrss.MainActivity;
+import org.fox.ttrss.OnlineActivity;
import org.fox.ttrss.R;
import org.fox.ttrss.types.Article;
import org.fox.ttrss.types.Feed;
@@ -46,8 +46,8 @@ public class OfflineDownloadService extends Service { public static final String INTENT_ACTION_SUCCESS = "org.fox.ttrss.intent.action.DownloadComplete";
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 = 500;
+ private static final int OFFLINE_SYNC_SEQ = 50;
+ private static final int OFFLINE_SYNC_MAX = OFFLINE_SYNC_SEQ * 10;
private SQLiteDatabase m_writableDb;
private SQLiteDatabase m_readableDb;
@@ -87,11 +87,12 @@ public class OfflineDownloadService extends Service { initDatabase();
}
+ @SuppressWarnings("deprecation")
private void updateNotification(String msg) {
Notification notification = new Notification(R.drawable.icon,
getString(R.string.notify_downloading_title), System.currentTimeMillis());
- Intent intent = new Intent(this, MainActivity.class);
+ Intent intent = new Intent(this, OnlineActivity.class);
intent.setAction(INTENT_ACTION_CANCEL);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
@@ -158,9 +159,9 @@ public class OfflineDownloadService extends Service { m_readableDb = dh.getReadableDatabase();
}
- private synchronized SQLiteDatabase getReadableDb() {
+ /* private synchronized SQLiteDatabase getReadableDb() {
return m_readableDb;
- }
+ } */
private synchronized SQLiteDatabase getWritableDb() {
return m_writableDb;
@@ -198,9 +199,11 @@ public class OfflineDownloadService extends Service { ApiRequest req = new ApiRequest(getApplicationContext()) {
@Override
- protected void onPostExecute(JsonElement content) {
+ protected JsonElement doInBackground(HashMap<String, String>... params) {
+ JsonElement content = super.doInBackground(params);
+
if (content != null) {
-
+
try {
Type listType = new TypeToken<List<Feed>>() {}.getType();
List<Feed> feeds = new Gson().fromJson(content, listType);
@@ -215,29 +218,35 @@ public class OfflineDownloadService extends Service { stmtInsert.bindString(3, feed.feed_url);
stmtInsert.bindLong(4, feed.has_icon ? 1 : 0);
stmtInsert.bindLong(5, feed.cat_id);
-
+
stmtInsert.execute();
}
-
+
stmtInsert.close();
-
+
Log.d(TAG, "offline: done downloading feeds");
m_articleOffset = 0;
getWritableDb().execSQL("DELETE FROM articles;");
-
- if (m_canProceed) {
- downloadArticles();
- } else {
- downloadFailed();
- }
} catch (Exception e) {
e.printStackTrace();
updateNotification(R.string.offline_switch_error);
downloadFailed();
}
+ }
+ return content;
+ }
+
+ @Override
+ protected void onPostExecute(JsonElement content) {
+ if (content != null) {
+ if (m_canProceed) {
+ downloadArticles();
+ } else {
+ downloadFailed();
+ }
} else {
updateNotification(getErrorMessage());
downloadFailed();
@@ -266,10 +275,10 @@ public class OfflineDownloadService extends Service { getWritableDb().execSQL("DELETE FROM categories;");
ApiRequest req = new ApiRequest(getApplicationContext()) {
- @Override
- protected void onPostExecute(JsonElement content) {
+ protected JsonElement doInBackground(HashMap<String, String>... params) {
+ JsonElement content = super.doInBackground(params);
+
if (content != null) {
-
try {
Type listType = new TypeToken<List<FeedCategory>>() {}.getType();
List<FeedCategory> cats = new Gson().fromJson(content, listType);
@@ -289,17 +298,23 @@ public class OfflineDownloadService extends Service { Log.d(TAG, "offline: done downloading categories");
- if (m_canProceed) {
- downloadFeeds();
- } else {
- downloadFailed();
- }
} catch (Exception e) {
e.printStackTrace();
updateNotification(R.string.offline_switch_error);
downloadFailed();
}
-
+ }
+
+ return content;
+ }
+ @Override
+ protected void onPostExecute(JsonElement content) {
+ if (content != null) {
+ if (m_canProceed) {
+ downloadFeeds();
+ } else {
+ downloadFailed();
+ }
} else {
updateNotification(getErrorMessage());
downloadFailed();
@@ -335,22 +350,27 @@ public class OfflineDownloadService extends Service { }
public class OfflineArticlesRequest extends ApiRequest {
+ List<Article> m_articles;
+
public OfflineArticlesRequest(Context context) {
super(context);
}
@Override
- protected void onPostExecute(JsonElement content) {
+ protected JsonElement doInBackground(HashMap<String, String>... params) {
+ JsonElement content = super.doInBackground(params);
+
if (content != null) {
+
try {
Type listType = new TypeToken<List<Article>>() {}.getType();
- List<Article> articles = new Gson().fromJson(content, listType);
+ m_articles = new Gson().fromJson(content, listType);
SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO articles " +
"("+BaseColumns._ID+", unread, marked, published, updated, is_updated, title, link, feed_id, tags, content) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
- for (Article article : articles) {
+ for (Article article : m_articles) {
String tagsString = "";
@@ -402,25 +422,12 @@ public class OfflineDownloadService extends Service { }
+ m_articleOffset += m_articles.size();
+
+ Log.d(TAG, "offline: received " + m_articles.size() + " articles; canProc=" + m_canProceed);
+
stmtInsert.close();
- //m_canGetMoreArticles = articles.size() == 30;
- m_articleOffset += articles.size();
-
- Log.d(TAG, "offline: received " + articles.size() + " articles; canProc=" + m_canProceed);
-
- if (m_canProceed) {
- if (articles.size() == OFFLINE_SYNC_SEQ && m_articleOffset < m_syncMax) {
- downloadArticles();
- } else {
- downloadComplete();
- }
- } else {
- downloadFailed();
- }
-
- return;
-
} catch (Exception e) {
updateNotification(R.string.offline_switch_error);
Log.d(TAG, "offline: failed: exception when loading articles");
@@ -428,6 +435,25 @@ public class OfflineDownloadService extends Service { downloadFailed();
}
+ }
+
+ return content;
+ }
+
+ @Override
+ protected void onPostExecute(JsonElement content) {
+ if (content != null) {
+
+ if (m_canProceed && m_articles != null) {
+ if (m_articles.size() == OFFLINE_SYNC_SEQ && m_articleOffset < m_syncMax) {
+ downloadArticles();
+ } else {
+ downloadComplete();
+ }
+ } else {
+ downloadFailed();
+ }
+
} else {
Log.d(TAG, "offline: failed: " + getErrorMessage());
updateNotification(getErrorMessage());
diff --git a/src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java b/src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java index f6ae2835..d46e5587 100644 --- a/src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java +++ b/src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java @@ -16,6 +16,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;
@@ -31,7 +32,7 @@ public class OfflineFeedCategoriesFragment extends Fragment implements OnItemCli private FeedCategoryListAdapter m_adapter;
private int m_selectedCatId;
private Cursor m_cursor;
- private OfflineServices m_offlineServices;
+ private OfflineFeedsActivity m_activity;
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
@@ -50,11 +51,11 @@ public class OfflineFeedCategoriesFragment extends Fragment implements OnItemCli }
public Cursor createCursor() {
- String unreadOnly = BaseColumns._ID + "> 0 AND " + (m_offlineServices.getUnreadOnly() ? "unread > 0" : "1");
+ String unreadOnly = BaseColumns._ID + "> 0 AND " + (m_activity.getUnreadOnly() ? "unread > 0" : "1");
String order = m_prefs.getBoolean("sort_feeds_by_unread", false) ? "unread DESC, title" : "title";
- return m_offlineServices.getReadableDb().query("cats_unread",
+ return m_activity.getReadableDb().query("cats_unread",
null, unreadOnly, null, null, null, order);
}
@@ -70,6 +71,48 @@ public class OfflineFeedCategoriesFragment extends Fragment implements OnItemCli }
@Override
+ public void onResume() {
+ super.onResume();
+ refresh();
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+ .getMenuInfo();
+
+ switch (item.getItemId()) {
+ case R.id.browse_articles:
+ if (true) {
+ int catId = getCatIdAtPosition(info.position);
+ if (catId != -10000) {
+ m_activity.onCatSelected(catId, true);
+ }
+ }
+ return true;
+ case R.id.browse_feeds:
+ if (true) {
+ int catId = getCatIdAtPosition(info.position);
+ if (catId != -10000) {
+ m_activity.onCatSelected(catId, false);
+ }
+ }
+ return true;
+ case R.id.catchup_category:
+ if (true) {
+ int catId = getCatIdAtPosition(info.position);
+ if (catId != -10000) {
+ m_activity.catchupFeed(catId, true);
+ }
+ }
+ return true;
+ default:
+ Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
+ return super.onContextItemSelected(item);
+ }
+ }
+
+ @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (savedInstanceState != null) {
@@ -106,7 +149,7 @@ public class OfflineFeedCategoriesFragment extends Fragment implements OnItemCli public void onAttach(Activity activity) {
super.onAttach(activity);
- m_offlineServices = (OfflineServices)activity;
+ m_activity = (OfflineFeedsActivity)activity;
m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
m_prefs.registerOnSharedPreferenceChangeListener(this);
@@ -131,9 +174,9 @@ public class OfflineFeedCategoriesFragment extends Fragment implements OnItemCli int feedId = (int) cursor.getLong(0);
Log.d(TAG, "clicked on feed " + feedId);
- m_offlineServices.onCatSelected(feedId);
+ m_activity.onCatSelected(feedId);
- if (!m_offlineServices.isSmallScreen())
+ if (!m_activity.isSmallScreen())
m_selectedCatId = feedId;
m_adapter.notifyDataSetChanged();
@@ -175,7 +218,7 @@ public class OfflineFeedCategoriesFragment extends Fragment implements OnItemCli public int getItemViewType(int position) {
Cursor cursor = (Cursor) this.getItem(position);
- if (!m_offlineServices.isSmallScreen() && cursor.getLong(0) == m_selectedCatId) {
+ if (!m_activity.isSmallScreen() && cursor.getLong(0) == m_selectedCatId) {
return VIEW_SELECTED;
} else {
return VIEW_NORMAL;
@@ -251,7 +294,7 @@ public class OfflineFeedCategoriesFragment extends Fragment implements OnItemCli return catId;
}
- return 0;
+ return -10000;
}
public void setSelectedFeedId(int feedId) {
diff --git a/src/org/fox/ttrss/offline/OfflineFeedsActivity.java b/src/org/fox/ttrss/offline/OfflineFeedsActivity.java new file mode 100644 index 00000000..35bf05b7 --- /dev/null +++ b/src/org/fox/ttrss/offline/OfflineFeedsActivity.java @@ -0,0 +1,253 @@ +package org.fox.ttrss.offline;
+
+import org.fox.ttrss.R;
+
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.database.sqlite.SQLiteStatement;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.provider.BaseColumns;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.MenuItem;
+import android.view.View;
+
+public class OfflineFeedsActivity extends OfflineActivity implements OfflineHeadlinesEventListener {
+ private final String TAG = this.getClass().getSimpleName();
+
+ @SuppressLint("NewApi")
+ @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) {
+
+ } else {
+ Intent intent = getIntent();
+
+ if (intent.getIntExtra("feed", -10000) != -10000 || intent.getIntExtra("category", -10000) != -10000 ||
+ intent.getIntExtra("article", -10000) != -10000) {
+
+ if (!isCompatMode()) {
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+ }
+
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+
+ int feedId = intent.getIntExtra("feed", -10000);
+ int catId = intent.getIntExtra("category", -10000);
+ int articleId = intent.getIntExtra("article", -10000);
+ boolean isCat = intent.getBooleanExtra("isCat", false);
+
+ if (articleId != -10000) {
+ ft.replace(R.id.feeds_fragment, new OfflineArticlePager(articleId, feedId, isCat), FRAG_ARTICLE);
+ } else {
+ if (feedId != -10000) {
+ ft.replace(R.id.feeds_fragment, new OfflineHeadlinesFragment(feedId, isCat), FRAG_HEADLINES);
+ }
+
+ if (catId != -10000) {
+ ft.replace(R.id.feeds_fragment, new OfflineFeedsFragment(catId), FRAG_FEEDS);
+ }
+ }
+
+ ft.commit();
+ } else {
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+
+ if (m_prefs.getBoolean("enable_cats", false)) {
+ ft.replace(R.id.feeds_fragment, new OfflineFeedCategoriesFragment(), FRAG_CATS);
+ } else {
+ ft.replace(R.id.feeds_fragment, new OfflineFeedsFragment(), FRAG_FEEDS);
+ }
+
+ ft.commit();
+ }
+ }
+
+ setLoadingStatus(R.string.blank, false);
+ findViewById(R.id.loading_container).setVisibility(View.GONE);
+
+ initMenu();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.show_feeds:
+ setUnreadOnly(!getUnreadOnly());
+ initMenu();
+ refresh();
+ return true;
+ default:
+ Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId());
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle out) {
+ super.onSaveInstanceState(out);
+
+ }
+
+ public void initMenu() {
+ super.initMenu();
+
+ if (m_menu != null) {
+ Fragment ff = getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS);
+ Fragment cf = getSupportFragmentManager().findFragmentByTag(FRAG_CATS);
+ OfflineArticlePager af = (OfflineArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
+ OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+
+ m_menu.setGroupVisible(R.id.menu_group_feeds, (ff != null && ff.isAdded()) || (cf != null && cf.isAdded()));
+
+ m_menu.setGroupVisible(R.id.menu_group_article, af != null && af.isAdded());
+
+ m_menu.setGroupVisible(R.id.menu_group_headlines, hf != null && hf.isAdded() && getSelectedArticleCount() == 0);
+ m_menu.setGroupVisible(R.id.menu_group_headlines_selection, hf != null && hf.isAdded() && getSelectedArticleCount() != 0);
+
+ MenuItem item = m_menu.findItem(R.id.show_feeds);
+
+ if (getUnreadOnly()) {
+ item.setTitle(R.string.menu_all_feeds);
+ } else {
+ item.setTitle(R.string.menu_unread_feeds);
+ }
+ }
+ }
+
+ public void onCatSelected(int catId) {
+ onCatSelected(catId, m_prefs.getBoolean("browse_cats_like_feeds", false));
+ }
+
+ public void onCatSelected(int catId, boolean openAsFeed) {
+ if (openAsFeed) {
+ onFeedSelected(catId, true, true);
+ } else {
+ if (isSmallScreen()) {
+ Intent intent = new Intent(OfflineFeedsActivity.this, OfflineFeedsActivity.class);
+ intent.putExtra("category", catId);
+
+ startActivityForResult(intent, 0);
+ } else {
+ FragmentTransaction ft = getSupportFragmentManager()
+ .beginTransaction();
+
+ OfflineFeedsFragment ff = new OfflineFeedsFragment(catId);
+
+ ft.replace(R.id.feeds_fragment, ff, FRAG_FEEDS);
+ ft.addToBackStack(null);
+
+ ft.commit();
+ }
+ }
+ }
+
+ public void onFeedSelected(int feedId) {
+ onFeedSelected(feedId, false, true);
+ }
+
+ public void onFeedSelected(int feedId, boolean isCat, boolean open) {
+
+ if (open) {
+ if (isSmallScreen()) {
+
+ Intent intent = new Intent(OfflineFeedsActivity.this, OfflineFeedsActivity.class);
+ intent.putExtra("feed", feedId);
+ intent.putExtra("isCat", isCat);
+
+ startActivityForResult(intent, 0);
+
+ } else {
+ FragmentTransaction ft = getSupportFragmentManager()
+ .beginTransaction();
+
+ OfflineHeadlinesFragment hf = new OfflineHeadlinesFragment(feedId, isCat);
+ ft.replace(R.id.headlines_fragment, hf, FRAG_HEADLINES);
+
+ ft.commit();
+ }
+ }
+ }
+
+ public void catchupFeed(int feedId, boolean isCat) {
+ if (isCat) {
+ SQLiteStatement stmt = getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 WHERE feed_id IN (SELECT "+
+ BaseColumns._ID+" FROM feeds WHERE cat_id = ?)");
+ stmt.bindLong(1, feedId);
+ stmt.execute();
+ stmt.close();
+ } else {
+ SQLiteStatement stmt = getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 WHERE feed_id = ?");
+ stmt.bindLong(1, feedId);
+ stmt.execute();
+ stmt.close();
+ }
+
+ refresh();
+ }
+
+ @Override
+ public void onArticleSelected(int articleId, boolean open) {
+ SQLiteStatement stmt = getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 " + "WHERE " + BaseColumns._ID
+ + " = ?");
+
+ stmt.bindLong(1, articleId);
+ stmt.execute();
+ stmt.close();
+
+ if (open) {
+ if (isSmallScreen()) {
+
+ OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+
+ Intent intent = new Intent(OfflineFeedsActivity.this, OfflineFeedsActivity.class);
+ intent.putExtra("feed", hf.getFeedId());
+ intent.putExtra("isCat", hf.getFeedIsCat());
+ intent.putExtra("article", articleId);
+
+ startActivityForResult(intent, 0);
+
+ } else {
+
+ OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+
+ Intent intent = new Intent(OfflineFeedsActivity.this, OfflineHeadlinesActivity.class);
+ intent.putExtra("feed", hf.getFeedId());
+ intent.putExtra("isCat", hf.getFeedIsCat());
+ intent.putExtra("article", articleId);
+
+ startActivityForResult(intent, 0);
+ }
+ } else {
+ refresh();
+ }
+
+ initMenu();
+
+ }
+
+ @Override
+ public void onArticleSelected(int articleId) {
+ onArticleSelected(articleId, true);
+ }
+}
diff --git a/src/org/fox/ttrss/offline/OfflineFeedsFragment.java b/src/org/fox/ttrss/offline/OfflineFeedsFragment.java index 605f506c..87af187c 100644 --- a/src/org/fox/ttrss/offline/OfflineFeedsFragment.java +++ b/src/org/fox/ttrss/offline/OfflineFeedsFragment.java @@ -21,6 +21,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;
@@ -39,7 +40,7 @@ public class OfflineFeedsFragment extends Fragment implements OnItemClickListene private int m_catId = -1;
private boolean m_enableFeedIcons;
private Cursor m_cursor;
- private OfflineServices m_offlineServices;
+ private OfflineFeedsActivity m_activity;
public OfflineFeedsFragment() {
//
@@ -48,8 +49,31 @@ public class OfflineFeedsFragment extends Fragment implements OnItemClickListene public OfflineFeedsFragment(int catId) {
m_catId = catId;
}
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ refresh();
+ }
@Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+ .getMenuInfo();
+ switch (item.getItemId()) {
+ case R.id.catchup_feed:
+ int feedId = getFeedIdAtPosition(info.position);
+ if (feedId != -10000) {
+ m_activity.catchupFeed(feedId, false);
+ }
+ 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) {
@@ -66,14 +90,14 @@ public class OfflineFeedsFragment extends Fragment implements OnItemClickListene }
public Cursor createCursor() {
- String unreadOnly = m_offlineServices.getUnreadOnly() ? "unread > 0" : "1";
+ String unreadOnly = m_activity.getUnreadOnly() ? "unread > 0" : "1";
String order = m_prefs.getBoolean("sort_feeds_by_unread", false) ? "unread DESC, title" : "title";
if (m_catId != -1) {
- return m_offlineServices.getReadableDb().query("feeds_unread",
+ return m_activity.getReadableDb().query("feeds_unread",
null, unreadOnly + " AND cat_id = ?", new String[] { String.valueOf(m_catId) }, null, null, order);
} else {
- return m_offlineServices.getReadableDb().query("feeds_unread",
+ return m_activity.getReadableDb().query("feeds_unread",
null, unreadOnly, null, null, null, order);
}
}
@@ -129,7 +153,7 @@ public class OfflineFeedsFragment extends Fragment implements OnItemClickListene public void onAttach(Activity activity) {
super.onAttach(activity);
- m_offlineServices = (OfflineServices)activity;
+ m_activity = (OfflineFeedsActivity)activity;
m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
m_prefs.registerOnSharedPreferenceChangeListener(this);
@@ -155,9 +179,9 @@ public class OfflineFeedsFragment extends Fragment implements OnItemClickListene int feedId = (int) cursor.getLong(0);
Log.d(TAG, "clicked on feed " + feedId);
- m_offlineServices.onFeedSelected(feedId);
+ m_activity.onFeedSelected(feedId);
- if (!m_offlineServices.isSmallScreen())
+ if (!m_activity.isSmallScreen())
m_selectedFeedId = feedId;
m_adapter.notifyDataSetChanged();
@@ -199,7 +223,7 @@ public class OfflineFeedsFragment extends Fragment implements OnItemClickListene public int getItemViewType(int position) {
Cursor cursor = (Cursor) this.getItem(position);
- if (!m_offlineServices.isSmallScreen() && cursor.getLong(0) == m_selectedFeedId) {
+ if (!m_activity.isSmallScreen() && cursor.getLong(0) == m_selectedFeedId) {
return VIEW_SELECTED;
} else {
return VIEW_NORMAL;
@@ -295,7 +319,7 @@ public class OfflineFeedsFragment extends Fragment implements OnItemClickListene return feedId;
}
- return 0;
+ return -10000;
}
public void setSelectedFeedId(int feedId) {
diff --git a/src/org/fox/ttrss/offline/OfflineHeadlinesActivity.java b/src/org/fox/ttrss/offline/OfflineHeadlinesActivity.java new file mode 100644 index 00000000..d9053f27 --- /dev/null +++ b/src/org/fox/ttrss/offline/OfflineHeadlinesActivity.java @@ -0,0 +1,142 @@ +package org.fox.ttrss.offline;
+
+import org.fox.ttrss.GlobalState;
+import org.fox.ttrss.R;
+
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteStatement;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.provider.BaseColumns;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.view.View;
+
+public class OfflineHeadlinesActivity extends OfflineActivity implements OfflineHeadlinesEventListener {
+ @SuppressWarnings("unused")
+ private final String TAG = this.getClass().getSimpleName();
+
+ protected SharedPreferences m_prefs;
+
+ @SuppressLint("NewApi")
+ @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) {
+ Intent i = getIntent();
+
+ if (i.getExtras() != null) {
+ int feedId = i.getIntExtra("feed", 0);
+ boolean isCat = i.getBooleanExtra("isCat", false);
+ int articleId = i.getIntExtra("article", 0);
+ String searchQuery = i.getStringExtra("searchQuery");
+
+ OfflineHeadlinesFragment hf = new OfflineHeadlinesFragment(feedId, isCat);
+ OfflineArticlePager af = new OfflineArticlePager(articleId, feedId, isCat);
+
+ hf.setActiveArticleId(articleId);
+
+ hf.setSearchQuery(searchQuery);
+ af.setSearchQuery(searchQuery);
+
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+
+ ft.replace(R.id.headlines_fragment, hf, FRAG_HEADLINES);
+ ft.replace(R.id.article_fragment, af, FRAG_ARTICLE);
+
+ ft.commit();
+
+ Cursor c;
+
+ if (isCat) {
+ c = getCatById(feedId);
+ } else {
+ c = getFeedById(feedId);
+ }
+
+ if (c != null) {
+ setTitle(c.getString(c.getColumnIndex("title")));
+ c.close();
+ }
+
+ }
+ }
+
+ setLoadingStatus(R.string.blank, false);
+ findViewById(R.id.loading_container).setVisibility(View.GONE);
+
+ initMenu();
+ }
+
+ @Override
+ public void onArticleSelected(int articleId, boolean open) {
+ SQLiteStatement stmt = getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 " + "WHERE " + BaseColumns._ID
+ + " = ?");
+
+ stmt.bindLong(1, articleId);
+ stmt.execute();
+ stmt.close();
+
+ if (open) {
+ OfflineArticlePager af = (OfflineArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
+
+ af.setArticleId(articleId);
+ } else {
+ OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+
+ hf.setActiveArticleId(articleId);
+ }
+
+ GlobalState.getInstance().m_selectedArticleId = articleId;
+
+ initMenu();
+ refresh();
+ }
+
+ @Override
+ protected void initMenu() {
+ super.initMenu();
+
+ if (m_menu != null) {
+ m_menu.setGroupVisible(R.id.menu_group_feeds, false);
+
+ OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES);
+
+ m_menu.setGroupVisible(R.id.menu_group_headlines, hf != null && hf.getSelectedArticleCount() == 0);
+ m_menu.setGroupVisible(R.id.menu_group_headlines_selection, hf != null && hf.getSelectedArticleCount() != 0);
+
+ Fragment af = getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE);
+
+ m_menu.setGroupVisible(R.id.menu_group_article, af != null);
+
+ m_menu.findItem(R.id.search).setVisible(false);
+ }
+ }
+
+ @Override
+ public void onArticleSelected(int articleId) {
+ onArticleSelected(articleId, true);
+ }
+}
diff --git a/src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java b/src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java new file mode 100644 index 00000000..cdff5913 --- /dev/null +++ b/src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java @@ -0,0 +1,7 @@ +package org.fox.ttrss.offline;
+
+
+public interface OfflineHeadlinesEventListener {
+ void onArticleSelected(int articleId, boolean open);
+ void onArticleSelected(int articleId);
+}
diff --git a/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java b/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java index e5428f59..158e36cd 100644 --- a/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java +++ b/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java @@ -5,6 +5,7 @@ import java.text.SimpleDateFormat; import java.util.Date;
import java.util.TimeZone;
+import org.fox.ttrss.GlobalState;
import org.fox.ttrss.R;
import org.jsoup.Jsoup;
@@ -27,6 +28,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;
@@ -55,10 +57,12 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis private Cursor m_cursor;
private ArticleListAdapter m_adapter;
- private OfflineServices m_offlineServices;
+ private OfflineHeadlinesEventListener m_listener;
+ private OfflineActivity m_activity;
private ImageGetter m_dummyGetter = new ImageGetter() {
+ @SuppressWarnings("deprecation")
@Override
public Drawable getDrawable(String source) {
return new BitmapDrawable();
@@ -83,7 +87,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis }
public int getSelectedArticleCount() {
- Cursor c = m_offlineServices.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);
@@ -93,10 +97,122 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis }
@Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+ .getMenuInfo();
+
+ switch (item.getItemId()) {
+ 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 (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 (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 (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) {
+ int articleId = getArticleIdAtPosition(info.position);
+
+ SQLiteStatement stmt = null;
+
+ if (m_feedIsCat) {
+ stmt = m_activity.getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 WHERE " +
+ "updated >= (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " +
+ "AND feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)");
+ } else {
+ stmt = m_activity.getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 WHERE " +
+ "updated >= (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " +
+ "AND feed_id = ?");
+ }
+
+ stmt.bindLong(1, articleId);
+ stmt.bindLong(2, m_feedId);
+ stmt.execute();
+ stmt.close();
+ }
+ refresh();
+ 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 (getSelectedArticleCount() > 0) {
menu.setHeaderTitle(R.string.headline_context_multiple);
@@ -107,12 +223,31 @@ 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);
}
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ if (GlobalState.getInstance().m_selectedArticleId != 0) {
+ m_activeArticleId = GlobalState.getInstance().m_selectedArticleId;
+ GlobalState.getInstance().m_selectedArticleId = 0;
+ }
+
+ if (m_activeArticleId != 0) {
+ setActiveArticleId(m_activeArticleId);
+ }
+
+ refresh();
+ }
+
public void refresh() {
if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close();
@@ -120,7 +255,6 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis if (m_cursor != null) {
m_adapter.changeCursor(m_cursor);
- setActiveArticleId(m_offlineServices.getSelectedArticleId());
m_adapter.notifyDataSetChanged();
}
}
@@ -135,6 +269,8 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis m_combinedMode = savedInstanceState.getBoolean("combinedMode");
m_searchQuery = (String) savedInstanceState.getCharSequence("searchQuery");
m_feedIsCat = savedInstanceState.getBoolean("feedIsCat");
+ } else {
+ m_activity.getWritableDb().execSQL("UPDATE articles SET selected = 0 ");
}
View view = inflater.inflate(R.layout.headlines_fragment, container, false);
@@ -150,7 +286,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis list.setEmptyView(view.findViewById(R.id.no_headlines));
registerForContextMenu(list);
- if (m_offlineServices.isSmallScreen() || m_offlineServices.isPortrait())
+ if (m_activity.isSmallScreen() || m_activity.isPortrait())
view.findViewById(R.id.headlines_fragment).setPadding(0, 0, 0, 0);
getActivity().setProgressBarIndeterminateVisibility(false);
@@ -167,12 +303,12 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis feedClause = "feed_id = ?";
}
- if (m_searchQuery.equals("")) {
- return m_offlineServices.getReadableDb().query("articles LEFT JOIN feeds ON (feed_id = feeds."+BaseColumns._ID+")",
+ if (m_searchQuery == null || m_searchQuery.equals("")) {
+ 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_offlineServices.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");
@@ -182,10 +318,11 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis @Override
public void onAttach(Activity activity) {
super.onAttach(activity);
- m_offlineServices = (OfflineServices)activity;
+ m_listener = (OfflineHeadlinesEventListener) activity;
+ m_activity = (OfflineActivity) activity;
m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
- m_combinedMode = m_prefs.getBoolean("combined_mode", false);
+ m_combinedMode = false; /* m_prefs.getBoolean("combined_mode", false); */
}
@Override
@@ -197,17 +334,22 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis if (list != null) {
Cursor cursor = (Cursor)list.getItemAtPosition(position);
- m_activeArticleId = cursor.getInt(0);
-
- SQLiteStatement stmtUpdate = m_offlineServices.getWritableDb().compileStatement("UPDATE articles SET unread = 0 " +
- "WHERE " + BaseColumns._ID + " = ?");
+ int articleId = cursor.getInt(0);
- stmtUpdate.bindLong(1, m_activeArticleId);
- stmtUpdate.execute();
- stmtUpdate.close();
+ if (getActivity().findViewById(R.id.article_fragment) != null) {
+ m_activeArticleId = articleId;
+ }
if (!m_combinedMode) {
- m_offlineServices.openArticle(m_activeArticleId, 0);
+ m_listener.onArticleSelected(articleId);
+ } else {
+ SQLiteStatement stmt = m_activity.getWritableDb().compileStatement(
+ "UPDATE articles SET unread = 0 " + "WHERE " + BaseColumns._ID
+ + " = ?");
+
+ stmt.bindLong(1, articleId);
+ stmt.execute();
+ stmt.close();
}
refresh();
@@ -321,7 +463,10 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis if (ft != null && feedTitleIndex != -1 && m_feedIsCat) {
String feedTitle = article.getString(feedTitleIndex);
- if (feedTitle != null) {
+ if (feedTitle.length() > 20)
+ feedTitle = feedTitle.substring(0, 20) + "...";
+
+ if (feedTitle.length() > 0) {
ft.setText(feedTitle);
} else {
ft.setVisibility(View.GONE);
@@ -339,7 +484,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis @Override
public void onClick(View v) {
- SQLiteStatement stmtUpdate = m_offlineServices.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);
@@ -360,7 +505,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis @Override
public void onClick(View v) {
- SQLiteStatement stmtUpdate = m_offlineServices.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);
@@ -438,7 +583,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis public void onClick(View view) {
CheckBox cb = (CheckBox)view;
- SQLiteStatement stmtUpdate = m_offlineServices.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);
@@ -448,7 +593,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis refresh();
- m_offlineServices.initMainMenu();
+ m_activity.initMenu();
}
});
@@ -476,13 +621,19 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis public void setActiveArticleId(int articleId) {
m_activeArticleId = articleId;
- // m_adapter.notifyDataSetChanged();
-
- ListView list = (ListView)getView().findViewById(R.id.headlines);
+ try {
+ m_adapter.notifyDataSetChanged();
+
+ ListView list = (ListView)getView().findViewById(R.id.headlines);
- if (list != null) {
- list.setSelection(getArticleIdPosition(articleId));
- }
+ Log.d(TAG, articleId + " position " + getArticleIdPosition(articleId));
+
+ if (list != null) {
+ list.setSelection(getArticleIdPosition(articleId));
+ }
+ } catch (NullPointerException e) {
+ // invoked before view is created, nvm
+ }
}
public Cursor getArticleAtPosition(int position) {
@@ -520,8 +671,19 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis public void setSearchQuery(String query) {
if (!m_searchQuery.equals(query)) {
m_searchQuery = query;
- refresh();
}
}
+
+ public int getFeedId() {
+ return m_feedId;
+ }
+
+ public boolean getFeedIsCat() {
+ return m_feedIsCat;
+ }
+
+ public String getSearchQuery() {
+ return m_searchQuery;
+ }
}
diff --git a/src/org/fox/ttrss/offline/OfflineServices.java b/src/org/fox/ttrss/offline/OfflineServices.java deleted file mode 100644 index 8483c97f..00000000 --- a/src/org/fox/ttrss/offline/OfflineServices.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.fox.ttrss.offline;
-
-import org.fox.ttrss.OnlineServices;
-
-import android.database.sqlite.SQLiteDatabase;
-
-public interface OfflineServices {
- public int getActiveFeedId();
- public SQLiteDatabase getReadableDb();
- public SQLiteDatabase getWritableDb();
- public int getRelativeArticleId(int baseId, int feedId, OnlineServices.RelativeArticle mode);
- public void onFeedSelected(int feedId);
- public void onCatSelected(int catId);
- public void openArticle(int articleId, int compatAnimation);
- public boolean getUnreadOnly();
- public int getSelectedArticleId();
- public void initMainMenu();
- public boolean isSmallScreen();
- public void setSelectedArticleId(int articleId);
- public boolean activeFeedIsCat();
- public boolean isPortrait();
-}
diff --git a/src/org/fox/ttrss/offline/OfflineUploadService.java b/src/org/fox/ttrss/offline/OfflineUploadService.java index 84a7fc92..bacb1ede 100644 --- a/src/org/fox/ttrss/offline/OfflineUploadService.java +++ b/src/org/fox/ttrss/offline/OfflineUploadService.java @@ -3,7 +3,7 @@ package org.fox.ttrss.offline; import java.util.HashMap;
import org.fox.ttrss.ApiRequest;
-import org.fox.ttrss.MainActivity;
+import org.fox.ttrss.OnlineActivity;
import org.fox.ttrss.R;
import org.fox.ttrss.util.DatabaseHelper;
@@ -48,12 +48,13 @@ public class OfflineUploadService extends IntentService { m_nmgr.cancel(NOTIFY_UPLOADING);
}
+ @SuppressWarnings("deprecation")
private void updateNotification(String msg) {
Notification notification = new Notification(R.drawable.icon,
getString(R.string.notify_uploading_title), System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
- new Intent(this, MainActivity.class), 0);
+ new Intent(this, OnlineActivity.class), 0);
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
|