diff --git a/res/layout/headlines_fragment.xml b/res/layout/headlines_fragment.xml index 83174697..2fb8ffde 100644 --- a/res/layout/headlines_fragment.xml +++ b/res/layout/headlines_fragment.xml @@ -8,4 +8,9 @@ + + diff --git a/src/org/fox/ttrss/MainActivity.java b/src/org/fox/ttrss/MainActivity.java index 32040b69..253229af 100644 --- a/src/org/fox/ttrss/MainActivity.java +++ b/src/org/fox/ttrss/MainActivity.java @@ -62,6 +62,7 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe private boolean m_isOffline = false; private int m_activeOfflineFeedId = 0; + private int m_selectedOfflineArticleId = 0; private SQLiteDatabase m_readableDb; private SQLiteDatabase m_writableDb; @@ -242,12 +243,14 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe } public synchronized void refreshFeeds() { - FeedsFragment frag = (FeedsFragment) getSupportFragmentManager().findFragmentById(R.id.feeds_fragment); - - Log.d(TAG, "Refreshing feeds..."); - - if (frag != null) { - frag.refresh(true); + if (m_sessionId != null) { + FeedsFragment frag = (FeedsFragment) getSupportFragmentManager().findFragmentById(R.id.feeds_fragment); + + Log.d(TAG, "Refreshing feeds..."); + + if (frag != null) { + frag.refresh(true); + } } } @@ -323,6 +326,7 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe m_isLicensed = savedInstanceState.getInt("isLicensed"); m_isOffline = savedInstanceState.getBoolean("isOffline"); m_activeOfflineFeedId = savedInstanceState.getInt("offlineActiveFeedId"); + m_selectedOfflineArticleId = savedInstanceState.getInt("offlineArticleId"); } m_enableCats = m_prefs.getBoolean("enable_cats", false); @@ -544,6 +548,10 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe } + public int getActiveOfflineFeedId() { + return m_activeOfflineFeedId; + } + public void setLoadingStatus(int status, boolean showProgress) { TextView tv = (TextView)findViewById(R.id.loading_message); @@ -572,6 +580,7 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe out.putInt("isLicensed", m_isLicensed); out.putBoolean("isOffline", m_isOffline); out.putInt("offlineActiveFeedId", m_activeOfflineFeedId); + out.putInt("offlineArticleId", m_selectedOfflineArticleId); } @Override @@ -636,12 +645,12 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe if (m_smallScreenMode) { if (m_selectedArticle != null) { closeArticle(); - } else if (m_activeFeed != null) { + } else if (m_activeFeed != null || m_activeOfflineFeedId != 0) { if (m_compatMode) { findViewById(R.id.main).setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_right)); } - if (m_activeFeed.is_cat) { + if (m_activeFeed != null && m_activeFeed.is_cat) { findViewById(R.id.headlines_fragment).setVisibility(View.GONE); findViewById(R.id.cats_fragment).setVisibility(View.VISIBLE); @@ -653,6 +662,7 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe refreshFeeds(); } m_activeFeed = null; + m_activeOfflineFeedId = 0; initMainMenu(); } else if (m_activeCategory != null) { @@ -1622,5 +1632,58 @@ public class MainActivity extends FragmentActivity implements FeedsFragment.OnFe public void offlineViewFeed(int feedId) { m_activeOfflineFeedId = feedId; + + initMainMenu(); + + if (m_smallScreenMode) { + findViewById(R.id.feeds_fragment).setVisibility(View.GONE); + findViewById(R.id.headlines_fragment).setVisibility(View.VISIBLE); + } + + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + OfflineHeadlinesFragment frag = new OfflineHeadlinesFragment(); + ft.replace(R.id.headlines_fragment, frag); + ft.commit(); + + } + + public void openOfflineArticle(int articleId, int compatAnimation) { + m_selectedOfflineArticleId = articleId; + + initMainMenu(); + + OfflineHeadlinesFragment hf = (OfflineHeadlinesFragment)getSupportFragmentManager().findFragmentById(R.id.headlines_fragment); + + if (hf != null) { + hf.setActiveArticleId(articleId); + } + + OfflineArticleFragment frag = new OfflineArticleFragment(); + + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + ft.replace(R.id.article_fragment, frag); + ft.commit(); + + if (m_compatMode) { + if (compatAnimation == 0) + findViewById(R.id.main).setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_left)); + else + findViewById(R.id.main).setAnimation(AnimationUtils.loadAnimation(this, compatAnimation)); + } + + if (m_smallScreenMode) { + findViewById(R.id.headlines_fragment).setVisibility(View.GONE); + findViewById(R.id.article_fragment).setVisibility(View.VISIBLE); + } else { + findViewById(R.id.feeds_fragment).setVisibility(View.GONE); + findViewById(R.id.cats_fragment).setVisibility(View.GONE); + findViewById(R.id.article_fragment).setVisibility(View.VISIBLE); + } + + + } + + public int getSelectedOfflineArticleId() { + return m_selectedOfflineArticleId; } } \ No newline at end of file diff --git a/src/org/fox/ttrss/OfflineArticleFragment.java b/src/org/fox/ttrss/OfflineArticleFragment.java new file mode 100644 index 00000000..61a2b498 --- /dev/null +++ b/src/org/fox/ttrss/OfflineArticleFragment.java @@ -0,0 +1,265 @@ +package org.fox.ttrss; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.fox.ttrss.ArticleOps.RelativeArticle; + +import android.app.Activity; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.provider.BaseColumns; +import android.support.v4.app.Fragment; +import android.text.Html; +import android.text.method.LinkMovementMethod; +import android.view.GestureDetector; +import android.view.GestureDetector.SimpleOnGestureListener; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.webkit.WebView; +import android.widget.ImageView; +import android.widget.TextView; + +import com.google.ads.AdRequest; +import com.google.ads.AdView; + +public class OfflineArticleFragment extends Fragment implements OnClickListener { + @SuppressWarnings("unused") + private final String TAG = this.getClass().getSimpleName(); + + private SharedPreferences m_prefs; + private int m_articleId; + private GestureDetector m_gestureDetector; + private View.OnTouchListener m_gestureListener; + private Cursor m_cursor; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + if (savedInstanceState != null) { + m_articleId = savedInstanceState.getInt("articleId"); + } + + View view = inflater.inflate(R.layout.article_fragment, container, false); + + m_gestureDetector = new GestureDetector(new MyGestureDetector()); + m_gestureListener = new View.OnTouchListener() { + public boolean onTouch(View v, MotionEvent aEvent) { + if (m_gestureDetector.onTouchEvent(aEvent)) + return true; + else + return false; + } + }; + + + // TODO change to interface? + MainActivity activity = (MainActivity)getActivity(); + + if (activity != null) { + int orientation = activity.getWindowManager().getDefaultDisplay().getOrientation(); + + if (!activity.isSmallScreen()) { + if (orientation % 2 == 0) { + view.findViewById(R.id.splitter_horizontal).setVisibility(View.GONE); + } else { + view.findViewById(R.id.splitter_vertical).setVisibility(View.GONE); + } + } else { + view.findViewById(R.id.splitter_vertical).setVisibility(View.GONE); + view.findViewById(R.id.splitter_horizontal).setVisibility(View.GONE); + } + } else { + view.findViewById(R.id.splitter_horizontal).setVisibility(View.GONE); + } + + m_cursor = ((MainActivity)getActivity()).getReadableDb().query("articles", null, BaseColumns._ID + "=?", + new String[] { String.valueOf(m_articleId) }, null, null, null); + + m_cursor.moveToFirst(); + + if (m_cursor.isFirst()) { + + TextView title = (TextView)view.findViewById(R.id.title); + + if (title != null) { + + 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.setMovementMethod(LinkMovementMethod.getInstance()); + title.setText(Html.fromHtml("" + titleStr + "")); + } + + WebView web = (WebView)view.findViewById(R.id.content); + + if (web != null) { + + String content; + String cssOverride = ""; + + + //WebSettings ws = web.getSettings(); + //ws.setSupportZoom(true); + //ws.setBuiltInZoomControls(true); + + if (m_prefs.getString("theme", "THEME_DARK").equals("THEME_DARK")) { + cssOverride = "body { background : black; color : #e0e0e0}\n"; + web.setBackgroundColor(android.R.color.black); + } else { + cssOverride = ""; + } + + content = + "" + + "" + + "" + + //"" + + "" + + "" + + "" + m_cursor.getString(m_cursor.getColumnIndex("content")) + ""; + + web.loadDataWithBaseURL(null, content, "text/html", "utf-8", null); + + if (activity.isSmallScreen()) + web.setOnTouchListener(m_gestureListener); + } + + TextView dv = (TextView)view.findViewById(R.id.date); + + if (dv != null) { + Date d = new Date(m_cursor.getInt(m_cursor.getColumnIndex("updated")) * 1000L); + SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy, HH:mm"); + dv.setText(df.format(d)); + } + + TextView tagv = (TextView)view.findViewById(R.id.tags); + + if (tagv != null) { + String tagsStr = m_cursor.getString(m_cursor.getColumnIndex("tags")); + tagv.setText(tagsStr); + } + + AdView av = (AdView)view.findViewById(R.id.ad); + + if (av != null) { + av.setVisibility(View.GONE); + } + + ImageView next = (ImageView)view.findViewById(R.id.next_article); + + if (next != null) { +// if (m_nextArticle != null) { +// next.setOnClickListener(this); +// } else { + next.setImageResource(R.drawable.ic_next_article_disabled); +// } + } + + ImageView prev = (ImageView)view.findViewById(R.id.prev_article); + + if (prev != null) { +// if (m_prevArticle != null) { +// prev.setOnClickListener(this); +// } else { + prev.setImageResource(R.drawable.ic_prev_article_disabled); +// } + } + + } + + 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_articleId = ((MainActivity)activity).getSelectedOfflineArticleId(); + /* m_articleOps = (ArticleOps)activity; + m_article = m_articleOps.getSelectedArticle(); + + m_prevArticle = m_articleOps.getRelativeArticle(m_article, RelativeArticle.BEFORE); + m_nextArticle = m_articleOps.getRelativeArticle(m_article, RelativeArticle.AFTER); */ + } + + @Override + public void onClick(View v) { + /* if (v.getId() == R.id.next_article) { + m_articleOps.openArticle(m_nextArticle, 0); + } else if (v.getId() == R.id.prev_article) { + m_articleOps.openArticle(m_prevArticle, R.anim.slide_right); + } */ + } + + // http://blog.blackmoonit.com/2010/07/gesture-detection-swipe-detection_4292.html + class MyGestureDetector extends SimpleOnGestureListener { + private static final int SWIPE_MIN_DISTANCE = 100; + private static final int SWIPE_MAX_OFF_PATH = 100; + private static final int SWIPE_THRESHOLD_VELOCITY = 100; + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { + float dX = e2.getX()-e1.getX(); + float dY = e1.getY()-e2.getY(); + if (Math.abs(dY)=SWIPE_THRESHOLD_VELOCITY && + Math.abs(dX)>=SWIPE_MIN_DISTANCE ) { + if (dX>0) { + //Log.d(TAG, "Right swipe"); + + //if (m_prevArticle != null) + // m_articleOps.openArticle(m_prevArticle, R.anim.slide_right); + + } else { + //Log.d(TAG, "Left swipe"); + + //if (m_nextArticle != null) + // m_articleOps.openArticle(m_nextArticle, 0); + + } + return true; + /* } else if (Math.abs(dX)=SWIPE_THRESHOLD_VELOCITY && + Math.abs(dY)>=SWIPE_MIN_DISTANCE ) { + if (dY>0) { + Log.d(TAG, "Up swipe"); + } else { + Log.d(TAG, "Down swipe"); + } + return true; */ + } + return false; + } + }; +} diff --git a/src/org/fox/ttrss/OfflineFeedsFragment.java b/src/org/fox/ttrss/OfflineFeedsFragment.java index 992adab1..cdb33ef9 100644 --- a/src/org/fox/ttrss/OfflineFeedsFragment.java +++ b/src/org/fox/ttrss/OfflineFeedsFragment.java @@ -24,7 +24,6 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.OnItemClickListener; -import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; @@ -54,6 +53,18 @@ public class OfflineFeedsFragment extends Fragment implements OnItemClickListene } + public Cursor createCursor() { + if (m_cursor != null) m_cursor.close(); + + return ((MainActivity)getActivity()).getReadableDb().query("feeds_unread", + null, null, null, null, null, "title"); + } + + public void refresh() { + m_adapter.changeCursor(createCursor()); + m_adapter.notifyDataSetChanged(); + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -65,8 +76,7 @@ public class OfflineFeedsFragment extends Fragment implements OnItemClickListene ListView list = (ListView)view.findViewById(R.id.feeds); - m_cursor = ((MainActivity)getActivity()).getReadableDb().query("feeds_unread", - null, null, null, null, null, "title"); + 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); diff --git a/src/org/fox/ttrss/OfflineHeadlinesFragment.java b/src/org/fox/ttrss/OfflineHeadlinesFragment.java new file mode 100644 index 00000000..a0547c0f --- /dev/null +++ b/src/org/fox/ttrss/OfflineHeadlinesFragment.java @@ -0,0 +1,421 @@ +package org.fox.ttrss; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +import org.jsoup.Jsoup; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.database.Cursor; +import android.database.sqlite.SQLiteStatement; +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.text.Html; +import android.text.Html.ImageGetter; +import android.text.method.LinkMovementMethod; +import android.util.Log; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.LayoutInflater; +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 int m_activeArticleId; + private boolean m_combinedMode = true; + private ArrayList m_selectedArticles = new ArrayList(); + + private SharedPreferences m_prefs; + + private Cursor m_cursor; + private ArticleListAdapter m_adapter; + + private ArticleOps m_articleOps; + + private ImageGetter m_dummyGetter = new ImageGetter() { + + @Override + public Drawable getDrawable(String source) { + return new BitmapDrawable(); + } + + }; + + public List getSelectedArticles() { + return m_selectedArticles; + } + + @Override + public void onDestroy() { + super.onDestroy(); + + m_cursor.close(); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + + getActivity().getMenuInflater().inflate(R.menu.headlines_menu, menu); + + if (m_selectedArticles.size() > 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"))); + menu.setGroupVisible(R.id.menu_group_single_article, true); + } + + super.onCreateContextMenu(menu, v, menuInfo); + + } + + public void refresh() { + m_adapter.changeCursor(createCursor()); + m_adapter.notifyDataSetChanged(); + } + + @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_combinedMode = savedInstanceState.getBoolean("combinedMode"); + } + + View view = inflater.inflate(R.layout.headlines_fragment, container, false); + + 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); + + list.setAdapter(m_adapter); + list.setOnItemClickListener(this); + registerForContextMenu(list); + + view.findViewById(R.id.loading_progress).setVisibility(View.GONE); + + return view; + } + + public Cursor createCursor() { + if (m_cursor != null) m_cursor.close(); + + return ((MainActivity)getActivity()).getReadableDb().query("articles", + null, "feed_id = ?", new String[] { String.valueOf(m_feedId) }, null, null, "updated DESC"); + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + m_feedId = ((MainActivity)activity).getActiveOfflineFeedId(); + m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); + m_articleOps = (ArticleOps) activity; + m_combinedMode = m_prefs.getBoolean("combined_mode", false); + } + + @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); + + m_activeArticleId = cursor.getInt(0); + + if (m_combinedMode) { + SQLiteStatement stmtUpdate = ((MainActivity)getActivity()).getWritableDb().compileStatement("UPDATE articles SET unread = 0 " + + "WHERE " + BaseColumns._ID + " = ?"); + + stmtUpdate.bindLong(1, m_activeArticleId); + stmtUpdate.execute(); + stmtUpdate.close(); + + refresh(); + } else { + ((MainActivity)getActivity()).openOfflineArticle(m_activeArticleId, 0); + } + + + } + } + + @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.putBoolean("combinedMode", m_combinedMode); + } + + 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); + } + + View pb = getView().findViewById(R.id.loading_progress); + + if (pb != null) { + pb.setVisibility(showProgress ? View.VISIBLE : View.GONE); + } + } + } + + private class ArticleListAdapter extends SimpleCursorAdapter { + public ArticleListAdapter(Context context, int layout, Cursor c, + String[] from, int[] to, int flags) { + super(context, layout, c, from, to, flags); + // TODO Auto-generated constructor stub + } + + 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_LOADMORE = 3; + + public static final int VIEW_COUNT = VIEW_LOADMORE+1; + + + public int getViewTypeCount() { + return VIEW_COUNT; + } + + @Override + public int getItemViewType(int position) { + Cursor c = (Cursor) getItem(position); + + if (c.getLong(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); + + 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: + 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) { + if (m_combinedMode) { + tt.setMovementMethod(LinkMovementMethod.getInstance()); + tt.setText(Html.fromHtml("" + + article.getString(article.getColumnIndex("title")) + "")); + } else { + tt.setText(Html.fromHtml(article.getString(article.getColumnIndex("title")))); + } + } + + ImageView marked = (ImageView)v.findViewById(R.id.marked); + + if (marked != null) { + marked.setImageResource(article.getInt(article.getColumnIndex("marked")) == 1 ? android.R.drawable.star_on : android.R.drawable.star_off); + + marked.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + SQLiteStatement stmtUpdate = ((MainActivity)getActivity()).getWritableDb().compileStatement("UPDATE articles SET 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_rss : R.drawable.ic_rss_bw); + + published.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + SQLiteStatement stmtUpdate = ((MainActivity)getActivity()).getWritableDb().compileStatement("UPDATE articles SET 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_combinedMode) { + String excerpt = Jsoup.parse(article.getString(article.getColumnIndex("content"))).text(); + + if (excerpt.length() > 100) + excerpt = excerpt.substring(0, 100) + "..."; + + te.setText(excerpt); + } else { + te.setVisibility(View.GONE); + } + } + + TextView content = (TextView)v.findViewById(R.id.content); + + if (content != null) { + if (m_combinedMode) { + content.setMovementMethod(LinkMovementMethod.getInstance()); + + content.setText(Html.fromHtml(article.getString(article.getColumnIndex("content")), m_dummyGetter, null)); + + } else { + content.setVisibility(View.GONE); + } + + } + + TextView dv = (TextView) v.findViewById(R.id.date); + + if (dv != null) { + 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(m_selectedArticles.contains(article)); + cb.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View view) { + CheckBox cb = (CheckBox)view; + + if (cb.isChecked()) { + if (!m_selectedArticles.contains(new Integer(articleId))) + m_selectedArticles.add(new Integer(articleId)); + } else { + m_selectedArticles.remove(new Integer(articleId)); + } + + ((MainActivity)getActivity()).initMainMenu(); + + Log.d(TAG, "num selected: " + m_selectedArticles.size()); + } + }); + } + + return v; + } + } + + public void notifyUpdated() { + m_adapter.notifyDataSetChanged(); + } + + public void setActiveArticleId(int id) { + m_activeArticleId = id; + m_adapter.notifyDataSetChanged(); + + /* ListView list = (ListView)getView().findViewById(R.id.headlines); + + if (list != null) { + int position = m_adapter.getPosition(getArticleById(id)); + list.setSelection(position); + } */ + } + + 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(); + } + + public Cursor getArticleAtPosition(int position) { + return (Cursor) m_adapter.getItem(position); + } + + public int getActiveArticleId() { + return m_activeArticleId; + } + +}