diff options
author | Andrew Dolgov <[email protected]> | 2014-10-17 00:06:56 +0400 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2014-10-17 00:06:56 +0400 |
commit | 97cc96839d31b6cce59ec29a6681c6fe802552ee (patch) | |
tree | 9f3b8df270095bc65c10cd7208d05b3dad4794b9 /src/org | |
parent | 5775c0d56b7c856b508bb34e478eef53c2460624 (diff) |
initial
Diffstat (limited to 'src/org')
55 files changed, 0 insertions, 13986 deletions
diff --git a/src/org/fox/ttrss/ApiRequest.java b/src/org/fox/ttrss/ApiRequest.java deleted file mode 100644 index 65e97e8e..00000000 --- a/src/org/fox/ttrss/ApiRequest.java +++ /dev/null @@ -1,351 +0,0 @@ -package org.fox.ttrss; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.HashMap; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.SharedPreferences; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.AsyncTask; -import android.os.Build; -import android.preference.PreferenceManager; -import android.util.Base64; -import android.util.Log; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - -public class ApiRequest extends AsyncTask<HashMap<String,String>, Integer, JsonElement> { - private final String TAG = this.getClass().getSimpleName(); - - public enum ApiError { NO_ERROR, HTTP_UNAUTHORIZED, HTTP_FORBIDDEN, HTTP_NOT_FOUND, - HTTP_SERVER_ERROR, HTTP_OTHER_ERROR, SSL_REJECTED, SSL_HOSTNAME_REJECTED, PARSE_ERROR, IO_ERROR, OTHER_ERROR, API_DISABLED, - API_UNKNOWN, LOGIN_FAILED, INVALID_URL, API_INCORRECT_USAGE, NETWORK_UNAVAILABLE, API_UNKNOWN_METHOD }; - - public static final int API_STATUS_OK = 0; - public static final int API_STATUS_ERR = 1; - - private String m_api; - private boolean m_transportDebugging = false; - protected int m_responseCode = 0; - protected String m_responseMessage; - protected int m_apiStatusCode = 0; - protected boolean m_canUseProgress = false; - protected Context m_context; - private SharedPreferences m_prefs; - - protected ApiError m_lastError; - - public ApiRequest(Context context) { - m_context = context; - - m_prefs = PreferenceManager.getDefaultSharedPreferences(m_context); - - m_api = m_prefs.getString("ttrss_url", "").trim(); - m_transportDebugging = m_prefs.getBoolean("transport_debugging", false); - m_lastError = ApiError.NO_ERROR; - - } - - @SuppressLint("NewApi") - @SuppressWarnings("unchecked") - public void execute(HashMap<String,String> map) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) - super.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, map); - else - super.execute(map); - } - - public int getErrorMessage() { - switch (m_lastError) { - case NO_ERROR: - return R.string.error_unknown; - case HTTP_UNAUTHORIZED: - return R.string.error_http_unauthorized; - case HTTP_FORBIDDEN: - return R.string.error_http_forbidden; - case HTTP_NOT_FOUND: - return R.string.error_http_not_found; - case HTTP_SERVER_ERROR: - return R.string.error_http_server_error; - case HTTP_OTHER_ERROR: - return R.string.error_http_other_error; - case SSL_REJECTED: - return R.string.error_ssl_rejected; - case SSL_HOSTNAME_REJECTED: - return R.string.error_ssl_hostname_rejected; - case PARSE_ERROR: - return R.string.error_parse_error; - case IO_ERROR: - return R.string.error_io_error; - case OTHER_ERROR: - return R.string.error_other_error; - case API_DISABLED: - return R.string.error_api_disabled; - case API_UNKNOWN: - return R.string.error_api_unknown; - case API_UNKNOWN_METHOD: - return R.string.error_api_unknown_method; - case LOGIN_FAILED: - return R.string.error_login_failed; - case INVALID_URL: - return R.string.error_invalid_api_url; - case API_INCORRECT_USAGE: - return R.string.error_api_incorrect_usage; - case NETWORK_UNAVAILABLE: - return R.string.error_network_unavailable; - default: - Log.d(TAG, "getErrorMessage: unknown error code=" + m_lastError); - return R.string.error_unknown; - } - } - - @Override - protected JsonElement doInBackground(HashMap<String, String>... params) { - - if (!isNetworkAvailable()) { - m_lastError = ApiError.NETWORK_UNAVAILABLE; - return null; - } - - Gson gson = new Gson(); - - String requestStr = gson.toJson(new HashMap<String,String>(params[0])); - byte[] postData = null; - - try { - postData = requestStr.getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - m_lastError = ApiError.OTHER_ERROR; - e.printStackTrace(); - return null; - } - - /* disableConnectionReuseIfNecessary(); */ - - if (m_transportDebugging) Log.d(TAG, ">>> (" + requestStr + ") " + m_api); - - /* ApiRequest.trustAllHosts(m_prefs.getBoolean("ssl_trust_any", false), - m_prefs.getBoolean("ssl_trust_any_host", false)); */ - - URL url; - - try { - url = new URL(m_api + "/api/"); - } catch (Exception e) { - m_lastError = ApiError.INVALID_URL; - e.printStackTrace(); - return null; - } - - try { - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - - String httpLogin = m_prefs.getString("http_login", "").trim(); - String httpPassword = m_prefs.getString("http_password", "").trim(); - - if (httpLogin.length() > 0) { - if (m_transportDebugging) Log.d(TAG, "Using HTTP Basic authentication."); - - conn.setRequestProperty("Authorization", "Basic " + - Base64.encodeToString((httpLogin + ":" + httpPassword).getBytes("UTF-8"), Base64.NO_WRAP)); - } - - conn.setDoInput(true); - conn.setDoOutput(true); - conn.setUseCaches(false); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Length", Integer.toString(postData.length)); - - OutputStream out = conn.getOutputStream(); - out.write(postData); - out.close(); - - m_responseCode = conn.getResponseCode(); - m_responseMessage = conn.getResponseMessage(); - - switch (m_responseCode) { - case HttpURLConnection.HTTP_OK: - StringBuffer response = new StringBuffer(); - InputStreamReader in = new InputStreamReader(conn.getInputStream(), "UTF-8"); - char[] buf = new char[256]; - int read = 0; - int total = 0; - - int contentLength = conn.getHeaderFieldInt("Api-Content-Length", -1); - - m_canUseProgress = (contentLength != -1); - - while ((read = in.read(buf)) >= 0) { - response.append(buf, 0, read); - total += read; - publishProgress(Integer.valueOf(total), Integer.valueOf(contentLength)); - } - - if (m_transportDebugging) Log.d(TAG, "<<< " + response); - - JsonParser parser = new JsonParser(); - - JsonElement result = parser.parse(response.toString()); - JsonObject resultObj = result.getAsJsonObject(); - - m_apiStatusCode = resultObj.get("status").getAsInt(); - - conn.disconnect(); - - switch (m_apiStatusCode) { - case API_STATUS_OK: - return result.getAsJsonObject().get("content"); - case API_STATUS_ERR: - JsonObject contentObj = resultObj.get("content").getAsJsonObject(); - String error = contentObj.get("error").getAsString(); - - if (error.equals("LOGIN_ERROR")) { - m_lastError = ApiError.LOGIN_FAILED; - } else if (error.equals("API_DISABLED")) { - m_lastError = ApiError.API_DISABLED; - } else if (error.equals("NOT_LOGGED_IN")) { - m_lastError = ApiError.LOGIN_FAILED; - } else if (error.equals("INCORRECT_USAGE")) { - m_lastError = ApiError.API_INCORRECT_USAGE; - } else if (error.equals("UNKNOWN_METHOD")) { - m_lastError = ApiError.API_UNKNOWN_METHOD; - } else { - Log.d(TAG, "Unknown API error: " + error); - m_lastError = ApiError.API_UNKNOWN; - } - } - - return null; - case HttpURLConnection.HTTP_UNAUTHORIZED: - m_lastError = ApiError.HTTP_UNAUTHORIZED; - break; - case HttpURLConnection.HTTP_FORBIDDEN: - m_lastError = ApiError.HTTP_FORBIDDEN; - break; - case HttpURLConnection.HTTP_NOT_FOUND: - m_lastError = ApiError.HTTP_NOT_FOUND; - break; - case HttpURLConnection.HTTP_INTERNAL_ERROR: - m_lastError = ApiError.HTTP_SERVER_ERROR; - break; - default: - Log.d(TAG, "HTTP response code: " + m_responseCode + "(" + m_responseMessage + ")"); - m_lastError = ApiError.HTTP_OTHER_ERROR; - break; - } - - conn.disconnect(); - return null; - } catch (javax.net.ssl.SSLPeerUnverifiedException e) { - m_lastError = ApiError.SSL_REJECTED; - e.printStackTrace(); - } catch (IOException e) { - m_lastError = ApiError.IO_ERROR; - - if (e.getMessage() != null) { - if (e.getMessage().matches("Hostname [^ ]+ was not verified")) { - m_lastError = ApiError.SSL_HOSTNAME_REJECTED; - } - } - - e.printStackTrace(); - } catch (com.google.gson.JsonSyntaxException e) { - m_lastError = ApiError.PARSE_ERROR; - e.printStackTrace(); - } catch (Exception e) { - m_lastError = ApiError.OTHER_ERROR; - e.printStackTrace(); - } - - return null; - } - - protected static void trustAllHosts(boolean trustAnyCert, boolean trustAnyHost) { - try { - if (trustAnyCert) { - X509TrustManager easyTrustManager = new X509TrustManager() { - - public void checkClientTrusted( - X509Certificate[] chain, - String authType) throws CertificateException { - // Oh, I am easy! - } - - public void checkServerTrusted( - X509Certificate[] chain, - String authType) throws CertificateException { - // Oh, I am easy! - } - - public X509Certificate[] getAcceptedIssuers() { - return null; - } - - }; - - // Create a trust manager that does not validate certificate chains - TrustManager[] trustAllCerts = new TrustManager[] {easyTrustManager}; - - // Install the all-trusting trust manager - - SSLContext sc = SSLContext.getInstance("TLS"); - - sc.init(null, trustAllCerts, new java.security.SecureRandom()); - - HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - } - - if (trustAnyHost) { - HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - @SuppressWarnings("deprecation") - protected static void disableConnectionReuseIfNecessary() { - // HTTP connection reuse which was buggy pre-froyo - if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) { - System.setProperty("http.keepAlive", "false"); - } - } - - protected boolean isNetworkAvailable() { - ConnectivityManager cm = (ConnectivityManager) - m_context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo networkInfo = cm.getActiveNetworkInfo(); - - // if no network is available networkInfo will be null - // otherwise check if we are connected - if (networkInfo != null && networkInfo.isConnected()) { - return true; - } - return false; - } -} diff --git a/src/org/fox/ttrss/ArticleFragment.java b/src/org/fox/ttrss/ArticleFragment.java deleted file mode 100644 index 4a568d3c..00000000 --- a/src/org/fox/ttrss/ArticleFragment.java +++ /dev/null @@ -1,449 +0,0 @@ -package org.fox.ttrss; - -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.types.Article; -import org.fox.ttrss.types.Attachment; -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.graphics.Color; -import android.graphics.Typeface; -import android.net.Uri; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.text.Html; -import android.util.TypedValue; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.KeyEvent; -import android.view.LayoutInflater; -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 ArticleFragment extends Fragment { - private final String TAG = this.getClass().getSimpleName(); - - private SharedPreferences m_prefs; - private Article m_article; - private OnlineActivity m_activity; - - public void initialize(Article article) { - m_article = article; - } - - private View.OnTouchListener m_gestureListener; - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - - 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(m_article.title); - getActivity().getMenuInflater().inflate(R.menu.article_link_context_menu, menu); - } - } else { - menu.setHeaderTitle(m_article.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) { - m_activity.setProgressBarVisibility(true); - - if (savedInstanceState != null) { - m_article = savedInstanceState.getParcelable("article"); - } - - 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); - - if (m_article != null) { - - 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); - - 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_article.title.length() > 200) - titleStr = m_article.title.substring(0, 200) + "..."; - else - titleStr = m_article.title; - - title.setText(Html.fromHtml(titleStr)); - //title.setPaintFlags(title.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); - title.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - try { - URL url = new URL(m_article.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) { - if (m_activity.getApiLevel() >= 4 && m_article.comments_count > 0) { - comments.setTextSize(TypedValue.COMPLEX_UNIT_SP, articleSmallFontSize); - - String commentsTitle = getString(R.string.article_comments, m_article.comments_count); - comments.setText(commentsTitle); - //comments.setPaintFlags(title.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); - comments.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - try { - URL url = new URL((m_article.comments_link != null && m_article.comments_link.length() > 0) ? - m_article.comments_link : m_article.link); - 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); - } - } - }); - - } else { - comments.setVisibility(View.GONE); - } - } - - TextView note = (TextView)view.findViewById(R.id.note); - - if (note != null) { - if (m_article.note != null && !"".equals(m_article.note)) { - note.setTextSize(TypedValue.COMPLEX_UNIT_SP, articleSmallFontSize); - note.setText(m_article.note); - } else { - 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; - } - } - }); - - // 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); - } - } - - 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); - - 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_article.content != null ? m_article.content : ""; - - Document doc = Jsoup.parse(articleContent); - - if (doc != null) { - // 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%; }" + - "img { max-width : 100%; width : auto; height : auto; }" + - cssOverride + - "</style>" + - "</head>" + - "<body>" + articleContent; - - if (useTitleWebView) { - content += "<p> </p><p> </p><p> </p><p> </p>"; - } - - if (m_article.attachments != null && m_article.attachments.size() != 0) { - String flatContent = articleContent.replaceAll("[\r\n]", ""); - boolean hasImages = flatContent.matches(".*?<img[^>+].*?"); - - for (Attachment a : m_article.attachments) { - if (a.content_type != null && a.content_url != null) { - try { - if (a.content_type.indexOf("image") != -1 && - (!hasImages || m_article.always_display_attachments)) { - - URL url = new URL(a.content_url.trim()); - String strUrl = url.toString().trim(); - - content += "<p><img src=\"" + strUrl.replace("\"", "\\\"") + "\"></p>"; - } - - } catch (MalformedURLException e) { - // - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - - content += "</body></html>"; - - try { - String baseUrl = null; - - try { - URL url = new URL(m_article.link); - baseUrl = url.getProtocol() + "://" + url.getHost(); - } catch (MalformedURLException e) { - // - } - - web.loadDataWithBaseURL(baseUrl, content, "text/html", "utf-8", null); - } catch (RuntimeException e) { - e.printStackTrace(); - } - - if (m_activity.isSmallScreen()) - web.setOnTouchListener(m_gestureListener); - - web.setVisibility(View.VISIBLE); - } - - TextView dv = (TextView)view.findViewById(R.id.date); - - if (dv != null) { - dv.setTextSize(TypedValue.COMPLEX_UNIT_SP, articleSmallFontSize); - - Date d = new Date(m_article.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); - - if (m_article.author != null && m_article.author.length() > 0) { - author.setText(getString(R.string.author_formatted, m_article.author)); - } 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); - - if (m_article.feed_title != null) { - String fTitle = m_article.feed_title; - - if (!hasAuthor && m_article.author != null && m_article.author.length() > 0) { - fTitle += " (" + getString(R.string.author_formatted, m_article.author) + ")"; - } - - tagv.setText(fTitle); - } else if (m_article.tags != null) { - String tagsStr = ""; - - for (String tag : m_article.tags) - tagsStr += tag + ", "; - - tagsStr = tagsStr.replaceAll(", $", ""); - - tagv.setText(tagsStr); - } else { - tagv.setVisibility(View.GONE); - } - } - - } - - return view; - } - - @Override - public void onDestroy() { - super.onDestroy(); - } - - @Override - public void onSaveInstanceState (Bundle out) { - super.onSaveInstanceState(out); - - out.setClassLoader(getClass().getClassLoader()); - out.putParcelable("article", m_article); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - m_activity = (OnlineActivity)activity; - //m_article = m_onlineServices.getSelectedArticle(); - - } -} diff --git a/src/org/fox/ttrss/ArticlePager.java b/src/org/fox/ttrss/ArticlePager.java deleted file mode 100644 index ee940e79..00000000 --- a/src/org/fox/ttrss/ArticlePager.java +++ /dev/null @@ -1,347 +0,0 @@ -package org.fox.ttrss; - -import java.util.HashMap; - -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; -import org.fox.ttrss.types.Feed; -import org.fox.ttrss.util.HeadlinesRequest; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.SharedPreferences; -import android.os.BadParcelableException; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.ClassloaderWorkaroundFragmentStatePagerAdapter; -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; - -import com.google.gson.JsonElement; -import com.viewpagerindicator.UnderlinePageIndicator; - -public class ArticlePager extends Fragment { - - private final String TAG = "ArticlePager"; - private PagerAdapter m_adapter; - private HeadlinesEventListener m_listener; - private Article m_article; - private ArticleList m_articles = GlobalState.getInstance().m_loadedArticles; - private OnlineActivity m_activity; - private String m_searchQuery = ""; - private Feed m_feed; - private SharedPreferences m_prefs; - - private class PagerAdapter extends ClassloaderWorkaroundFragmentStatePagerAdapter { - - public PagerAdapter(FragmentManager fm) { - super(fm); - } - - @Override - public Fragment getItem(int position) { - Article article = m_articles.get(position); - - if (article != null) { - ArticleFragment af = new ArticleFragment(); - af.initialize(article); - - if (m_prefs.getBoolean("dim_status_bar", false) && getView() != null && !m_activity.isCompatMode()) { - getView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); - } - - return af; - } - return null; - } - - @Override - public int getCount() { - return m_articles.size(); - } - - } - - public void initialize(Article article, Feed feed) { - m_article = article; - m_feed = feed; - } - - public void setSearchQuery(String searchQuery) { - m_searchQuery = searchQuery; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.article_pager, container, false); - - if (savedInstanceState != null) { - m_article = savedInstanceState.getParcelable("article"); - m_feed = savedInstanceState.getParcelable("feed"); - } - - m_adapter = new PagerAdapter(getActivity().getSupportFragmentManager()); - - ViewPager pager = (ViewPager) view.findViewById(R.id.article_pager); - - int position = m_articles.indexOf(m_article); - - m_listener.onArticleSelected(m_article, false); - - m_activity.setProgressBarVisibility(true); - - 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) { - Article article = m_articles.get(position); - - if (article != null) { - m_article = article; - - /* if (article.unread) { - article.unread = false; - m_activity.saveArticleUnread(article); - } */ - - m_listener.onArticleSelected(article, false); - - //Log.d(TAG, "Page #" + position + "/" + m_adapter.getCount()); - - if ((m_activity.isSmallScreen() || m_activity.isPortrait()) && position == m_adapter.getCount() - 15) { - Log.d(TAG, "loading more articles..."); - refresh(true); - } - } - } - }); - - return view; - } - - @SuppressWarnings({ "serial" }) - protected void refresh(boolean append) { - m_activity.setLoadingStatus(R.string.blank, true); - - m_activity.setProgressBarVisibility(true); - //m_activity.m_pullToRefreshAttacher.setRefreshing(true); - - if (!m_feed.equals(GlobalState.getInstance().m_activeFeed)) { - append = false; - } - - HeadlinesRequest req = new HeadlinesRequest(getActivity().getApplicationContext(), m_activity, m_feed) { - @Override - protected void onProgressUpdate(Integer... progress) { - m_activity.setProgress(progress[0] / progress[1] * 10000); - } - - @Override - protected void onPostExecute(JsonElement result) { - if (isDetached()) return; - - m_activity.setProgressBarVisibility(false); - //m_activity.m_pullToRefreshAttacher.setRefreshComplete(); - - super.onPostExecute(result); - - if (result != null) { - try { - m_adapter.notifyDataSetChanged(); - } catch (BadParcelableException e) { - if (getActivity() != null) { - getActivity().finish(); - return; - } - } - - if (m_article != null) { - if (m_article.id == 0 || m_articles.indexOf(m_article) == -1) { - if (m_articles.size() > 0) { - m_article = m_articles.get(0); - m_listener.onArticleSelected(m_article, false); - } - } - } - - } else { - if (m_lastError == ApiError.LOGIN_FAILED) { - m_activity.login(true); - } else { - m_activity.toast(getErrorMessage()); - //setLoadingStatus(getErrorMessage(), false); - } - } - } - }; - - final Feed feed = m_feed; - - final String sessionId = m_activity.getSessionId(); - int skip = 0; - - if (append) { - // adaptive, all_articles, marked, published, unread - String viewMode = m_activity.getViewMode(); - int numUnread = 0; - int numAll = m_articles.size(); - - for (Article a : m_articles) { - if (a.unread) ++numUnread; - } - - if ("marked".equals(viewMode)) { - skip = numAll; - } else if ("published".equals(viewMode)) { - skip = numAll; - } else if ("unread".equals(viewMode)) { - skip = numUnread; - } else if (m_searchQuery != null && m_searchQuery.length() > 0) { - skip = numAll; - } else if ("adaptive".equals(viewMode)) { - skip = numUnread > 0 ? numUnread : numAll; - } else { - skip = numAll; - } - } - - final int fskip = skip; - - req.setOffset(skip); - - HashMap<String,String> map = new HashMap<String,String>() { - { - put("op", "getHeadlines"); - put("sid", sessionId); - put("feed_id", String.valueOf(feed.id)); - put("show_content", "true"); - put("include_attachments", "true"); - put("limit", String.valueOf(HeadlinesFragment.HEADLINES_REQUEST_SIZE)); - put("offset", String.valueOf(0)); - put("view_mode", m_activity.getViewMode()); - put("skip", String.valueOf(fskip)); - put("include_nested", "true"); - put("order_by", m_prefs.getBoolean("oldest_first", false) ? "date_reverse" : ""); - - if (feed.is_cat) put("is_cat", "true"); - - if (m_searchQuery != null && m_searchQuery.length() != 0) { - put("search", m_searchQuery); - put("search_mode", ""); - put("match_on", "both"); - } - } - }; - - req.execute(map); - } - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - out.setClassLoader(getClass().getClassLoader()); - out.putParcelable("article", m_article); - out.putParcelable("feed", m_feed); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - m_listener = (HeadlinesEventListener)activity; - m_activity = (OnlineActivity)activity; - - m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - } - - @SuppressLint("NewApi") - @Override - public void onResume() { - super.onResume(); - - if (m_articles.size() == 0 || !m_feed.equals(GlobalState.getInstance().m_activeFeed)) { - refresh(false); - GlobalState.getInstance().m_activeFeed = m_feed; - } - - m_activity.initMenu(); - - 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 Article getSelectedArticle() { - return m_article; - } - - public void setActiveArticle(Article article) { - if (m_article != article) { - m_article = article; - - int position = m_articles.indexOf(m_article); - - ViewPager pager = (ViewPager) getView().findViewById(R.id.article_pager); - - pager.setCurrentItem(position); - } - } - - public void selectArticle(boolean next) { - if (m_article != null) { - int position = m_articles.indexOf(m_article); - - if (next) - position++; - else - position--; - - try { - Article tmp = m_articles.get(position); - - if (tmp != null) { - setActiveArticle(tmp); - } - - } catch (IndexOutOfBoundsException e) { - // do nothing - } - } - } - - public void notifyUpdated() { - m_adapter.notifyDataSetChanged(); - } -} diff --git a/src/org/fox/ttrss/CommonActivity.java b/src/org/fox/ttrss/CommonActivity.java deleted file mode 100644 index 5a64ae57..00000000 --- a/src/org/fox/ttrss/CommonActivity.java +++ /dev/null @@ -1,250 +0,0 @@ -package org.fox.ttrss; - - -import java.io.File; -import java.io.IOException; - -import org.fox.ttrss.util.DatabaseHelper; - -import com.nostra13.universalimageloader.core.ImageLoader; -import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; -import com.nostra13.universalimageloader.utils.StorageUtils; -import com.readystatesoftware.systembartint.SystemBarTintManager; - -import android.annotation.SuppressLint; -import android.content.SharedPreferences; -import android.database.sqlite.SQLiteDatabase; -import android.graphics.BitmapFactory; -import android.graphics.Point; -import android.net.http.HttpResponseCache; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.app.ActionBarActivity; -import android.util.Log; -import android.util.TypedValue; -import android.view.Display; -import android.view.View; -import android.widget.TextView; -import android.widget.Toast; - -public class CommonActivity extends ActionBarActivity { - private final String TAG = this.getClass().getSimpleName(); - - public final static String FRAG_HEADLINES = "headlines"; - public final static String FRAG_ARTICLE = "article"; - public final static String FRAG_FEEDS = "feeds"; - public final static String FRAG_CATS = "cats"; - - public final static String THEME_DARK = "THEME_DARK"; - public final static String THEME_LIGHT = "THEME_LIGHT"; - public final static String THEME_SEPIA = "THEME_SEPIA"; - public final static String THEME_HOLO = "THEME_HOLO"; - public final static String THEME_DEFAULT = CommonActivity.THEME_LIGHT; - - public static final int EXCERPT_MAX_SIZE = 200; - - private SQLiteDatabase m_readableDb; - private SQLiteDatabase m_writableDb; - - private boolean m_smallScreenMode = true; - private boolean m_compatMode = false; - private String m_theme; - - protected SharedPreferences m_prefs; - - /* protected void enableHttpCaching() { - // enable resource caching - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - try { - File httpCacheDir = new File(getApplicationContext().getCacheDir(), "http"); - long httpCacheSize = 10 * 1024 * 1024; // 10 MiB - HttpResponseCache.install(httpCacheDir, httpCacheSize); - } catch (IOException e) { - e.printStackTrace(); - } - } - } */ - - protected void setSmallScreen(boolean smallScreen) { - Log.d(TAG, "m_smallScreenMode=" + smallScreen); - m_smallScreenMode = smallScreen; - } - - public boolean getUnreadOnly() { - return m_prefs.getBoolean("show_unread_only", true); - } - - public void setUnreadOnly(boolean unread) { - SharedPreferences.Editor editor = m_prefs.edit(); - editor.putBoolean("show_unread_only", unread); - editor.commit(); - } - - public void setLoadingStatus(int status, boolean showProgress) { - TextView tv = (TextView) findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(status); - } - - findViewById(R.id.loading_container).setVisibility(status == R.string.blank ? View.GONE : View.VISIBLE); - - setProgressBarIndeterminateVisibility(showProgress); - } - - public void toast(int msgId) { - Toast toast = Toast.makeText(CommonActivity.this, msgId, Toast.LENGTH_SHORT); - toast.show(); - } - - public void toast(String msg) { - Toast toast = Toast.makeText(CommonActivity.this, msg, Toast.LENGTH_SHORT); - toast.show(); - } - - private void initDatabase() { - DatabaseHelper dh = new DatabaseHelper(getApplicationContext()); - - m_writableDb = dh.getWritableDatabase(); - m_readableDb = dh.getReadableDatabase(); - } - - public synchronized SQLiteDatabase getReadableDb() { - return m_readableDb; - } - - public synchronized SQLiteDatabase getWritableDb() { - return m_writableDb; - } - - @Override - public void onResume() { - super.onResume(); - - if (!m_theme.equals(m_prefs.getString("theme", CommonActivity.THEME_DEFAULT))) { - Log.d(TAG, "theme changed, restarting"); - - finish(); - startActivity(getIntent()); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - - m_readableDb.close(); - m_writableDb.close(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - if (savedInstanceState != null) { - m_theme = savedInstanceState.getString("theme"); - } else { - m_theme = m_prefs.getString("theme", CommonActivity.THEME_DEFAULT); - } - - initDatabase(); - - m_compatMode = android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB; - - Log.d(TAG, "m_compatMode=" + m_compatMode); - - super.onCreate(savedInstanceState); - } - - public void setStatusBarTint() { - if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.KITKAT) { - SystemBarTintManager tintManager = new SystemBarTintManager(this); - // enable status bar tint - tintManager.setStatusBarTintEnabled(true); - // enable navigation bar tint - tintManager.setNavigationBarTintEnabled(true); - - TypedValue tv = new TypedValue(); - getTheme().resolveAttribute(R.attr.statusBarHintColor, tv, true); - - tintManager.setStatusBarTintColor(tv.data); - } - } - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - out.putString("theme", m_theme); - } - - public boolean isSmallScreen() { - return m_smallScreenMode; - } - - public boolean isCompatMode() { - return m_compatMode; - } - - @SuppressWarnings("deprecation") - public boolean isPortrait() { - Display display = getWindowManager().getDefaultDisplay(); - - int width = display.getWidth(); - int height = display.getHeight(); - - return width < height; - } - - @SuppressLint({ "NewApi", "ServiceCast" }) - @SuppressWarnings("deprecation") - public void copyToClipboard(String str) { - if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(CLIPBOARD_SERVICE); - clipboard.setText(str); - } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(CLIPBOARD_SERVICE); - clipboard.setText(str); - } - - Toast toast = Toast.makeText(this, R.string.text_copied_to_clipboard, Toast.LENGTH_SHORT); - toast.show(); - } - - public boolean isDarkTheme() { - String theme = m_prefs.getString("theme", THEME_DEFAULT); - - return theme.equals(THEME_DARK) || theme.equals(THEME_HOLO); - } - - protected void setAppTheme(SharedPreferences prefs) { - String theme = prefs.getString("theme", CommonActivity.THEME_DEFAULT); - - if (theme.equals(THEME_DARK)) { - setTheme(R.style.DarkTheme); - } else if (theme.equals(THEME_SEPIA)) { - setTheme(R.style.SepiaTheme); - } else if (theme.equals(THEME_HOLO)) { - setTheme(R.style.HoloTheme); - } else { - setTheme(R.style.LightTheme); - } - } - - @SuppressWarnings("deprecation") - @SuppressLint("NewApi") - protected int getScreenWidthInPixel() { - Display display = getWindowManager().getDefaultDisplay(); - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) { - Point size = new Point(); - display.getSize(size); - int width = size.x; - return width; - } else { - return display.getWidth(); - } - } -} diff --git a/src/org/fox/ttrss/DashClock.java b/src/org/fox/ttrss/DashClock.java deleted file mode 100644 index b3491972..00000000 --- a/src/org/fox/ttrss/DashClock.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.fox.ttrss; - -import java.util.HashMap; - -import org.fox.ttrss.util.SimpleLoginManager; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.view.View; - -import com.google.android.apps.dashclock.api.DashClockExtension; -import com.google.android.apps.dashclock.api.ExtensionData; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -public class DashClock extends DashClockExtension { - - private final String TAG = this.getClass().getSimpleName(); - - protected SharedPreferences m_prefs; - - @Override - protected void onInitialize(boolean isReconnect) { - super.onInitialize(isReconnect); - setUpdateWhenScreenOn(true); - - m_prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - } - - @Override - protected void onUpdateData(int reason) { - - SimpleLoginManager loginManager = new SimpleLoginManager() { - - @Override - protected void onLoginSuccess(int requestId, String sessionId, int apiLevel) { - - ApiRequest aru = new ApiRequest(getApplicationContext()) { - @Override - protected void onPostExecute(JsonElement result) { - if (result != null) { - try { - JsonObject content = result.getAsJsonObject(); - - if (content != null) { - int unread = content.get("unread").getAsInt(); - - ExtensionData updatedData = null; // when null DashClock hides the widget - - if (unread > 0) { - updatedData = new ExtensionData(); - updatedData.visible(true); - - updatedData.icon(R.drawable.dashclock); - updatedData.status(String.valueOf(unread)); - - updatedData.expandedTitle(getString(R.string.n_unread_articles, unread)); - //updatedData.expandedBody(getString(R.string.app_name)); - - updatedData.clickIntent(new Intent().setClassName("org.fox.ttrss", - "org.fox.ttrss.OnlineActivity")); - } - - publishUpdate(updatedData); - - return; - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - } - }; - - final String fSessionId = sessionId; - - HashMap<String, String> umap = new HashMap<String, String>() { - { - put("op", "getUnread"); - put("sid", fSessionId); - } - }; - - aru.execute(umap); - } - - @Override - protected void onLoginFailed(int requestId, ApiRequest ar) { - - } - - @Override - protected void onLoggingIn(int requestId) { - - - } - }; - - String login = m_prefs.getString("login", "").trim(); - String password = m_prefs.getString("password", "").trim(); - - loginManager.logIn(getApplicationContext(), 1, login, password); - } -} diff --git a/src/org/fox/ttrss/DummyFragment.java b/src/org/fox/ttrss/DummyFragment.java deleted file mode 100644 index 7bf799a9..00000000 --- a/src/org/fox/ttrss/DummyFragment.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.fox.ttrss; - -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -public class DummyFragment extends Fragment { - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - View view = inflater.inflate(R.layout.dummy_fragment, container, false); - - return view; - } -} diff --git a/src/org/fox/ttrss/FeedCategoriesFragment.java b/src/org/fox/ttrss/FeedCategoriesFragment.java deleted file mode 100644 index 4439a943..00000000 --- a/src/org/fox/ttrss/FeedCategoriesFragment.java +++ /dev/null @@ -1,547 +0,0 @@ -package org.fox.ttrss; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; - -import org.fox.ttrss.types.Feed; -import org.fox.ttrss.types.FeedCategory; -import org.fox.ttrss.types.FeedCategoryList; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.support.v4.widget.SwipeRefreshLayout; -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.ArrayAdapter; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.TextView; - -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; - -public class FeedCategoriesFragment extends Fragment implements OnItemClickListener, OnSharedPreferenceChangeListener { - private final String TAG = this.getClass().getSimpleName(); - private SharedPreferences m_prefs; - private FeedCategoryListAdapter m_adapter; - private FeedCategoryList m_cats = new FeedCategoryList(); - private FeedCategory m_selectedCat; - private FeedsActivity m_activity; - private SwipeRefreshLayout m_swipeLayout; - - @SuppressLint("DefaultLocale") - class CatUnreadComparator implements Comparator<FeedCategory> { - @Override - public int compare(FeedCategory a, FeedCategory b) { - if (a.unread != b.unread) - return b.unread - a.unread; - else - return a.title.toUpperCase().compareTo(b.title.toUpperCase()); - } - } - - - @SuppressLint("DefaultLocale") - class CatTitleComparator implements Comparator<FeedCategory> { - - @Override - public int compare(FeedCategory a, FeedCategory b) { - if (a.id >= 0 && b.id >= 0) - return a.title.toUpperCase().compareTo(b.title.toUpperCase()); - else - return a.id - b.id; - } - - } - - @SuppressLint("DefaultLocale") - class CatOrderComparator implements Comparator<FeedCategory> { - - @Override - public int compare(FeedCategory a, FeedCategory b) { - if (a.id >= 0 && b.id >= 0) - if (a.order_id != 0 && b.order_id != 0) - return a.order_id - b.order_id; - else - return a.title.toUpperCase().compareTo(b.title.toUpperCase()); - else - return a.id - b.id; - } - - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo) item - .getMenuInfo(); - - switch (item.getItemId()) { - case R.id.browse_articles: - if (true) { - FeedCategory cat = getCategoryAtPosition(info.position); - if (cat != null) { - m_activity.openFeedArticles(new Feed(cat.id, cat.title, true)); - //setSelectedCategory(cat); - } - } - return true; - case R.id.browse_headlines: - if (true) { - FeedCategory cat = getCategoryAtPosition(info.position); - if (cat != null) { - m_activity.onCatSelected(cat, true); - //setSelectedCategory(cat); - } - } - return true; - case R.id.browse_feeds: - if (true) { - FeedCategory cat = getCategoryAtPosition(info.position); - if (cat != null) { - m_activity.onCatSelected(cat, false); - //cf.setSelectedCategory(cat); - } - } - return true; - case R.id.create_shortcut: - if (true) { - FeedCategory cat = getCategoryAtPosition(info.position); - if (cat != null) { - m_activity.createCategoryShortcut(cat); - //cf.setSelectedCategory(cat); - } - } - return true; - case R.id.catchup_category: - if (true) { - final FeedCategory cat = getCategoryAtPosition(info.position); - if (cat != null) { - - if (m_prefs.getBoolean("confirm_headlines_catchup", true)) { - AlertDialog.Builder builder = new AlertDialog.Builder( - m_activity) - .setMessage(getString(R.string.context_confirm_catchup, cat.title)) - .setPositiveButton(R.string.catchup, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - m_activity.catchupFeed(new Feed(cat.id, cat.title, true)); - - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } else { - m_activity.catchupFeed(new Feed(cat.id, cat.title, true)); - } - - } - } - 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) { - - m_activity.getMenuInflater().inflate(R.menu.category_menu, menu); - - AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; - FeedCategory cat = m_adapter.getItem(info.position); - - if (cat != null) - menu.setHeaderTitle(cat.title); - - if (!m_activity.isSmallScreen()) { - menu.findItem(R.id.browse_articles).setVisible(false); - } - - super.onCreateContextMenu(menu, v, menuInfo); - - } - - public FeedCategory getCategoryAtPosition(int position) { - return m_adapter.getItem(position); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - if (savedInstanceState != null) { - m_selectedCat = savedInstanceState.getParcelable("selectedCat"); - m_cats = savedInstanceState.getParcelable("cats"); - } - - View view = inflater.inflate(R.layout.cats_fragment, container, false); - - m_swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.feeds_swipe_container); - - m_swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - refresh(false); - } - }); - - 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); - } - - - ListView list = (ListView)view.findViewById(R.id.feeds); - m_adapter = new FeedCategoryListAdapter(getActivity(), R.layout.feeds_row, (ArrayList<FeedCategory>)m_cats); - list.setAdapter(m_adapter); - list.setOnItemClickListener(this); - registerForContextMenu(list); - - //m_activity.m_pullToRefreshAttacher.addRefreshableView(list, this); - - return view; - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - m_activity = (FeedsActivity)activity; - - m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - m_prefs.registerOnSharedPreferenceChangeListener(this); - - } - - @Override - public void onResume() { - super.onResume(); - - refresh(false); - - m_activity.initMenu(); - } - - @Override - public void onSaveInstanceState (Bundle out) { - super.onSaveInstanceState(out); - - out.setClassLoader(getClass().getClassLoader()); - out.putParcelable("selectedCat", m_selectedCat); - out.putParcelable("cats", m_cats); - } - - /* private void setLoadingStatus(int status, boolean showProgress) { - if (getView() != null) { - TextView tv = (TextView)getView().findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(status); - } - } - - m_activity.setProgressBarIndeterminateVisibility(showProgress); - } */ - - public void refresh(boolean background) { - m_swipeLayout.setRefreshing(true); - - CatsRequest req = new CatsRequest(getActivity().getApplicationContext()); - - final String sessionId = m_activity.getSessionId(); - final boolean unreadOnly = m_activity.getUnreadOnly(); - - if (sessionId != null) { - //m_activity.setLoadingStatus(R.string.blank, true); - //m_activity.setProgressBarVisibility(true); - - @SuppressWarnings("serial") - HashMap<String,String> map = new HashMap<String,String>() { - { - put("op", "getCategories"); - put("sid", sessionId); - put("enable_nested", "true"); - if (unreadOnly) { - put("unread_only", String.valueOf(unreadOnly)); - } - } - }; - - req.execute(map); - } - } - - private class CatsRequest extends ApiRequest { - - public CatsRequest(Context context) { - super(context); - } - - @Override - protected void onProgressUpdate(Integer... progress) { - m_activity.setProgress(Math.round((((float)progress[0] / (float)progress[1]) * 10000))); - } - - @Override - protected void onPostExecute(JsonElement result) { - if (isDetached()) return; - - m_activity.setProgressBarVisibility(false); - m_swipeLayout.setRefreshing(false); - - if (getView() != null) { - ListView list = (ListView)getView().findViewById(R.id.feeds); - - if (list != null) { - list.setEmptyView(getView().findViewById(R.id.no_feeds)); - } - } - - if (result != null) { - try { - JsonArray content = result.getAsJsonArray(); - if (content != null) { - Type listType = new TypeToken<List<FeedCategory>>() {}.getType(); - final List<FeedCategory> cats = new Gson().fromJson(content, listType); - - m_cats.clear(); - - int apiLevel = m_activity.getApiLevel(); - - // virtual cats implemented in getCategories since api level 1 - if (apiLevel == 0) { - m_cats.add(new FeedCategory(-1, "Special", 0)); - m_cats.add(new FeedCategory(-2, "Labels", 0)); - m_cats.add(new FeedCategory(0, "Uncategorized", 0)); - } - - for (FeedCategory c : cats) - m_cats.add(c); - - sortCats(); - - /* if (m_cats.size() == 0) - setLoadingStatus(R.string.no_feeds_to_display, false); - else */ - - //m_adapter.notifyDataSetChanged(); (done by sortCats) - m_activity.setLoadingStatus(R.string.blank, false); - - return; - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (m_lastError == ApiError.LOGIN_FAILED) { - m_activity.login(true); - } else { - m_activity.setLoadingStatus(getErrorMessage(), false); - } - } - - } - - public void sortCats() { - Comparator<FeedCategory> cmp; - - if (m_prefs.getBoolean("sort_feeds_by_unread", false)) { - cmp = new CatUnreadComparator(); - } else { - if (m_activity.getApiLevel() >= 3) { - cmp = new CatOrderComparator(); - } else { - cmp = new CatTitleComparator(); - } - } - - try { - Collections.sort(m_cats, cmp); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } - try { - m_adapter.notifyDataSetChanged(); - } catch (NullPointerException e) { - // adapter missing - } - - } - - private class FeedCategoryListAdapter extends ArrayAdapter<FeedCategory> { - private ArrayList<FeedCategory> items; - - public static final int VIEW_NORMAL = 0; - public static final int VIEW_SELECTED = 1; - - public static final int VIEW_COUNT = VIEW_SELECTED+1; - - public FeedCategoryListAdapter(Context context, int textViewResourceId, ArrayList<FeedCategory> items) { - super(context, textViewResourceId, items); - this.items = items; - } - - public int getViewTypeCount() { - return VIEW_COUNT; - } - - @Override - public int getItemViewType(int position) { - FeedCategory cat = items.get(position); - - if (!m_activity.isSmallScreen() && m_selectedCat != null && cat.id == m_selectedCat.id) { - return VIEW_SELECTED; - } else { - return VIEW_NORMAL; - } - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - - FeedCategory cat = items.get(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(cat.title); - } - - TextView tu = (TextView) v.findViewById(R.id.unread_counter); - - if (tu != null) { - tu.setText(String.valueOf(cat.unread)); - tu.setVisibility((cat.unread > 0) ? View.VISIBLE : View.INVISIBLE); - } - - ImageView icon = (ImageView)v.findViewById(R.id.icon); - - if (icon != null) { - icon.setImageResource(cat.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; - } - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, - String key) { - - sortCats(); - - } - - @Override - public void onItemClick(AdapterView<?> av, View view, int position, long id) { - ListView list = (ListView)av; - - Log.d(TAG, "onItemClick=" + position); - - if (list != null) { - FeedCategory cat = (FeedCategory)list.getItemAtPosition(position); - - if (cat.id < 0) { - m_activity.onCatSelected(cat, false); - } else { - if ("ARTICLES".equals(m_prefs.getString("default_view_mode", "HEADLINES")) && - m_prefs.getBoolean("browse_cats_like_feeds", false)) { - - m_activity.openFeedArticles(new Feed(cat.id, cat.title, true)); - - } else { - m_activity.onCatSelected(cat); - } - } - - //if (!m_activity.isSmallScreen()) - // m_selectedCat = cat; - - m_adapter.notifyDataSetChanged(); - } - } - - public void setSelectedCategory(FeedCategory cat) { - m_selectedCat = cat; - - if (m_adapter != null) { - m_adapter.notifyDataSetChanged(); - } - } - - public FeedCategory getSelectedCategory() { - return m_selectedCat; - } - - /* @Override - public void onRefreshStarted(View view) { - refresh(false); - } */ -} diff --git a/src/org/fox/ttrss/FeedsActivity.java b/src/org/fox/ttrss/FeedsActivity.java deleted file mode 100644 index 90e2c118..00000000 --- a/src/org/fox/ttrss/FeedsActivity.java +++ /dev/null @@ -1,509 +0,0 @@ -package org.fox.ttrss; - - -import java.util.Date; -import java.util.HashMap; - -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; -import org.fox.ttrss.types.Feed; -import org.fox.ttrss.types.FeedCategory; -import org.fox.ttrss.util.AppRater; - -import android.animation.ObjectAnimator; -import android.annotation.SuppressLint; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.os.Handler; -import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentTransaction; -import android.util.Log; -import android.util.TypedValue; -import android.view.MenuItem; -import android.view.Window; -import android.view.WindowManager; -import android.widget.LinearLayout; - -import com.google.gson.JsonElement; -import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; -import com.readystatesoftware.systembartint.SystemBarTintManager; - -public class FeedsActivity extends OnlineActivity implements HeadlinesEventListener { - private final String TAG = this.getClass().getSimpleName(); - - private static final int HEADLINES_REQUEST = 1; - - protected SharedPreferences m_prefs; - protected long m_lastRefresh = 0; - - 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.setMenu(R.layout.feeds); - m_slidingMenu.setSlidingEnabled(true); - - 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; - getSupportActionBar().setDisplayHomeAsUpEnabled(false); - refresh(false); - } - - m_feedIsSelected = false; - initMenu(); - } - }); - } - - if (savedInstanceState == null) { - if (m_slidingMenu != null) - m_slidingMenu.showMenu(); - - final Intent i = getIntent(); - boolean shortcutMode = i.getBooleanExtra("shortcut_mode", false); - - Log.d(TAG, "is_shortcut_mode: " + shortcutMode); - - if (shortcutMode) { - LoginRequest lr = new LoginRequest(this, false, new OnLoginFinishedListener() { - - @Override - public void OnLoginSuccess() { - int feedId = i.getIntExtra("feed_id", 0); - boolean isCat = i.getBooleanExtra("feed_is_cat", false); - String feedTitle = i.getStringExtra("feed_title"); - - Feed tmpFeed = new Feed(feedId, feedTitle, isCat); - - onFeedSelected(tmpFeed); - } - - @Override - public void OnLoginFailed() { - login(); - } - }); - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("op", "login"); - put("user", m_prefs.getString("login", "").trim()); - put("password", m_prefs.getString("password", "").trim()); - } - }; - - lr.execute(map); - } - - //m_pullToRefreshAttacher.setRefreshing(true); - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (m_prefs.getBoolean("enable_cats", false)) { - ft.replace(R.id.feeds_fragment, new FeedCategoriesFragment(), FRAG_CATS); - } else { - ft.replace(R.id.feeds_fragment, new FeedsFragment(), FRAG_FEEDS); - } - - ft.commit(); - - AppRater.appLaunched(this); - checkTrial(true); - - } else { // 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); - } - - if (!isSmallScreen()) { - // temporary hack because FeedsActivity doesn't track whether active feed is open - LinearLayout container = (LinearLayout) findViewById(R.id.fragment_container); - - if (container != null) - container.setWeightSum(3f); - } - - } - - /* if (!isCompatMode() && !isSmallScreen()) { - ((ViewGroup)findViewById(R.id.headlines_fragment)).setLayoutTransition(new LayoutTransition()); - ((ViewGroup)findViewById(R.id.feeds_fragment)).setLayoutTransition(new LayoutTransition()); - } */ - - } - - @Override - protected void initMenu() { - super.initMenu(); - - if (m_menu != null && getSessionId() != null) { - Fragment ff = getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - Fragment cf = getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - HeadlinesFragment hf = (HeadlinesFragment)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.update_headlines).setVisible(false); - } - - 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 onFeedSelected(Feed feed) { - GlobalState.getInstance().m_loadedArticles.clear(); - //m_pullToRefreshAttacher.setRefreshing(true); - - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - ft.replace(R.id.headlines_fragment, new LoadingFragment(), null); - ft.commit(); - - if (!isCompatMode() && !isSmallScreen()) { - LinearLayout container = (LinearLayout) findViewById(R.id.fragment_container); - if (container != null) { - float wSum = container.getWeightSum(); - if (wSum <= 2.0f) { - ObjectAnimator anim = ObjectAnimator.ofFloat(container, "weightSum", wSum, 3.0f); - anim.setDuration(200); - anim.start(); - } - } - } - - final Feed fFeed = feed; - - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - HeadlinesFragment hf = new HeadlinesFragment(); - hf.initialize(fFeed); - 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); - - - Date date = new Date(); - - if (date.getTime() - m_lastRefresh > 10000) { - m_lastRefresh = date.getTime(); - refresh(false); - } - } - - public void onCatSelected(FeedCategory cat, boolean openAsFeed) { - FeedCategoriesFragment fc = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - - //m_pullToRefreshAttacher.setRefreshing(true); - - if (!openAsFeed) { - - if (fc != null) { - fc.setSelectedCategory(null); - } - - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - FeedsFragment ff = new FeedsFragment(); - ff.initialize(cat); - ft.replace(R.id.feeds_fragment, ff, FRAG_FEEDS); - - ft.addToBackStack(null); - ft.commit(); - - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - m_actionbarUpEnabled = true; - m_actionbarRevertDepth = m_actionbarRevertDepth + 1; - - } else { - - if (fc != null) { - fc.setSelectedCategory(cat); - } - - Feed feed = new Feed(cat.id, cat.title, true); - onFeedSelected(feed); - } - } - - public void onCatSelected(FeedCategory cat) { - onCatSelected(cat, m_prefs.getBoolean("browse_cats_like_feeds", false)); - } - - @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; - case R.id.update_feeds: - //m_pullToRefreshAttacher.setRefreshing(true); - refresh(); - return true; - default: - Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId()); - return super.onOptionsItemSelected(item); - } - } - - @Override - protected void loginSuccess(boolean refresh) { - setLoadingStatus(R.string.blank, false); - //findViewById(R.id.loading_container).setVisibility(View.GONE); - initMenu(); - - if (refresh) refresh(); - } - - @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); - } - - @Override - public void onResume() { - super.onResume(); - initMenu(); - } - - @Override - public void onArticleListSelectionChange(ArticleList m_selectedArticles) { - initMenu(); - } - - public void openFeedArticles(Feed feed) { - GlobalState.getInstance().m_loadedArticles.clear(); - - Intent intent = new Intent(FeedsActivity.this, HeadlinesActivity.class); - intent.putExtra("feed", feed); - intent.putExtra("article", (Article)null); - intent.putExtra("searchQuery", (String)null); - - startActivityForResult(intent, HEADLINES_REQUEST); - overridePendingTransition(R.anim.right_slide_in, 0); - } - - public void onArticleSelected(Article article, boolean open) { - if (article.unread) { - article.unread = false; - saveArticleUnread(article); - } - - if (open) { - HeadlinesFragment hf = (HeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - - Intent intent = new Intent(FeedsActivity.this, HeadlinesActivity.class); - intent.putExtra("feed", hf.getFeed()); - intent.putExtra("article", article); - intent.putExtra("searchQuery", hf.getSearchQuery()); - - startActivityForResult(intent, HEADLINES_REQUEST); - overridePendingTransition(R.anim.right_slide_in, 0); - - } else { - initMenu(); - } - } - - @Override - public void onArticleSelected(Article article) { - onArticleSelected(article, true); - } - - public void catchupFeed(final Feed feed) { - super.catchupFeed(feed); - refresh(); - } - - @Override - public void onHeadlinesLoaded(boolean appended) { - // TODO Auto-generated method stub - - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == HEADLINES_REQUEST) { - GlobalState.getInstance().m_activeArticle = null; - } - } - - public void createFeedShortcut(Feed feed) { - final Intent shortcutIntent = new Intent(this, FeedsActivity.class); - shortcutIntent.putExtra("feed_id", feed.id); - shortcutIntent.putExtra("feed_is_cat", feed.is_cat); - shortcutIntent.putExtra("feed_title", feed.title); - shortcutIntent.putExtra("shortcut_mode", true); - - Intent intent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT"); - - intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, feed.title); - intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); - intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(this, R.drawable.icon)); - intent.putExtra("duplicate", false); - - sendBroadcast(intent); - - toast(R.string.shortcut_has_been_placed_on_the_home_screen); - } - - public void createCategoryShortcut(FeedCategory cat) { - createFeedShortcut(new Feed(cat.id, cat.title, true)); - } - - public void unsubscribeFeed(final Feed feed) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - refresh(); - } - }; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "unsubscribeFeed"); - put("feed_id", String.valueOf(feed.id)); - } - }; - - req.execute(map); - - } -} diff --git a/src/org/fox/ttrss/FeedsFragment.java b/src/org/fox/ttrss/FeedsFragment.java deleted file mode 100644 index 7c974809..00000000 --- a/src/org/fox/ttrss/FeedsFragment.java +++ /dev/null @@ -1,808 +0,0 @@ -package org.fox.ttrss; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.lang.reflect.Type; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; - -import org.fox.ttrss.types.Feed; -import org.fox.ttrss.types.FeedCategory; -import org.fox.ttrss.types.FeedList; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.net.http.AndroidHttpClient; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.support.v4.widget.SwipeRefreshLayout; -import android.util.Base64; -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.ArrayAdapter; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.TextView; - -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; - -public class FeedsFragment extends Fragment implements OnItemClickListener, OnSharedPreferenceChangeListener { - private final String TAG = this.getClass().getSimpleName(); - private SharedPreferences m_prefs; - private FeedListAdapter m_adapter; - private FeedList m_feeds = new FeedList(); - private FeedsActivity m_activity; - private Feed m_selectedFeed; - private FeedCategory m_activeCategory; - private static final String ICON_PATH = "/icons/"; - private boolean m_enableFeedIcons; - private boolean m_feedIconsChecked = false; - private SwipeRefreshLayout m_swipeLayout; - - public void initialize(FeedCategory cat) { - m_activeCategory = cat; - } - - @SuppressLint("DefaultLocale") - class FeedUnreadComparator implements Comparator<Feed> { - - @Override - public int compare(Feed a, Feed b) { - if (a.unread != b.unread) - return b.unread - a.unread; - else - return a.title.toUpperCase().compareTo(b.title.toUpperCase()); - } - - } - - - @SuppressLint("DefaultLocale") - class FeedTitleComparator implements Comparator<Feed> { - - @Override - public int compare(Feed a, Feed b) { - if (a.is_cat && b.is_cat) - return a.title.toUpperCase().compareTo(b.title.toUpperCase()); - else if (a.is_cat && !b.is_cat) - return -1; - else if (!a.is_cat && b.is_cat) - return 1; - else if (a.id >= 0 && b.id >= 0) - return a.title.toUpperCase().compareTo(b.title.toUpperCase()); - else - return a.id - b.id; - } - - } - - @SuppressLint("DefaultLocale") - class FeedOrderComparator implements Comparator<Feed> { - - @Override - public int compare(Feed a, Feed b) { - if (a.id >= 0 && b.id >= 0) - if (a.is_cat && b.is_cat) - return a.title.toUpperCase().compareTo(b.title.toUpperCase()); - else if (a.is_cat && !b.is_cat) - return -1; - else if (!a.is_cat && b.is_cat) - return 1; - else if (a.order_id != 0 && b.order_id != 0) - return a.order_id - b.order_id; - else - return a.title.toUpperCase().compareTo(b.title.toUpperCase()); - else - return a.id - b.id; - } - - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo) item - .getMenuInfo(); - switch (item.getItemId()) { - case R.id.browse_articles: - if (true) { - Feed feed = getFeedAtPosition(info.position); - if (feed != null) { - m_activity.openFeedArticles(feed); - } - } - return true; - case R.id.browse_headlines: - if (true) { - Feed feed = getFeedAtPosition(info.position); - if (feed != null) { - m_activity.onFeedSelected(feed); - } - } - return true; - case R.id.browse_feeds: - if (true) { - Feed feed = getFeedAtPosition(info.position); - if (feed != null) { - m_activity.onCatSelected(new FeedCategory(feed.id, feed.title, feed.unread), false); - } - } - return true; - case R.id.unsubscribe_feed: - if (true) { - final Feed feed = getFeedAtPosition(info.position); - - AlertDialog.Builder builder = new AlertDialog.Builder( - m_activity) - .setMessage(getString(R.string.unsubscribe_from_prompt, feed.title)) - .setPositiveButton(R.string.unsubscribe, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - m_activity.unsubscribeFeed(feed); - - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } - - return true; - case R.id.create_shortcut: - if (true) { - Feed feed = getFeedAtPosition(info.position); - if (feed != null) { - m_activity.createFeedShortcut(feed); - } - } - return true; - case R.id.catchup_feed: - if (true) { - final Feed feed = getFeedAtPosition(info.position); - - if (feed != null) { - if (m_prefs.getBoolean("confirm_headlines_catchup", true)) { - AlertDialog.Builder builder = new AlertDialog.Builder( - m_activity) - .setMessage(getString(R.string.context_confirm_catchup, feed.title)) - .setPositiveButton(R.string.catchup, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - m_activity.catchupFeed(feed); - - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } else { - m_activity.catchupFeed(feed); - } - } - } - 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; - Feed feed = m_adapter.getItem(info.position); - - if (feed != null) - menu.setHeaderTitle(feed.title); - - if (!m_activity.isSmallScreen()) { - menu.findItem(R.id.browse_articles).setVisible(false); - } - - if (!feed.is_cat) { - menu.findItem(R.id.browse_feeds).setVisible(false); - } - - if (feed.id <= 0) { - menu.findItem(R.id.unsubscribe_feed).setVisible(false); - } - - super.onCreateContextMenu(menu, v, menuInfo); - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - if (savedInstanceState != null) { - m_selectedFeed = savedInstanceState.getParcelable("selectedFeed"); - m_feeds = savedInstanceState.getParcelable("feeds"); - m_feedIconsChecked = savedInstanceState.getBoolean("feedIconsChecked"); - m_activeCategory = savedInstanceState.getParcelable("activeCat"); - } - - View view = inflater.inflate(R.layout.feeds_fragment, container, false); - - m_swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.feeds_swipe_container); - - m_swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - refresh(false); - } - }); - - 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); - } - - ListView list = (ListView)view.findViewById(R.id.feeds); - m_adapter = new FeedListAdapter(getActivity(), R.layout.feeds_row, (ArrayList<Feed>)m_feeds); - list.setAdapter(m_adapter); - //list.setEmptyView(view.findViewById(R.id.no_feeds)); - list.setOnItemClickListener(this); - - registerForContextMenu(list); - - m_enableFeedIcons = m_prefs.getBoolean("download_feed_icons", false); - - //Log.d(TAG, "mpTRA=" + m_activity.m_pullToRefreshAttacher); - //m_activity.m_pullToRefreshAttacher.addRefreshableView(list, this); - - return view; - } - - @Override - public void onDestroy() { - super.onDestroy(); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - m_prefs.registerOnSharedPreferenceChangeListener(this); - - m_activity = (FeedsActivity)activity; - - } - - @Override - public void onResume() { - super.onResume(); - - refresh(false); - - m_activity.initMenu(); - } - - @Override - public void onSaveInstanceState (Bundle out) { - super.onSaveInstanceState(out); - - out.setClassLoader(getClass().getClassLoader()); - out.putParcelable("selectedFeed", m_selectedFeed); - out.putParcelable("feeds", m_feeds); - out.putBoolean("feedIconsChecked", m_feedIconsChecked); - out.putParcelable("activeCat", m_activeCategory); - } - - @Override - public void onItemClick(AdapterView<?> av, View view, int position, long id) { - ListView list = (ListView)av; - - if (list != null) { - Feed feed = (Feed)list.getItemAtPosition(position); - - if (feed.is_cat) { - if (m_activity.isSmallScreen() && "ARTICLES".equals(m_prefs.getString("default_view_mode", "HEADLINES")) && - m_prefs.getBoolean("browse_cats_like_feeds", false)) { - - m_activity.openFeedArticles(feed); - - } else { - m_activity.onCatSelected(new FeedCategory(feed.id, feed.title, feed.unread)); - } - } else { - if ("ARTICLES".equals(m_prefs.getString("default_view_mode", "HEADLINES"))) { - m_activity.openFeedArticles(feed); - } else { - m_activity.onFeedSelected(feed); - } - } - - if (!m_activity.isSmallScreen()) - m_selectedFeed = feed; - - m_adapter.notifyDataSetChanged(); - } - } - - @SuppressWarnings({ "serial" }) - public void refresh(boolean background) { - //FeedCategory cat = m_onlineServices.getActiveCategory(); - - m_swipeLayout.setRefreshing(true); - - final int catId = (m_activeCategory != null) ? m_activeCategory.id : -4; - - final String sessionId = m_activity.getSessionId(); - final boolean unreadOnly = m_activity.getUnreadOnly(); - - FeedsRequest req = new FeedsRequest(getActivity().getApplicationContext(), catId); - - if (sessionId != null) { - //m_activity.setLoadingStatus(R.string.blank, true); - //m_activity.setProgressBarVisibility(true); - - HashMap<String,String> map = new HashMap<String,String>() { - { - put("op", "getFeeds"); - put("sid", sessionId); - put("include_nested", "true"); - put("cat_id", String.valueOf(catId)); - if (unreadOnly) { - put("unread_only", String.valueOf(unreadOnly)); - } - } - }; - - req.execute(map); - - } - } - - /* private void setLoadingStatus(int status, boolean showProgress) { - if (getView() != null) { - TextView tv = (TextView)getView().findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(status); - } - } - - if (getActivity() != null) - getActivity().setProgressBarIndeterminateVisibility(showProgress); - } */ - - @SuppressWarnings({ "serial" }) - public void getFeedIcons() { - - ApiRequest req = new ApiRequest(getActivity().getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - if (isDetached()) return; - - if (result != null) { - - try { - JsonElement iconsUrl = result.getAsJsonObject().get("icons_dir"); - - if (iconsUrl != null) { - String iconsStr = iconsUrl.getAsString(); - String baseUrl = ""; - - if (!iconsStr.contains("://")) { - baseUrl = m_prefs.getString("ttrss_url", "").trim() + "/" + iconsStr; - } else { - baseUrl = iconsStr; - } - - GetIconsTask git = new GetIconsTask(baseUrl); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) - git.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, m_feeds); - else - git.execute(m_feeds); - - m_feedIconsChecked = true; - } - } catch (Exception e) { - Log.d(TAG, "Error receiving icons configuration"); - e.printStackTrace(); - } - - } - } - }; - - final String sessionId = m_activity.getSessionId(); - - HashMap<String,String> map = new HashMap<String,String>() { - { - put("sid", sessionId); - put("op", "getConfig"); - } - }; - - req.execute(map); - } - - private class FeedsRequest extends ApiRequest { - private int m_catId; - - public FeedsRequest(Context context, int catId) { - super(context); - m_catId = catId; - } - - @Override - protected void onProgressUpdate(Integer... progress) { - m_activity.setProgress(Math.round((((float)progress[0] / (float)progress[1]) * 10000))); - } - - @Override - protected void onPostExecute(JsonElement result) { - if (isDetached()) return; - - if (getView() != null) { - ListView list = (ListView)getView().findViewById(R.id.feeds); - - if (list != null) { - list.setEmptyView(getView().findViewById(R.id.no_feeds)); - } - } - - m_activity.setProgressBarVisibility(false); - //m_activity.m_pullToRefreshAttacher.setRefreshComplete(); - m_swipeLayout.setRefreshing(false); - - if (result != null) { - try { - JsonArray content = result.getAsJsonArray(); - if (content != null) { - - Type listType = new TypeToken<List<Feed>>() {}.getType(); - final List<Feed> feeds = new Gson().fromJson(content, listType); - - m_feeds.clear(); - - for (Feed f : feeds) - if (f.id > -10 || m_catId != -4) // skip labels for flat feedlist for now - m_feeds.add(f); - - sortFeeds(); - - /*if (m_feeds.size() == 0) - setLoadingStatus(R.string.no_feeds_to_display, false); - else */ - - m_activity.setLoadingStatus(R.string.blank, false); - //m_adapter.notifyDataSetChanged(); (done by sortFeeds) - - if (m_enableFeedIcons && !m_feedIconsChecked && Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) - getFeedIcons(); - - return; - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (m_lastError == ApiError.LOGIN_FAILED) { - m_activity.login(true); - } else { - m_activity.setLoadingStatus(getErrorMessage(), false); - } - } - } - - private class FeedListAdapter extends ArrayAdapter<Feed> { - private ArrayList<Feed> items; - - public static final int VIEW_NORMAL = 0; - public static final int VIEW_SELECTED = 1; - - public static final int VIEW_COUNT = VIEW_SELECTED+1; - - public FeedListAdapter(Context context, int textViewResourceId, ArrayList<Feed> items) { - super(context, textViewResourceId, items); - this.items = items; - } - - public int getViewTypeCount() { - return VIEW_COUNT; - } - - @Override - public int getItemViewType(int position) { - Feed feed = items.get(position); - - if (!m_activity.isSmallScreen() && m_selectedFeed != null && feed.id == m_selectedFeed.id) { - return VIEW_SELECTED; - } else { - return VIEW_NORMAL; - } - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - - Feed feed = items.get(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(feed.title); - } - - TextView tu = (TextView) v.findViewById(R.id.unread_counter); - - if (tu != null) { - tu.setText(String.valueOf(feed.unread)); - tu.setVisibility((feed.unread > 0) ? View.VISIBLE : View.INVISIBLE); - } - - ImageView icon = (ImageView)v.findViewById(R.id.icon); - - if (icon != null) { - - if (m_enableFeedIcons) { - - try { - File storage = m_activity.getExternalCacheDir(); - - File iconFile = new File(storage.getAbsolutePath() + ICON_PATH + feed.id + ".ico"); - if (iconFile.exists()) { - Bitmap bmpOrig = BitmapFactory.decodeFile(iconFile.getAbsolutePath()); - if (bmpOrig != null) { - icon.setImageBitmap(bmpOrig); - } - } else { - icon.setImageResource(feed.unread > 0 ? R.drawable.ic_published : R.drawable.ic_unpublished); - } - } catch (NullPointerException e) { - icon.setImageResource(feed.unread > 0 ? R.drawable.ic_published : R.drawable.ic_unpublished); - } - - } else { - icon.setImageResource(feed.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() { - Comparator<Feed> cmp; - - if (m_prefs.getBoolean("sort_feeds_by_unread", false)) { - cmp = new FeedUnreadComparator(); - } else { - if (m_activity.getApiLevel() >= 3) { - cmp = new FeedOrderComparator(); - } else { - cmp = new FeedTitleComparator(); - } - } - - try { - Collections.sort(m_feeds, cmp); - } catch (IllegalArgumentException e) { - // sort order got changed in prefs or something - e.printStackTrace(); - } - - try { - m_adapter.notifyDataSetChanged(); - } catch (NullPointerException e) { - // adapter missing - } - } - - public class GetIconsTask extends AsyncTask<FeedList, Integer, Integer> { - - private String m_baseUrl; - - public GetIconsTask(String baseUrl) { - m_baseUrl = baseUrl.trim(); - } - - @Override - protected Integer doInBackground(FeedList... params) { - - FeedList localList = new FeedList(); - - try { - localList.addAll(params[0]); - - File storage = m_activity.getExternalCacheDir(); - final File iconPath = new File(storage.getAbsolutePath() + ICON_PATH); - if (!iconPath.exists()) iconPath.mkdirs(); - - if (iconPath.exists()) { - for (Feed feed : localList) { - if (feed.id > 0 && feed.has_icon && !feed.is_cat) { - File outputFile = new File(iconPath.getAbsolutePath() + "/" + feed.id + ".ico"); - String fetchUrl = m_baseUrl + "/" + feed.id + ".ico"; - - if (!outputFile.exists()) { - downloadFile(fetchUrl, outputFile.getAbsolutePath()); - Thread.sleep(2000); - } - } - } - } - } catch (Exception e) { - Log.d(TAG, "Error while downloading feed icons"); - e.printStackTrace(); - } - return null; - } - - protected void downloadFile(String fetchUrl, String outputFile) { - AndroidHttpClient client = AndroidHttpClient.newInstance("Tiny Tiny RSS"); - - /* ApiRequest.disableConnectionReuseIfNecessary(); */ - - /* ApiRequest.trustAllHosts(m_prefs.getBoolean("ssl_trust_any", false), - m_prefs.getBoolean("ssl_trust_any_host", false)); */ - - try { - URL url = new URL(fetchUrl); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - - conn.setConnectTimeout(1000); - conn.setReadTimeout(5000); - - Log.d(TAG, "[downloadFile] " + url); - - String httpLogin = m_prefs.getString("http_login", ""); - String httpPassword = m_prefs.getString("http_password", ""); - - if (httpLogin.length() > 0) { - conn.setRequestProperty("Authorization", "Basic " + - Base64.encodeToString((httpLogin + ":" + httpPassword).getBytes("UTF-8"), Base64.NO_WRAP)); - } - - InputStream content = conn.getInputStream(); - - BufferedInputStream is = new BufferedInputStream(content, 1024); - FileOutputStream fos = new FileOutputStream(outputFile); - - byte[] buffer = new byte[1024]; - int len = 0; - while ((len = is.read(buffer)) != -1) { - fos.write(buffer, 0, len); - } - - fos.close(); - is.close(); - - } catch (Exception e) { - e.printStackTrace(); - } - - client.close(); - } - - protected void onPostExecute(Integer result) { - if (isDetached()) return; - - m_adapter.notifyDataSetChanged(); - } - - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, - String key) { - - sortFeeds(); - m_enableFeedIcons = m_prefs.getBoolean("download_feed_icons", false); - - } - - public Feed getFeedAtPosition(int position) { - try { - return m_adapter.getItem(position); - } catch (IndexOutOfBoundsException e) { - return null; - } - } - - public Feed getSelectedFeed() { - return m_selectedFeed; - } - - public void setSelectedFeed(Feed feed) { - m_selectedFeed = feed; - - if (m_adapter != null) { - m_adapter.notifyDataSetChanged(); - } - } - - /* @Override - public void onRefreshStarted(View view) { - refresh(false); - } */ - -} diff --git a/src/org/fox/ttrss/GlobalState.java b/src/org/fox/ttrss/GlobalState.java deleted file mode 100644 index 6f81fc5d..00000000 --- a/src/org/fox/ttrss/GlobalState.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.fox.ttrss; - -import java.util.ArrayList; - -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; -import org.fox.ttrss.types.Feed; - -import android.app.Application; -import android.os.Bundle; -import android.os.Parcelable; - -public class GlobalState extends Application { - private static GlobalState m_singleton; - - public ArticleList m_loadedArticles = new ArticleList(); - public Feed m_activeFeed; - public Article m_activeArticle; - public int m_selectedArticleId; - public String m_sessionId; - public int m_apiLevel; - public boolean m_canUseProgress; - - public static GlobalState getInstance(){ - return m_singleton; - } - - @Override - public final void onCreate() { - super.onCreate(); - m_singleton = this; - } - - public void save(Bundle out) { - - out.setClassLoader(getClass().getClassLoader()); - out.putParcelableArrayList("gs:loadedArticles", m_loadedArticles); - out.putParcelable("gs:activeFeed", m_activeFeed); - out.putParcelable("gs:activeArticle", m_activeArticle); - out.putString("gs:sessionId", m_sessionId); - out.putInt("gs:apiLevel", m_apiLevel); - out.putBoolean("gs:canUseProgress", m_canUseProgress); - out.putInt("gs:selectedArticleId", m_selectedArticleId); - } - - public void load(Bundle in) { - if (m_loadedArticles.size() == 0 && in != null) { - ArrayList<Parcelable> list = in.getParcelableArrayList("gs:loadedArticles"); - - for (Parcelable p : list) { - m_loadedArticles.add((Article)p); - } - - m_activeFeed = (Feed) in.getParcelable("gs:activeFeed"); - m_activeArticle = (Article) in.getParcelable("gs:activeArticle"); - m_sessionId = in.getString("gs:sessionId"); - m_apiLevel = in.getInt("gs:apiLevel"); - m_canUseProgress = in.getBoolean("gs:canUseProgress"); - m_selectedArticleId = in.getInt("gs:selectedArticleId"); - } - - } -} diff --git a/src/org/fox/ttrss/HeadlinesActivity.java b/src/org/fox/ttrss/HeadlinesActivity.java deleted file mode 100644 index c4e0f0cc..00000000 --- a/src/org/fox/ttrss/HeadlinesActivity.java +++ /dev/null @@ -1,281 +0,0 @@ -package org.fox.ttrss; - -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; -import org.fox.ttrss.types.Feed; - -import android.annotation.SuppressLint; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.os.Handler; -import android.preference.PreferenceManager; -import android.support.v4.app.FragmentTransaction; -import android.util.Log; -import android.view.MenuItem; -import android.view.View; - -public class HeadlinesActivity extends OnlineActivity implements HeadlinesEventListener { - 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); - - GlobalState.getInstance().load(savedInstanceState); - - 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) { - boolean shortcutMode = i.getBooleanExtra("shortcut_mode", false); - - Log.d(TAG, "is_shortcut_mode: " + shortcutMode); - - Feed tmpFeed; - - if (shortcutMode) { - int feedId = i.getIntExtra("feed_id", 0); - boolean isCat = i.getBooleanExtra("feed_is_cat", false); - String feedTitle = i.getStringExtra("feed_title"); - - tmpFeed = new Feed(feedId, feedTitle, isCat); - - GlobalState.getInstance().m_loadedArticles.clear(); - } else { - tmpFeed = i.getParcelableExtra("feed"); - } - - final Feed feed = tmpFeed; - - final Article article = i.getParcelableExtra("article"); - final String searchQuery = i.getStringExtra("searchQuery"); - - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - ft.replace(R.id.headlines_fragment, new LoadingFragment(), null); - ft.replace(R.id.article_fragment, new LoadingFragment(), null); - - ft.commit(); - - setTitle(feed.title); - - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - HeadlinesFragment hf = new HeadlinesFragment(); - hf.initialize(feed, article); - hf.setSearchQuery(searchQuery); - - ArticlePager af = new ArticlePager(); - af.initialize(article != null ? hf.getArticleById(article.id) : new Article(), feed); - af.setSearchQuery(searchQuery); - - ft.replace(R.id.headlines_fragment, hf, FRAG_HEADLINES); - ft.replace(R.id.article_fragment, af, FRAG_ARTICLE); - - ft.commit(); - } - }, 25); - - } - } - - /* if (!isCompatMode()) { - ((ViewGroup)findViewById(R.id.headlines_fragment)).setLayoutTransition(new LayoutTransition()); - ((ViewGroup)findViewById(R.id.article_fragment)).setLayoutTransition(new LayoutTransition()); - } */ - } - - @Override - protected void refresh() { - super.refresh(); - - - } - - @Override - protected void loginSuccess(boolean refresh) { - Log.d(TAG, "loginSuccess"); - - setLoadingStatus(R.string.blank, false); - findViewById(R.id.loading_container).setVisibility(View.GONE); - - initMenu(); - - if (refresh) refresh(); - } - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - GlobalState.getInstance().save(out); - } - - @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 onResume() { - super.onResume(); - } - - @Override - protected void initMenu() { - super.initMenu(); - - if (m_menu != null && getSessionId() != null) { - m_menu.setGroupVisible(R.id.menu_group_feeds, false); - - //HeadlinesFragment hf = (HeadlinesFragment)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()); - - ArticlePager af = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - - m_menu.setGroupVisible(R.id.menu_group_article, af != null); - - if (af != null) { - if (af.getSelectedArticle() != null && af.getSelectedArticle().attachments != null && af.getSelectedArticle().attachments.size() > 0) { - if (!isCompatMode() && (isSmallScreen() || !isPortrait())) { - m_menu.findItem(R.id.toggle_attachments).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - } - m_menu.findItem(R.id.toggle_attachments).setVisible(true); - } else { - if (!isCompatMode()) { - m_menu.findItem(R.id.toggle_attachments).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); - } - m_menu.findItem(R.id.toggle_attachments).setVisible(false); - } - } - - m_menu.findItem(R.id.search).setVisible(false); - } - } - - @Override - public void onArticleListSelectionChange(ArticleList m_selectedArticles) { - initMenu(); - } - - @Override - public void onArticleSelected(Article article) { - onArticleSelected(article, true); - } - - @Override - public void onArticleSelected(Article article, boolean open) { - - if (article == null) return; - - if (article.unread) { - article.unread = false; - saveArticleUnread(article); - } - - if (open) { - - final Article fArticle = article; - - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - ArticlePager af = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - - if (af != null) { - af.setActiveArticle(fArticle); - } - } - }, 10); - - } else { - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - if (hf != null) { - hf.setActiveArticle(article); - } - } - - GlobalState.getInstance().m_activeArticle = article; - - initMenu(); - - } - - @Override - public void onHeadlinesLoaded(boolean appended) { - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - - if (hf != null) { - Article article = hf.getActiveArticle(); - - if (article == null && hf.getAllArticles().size() > 0) { - article = hf.getAllArticles().get(0); - - hf.setActiveArticle(article); - - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - ft.replace(R.id.article_fragment, new LoadingFragment(), null); - - ft.commitAllowingStateLoss(); - - final Article fArticle = article; - final Feed fFeed = hf.getFeed(); - - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - FragmentTransaction ft = getSupportFragmentManager() - .beginTransaction(); - - ArticlePager af = new ArticlePager(); - af.initialize(fArticle, fFeed); - - ft.replace(R.id.article_fragment, af, FRAG_ARTICLE); - ft.commitAllowingStateLoss(); - } - }, 10); - } - } - } - - @Override - public void onBackPressed() { - super.onBackPressed(); - overridePendingTransition(0, R.anim.right_slide_out); - } -} diff --git a/src/org/fox/ttrss/HeadlinesEventListener.java b/src/org/fox/ttrss/HeadlinesEventListener.java deleted file mode 100644 index 5494bb2b..00000000 --- a/src/org/fox/ttrss/HeadlinesEventListener.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.fox.ttrss; - -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; - -public interface HeadlinesEventListener { - void onArticleListSelectionChange(ArticleList m_selectedArticles); - void onArticleSelected(Article article); - void onArticleSelected(Article article, boolean open); - void onHeadlinesLoaded(boolean appended); -} diff --git a/src/org/fox/ttrss/HeadlinesFragment.java b/src/org/fox/ttrss/HeadlinesFragment.java deleted file mode 100644 index 32670252..00000000 --- a/src/org/fox/ttrss/HeadlinesFragment.java +++ /dev/null @@ -1,1179 +0,0 @@ -package org.fox.ttrss; - -import java.net.MalformedURLException; -import java.net.URL; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.TimeZone; - -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; -import org.fox.ttrss.types.Feed; -import org.fox.ttrss.util.HeadlinesRequest; -import org.fox.ttrss.util.TypefaceCache; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; - -import android.animation.ObjectAnimator; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Resources.Theme; -import android.graphics.Bitmap; -import android.graphics.Paint; -import android.graphics.Typeface; -import android.net.Uri; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.provider.OpenableColumns; -import android.support.v4.app.Fragment; -import android.support.v4.widget.SwipeRefreshLayout; -import android.text.Html; -import android.util.DisplayMetrics; -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.AbsListView; -import android.widget.AbsListView.OnScrollListener; -import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ArrayAdapter; -import android.widget.CheckBox; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.TextView; - -import com.google.gson.JsonElement; -import com.nostra13.universalimageloader.core.DisplayImageOptions; -import com.nostra13.universalimageloader.core.ImageLoader; -import com.nostra13.universalimageloader.core.assist.FailReason; -import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; - -public class HeadlinesFragment extends Fragment implements OnItemClickListener, OnScrollListener { - public static enum ArticlesSelection { ALL, NONE, UNREAD }; - - public static final int HEADLINES_REQUEST_SIZE = 30; - public static final int HEADLINES_BUFFER_MAX = 500; - - private final String TAG = this.getClass().getSimpleName(); - - private Feed m_feed; - private Article m_activeArticle; - private String m_searchQuery = ""; - private boolean m_refreshInProgress = false; - private boolean m_autoCatchupDisabled = false; - - private SharedPreferences m_prefs; - - private ArticleListAdapter m_adapter; - private ArticleList m_articles = GlobalState.getInstance().m_loadedArticles; - private ArticleList m_selectedArticles = new ArticleList(); - private ArticleList m_readArticles = new ArticleList(); - private HeadlinesEventListener m_listener; - private OnlineActivity m_activity; - private SwipeRefreshLayout m_swipeLayout; - private int m_maxImageSize = 0; - - public ArticleList getSelectedArticles() { - return m_selectedArticles; - } - - public void initialize(Feed feed) { - m_feed = feed; - } - - public void initialize(Feed feed, Article activeArticle) { - m_feed = feed; - - if (activeArticle != null) { - m_activeArticle = getArticleById(activeArticle.id); - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo) item - .getMenuInfo(); - - switch (item.getItemId()) { - case R.id.set_labels: - if (true) { - Article article = getArticleAtPosition(info.position); - - if (article != null) { - if (m_activity.getApiLevel() != 7) { - m_activity.editArticleLabels(article); - } else { - m_activity.toast(R.string.server_function_not_available); - } - } - } - return true; - case R.id.article_set_note: - if (true) { - Article article = getArticleAtPosition(info.position); - - if (article != null) { - m_activity.editArticleNote(article); - } - } - return true; - - case R.id.headlines_article_link_copy: - if (true) { - Article article = getArticleAtPosition(info.position); - - if (article != null) { - m_activity.copyToClipboard(article.link); - } - } - return true; - case R.id.headlines_article_link_open: - if (true) { - Article article = getArticleAtPosition(info.position); - - if (article != null) { - Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(article.link)); - startActivity(browserIntent); - - if (article.unread) { - article.unread = false; - m_activity.saveArticleUnread(article); - } - } - } - return true; - case R.id.selection_toggle_marked: - if (true) { - ArticleList selected = getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.marked = !a.marked; - - m_activity.toggleArticlesMarked(selected); - //updateHeadlines(); - } else { - Article article = getArticleAtPosition(info.position); - if (article != null) { - article.marked = !article.marked; - m_activity.saveArticleMarked(article); - //updateHeadlines(); - } - } - m_adapter.notifyDataSetChanged(); - } - return true; - case R.id.selection_toggle_published: - if (true) { - ArticleList selected = getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.published = !a.published; - - m_activity.toggleArticlesPublished(selected); - //updateHeadlines(); - } else { - Article article = getArticleAtPosition(info.position); - if (article != null) { - article.published = !article.published; - m_activity.saveArticlePublished(article); - //updateHeadlines(); - } - } - m_adapter.notifyDataSetChanged(); - } - return true; - case R.id.selection_toggle_unread: - if (true) { - ArticleList selected = getSelectedArticles(); - - if (selected.size() > 0) { - for (Article a : selected) - a.unread = !a.unread; - - m_activity.toggleArticlesUnread(selected); - //updateHeadlines(); - } else { - Article article = getArticleAtPosition(info.position); - if (article != null) { - article.unread = !article.unread; - m_activity.saveArticleUnread(article); - //updateHeadlines(); - } - } - m_adapter.notifyDataSetChanged(); - } - return true; - case R.id.headlines_share_article: - if (true) { - Article article = getArticleAtPosition(info.position); - if (article != null) - m_activity.shareArticle(article); - } - return true; - case R.id.catchup_above: - if (true) { - Article article = getArticleAtPosition(info.position); - if (article != null) { - 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, "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 (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; - Article article = getArticleAtPosition(info.position); - menu.setHeaderTitle(Html.fromHtml(article.title)); - menu.setGroupVisible(R.id.menu_group_single_article, true); - } - - menu.findItem(R.id.set_labels).setEnabled(m_activity.getApiLevel() >= 1); - menu.findItem(R.id.article_set_note).setEnabled(m_activity.getApiLevel() >= 1); - - super.onCreateContextMenu(menu, v, menuInfo); - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - if (savedInstanceState != null) { - m_feed = savedInstanceState.getParcelable("feed"); - //m_articles = savedInstanceState.getParcelable("articles"); - m_activeArticle = savedInstanceState.getParcelable("activeArticle"); - m_selectedArticles = savedInstanceState.getParcelable("selectedArticles"); - m_searchQuery = (String) savedInstanceState.getCharSequence("searchQuery"); - } - - DisplayMetrics metrics = new DisplayMetrics(); - getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics); - m_maxImageSize = (int) (128 * metrics.density + 0.5); - - Log.d(TAG, "maxImageSize=" + m_maxImageSize); - - 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(false, true); - } - }); - - 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); - } - - - ListView list = (ListView)view.findViewById(R.id.headlines); - m_adapter = new ArticleListAdapter(getActivity(), R.layout.headlines_row, (ArrayList<Article>)m_articles); - - /* 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.setOnScrollListener(this); - //list.setEmptyView(view.findViewById(R.id.no_headlines)); - registerForContextMenu(list); - - //m_activity.m_pullToRefreshAttacher.addRefreshableView(list, this); - - //if (m_activity.isSmallScreen()) - //view.findViewById(R.id.headlines_fragment).setPadding(0, 0, 0, 0); - - Log.d(TAG, "onCreateView, feed=" + m_feed); - - return view; - } - - @Override - public void onResume() { - super.onResume(); - - if (GlobalState.getInstance().m_activeArticle != null) { - m_activeArticle = GlobalState.getInstance().m_activeArticle; - GlobalState.getInstance().m_activeArticle = null; - } - - if (m_activeArticle != null) { - setActiveArticle(m_activeArticle); - } - - if (m_articles.size() == 0 || !m_feed.equals(GlobalState.getInstance().m_activeFeed)) { - if (m_activity.getSupportFragmentManager().findFragmentByTag(CommonActivity.FRAG_ARTICLE) == null) { - refresh(false); - GlobalState.getInstance().m_activeFeed = m_feed; - } - } else { - notifyUpdated(); - } - - m_activity.initMenu(); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - m_activity = (OnlineActivity) activity; - m_listener = (HeadlinesEventListener) activity; - } - - @Override - public void onItemClick(AdapterView<?> av, View view, int position, long id) { - ListView list = (ListView)av; - - Log.d(TAG, "onItemClick=" + position); - - if (list != null) { - Article article = (Article)list.getItemAtPosition(position); - if (article.id >= 0) { - m_listener.onArticleSelected(article); - - // only set active article when it makes sense (in HeadlinesActivity) - if (getActivity().findViewById(R.id.article_fragment) != null) { - m_activeArticle = article; - } - - m_adapter.notifyDataSetChanged(); - } - } - } - - public void refresh(boolean append) { - refresh(append, false); - } - - @SuppressWarnings({ "serial" }) - public void refresh(boolean append, boolean userInitiated) { - if (m_activity != null && m_feed != null) { - m_refreshInProgress = true; - - m_swipeLayout.setRefreshing(true); - m_activity.setProgressBarVisibility(true); - - if (!m_feed.equals(GlobalState.getInstance().m_activeFeed)) { - append = false; - } - - // new stuff may appear on top, scroll back to show it - if (!append) { - if (getView() != null) { - Log.d(TAG, "scroll hack"); - ListView list = (ListView)getView().findViewById(R.id.headlines); - m_autoCatchupDisabled = true; - list.setSelection(0); - m_autoCatchupDisabled = false; - list.setEmptyView(null); - m_adapter.clear(); - m_adapter.notifyDataSetChanged(); - } - } - - final boolean fappend = append; - final String sessionId = m_activity.getSessionId(); - final boolean isCat = m_feed.is_cat; - - HeadlinesRequest req = new HeadlinesRequest(getActivity().getApplicationContext(), m_activity, m_feed) { - @Override - protected void onProgressUpdate(Integer... progress) { - m_activity.setProgress(Math.round((((float)progress[0] / (float)progress[1]) * 10000))); - } - - @Override - protected void onPostExecute(JsonElement result) { - if (isDetached()) return; - - if (getView() != null) { - ListView list = (ListView)getView().findViewById(R.id.headlines); - - if (list != null) { - list.setEmptyView(getView().findViewById(R.id.no_headlines)); - } - } - - m_activity.setProgressBarVisibility(false); - - super.onPostExecute(result); - - if (isAdded()) { - m_swipeLayout.setRefreshing(false); - } - - if (result != null) { - m_refreshInProgress = false; - - if (m_articles.indexOf(m_activeArticle) == -1) - m_activeArticle = null; - - m_adapter.notifyDataSetChanged(); - m_listener.onHeadlinesLoaded(fappend); - - } else { - if (m_lastError == ApiError.LOGIN_FAILED) { - m_activity.login(true); - } else { - m_activity.setLoadingStatus(getErrorMessage(), false); - } - } - } - }; - - int skip = 0; - - if (append) { - // adaptive, all_articles, marked, published, unread - String viewMode = m_activity.getViewMode(); - int numUnread = 0; - int numAll = m_articles.size(); - - for (Article a : m_articles) { - if (a.unread) ++numUnread; - } - - if ("marked".equals(viewMode)) { - skip = numAll; - } else if ("published".equals(viewMode)) { - skip = numAll; - } else if ("unread".equals(viewMode)) { - skip = numUnread; - } else if (m_searchQuery != null && m_searchQuery.length() > 0) { - skip = numAll; - } else if ("adaptive".equals(viewMode)) { - skip = numUnread > 0 ? numUnread : numAll; - } else { - skip = numAll; - } - - } else { - m_activity.setLoadingStatus(R.string.blank, true); - } - - final int fskip = skip; - - final boolean allowForceUpdate = m_activity.getApiLevel() >= 9 && - !m_feed.is_cat && m_feed.id > 0 && !append && userInitiated && - skip == 0; - - Log.d(TAG, "allowForceUpdate=" + allowForceUpdate + " userInitiated=" + userInitiated); - - - req.setOffset(skip); - - HashMap<String,String> map = new HashMap<String,String>() { - { - put("op", "getHeadlines"); - put("sid", sessionId); - put("feed_id", String.valueOf(m_feed.id)); - put("show_content", "true"); - put("include_attachments", "true"); - put("view_mode", m_activity.getViewMode()); - put("limit", String.valueOf(HEADLINES_REQUEST_SIZE)); - put("offset", String.valueOf(0)); - put("skip", String.valueOf(fskip)); - put("include_nested", "true"); - put("order_by", m_prefs.getBoolean("oldest_first", false) ? "date_reverse" : ""); - - if (isCat) put("is_cat", "true"); - - if (allowForceUpdate) { - put("force_update", "true"); - } - - if (m_searchQuery != null && m_searchQuery.length() != 0) { - put("search", m_searchQuery); - put("search_mode", ""); - put("match_on", "both"); - } - - } - }; - - req.execute(map); - } - } - - @Override - public void onSaveInstanceState (Bundle out) { - super.onSaveInstanceState(out); - - out.setClassLoader(getClass().getClassLoader()); - out.putParcelable("feed", m_feed); - //out.putParcelable("articles", m_articles); - out.putParcelable("activeArticle", m_activeArticle); - out.putParcelable("selectedArticles", m_selectedArticles); - out.putCharSequence("searchQuery", m_searchQuery); - } - - /* private void setLoadingStatus(int status, boolean showProgress) { - if (getView() != null) { - TextView tv = (TextView)getView().findViewById(R.id.loading_message); - - if (tv != null) { - tv.setText(status); - } - } - - if (getActivity() != null) - getActivity().setProgressBarIndeterminateVisibility(showProgress); - } */ - - /* private class HeadlinesRequest extends ApiRequest { - int m_offset = 0; - - public HeadlinesRequest(Context context) { - super(context); - } - - protected void onPostExecute(JsonElement result) { - if (result != null) { - try { - JsonArray content = result.getAsJsonArray(); - if (content != null) { - Type listType = new TypeToken<List<Article>>() {}.getType(); - final List<Article> articles = new Gson().fromJson(content, listType); - - while (m_articles.size() > HEADLINES_BUFFER_MAX) - m_articles.remove(0); - - if (m_offset == 0) - m_articles.clear(); - else - m_articles.remove(m_articles.size()-1); // remove previous placeholder - - for (Article f : articles) - m_articles.add(f); - - if (articles.size() == HEADLINES_REQUEST_SIZE) { - Article placeholder = new Article(-1); - m_articles.add(placeholder); - - m_canLoadMore = true; - } else { - m_canLoadMore = false; - } - - m_adapter.notifyDataSetChanged(); - - if (m_articles.size() == 0) - setLoadingStatus(R.string.no_headlines_to_display, false); - else - setLoadingStatus(R.string.blank, false); - - m_refreshInProgress = false; - - return; - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (m_lastError == ApiError.LOGIN_FAILED) { - m_activity.login(); - } else { - setLoadingStatus(getErrorMessage(), false); - } - m_refreshInProgress = false; - } - - public void setOffset(int skip) { - m_offset = skip; - } - } */ - - static class HeadlineViewHolder { - public TextView titleView; - public TextView feedTitleView; - public ImageView markedView; - public ImageView publishedView; - public TextView excerptView; - public ImageView flavorImageView; - public TextView authorView; - public TextView dateView; - public CheckBox selectionBoxView; - public ImageView menuButtonView; - public ViewGroup flavorImageHolder; - - } - - private class ArticleListAdapter extends ArrayAdapter<Article> { - private ArrayList<Article> items; - - 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 textViewResourceId, ArrayList<Article> items) { - super(context, textViewResourceId, items); - this.items = items; - - 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) { - Article a = items.get(position); - - if (a.id == -1) { - return VIEW_LOADMORE; - } else if (m_activeArticle != null && a.id == m_activeArticle.id && a.unread) { - return VIEW_SELECTED_UNREAD; - } else if (m_activeArticle != null && a.id == m_activeArticle.id) { - return VIEW_SELECTED; - } else if (a.unread) { - return VIEW_UNREAD; - } else { - return VIEW_NORMAL; - } - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - - View v = convertView; - - final Article article = items.get(position); - HeadlineViewHolder holder; - - 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: - layoutId = R.layout.headlines_row_selected; - break; - case VIEW_SELECTED_UNREAD: - layoutId = R.layout.headlines_row_selected_unread; - break; - } - - LayoutInflater vi = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(layoutId, null); - - holder = new HeadlineViewHolder(); - holder.titleView = (TextView)v.findViewById(R.id.title); - - holder.feedTitleView = (TextView)v.findViewById(R.id.feed_title); - holder.markedView = (ImageView)v.findViewById(R.id.marked); - holder.publishedView = (ImageView)v.findViewById(R.id.published); - holder.excerptView = (TextView)v.findViewById(R.id.excerpt); - holder.flavorImageView = (ImageView) v.findViewById(R.id.flavor_image); - holder.authorView = (TextView)v.findViewById(R.id.author); - holder.dateView = (TextView) v.findViewById(R.id.date); - holder.selectionBoxView = (CheckBox) v.findViewById(R.id.selected); - holder.menuButtonView = (ImageView) v.findViewById(R.id.article_menu_button); - holder.flavorImageHolder = (ViewGroup) v.findViewById(R.id.flavorImageHolder); - - v.setTag(holder); - - // http://code.google.com/p/android/issues/detail?id=3414 - ((ViewGroup)v).setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); - } else { - holder = (HeadlineViewHolder) v.getTag(); - } - - if (holder.titleView != null) { - holder.titleView.setText(Html.fromHtml(article.title)); - - if (m_prefs.getBoolean("enable_condensed_fonts", false)) { - Typeface tf = TypefaceCache.get(m_activity, "sans-serif-condensed", article.unread ? Typeface.BOLD : Typeface.NORMAL); - - if (tf != null && !tf.equals(holder.titleView.getTypeface())) { - holder.titleView.setTypeface(tf); - } - - holder.titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, Math.min(21, headlineFontSize + 5)); - } else { - holder.titleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, Math.min(21, headlineFontSize + 3)); - } - - adjustTitleTextView(article.score, holder.titleView, position); - } - - - - if (holder.feedTitleView != null) { - if (article.feed_title != null && (m_feed.is_cat || m_feed.id < 0)) { - - /* if (article.feed_title.length() > 20) - ft.setText(article.feed_title.substring(0, 20) + "..."); - else */ - - holder.feedTitleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineSmallFontSize); - holder.feedTitleView.setText(article.feed_title); - - } else { - holder.feedTitleView.setVisibility(View.GONE); - } - - } - - - - if (holder.markedView != null) { - holder.markedView.setImageResource(article.marked ? R.drawable.ic_star_full : R.drawable.ic_star_empty); - - holder.markedView.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - article.marked = !article.marked; - m_adapter.notifyDataSetChanged(); - - m_activity.saveArticleMarked(article); - } - }); - } - - - - if (holder.publishedView != null) { - holder.publishedView.setImageResource(article.published ? R.drawable.ic_published : R.drawable.ic_unpublished); - - holder.publishedView.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - article.published = !article.published; - m_adapter.notifyDataSetChanged(); - - m_activity.saveArticlePublished(article); - } - }); - } - - String articleContent = article.content != null ? article.content : ""; - - if (holder.excerptView != null) { - if (!m_prefs.getBoolean("headlines_show_content", true)) { - holder.excerptView.setVisibility(View.GONE); - } else { - String excerpt = Jsoup.parse(articleContent).text(); - - if (excerpt.length() > CommonActivity.EXCERPT_MAX_SIZE) - excerpt = excerpt.substring(0, CommonActivity.EXCERPT_MAX_SIZE) + "..."; - - holder.excerptView.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineFontSize); - holder.excerptView.setText(excerpt); - } - } - - - - if (holder.flavorImageView != null && m_prefs.getBoolean("headlines_show_flavor_image", true)) { - holder.flavorImageView.setVisibility(View.GONE); - - Document doc = Jsoup.parse(articleContent); - - Element img = doc.select("img").first(); - if (doc != null) { - - if (img != null) { - String imgSrc = img.attr("src"); - - // retarded schema-less urls - if (imgSrc.indexOf("//") == 0) - imgSrc = "http:" + imgSrc; - - DisplayImageOptions options = new DisplayImageOptions.Builder(). - cacheInMemory(true). - cacheOnDisk(true). - build(); - - final ImageView flavorImageView = holder.flavorImageView; - - ImageLoader.getInstance().displayImage(imgSrc, holder.flavorImageView, options, new ImageLoadingListener() { - - @Override - public void onLoadingCancelled(String arg0, - View arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void onLoadingComplete(String arg0, - View arg1, Bitmap arg2) { - // TODO Auto-generated method stub - - if (!isAdded()) return; - - if (arg2.getWidth() > 128 && arg2.getHeight() > 128) { - if (arg0 != null && !arg0.equals(arg1.getTag())) { - if (!m_activity.isCompatMode() && flavorImageView.getVisibility() != View.VISIBLE) { - ObjectAnimator anim = ObjectAnimator.ofFloat(flavorImageView, "alpha", 0f, 1f); - anim.setDuration(500); - anim.start(); - } - } - - flavorImageView.setTag(arg0); - flavorImageView.setVisibility(View.VISIBLE); - } - } - - @Override - public void onLoadingFailed(String arg0, - View arg1, FailReason arg2) { - // TODO Auto-generated method stub - } - - @Override - public void onLoadingStarted(String arg0, - View arg1) { - // TODO Auto-generated method stub - - } - - }); - } - - } - } else if (holder.flavorImageHolder != null) { - holder.flavorImageHolder.setVisibility(View.GONE); - } - - String articleAuthor = article.author != null ? article.author : ""; - - - if (holder.authorView != null) { - holder.authorView.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineSmallFontSize); - - if (articleAuthor.length() > 0) { - holder.authorView.setText(getString(R.string.author_formatted, articleAuthor)); - } else { - holder.authorView.setText(""); - } - } - - if (holder.dateView != null) { - holder.dateView.setTextSize(TypedValue.COMPLEX_UNIT_SP, headlineSmallFontSize); - - Date d = new Date((long)article.updated * 1000); - DateFormat df = new SimpleDateFormat("MMM dd, HH:mm"); - df.setTimeZone(TimeZone.getDefault()); - holder.dateView.setText(df.format(d)); - } - - - if (holder.selectionBoxView != null) { - holder.selectionBoxView.setChecked(m_selectedArticles.contains(article)); - holder.selectionBoxView.setOnClickListener(new OnClickListener() { - - @Override - 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); - } - - m_listener.onArticleListSelectionChange(m_selectedArticles); - - Log.d(TAG, "num selected: " + m_selectedArticles.size()); - } - }); - } - - if (holder.menuButtonView != null) { - //if (m_activity.isDarkTheme()) - // ib.setImageResource(R.drawable.ic_mailbox_collapsed_holo_dark); - - holder.menuButtonView.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 ArticleList getAllArticles() { - return m_articles; - } - - public void setActiveArticle(Article article) { - if (article != m_activeArticle) { - m_activeArticle = article; - m_adapter.notifyDataSetChanged(); - - ListView list = (ListView)getView().findViewById(R.id.headlines); - - if (list != null && article != null) { - int position = m_adapter.getPosition(article); - 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 Article getArticleAtPosition(int position) { - try { - return m_adapter.getItem(position); - } catch (IndexOutOfBoundsException e) { - return null; - } catch (NullPointerException e) { - return null; - } - } - - public Article getArticleById(int id) { - for (Article a : m_articles) { - if (a.id == id) - return a; - } - return null; - } - - public ArticleList getUnreadArticles() { - ArticleList tmp = new ArticleList(); - for (Article a : m_articles) { - if (a.unread) tmp.add(a); - } - return tmp; - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (!m_refreshInProgress && m_articles.findById(-1) != null && firstVisibleItem + visibleItemCount == m_articles.size()) { - refresh(true); - } - - if (m_prefs.getBoolean("headlines_mark_read_scroll", false) && firstVisibleItem > 0 && !m_autoCatchupDisabled) { - Article a = m_articles.get(firstVisibleItem - 1); - - if (a != null && a.unread) { - a.unread = false; - m_readArticles.add(a); - m_feed.unread--; - } - } - } - - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - if (scrollState == SCROLL_STATE_IDLE && m_prefs.getBoolean("headlines_mark_read_scroll", false)) { - if (!m_readArticles.isEmpty()) { - m_activity.toggleArticlesUnread(m_readArticles); - m_activity.refresh(false); - m_readArticles.clear(); - } - } - } - - public Article getActiveArticle() { - return m_activeArticle; - } - - public int getArticlePosition(Article article) { - try { - return m_adapter.getPosition(article); - } catch (NullPointerException e) { - return -1; - } - } - - public String getSearchQuery() { - return m_searchQuery; - } - - public void setSearchQuery(String query) { - if (!m_searchQuery.equals(query)) { - m_searchQuery = query; - refresh(false); - } - } - - public Feed getFeed() { - return m_feed; - } - - /* class DownloadFlavorImagesTask extends AsyncTask<ImageView, Void, Bitmap> { - ImageView imageView = null; - @Override - protected Bitmap doInBackground(ImageView... imageViews) { - this.imageView = imageViews[0]; - return download((URL)imageView.getTag()); - } - - @Override - protected void onPostExecute(Bitmap result) { - if (result != null) { - imageView.setImageBitmap(result); - imageView.setVisibility(View.VISIBLE); - } - } - - private Bitmap download(URL url) { - try { - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - - conn.setDoInput(true); - conn.setUseCaches(true); - conn.connect(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - - byte[] buf = new byte[256]; - int read = 0; - - while ((read = conn.getInputStream().read(buf)) >= 0) { - bos.write(buf, 0, read); - } - - final BitmapFactory.Options options = new BitmapFactory.Options(); - - byte[] bitmap = bos.toByteArray(); - - options.inJustDecodeBounds = true; - BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length, options); - options.inJustDecodeBounds = false; - - int inSampleSize = CommonActivity.calculateInSampleSize(options, 128, 128); - - Bitmap decodedBitmap = BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length, options); - - return decodedBitmap; - } catch (OutOfMemoryError e) { - Log.d(TAG, "OOM while trying to decode headline flavor image. :("); - e.printStackTrace(); - } catch (IOException e) { - // - } - - return null; - } - } */ -} diff --git a/src/org/fox/ttrss/LoadingFragment.java b/src/org/fox/ttrss/LoadingFragment.java deleted file mode 100644 index f0802b0a..00000000 --- a/src/org/fox/ttrss/LoadingFragment.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.fox.ttrss; - -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -public class LoadingFragment extends Fragment { - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - View view = inflater.inflate(R.layout.loading_fragment, container, false); - - return view; - } - -} diff --git a/src/org/fox/ttrss/OnlineActivity.java b/src/org/fox/ttrss/OnlineActivity.java deleted file mode 100644 index e33a02b7..00000000 --- a/src/org/fox/ttrss/OnlineActivity.java +++ /dev/null @@ -1,1765 +0,0 @@ -package org.fox.ttrss; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.List; - -import org.fox.ttrss.offline.OfflineActivity; -import org.fox.ttrss.offline.OfflineDownloadService; -import org.fox.ttrss.offline.OfflineUploadService; -import org.fox.ttrss.share.SubscribeActivity; -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; -import org.fox.ttrss.types.Feed; -import org.fox.ttrss.types.Label; -import org.fox.ttrss.widget.SmallWidgetProvider; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.select.Elements; - -import android.annotation.TargetApi; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.ActivityNotFoundException; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.DialogInterface.OnMultiChoiceClickListener; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.preference.PreferenceManager; -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; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.reflect.TypeToken; -import com.nostra13.universalimageloader.core.ImageLoader; -import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; - -public class OnlineActivity extends CommonActivity { - private final String TAG = this.getClass().getSimpleName(); - - private final static int TRIAL_DAYS = 8; - - protected SharedPreferences m_prefs; - protected Menu m_menu; - - protected int m_offlineModeStatus = 0; - - private ActionMode m_headlinesActionMode; - private HeadlinesActionModeCallback m_headlinesActionModeCallback; - - private String m_lastImageHitTestUrl; - - //protected PullToRefreshAttacher m_pullToRefreshAttacher; - - protected abstract class OnLoginFinishedListener { - public abstract void OnLoginSuccess(); - public abstract void OnLoginFailed(); - }; - - private BroadcastReceiver m_broadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context content, Intent intent) { - - if (intent.getAction().equals(OfflineDownloadService.INTENT_ACTION_SUCCESS)) { - - m_offlineModeStatus = 2; - - switchOffline(); - - } else if (intent.getAction().equals(OfflineUploadService.INTENT_ACTION_SUCCESS)) { - Log.d(TAG, "offline upload service reports success"); - toast(R.string.offline_sync_success); - } - } - }; - - - @TargetApi(11) - 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; - - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - if (selected.size() > 0) { - selected.clear(); - initMenu(); - hf.notifyUpdated(); - } - } - } - - @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; - } - }; - - protected String getSessionId() { - return GlobalState.getInstance().m_sessionId; - } - - protected void setSessionId(String sessionId) { - GlobalState.getInstance().m_sessionId = sessionId; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - ApiRequest.disableConnectionReuseIfNecessary(); - - // we use that before parent onCreate so let's init locally - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - setAppTheme(m_prefs); - - super.onCreate(savedInstanceState); - - if (canUseProgress()) { - requestWindowFeature(Window.FEATURE_PROGRESS); - } - - //requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); - - setProgressBarVisibility(false); - setProgressBarIndeterminateVisibility(false); - -// SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - - boolean isOffline = localPrefs.getBoolean("offline_mode_active", false); - - Log.d(TAG, "m_isOffline=" + isOffline); - - setContentView(R.layout.login); - - setStatusBarTint(); - - ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).build(); - ImageLoader.getInstance().init(config); - ImageLoader.getInstance().clearDiskCache(); - - //m_pullToRefreshAttacher = PullToRefreshAttacher.get(this); - - if (isOffline) { - switchOfflineSuccess(); - } else { - checkTrial(false); - - /* if (getIntent().getExtras() != null) { - Intent i = getIntent(); - } */ - - if (savedInstanceState != null) { - m_offlineModeStatus = savedInstanceState.getInt("offlineModeStatus"); - } - - m_headlinesActionModeCallback = new HeadlinesActionModeCallback(); - } - } - - protected boolean canUseProgress() { - return GlobalState.getInstance().m_canUseProgress; - } - - private void switchOffline() { - if (m_offlineModeStatus == 2) { - - AlertDialog.Builder builder = new AlertDialog.Builder( - OnlineActivity.this) - .setMessage(R.string.dialog_offline_success) - .setPositiveButton(R.string.dialog_offline_go, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - m_offlineModeStatus = 0; - - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = localPrefs.edit(); - editor.putBoolean("offline_mode_active", true); - editor.commit(); - - Intent offline = new Intent( - OnlineActivity.this, - OfflineActivity.class); - offline.putExtra("initial", true); - startActivity(offline); - finish(); - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - m_offlineModeStatus = 0; - - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - - } else if (m_offlineModeStatus == 0) { - - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setMessage(R.string.dialog_offline_switch_prompt) - .setPositiveButton(R.string.dialog_offline_go, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - if (getSessionId() != null) { - Log.d(TAG, "offline: starting"); - - m_offlineModeStatus = 1; - - Intent intent = new Intent( - OnlineActivity.this, - OfflineDownloadService.class); - intent.putExtra("sessionId", getSessionId()); - - startService(intent); - } - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - // - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } else if (m_offlineModeStatus == 1) { - cancelOfflineSync(); - } - } - - private boolean hasPendingOfflineData() { - try { - Cursor c = getReadableDb().query("articles", - new String[] { "COUNT(*)" }, "modified = 1", null, null, null, - null); - if (c.moveToFirst()) { - int modified = c.getInt(0); - c.close(); - - return modified > 0; - } - } catch (IllegalStateException e) { - // db is closed? ugh - } - - return false; - } - - private boolean hasOfflineData() { - try { - Cursor c = getReadableDb().query("articles", - new String[] { "COUNT(*)" }, null, null, null, null, null); - if (c.moveToFirst()) { - int modified = c.getInt(0); - c.close(); - - return modified > 0; - } - } catch (IllegalStateException e) { - // db is closed? - } - - return false; - } - - @Override - public void onStop() { - super.onStop(); - - Intent initialUpdateIntent = new Intent(SmallWidgetProvider.FORCE_UPDATE_ACTION); - sendBroadcast(initialUpdateIntent); - } - - @Override - public void onPause() { - super.onPause(); - - unregisterReceiver(m_broadcastReceiver); - } - - @Override - public void onDestroy() { - super.onDestroy(); - } - - private void syncOfflineData() { - Log.d(TAG, "offlineSync: starting"); - - Intent intent = new Intent( - OnlineActivity.this, - OfflineUploadService.class); - - intent.putExtra("sessionId", getSessionId()); - - startService(intent); - } - - private void cancelOfflineSync() { - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setMessage(R.string.dialog_offline_sync_in_progress) - .setNegativeButton(R.string.dialog_offline_sync_stop, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - if (getSessionId() != null) { - Log.d(TAG, "offline: stopping"); - - m_offlineModeStatus = 0; - - Intent intent = new Intent( - OnlineActivity.this, - OfflineDownloadService.class); - - stopService(intent); - - dialog.dismiss(); - - restart(); - } - } - }) - .setPositiveButton(R.string.dialog_offline_sync_continue, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - dialog.dismiss(); - - restart(); - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } - - public void restart() { - Intent refresh = new Intent(OnlineActivity.this, OnlineActivity.class); - startActivity(refresh); - finish(); - } - - private void switchOfflineSuccess() { - logout(); - // setLoadingStatus(R.string.blank, false); - - SharedPreferences.Editor editor = m_prefs.edit(); - editor.putBoolean("offline_mode_active", true); - editor.commit(); - - Intent offline = new Intent(OnlineActivity.this, OfflineActivity.class); - offline.putExtra("initial", true); - offline.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - - startActivityForResult(offline, 0); - - finish(); - - } - - public void login() { - login(false, null); - } - - public void login(boolean refresh) { - login(refresh, null); - } - - public void login(boolean refresh, OnLoginFinishedListener listener) { - if (m_prefs.getString("ttrss_url", "").trim().length() == 0) { - - setLoadingStatus(R.string.login_need_configure, false); - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage(R.string.dialog_need_configure_prompt) - .setCancelable(false) - .setPositiveButton(R.string.dialog_open_preferences, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // launch preferences - - Intent intent = new Intent(OnlineActivity.this, - PreferencesActivity.class); - startActivityForResult(intent, 0); - } - }) - .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - AlertDialog alert = builder.create(); - alert.show(); - - } else { - setLoadingStatus(R.string.login_in_progress, true); - - LoginRequest ar = new LoginRequest(getApplicationContext(), refresh, listener); - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("op", "login"); - put("user", m_prefs.getString("login", "").trim()); - put("password", m_prefs.getString("password", "").trim()); - } - }; - - ar.execute(map); - - setLoadingStatus(R.string.login_in_progress, true); - } - } - - protected void loginSuccess(boolean refresh) { - setLoadingStatus(R.string.blank, false); - - initMenu(); - - Intent intent = new Intent(OnlineActivity.this, FeedsActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - - startActivityForResult(intent, 0); - overridePendingTransition(0, 0); - - if (hasPendingOfflineData()) - syncOfflineData(); - - finish(); - } - - public void checkTrial(boolean notify) { - boolean isTrial = getPackageManager().checkSignatures( - getPackageName(), "org.fox.ttrss.key") != PackageManager.SIGNATURE_MATCH; - - if (isTrial) { - long firstStart = m_prefs.getLong("date_firstlaunch_trial", -1); - - if (firstStart == -1) { - firstStart = System.currentTimeMillis(); - - SharedPreferences.Editor editor = m_prefs.edit(); - editor.putLong("date_firstlaunch_trial", firstStart); - editor.commit(); - } - - if (!notify && System.currentTimeMillis() > firstStart + (TRIAL_DAYS * 24 * 60 * 60 * 1000)) { - - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setTitle(R.string.trial_expired) - .setMessage(R.string.trial_expired_message) - .setCancelable(false) - .setPositiveButton(getString(R.string.trial_purchase), - new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, - int which) { - - openUnlockUrl(); - finish(); - - } - }) - .setNegativeButton(getString(R.string.cancel), - new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, - int which) { - - finish(); - - } - }); - - AlertDialog dialog = builder.create(); - dialog.show(); - - } else { - long daysLeft = Math.round((firstStart + (TRIAL_DAYS * 24 * 60 * 60 * 1000) - System.currentTimeMillis()) / (24 * 60 * 60 * 1000)); - - if (notify) { - toast(getString(R.string.trial_mode_prompt, Long.valueOf(daysLeft))); - } - } - } else if (notify) { - //toast(R.string.trial_thanks); - } - } - - private void openUnlockUrl() { - try { - Intent intent = new Intent(Intent.ACTION_VIEW, - Uri.parse("market://details?id=org.fox.ttrss.key")); - startActivity(intent); - } catch (ActivityNotFoundException ae) { - try { - Intent intent = new Intent(Intent.ACTION_VIEW, - Uri.parse("https://play.google.com/store/apps/details?id=org.fox.ttrss.key")); - startActivity(intent); - } catch (Exception e) { - e.printStackTrace(); - toast(R.string.error_other_error); - } - } - } - - @Override - public boolean onContextItemSelected(android.view.MenuItem item) { - /* AdapterContextMenuInfo info = (AdapterContextMenuInfo) item - .getMenuInfo(); */ - - final ArticlePager ap = (ArticlePager)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) { - - // 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); - } - } - return true; - case R.id.article_link_share: - if (ap != null && ap.getSelectedArticle() != null) { - shareArticle(ap.getSelectedArticle()); - } - return true; - case R.id.article_link_copy: - Log.d(TAG, "article_link_copy"); - if (ap != null && ap.getSelectedArticle() != null) { - copyToClipboard(ap.getSelectedArticle().link); - } - return true; - default: - Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); - return super.onContextItemSelected(item); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - final ArticlePager ap = (ArticlePager)getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - - switch (item.getItemId()) { - /* case android.R.id.home: - finish(); - return true; */ - case R.id.headlines_toggle_sidebar: - if (true && !isSmallScreen()) { - View v = findViewById(R.id.headlines_fragment); - - if (v != null) { - SharedPreferences.Editor editor = m_prefs.edit(); - editor.putBoolean("headlines_hide_sidebar", !m_prefs.getBoolean("headlines_hide_sidebar", false)); - editor.commit(); - - v.setVisibility(m_prefs.getBoolean("headlines_hide_sidebar", false) ? View.GONE : View.VISIBLE); - } - } - return true; - case R.id.subscribe_to_feed: - Intent subscribe = new Intent(OnlineActivity.this, SubscribeActivity.class); - startActivityForResult(subscribe, 0); - return true; - case R.id.toggle_attachments: - if (true) { - Article article = ap.getSelectedArticle(); - - if (article != null && article.attachments != null && article.attachments.size() > 0) { - CharSequence[] items = new CharSequence[article.attachments.size()]; - final CharSequence[] itemUrls = new CharSequence[article.attachments.size()]; - - for (int i = 0; i < article.attachments.size(); i++) { - items[i] = article.attachments.get(i).title != null ? article.attachments.get(i).content_url : - article.attachments.get(i).content_url; - - itemUrls[i] = article.attachments.get(i).content_url; - } - - Dialog dialog = new Dialog(OnlineActivity.this); - AlertDialog.Builder builder = new AlertDialog.Builder(OnlineActivity.this) - .setTitle(R.string.attachments_prompt) - .setCancelable(true) - .setSingleChoiceItems(items, 0, new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // - } - }).setNeutralButton(R.string.attachment_copy, new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - int selectedPosition = ((AlertDialog)dialog).getListView().getCheckedItemPosition(); - - copyToClipboard((String)itemUrls[selectedPosition]); - } - }).setPositiveButton(R.string.attachment_view, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int id) { - int selectedPosition = ((AlertDialog)dialog).getListView().getCheckedItemPosition(); - - Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse((String)itemUrls[selectedPosition])); - startActivity(browserIntent); - - dialog.cancel(); - } - }).setNegativeButton(R.string.dialog_cancel, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - - dialog = builder.create(); - dialog.show(); - } - } - return true; - case R.id.donate: - if (true) { - openUnlockUrl(); - } - return true; - case R.id.logout: - logout(); - return true; - case R.id.login: - login(); - return true; - case R.id.go_offline: - switchOffline(); - return true; - case R.id.article_set_note: - if (ap != null && ap.getSelectedArticle() != null) { - editArticleNote(ap.getSelectedArticle()); - } - return true; - case R.id.preferences: - Intent intent = new Intent(OnlineActivity.this, - PreferencesActivity.class); - startActivityForResult(intent, 0); - return true; - case R.id.search: - if (hf != 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(); - - hf.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.headlines_mark_as_read: - if (hf != null) { - - int count = hf.getUnreadArticles().size(); - - boolean confirm = m_prefs.getBoolean("confirm_headlines_catchup", true); - - if (count > 0) { - if (confirm) { - AlertDialog.Builder builder = new AlertDialog.Builder( - OnlineActivity.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) { - - catchupVisibleArticles(); - - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } else { - catchupVisibleArticles(); - } - } - } - return true; - case R.id.headlines_view_mode: - if (hf != null) { - Dialog dialog = new Dialog(this); - - String viewMode = getViewMode(); - - //Log.d(TAG, "viewMode:" + getViewMode()); - - int selectedIndex = 0; - - if (viewMode.equals("all_articles")) { - selectedIndex = 1; - } else if (viewMode.equals("marked")) { - selectedIndex = 2; - } else if (viewMode.equals("published")) { - selectedIndex = 3; - } else if (viewMode.equals("unread")) { - selectedIndex = 4; - } - - 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 1: - setViewMode("all_articles"); - break; - case 2: - setViewMode("marked"); - break; - case 3: - setViewMode("published"); - break; - case 4: - setViewMode("unread"); - break; - } - dialog.cancel(); - - refresh(); - } - }); - - dialog = builder.create(); - dialog.show(); - - } - return true; - case R.id.headlines_select: - if (hf != null) { - Dialog dialog = new Dialog(this); - AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setTitle(R.string.headlines_select_dialog) - .setSingleChoiceItems( - new String[] { - getString(R.string.headlines_select_all), - getString(R.string.headlines_select_unread), - getString(R.string.headlines_select_none) }, - 0, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, - int which) { - switch (which) { - case 0: - hf.setSelection(HeadlinesFragment.ArticlesSelection.ALL); - break; - case 1: - hf.setSelection(HeadlinesFragment.ArticlesSelection.UNREAD); - break; - case 2: - hf.setSelection(HeadlinesFragment.ArticlesSelection.NONE); - break; - } - dialog.cancel(); - initMenu(); - } - }); - - dialog = builder.create(); - dialog.show(); - } - return true; - case R.id.share_article: - if (ap != null) { - shareArticle(ap.getSelectedArticle()); - } - return true; - case R.id.toggle_marked: - if (ap != null & ap.getSelectedArticle() != null) { - Article a = ap.getSelectedArticle(); - a.marked = !a.marked; - saveArticleMarked(a); - if (hf != null) hf.notifyUpdated(); - } - return true; - /* case R.id.selection_select_none: - if (hf != null) { - ArticleList selected = hf.getSelectedArticles(); - if (selected.size() > 0) { - selected.clear(); - initMenu(); - 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(); - initMenu(); - } - } - 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(); - initMenu(); - } - } - 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(); - initMenu(); - } - } - return true; - case R.id.toggle_published: - if (ap != null && ap.getSelectedArticle() != null) { - Article a = ap.getSelectedArticle(); - a.published = !a.published; - saveArticlePublished(a); - if (hf != null) hf.notifyUpdated(); - } - return true; - case R.id.catchup_above: - if (hf != null) { - if (ap != null && ap.getSelectedArticle() != null) { - Article article = ap.getSelectedArticle(); - - ArticleList articles = hf.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) { - toggleArticlesUnread(tmp); - hf.notifyUpdated(); - initMenu(); - } - } - } - return true; - case R.id.set_unread: - if (ap != null && ap.getSelectedArticle() != null) { - Article a = ap.getSelectedArticle(); - - if (a != null) { - a.unread = !a.unread; - saveArticleUnread(a); - } - - if (hf != null) hf.notifyUpdated(); - } - return true; - case R.id.set_labels: - if (ap != null && ap.getSelectedArticle() != null) { - if (getApiLevel() != 7) { - editArticleLabels(ap.getSelectedArticle()); - } else { - toast(R.string.server_function_not_available); - } - - } - return true; - case R.id.update_headlines: - if (hf != null) { - //m_pullToRefreshAttacher.setRefreshing(true); - hf.refresh(false, true); - } - return true; - default: - Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId()); - return super.onOptionsItemSelected(item); - } - } - - protected void catchupVisibleArticles() { - final HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - - if (hf != null) { - ArticleList articles = hf.getUnreadArticles(); - - for (Article a : articles) - a.unread = false; - - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - if (hf.isAdded()) { - hf.refresh(false); - } - } - }; - - final String articleIds = articlesToIdString(articles); - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "updateArticle"); - put("article_ids", articleIds); - put("mode", "0"); - put("field", "2"); - } - }; - req.execute(map); - } - } - - public void editArticleNote(final Article article) { - String note = ""; - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(article.title); - final EditText topicEdit = new EditText(this); - topicEdit.setText(note); - builder.setView(topicEdit); - - builder.setPositiveButton(R.string.article_set_note, new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - String note = topicEdit.getText().toString().trim(); - - saveArticleNote(article, note); - article.published = true; - article.note = note; - - saveArticlePublished(article); - - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - if (hf != null) hf.notifyUpdated(); - } - }); - - builder.setNegativeButton(R.string.dialog_cancel, new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // - } - }); - - AlertDialog dialog = builder.create(); - dialog.show(); - } - - public void editArticleLabels(Article article) { - final int articleId = article.id; - - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - protected void onPostExecute(JsonElement result) { - if (result != null) { - Type listType = new TypeToken<List<Label>>() {}.getType(); - final List<Label> labels = new Gson().fromJson(result, listType); - - CharSequence[] items = new CharSequence[labels.size()]; - final int[] itemIds = new int[labels.size()]; - boolean[] checkedItems = new boolean[labels.size()]; - - for (int i = 0; i < labels.size(); i++) { - items[i] = labels.get(i).caption; - itemIds[i] = labels.get(i).id; - checkedItems[i] = labels.get(i).checked; - } - - Dialog dialog = new Dialog(OnlineActivity.this); - AlertDialog.Builder builder = new AlertDialog.Builder(OnlineActivity.this) - .setTitle(R.string.article_set_labels) - .setMultiChoiceItems(items, checkedItems, new OnMultiChoiceClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which, final boolean isChecked) { - final int labelId = itemIds[which]; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "setArticleLabel"); - put("label_id", String.valueOf(labelId)); - put("article_ids", String.valueOf(articleId)); - if (isChecked) put("assign", "true"); - } - }; - - ApiRequest req = new ApiRequest(m_context); - req.execute(map); - - } - }).setPositiveButton(R.string.dialog_close, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - - dialog = builder.create(); - dialog.show(); - - } - } - }; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "getLabels"); - put("article_id", String.valueOf(articleId)); - } - }; - - req.execute(map); - } - - protected void logout() { - setSessionId(null); - - findViewById(R.id.loading_container).setVisibility(View.VISIBLE); - setLoadingStatus(R.string.login_ready, false); - - initMenu(); - } - - protected void loginFailure() { - setSessionId(null); - initMenu(); - - if (hasOfflineData()) { - - AlertDialog.Builder builder = new AlertDialog.Builder( - OnlineActivity.this) - .setMessage(R.string.dialog_offline_prompt) - .setPositiveButton(R.string.dialog_offline_go, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - switchOfflineSuccess(); - } - }) - .setNegativeButton(R.string.dialog_cancel, - new Dialog.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - // - } - }); - - AlertDialog dlg = builder.create(); - dlg.show(); - } - } - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - out.putInt("offlineModeStatus", m_offlineModeStatus); - } - - @Override - public void onResume() { - super.onResume(); - - ApiRequest.trustAllHosts(m_prefs.getBoolean("ssl_trust_any", false), - m_prefs.getBoolean("ssl_trust_any_host", false)); - - IntentFilter filter = new IntentFilter(); - filter.addAction(OfflineDownloadService.INTENT_ACTION_SUCCESS); - filter.addAction(OfflineUploadService.INTENT_ACTION_SUCCESS); - filter.addCategory(Intent.CATEGORY_DEFAULT); - - registerReceiver(m_broadcastReceiver, filter); - - if (getSessionId() == null) { - login(); - } else { - loginSuccess(false); - } - } - - public Menu getMenu() { - return m_menu; - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.main_menu, menu); - - m_menu = menu; - - initMenu(); - - List<PackageInfo> pkgs = getPackageManager() - .getInstalledPackages(0); - - for (PackageInfo p : pkgs) { - if ("org.fox.ttrss.key".equals(p.packageName)) { - Log.d(TAG, "license apk found"); - menu.findItem(R.id.donate).setVisible(false); - break; - } - } - - return true; - } - - protected int getApiLevel() { - return GlobalState.getInstance().m_apiLevel; - } - - protected void setApiLevel(int apiLevel) { - GlobalState.getInstance().m_apiLevel = apiLevel; - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticleUnread(final Article article) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - //toast(R.string.article_set_unread); - initMenu(); - } - }; - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", article.unread ? "1" : "0"); - put("field", "2"); - } - }; - - req.execute(map); - } - - public void saveArticleMarked(final Article article) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - //toast(article.marked ? R.string.notify_article_marked : R.string.notify_article_unmarked); - initMenu(); - } - }; - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", article.marked ? "1" : "0"); - put("field", "0"); - } - }; - - req.execute(map); - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticlePublished(final Article article) { - - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - //toast(article.published ? R.string.notify_article_published : R.string.notify_article_unpublished); - initMenu(); - } - }; - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", article.published ? "1" : "0"); - put("field", "1"); - } - }; - - req.execute(map); - } - - @SuppressWarnings({ "unchecked", "serial" }) - public void saveArticleNote(final Article article, final String note) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - toast(R.string.notify_article_note_set); - } - }; - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "updateArticle"); - put("article_ids", String.valueOf(article.id)); - put("mode", "1"); - put("data", note); - put("field", "3"); - } - }; - - req.execute(map); - } - - public static String articlesToIdString(ArticleList articles) { - String tmp = ""; - - for (Article a : articles) - tmp += String.valueOf(a.id) + ","; - - return tmp.replaceAll(",$", ""); - } - - public void shareText(String text) { - - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, text); - - startActivity(Intent.createChooser(intent, text)); - } - - public void shareArticle(Article article) { - if (article != null) { - - Intent intent = getShareIntent(article); - - startActivity(Intent.createChooser(intent, - getString(R.string.share_article))); - } - } - - protected Intent getShareIntent(Article article) { - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_SUBJECT, article.title); - intent.putExtra(Intent.EXTRA_TEXT, article.link); - - return intent; - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (m_prefs.getBoolean("use_volume_keys", false)) { - ArticlePager ap = (ArticlePager) 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); - } - - public void catchupFeed(final Feed feed) { - Log.d(TAG, "catchupFeed=" + feed); - - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - // refresh? - } - }; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "catchupFeed"); - put("feed_id", String.valueOf(feed.id)); - if (feed.is_cat) - put("is_cat", "1"); - } - }; - - req.execute(map); - } - - public void toggleArticlesMarked(final ArticleList articles) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "updateArticle"); - put("article_ids", articlesToIdString(articles)); - put("mode", "2"); - put("field", "0"); - } - }; - - req.execute(map); - } - - public void toggleArticlesUnread(final ArticleList articles) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "updateArticle"); - put("article_ids", articlesToIdString(articles)); - put("mode", "2"); - put("field", "2"); - } - }; - - req.execute(map); - //refresh(); - } - - public void toggleArticlesPublished(final ArticleList articles) { - ApiRequest req = new ApiRequest(getApplicationContext()); - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "updateArticle"); - put("article_ids", articlesToIdString(articles)); - put("mode", "2"); - put("field", "1"); - } - }; - - req.execute(map); - } - - - protected void initMenu() { - if (m_menu != null) { - if (getSessionId() != null) { - m_menu.setGroupVisible(R.id.menu_group_logged_in, true); - m_menu.setGroupVisible(R.id.menu_group_logged_out, false); - } else { - m_menu.setGroupVisible(R.id.menu_group_logged_in, false); - m_menu.setGroupVisible(R.id.menu_group_logged_out, true); - } - - 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); - - m_menu.findItem(R.id.set_labels).setEnabled(getApiLevel() >= 1); - m_menu.findItem(R.id.article_set_note).setEnabled(getApiLevel() >= 1); - m_menu.findItem(R.id.subscribe_to_feed).setEnabled(getApiLevel() >= 5); - - MenuItem search = m_menu.findItem(R.id.search); - search.setEnabled(getApiLevel() >= 2); - - ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - - if (ap != null) { - Article article = ap.getSelectedArticle(); - - if (article != null) { - m_menu.findItem(R.id.toggle_marked).setIcon(article.marked ? R.drawable.ic_important_light : - R.drawable.ic_unimportant_light); - - m_menu.findItem(R.id.toggle_published).setIcon(article.published ? R.drawable.ic_menu_published_light : - R.drawable.ic_menu_unpublished_light); - - m_menu.findItem(R.id.set_unread).setIcon(article.unread ? R.drawable.ic_unread_light : - R.drawable.ic_read_light); - } - } - - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - - if (hf != null) { - if (hf.getSelectedArticles().size() > 0 && m_headlinesActionMode == null) { - m_headlinesActionMode = startSupportActionMode(m_headlinesActionModeCallback); - } else if (hf.getSelectedArticles().size() == 0 && m_headlinesActionMode != null) { - m_headlinesActionMode.finish(); - } - } - - if (!isCompatMode()) { - SearchView searchView = (SearchView) search.getActionView(); - - if (searchView != null) { - searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - private String query = ""; - - @Override - public boolean onQueryTextSubmit(String query) { - HeadlinesFragment frag = (HeadlinesFragment) 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)) { - HeadlinesFragment frag = (HeadlinesFragment) getSupportFragmentManager() - .findFragmentByTag(FRAG_HEADLINES); - - if (frag != null) { - frag.setSearchQuery(newText); - this.query = newText; - } - } - - return false; - } - }); - } - } - } - } - - protected void refresh(boolean includeHeadlines) { - FeedCategoriesFragment cf = (FeedCategoriesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_CATS); - - if (cf != null) { - cf.refresh(false); - } - - FeedsFragment ff = (FeedsFragment) getSupportFragmentManager().findFragmentByTag(FRAG_FEEDS); - - if (ff != null) { - ff.refresh(false); - } - - if (includeHeadlines) { - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - - if (hf != null) { - hf.refresh(false); - } - - ArticlePager af = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - - if (af != null) { - af.refresh(false); - } - } - } - - protected void refresh() { - refresh(true); - } - - protected class LoginRequest extends ApiRequest { - boolean m_refreshAfterLogin = false; - OnLoginFinishedListener m_listener; - - public LoginRequest(Context context, boolean refresh, OnLoginFinishedListener listener) { - super(context); - m_refreshAfterLogin = refresh; - m_listener = listener; - } - - @SuppressWarnings("unchecked") - protected void onPostExecute(JsonElement result) { - if (result != null) { - try { - JsonObject content = result.getAsJsonObject(); - - if (content != null) { - setSessionId(content.get("session_id").getAsString()); - - JsonElement apiLevel = content.get("api_level"); - - GlobalState.getInstance().m_canUseProgress = m_canUseProgress; - - Log.d(TAG, "Authenticated! canUseProgress=" + m_canUseProgress); - - if (apiLevel != null) { - setApiLevel(apiLevel.getAsInt()); - Log.d(TAG, "Received API level: " + getApiLevel()); - - if (m_listener != null) { - m_listener.OnLoginSuccess(); - } else { - loginSuccess(m_refreshAfterLogin); - } - - } else { - - ApiRequest req = new ApiRequest(m_context) { - protected void onPostExecute(JsonElement result) { - setApiLevel(0); - - if (result != null) { - try { - setApiLevel(result.getAsJsonObject().get("level").getAsInt()); - } catch (Exception e) { - e.printStackTrace(); - } - } else if (m_lastError != ApiError.API_UNKNOWN_METHOD) { - // Unknown method means old tt-rss, in that case we assume API 0 and continue - - setLoadingStatus(getErrorMessage(), false); - - if (m_listener != null) { - m_listener.OnLoginFailed(); - } else { - loginFailure(); - } - - return; - } - - Log.d(TAG, "Received API level: " + getApiLevel()); - - loginSuccess(m_refreshAfterLogin); - - return; - } - }; - - @SuppressWarnings("serial") - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", getSessionId()); - put("op", "getApiLevel"); - } - }; - - req.execute(map); - - setLoadingStatus(R.string.loading_message, true); - } - - return; - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - setSessionId(null); - setLoadingStatus(getErrorMessage(), false); - - loginFailure(); - } - - } - - public void setViewMode(String viewMode) { - SharedPreferences.Editor editor = m_prefs.edit(); - editor.putString("view_mode", viewMode); - editor.commit(); - } - - public String getViewMode() { - return m_prefs.getString("view_mode", "adaptive"); - } - - public void setLastContentImageHitTestUrl(String url) { - m_lastImageHitTestUrl = url; - } - - public String getLastContentImageHitTestUrl() { - return m_lastImageHitTestUrl; - } - -} diff --git a/src/org/fox/ttrss/PreferencesActivity.java b/src/org/fox/ttrss/PreferencesActivity.java deleted file mode 100644 index f42154a7..00000000 --- a/src/org/fox/ttrss/PreferencesActivity.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.fox.ttrss; - -import android.os.Bundle; -import android.preference.PreferenceActivity; - -public class PreferencesActivity extends PreferenceActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - addPreferencesFromResource(R.xml.preferences); - - boolean compatMode = android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB; - - if (compatMode) { - findPreference("dim_status_bar").setEnabled(false); - findPreference("webview_hardware_accel").setEnabled(false); - } - - if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { - findPreference("enable_condensed_fonts").setEnabled(false); - } - } - -} 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(); - } - } - -} diff --git a/src/org/fox/ttrss/share/CommonActivity.java b/src/org/fox/ttrss/share/CommonActivity.java deleted file mode 100644 index 63458532..00000000 --- a/src/org/fox/ttrss/share/CommonActivity.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.fox.ttrss.share; - -import android.app.Activity; -import android.os.Bundle; -import android.util.Log; -import android.view.Display; -import android.widget.Toast; - -public class CommonActivity extends Activity { - private final String TAG = this.getClass().getSimpleName(); - - private boolean m_smallScreenMode = true; - private boolean m_compatMode = false; - - protected void setSmallScreen(boolean smallScreen) { - Log.d(TAG, "m_smallScreenMode=" + smallScreen); - m_smallScreenMode = smallScreen; - } - - public void toast(int msgId) { - Toast toast = Toast.makeText(CommonActivity.this, msgId, Toast.LENGTH_SHORT); - toast.show(); - } - - public void toast(String msg) { - Toast toast = Toast.makeText(CommonActivity.this, msg, Toast.LENGTH_SHORT); - toast.show(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - m_compatMode = android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB; - - Log.d(TAG, "m_compatMode=" + m_compatMode); - - super.onCreate(savedInstanceState); - } - - public boolean isSmallScreen() { - return m_smallScreenMode; - } - - public boolean isCompatMode() { - return m_compatMode; - } - - public boolean isPortrait() { - Display display = getWindowManager().getDefaultDisplay(); - - int width = display.getWidth(); - int height = display.getHeight(); - - return width < height; - } - - -} diff --git a/src/org/fox/ttrss/share/CommonShareActivity.java b/src/org/fox/ttrss/share/CommonShareActivity.java deleted file mode 100644 index 165d38f7..00000000 --- a/src/org/fox/ttrss/share/CommonShareActivity.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.fox.ttrss.share; - -import java.util.HashMap; - -import org.fox.ttrss.ApiRequest; -import org.fox.ttrss.PreferencesActivity; -import org.fox.ttrss.R; -import org.fox.ttrss.util.SimpleLoginManager; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.util.Log; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; - - -public abstract class CommonShareActivity extends CommonActivity { - protected SharedPreferences m_prefs; - protected String m_sessionId; - protected int m_apiLevel = 0; - - private final String TAG = this.getClass().getSimpleName(); - - @Override - public void onCreate(Bundle savedInstanceState) { - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - super.onCreate(savedInstanceState); - - if (savedInstanceState != null) { - m_sessionId = savedInstanceState.getString("sessionId"); - m_apiLevel = savedInstanceState.getInt("apiLevel"); - } - } - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - out.putString("sessionId", m_sessionId); - out.putInt("apiLevel", m_apiLevel); - } - - protected abstract void onLoggedIn(int requestId); - - protected abstract void onLoggingIn(int requestId); - - public void login(int requestId) { - - if (m_prefs.getString("ttrss_url", "").trim().length() == 0) { - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage(R.string.dialog_need_configure_prompt) - .setCancelable(false) - .setPositiveButton(R.string.dialog_open_preferences, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - // launch preferences - - Intent intent = new Intent(CommonShareActivity.this, - PreferencesActivity.class); - startActivityForResult(intent, 0); - } - }) - .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - AlertDialog alert = builder.create(); - alert.show(); - - } else { - - SimpleLoginManager loginManager = new SimpleLoginManager() { - - @Override - protected void onLoginSuccess(int requestId, String sessionId, int apiLevel) { - m_sessionId = sessionId; - m_apiLevel = apiLevel; - - CommonShareActivity.this.onLoggedIn(requestId); - } - - @Override - protected void onLoginFailed(int requestId, ApiRequest ar) { - toast(ar.getErrorMessage()); - setProgressBarIndeterminateVisibility(false); - } - - @Override - protected void onLoggingIn(int requestId) { - CommonShareActivity.this.onLoggingIn(requestId); - } - }; - - String login = m_prefs.getString("login", "").trim(); - String password = m_prefs.getString("password", "").trim(); - - loginManager.logIn(this, requestId, login, password); - } - } - - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.preferences: - Intent intent = new Intent(CommonShareActivity.this, - PreferencesActivity.class); - startActivityForResult(intent, 0); - 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.share_menu, menu); - return true; - } - - - -} diff --git a/src/org/fox/ttrss/share/ShareActivity.java b/src/org/fox/ttrss/share/ShareActivity.java deleted file mode 100644 index dff48502..00000000 --- a/src/org/fox/ttrss/share/ShareActivity.java +++ /dev/null @@ -1,146 +0,0 @@ -package org.fox.ttrss.share; - -import java.util.HashMap; - -import org.fox.ttrss.ApiRequest; -import org.fox.ttrss.R; - -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.view.Window; -import android.widget.Button; -import android.widget.EditText; - -import com.google.gson.JsonElement; - -public class ShareActivity extends CommonShareActivity { - private final String TAG = this.getClass().getSimpleName(); - - private Button m_button; - - @Override - public void onCreate(Bundle savedInstanceState) { - //setTheme(R.style.DarkTheme); - - super.onCreate(savedInstanceState); - - requestWindowFeature(Window.FEATURE_LEFT_ICON); - - Intent intent = getIntent(); - - String urlValue = intent.getStringExtra(Intent.EXTRA_TEXT); - String titleValue = intent.getStringExtra(Intent.EXTRA_SUBJECT); - String contentValue = ""; - - if (savedInstanceState != null) { - urlValue = savedInstanceState.getString("url"); - titleValue = savedInstanceState.getString("title"); - contentValue = savedInstanceState.getString("content"); - } - - setContentView(R.layout.share); - - getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.icon); - - setSmallScreen(false); - - EditText url = (EditText) findViewById(R.id.url); - url.setText(urlValue); - - EditText title = (EditText) findViewById(R.id.title); - title.setText(titleValue); - - EditText content = (EditText) findViewById(R.id.content); - content.setText(contentValue); - - m_button = (Button) findViewById(R.id.share_button); - - m_button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - login(0); - } - }); - } - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - EditText url = (EditText) findViewById(R.id.url); - - if (url != null) { - out.putString("url", url.getText().toString()); - } - - EditText title = (EditText) findViewById(R.id.title); - - if (title != null) { - out.putString("title", title.getText().toString()); - } - - EditText content = (EditText) findViewById(R.id.content); - - if (content != null) { - out.putString("content", content.getText().toString()); - } - - } - - private void postData() { - m_button.setEnabled(false); - - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - setProgressBarIndeterminateVisibility(false); - - if (m_lastError != ApiError.NO_ERROR) { - toast(getErrorMessage()); - } else { - toast(R.string.share_article_posted); - finish(); - } - - m_button.setEnabled(true); - } - }; - - final EditText url = (EditText) findViewById(R.id.url); - final EditText title = (EditText) findViewById(R.id.title); - final EditText content = (EditText) findViewById(R.id.content); - - if (url != null && title != null && content != null) { - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "shareToPublished"); - put("title", title.getText().toString()); - put("url", url.getText().toString()); - put("content", content.getText().toString()); - } - }; - - setProgressBarIndeterminateVisibility(true); - - req.execute(map); - } - } - - - @Override - public void onLoggingIn(int requestId) { - m_button.setEnabled(false); - } - - @Override - protected void onLoggedIn(int requestId) { - m_button.setEnabled(true); - - if (m_apiLevel < 4) { - toast(R.string.api_too_low); - } else { - postData(); - } - } -} diff --git a/src/org/fox/ttrss/share/SubscribeActivity.java b/src/org/fox/ttrss/share/SubscribeActivity.java deleted file mode 100644 index bd7e964f..00000000 --- a/src/org/fox/ttrss/share/SubscribeActivity.java +++ /dev/null @@ -1,321 +0,0 @@ -package org.fox.ttrss.share; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; - -import org.fox.ttrss.ApiRequest; -import org.fox.ttrss.R; -import org.fox.ttrss.types.FeedCategory; -import org.fox.ttrss.types.FeedCategoryList; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.view.Window; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Spinner; - -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; - -public class SubscribeActivity extends CommonShareActivity { - private final String TAG = this.getClass().getSimpleName(); - - private Button m_postButton; - private Button m_catButton; - private CatListAdapter m_adapter; - private FeedCategoryList m_cats = new FeedCategoryList(); - - private static final int REQ_CATS = 1; - private static final int REQ_POST = 2; - - class CatTitleComparator implements Comparator<FeedCategory> { - - @Override - public int compare(FeedCategory a, FeedCategory b) { - if (a.id >= 0 && b.id >= 0) - return a.title.compareTo(b.title); - else - return a.id - b.id; - } - - } - - public void sortCats() { - Comparator<FeedCategory> cmp = new CatTitleComparator(); - - Collections.sort(m_cats, cmp); - try { - m_adapter.notifyDataSetChanged(); - } catch (NullPointerException e) { - // adapter missing - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - requestWindowFeature(Window.FEATURE_LEFT_ICON); - - String urlValue = getIntent().getDataString(); - - if (urlValue == null) - urlValue = getIntent().getStringExtra(Intent.EXTRA_TEXT); - - if (savedInstanceState != null) { - urlValue = savedInstanceState.getString("url"); - - ArrayList<FeedCategory> list = savedInstanceState.getParcelableArrayList("cats"); - - for (FeedCategory c : list) - m_cats.add(c); - } - - setContentView(R.layout.subscribe); - - getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.icon); - - setSmallScreen(false); - - Spinner catList = (Spinner) findViewById(R.id.category_spinner); - - if (m_cats.size() == 0) m_cats.add(new FeedCategory(0, "Uncategorized", 0)); - - m_adapter = new CatListAdapter(this, android.R.layout.simple_spinner_dropdown_item, m_cats); - catList.setAdapter(m_adapter); - - EditText feedUrl = (EditText) findViewById(R.id.feed_url); - feedUrl.setText(urlValue); - - m_postButton = (Button) findViewById(R.id.subscribe_button); - - m_postButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - login(REQ_POST); - } - }); - - m_catButton = (Button) findViewById(R.id.cats_button); - - m_catButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - login(REQ_CATS); - } - }); - - login(REQ_CATS); - } - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - EditText url = (EditText) findViewById(R.id.url); - - if (url != null) { - out.putString("url", url.getText().toString()); - } - - out.putParcelableArrayList("cats", m_cats); - - } - - private void subscribeToFeed() { - m_postButton.setEnabled(false); - - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - setProgressBarIndeterminateVisibility(false); - - if (m_lastError != ApiError.NO_ERROR) { - toast(getErrorMessage()); - } else { - try { - int rc = -1; - - try { - rc = result.getAsJsonObject().get("status").getAsJsonObject().get("code").getAsInt(); - } catch (Exception e) { - e.printStackTrace(); - } - - switch (rc) { - case -1: - toast(R.string.error_api_unknown); - //finish(); - break; - case 0: - toast(R.string.error_feed_already_exists_); - //finish(); - break; - case 1: - toast(R.string.subscribed_to_feed); - finish(); - break; - case 2: - toast(R.string.error_invalid_url); - break; - case 3: - toast(R.string.error_url_is_an_html_page_no_feeds_found); - break; - case 4: - toast(R.string.error_url_contains_multiple_feeds); - break; - case 5: - toast(R.string.error_could_not_download_url); - break; - } - - } catch (Exception e) { - toast(R.string.error_while_subscribing); - e.printStackTrace(); - } - } - - m_postButton.setEnabled(true); - } - }; - - Spinner catSpinner = (Spinner) findViewById(R.id.category_spinner); - - final FeedCategory cat = (FeedCategory) m_adapter.getCategory(catSpinner.getSelectedItemPosition()); - final EditText feedUrl = (EditText) findViewById(R.id.feed_url); - - if (feedUrl != null ) { - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "subscribeToFeed"); - put("feed_url", feedUrl.getText().toString()); - - if (cat != null) { - put("category_id", String.valueOf(cat.id)); - } - } - }; - - setProgressBarIndeterminateVisibility(true); - - req.execute(map); - } - } - - @Override - public void onLoggingIn(int requestId) { - switch (requestId) { - case REQ_CATS: - m_catButton.setEnabled(false); - break; - case REQ_POST: - m_postButton.setEnabled(false); - break; - } - } - - private void updateCats() { - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected void onPostExecute(JsonElement result) { - setProgressBarIndeterminateVisibility(false); - - if (m_lastError != ApiError.NO_ERROR) { - toast(getErrorMessage()); - } else { - JsonArray content = result.getAsJsonArray(); - - if (content != null) { - Type listType = new TypeToken<List<FeedCategory>>() {}.getType(); - final List<FeedCategory> cats = new Gson().fromJson(content, listType); - - m_cats.clear(); - - for (FeedCategory c : cats) { - if (c.id > 0) - m_cats.add(c); - } - - sortCats(); - - m_cats.add(0, new FeedCategory(0, "Uncategorized", 0)); - - m_adapter.notifyDataSetChanged(); - - toast(R.string.category_list_updated); - } - } - - m_catButton.setEnabled(true); - } - }; - - HashMap<String, String> map = new HashMap<String, String>() { - { - put("sid", m_sessionId); - put("op", "getCategories"); - } - }; - - setProgressBarIndeterminateVisibility(true); - - req.execute(map); - } - - @Override - protected void onLoggedIn(int requestId) { - switch (requestId) { - case REQ_CATS: - updateCats(); - break; - case REQ_POST: - m_postButton.setEnabled(true); - if (m_apiLevel < 5) { - toast(R.string.api_too_low); - } else { - subscribeToFeed(); - } - break; - } - } - - private class CatListAdapter extends ArrayAdapter<String> { - private List<FeedCategory> m_items; - - public CatListAdapter(Context context, int resource, - List<FeedCategory> items) { - super(context, resource); - - m_items = items; - } - - @Override - public String getItem(int item) { - return m_items.get(item).title; - } - - public FeedCategory getCategory(int item) { - try { - return m_items.get(item); - } catch (ArrayIndexOutOfBoundsException e) { - return null; - } - } - - @Override - public int getCount() { - return m_items.size(); - } - } - -} diff --git a/src/org/fox/ttrss/tasker/TaskerReceiver.java b/src/org/fox/ttrss/tasker/TaskerReceiver.java deleted file mode 100644 index 3981af7c..00000000 --- a/src/org/fox/ttrss/tasker/TaskerReceiver.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.fox.ttrss.tasker;
-
-import org.fox.ttrss.ApiRequest;
-import org.fox.ttrss.CommonActivity;
-import org.fox.ttrss.OnlineActivity;
-import org.fox.ttrss.offline.OfflineDownloadService;
-import org.fox.ttrss.offline.OfflineUploadService;
-import org.fox.ttrss.util.SimpleLoginManager;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.util.Log;
-import android.widget.Toast;
-
-public class TaskerReceiver extends BroadcastReceiver {
- private final String TAG = this.getClass().getSimpleName();
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.d(TAG, "Got action: " + intent.getAction());
-
- final Context fContext = context;
-
- if (com.twofortyfouram.locale.Intent.ACTION_FIRE_SETTING.equals(intent.getAction())) {
-
- final Bundle settings = intent.getBundleExtra(com.twofortyfouram.locale.Intent.EXTRA_BUNDLE);
- final int actionId = settings != null ? settings.getInt("actionId", -1) : -1;
-
- Log.d(TAG, "received action id=" + actionId);
-
- SimpleLoginManager loginMgr = new SimpleLoginManager() {
-
- @Override
- protected void onLoginSuccess(int requestId, String sessionId, int apiLevel) {
-
- switch (actionId) {
- case TaskerSettingsActivity.ACTION_DOWNLOAD:
- if (true) {
- Intent intent = new Intent(fContext,
- OfflineDownloadService.class);
- intent.putExtra("sessionId", sessionId);
- intent.putExtra("batchMode", true);
-
- fContext.startService(intent);
- }
- break;
- case TaskerSettingsActivity.ACTION_UPLOAD:
- if (true) {
- Intent intent = new Intent(fContext,
- OfflineUploadService.class);
- intent.putExtra("sessionId", sessionId);
- intent.putExtra("batchMode", true);
-
- fContext.startService(intent);
- }
- break;
- default:
- Log.d(TAG, "unknown action id=" + actionId);
- }
- }
-
- @Override
- protected void onLoginFailed(int requestId, ApiRequest ar) {
- Toast toast = Toast.makeText(fContext, fContext.getString(ar.getErrorMessage()), Toast.LENGTH_SHORT);
- toast.show();
- }
-
- @Override
- protected void onLoggingIn(int requestId) {
- //
- }
- };
-
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-
- String login = prefs.getString("login", "").trim();
- String password = prefs.getString("password", "").trim();
- String ttrssUrl = prefs.getString("ttrss_url", "").trim();
-
- if (ttrssUrl.equals("")) {
- Toast toast = Toast.makeText(fContext, "Could not download articles: not configured?", Toast.LENGTH_SHORT);
- toast.show();
- } else {
- loginMgr.logIn(context, 1, login, password);
- }
- }
- }
-
-}
diff --git a/src/org/fox/ttrss/tasker/TaskerSettingsActivity.java b/src/org/fox/ttrss/tasker/TaskerSettingsActivity.java deleted file mode 100644 index ff56ad1a..00000000 --- a/src/org/fox/ttrss/tasker/TaskerSettingsActivity.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.fox.ttrss.tasker;
-
-import org.fox.ttrss.R;
-import org.fox.ttrss.offline.OfflineDownloadService;
-import org.fox.ttrss.offline.OfflineUploadService;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.RadioGroup;
-import android.widget.RadioGroup.OnCheckedChangeListener;
-
-public class TaskerSettingsActivity extends Activity {
- protected static final int ACTION_DOWNLOAD = 0;
- protected static final int ACTION_UPLOAD = 1;
-
- private final String TAG = this.getClass().getSimpleName();
-
- protected Bundle m_settings = new Bundle();
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- Bundle settings = getIntent().getBundleExtra(com.twofortyfouram.locale.Intent.EXTRA_BUNDLE);
-
- int actionId = settings != null ? settings.getInt("actionId", -1) : -1;
-
- setContentView(R.layout.tasker_settings);
-
- RadioGroup radioGroup = (RadioGroup) findViewById(R.id.taskerActions);
-
- switch (actionId) {
- case TaskerSettingsActivity.ACTION_DOWNLOAD:
- radioGroup.check(R.id.actionDownload);
- break;
- case TaskerSettingsActivity.ACTION_UPLOAD:
- radioGroup.check(R.id.actionUpload);
- break;
- default:
- Log.d(TAG, "unknown action id=" + actionId);
- }
-
- radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(RadioGroup group, int checkedId) {
- switch (checkedId) {
- case R.id.actionDownload:
- m_settings.putInt("actionId", ACTION_DOWNLOAD);
- break;
- case R.id.actionUpload:
- m_settings.putInt("actionId", ACTION_UPLOAD);
- break;
- }
- }
- });
-
- Button button = (Button)findViewById(R.id.close_button);
-
- button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
- }
-
- @Override
- public void finish() {
- final Intent intent = new Intent();
-
- intent.putExtra(com.twofortyfouram.locale.Intent.EXTRA_BUNDLE, m_settings);
-
- String blurb = "?";
-
- switch (m_settings.getInt("actionId")) {
- case TaskerSettingsActivity.ACTION_DOWNLOAD:
- blurb = getString(R.string.download_articles_and_go_offline);
- break;
- case TaskerSettingsActivity.ACTION_UPLOAD:
- blurb = getString(R.string.synchronize_read_articles_and_go_online);
- break;
- }
-
- intent.putExtra(com.twofortyfouram.locale.Intent.EXTRA_STRING_BLURB, blurb);
-
- setResult(RESULT_OK, intent);
-
- super.finish();
-
- }
-}
diff --git a/src/org/fox/ttrss/types/Article.java b/src/org/fox/ttrss/types/Article.java deleted file mode 100644 index 9beea81a..00000000 --- a/src/org/fox/ttrss/types/Article.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.fox.ttrss.types; -import java.util.ArrayList; -import java.util.List; - - -import android.os.Parcel; -import android.os.Parcelable; - -// TODO: serialize Labels -public class Article implements Parcelable { - public int id; - public boolean unread; - public boolean marked; - public boolean published; - public int score; - public int updated; - public boolean is_updated; - public String title; - public String link; - public int feed_id; - public List<String> tags; - public List<Attachment> attachments; - public String content; - public List<List<String>> labels; - public String feed_title; - public int comments_count; - public String comments_link; - public boolean always_display_attachments; - public String author; - public String note; - - public Article(Parcel in) { - readFromParcel(in); - } - - public Article() { - - } - - public Article(int id) { - this.id = id; - this.title = ""; - this.link = ""; - this.tags = new ArrayList<String>(); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(id); - out.writeInt(unread ? 1 : 0); - out.writeInt(marked ? 1 : 0); - out.writeInt(published ? 1 : 0); - out.writeInt(score); - out.writeInt(updated); - out.writeInt(is_updated ? 1 : 0); - out.writeString(title); - out.writeString(link); - out.writeInt(feed_id); - out.writeStringList(tags); - out.writeString(content); - out.writeList(attachments); - out.writeString(feed_title); - out.writeInt(comments_count); - out.writeString(comments_link); - out.writeInt(always_display_attachments ? 1 : 0); - out.writeString(author); - out.writeString(note); - } - - public void readFromParcel(Parcel in) { - id = in.readInt(); - unread = in.readInt() == 1; - marked = in.readInt() == 1; - published = in.readInt() == 1; - score = in.readInt(); - updated = in.readInt(); - is_updated = in.readInt() == 1; - title = in.readString(); - link = in.readString(); - feed_id = in.readInt(); - - if (tags == null) tags = new ArrayList<String>(); - in.readStringList(tags); - - content = in.readString(); - - attachments = new ArrayList<Attachment>(); - in.readList(attachments, Attachment.class.getClassLoader()); - - feed_title = in.readString(); - - comments_count = in.readInt(); - comments_link = in.readString(); - always_display_attachments = in.readInt() == 1; - author = in.readString(); - note = in.readString(); - } - - @SuppressWarnings("rawtypes") - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public Article createFromParcel(Parcel in) { - return new Article(in); - } - - public Article[] newArray(int size) { - return new Article[size]; - } - }; -} diff --git a/src/org/fox/ttrss/types/ArticleList.java b/src/org/fox/ttrss/types/ArticleList.java deleted file mode 100644 index c9b491ee..00000000 --- a/src/org/fox/ttrss/types/ArticleList.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.fox.ttrss.types; - -import java.util.ArrayList; - - -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -@SuppressWarnings("serial") -public class ArticleList extends ArrayList<Article> implements Parcelable { - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeList(this); - } - - public Article findById(int id) { - for (Article a : this) { - if (a.id == id) - return a; - } - return null; - } - - public void readFromParcel(Parcel in) { - in.readList(this, getClass().getClassLoader()); - } - - public ArticleList() { } - - public ArticleList(Parcel in) { - readFromParcel(in); - } - - public boolean containsId(int id) { - for (Article a : this) { - if (a.id == id) - return true; - } - return false; - } - - @SuppressWarnings("rawtypes") - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public ArticleList createFromParcel(Parcel in) { - return new ArticleList(in); - } - - public ArticleList[] newArray(int size) { - return new ArticleList[size]; - } - }; -}
\ No newline at end of file diff --git a/src/org/fox/ttrss/types/Attachment.java b/src/org/fox/ttrss/types/Attachment.java deleted file mode 100644 index 9e363dba..00000000 --- a/src/org/fox/ttrss/types/Attachment.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.fox.ttrss.types; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; - -import android.os.Parcel; -import android.os.Parcelable; - -public class Attachment implements Parcelable { - public int id; - public String content_url; - public String content_type; - public String title; - public String duration; - public int post_id; - - public Attachment(Parcel in) { - readFromParcel(in); - } - - public Attachment() { - - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(id); - out.writeString(content_url); - out.writeString(content_type); - out.writeString(title); - out.writeString(duration); - out.writeInt(post_id); - } - - public String toString() { - if (title != null && title.length() > 0) { - return title; - } else { - try { - URL url = new URL(content_url.trim()); - return new File(url.getFile()).getName(); - } catch (MalformedURLException e) { - return content_url; - } - } - } - - public void readFromParcel(Parcel in) { - id = in.readInt(); - content_url = in.readString(); - content_type = in.readString(); - title = in.readString(); - duration = in.readString(); - post_id = in.readInt(); - } - - @SuppressWarnings("rawtypes") - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public Attachment createFromParcel(Parcel in) { - return new Attachment(in); - } - - public Attachment[] newArray(int size) { - return new Attachment[size]; - } - }; - -} diff --git a/src/org/fox/ttrss/types/Feed.java b/src/org/fox/ttrss/types/Feed.java deleted file mode 100644 index 6cf4a1b1..00000000 --- a/src/org/fox/ttrss/types/Feed.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.fox.ttrss.types; - -import android.os.Parcel; -import android.os.Parcelable; - -public class Feed implements Comparable<Feed>, Parcelable { - public String feed_url; - public String title; - public int id; - public int unread; - public boolean has_icon; - public int cat_id; - public int last_updated; - public int order_id; - public boolean is_cat; - - public Feed(int id, String title, boolean is_cat) { - this.id = id; - this.title = title; - this.is_cat = is_cat; - } - - public Feed(Parcel in) { - readFromParcel(in); - } - - public Feed() { - - } - - public boolean equals(Feed feed) { - if (feed == this) - return true; - - if (feed == null) - return false; - - return feed.id == this.id && (this.title == null || this.title.equals(feed.title)) && this.is_cat == feed.is_cat; - } - - @Override - public int compareTo(Feed feed) { - if (feed.unread != this.unread) - return feed.unread - this.unread; - else - return this.title.compareTo(feed.title); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeString(feed_url); - out.writeString(title); - out.writeInt(id); - out.writeInt(unread); - out.writeInt(has_icon ? 1 : 0); - out.writeInt(cat_id); - out.writeInt(last_updated); - out.writeInt(is_cat ? 1 : 0); - out.writeInt(order_id); - } - - public void readFromParcel(Parcel in) { - feed_url = in.readString(); - title = in.readString(); - id = in.readInt(); - unread = in.readInt(); - has_icon = in.readInt() == 1; - cat_id = in.readInt(); - last_updated = in.readInt(); - is_cat = in.readInt() == 1; - order_id = in.readInt(); - } - - @SuppressWarnings("rawtypes") - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public Feed createFromParcel(Parcel in) { - return new Feed(in); - } - - public Feed[] newArray(int size) { - return new Feed[size]; - } - }; -}
\ No newline at end of file diff --git a/src/org/fox/ttrss/types/FeedCategory.java b/src/org/fox/ttrss/types/FeedCategory.java deleted file mode 100644 index c8193f94..00000000 --- a/src/org/fox/ttrss/types/FeedCategory.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.fox.ttrss.types; - -import android.os.Parcel; -import android.os.Parcelable; - -public class FeedCategory implements Parcelable { - public int id; - public String title; - public int unread; - public int order_id; - - public FeedCategory(Parcel in) { - readFromParcel(in); - } - - public FeedCategory(int id, String title, int unread) { - this.id = id; - this.title = title; - this.unread = unread; - this.order_id = 0; - } - - public FeedCategory() { - - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(id); - out.writeString(title); - out.writeInt(unread); - out.writeInt(order_id); - } - - public void readFromParcel(Parcel in) { - id = in.readInt(); - title = in.readString(); - unread = in.readInt(); - order_id = in.readInt(); - } - - @SuppressWarnings("rawtypes") - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public FeedCategory createFromParcel(Parcel in) { - return new FeedCategory(in); - } - - public FeedCategory[] newArray(int size) { - return new FeedCategory[size]; - } - }; -} diff --git a/src/org/fox/ttrss/types/FeedCategoryList.java b/src/org/fox/ttrss/types/FeedCategoryList.java deleted file mode 100644 index eb5331bc..00000000 --- a/src/org/fox/ttrss/types/FeedCategoryList.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.fox.ttrss.types; - -import java.util.ArrayList; - - -import android.os.Parcel; -import android.os.Parcelable; - -@SuppressWarnings("serial") -public class FeedCategoryList extends ArrayList<FeedCategory> implements Parcelable { - - public FeedCategoryList() { } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeList(this); - } - - public void readFromParcel(Parcel in) { - in.readList(this, getClass().getClassLoader()); - } - - public FeedCategoryList(Parcel in) { - readFromParcel(in); - } - - @SuppressWarnings("rawtypes") - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public FeedCategoryList createFromParcel(Parcel in) { - return new FeedCategoryList(in); - } - - public FeedCategoryList[] newArray(int size) { - return new FeedCategoryList[size]; - } - }; - } diff --git a/src/org/fox/ttrss/types/FeedList.java b/src/org/fox/ttrss/types/FeedList.java deleted file mode 100644 index 350f45ad..00000000 --- a/src/org/fox/ttrss/types/FeedList.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.fox.ttrss.types; - -import java.util.ArrayList; - - -import android.os.Parcel; -import android.os.Parcelable; - -@SuppressWarnings("serial") -public class FeedList extends ArrayList<Feed> implements Parcelable { - - public FeedList() { } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeList(this); - } - - public void readFromParcel(Parcel in) { - in.readList(this, getClass().getClassLoader()); - } - - public FeedList(Parcel in) { - readFromParcel(in); - } - - @SuppressWarnings("rawtypes") - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public FeedList createFromParcel(Parcel in) { - return new FeedList(in); - } - - public FeedList[] newArray(int size) { - return new FeedList[size]; - } - }; - } diff --git a/src/org/fox/ttrss/types/Label.java b/src/org/fox/ttrss/types/Label.java deleted file mode 100644 index 0d4f3699..00000000 --- a/src/org/fox/ttrss/types/Label.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.fox.ttrss.types; - -public class Label { - public int id; - public String caption; - public String fg_color; - public String bg_color; - public boolean checked; - - public Label() { - - } -} diff --git a/src/org/fox/ttrss/util/AppRater.java b/src/org/fox/ttrss/util/AppRater.java deleted file mode 100644 index 21dccdff..00000000 --- a/src/org/fox/ttrss/util/AppRater.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.fox.ttrss.util; - -// From http://androidsnippets.com/prompt-engaged-users-to-rate-your-app-in-the-android-market-appirater - -import android.app.Dialog; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.TextView; - -public class AppRater { - private final static String APP_TITLE = "Tiny Tiny RSS"; - private final static String APP_PNAME = "org.fox.ttrss"; - - private final static int DAYS_UNTIL_PROMPT = 3; - private final static int LAUNCHES_UNTIL_PROMPT = 7; - - public static void appLaunched(Context mContext) { - SharedPreferences prefs = mContext.getSharedPreferences("apprater", 0); - - if (prefs.getBoolean("dontshowagain", false)) { return ; } - - SharedPreferences.Editor editor = prefs.edit(); - - // Increment launch counter - long launch_count = prefs.getLong("launch_count", 0) + 1; - editor.putLong("launch_count", launch_count); - - // Get date of first launch - Long date_firstLaunch = prefs.getLong("date_firstlaunch", 0); - if (date_firstLaunch == 0) { - date_firstLaunch = System.currentTimeMillis(); - editor.putLong("date_firstlaunch", date_firstLaunch); - } - - // Wait at least n days before opening - if (launch_count >= LAUNCHES_UNTIL_PROMPT && - !prefs.getBoolean("dontshowagain", false) && - System.currentTimeMillis() >= date_firstLaunch + (DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000)) { - - showRateDialog(mContext, editor); - } - - editor.commit(); - } - - public static void showRateDialog(final Context mContext, final SharedPreferences.Editor editor) { - final Dialog dialog = new Dialog(mContext); - dialog.setTitle("Rate " + APP_TITLE); - - LinearLayout ll = new LinearLayout(mContext); - ll.setOrientation(LinearLayout.VERTICAL); - - TextView tv = new TextView(mContext); - tv.setText("If you enjoy using " + APP_TITLE + ", please take a moment to rate it. Thanks for your support!"); - tv.setWidth(240); - tv.setPadding(4, 0, 4, 10); - ll.addView(tv); - - Button b1 = new Button(mContext); - b1.setText("Rate " + APP_TITLE); - b1.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - try { - mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + APP_PNAME))); - } catch (ActivityNotFoundException e) { - mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + APP_PNAME))); - } - dialog.dismiss(); - } - }); - ll.addView(b1); - - Button b2 = new Button(mContext); - b2.setText("Remind me later"); - b2.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - dialog.dismiss(); - } - }); - ll.addView(b2); - - Button b3 = new Button(mContext); - b3.setText("No, thanks"); - b3.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - if (editor != null) { - editor.putBoolean("dontshowagain", true); - editor.commit(); - } - dialog.dismiss(); - } - }); - ll.addView(b3); - - dialog.setContentView(ll); - dialog.show(); - } -}
\ No newline at end of file diff --git a/src/org/fox/ttrss/util/DatabaseHelper.java b/src/org/fox/ttrss/util/DatabaseHelper.java deleted file mode 100644 index 572ff62e..00000000 --- a/src/org/fox/ttrss/util/DatabaseHelper.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.fox.ttrss.util; -import android.content.Context; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.provider.BaseColumns; - - -public class DatabaseHelper extends SQLiteOpenHelper { - - @SuppressWarnings("unused") - private final String TAG = this.getClass().getSimpleName(); - public static final String DATABASE_NAME = "OfflineStorage.db"; - public static final int DATABASE_VERSION = 4; - - public DatabaseHelper(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - } - - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL("DROP VIEW IF EXISTS cats_unread;"); - db.execSQL("DROP VIEW IF EXISTS feeds_unread;"); - db.execSQL("DROP TRIGGER IF EXISTS articles_set_modified;"); - db.execSQL("DROP TABLE IF EXISTS categories;"); - db.execSQL("DROP TABLE IF EXISTS feeds;"); - db.execSQL("DROP TABLE IF EXISTS articles;"); - - db.execSQL("CREATE TABLE IF NOT EXISTS feeds (" + - BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + - "feed_url TEXT, " + - "title TEXT, " + - "has_icon BOOLEAN, " + - "cat_id INTEGER" + - ");"); - - db.execSQL("CREATE TABLE IF NOT EXISTS categories (" + - BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + - "title TEXT" + - ");"); - - db.execSQL("CREATE TABLE IF NOT EXISTS articles (" + - BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + - "unread BOOLEAN, " + - "marked BOOLEAN, " + - "published BOOLEAN, " + - "score INTEGER, " + - "updated INTEGER, " + - "is_updated BOOLEAN, " + - "title TEXT, " + - "link TEXT, " + - "feed_id INTEGER, " + - "tags TEXT, " + - "content TEXT, " + - "author TEXT, " + - "selected BOOLEAN, " + - "modified BOOLEAN" + - ");"); - - db.execSQL("CREATE TRIGGER articles_set_modified UPDATE OF marked, published, unread ON articles " + - "BEGIN " + - " UPDATE articles SET modified = 1 WHERE " + BaseColumns._ID + " = " + "OLD." + BaseColumns._ID + "; " + - "END;"); - - db.execSQL("CREATE VIEW feeds_unread AS SELECT feeds."+BaseColumns._ID+" AS "+BaseColumns._ID+", " + - "feeds.title AS title, " + - "cat_id, " + - "SUM(articles.unread) AS unread FROM feeds " + - "LEFT JOIN articles ON (articles.feed_id = feeds."+BaseColumns._ID+") " + - "GROUP BY feeds."+BaseColumns._ID+", feeds.title;"); - - //sqlite> select categories._id,categories.title,sum(articles.unread) from categories left j - //oin feeds on (feeds.cat_id = categories._id) left join articles on (articles.feed_id = fee - //ds._id) group by categories._id; - - db.execSQL("CREATE VIEW cats_unread AS SELECT categories."+BaseColumns._ID+" AS "+BaseColumns._ID+", " + - "categories.title AS title, " + - "SUM(articles.unread) AS unread FROM categories " + - "LEFT JOIN feeds ON (feeds.cat_id = categories."+BaseColumns._ID+") "+ - "LEFT JOIN articles ON (articles.feed_id = feeds."+BaseColumns._ID+") " + - "GROUP BY categories."+BaseColumns._ID+", categories.title;"); - - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - onCreate(db); - } - -} diff --git a/src/org/fox/ttrss/util/EnlargingImageView.java b/src/org/fox/ttrss/util/EnlargingImageView.java deleted file mode 100644 index b6f9bce9..00000000 --- a/src/org/fox/ttrss/util/EnlargingImageView.java +++ /dev/null @@ -1,252 +0,0 @@ -package org.fox.ttrss.util;
-
-/*
- * Copyright (C) 2013 Tomáš Procházka
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.lang.reflect.Field;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Special version of ImageView which allow enlarge width of image if android:adjustViewBounds is true.
- *
- * <p>It simulate HTML behaviour <img src="" widh="100" /></p>
- * <p><a href="http://stackoverflow.com/questions/6202000/imageview-one-dimension-to-fit-free-space-and-second-evaluate-to-keep-aspect-rati">Stackoverflow question link</a></p>
- *
- * <p>It also allow set related view which will be used as reference for size measure.</p>
- *
- * @author Tomáš Procházka <<a href="mailto:[email protected]">[email protected]</a>>
- * @version $Revision: 0$ ($Date: 6.6.2011 18:16:52$)
- */
-public class EnlargingImageView extends android.widget.ImageView {
-
- private int mDrawableWidth;
- private int mDrawableHeight;
- private boolean mAdjustViewBoundsL;
- private int mMaxWidthL = Integer.MAX_VALUE;
- private int mMaxHeightL = Integer.MAX_VALUE;
- private View relatedView;
-
- public EnlargingImageView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- // hack for acces some private field of parent :-(
- Field f;
- try {
- f = android.widget.ImageView.class.getDeclaredField("mAdjustViewBounds");
- f.setAccessible(true);
- setAdjustViewBounds((Boolean) f.get(this));
-
- f = android.widget.ImageView.class.getDeclaredField("mMaxWidth");
- f.setAccessible(true);
- setMaxWidth((Integer) f.get(this));
-
- f = android.widget.ImageView.class.getDeclaredField("mMaxHeight");
- f.setAccessible(true);
- setMaxHeight((Integer) f.get(this));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public EnlargingImageView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public EnlargingImageView(Context context) {
- super(context);
- }
-
- public void setAdjustViewBounds(boolean adjustViewBounds) {
- super.setAdjustViewBounds(adjustViewBounds);
- mAdjustViewBoundsL = adjustViewBounds;
- }
-
- public void setMaxWidth(int maxWidth) {
- super.setMaxWidth(maxWidth);
- mMaxWidthL = maxWidth;
- }
-
- public void setMaxHeight(int maxHeight) {
- super.setMaxHeight(maxHeight);
- mMaxHeightL = maxHeight;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
- if (getDrawable() == null) {
- setMeasuredDimension(0, 0);
- return;
- }
-
- mDrawableWidth = getDrawable().getIntrinsicWidth();
- mDrawableHeight = getDrawable().getIntrinsicHeight();
-
- int w = 0;
- int h = 0;
-
- // Desired aspect ratio of the view's contents (not including padding)
- float desiredAspect = 0.0f;
-
- // We are allowed to change the view's width
- boolean resizeWidth = false;
-
- // We are allowed to change the view's height
- boolean resizeHeight = false;
-
- if (mDrawableWidth > 0) {
- w = mDrawableWidth;
- h = mDrawableHeight;
- if (w <= 0) w = 1;
- if (h <= 0) h = 1;
-
- // We are supposed to adjust view bounds to match the aspect
- // ratio of our drawable. See if that is possible.
- if (mAdjustViewBoundsL) {
-
- int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
- int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
-
- resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
- resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
-
- desiredAspect = (float) w / (float) h;
- }
- }
-
- int pleft = getPaddingLeft();
- int pright = getPaddingRight();
- int ptop = getPaddingTop();
- int pbottom = getPaddingBottom();
-
- int widthSize;
- int heightSize;
-
- if (resizeWidth || resizeHeight) {
- /* If we get here, it means we want to resize to match the
- drawables aspect ratio, and we have the freedom to change at
- least one dimension.
- */
-
- // Get the max possible width given our constraints
- widthSize = resolveAdjustedSize(w + pleft + pright,
- mMaxWidthL, widthMeasureSpec);
-
- // Get the max possible height given our constraints
- heightSize = resolveAdjustedSize(h + ptop + pbottom,
- mMaxHeightL, heightMeasureSpec);
-
- if (desiredAspect != 0.0f) {
- // See what our actual aspect ratio is
- float actualAspect = (float) (widthSize - pleft - pright) /
- (heightSize - ptop - pbottom);
-
- if (Math.abs(actualAspect - desiredAspect) > 0.0000001) {
-
- // Try adjusting width to be proportional to height
- if (resizeWidth) {
- int newWidth = (int) (desiredAspect * (heightSize - ptop - pbottom)) + pleft + pright;
- if (/*newWidth <= widthSize &&*/newWidth > 0) {
- widthSize = Math.min(newWidth, mMaxWidthL);
- heightSize = (int) ((widthSize - pleft - pright) / desiredAspect) + ptop + pbottom;
- }
- }
-
- // Try adjusting height to be proportional to width
- if (resizeHeight) {
- int newHeight = (int) ((widthSize - pleft - pright) / desiredAspect) + ptop + pbottom;
- if (/*newHeight <= heightSize && */newHeight > 0) {
- heightSize = Math.min(newHeight, mMaxHeightL);
- widthSize = (int) (desiredAspect * (heightSize - ptop - pbottom)) + pleft + pright;
- }
- }
- }
- }
- } else {
- /* We are either don't want to preserve the drawables aspect ratio,
- or we are not allowed to change view dimensions. Just measure in
- the normal way.
- */
- w += pleft + pright;
- h += ptop + pbottom;
-
- w = Math.max(w, getSuggestedMinimumWidth());
- h = Math.max(h, getSuggestedMinimumHeight());
-
- widthSize = resolveSize(w, widthMeasureSpec);
- heightSize = resolveSize(h, heightMeasureSpec);
- }
-
- //Log.d(Constants.LOGTAG, mDrawableWidth + ":" + mDrawableHeight + " to " + widthSize + ":" + heightSize);
-
- setMeasuredDimension(widthSize, heightSize);
-
- if (relatedView != null) {
- //Log.i(Constants.LOGTAG, getTag() + " onMeasure:" + widthSize + ", " + heightSize + " update size of related view!");
- relatedView.getLayoutParams().width = widthSize;
- relatedView.getLayoutParams().height = heightSize;
- }
-
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- //Log.d(Constants.LOGTAG, getTag() + " onLayout:" + left + ", " + top + ", " + right + ", " + bottom);
- }
-
- /**
- * Experimental. This view will be set to the same size as this image.
- */
- public void setRelatedView(View view) {
- relatedView = view;
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- //Log.d(Constants.LOGTAG, getTag() + " onSizeChanged:" + w + ", " + h + ", " + oldw + ", " + oldh);
- }
-
- private int resolveAdjustedSize(int desiredSize, int maxSize, int measureSpec) {
- int result = desiredSize;
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
- switch (specMode) {
- case MeasureSpec.UNSPECIFIED:
- /* Parent says we can be as big as we want. Just don't be larger
- than max size imposed on ourselves.
- */
- result = Math.min(desiredSize, maxSize);
- break;
- case MeasureSpec.AT_MOST:
- // Parent says we can be as big as we want, up to specSize.
- // Don't be larger than specSize, and don't be larger than
- // the max size imposed on ourselves.
- result = Math.min(Math.min(desiredSize, specSize), maxSize);
- break;
- case MeasureSpec.EXACTLY:
- // No choice. Do what we are told.
- result = specSize;
- break;
- }
- return result;
- }
-}
\ No newline at end of file diff --git a/src/org/fox/ttrss/util/FontSizeDialogPreference.java b/src/org/fox/ttrss/util/FontSizeDialogPreference.java deleted file mode 100644 index a4220fd1..00000000 --- a/src/org/fox/ttrss/util/FontSizeDialogPreference.java +++ /dev/null @@ -1,224 +0,0 @@ -package org.fox.ttrss.util;
-
-// http://www.lukehorvat.com/blog/android-seekbardialogpreference/
-
-import org.fox.ttrss.R;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.preference.DialogPreference;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.View;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-import android.widget.TextView;
-
-/**
- * A {@link DialogPreference} that provides a user with the means to select an
- * integer from a {@link SeekBar}, and persist it.
- *
- * @author lukehorvat
- *
- */
-public class FontSizeDialogPreference extends DialogPreference {
- private static final int DEFAULT_MIN_PROGRESS = 9;
- private static final int DEFAULT_MAX_PROGRESS = 24;
- private static final String DEFAULT_PROGRESS = "0";
-
- private int mMinProgress = DEFAULT_MIN_PROGRESS;
- private int mMaxProgress = DEFAULT_MAX_PROGRESS;
- private int mProgress;
- private CharSequence mProgressTextSuffix;
- private TextView mProgressText;
- private SeekBar mSeekBar;
-
- public FontSizeDialogPreference(Context context) {
- this(context, null);
- }
-
- public FontSizeDialogPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- setProgressTextSuffix(" " + context.getString(R.string.font_size_dialog_suffix));
-
- // set layout
- setDialogLayoutResource(R.layout.select_font_size_dialog);
- setPositiveButtonText(android.R.string.ok);
- setNegativeButtonText(android.R.string.cancel);
- setDialogIcon(null);
- }
-
- @Override
- protected void onSetInitialValue(boolean restore, Object defaultValue) {
- setProgress(restore ? Integer.valueOf(getPersistedString(DEFAULT_PROGRESS))
- : Integer.valueOf((String)defaultValue));
- }
-
- @Override
- protected Object onGetDefaultValue(TypedArray a, int index) {
- return a.getString(index);
- }
-
- @Override
- protected void onBindDialogView(View view) {
- super.onBindDialogView(view);
-
- mProgressText = (TextView) view.findViewById(R.id.text_progress);
-
- mSeekBar = (SeekBar) view.findViewById(R.id.seek_bar);
- mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
- // update text that displays the current SeekBar progress value
- // note: this does not persist the progress value. that is only
- // ever done in setProgress()
- String progressStr = String.valueOf(progress + mMinProgress);
- mProgressText.setText(mProgressTextSuffix == null ? progressStr
- : progressStr.concat(mProgressTextSuffix.toString()));
- mProgressText.setTextSize(TypedValue.COMPLEX_UNIT_SP, progress + mMinProgress);
- }
- });
-
- mSeekBar.setMax(mMaxProgress - mMinProgress);
- mSeekBar.setProgress(mProgress - mMinProgress);
- }
-
- public int getMinProgress() {
- return mMinProgress;
- }
-
- public void setMinProgress(int minProgress) {
- mMinProgress = minProgress;
- setProgress(Math.max(mProgress, mMinProgress));
- }
-
- public int getMaxProgress() {
- return mMaxProgress;
- }
-
- public void setMaxProgress(int maxProgress) {
- mMaxProgress = maxProgress;
- setProgress(Math.min(mProgress, mMaxProgress));
- }
-
- public int getProgress() {
- return mProgress;
- }
-
- public void setProgress(int progress) {
- progress = Math.max(Math.min(progress, mMaxProgress), mMinProgress);
-
- if (progress != mProgress) {
- mProgress = progress;
- persistString(String.valueOf(progress));
- notifyChanged();
- }
- }
-
- public CharSequence getProgressTextSuffix() {
- return mProgressTextSuffix;
- }
-
- public void setProgressTextSuffix(CharSequence progressTextSuffix) {
- mProgressTextSuffix = progressTextSuffix;
- }
-
- @Override
- protected void onDialogClosed(boolean positiveResult) {
- super.onDialogClosed(positiveResult);
-
- // when the user selects "OK", persist the new value
- if (positiveResult) {
- int seekBarProgress = mSeekBar.getProgress() + mMinProgress;
- if (callChangeListener(seekBarProgress)) {
- setProgress(seekBarProgress);
- }
- }
- }
-
- @Override
- protected Parcelable onSaveInstanceState() {
- // save the instance state so that it will survive screen orientation
- // changes and other events that may temporarily destroy it
- final Parcelable superState = super.onSaveInstanceState();
-
- // set the state's value with the class member that holds current
- // setting value
- final SavedState myState = new SavedState(superState);
- myState.minProgress = getMinProgress();
- myState.maxProgress = getMaxProgress();
- myState.progress = getProgress();
-
- return myState;
- }
-
- @Override
- protected void onRestoreInstanceState(Parcelable state) {
- // check whether we saved the state in onSaveInstanceState()
- if (state == null || !state.getClass().equals(SavedState.class)) {
- // didn't save the state, so call superclass
- super.onRestoreInstanceState(state);
- return;
- }
-
- // restore the state
- SavedState myState = (SavedState) state;
- setMinProgress(myState.minProgress);
- setMaxProgress(myState.maxProgress);
- setProgress(myState.progress);
-
- super.onRestoreInstanceState(myState.getSuperState());
- }
-
- private static class SavedState extends BaseSavedState {
- int minProgress;
- int maxProgress;
- int progress;
-
- public SavedState(Parcelable superState) {
- super(superState);
- }
-
- public SavedState(Parcel source) {
- super(source);
-
- minProgress = source.readInt();
- maxProgress = source.readInt();
- progress = source.readInt();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
-
- dest.writeInt(minProgress);
- dest.writeInt(maxProgress);
- dest.writeInt(progress);
- }
-
- @SuppressWarnings("unused")
- public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
- @Override
- public SavedState createFromParcel(Parcel in) {
- return new SavedState(in);
- }
-
- @Override
- public SavedState[] newArray(int size) {
- return new SavedState[size];
- }
- };
- }
-}
\ No newline at end of file diff --git a/src/org/fox/ttrss/util/HeadlinesRequest.java b/src/org/fox/ttrss/util/HeadlinesRequest.java deleted file mode 100644 index 551c0add..00000000 --- a/src/org/fox/ttrss/util/HeadlinesRequest.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.fox.ttrss.util; - -import java.lang.reflect.Type; -import java.util.List; - -import org.fox.ttrss.ApiRequest; -import org.fox.ttrss.GlobalState; -import org.fox.ttrss.OnlineActivity; -import org.fox.ttrss.R; -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; -import org.fox.ttrss.types.Feed; - -import android.content.Context; -import android.util.Log; - -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; - -public class HeadlinesRequest extends ApiRequest { - public static final int HEADLINES_REQUEST_SIZE = 30; - public static final int HEADLINES_BUFFER_MAX = 1500; - - private final String TAG = this.getClass().getSimpleName(); - - private int m_offset = 0; - private OnlineActivity m_activity; - private ArticleList m_articles = GlobalState.getInstance().m_loadedArticles; - private Feed m_feed; - - public HeadlinesRequest(Context context, OnlineActivity activity, final Feed feed) { - super(context); - - m_activity = activity; - m_feed = feed; - } - - protected void onPostExecute(JsonElement result) { - if (result != null) { - try { - - // check if we are returning results for correct feed - if (GlobalState.getInstance().m_activeFeed != null && !m_feed.equals(GlobalState.getInstance().m_activeFeed)) { - Log.d(TAG, "received results for wrong feed, bailing out."); - return; - } - - JsonArray content = result.getAsJsonArray(); - if (content != null) { - Type listType = new TypeToken<List<Article>>() {}.getType(); - final List<Article> articles = new Gson().fromJson(content, listType); - - if (m_offset == 0) { - m_articles.clear(); - } else { - while (m_articles.size() > HEADLINES_BUFFER_MAX) { - m_articles.remove(0); - } - - if (m_articles.get(m_articles.size()-1).id == -1) { - m_articles.remove(m_articles.size()-1); // remove previous placeholder - } - - } - - for (Article f : articles) - if (!m_articles.containsId(f.id)) - m_articles.add(f); - - if (articles.size() == HEADLINES_REQUEST_SIZE) { - Article placeholder = new Article(-1); - m_articles.add(placeholder); - } - - /* if (m_articles.size() == 0) - m_activity.setLoadingStatus(R.string.no_headlines_to_display, false); - else */ - - m_activity.setLoadingStatus(R.string.blank, false); - - return; - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (m_lastError == ApiError.LOGIN_FAILED) { - m_activity.login(); - } else { - m_activity.setLoadingStatus(getErrorMessage(), false); - } - } - - public void setOffset(int skip) { - m_offset = skip; - } -} diff --git a/src/org/fox/ttrss/util/ImageCacheService.java b/src/org/fox/ttrss/util/ImageCacheService.java deleted file mode 100644 index 5b029fc6..00000000 --- a/src/org/fox/ttrss/util/ImageCacheService.java +++ /dev/null @@ -1,212 +0,0 @@ -package org.fox.ttrss.util; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Date; - -import org.fox.ttrss.OnlineActivity; -import org.fox.ttrss.R; -import org.fox.ttrss.offline.OfflineDownloadService; - -import android.app.ActivityManager; -import android.app.ActivityManager.RunningServiceInfo; -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.os.Environment; - -public class ImageCacheService extends IntentService { - - @SuppressWarnings("unused") - private final String TAG = this.getClass().getSimpleName(); - - public static final int NOTIFY_DOWNLOADING = 1; - - private static final String CACHE_PATH = "/image-cache/"; - - private int m_imagesDownloaded = 0; - - private NotificationManager m_nmgr; - - public ImageCacheService() { - super("ImageCacheService"); - } - - private boolean isDownloadServiceRunning() { - ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); - for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { - if ("org.fox.ttrss.OfflineDownloadService".equals(service.service.getClassName())) { - return true; - } - } - return false; - } - - - @Override - public void onCreate() { - super.onCreate(); - m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - } - - public static boolean isUrlCached(Context context, String url) { - String hashedUrl = md5(url); - - File storage = context.getExternalCacheDir(); - - File file = new File(storage.getAbsolutePath() + CACHE_PATH + "/" + hashedUrl + ".png"); - - return file.exists(); - } - - public static String getCacheFileName(Context context, String url) { - String hashedUrl = md5(url); - - File storage = context.getExternalCacheDir(); - - File file = new File(storage.getAbsolutePath() + CACHE_PATH + "/" + hashedUrl + ".png"); - - return file.getAbsolutePath(); - } - - public static void cleanupCache(Context context, boolean deleteAll) { - if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { - File storage = context.getExternalCacheDir(); - File cachePath = new File(storage.getAbsolutePath() + CACHE_PATH); - - long now = new Date().getTime(); - - if (cachePath.isDirectory()) { - for (File file : cachePath.listFiles()) { - if (deleteAll || now - file.lastModified() > 1000*60*60*24*7) { - file.delete(); - } - } - } - } - } - - protected static String md5(String s) { - try { - MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); - digest.update(s.getBytes()); - byte messageDigest[] = digest.digest(); - - StringBuffer hexString = new StringBuffer(); - for (int i=0; i<messageDigest.length; i++) - hexString.append(Integer.toHexString(0xFF & messageDigest[i])); - - return hexString.toString(); - - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - - return null; - } - - private InputStream getStream(String urlString) { - try { - URL url = new URL(urlString); - URLConnection urlConnection = url.openConnection(); - urlConnection.setConnectTimeout(250); - urlConnection.setReadTimeout(5*1000); - return urlConnection.getInputStream(); - } catch (Exception ex) { - return null; - } - } - - @SuppressWarnings("deprecation") - private void updateNotification(String msg) { - Notification notification = new Notification(R.drawable.icon, - getString(R.string.notify_downloading_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_downloading_title), msg, contentIntent); - - m_nmgr.notify(NOTIFY_DOWNLOADING, notification); - } - - /* private void updateNotification(int msgResId) { - updateNotification(getString(msgResId)); - } */ - - @Override - protected void onHandleIntent(Intent intent) { - String url = intent.getStringExtra("url"); - - //Log.d(TAG, "got request to download URL=" + url); - - if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) - return; - - String hashedUrl = md5(url); - - File storage = getExternalCacheDir(); - File cachePath = new File(storage.getAbsolutePath() + CACHE_PATH); - if (!cachePath.exists()) cachePath.mkdirs(); - - if (cachePath.isDirectory() && hashedUrl != null) { - File outputFile = new File(cachePath.getAbsolutePath() + "/" + hashedUrl + ".png"); - - if (!outputFile.exists()) { - - //Log.d(TAG, "downloading to " + outputFile.getAbsolutePath()); - - InputStream is = getStream(url); - - if (is != null) { - try { - FileOutputStream fos = new FileOutputStream(outputFile); - - byte[] buffer = new byte[1024]; - int len = 0; - while ((len = is.read(buffer)) != -1) { - fos.write(buffer, 0, len); - } - - fos.close(); - is.close(); - - m_imagesDownloaded++; - - updateNotification(getString(R.string.notify_downloading_images, m_imagesDownloaded)); - - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - - if (!isDownloadServiceRunning()) { - m_nmgr.cancel(NOTIFY_DOWNLOADING); - - Intent success = new Intent(); - success.setAction(OfflineDownloadService.INTENT_ACTION_SUCCESS); - success.addCategory(Intent.CATEGORY_DEFAULT); - sendBroadcast(success); - } - } - -} diff --git a/src/org/fox/ttrss/util/LessBrokenWebView.java b/src/org/fox/ttrss/util/LessBrokenWebView.java deleted file mode 100644 index c6cab513..00000000 --- a/src/org/fox/ttrss/util/LessBrokenWebView.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.fox.ttrss.util;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.webkit.WebView;
-
-public class LessBrokenWebView extends WebView {
-
- public LessBrokenWebView(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- }
-
- public LessBrokenWebView(Context context, AttributeSet attrs) {
- super(context, attrs);
- // TODO Auto-generated constructor stub
- }
-
- public LessBrokenWebView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- // TODO Auto-generated constructor stub
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
-
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- int temp_ScrollY = getScrollY();
- scrollTo(getScrollX(), getScrollY() + 1);
- scrollTo(getScrollX(), temp_ScrollY);
- }
-
- return super.onTouchEvent(event);
- }
-
-}
diff --git a/src/org/fox/ttrss/util/NoChildFocusScrollView.java b/src/org/fox/ttrss/util/NoChildFocusScrollView.java deleted file mode 100644 index 3dea82a4..00000000 --- a/src/org/fox/ttrss/util/NoChildFocusScrollView.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.fox.ttrss.util;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.webkit.WebView;
-import android.widget.ScrollView;
-
-public class NoChildFocusScrollView extends ScrollView {
-
- public NoChildFocusScrollView(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- }
-
-
- public NoChildFocusScrollView(Context context, AttributeSet attrs) {
- super(context, attrs);
- // TODO Auto-generated constructor stub
- }
-
- public NoChildFocusScrollView(Context context, AttributeSet attrs,
- int defStyle) {
- super(context, attrs, defStyle);
- // TODO Auto-generated constructor stub
- }
-
- @Override
- public void requestChildFocus(View child, View focused) {
- if (focused instanceof WebView )
- return;
- super.requestChildFocus(child, focused);
- }
-}
diff --git a/src/org/fox/ttrss/util/PrefsBackupAgent.java b/src/org/fox/ttrss/util/PrefsBackupAgent.java deleted file mode 100644 index 2b33615f..00000000 --- a/src/org/fox/ttrss/util/PrefsBackupAgent.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.fox.ttrss.util; - -import android.app.backup.BackupAgentHelper; -import android.app.backup.SharedPreferencesBackupHelper; - -public class PrefsBackupAgent extends BackupAgentHelper { - // The name of the SharedPreferences file - static final String PREFS = "org.fox.ttrss_preferences"; - - // A key to uniquely identify the set of backup data - static final String PREFS_BACKUP_KEY = "prefs"; - - // Allocate a helper and add it to the backup agent - @Override - public void onCreate() { - SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS); - addHelper(PREFS_BACKUP_KEY, helper); - } -} diff --git a/src/org/fox/ttrss/util/SimpleLoginManager.java b/src/org/fox/ttrss/util/SimpleLoginManager.java deleted file mode 100644 index 072c0062..00000000 --- a/src/org/fox/ttrss/util/SimpleLoginManager.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.fox.ttrss.util;
-
-import java.util.HashMap;
-
-import org.fox.ttrss.ApiRequest;
-
-import android.content.Context;
-import android.util.Log;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-
-public abstract class SimpleLoginManager {
- private final String TAG = this.getClass().getSimpleName();
-
- protected class LoginRequest extends ApiRequest {
- private int m_requestId;
- protected String m_sessionId;
- protected int m_apiLevel;
- protected Context m_context;
-
- public LoginRequest(Context context, int requestId) {
- super(context);
- m_context = context;
- m_requestId = requestId;
- }
-
- protected void onPostExecute(JsonElement result) {
- Log.d(TAG, "onPostExecute");
-
- if (result != null) {
- try {
- JsonObject content = result.getAsJsonObject();
- if (content != null) {
- m_sessionId = content.get("session_id").getAsString();
-
- Log.d(TAG, "[SLM] Authenticated!");
-
- ApiRequest req = new ApiRequest(m_context) {
- protected void onPostExecute(JsonElement result) {
- m_apiLevel = 0;
-
- if (result != null) {
- try {
- m_apiLevel = result.getAsJsonObject()
- .get("level").getAsInt();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- Log.d(TAG, "[SLM] Received API level: " + m_apiLevel);
-
- onLoginSuccess(m_requestId, m_sessionId, m_apiLevel);
- }
- };
-
- @SuppressWarnings("serial")
- HashMap<String, String> map = new HashMap<String, String>() {
- {
- put("sid", m_sessionId);
- put("op", "getApiLevel");
- }
- };
-
- req.execute(map);
-
- return;
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- m_sessionId = null;
-
- onLoginFailed(m_requestId, this);
- }
-
- }
-
- public void logIn(Context context, int requestId, final String login, final String password) {
- LoginRequest ar = new LoginRequest(context, requestId);
-
- HashMap<String, String> map = new HashMap<String, String>() {
- {
- put("op", "login");
- put("user", login.trim());
- put("password", password.trim());
- }
- };
-
- onLoggingIn(requestId);
-
- ar.execute(map);
- }
-
- protected abstract void onLoggingIn(int requestId);
-
- protected abstract void onLoginSuccess(int requestId, String sessionId, int apiLevel);
-
- protected abstract void onLoginFailed(int requestId, ApiRequest ar);
-
-}
diff --git a/src/org/fox/ttrss/util/TitleWebView.java b/src/org/fox/ttrss/util/TitleWebView.java deleted file mode 100644 index 4d97918e..00000000 --- a/src/org/fox/ttrss/util/TitleWebView.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.fox.ttrss.util; - -// http://www.techques.com/question/1-9718245/Webview-in-Scrollview - -import android.content.Context; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; -import android.webkit.WebView; - -public class TitleWebView extends WebView{ - - public TitleWebView(Context context, AttributeSet attrs){ - super(context, attrs); - } - - private int titleHeight; - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - // determine height of title bar - View title = getChildAt(0); - titleHeight = title==null ? 0 : title.getMeasuredHeight(); - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev){ - return true; // don't pass our touch events to children (title bar), we send these in dispatchTouchEvent - } - - private boolean touchInTitleBar; - @Override - public boolean dispatchTouchEvent(MotionEvent me){ - - boolean wasInTitle = false; - switch(me.getActionMasked()){ - case MotionEvent.ACTION_DOWN: - touchInTitleBar = (me.getY() <= visibleTitleHeight()); - break; - - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - wasInTitle = touchInTitleBar; - touchInTitleBar = false; - break; - } - if(touchInTitleBar || wasInTitle) { - View title = getChildAt(0); - if(title!=null) { - // this touch belongs to title bar, dispatch it here - me.offsetLocation(0, getScrollY()); - return title.dispatchTouchEvent(me); - } - } - // this is our touch, offset and process - me.offsetLocation(0, -titleHeight); - return super.dispatchTouchEvent(me); - } - - /** - * @return visible height of title (may return negative values) - */ - private int visibleTitleHeight(){ - return titleHeight-getScrollY(); - } - - @Override - protected void onScrollChanged(int l, int t, int oldl, int oldt){ - super.onScrollChanged(l, t, oldl, oldt); - View title = getChildAt(0); - if(title!=null) // undo horizontal scroll, so that title scrolls only vertically - title.offsetLeftAndRight(l - title.getLeft()); - } - - @Override - protected void onDraw(Canvas c){ - - c.save(); - int tH = visibleTitleHeight(); - if(tH>0) { - // clip so that it doesn't clear background under title bar - int sx = getScrollX(), sy = getScrollY(); - c.clipRect(sx, sy+tH, sx+getWidth(), sy+getHeight()); - } - c.translate(0, titleHeight); - super.onDraw(c); - c.restore(); - } - } diff --git a/src/org/fox/ttrss/util/TypefaceCache.java b/src/org/fox/ttrss/util/TypefaceCache.java deleted file mode 100644 index 150d3d83..00000000 --- a/src/org/fox/ttrss/util/TypefaceCache.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.fox.ttrss.util;
-
-import java.util.Hashtable;
-
-import android.content.Context;
-import android.graphics.Typeface;
-import android.util.Log;
-
-public class TypefaceCache {
- private static final String TAG = "TypefaceCache";
- private static final Hashtable<String, Typeface> cache = new Hashtable<String, Typeface>();
-
- public static Typeface get(Context c, String typefaceName, int style) {
- synchronized (cache) {
- String key = typefaceName + ":" + style;
-
- if (!cache.containsKey(key)) {
- try {
- Typeface t = Typeface.create(typefaceName, style);
- cache.put(key, t);
- } catch (Exception e) {
- Log.e(TAG, "Could not get typeface '" + typefaceName + "' because " + e.getMessage());
- return null;
- }
- }
- return cache.get(key);
- }
- }
-}
\ No newline at end of file diff --git a/src/org/fox/ttrss/widget/SmallWidgetProvider.java b/src/org/fox/ttrss/widget/SmallWidgetProvider.java deleted file mode 100644 index dbbe718c..00000000 --- a/src/org/fox/ttrss/widget/SmallWidgetProvider.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.fox.ttrss.widget;
-
-import org.fox.ttrss.R;
-
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.app.Service;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProvider;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-import android.widget.RemoteViews;
-
-public class SmallWidgetProvider extends AppWidgetProvider {
- private final String TAG = this.getClass().getSimpleName();
-
- public static final String FORCE_UPDATE_ACTION = "org.fox.ttrss.WIDGET_FORCE_UPDATE";
-
- @Override
- public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
- //RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_small);
-
- final int N = appWidgetIds.length;
-
- for (int i=0; i < N; i++) {
- int appWidgetId = appWidgetIds[i];
-
- Intent updateIntent = new Intent(context, org.fox.ttrss.widget.WidgetUpdateService.class);
- PendingIntent updatePendingIntent = PendingIntent.getService(context, 0, updateIntent, 0);
-
- Intent intent = new Intent(context, org.fox.ttrss.OnlineActivity.class);
- PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
-
- RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_small);
- views.setOnClickPendingIntent(R.id.widget_main, pendingIntent);
-
- appWidgetManager.updateAppWidget(appWidgetId, views);
-
- try {
- updatePendingIntent.send();
- } catch (CanceledException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- super.onReceive(context, intent);
-
- if (FORCE_UPDATE_ACTION.equals(intent.getAction())) {
-
- AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
- ComponentName thisAppWidget = new ComponentName(context.getPackageName(), SmallWidgetProvider.class.getName());
- int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
-
- onUpdate(context, appWidgetManager, appWidgetIds);
- }
- }
-
-}
diff --git a/src/org/fox/ttrss/widget/WidgetUpdateService.java b/src/org/fox/ttrss/widget/WidgetUpdateService.java deleted file mode 100644 index 00c8002f..00000000 --- a/src/org/fox/ttrss/widget/WidgetUpdateService.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.fox.ttrss.widget;
-
-import java.util.HashMap;
-
-import org.fox.ttrss.ApiRequest;
-import org.fox.ttrss.R;
-import org.fox.ttrss.util.SimpleLoginManager;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-
-import android.app.Service;
-import android.appwidget.AppWidgetManager;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.IBinder;
-import android.preference.PreferenceManager;
-import android.util.Log;
-import android.view.View;
-import android.widget.RemoteViews;
-
-public class WidgetUpdateService extends Service {
- private final String TAG = this.getClass().getSimpleName();
-
- @Override
- public IBinder onBind(Intent intent) {
- Log.d(TAG, "onBind");
-
- // TODO Auto-generated method stub
- return null;
- }
-
- /* @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- Log.d(TAG, "onStartCommand");
-
- return super.onStartCommand(intent, flags, startId);
- } */
-
- public void update() {
-
-
- }
-
- @Override
- public void onStart(Intent intent, int startId) {
- final RemoteViews view = new RemoteViews(getPackageName(), R.layout.widget_small);
-
- final ComponentName thisWidget = new ComponentName(this, SmallWidgetProvider.class);
- final AppWidgetManager manager = AppWidgetManager.getInstance(this);
-
- try {
- view.setTextViewText(R.id.counter, String.valueOf(""));
- view.setViewVisibility(R.id.progress, View.VISIBLE);
-
- manager.updateAppWidget(thisWidget, view);
-
- final SharedPreferences m_prefs = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext());
-
- if (m_prefs.getString("ttrss_url", "").trim().length() == 0) {
-
- // Toast: need configure
-
- } else {
-
- SimpleLoginManager loginManager = new SimpleLoginManager() {
-
- @Override
- protected void onLoginSuccess(int requestId, String sessionId, int apiLevel) {
-
- ApiRequest aru = new ApiRequest(getApplicationContext()) {
- @Override
- protected void onPostExecute(JsonElement result) {
- if (result != null) {
- try {
- JsonObject content = result.getAsJsonObject();
-
- if (content != null) {
- int unread = content.get("unread").getAsInt();
-
- view.setViewVisibility(R.id.progress, View.GONE);
- view.setTextViewText(R.id.counter, String.valueOf(unread));
- manager.updateAppWidget(thisWidget, view);
-
- return;
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- view.setViewVisibility(R.id.progress, View.GONE);
- view.setTextViewText(R.id.counter, "?");
- manager.updateAppWidget(thisWidget, view);
- }
- };
-
- final String fSessionId = sessionId;
-
- HashMap<String, String> umap = new HashMap<String, String>() {
- {
- put("op", "getUnread");
- put("sid", fSessionId);
- }
- };
-
- aru.execute(umap);
- }
-
- @Override
- protected void onLoginFailed(int requestId, ApiRequest ar) {
-
- view.setViewVisibility(R.id.progress, View.GONE);
- view.setTextViewText(R.id.counter, "?");
- manager.updateAppWidget(thisWidget, view);
- }
-
- @Override
- protected void onLoggingIn(int requestId) {
-
-
- }
- };
-
- String login = m_prefs.getString("login", "").trim();
- String password = m_prefs.getString("password", "").trim();
-
- loginManager.logIn(getApplicationContext(), 1, login, password);
- }
- } catch (Exception e) {
- e.printStackTrace();
-
- view.setViewVisibility(R.id.progress, View.GONE);
- view.setTextViewText(R.id.counter, getString(R.string.app_name));
- manager.updateAppWidget(thisWidget, view);
-
- }
- }
-}
|