summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2011-11-29 14:09:27 +0300
committerAndrew Dolgov <[email protected]>2011-11-29 14:09:27 +0300
commitc8f79f546557bb624740c59ac44b8ed814c944db (patch)
tree29900f624e89b27c0773fda0fc8033a6d96d2474
parent980b5696e34b7025cd62d829fa9032bc864c2ab6 (diff)
implement batch actions on selected articles
-rw-r--r--res/menu/category_menu.xml4
-rw-r--r--res/menu/main_menu.xml32
-rw-r--r--res/values/strings.xml8
-rw-r--r--src/org/fox/ttrss/FeedCategoriesFragment.java1
-rw-r--r--src/org/fox/ttrss/FeedsFragment.java1
-rw-r--r--src/org/fox/ttrss/HeadlinesFragment.java34
-rw-r--r--src/org/fox/ttrss/MainActivity.java115
7 files changed, 181 insertions, 14 deletions
diff --git a/res/menu/category_menu.xml b/res/menu/category_menu.xml
index d437a0ca..59ff8f8c 100644
--- a/res/menu/category_menu.xml
+++ b/res/menu/category_menu.xml
@@ -2,10 +2,10 @@
<item
android:id="@+id/browse_articles"
- android:title="Browse articles"/>
+ android:title="@string/category_browse_articles"/>
<item
android:id="@+id/browse_feeds"
- android:title="Browse feeds"/>
+ android:title="@string/category_browse_feeds"/>
</menu> \ No newline at end of file
diff --git a/res/menu/main_menu.xml b/res/menu/main_menu.xml
index 76471811..a23bcb61 100644
--- a/res/menu/main_menu.xml
+++ b/res/menu/main_menu.xml
@@ -42,6 +42,38 @@
android:icon="@android:drawable/ic_menu_agenda"
android:showAsAction=""
android:title="@string/show_all_articles"/>
+
+ <item
+ android:id="@+id/headlines_select_all"
+ android:title="@string/headlines_select_all"/>
+
+ <item
+ android:id="@+id/headlines_select_unread"
+ android:title="@string/headlines_select_unread"/>
+
+ <item
+ android:id="@+id/headlines_select_none"
+ android:title="@string/headlines_select_none"/>
+
+ <item
+ android:id="@+id/selection_toggle_unread"
+ android:icon="@android:drawable/ic_menu_recent_history"
+ android:showAsAction=""
+ android:title="@string/selection_toggle_unread"/>
+
+ <item
+ android:id="@+id/selection_toggle_marked"
+ android:icon="@android:drawable/star_off"
+ android:showAsAction=""
+ android:title="@string/selection_toggle_marked"/>
+
+ <item
+ android:id="@+id/selection_toggle_published"
+ android:icon="@drawable/ic_menu_rss"
+ android:showAsAction=""
+ android:title="@string/selection_toggle_published"/>
+
+
</group>
<group android:id="@+id/menu_group_article" >
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6f2f0a8c..c73be87f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -37,10 +37,18 @@
<string name="show_all_articles">Show all articles</string>
<string name="show_unread_articles">Show unread articles</string>
<string name="ssl_trust_any">Accept any SSL certificate</string>
+ <string name="category_browse_feeds">Browse feeds</string>
+ <string name="category_browse_articles">Browse articles</string>
<string name="blank"></string>
<string name="transport_debugging">Log sent and received data</string>
<string name="toggle_marked">Toggle starred</string>
<string name="toggle_published">Toggle published</string>
+ <string name="headlines_select_all">Select all</string>
+ <string name="headlines_select_none">Select none</string>
+ <string name="headlines_select_unread">Select unread</string>
+ <string name="selection_toggle_marked">Toggle starred</string>
+ <string name="selection_toggle_published">Toggle published</string>
+ <string name="selection_toggle_unread">Toggle unread</string>
<string name="set_unread">Mark unread</string>
<string name="http_login_summary">Optional. Fill this if your tt-rss installation is protected by HTTP Basic authentication</string>
<string name="login_summary">Your tt-rss login. Not needed for single user mode</string>
diff --git a/src/org/fox/ttrss/FeedCategoriesFragment.java b/src/org/fox/ttrss/FeedCategoriesFragment.java
index ea9c433a..c2f4f298 100644
--- a/src/org/fox/ttrss/FeedCategoriesFragment.java
+++ b/src/org/fox/ttrss/FeedCategoriesFragment.java
@@ -14,7 +14,6 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
diff --git a/src/org/fox/ttrss/FeedsFragment.java b/src/org/fox/ttrss/FeedsFragment.java
index 4fb7c404..de30ed6e 100644
--- a/src/org/fox/ttrss/FeedsFragment.java
+++ b/src/org/fox/ttrss/FeedsFragment.java
@@ -45,7 +45,6 @@ import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
import android.widget.ListView;
import android.widget.TextView;
diff --git a/src/org/fox/ttrss/HeadlinesFragment.java b/src/org/fox/ttrss/HeadlinesFragment.java
index 63fa52f9..3e183c95 100644
--- a/src/org/fox/ttrss/HeadlinesFragment.java
+++ b/src/org/fox/ttrss/HeadlinesFragment.java
@@ -25,8 +25,6 @@ import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
@@ -37,6 +35,8 @@ import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
public class HeadlinesFragment extends Fragment implements OnItemClickListener {
+ public static enum ArticlesSelection { ALL, NONE, UNREAD };
+
private final String TAG = this.getClass().getSimpleName();
private Feed m_feed;
@@ -345,20 +345,20 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener {
if (cb != null) {
cb.setChecked(m_selectedArticles.contains(article));
-
- cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+ cb.setOnClickListener(new OnClickListener() {
+
@Override
- public void onCheckedChanged(CompoundButton buttonView,
- boolean isChecked) {
-
- if (isChecked) {
- m_selectedArticles.add(article);
+ public void onClick(View view) {
+ CheckBox cb = (CheckBox)view;
+
+ if (cb.isChecked()) {
+ if (!m_selectedArticles.contains(article))
+ m_selectedArticles.add(article);
} else {
m_selectedArticles.remove(article);
}
Log.d(TAG, "num selected: " + m_selectedArticles.size());
-
}
});
}
@@ -389,4 +389,18 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener {
}
}
+ public void setSelection(ArticlesSelection select) {
+ m_selectedArticles.clear();
+
+ if (select != ArticlesSelection.NONE) {
+ for (Article a : m_articles) {
+ if (select == ArticlesSelection.ALL || select == ArticlesSelection.UNREAD && a.unread) {
+ m_selectedArticles.add(a);
+ }
+ }
+ }
+
+ m_adapter.notifyDataSetChanged();
+ }
+
}
diff --git a/src/org/fox/ttrss/MainActivity.java b/src/org/fox/ttrss/MainActivity.java
index 66066465..50e4805e 100644
--- a/src/org/fox/ttrss/MainActivity.java
+++ b/src/org/fox/ttrss/MainActivity.java
@@ -110,6 +110,69 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe
req.execute(map);
}
+ public static String articlesToIdString(ArticleList articles) {
+ String tmp = "";
+
+ for (Article a : articles)
+ tmp += String.valueOf(a.id) + ",";
+
+ return tmp.replaceAll(",$", "");
+ }
+
+ @SuppressWarnings("unchecked")
+ public void toggleArticlesMarked(final ArticleList articles) {
+ ApiRequest req = new ApiRequest(getApplicationContext());
+
+ @SuppressWarnings("serial")
+ HashMap<String,String> map = new HashMap<String,String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "updateArticle");
+ put("article_ids", articlesToIdString(articles));
+ put("mode", "2");
+ put("field", "0");
+ }
+ };
+
+ req.execute(map);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void toggleArticlesUnread(final ArticleList articles) {
+ ApiRequest req = new ApiRequest(getApplicationContext());
+
+ @SuppressWarnings("serial")
+ HashMap<String,String> map = new HashMap<String,String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "updateArticle");
+ put("article_ids", articlesToIdString(articles));
+ put("mode", "2");
+ put("field", "2");
+ }
+ };
+
+ req.execute(map);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void toggleArticlesPublished(final ArticleList articles) {
+ ApiRequest req = new ApiRequest(getApplicationContext());
+
+ @SuppressWarnings("serial")
+ HashMap<String,String> map = new HashMap<String,String>() {
+ {
+ put("sid", m_sessionId);
+ put("op", "updateArticle");
+ put("article_ids", articlesToIdString(articles));
+ put("mode", "2");
+ put("field", "1");
+ }
+ };
+
+ req.execute(map);
+ }
+
private class RefreshTask extends TimerTask {
@Override
@@ -436,6 +499,8 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe
@Override
public boolean onOptionsItemSelected(MenuItem item) {
+ HeadlinesFragment hf = (HeadlinesFragment)getSupportFragmentManager().findFragmentById(R.id.headlines_fragment);
+
switch (item.getItemId()) {
case R.id.preferences:
Intent intent = new Intent(this, PreferencesActivity.class);
@@ -459,6 +524,54 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe
case R.id.back_to_categories:
closeCategory();
return true;
+ case R.id.headlines_select_all:
+ if (hf != null) hf.setSelection(HeadlinesFragment.ArticlesSelection.ALL);
+ return true;
+ case R.id.headlines_select_none:
+ if (hf != null) hf.setSelection(HeadlinesFragment.ArticlesSelection.NONE);
+ return true;
+ case R.id.headlines_select_unread:
+ if (hf != null) hf.setSelection(HeadlinesFragment.ArticlesSelection.UNREAD);
+ return true;
+ case R.id.selection_toggle_marked:
+ if (hf != null) {
+ ArticleList selected = hf.getSelectedArticles();
+
+ if (selected.size() > 0) {
+ for (Article a : selected)
+ a.marked = !a.marked;
+
+ toggleArticlesMarked(selected);
+ hf.notifyUpdated();
+ }
+ }
+ return true;
+ case R.id.selection_toggle_published:
+ if (hf != null) {
+ ArticleList selected = hf.getSelectedArticles();
+
+ if (selected.size() > 0) {
+ for (Article a : selected)
+ a.published = !a.published;
+
+ toggleArticlesPublished(selected);
+ hf.notifyUpdated();
+ }
+ }
+ return true;
+ case R.id.selection_toggle_unread:
+ if (hf != null) {
+ ArticleList selected = hf.getSelectedArticles();
+
+ if (selected.size() > 0) {
+ for (Article a : selected)
+ a.unread = !a.unread;
+
+ toggleArticlesUnread(selected);
+ hf.notifyUpdated();
+ }
+ }
+ return true;
case R.id.load_more_articles:
viewFeed(m_activeFeed, true);
return true;
@@ -698,6 +811,7 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe
super(context);
}
+ @SuppressWarnings("unchecked")
protected void onPostExecute(JsonElement result) {
if (result != null) {
try {
@@ -732,6 +846,7 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe
}
};
+ @SuppressWarnings("serial")
HashMap<String,String> map = new HashMap<String,String>() {
{
put("sid", m_sessionId);