diff options
| author | Andrew Dolgov <noreply@fakecake.org> | 2014-10-17 00:06:56 +0400 |
|---|---|---|
| committer | Andrew Dolgov <noreply@fakecake.org> | 2014-10-17 00:06:56 +0400 |
| commit | 97cc96839d31b6cce59ec29a6681c6fe802552ee (patch) | |
| tree | 9f3b8df270095bc65c10cd7208d05b3dad4794b9 /src/org/fox/ttrss/offline | |
| parent | 5775c0d56b7c856b508bb34e478eef53c2460624 (diff) | |
initial
Diffstat (limited to 'src/org/fox/ttrss/offline')
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineActivity.java | 881 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineArticleFragment.java | 439 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineArticlePager.java | 298 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineDownloadService.java | 500 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java | 337 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineFeedsActivity.java | 349 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineFeedsFragment.java | 372 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineHeadlinesActivity.java | 167 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java | 7 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java | 774 | ||||
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineUploadService.java | 286 |
11 files changed, 0 insertions, 4410 deletions
diff --git a/src/org/fox/ttrss/offline/OfflineActivity.java b/src/org/fox/ttrss/offline/OfflineActivity.java deleted file mode 100644 index fd05b596..00000000 --- a/src/org/fox/ttrss/offline/OfflineActivity.java +++ /dev/null @@ -1,881 +0,0 @@ -package org.fox.ttrss.offline; - -import org.fox.ttrss.CommonActivity; -import org.fox.ttrss.PreferencesActivity; -import org.fox.ttrss.R; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.select.Elements; - -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.net.Uri; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.provider.BaseColumns; -import android.support.v7.view.ActionMode; -import android.util.Log; -import android.view.KeyEvent; -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.TextView; - -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; - - private String m_lastImageHitTestUrl; - - @SuppressLint("NewApi") - private class HeadlinesActionModeCallback implements ActionMode.Callback { - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return false; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - m_headlinesActionMode = null; - deselectAllArticles(); - } - - @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 boolean onContextItemSelected(android.view.MenuItem item) { - /* AdapterContextMenuInfo info = (AdapterContextMenuInfo) item - .getMenuInfo(); */ - - final OfflineArticlePager ap = (OfflineArticlePager)getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - - switch (item.getItemId()) { - case R.id.article_img_open: - if (getLastContentImageHitTestUrl() != null) { - try { - Intent intent = new Intent(Intent.ACTION_VIEW, - Uri.parse(getLastContentImageHitTestUrl())); - startActivity(intent); - } catch (Exception e) { - e.printStackTrace(); - toast(R.string.error_other_error); - } - } - return true; - case R.id.article_img_copy: - if (getLastContentImageHitTestUrl() != null) { - copyToClipboard(getLastContentImageHitTestUrl()); - } - return true; - case R.id.article_img_share: - if (getLastContentImageHitTestUrl() != null) { - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("image/png"); - intent.putExtra(Intent.EXTRA_SUBJECT, getLastContentImageHitTestUrl()); - intent.putExtra(Intent.EXTRA_TEXT, getLastContentImageHitTestUrl()); - - startActivity(Intent.createChooser(intent, getLastContentImageHitTestUrl())); - } - return true; - case R.id.article_img_view_caption: - if (getLastContentImageHitTestUrl() != null) { - - String content = ""; - - Cursor article = getArticleById(ap.getSelectedArticleId()); - - if (article != null) { - content = article.getString(article.getColumnIndex("content")); - article.close(); - } - - // Android doesn't give us an easy way to access title tags; - // we'll use Jsoup on the body text to grab the title text - // from the first image tag with this url. This will show - // the wrong text if an image is used multiple times. - Document doc = Jsoup.parse(content); - Elements es = doc.getElementsByAttributeValue("src", getLastContentImageHitTestUrl()); - if (es.size() > 0){ - if (es.get(0).hasAttr("title")){ - Dialog dia = new Dialog(this); - if (es.get(0).hasAttr("alt")){ - dia.setTitle(es.get(0).attr("alt")); - } else { - dia.setTitle(es.get(0).attr("title")); - } - TextView titleText = new TextView(this); - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { - titleText.setPaddingRelative(24, 24, 24, 24); - } else { - titleText.setPadding(24, 24, 24, 24); - } - - titleText.setTextSize(16); - titleText.setText(es.get(0).attr("title")); - dia.setContentView(titleText); - dia.show(); - } else { - toast(R.string.no_caption_to_display); - } - } else { - toast(R.string.no_caption_to_display); - } - } - return true; - default: - Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); - return super.onContextItemSelected(item); - } - - } - - @Override - public void onCreate(Bundle savedInstanceState) { - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - setAppTheme(m_prefs); - - 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) { - - } */ - - 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.headlines_toggle_sidebar: - if (true && !isSmallScreen()) { - SharedPreferences.Editor editor = m_prefs.edit(); - editor.putBoolean("headlines_hide_sidebar", !m_prefs.getBoolean("headlines_hide_sidebar", false)); - editor.commit(); - - if (ohf != null && ohf.isAdded()) { - ohf.getView().setVisibility(m_prefs.getBoolean("headlines_hide_sidebar", false) ? View.GONE : View.VISIBLE); - } - } - 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_view_mode: - if (ohf != null) { - Dialog dialog = new Dialog(this); - - String viewMode = getViewMode(); - - //Log.d(TAG, "viewMode:" + getViewMode()); - - int selectedIndex = 0; - - if (viewMode.equals("all_articles")) { - selectedIndex = 0; - } else if (viewMode.equals("marked")) { - selectedIndex = 1; - } else if (viewMode.equals("published")) { - selectedIndex = 2; - } else if (viewMode.equals("unread")) { - selectedIndex = 3; - } - - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setTitle(R.string.headlines_set_view_mode) - .setSingleChoiceItems( - new String[] { - /* getString(R.string.headlines_adaptive), */ - getString(R.string.headlines_all_articles), - getString(R.string.headlines_starred), - getString(R.string.headlines_published), - getString(R.string.headlines_unread) }, - selectedIndex, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, - int which) { - switch (which) { - /* case 0: - setViewMode("adaptive"); - break; */ - case 0: - setViewMode("all_articles"); - break; - case 1: - setViewMode("marked"); - break; - case 2: - setViewMode("published"); - break; - case 3: - setViewMode("unread"); - break; - } - dialog.cancel(); - - refresh(); - } - }); - - dialog = builder.create(); - dialog.show(); - - } - 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) { - final int feedId = ohf.getFeedId(); - final boolean isCat = ohf.getFeedIsCat(); - - int count = getUnreadArticleCount(feedId, isCat); - boolean confirm = m_prefs.getBoolean("confirm_headlines_catchup", true); - - if (count > 0) { - if (confirm) { - AlertDialog.Builder builder = new AlertDialog.Builder( - OfflineActivity.this) - .setMessage(getString(R.string.mark_num_headlines_as_read, count)) - .setPositiveButton(R.string.catchup, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - catchupFeed(feedId, isCat); - - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - - - } else { - catchupFeed(feedId, isCat); - } - } - } - return true; - case R.id.share_article: - if (true) { - 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 modified = 1, 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 modified = 1, 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 modified = 1, 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 modified = 1, 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 modified = 1, 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 modified = 1, 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 modified = 1, 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 modified = 1, 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_article, false); - m_menu.setGroupVisible(R.id.menu_group_feeds, false); - - OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - - if (hf != null) { - if (hf.getSelectedArticleCount() > 0 && m_headlinesActionMode == null) { - m_headlinesActionMode = startSupportActionMode(m_headlinesActionModeCallback); - } else if (hf.getSelectedArticleCount() == 0 && m_headlinesActionMode != null) { - m_headlinesActionMode.finish(); - } - } - - OfflineArticlePager ap = (OfflineArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - - if (ap != null) { - int articleId = ap.getSelectedArticleId(); - - Cursor article = getArticleById(articleId); - - if (article != null) { - boolean unread = article.getInt(article.getColumnIndex("unread")) == 1; - boolean marked = article.getInt(article.getColumnIndex("marked")) == 1; - boolean published = article.getInt(article.getColumnIndex("published")) == 1; - - m_menu.findItem(R.id.toggle_marked).setIcon(marked ? R.drawable.ic_important_light : - R.drawable.ic_unimportant_light); - - m_menu.findItem(R.id.toggle_published).setIcon(published ? R.drawable.ic_menu_published_light : - R.drawable.ic_menu_unpublished_light); - - m_menu.findItem(R.id.set_unread).setIcon(unread ? R.drawable.ic_unread_light : - R.drawable.ic_read_light); - - article.close(); - } - } - - if (!isCompatMode()) { - MenuItem search = m_menu.findItem(R.id.search); - - SearchView searchView = (SearchView) search.getActionView(); - - if (searchView != null) { - 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; - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (m_prefs.getBoolean("use_volume_keys", false)) { - OfflineArticlePager ap = (OfflineArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - - if (ap != null && ap.isAdded()) { - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_UP: - ap.selectArticle(false); - return true; - case KeyEvent.KEYCODE_VOLUME_DOWN: - ap.selectArticle(true); - return true; - } - } - } - - return super.onKeyDown(keyCode, event); - } - - // Handle onKeyUp too to suppress beep - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - if (m_prefs.getBoolean("use_volume_keys", false)) { - - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: - return true; - } - } - - return super.onKeyUp(keyCode, event); - } - - 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) { - if (article != null) { - 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; - } else { - return null; - } - } - - 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 int getUnreadArticleCount(int feedId, boolean isCat) { - - Cursor c; - - if (isCat) { - c = getReadableDb().query("articles", - new String[] { "COUNT(*)" }, "unread = 1 AND feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)", - new String[] { String.valueOf(feedId) }, - null, null, null); - } else { - c = getReadableDb().query("articles", - new String[] { "COUNT(*)" }, "unread = 1 AND feed_id = ?", - new String[] { String.valueOf(feedId) }, - 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(); - } - - initMenu(); - } - - public void catchupFeed(int feedId, boolean isCat) { - if (isCat) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET modified = 1, 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 modified = 1, unread = 0 WHERE feed_id = ?"); - stmt.bindLong(1, feedId); - stmt.execute(); - stmt.close(); - } - - refresh(); - } - - public void setLastContentImageHitTestUrl(String url) { - m_lastImageHitTestUrl = url; - } - - public String getLastContentImageHitTestUrl() { - return m_lastImageHitTestUrl; - } - - public void setViewMode(String viewMode) { - SharedPreferences.Editor editor = m_prefs.edit(); - editor.putString("offline_view_mode", viewMode); - editor.commit(); - } - - public String getViewMode() { - return m_prefs.getString("offline_view_mode", "adaptive"); - } - -} diff --git a/src/org/fox/ttrss/offline/OfflineArticleFragment.java b/src/org/fox/ttrss/offline/OfflineArticleFragment.java deleted file mode 100644 index 985150a9..00000000 --- a/src/org/fox/ttrss/offline/OfflineArticleFragment.java +++ /dev/null @@ -1,439 +0,0 @@ -package org.fox.ttrss.offline; - -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.fox.ttrss.CommonActivity; -import org.fox.ttrss.R; -import org.fox.ttrss.util.ImageCacheService; -import org.fox.ttrss.util.TypefaceCache; -import org.jsoup.Jsoup; -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.Color; -import android.graphics.Typeface; -import android.net.Uri; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.provider.BaseColumns; -import android.support.v4.app.Fragment; -import android.util.Log; -import android.util.TypedValue; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.webkit.WebChromeClient; -import android.webkit.WebSettings; -import android.webkit.WebView; -import android.webkit.WebView.HitTestResult; -import android.widget.TextView; - -public class OfflineArticleFragment extends Fragment { - 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 OfflineActivity m_activity; - - public void initialize(int articleId) { - 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) { - - //getActivity().getMenuInflater().inflate(R.menu.article_link_context_menu, menu); - //menu.setHeaderTitle(m_cursor.getString(m_cursor.getColumnIndex("title"))); - - String title = m_cursor.getString(m_cursor.getColumnIndex("title")); - - if (v.getId() == R.id.content) { - HitTestResult result = ((WebView)v).getHitTestResult(); - - if (result != null && (result.getType() == HitTestResult.IMAGE_TYPE || result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE)) { - menu.setHeaderTitle(result.getExtra()); - getActivity().getMenuInflater().inflate(R.menu.article_content_img_context_menu, menu); - - /* FIXME I have no idea how to do this correctly ;( */ - - m_activity.setLastContentImageHitTestUrl(result.getExtra()); - - } else { - menu.setHeaderTitle(title); - getActivity().getMenuInflater().inflate(R.menu.article_link_context_menu, menu); - } - } else { - menu.setHeaderTitle(title); - getActivity().getMenuInflater().inflate(R.menu.article_link_context_menu, menu); - } - - super.onCreateContextMenu(menu, v, menuInfo); - - } - - @SuppressLint("NewApi") - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - if (savedInstanceState != null) { - m_articleId = savedInstanceState.getInt("articleId"); - } - - boolean useTitleWebView = m_prefs.getBoolean("article_compat_view", false); - - View view = inflater.inflate(useTitleWebView ? R.layout.article_fragment_compat : R.layout.article_fragment, container, false); - - 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); - - m_cursor.moveToFirst(); - - if (m_cursor.isFirst()) { - if (!useTitleWebView) { - View scroll = view.findViewById(R.id.article_scrollview); - - if (scroll != null) { - final float scale = getResources().getDisplayMetrics().density; - - if (m_activity.isSmallScreen()) { - scroll.setPadding((int)(8 * scale + 0.5f), - (int)(5 * scale + 0.5f), - (int)(8 * scale + 0.5f), - 0); - } else { - scroll.setPadding((int)(25 * scale + 0.5f), - (int)(10 * scale + 0.5f), - (int)(25 * scale + 0.5f), - 0); - - } - - } - } - - int articleFontSize = Integer.parseInt(m_prefs.getString("article_font_size_sp", "16")); - int articleSmallFontSize = Math.max(10, Math.min(18, articleFontSize - 2)); - - TextView title = (TextView)view.findViewById(R.id.title); - - final String link = m_cursor.getString(m_cursor.getColumnIndex("link")); - - if (title != null) { - - if (m_prefs.getBoolean("enable_condensed_fonts", false)) { - Typeface tf = TypefaceCache.get(m_activity, "sans-serif-condensed", Typeface.NORMAL); - - if (tf != null && !tf.equals(title.getTypeface())) { - title.setTypeface(tf); - } - - title.setTextSize(TypedValue.COMPLEX_UNIT_SP, Math.min(21, articleFontSize + 5)); - } else { - title.setTextSize(TypedValue.COMPLEX_UNIT_SP, Math.min(21, articleFontSize + 3)); - } - - String titleStr; - - if (m_cursor.getString(m_cursor.getColumnIndex("title")).length() > 200) - titleStr = m_cursor.getString(m_cursor.getColumnIndex("title")).substring(0, 200) + "..."; - else - titleStr = m_cursor.getString(m_cursor.getColumnIndex("title")); - - title.setText(titleStr); - //title.setPaintFlags(title.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); - title.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - try { - URL url = new URL(link.trim()); - String uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), - url.getPort(), url.getPath(), url.getQuery(), url.getRef()).toString(); - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); - startActivity(intent); - } catch (Exception e) { - e.printStackTrace(); - m_activity.toast(R.string.error_other_error); - } - } - }); - - registerForContextMenu(title); - } - - TextView comments = (TextView)view.findViewById(R.id.comments); - - if (comments != null) { - comments.setVisibility(View.GONE); - } - - TextView note = (TextView)view.findViewById(R.id.note); - - if (note != null) { - note.setVisibility(View.GONE); - } - - final WebView web = (WebView)view.findViewById(R.id.content); - - if (web != null) { - - web.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - HitTestResult result = ((WebView)v).getHitTestResult(); - - if (result != null && (result.getType() == HitTestResult.IMAGE_TYPE || result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE)) { - registerForContextMenu(web); - m_activity.openContextMenu(web); - unregisterForContextMenu(web); - return true; - } else { - if (m_activity.isCompatMode()) { - KeyEvent shiftPressEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SHIFT_LEFT, 0, 0); - shiftPressEvent.dispatch(web); - } - - return false; - } - } - }); - - 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 = ""; - - WebSettings ws = web.getSettings(); - ws.setSupportZoom(false); - - TypedValue tv = new TypedValue(); - getActivity().getTheme().resolveAttribute(R.attr.linkColor, tv, true); - - // prevent flicker in ics - if (!m_prefs.getBoolean("webview_hardware_accel", true) || useTitleWebView) { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { - web.setLayerType(View.LAYER_TYPE_SOFTWARE, null); - } - } - - String theme = m_prefs.getString("theme", CommonActivity.THEME_DEFAULT); - - if (CommonActivity.THEME_HOLO.equals(theme)) { - cssOverride = "body { background : transparent; color : #e0e0e0}"; - } else if (CommonActivity.THEME_DARK.equals(theme)) { - cssOverride = "body { background : transparent; color : #e0e0e0}"; - } else { - cssOverride = "body { background : transparent; }"; - } - - if (useTitleWebView || android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) { - web.setBackgroundColor(Color.TRANSPARENT); - } else { - // seriously? - web.setBackgroundColor(Color.argb(1, 0, 0, 0)); - } - - String hexColor = String.format("#%06X", (0xFFFFFF & tv.data)); - cssOverride += " a:link {color: "+hexColor+";} a:visited { color: "+hexColor+";}"; - - cssOverride += " table { width : 100%; }"; - - String articleContent = m_cursor.getString(m_cursor.getColumnIndex("content")); - Document doc = Jsoup.parse(articleContent); - - if (doc != null) { - if (m_prefs.getBoolean("offline_image_cache_enabled", false)) { - - Elements images = doc.select("img"); - - for (Element img : images) { - String url = img.attr("src"); - - if (ImageCacheService.isUrlCached(m_activity, url)) { - img.attr("src", "file://" + ImageCacheService.getCacheFileName(m_activity, url)); - } - } - } - - // thanks webview for crashing on <video> tag - Elements videos = doc.select("video"); - - for (Element video : videos) - video.remove(); - - articleContent = doc.toString(); - } - - if (m_prefs.getBoolean("justify_article_text", true)) { - cssOverride += "body { text-align : justify; } "; - } - - ws.setDefaultFontSize(articleFontSize); - - content = - "<html>" + - "<head>" + - "<meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\">" + - "<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\" />" + - "<style type=\"text/css\">" + - "body { padding : 0px; margin : 0px; line-height : 130%; }" + - cssOverride + - "img { max-width : 100%; width : auto; height : auto; }" + - "</style>" + - "</head>" + - "<body>" + articleContent; - - if (useTitleWebView) { - content += "<p> </p><p> </p><p> </p><p> </p>"; - } - - content += "</body></html>"; - - try { - String baseUrl = null; - - try { - URL url = new URL(link); - baseUrl = url.getProtocol() + "://" + url.getHost(); - } catch (MalformedURLException e) { - // - } - - web.loadDataWithBaseURL(baseUrl, content, "text/html", "utf-8", null); - } catch (RuntimeException e) { - e.printStackTrace(); - } - - - } - - TextView dv = (TextView)view.findViewById(R.id.date); - - if (dv != null) { - dv.setTextSize(TypedValue.COMPLEX_UNIT_SP, articleSmallFontSize); - - Date d = new Date(m_cursor.getInt(m_cursor.getColumnIndex("updated")) * 1000L); - DateFormat df = new SimpleDateFormat("MMM dd, HH:mm"); - dv.setText(df.format(d)); - } - - TextView author = (TextView)view.findViewById(R.id.author); - - boolean hasAuthor = false; - - if (author != null) { - author.setTextSize(TypedValue.COMPLEX_UNIT_SP, articleSmallFontSize); - - int authorIndex = m_cursor.getColumnIndex("author"); - if (authorIndex >= 0) - author.setText(m_cursor.getString(authorIndex)); - else - author.setVisibility(View.GONE); - - hasAuthor = true; - } - - TextView tagv = (TextView)view.findViewById(R.id.tags); - - if (tagv != null) { - tagv.setTextSize(TypedValue.COMPLEX_UNIT_SP, articleSmallFontSize); - - int feedTitleIndex = m_cursor.getColumnIndex("feed_title"); - - if (feedTitleIndex != -1 /* && m_isCat */) { - String fTitle = m_cursor.getString(feedTitleIndex); - - int authorIndex = m_cursor.getColumnIndex("author"); - - if (!hasAuthor && authorIndex >= 0) { - fTitle += " (" + getString(R.string.author_formatted, m_cursor.getString(authorIndex)) + ")"; - } - - tagv.setText(fTitle); - } else { - String tagsStr = m_cursor.getString(m_cursor.getColumnIndex("tags")); - tagv.setText(tagsStr); - } - } - - } - - return view; - } - - @Override - public void onDestroy() { - super.onDestroy(); - - m_cursor.close(); - } - - @Override - public void onSaveInstanceState (Bundle out) { - super.onSaveInstanceState(out); - - out.putInt("articleId", m_articleId); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - - m_activity = (OfflineActivity) activity; - - } -} diff --git a/src/org/fox/ttrss/offline/OfflineArticlePager.java b/src/org/fox/ttrss/offline/OfflineArticlePager.java deleted file mode 100644 index 510ab97b..00000000 --- a/src/org/fox/ttrss/offline/OfflineArticlePager.java +++ /dev/null @@ -1,298 +0,0 @@ -package org.fox.ttrss.offline; - -import org.fox.ttrss.R; - -import com.viewpagerindicator.UnderlinePageIndicator; - -import android.app.Activity; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.os.Bundle; -import android.preference.PreferenceManager; -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; -import android.view.WindowManager; - -public class OfflineArticlePager extends Fragment { - private final String TAG = this.getClass().getSimpleName(); - - private PagerAdapter m_adapter; - 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 SharedPreferences m_prefs; - - 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 = ?"; - } - - String viewMode = m_activity.getViewMode(); - - if ("adaptive".equals(viewMode)) { - // TODO: implement adaptive - } else if ("marked".equals(viewMode)) { - feedClause += "AND (marked = 1)"; - } else if ("published".equals(viewMode)) { - feedClause += "AND (published = 1)"; - } else if ("unread".equals(viewMode)) { - feedClause += "AND (unread = 1)"; - } else { // all_articles - // - } - - String orderBy = (m_prefs.getBoolean("offline_oldest_first", false)) ? "updated" : "updated DESC"; - - 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, orderBy); - } 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, orderBy); - } - } - - @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) { - Log.d(TAG, "getItem: " + position); - - if (m_cursor.moveToPosition(position)) { - - if (m_prefs.getBoolean("dim_status_bar", false) && getView() != null && !m_activity.isCompatMode()) { - getView().setSystemUiVisibility(View.STATUS_BAR_HIDDEN); - } - - OfflineArticleFragment oaf = new OfflineArticleFragment(); - oaf.initialize(m_cursor.getInt(m_cursor.getColumnIndex(BaseColumns._ID))); - - return oaf; - } - - return null; - } - - @Override - public int getCount() { - return m_cursor.getCount(); - } - } - - @Override - public void onResume() { - super.onResume(); - - if (!m_activity.isCompatMode() && m_prefs.getBoolean("dim_status_bar", false)) { - getView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); - } - - if (m_prefs.getBoolean("full_screen_mode", false)) { - m_activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, - WindowManager.LayoutParams.FLAG_FULLSCREEN); - - /* if (!m_activity.isCompatMode()) { - m_activity.getSupportActionBar().hide(); - } */ - } - } - - public void initialize(int articleId, int feedId, boolean isCat) { - 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); - } - - Log.d(TAG, "feed=" + m_feedId + "; iscat=" + m_isCat); - - m_cursor = createCursor(); - - m_adapter = new PagerAdapter(getActivity().getSupportFragmentManager()); - - int position = 0; - - Log.d(TAG, "maId=" + m_articleId); - - if (m_articleId != 0) { - if (m_cursor.moveToFirst()) { - - while (!m_cursor.isAfterLast()) { - if (m_cursor.getInt(m_cursor.getColumnIndex(BaseColumns._ID)) == m_articleId) { - position = m_cursor.getPosition(); - break; - } - m_cursor.moveToNext(); - } - - Log.d(TAG, "(1)maId=" + m_articleId); - m_listener.onArticleSelected(m_articleId, false); - } - } else { - if (m_cursor.moveToFirst()) { - m_articleId = m_cursor.getInt(m_cursor.getColumnIndex(BaseColumns._ID)); - m_listener.onArticleSelected(m_articleId, false); - - Log.d(TAG, "(2)maId=" + m_articleId); - } - } - - - ViewPager pager = (ViewPager) view.findViewById(R.id.article_pager); - - pager.setAdapter(m_adapter); - - UnderlinePageIndicator indicator = (UnderlinePageIndicator)view.findViewById(R.id.article_titles); - indicator.setViewPager(pager); - - pager.setCurrentItem(position); - indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { - - @Override - public void onPageScrollStateChanged(int arg0) { - } - - @Override - public void onPageScrolled(int arg0, float arg1, int arg2) { - } - - @Override - public void onPageSelected(int position) { - if (m_cursor.moveToPosition(position)) { - int articleId = m_cursor.getInt(m_cursor.getColumnIndex(BaseColumns._ID)); - - m_articleId = articleId; - m_listener.onArticleSelected(articleId, false); - } - } - }); - - return view; - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - m_activity = (OfflineActivity)activity; - m_listener = (OfflineHeadlinesEventListener)activity; - - m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - - } - - 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; - - int position = getArticleIdPosition(articleId); - - ViewPager pager = (ViewPager) getView().findViewById(R.id.article_pager); - - pager.setCurrentItem(position); - - } - - public int getArticleIdPosition(int articleId) { - m_cursor.moveToFirst(); - - while (!m_cursor.isAfterLast()) { - if (m_cursor.getInt(m_cursor.getColumnIndex(BaseColumns._ID)) == articleId) { - return m_cursor.getPosition(); - } - m_cursor.moveToNext(); - } - - return -1; - } - - public void selectArticle(boolean next) { - int position = getArticleIdPosition(m_articleId); - - if (position != -1) { - if (next) - position++; - else - position--; - - Log.d(TAG, "pos=" + position); - - if (m_cursor.moveToPosition(position)) { - setArticleId(m_cursor.getInt(m_cursor.getColumnIndex(BaseColumns._ID))); - } - } - } -} diff --git a/src/org/fox/ttrss/offline/OfflineDownloadService.java b/src/org/fox/ttrss/offline/OfflineDownloadService.java deleted file mode 100644 index 2d65c890..00000000 --- a/src/org/fox/ttrss/offline/OfflineDownloadService.java +++ /dev/null @@ -1,500 +0,0 @@ -package org.fox.ttrss.offline; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.List; - -import org.fox.ttrss.ApiRequest; -import org.fox.ttrss.OnlineActivity; -import org.fox.ttrss.R; -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.Feed; -import org.fox.ttrss.types.FeedCategory; -import org.fox.ttrss.util.DatabaseHelper; -import org.fox.ttrss.util.ImageCacheService; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; - -import android.app.ActivityManager; -import android.app.ActivityManager.RunningServiceInfo; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteStatement; -import android.os.Binder; -import android.os.IBinder; -import android.preference.PreferenceManager; -import android.provider.BaseColumns; -import android.util.Log; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; - -public class OfflineDownloadService extends Service { - - private final String TAG = this.getClass().getSimpleName(); - - public static final int NOTIFY_DOWNLOADING = 1; - 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 = 50; - private static final int OFFLINE_SYNC_MAX = OFFLINE_SYNC_SEQ * 10; - - private SQLiteDatabase m_writableDb; - private SQLiteDatabase m_readableDb; - private int m_articleOffset = 0; - private String m_sessionId; - private NotificationManager m_nmgr; - - private boolean m_batchMode = false; - private boolean m_downloadInProgress = false; - private boolean m_downloadImages = false; - private int m_syncMax; - private SharedPreferences m_prefs; - private boolean m_canProceed = true; - - private final IBinder m_binder = new LocalBinder(); - - public class LocalBinder extends Binder { - OfflineDownloadService getService() { - return OfflineDownloadService.this; - } - } - - @Override - public IBinder onBind(Intent intent) { - return m_binder; - } - - @Override - public void onCreate() { - super.onCreate(); - m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - m_downloadImages = m_prefs.getBoolean("offline_image_cache_enabled", false); - m_syncMax = Integer.parseInt(m_prefs.getString("offline_sync_max", String.valueOf(OFFLINE_SYNC_MAX))); - - 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, OnlineActivity.class); - intent.setAction(INTENT_ACTION_CANCEL); - - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, - intent, 0); - - notification.flags |= Notification.FLAG_ONGOING_EVENT; - notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE; - - notification.setLatestEventInfo(this, getString(R.string.notify_downloading_title), msg, contentIntent); - - m_nmgr.notify(NOTIFY_DOWNLOADING, notification); - } - - private void updateNotification(int msgResId) { - updateNotification(getString(msgResId)); - } - - private void downloadFailed() { - m_readableDb.close(); - m_writableDb.close(); - - m_nmgr.cancel(NOTIFY_DOWNLOADING); - - // TODO send notification to activity? - - m_downloadInProgress = false; - stopSelf(); - } - - private boolean isCacheServiceRunning() { - ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); - for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { - if ("org.fox.ttrss.util.ImageCacheService".equals(service.service.getClassName())) { - return true; - } - } - return false; - } - - public void downloadComplete() { - m_downloadInProgress = false; - - // if cache service is running, it will send a finished intent on its own - if (!isCacheServiceRunning()) { - m_nmgr.cancel(NOTIFY_DOWNLOADING); - - if (m_batchMode) { - - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = localPrefs.edit(); - editor.putBoolean("offline_mode_active", true); - editor.commit(); - - } else { - Intent intent = new Intent(); - intent.setAction(INTENT_ACTION_SUCCESS); - intent.addCategory(Intent.CATEGORY_DEFAULT); - sendBroadcast(intent); - } - } else { - updateNotification(getString(R.string.notify_downloading_images, 0)); - } - - m_readableDb.close(); - m_writableDb.close(); - - stopSelf(); - } - - private void initDatabase() { - DatabaseHelper dh = new DatabaseHelper(getApplicationContext()); - m_writableDb = dh.getWritableDatabase(); - m_readableDb = dh.getReadableDatabase(); - } - - /* private synchronized SQLiteDatabase getReadableDb() { - return m_readableDb; - } */ - - private synchronized SQLiteDatabase getWritableDb() { - return m_writableDb; - } - - @SuppressWarnings("unchecked") - private void downloadArticles() { - Log.d(TAG, "offline: downloading articles... offset=" + m_articleOffset); - - updateNotification(getString(R.string.notify_downloading_articles, m_articleOffset)); - - OfflineArticlesRequest req = new OfflineArticlesRequest(this); - - @SuppressWarnings("serial") - HashMap<String,String> map = new HashMap<String,String>() { - { - put("op", "getHeadlines"); - put("sid", m_sessionId); - put("feed_id", "-4"); - put("view_mode", "unread"); - put("show_content", "true"); - put("skip", String.valueOf(m_articleOffset)); - put("limit", String.valueOf(OFFLINE_SYNC_SEQ)); - } - }; - - req.execute(map); - } - - private void downloadFeeds() { - - updateNotification(R.string.notify_downloading_feeds); - - getWritableDb().execSQL("DELETE FROM feeds;"); - - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - 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); - - SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO feeds " + - "("+BaseColumns._ID+", title, feed_url, has_icon, cat_id) " + - "VALUES (?, ?, ?, ?, ?);"); - - for (Feed feed : feeds) { - stmtInsert.bindLong(1, feed.id); - stmtInsert.bindString(2, feed.title); - 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;"); - } 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(); - } - } - - }; - - @SuppressWarnings("serial") - HashMap<String,String> map = new HashMap<String,String>() { - { - put("op", "getFeeds"); - put("sid", m_sessionId); - put("cat_id", "-3"); - put("unread_only", "true"); - } - }; - - req.execute(map); - } - - private void downloadCategories() { - - updateNotification(R.string.notify_downloading_feeds); - - getWritableDb().execSQL("DELETE FROM categories;"); - - ApiRequest req = new ApiRequest(getApplicationContext()) { - 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); - - SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO categories " + - "("+BaseColumns._ID+", title) " + - "VALUES (?, ?);"); - - for (FeedCategory cat : cats) { - stmtInsert.bindLong(1, cat.id); - stmtInsert.bindString(2, cat.title); - - stmtInsert.execute(); - } - - stmtInsert.close(); - - Log.d(TAG, "offline: done downloading categories"); - - } 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(); - } - } - - }; - - @SuppressWarnings("serial") - HashMap<String,String> map = new HashMap<String,String>() { - { - put("op", "getCategories"); - put("sid", m_sessionId); - //put("cat_id", "-3"); - put("unread_only", "true"); - } - }; - - req.execute(map); - } - - - @Override - public void onDestroy() { - super.onDestroy(); - m_nmgr.cancel(NOTIFY_DOWNLOADING); - - m_canProceed = false; - Log.d(TAG, "onDestroy"); - - //m_readableDb.close(); - //m_writableDb.close(); - } - - public class OfflineArticlesRequest extends ApiRequest { - List<Article> m_articles; - - public OfflineArticlesRequest(Context context) { - super(context); - } - - @Override - protected JsonElement doInBackground(HashMap<String, String>... params) { - JsonElement content = super.doInBackground(params); - - if (content != null) { - - try { - Type listType = new TypeToken<List<Article>>() {}.getType(); - m_articles = new Gson().fromJson(content, listType); - - SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO articles " + - "("+BaseColumns._ID+", unread, marked, published, score, updated, is_updated, title, link, feed_id, tags, content, author) " + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); - - for (Article article : m_articles) { - - String tagsString = ""; - - for (String t : article.tags) { - tagsString += t + ", "; - } - - tagsString = tagsString.replaceAll(", $", ""); - - int index = 1; - stmtInsert.bindLong(index++, article.id); - stmtInsert.bindLong(index++, article.unread ? 1 : 0); - stmtInsert.bindLong(index++, article.marked ? 1 : 0); - stmtInsert.bindLong(index++, article.published ? 1 : 0); - stmtInsert.bindLong(index++, article.score); - stmtInsert.bindLong(index++, article.updated); - stmtInsert.bindLong(index++, article.is_updated ? 1 : 0); - stmtInsert.bindString(index++, article.title); - stmtInsert.bindString(index++, article.link); - stmtInsert.bindLong(index++, article.feed_id); - stmtInsert.bindString(index++, tagsString); // comma-separated tags - stmtInsert.bindString(index++, article.content); - stmtInsert.bindString(index++, article.author != null ? article.author : ""); - - if (m_downloadImages) { - Document doc = Jsoup.parse(article.content); - - if (doc != null) { - Elements images = doc.select("img"); - - for (Element img : images) { - String url = img.attr("src"); - - if (url.indexOf("://") != -1) { - if (!ImageCacheService.isUrlCached(OfflineDownloadService.this, url)) { - Intent intent = new Intent(OfflineDownloadService.this, - ImageCacheService.class); - - intent.putExtra("url", url); - startService(intent); - } - } - } - } - } - - try { - stmtInsert.execute(); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - m_articleOffset += m_articles.size(); - - Log.d(TAG, "offline: received " + m_articles.size() + " articles; canProc=" + m_canProceed); - - stmtInsert.close(); - - } catch (Exception e) { - updateNotification(R.string.offline_switch_error); - Log.d(TAG, "offline: failed: exception when loading articles"); - e.printStackTrace(); - 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()); - downloadFailed(); - } - } - } - - @Override - public void onStart(Intent intent, int startId) { - try { - if (getWritableDb().isDbLockedByCurrentThread() || getWritableDb().isDbLockedByOtherThreads()) { - return; - } - - m_sessionId = intent.getStringExtra("sessionId"); - m_batchMode = intent.getBooleanExtra("batchMode", false); - - if (!m_downloadInProgress) { - if (m_downloadImages) ImageCacheService.cleanupCache(this, false); - - updateNotification(R.string.notify_downloading_init); - m_downloadInProgress = true; - - downloadCategories(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java b/src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java deleted file mode 100644 index 8fde8176..00000000 --- a/src/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java +++ /dev/null @@ -1,337 +0,0 @@ -package org.fox.ttrss.offline; - -import org.fox.ttrss.R; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.database.Cursor; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.provider.BaseColumns; -import android.support.v4.app.Fragment; -import android.support.v4.widget.SimpleCursorAdapter; -import android.util.Log; -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.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.TextView; - -public class OfflineFeedCategoriesFragment extends Fragment implements OnItemClickListener, OnSharedPreferenceChangeListener { - private final String TAG = this.getClass().getSimpleName(); - private SharedPreferences m_prefs; - private FeedCategoryListAdapter m_adapter; - private int m_selectedCatId; - private Cursor m_cursor; - private OfflineFeedsActivity m_activity; - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - - getActivity().getMenuInflater().inflate(R.menu.category_menu, menu); - - AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; - Cursor cursor = (Cursor)m_adapter.getItem(info.position); - - if (cursor != null) - menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex("title"))); - - if (!m_activity.isSmallScreen()) { - menu.findItem(R.id.browse_articles).setVisible(false); - } - - super.onCreateContextMenu(menu, v, menuInfo); - - } - - public Cursor createCursor() { - 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_activity.getReadableDb().query("cats_unread", - null, unreadOnly, null, null, null, order); - } - - public void refresh() { - if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close(); - - m_cursor = createCursor(); - - if (m_cursor != null && m_adapter != null) { - m_adapter.changeCursor(m_cursor); - m_adapter.notifyDataSetChanged(); - } - } - - @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.openFeedArticles(catId, true); - } - } - return true; - case R.id.browse_headlines: - 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) { - m_selectedCatId = savedInstanceState.getInt("selectedFeedId"); - } - - View view = inflater.inflate(R.layout.feeds_fragment, container, false); - - ListView list = (ListView)view.findViewById(R.id.feeds); - - m_cursor = createCursor(); - - m_adapter = new FeedCategoryListAdapter(getActivity(), R.layout.feeds_row, m_cursor, - new String[] { "title", "unread" }, new int[] { R.id.title, R.id.unread_counter }, 0); - - list.setAdapter(m_adapter); - list.setOnItemClickListener(this); - list.setEmptyView(view.findViewById(R.id.no_feeds)); - registerForContextMenu(list); - - view.findViewById(R.id.loading_container).setVisibility(View.GONE); - - return view; - } - - @Override - public void onDestroy() { - super.onDestroy(); - - if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close(); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - m_activity = (OfflineFeedsActivity)activity; - - m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - m_prefs.registerOnSharedPreferenceChangeListener(this); - - } - - @Override - public void onSaveInstanceState (Bundle out) { - super.onSaveInstanceState(out); - - out.putInt("selectedFeedId", m_selectedCatId); - } - - @Override - public void onItemClick(AdapterView<?> av, View view, int position, long id) { - ListView list = (ListView)getActivity().findViewById(R.id.feeds); - - if (list != null) { - Cursor cursor = (Cursor) list.getItemAtPosition(position); - - if (cursor != null) { - int feedId = (int) cursor.getLong(0); - Log.d(TAG, "clicked on feed " + feedId); - - if (m_activity.isSmallScreen() && "ARTICLES".equals(m_prefs.getString("default_view_mode", "HEADLINES")) && - m_prefs.getBoolean("browse_cats_like_feeds", false)) { - - m_activity.openFeedArticles(feedId, true); - - } else { - m_activity.onCatSelected(feedId); - } - - /* if (!m_activity.isSmallScreen()) - m_selectedCatId = feedId; */ - - m_adapter.notifyDataSetChanged(); - } - } - } - - /* public void setLoadingStatus(int status, boolean showProgress) { - if (getView() != null) { - TextView tv = (TextView)getView().findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(status); - } - } - - getActivity().setProgressBarIndeterminateVisibility(showProgress); - } */ - - private class FeedCategoryListAdapter extends SimpleCursorAdapter { - - - public FeedCategoryListAdapter(Context context, int layout, Cursor c, - String[] from, int[] to, int flags) { - super(context, layout, c, from, to, flags); - } - - public static final int VIEW_NORMAL = 0; - public static final int VIEW_SELECTED = 1; - - public static final int VIEW_COUNT = VIEW_SELECTED+1; - - @Override - public int getViewTypeCount() { - return VIEW_COUNT; - } - - @Override - public int getItemViewType(int position) { - Cursor cursor = (Cursor) this.getItem(position); - - if (!m_activity.isSmallScreen() && cursor.getLong(0) == m_selectedCatId) { - return VIEW_SELECTED; - } else { - return VIEW_NORMAL; - } - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - - Cursor cursor = (Cursor)getItem(position); - - if (v == null) { - int layoutId = R.layout.feeds_row; - - switch (getItemViewType(position)) { - case VIEW_SELECTED: - layoutId = R.layout.feeds_row_selected; - break; - } - - LayoutInflater vi = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(layoutId, null); - - } - - TextView tt = (TextView) v.findViewById(R.id.title); - - if (tt != null) { - tt.setText(cursor.getString(cursor.getColumnIndex("title"))); - } - - TextView tu = (TextView) v.findViewById(R.id.unread_counter); - - if (tu != null) { - tu.setText(String.valueOf(cursor.getInt(cursor.getColumnIndex("unread")))); - tu.setVisibility((cursor.getInt(cursor.getColumnIndex("unread")) > 0) ? View.VISIBLE : View.INVISIBLE); - } - - ImageView icon = (ImageView)v.findViewById(R.id.icon); - - if (icon != null) { - icon.setImageResource(cursor.getInt(cursor.getColumnIndex("unread")) > 0 ? R.drawable.ic_published : R.drawable.ic_unpublished); - } - - ImageButton ib = (ImageButton) v.findViewById(R.id.feed_menu_button); - - if (ib != null) { - ib.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - getActivity().openContextMenu(v); - } - }); - } - - - return v; - } - } - - public void sortCategories() { - try { - refresh(); - } catch (NullPointerException e) { - // activity is gone? - } catch (IllegalStateException e) { - // we're probably closing and DB is gone already - } - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, - String key) { - - sortCategories(); - } - - public int getCatIdAtPosition(int position) { - Cursor c = (Cursor)m_adapter.getItem(position); - - if (c != null) { - int catId = c.getInt(0); - return catId; - } - - return -10000; - } - - public void setSelectedFeedId(int feedId) { - m_selectedCatId = feedId; - refresh(); - } - -} diff --git a/src/org/fox/ttrss/offline/OfflineFeedsActivity.java b/src/org/fox/ttrss/offline/OfflineFeedsActivity.java deleted file mode 100644 index f7263fe0..00000000 --- a/src/org/fox/ttrss/offline/OfflineFeedsActivity.java +++ /dev/null @@ -1,349 +0,0 @@ -package org.fox.ttrss.offline; - -import org.fox.ttrss.GlobalState; -import org.fox.ttrss.R; - -import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; - -import android.animation.LayoutTransition; -import android.annotation.SuppressLint; -import android.content.Intent; -import android.database.sqlite.SQLiteStatement; -import android.os.Bundle; -import android.os.Handler; -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.ViewGroup; -import android.widget.LinearLayout; - -public class OfflineFeedsActivity extends OfflineActivity implements OfflineHeadlinesEventListener { - private final String TAG = this.getClass().getSimpleName(); - - private boolean m_actionbarUpEnabled = false; - private int m_actionbarRevertDepth = 0; - private SlidingMenu m_slidingMenu; - private boolean m_feedIsSelected = false; - private boolean m_feedWasSelected = false; - - @SuppressLint("NewApi") - @Override - public void onCreate(Bundle savedInstanceState) { - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - setAppTheme(m_prefs); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.headlines); - - setStatusBarTint(); - setSmallScreen(findViewById(R.id.sw600dp_anchor) == null && - findViewById(R.id.sw600dp_port_anchor) == null); - - GlobalState.getInstance().load(savedInstanceState); - - if (isSmallScreen() || findViewById(R.id.sw600dp_port_anchor) != null) { - m_slidingMenu = new SlidingMenu(this); - - /* if (findViewById(R.id.sw600dp_port_anchor) != null) { - m_slidingMenu.setBehindWidth(getScreenWidthInPixel() * 2/3); - } */ - - m_slidingMenu.setMode(SlidingMenu.LEFT); - m_slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); - m_slidingMenu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT); - m_slidingMenu.setSlidingEnabled(true); - m_slidingMenu.setMenu(R.layout.feeds); - - m_slidingMenu.setOnClosedListener(new SlidingMenu.OnClosedListener() { - - @Override - public void onClosed() { - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - m_actionbarUpEnabled = true; - m_feedIsSelected = true; - - initMenu(); - } - }); - - m_slidingMenu.setOnOpenedListener(new SlidingMenu.OnOpenedListener() { - - @Override - public void onOpened() { - if (m_actionbarRevertDepth == 0) { - m_actionbarUpEnabled = false; - m_feedIsSelected = false; - getSupportActionBar().setDisplayHomeAsUpEnabled(false); - refresh(); - } - - initMenu(); - } - }); - } - - if (savedInstanceState != null) { - - m_actionbarUpEnabled = savedInstanceState.getBoolean("actionbarUpEnabled"); - m_actionbarRevertDepth = savedInstanceState.getInt("actionbarRevertDepth"); - m_feedIsSelected = savedInstanceState.getBoolean("feedIsSelected"); - m_feedWasSelected = savedInstanceState.getBoolean("feedWasSelected"); - - if (findViewById(R.id.sw600dp_port_anchor) != null && m_feedWasSelected && m_slidingMenu != null) { - m_slidingMenu.setBehindWidth(getScreenWidthInPixel() * 2/3); - } - - if (m_slidingMenu != null && m_feedIsSelected == false) { - m_slidingMenu.showMenu(); - } else if (m_slidingMenu != null) { - m_actionbarUpEnabled = true; - } else { - m_actionbarUpEnabled = m_actionbarRevertDepth > 0; - } - - if (m_actionbarUpEnabled) { - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } - - } else { - if (m_slidingMenu != null) - m_slidingMenu.showMenu(); - - 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); - - initMenu(); - - if (!isCompatMode() && !isSmallScreen()) { - ((ViewGroup)findViewById(R.id.headlines_fragment)).setLayoutTransition(new LayoutTransition()); - ((ViewGroup)findViewById(R.id.feeds_fragment)).setLayoutTransition(new LayoutTransition()); - } - } - - public void openFeedArticles(int feedId, boolean isCat) { - if (isSmallScreen()) { - Intent intent = new Intent(OfflineFeedsActivity.this, OfflineHeadlinesActivity.class); - - intent.putExtra("feed", feedId); - intent.putExtra("isCat", isCat); - intent.putExtra("article", 0); - startActivityForResult(intent, 0); - } - } - - @Override - public void onBackPressed() { - if (m_actionbarRevertDepth > 0) { - - if (m_feedIsSelected && m_slidingMenu != null && !m_slidingMenu.isMenuShowing()) { - m_slidingMenu.showMenu(); - } else { - m_actionbarRevertDepth = m_actionbarRevertDepth - 1; - m_actionbarUpEnabled = m_actionbarRevertDepth > 0; - getSupportActionBar().setDisplayHomeAsUpEnabled(m_actionbarUpEnabled); - - onBackPressed(); - } - } else if (m_slidingMenu != null && !m_slidingMenu.isMenuShowing()) { - m_slidingMenu.showMenu(); - } else { - super.onBackPressed(); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - if (m_actionbarUpEnabled) - onBackPressed(); - return true; - 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); - - out.putBoolean("actionbarUpEnabled", m_actionbarUpEnabled); - out.putInt("actionbarRevertDepth", m_actionbarRevertDepth); - out.putBoolean("feedIsSelected", m_feedIsSelected); - out.putBoolean("feedWasSelected", m_feedWasSelected); - - - //if (m_slidingMenu != null ) - // out.putBoolean("slidingMenuVisible", m_slidingMenu.isMenuShowing()); - - GlobalState.getInstance().save(out); - } - - public void initMenu() { - super.initMenu(); - - if (m_menu != null) { - Fragment ff = getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - Fragment cf = getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - - if (m_slidingMenu != null) { - m_menu.setGroupVisible(R.id.menu_group_feeds, m_slidingMenu.isMenuShowing()); - m_menu.setGroupVisible(R.id.menu_group_headlines, hf != null && hf.isAdded() && !m_slidingMenu.isMenuShowing()); - } else { - m_menu.setGroupVisible(R.id.menu_group_feeds, (ff != null && ff.isAdded()) || (cf != null && cf.isAdded())); - m_menu.setGroupVisible(R.id.menu_group_headlines, hf != null && hf.isAdded()); - } - - m_menu.findItem(R.id.headlines_toggle_sidebar).setVisible(false); - - 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) { - OfflineFeedCategoriesFragment fc = (OfflineFeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - - if (openAsFeed) { - if (fc != null) { - fc.setSelectedFeedId(catId); - } - - onFeedSelected(catId, true, true); - } else { - if (fc != null) { - fc.setSelectedFeedId(-1); - } - - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - OfflineFeedsFragment ff = new OfflineFeedsFragment(); - ff.initialize(catId); - - ft.replace(R.id.feeds_fragment, ff, FRAG_FEEDS); - ft.addToBackStack(null); - - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - m_actionbarUpEnabled = true; - m_actionbarRevertDepth = m_actionbarRevertDepth + 1; - - ft.commit(); - } - } - - public void onFeedSelected(int feedId) { - onFeedSelected(feedId, false, true); - } - - public void onFeedSelected(final int feedId, final boolean isCat, boolean open) { - - if (open) { - if (!isSmallScreen()) { - LinearLayout container = (LinearLayout) findViewById(R.id.fragment_container); - if (container != null) { - container.setWeightSum(3f); - } - } - - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - OfflineHeadlinesFragment hf = new OfflineHeadlinesFragment(); - hf.initialize(feedId, isCat); - ft.replace(R.id.headlines_fragment, hf, FRAG_HEADLINES); - - ft.commit(); - - m_feedIsSelected = true; - m_feedWasSelected = true; - - if (m_slidingMenu != null) { - if (findViewById(R.id.sw600dp_port_anchor) != null) { - m_slidingMenu.setBehindWidth(getScreenWidthInPixel() * 2/3); - } - - m_slidingMenu.showContent(); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - m_actionbarUpEnabled = true; - } - } - }, 10); - } - } - - @Override - public void onArticleSelected(int articleId, boolean open) { - - if (!open) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET modified = 1, unread = 0 " + "WHERE " + BaseColumns._ID - + " = ?"); - - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - } - - initMenu(); - - if (open) { - 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); - - overridePendingTransition(R.anim.right_slide_in, 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 deleted file mode 100644 index 8c04d0cd..00000000 --- a/src/org/fox/ttrss/offline/OfflineFeedsFragment.java +++ /dev/null @@ -1,372 +0,0 @@ -package org.fox.ttrss.offline; - -import java.io.File; - -import org.fox.ttrss.R; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.Bundle; -import android.os.Environment; -import android.preference.PreferenceManager; -import android.provider.BaseColumns; -import android.support.v4.app.Fragment; -import android.support.v4.widget.SimpleCursorAdapter; -import android.util.Log; -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.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.TextView; - -public class OfflineFeedsFragment extends Fragment implements OnItemClickListener, OnSharedPreferenceChangeListener { - private final String TAG = this.getClass().getSimpleName(); - private SharedPreferences m_prefs; - private FeedListAdapter m_adapter; - private static final String ICON_PATH = "/data/org.fox.ttrss/icons/"; - private int m_selectedFeedId; - private int m_catId = -1; - private boolean m_enableFeedIcons; - private Cursor m_cursor; - private OfflineFeedsActivity m_activity; - - public void initialize(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.browse_articles: - if (true) { - int feedId = getFeedIdAtPosition(info.position); - if (feedId != -10000) { - m_activity.openFeedArticles(feedId, false); - } - } - return true; - case R.id.browse_headlines: - if (true) { - int feedId = getFeedIdAtPosition(info.position); - if (feedId != -10000) { - m_activity.onFeedSelected(feedId); - } - } - return true; - 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) { - - getActivity().getMenuInflater().inflate(R.menu.feed_menu, menu); - - AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; - Cursor cursor = (Cursor)m_adapter.getItem(info.position); - - if (cursor != null) - menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex("title"))); - - if (!m_activity.isSmallScreen()) { - menu.findItem(R.id.browse_articles).setVisible(false); - } - - super.onCreateContextMenu(menu, v, menuInfo); - - } - - public Cursor createCursor() { - 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_activity.getReadableDb().query("feeds_unread", - null, unreadOnly + " AND cat_id = ?", new String[] { String.valueOf(m_catId) }, null, null, order); - } else { - return m_activity.getReadableDb().query("feeds_unread", - null, unreadOnly, null, null, null, order); - } - } - - public void refresh() { - try { - if (!isAdded()) return; - - if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close(); - - m_cursor = createCursor(); - - if (m_cursor != null && m_adapter != null) { - m_adapter.changeCursor(m_cursor); - m_adapter.notifyDataSetChanged(); - } - } catch (NullPointerException e) { - e.printStackTrace(); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - if (savedInstanceState != null) { - m_selectedFeedId = savedInstanceState.getInt("selectedFeedId"); - m_catId = savedInstanceState.getInt("catId"); - } - - View view = inflater.inflate(R.layout.feeds_fragment, container, false); - - ListView list = (ListView)view.findViewById(R.id.feeds); - - m_cursor = createCursor(); - - m_adapter = new FeedListAdapter(getActivity(), R.layout.feeds_row, m_cursor, - new String[] { "title", "unread" }, new int[] { R.id.title, R.id.unread_counter }, 0); - - list.setAdapter(m_adapter); - list.setOnItemClickListener(this); - list.setEmptyView(view.findViewById(R.id.no_feeds)); - registerForContextMenu(list); - - view.findViewById(R.id.loading_container).setVisibility(View.GONE); - - m_enableFeedIcons = m_prefs.getBoolean("download_feed_icons", false); - - return view; - } - - @Override - public void onDestroy() { - super.onDestroy(); - - if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close(); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - m_activity = (OfflineFeedsActivity)activity; - - m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - m_prefs.registerOnSharedPreferenceChangeListener(this); - - } - - @Override - public void onSaveInstanceState (Bundle out) { - super.onSaveInstanceState(out); - - out.putInt("selectedFeedId", m_selectedFeedId); - out.putInt("catId", m_catId); - } - - @Override - public void onItemClick(AdapterView<?> av, View view, int position, long id) { - ListView list = (ListView)getActivity().findViewById(R.id.feeds); - - if (list != null) { - Cursor cursor = (Cursor) list.getItemAtPosition(position); - - if (cursor != null) { - int feedId = (int) cursor.getLong(0); - Log.d(TAG, "clicked on feed " + feedId); - - if (!m_activity.isSmallScreen() && "ARTICLES".equals(m_prefs.getString("default_view_mode", "HEADLINES"))) { - m_activity.openFeedArticles(feedId, false); - } else { - m_activity.onFeedSelected(feedId); - } - - if (!m_activity.isSmallScreen()) - m_selectedFeedId = feedId; - - m_adapter.notifyDataSetChanged(); - } - } - } - - /* public void setLoadingStatus(int status, boolean showProgress) { - if (getView() != null) { - TextView tv = (TextView)getView().findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(status); - } - } - - getActivity().setProgressBarIndeterminateVisibility(showProgress); - } */ - - private class FeedListAdapter extends SimpleCursorAdapter { - - - public FeedListAdapter(Context context, int layout, Cursor c, - String[] from, int[] to, int flags) { - super(context, layout, c, from, to, flags); - } - - public static final int VIEW_NORMAL = 0; - public static final int VIEW_SELECTED = 1; - - public static final int VIEW_COUNT = VIEW_SELECTED+1; - - @Override - public int getViewTypeCount() { - return VIEW_COUNT; - } - - @Override - public int getItemViewType(int position) { - Cursor cursor = (Cursor) this.getItem(position); - - if (!m_activity.isSmallScreen() && cursor.getLong(0) == m_selectedFeedId) { - return VIEW_SELECTED; - } else { - return VIEW_NORMAL; - } - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - - Cursor cursor = (Cursor)getItem(position); - - if (v == null) { - int layoutId = R.layout.feeds_row; - - switch (getItemViewType(position)) { - case VIEW_SELECTED: - layoutId = R.layout.feeds_row_selected; - break; - } - - LayoutInflater vi = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(layoutId, null); - - } - - TextView tt = (TextView) v.findViewById(R.id.title); - - if (tt != null) { - tt.setText(cursor.getString(cursor.getColumnIndex("title"))); - } - - TextView tu = (TextView) v.findViewById(R.id.unread_counter); - - if (tu != null) { - tu.setText(String.valueOf(cursor.getInt(cursor.getColumnIndex("unread")))); - tu.setVisibility((cursor.getInt(cursor.getColumnIndex("unread")) > 0) ? View.VISIBLE : View.INVISIBLE); - } - - ImageView icon = (ImageView)v.findViewById(R.id.icon); - - if (icon != null) { - - if (m_enableFeedIcons) { - - try { - File storage = Environment.getExternalStorageDirectory(); - - File iconFile = new File(storage.getAbsolutePath() + ICON_PATH + cursor.getInt(cursor.getColumnIndex(BaseColumns._ID)) + ".ico"); - if (iconFile.exists()) { - Bitmap bmpOrig = BitmapFactory.decodeFile(iconFile.getAbsolutePath()); - if (bmpOrig != null) { - icon.setImageBitmap(bmpOrig); - } - } else { - icon.setImageResource(cursor.getInt(cursor.getColumnIndex("unread")) > 0 ? R.drawable.ic_published : R.drawable.ic_unpublished); - } - } catch (NullPointerException e) { - icon.setImageResource(cursor.getInt(cursor.getColumnIndex("unread")) > 0 ? R.drawable.ic_published : R.drawable.ic_unpublished); - } - - } else { - icon.setImageResource(cursor.getInt(cursor.getColumnIndex("unread")) > 0 ? R.drawable.ic_published : R.drawable.ic_unpublished); - } - - } - - ImageButton ib = (ImageButton) v.findViewById(R.id.feed_menu_button); - - if (ib != null) { - ib.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - getActivity().openContextMenu(v); - } - }); - } - - return v; - } - } - - public void sortFeeds() { - try { - refresh(); - } catch (NullPointerException e) { - // activity is gone? - } catch (IllegalStateException e) { - // we're probably closing and DB is gone already - } - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, - String key) { - - sortFeeds(); - m_enableFeedIcons = m_prefs.getBoolean("download_feed_icons", false); - - } - - public int getFeedIdAtPosition(int position) { - Cursor c = (Cursor)m_adapter.getItem(position); - - if (c != null) { - int feedId = c.getInt(0); - return feedId; - } - - return -10000; - } - - public void setSelectedFeedId(int feedId) { - m_selectedFeedId = feedId; - refresh(); - } - -} diff --git a/src/org/fox/ttrss/offline/OfflineHeadlinesActivity.java b/src/org/fox/ttrss/offline/OfflineHeadlinesActivity.java deleted file mode 100644 index de57c985..00000000 --- a/src/org/fox/ttrss/offline/OfflineHeadlinesActivity.java +++ /dev/null @@ -1,167 +0,0 @@ -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.util.Log; -import android.view.MenuItem; -import android.view.View; - -public class OfflineHeadlinesActivity extends OfflineActivity implements OfflineHeadlinesEventListener { - private final String TAG = this.getClass().getSimpleName(); - - protected SharedPreferences m_prefs; - - @SuppressLint("NewApi") - @Override - public void onCreate(Bundle savedInstanceState) { - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - setAppTheme(m_prefs); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.headlines_articles); - - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - setStatusBarTint(); - setSmallScreen(findViewById(R.id.sw600dp_anchor) == null); - - if (isPortrait() || m_prefs.getBoolean("headlines_hide_sidebar", false)) { - findViewById(R.id.headlines_fragment).setVisibility(View.GONE); - } - - 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(); - hf.initialize(feedId, isCat); - - OfflineArticlePager af = new OfflineArticlePager(); - af.initialize(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 boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - overridePendingTransition(0, R.anim.right_slide_out); - return true; - default: - Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId()); - return super.onOptionsItemSelected(item); - } - } - - @Override - public void onArticleSelected(int articleId, boolean open) { - - if (!open) { - SQLiteStatement stmt = getWritableDb().compileStatement( - "UPDATE articles SET modified = 1, 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, !isPortrait() && !isSmallScreen()); - m_menu.findItem(R.id.headlines_toggle_sidebar).setVisible(!isPortrait() && !isSmallScreen()); - - 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); - } - - @Override - public void onBackPressed() { - super.onBackPressed(); - overridePendingTransition(0, R.anim.right_slide_out); - } -} diff --git a/src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java b/src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java deleted file mode 100644 index 0818a66b..00000000 --- a/src/org/fox/ttrss/offline/OfflineHeadlinesEventListener.java +++ /dev/null @@ -1,7 +0,0 @@ -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 deleted file mode 100644 index 7f9d73f7..00000000 --- a/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java +++ /dev/null @@ -1,774 +0,0 @@ -package org.fox.ttrss.offline; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; - -import org.fox.ttrss.CommonActivity; -import org.fox.ttrss.GlobalState; -import org.fox.ttrss.R; -import org.fox.ttrss.util.TypefaceCache; -import org.jsoup.Jsoup; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Resources.Theme; -import android.database.Cursor; -import android.database.sqlite.SQLiteStatement; -import android.graphics.Paint; -import android.graphics.Typeface; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.provider.BaseColumns; -import android.support.v4.app.Fragment; -import android.support.v4.widget.SimpleCursorAdapter; -import android.support.v4.widget.SwipeRefreshLayout; -import android.text.Html; -import android.text.Html.ImageGetter; -import android.util.Log; -import android.util.TypedValue; -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; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.CheckBox; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.TextView; - -public class OfflineHeadlinesFragment extends Fragment implements OnItemClickListener { - public static enum ArticlesSelection { ALL, NONE, UNREAD }; - - private final String TAG = this.getClass().getSimpleName(); - - private int m_feedId; - private boolean m_feedIsCat = false; - private int m_activeArticleId; - private String m_searchQuery = ""; - - private SharedPreferences m_prefs; - - private Cursor m_cursor; - private ArticleListAdapter m_adapter; - - private OfflineHeadlinesEventListener m_listener; - private OfflineActivity m_activity; - private SwipeRefreshLayout m_swipeLayout; - - public void initialize(int feedId, boolean isCat) { - m_feedId = feedId; - m_feedIsCat = isCat; - } - - @Override - public void onDestroy() { - super.onDestroy(); - - if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close(); - } - - public int getSelectedArticleCount() { - Cursor c = m_activity.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 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 modified = 1, 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 modified = 1, 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 modified = 1, 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 modified = 1, 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 modified = 1, 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 modified = 1, 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; - - String updatedOperator = (m_prefs.getBoolean("offline_oldest_first", false)) ? "<" : ">"; - - if (m_feedIsCat) { - stmt = m_activity.getWritableDb().compileStatement( - "UPDATE articles SET modified = 1, unread = 0 WHERE " + - "updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " + - "AND unread = 1 AND feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)"); - } else { - stmt = m_activity.getWritableDb().compileStatement( - "UPDATE articles SET modified = 1, unread = 0 WHERE " + - "updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " + - "AND unread = 1 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_context_menu, menu); - - if (getSelectedArticleCount() > 0) { - menu.setHeaderTitle(R.string.headline_context_multiple); - menu.setGroupVisible(R.id.menu_group_single_article, false); - } else { - AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; - Cursor c = getArticleAtPosition(info.position); - 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(); - - m_activity.initMenu(); - } - - public void refresh() { - try { - if (!isAdded()) return; - - m_swipeLayout.setRefreshing(true); - - if (m_cursor != null && !m_cursor.isClosed()) m_cursor.close(); - - m_cursor = createCursor(); - - if (m_cursor != null && m_adapter != null) { - m_adapter.changeCursor(m_cursor); - m_adapter.notifyDataSetChanged(); - } - - m_swipeLayout.setRefreshing(false); - - } catch (NullPointerException e) { - e.printStackTrace(); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - if (savedInstanceState != null) { - m_feedId = savedInstanceState.getInt("feedId"); - m_activeArticleId = savedInstanceState.getInt("activeArticleId"); - //m_selectedArticles = savedInstanceState.getParcelableArrayList("selectedArticles"); - 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); - - m_swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.headlines_swipe_container); - - m_swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - refresh(); - } - }); - - if (!m_activity.isCompatMode()) { - m_swipeLayout.setColorScheme(android.R.color.holo_green_dark, - android.R.color.holo_red_dark, - android.R.color.holo_blue_dark, - android.R.color.holo_orange_dark); - } - - m_cursor = createCursor(); - - ListView list = (ListView)view.findViewById(R.id.headlines); - m_adapter = new ArticleListAdapter(getActivity(), R.layout.headlines_row, m_cursor, - new String[] { "title" }, new int[] { R.id.title }, 0); - - /* if (!m_activity.isCompatMode()) { - AnimationSet set = new AnimationSet(true); - - Animation animation = new AlphaAnimation(0.0f, 1.0f); - animation.setDuration(500); - set.addAnimation(animation); - - animation = new TranslateAnimation( - Animation.RELATIVE_TO_SELF, 50.0f,Animation.RELATIVE_TO_SELF, 0.0f, - Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f - ); - animation.setDuration(1000); - set.addAnimation(animation); - - LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f); - - list.setLayoutAnimation(controller); - } */ - - list.setAdapter(m_adapter); - list.setOnItemClickListener(this); - list.setEmptyView(view.findViewById(R.id.no_headlines)); - registerForContextMenu(list); - - //if (m_activity.isSmallScreen()) - // view.findViewById(R.id.headlines_fragment).setPadding(0, 0, 0, 0); - - getActivity().setProgressBarIndeterminateVisibility(false); - - return view; - } - - public Cursor createCursor() { - String feedClause = null; - - if (m_feedIsCat) { - feedClause = "feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)"; - } else { - feedClause = "feed_id = ?"; - } - - String viewMode = m_activity.getViewMode(); - - if ("adaptive".equals(viewMode)) { - // TODO: implement adaptive - } else if ("marked".equals(viewMode)) { - feedClause += "AND (marked = 1)"; - } else if ("published".equals(viewMode)) { - feedClause += "AND (published = 1)"; - } else if ("unread".equals(viewMode)) { - feedClause += "AND (unread = 1)"; - } else { // all_articles - // - } - - String orderBy = (m_prefs.getBoolean("offline_oldest_first", false)) ? "updated" : "updated DESC"; - - 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, orderBy); - } else { - 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, orderBy); - } - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - m_listener = (OfflineHeadlinesEventListener) activity; - m_activity = (OfflineActivity) activity; - - m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - } - - @Override - public void onItemClick(AdapterView<?> av, View view, int position, long id) { - ListView list = (ListView)av; - - Log.d(TAG, "onItemClick=" + position); - - if (list != null) { - /* Cursor cursor = (Cursor)list.getItemAtPosition(position); - - int articleId = cursor.getInt(0); */ - - int articleId = getArticleIdAtPosition(position); - - if (getActivity().findViewById(R.id.article_fragment) != null) { - m_activeArticleId = articleId; - } - - m_listener.onArticleSelected(articleId); - - refresh(); - } - } - - @Override - public void onSaveInstanceState (Bundle out) { - super.onSaveInstanceState(out); - - out.putInt("feedId", m_feedId); - out.putInt("activeArticleId", m_activeArticleId); - //out.putParcelableArrayList("selectedArticles", m_selectedArticles); - out.putCharSequence("searchQuery", m_searchQuery); - out.putBoolean("feedIsCat", m_feedIsCat); - } - - /* public void setLoadingStatus(int status, boolean showProgress) { - if (getView() != null) { - TextView tv = (TextView)getView().findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(status); - } - } - - getActivity().setProgressBarIndeterminateVisibility(showProgress); - } */ - - private class ArticleListAdapter extends SimpleCursorAdapter { - public static final int VIEW_NORMAL = 0; - public static final int VIEW_UNREAD = 1; - public static final int VIEW_SELECTED = 2; - public static final int VIEW_SELECTED_UNREAD = 3; - public static final int VIEW_LOADMORE = 4; - - public static final int VIEW_COUNT = VIEW_LOADMORE+1; - - private final Integer[] origTitleColors = new Integer[VIEW_COUNT]; - private final int titleHighScoreUnreadColor; - - public ArticleListAdapter(Context context, int layout, Cursor c, - String[] from, int[] to, int flags) { - super(context, layout, c, from, to, flags); - - Theme theme = context.getTheme(); - TypedValue tv = new TypedValue(); - theme.resolveAttribute(R.attr.headlineTitleHighScoreUnreadTextColor, tv, true); - titleHighScoreUnreadColor = tv.data; - } - - public int getViewTypeCount() { - return VIEW_COUNT; - } - - @Override - public int getItemViewType(int position) { - Cursor c = (Cursor) getItem(position); - - //Log.d(TAG, "@gIVT " + position + " " + c.getInt(0) + " vs " + m_activeArticleId); - - if (c.getInt(0) == m_activeArticleId && c.getInt(c.getColumnIndex("unread")) == 1) { - return VIEW_SELECTED_UNREAD; - } else if (c.getInt(0) == m_activeArticleId) { - return VIEW_SELECTED; - } else if (c.getInt(c.getColumnIndex("unread")) == 1) { - return VIEW_UNREAD; - } else { - return VIEW_NORMAL; - } - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - - View v = convertView; - - Cursor article = (Cursor)getItem(position); - final int articleId = article.getInt(0); - - int headlineFontSize = Integer.parseInt(m_prefs.getString("headlines_font_size_sp", "13")); - int headlineSmallFontSize = Math.max(10, Math.min(18, headlineFontSize - 2)); - - if (v == null) { - int layoutId = R.layout.headlines_row; - - switch (getItemViewType(position)) { - case VIEW_LOADMORE: - layoutId = R.layout.headlines_row_loadmore; - break; - case VIEW_UNREAD: - layoutId = R.layout.headlines_row_unread; - break; - case VIEW_SELECTED_UNREAD: - layoutId = R.layout.headlines_row_selected_unread; - break; - case VIEW_SELECTED: - layoutId = R.layout.headlines_row_selected; - break; - } - - LayoutInflater vi = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(layoutId, null); - - // http://code.google.com/p/android/issues/detail?id=3414 - ((ViewGroup)v).setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); - } - - TextView tt = (TextView)v.findViewById(R.id.title); - - if (tt != null) { - - tt.setText(Html.fromHtml(article.getString(article.getColumnIndex("title")))); - - if (m_prefs.getBoolean("enable_condensed_fonts", false)) { - Typeface tf = TypefaceCache.get(m_activity, "sans-serif-condensed", article.getInt(article.getColumnIndex("unread")) == 1 ? Typeface.BOLD : Typeface.NORMAL); - - if (tf != null && !tf.equals(tt.getTypeface())) { - tt.setTypeface(tf); - } - - tt.setTextSize(TypedValue.COMPLEX_UNIT_SP, Math.min(21, headlineFontSize + 5)); - } else { - tt.setTextSize(TypedValue.COMPLEX_UNIT_SP, Math.min(21, headlineFontSize + 3)); - } - - int scoreIndex = article.getColumnIndex("score"); - if (scoreIndex >= 0) - adjustTitleTextView(article.getInt(scoreIndex), tt, position); - } - - TextView ft = (TextView)v.findViewById(R.id.feed_title); - - int feedTitleIndex = article.getColumnIndex("feed_title"); - - if (ft != null && feedTitleIndex != -1 && m_feedIsCat) { - String feedTitle = article.getString(feedTitleIndex); - - if (feedTitle.length() > 20) - feedTitle = feedTitle.substring(0, 20) + "..."; - - if (feedTitle.length() > 0) { - ft.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineSmallFontSize); - ft.setText(feedTitle); - } else { - ft.setVisibility(View.GONE); - } - } else if (ft != null) { - ft.setVisibility(View.GONE); - } - - ImageView marked = (ImageView)v.findViewById(R.id.marked); - - if (marked != null) { - marked.setImageResource(article.getInt(article.getColumnIndex("marked")) == 1 ? R.drawable.ic_star_full : R.drawable.ic_star_empty); - - marked.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - SQLiteStatement stmtUpdate = m_activity.getWritableDb().compileStatement("UPDATE articles SET modified = 1, marked = NOT marked " + - "WHERE " + BaseColumns._ID + " = ?"); - - stmtUpdate.bindLong(1, articleId); - stmtUpdate.execute(); - stmtUpdate.close(); - - refresh(); - } - }); - } - - ImageView published = (ImageView)v.findViewById(R.id.published); - - if (published != null) { - published.setImageResource(article.getInt(article.getColumnIndex("published")) == 1 ? R.drawable.ic_published : R.drawable.ic_unpublished); - - published.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - SQLiteStatement stmtUpdate = m_activity.getWritableDb().compileStatement("UPDATE articles SET modified = 1, published = NOT published " + - "WHERE " + BaseColumns._ID + " = ?"); - - stmtUpdate.bindLong(1, articleId); - stmtUpdate.execute(); - stmtUpdate.close(); - - refresh(); - } - }); - } - - TextView te = (TextView)v.findViewById(R.id.excerpt); - - if (te != null) { - if (!m_prefs.getBoolean("headlines_show_content", true)) { - te.setVisibility(View.GONE); - } else { - String excerpt = Jsoup.parse(article.getString(article.getColumnIndex("content"))).text(); - - if (excerpt.length() > CommonActivity.EXCERPT_MAX_SIZE) - excerpt = excerpt.substring(0, CommonActivity.EXCERPT_MAX_SIZE) + "..."; - - te.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineFontSize); - te.setText(excerpt); - } - } - - TextView ta = (TextView)v.findViewById(R.id.author); - - if (ta != null) { - int authorIndex = article.getColumnIndex("author"); - if (authorIndex >= 0) { - String author = article.getString(authorIndex); - - ta.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineSmallFontSize); - - if (author != null && author.length() > 0) - ta.setText(getString(R.string.author_formatted, author)); - else - ta.setText(""); - } - } - - /* ImageView separator = (ImageView)v.findViewById(R.id.headlines_separator); - - if (separator != null && m_offlineServices.isSmallScreen()) { - separator.setVisibility(View.GONE); - } */ - - TextView dv = (TextView) v.findViewById(R.id.date); - - if (dv != null) { - dv.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineSmallFontSize); - - Date d = new Date((long)article.getInt(article.getColumnIndex("updated")) * 1000); - DateFormat df = new SimpleDateFormat("MMM dd, HH:mm"); - df.setTimeZone(TimeZone.getDefault()); - dv.setText(df.format(d)); - } - - CheckBox cb = (CheckBox) v.findViewById(R.id.selected); - - if (cb != null) { - cb.setChecked(article.getInt(article.getColumnIndex("selected")) == 1); - cb.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View view) { - CheckBox cb = (CheckBox)view; - - SQLiteStatement stmtUpdate = m_activity.getWritableDb().compileStatement("UPDATE articles SET selected = ? " + - "WHERE " + BaseColumns._ID + " = ?"); - - stmtUpdate.bindLong(1, cb.isChecked() ? 1 : 0); - stmtUpdate.bindLong(2, articleId); - stmtUpdate.execute(); - stmtUpdate.close(); - - refresh(); - - m_activity.initMenu(); - - } - }); - } - - ImageView ib = (ImageView) v.findViewById(R.id.article_menu_button); - - if (ib != null) { - //if (m_activity.isDarkTheme()) - // ib.setImageResource(R.drawable.ic_mailbox_collapsed_holo_dark); - - ib.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - getActivity().openContextMenu(v); - } - }); - } - - return v; - } - - private void adjustTitleTextView(int score, TextView tv, int position) { - int viewType = getItemViewType(position); - if (origTitleColors[viewType] == null) - // store original color - origTitleColors[viewType] = Integer.valueOf(tv.getCurrentTextColor()); - - if (score < -500) { - tv.setPaintFlags(tv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); - } else if (score > 500) { - tv.setTextColor(titleHighScoreUnreadColor); - tv.setPaintFlags(tv.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); - } else { - tv.setTextColor(origTitleColors[viewType].intValue()); - tv.setPaintFlags(tv.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); - } - } - } - - public void notifyUpdated() { - m_adapter.notifyDataSetChanged(); - } - - public void setActiveArticleId(int articleId) { - m_activeArticleId = articleId; - try { - m_adapter.notifyDataSetChanged(); - - ListView list = (ListView)getView().findViewById(R.id.headlines); - - 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) { - return (Cursor) m_adapter.getItem(position); - } - - public int getArticleIdAtPosition(int position) { - /*Cursor c = getArticleAtPosition(position); - - if (c != null) { - int id = c.getInt(0); - return id; - } */ - - return (int) m_adapter.getItemId(position); - } - - public int getActiveArticleId() { - return m_activeArticleId; - } - - public int getArticleIdPosition(int articleId) { - for (int i = 0; i < m_adapter.getCount(); i++) { - if (articleId == m_adapter.getItemId(i)) - return i; - } - - return -1; - } - - public int getArticleCount() { - return m_adapter.getCount(); - } - - public void setSearchQuery(String query) { - if (!m_searchQuery.equals(query)) { - m_searchQuery = query; - } - } - - 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/OfflineUploadService.java b/src/org/fox/ttrss/offline/OfflineUploadService.java deleted file mode 100644 index 4c3349d4..00000000 --- a/src/org/fox/ttrss/offline/OfflineUploadService.java +++ /dev/null @@ -1,286 +0,0 @@ -package org.fox.ttrss.offline; - -import java.util.HashMap; - -import org.fox.ttrss.ApiRequest; -import org.fox.ttrss.OnlineActivity; -import org.fox.ttrss.R; -import org.fox.ttrss.util.DatabaseHelper; - -import android.app.IntentService; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.util.Log; - -import com.google.gson.JsonElement; - -public class OfflineUploadService extends IntentService { - private final String TAG = this.getClass().getSimpleName(); - - public static final int NOTIFY_UPLOADING = 2; - public static final String INTENT_ACTION_SUCCESS = "org.fox.ttrss.intent.action.UploadComplete"; - - private SQLiteDatabase m_writableDb; - private SQLiteDatabase m_readableDb; - private String m_sessionId; - private NotificationManager m_nmgr; - private boolean m_uploadInProgress = false; - private boolean m_batchMode = false; - - public OfflineUploadService() { - super("OfflineUploadService"); - } - - @Override - public void onCreate() { - super.onCreate(); - m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - initDatabase(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - - 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, OnlineActivity.class), 0); - - notification.flags |= Notification.FLAG_ONGOING_EVENT; - notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE; - - notification.setLatestEventInfo(this, getString(R.string.notify_uploading_title), msg, contentIntent); - - m_nmgr.notify(NOTIFY_UPLOADING, notification); - } - - private void updateNotification(int msgResId) { - updateNotification(getString(msgResId)); - } - - private void initDatabase() { - DatabaseHelper dh = new DatabaseHelper(getApplicationContext()); - m_writableDb = dh.getWritableDatabase(); - m_readableDb = dh.getReadableDatabase(); - } - - private synchronized SQLiteDatabase getReadableDb() { - return m_readableDb; - } - - private synchronized SQLiteDatabase getWritableDb() { - return m_writableDb; - } - - private void uploadRead() { - Log.d(TAG, "syncing modified offline data... (read)"); - - final String ids = getModifiedIds(ModifiedCriteria.READ); - - if (ids.length() > 0) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - protected void onPostExecute(JsonElement result) { - if (result != null) { - uploadMarked(); - } else { - updateNotification(getErrorMessage()); - uploadFailed(); - } - } - }; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", ids); - put("mode", "0"); - put("field", "2"); - } - }; - - req.execute(map); - } else { - uploadMarked(); - } - } - - private enum ModifiedCriteria { - READ, MARKED, PUBLISHED - }; - - private String getModifiedIds(ModifiedCriteria criteria) { - - String criteriaStr = ""; - - switch (criteria) { - case READ: - criteriaStr = "unread = 0"; - break; - case MARKED: - criteriaStr = "marked = 1"; - break; - case PUBLISHED: - criteriaStr = "published = 1"; - break; - } - - Cursor c = getReadableDb().query("articles", null, - "modified = 1 AND " + criteriaStr, null, null, null, null); - - String tmp = ""; - - while (c.moveToNext()) { - tmp += c.getInt(0) + ","; - } - - tmp = tmp.replaceAll(",$", ""); - - c.close(); - - return tmp; - } - - private void uploadMarked() { - Log.d(TAG, "syncing modified offline data... (marked)"); - - final String ids = getModifiedIds(ModifiedCriteria.MARKED); - - if (ids.length() > 0) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - protected void onPostExecute(JsonElement result) { - if (result != null) { - uploadPublished(); - } else { - updateNotification(getErrorMessage()); - uploadFailed(); - } - } - }; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", ids); - put("mode", "1"); - put("field", "0"); - } - }; - - req.execute(map); - } else { - uploadPublished(); - } - } - - private void uploadFailed() { - m_readableDb.close(); - m_writableDb.close(); - - // TODO send notification to activity? - - m_uploadInProgress = false; - } - - private void uploadSuccess() { - getWritableDb().execSQL("UPDATE articles SET modified = 0"); - - if (m_batchMode) { - - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = localPrefs.edit(); - editor.putBoolean("offline_mode_active", false); - editor.commit(); - - } else { - Intent intent = new Intent(); - intent.setAction(INTENT_ACTION_SUCCESS); - intent.addCategory(Intent.CATEGORY_DEFAULT); - sendBroadcast(intent); - } - - m_readableDb.close(); - m_writableDb.close(); - - m_uploadInProgress = false; - - m_nmgr.cancel(NOTIFY_UPLOADING); - } - - private void uploadPublished() { - Log.d(TAG, "syncing modified offline data... (published)"); - - final String ids = getModifiedIds(ModifiedCriteria.MARKED); - - if (ids.length() > 0) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - protected void onPostExecute(JsonElement result) { - if (result != null) { - uploadSuccess(); - } else { - updateNotification(getErrorMessage()); - uploadFailed(); - } - } - }; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", ids); - put("mode", "1"); - put("field", "1"); - } - }; - - req.execute(map); - } else { - uploadSuccess(); - } - } - - - @Override - protected void onHandleIntent(Intent intent) { - try { - if (getWritableDb().isDbLockedByCurrentThread() || getWritableDb().isDbLockedByOtherThreads()) { - return; - } - - m_sessionId = intent.getStringExtra("sessionId"); - m_batchMode = intent.getBooleanExtra("batchMode", false); - - if (!m_uploadInProgress) { - m_uploadInProgress = true; - - updateNotification(R.string.notify_uploading_sending_data); - - uploadRead(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - -} |