rework headlines context menu to use popupmenu instead

This commit is contained in:
Andrew Dolgov 2015-12-01 14:33:31 +03:00
parent 36561a436e
commit 69e6844711
6 changed files with 232 additions and 243 deletions

View File

@ -413,39 +413,7 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
// TODO: this needs access to article text, I'm afraid
case R.id.article_img_view_caption:
if (url != null) {
// 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(m_content);
Elements es = doc.getElementsByAttributeValue("src", url);
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);
}
displayImageCaption(url, m_content);
}
return true;
default:
@ -453,4 +421,5 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur
return super.onContextItemSelected(item);
}
}
}

View File

@ -28,9 +28,13 @@ import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import org.fox.ttrss.util.DatabaseHelper;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.util.Arrays;
@ -342,5 +346,40 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc
}
}
public void displayImageCaption(String url, String htmlContent) {
// 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(htmlContent);
Elements es = doc.getElementsByAttributeValue("src", url);
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);
}
}
}

View File

@ -29,6 +29,7 @@ import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
@ -43,6 +44,7 @@ import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
@ -142,7 +144,60 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
}
}
@Override
public boolean onArticleMenuItemSelected(MenuItem item, Article article) {
if (article == null) return false;
switch (item.getItemId()) {
case R.id.set_labels:
m_activity.editArticleLabels(article);
return true;
case R.id.article_set_note:
m_activity.editArticleNote(article);
return true;
case R.id.headlines_article_link_copy:
m_activity.copyToClipboard(article.link);
return true;
case R.id.headlines_article_link_open:
m_activity.openUri(Uri.parse(article.link));
if (article.unread) {
article.unread = false;
m_activity.saveArticleUnread(article);
m_adapter.notifyDataSetChanged();
}
return true;
case R.id.headlines_share_article:
m_activity.shareArticle(article);
return true;
case R.id.catchup_above:
if (true) {
ArticleList articles = getAllArticles();
ArticleList tmp = new ArticleList();
for (Article a : articles) {
if (article.id == a.id)
break;
if (a.unread) {
a.unread = false;
tmp.add(a);
}
}
if (tmp.size() > 0) {
m_activity.toggleArticlesUnread(tmp);
//updateHeadlines();
}
m_adapter.notifyDataSetChanged();
}
return true;
default:
Log.d(TAG, "onArticleMenuItemSelected, unhandled id=" + item.getItemId());
return false;
}
}
/*@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
@ -291,7 +346,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
return super.onContextItemSelected(item);
}
}
} */
public HeadlinesFragment() {
super();
@ -304,7 +359,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
}
}
@Override
/*@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
@ -326,7 +381,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
super.onCreateContextMenu(menu, v, menuInfo);
}
}*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -409,7 +464,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
m_list.setOnItemClickListener(this);
m_list.setOnScrollListener(this);
registerForContextMenu(m_list);
//registerForContextMenu(m_list);
if (m_activity.isSmallScreen()) {
m_activity.setTitle(m_feed.title);
@ -1070,14 +1125,6 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
holder.flavorVideoKindView.setVisibility(View.GONE);
holder.headlineHeader.setBackgroundDrawable(null);
holder.headlineHeader.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
m_activity.openContextMenu(v);
return true;
}
});
holder.headlineHeader.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@ -1085,15 +1132,42 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
}
});
holder.flavorImageView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
m_activity.openContextMenu(v);
return true;
}
});
if (showFlavorImage && article.flavorImageUri != null && holder.flavorImageView != null) {
holder.flavorImageView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
PopupMenu popup = new PopupMenu(getActivity(), holder.titleView);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.context_article_content_img, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.article_img_open:
m_activity.openUri(Uri.parse(article.flavorImageUri));
return true;
case R.id.article_img_copy:
m_activity.copyToClipboard(article.flavorImageUri);
return true;
case R.id.article_img_share:
m_activity.shareText(article.flavorImageUri);
return true;
case R.id.article_img_view_caption:
m_activity.displayImageCaption(article.flavorImageUri, article.content);
return true;
default:
return false;
}
}
});
popup.show();
return true;
}
});
if (!article.flavorImageUri.equals(holder.flavorImageView.getTag())) {
@ -1142,7 +1216,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
@Override
public void onProgressUpdate(String s, View view, int current, int total) {
if (total != 0) {
int p = (int)((float)current/total*100);
int p = (int) ((float) current / total * 100);
holder.flavorImageLoadingBar.setIndeterminate(false);
holder.flavorImageLoadingBar.setProgress(p);
@ -1235,7 +1309,22 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
holder.menuButtonView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
getActivity().openContextMenu(v);
PopupMenu popup = new PopupMenu(getActivity(), v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.context_headlines, popup.getMenu());
popup.getMenu().findItem(R.id.set_labels).setEnabled(m_activity.getApiLevel() >= 1);
popup.getMenu().findItem(R.id.article_set_note).setEnabled(m_activity.getApiLevel() >= 1);
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return onArticleMenuItemSelected(item, article);
}
});
popup.show();
}
});
}

View File

@ -557,39 +557,7 @@ public class OnlineActivity extends CommonActivity {
return true;
case R.id.article_img_view_caption:
if (getLastContentImageHitTestUrl() != null) {
// 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(ap.getSelectedArticle().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);
}
displayImageCaption(getLastContentImageHitTestUrl(), ap.getSelectedArticle().content);
}
return true;
case R.id.article_link_share:
@ -598,7 +566,6 @@ public class OnlineActivity extends CommonActivity {
}
return true;
case R.id.article_link_copy:
Log.d(TAG, "article_link_copy");
if (ap != null && ap.getSelectedArticle() != null) {
copyToClipboard(ap.getSelectedArticle().link);
}

View File

@ -7,6 +7,7 @@ import android.content.res.Resources.Theme;
import android.database.Cursor;
import android.database.sqlite.SQLiteStatement;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
@ -20,6 +21,7 @@ import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
@ -32,6 +34,7 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.ProgressBar;
import android.widget.TextView;
@ -100,144 +103,66 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
return selected;
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
private boolean onArticleMenuItemSelected(MenuItem item, int articleId) {
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();
case R.id.headlines_article_link_copy:
if (true) {
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.getDatabase()
.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.getDatabase().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.getDatabase()
.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.getDatabase().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.getDatabase()
.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.getDatabase().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.headlines_share_article:
if (true) {
int articleId = getArticleIdAtPosition(info.position);
return true;
case R.id.headlines_article_link_open:
if (true) {
Cursor article = m_activity.getArticleById(articleId);
if (article != null) {
m_activity.openUri(Uri.parse(article.getString(article.getColumnIndex("link"))));
// TODO: mark article as read, set modified = 1, refresh
article.close();
}
}
return true;
case R.id.headlines_share_article:
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.getDatabase().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.getDatabase().compileStatement(
"UPDATE articles SET modified = 1, unread = 0 WHERE " +
"updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " +
"AND unread = 1 AND feed_id = ?");
return true;
case R.id.catchup_above:
if (true) {
SQLiteStatement stmt = null;
String updatedOperator = (m_prefs.getBoolean("offline_oldest_first", false)) ? "<" : ">";
if (m_feedIsCat) {
stmt = m_activity.getDatabase().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.getDatabase().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();
}
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);
refresh();
return true;
default:
Log.d(TAG, "onArticleMenuItemSelected, unhandled id=" + item.getItemId());
return super.onContextItemSelected(item);
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
getActivity().getMenuInflater().inflate(R.menu.context_headlines, 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();
@ -346,7 +271,6 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
m_list.setOnItemClickListener(this);
m_list.setOnScrollListener(this);
registerForContextMenu(m_list);
return view;
}
@ -781,7 +705,22 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
holder.menuButtonView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
getActivity().openContextMenu(v);
PopupMenu popup = new PopupMenu(getActivity(), v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.context_headlines, popup.getMenu());
popup.getMenu().findItem(R.id.set_labels).setVisible(false);
popup.getMenu().findItem(R.id.article_set_note).setVisible(false);
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return onArticleMenuItemSelected(item, articleId);
}
});
popup.show();
}
});
}

View File

@ -1,27 +1,14 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/selection_toggle_unread"
app:showAsAction=""
android:title="@string/context_selection_toggle_unread"/>
<item
android:id="@+id/selection_toggle_marked"
app:showAsAction=""
android:title="@string/context_selection_toggle_marked"/>
<item
android:id="@+id/selection_toggle_published"
app:showAsAction=""
android:title="@string/context_selection_toggle_published"/>
<group android:id="@+id/menu_group_single_article" >
<item
android:id="@+id/headlines_article_link_open"
app:showAsAction=""
android:title="@string/open_with"/>
<item
android:id="@+id/headlines_share_article"
app:showAsAction=""
android:title="@string/share_article"/>
<item
android:id="@+id/headlines_article_link_open"
app:showAsAction=""
android:title="@string/open_article_in_web_browser"/>
<item
android:id="@+id/headlines_article_link_copy"
app:showAsAction=""
@ -37,6 +24,5 @@
android:id="@+id/article_set_note"
app:showAsAction=""
android:title="@string/article_set_note"/>
</group>
</menu>