diff --git a/res/values/arrays.xml b/res/values/arrays.xml index 8c95e3db1b441e614872fb6a5b677ce955d59b8f..6637d9a9cba1596253e8cf3e4176361a24f9f9ee 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -5,7 +5,6 @@ <item>@string/label_addressbook</item> <item>@string/label_i2ptunnel</item> <item>@string/label_logs</item> - <item>@string/label_error_logs</item> <item>@string/label_graphs</item> <item>@string/label_peers_status</item> <item>@string/label_welcome_page</item> @@ -13,6 +12,10 @@ <item>@string/label_website_nonanon</item> <item>@string/label_faq_nonanon</item> </string-array> + <string-array name="log_level_list"> + <item>ERROR</item> + <item>All</item> + </string-array> <string-array name="graph_list"> <item>router.activePeers</item> <item>router.memoryUsed</item> diff --git a/src/net/i2p/android/router/activity/I2PActivityBase.java b/src/net/i2p/android/router/activity/I2PActivityBase.java index 918b964e403e77534cb64685e5a78db01faa396c..5332c0998af872a9e2a0aba9f814008ba94328f5 100644 --- a/src/net/i2p/android/router/activity/I2PActivityBase.java +++ b/src/net/i2p/android/router/activity/I2PActivityBase.java @@ -144,36 +144,31 @@ public abstract class I2PActivityBase extends ActionBarActivity implements startActivity(log); break; case 4: - Intent err = new Intent(I2PActivityBase.this, LogActivity.class); - err.putExtra(LogActivity.ERRORS_ONLY, true); - startActivity(err); - break; - case 5: Intent active = new Intent(I2PActivityBase.this, GraphActivity.class); startActivity(active); break; - case 6: + case 5: Intent peers = new Intent(I2PActivityBase.this, PeersActivity.class); startActivity(peers); break; - case 7: + case 6: Intent wp = new Intent(I2PActivityBase.this, WebActivity.class); wp.putExtra(WebFragment.HTML_RESOURCE_ID, R.raw.welcome_html); startActivity(wp); break; - case 8: + case 7: getSupportFragmentManager() .beginTransaction() .replace(R.id.main_fragment, new NewsFragment()) .addToBackStack(null) .commit(); break; - case 9: + case 8: Intent website = new Intent(I2PActivityBase.this, WebActivity.class); website.putExtra(WebFragment.HTML_URI, "http://www.i2p2.de/"); startActivity(website); break; - case 10: + case 9: Intent faq = new Intent(I2PActivityBase.this, WebActivity.class); faq.putExtra(WebFragment.HTML_URI, "http://www.i2p2.de/faq"); startActivity(faq); diff --git a/src/net/i2p/android/router/activity/LogActivity.java b/src/net/i2p/android/router/activity/LogActivity.java index a1e9d85b3d48b665e18a7a7880bb18c20cacfd6e..d6ba39c1165fa30b9498242ca5814dde27b08f1d 100644 --- a/src/net/i2p/android/router/activity/LogActivity.java +++ b/src/net/i2p/android/router/activity/LogActivity.java @@ -1,146 +1,52 @@ package net.i2p.android.router.activity; -import android.app.ListActivity; -import android.content.Intent; +import net.i2p.android.router.R; +import net.i2p.android.router.fragment.LogFragment; import android.os.Bundle; -import android.os.Handler; +import android.support.v7.app.ActionBar; import android.widget.ArrayAdapter; -import android.widget.ListView; -import android.widget.TextView; -import java.util.Collections; -import java.util.List; -import net.i2p.I2PAppContext; -import net.i2p.android.router.R; - -public class LogActivity extends ListActivity { +import android.widget.SpinnerAdapter; - boolean _errorsOnly; - private Handler _handler; - private Runnable _updater; - private ArrayAdapter<String> _adap; - private TextView _headerView; - - public final static String ERRORS_ONLY = "errors_only"; - private static final int MAX = 250; +public class LogActivity extends I2PActivityBase { + private static final String SELECTED_LEVEL = "selected_level"; @Override - public void onCreate(Bundle savedInstanceState) - { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Grab context if router has started, otherwise create new - // FIXME dup contexts, locking, ... - List<String> msgs; - String header; - I2PAppContext ctx = I2PAppContext.getCurrentContext(); - if (ctx != null) { - Intent intent = getIntent(); - _errorsOnly = intent.getBooleanExtra(ERRORS_ONLY, false); - if (_errorsOnly) { - msgs = ctx.logManager().getBuffer().getMostRecentCriticalMessages(); - } else { - msgs = ctx.logManager().getBuffer().getMostRecentMessages(); - } - int sz = msgs.size(); - header = getHeader(sz, _errorsOnly); - if (sz > 1) { - Collections.reverse(msgs); - } - } else { - //msgs = Collections.EMPTY_LIST; - msgs = Collections.emptyList(); - header = "No messages, router has not started yet."; - } - - // set the header - _headerView = (TextView) getLayoutInflater().inflate(R.layout.logs_header, null); - _headerView.setText(header); - ListView lv = getListView(); - lv.addHeaderView(_headerView, "", false); - _adap = new ArrayAdapter<String>(this, R.layout.logs_list_item, msgs); - setListAdapter(_adap); + // Set up action bar for drop-down list + ActionBar actionBar = getSupportActionBar(); + actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); -/*** - // set the callback - lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { - public void onItemClick(AdapterView parent, View view, int pos, long id) { - // make it bigger or something - } - }); -***/ + mDrawerToggle.setDrawerIndicatorEnabled(false); - _handler = new Handler(); - _updater = new Updater(); - } + SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource(this, + R.array.log_level_list, android.R.layout.simple_spinner_dropdown_item); - @Override - public void onStart() { - super.onStart(); - _handler.removeCallbacks(_updater); - _handler.postDelayed(_updater, 10*1000); - } - - @Override - public void onStop() { - super.onStop(); - _handler.removeCallbacks(_updater); - } + ActionBar.OnNavigationListener mNavigationListener = new ActionBar.OnNavigationListener() { + String[] levels = getResources().getStringArray(R.array.log_level_list); + + public boolean onNavigationItemSelected(int position, long itemId) { + String level = levels[position]; + LogFragment f = LogFragment.newInstance(level); + getSupportFragmentManager().beginTransaction() + .replace(R.id.main_fragment, f, levels[position]).commit(); + return true; + } + }; - private class Updater implements Runnable { - private int counter; + actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationListener); - public void run() { - I2PAppContext ctx = I2PAppContext.getCurrentContext(); - if (ctx != null) { - List<String> msgs; - if (_errorsOnly) { - msgs = ctx.logManager().getBuffer().getMostRecentCriticalMessages(); - } else { - msgs = ctx.logManager().getBuffer().getMostRecentMessages(); - } - int sz = msgs.size(); - if (sz > 0) { - Collections.reverse(msgs); - String oldNewest = _adap.getCount() > 0 ? _adap.getItem(0) : null; - boolean changed = false; - for (int i = 0; i < sz; i++) { - String newItem = msgs.get(i); - if (newItem.equals(oldNewest)) - break; - _adap.insert(newItem, i); - changed = true; - } - int newSz = _adap.getCount(); - for (int i = newSz - 1; i > MAX; i--) { - _adap.remove(_adap.getItem(i)); - } - if (changed) { - // fixme update header - newSz = _adap.getCount(); - String header = getHeader(newSz, _errorsOnly); - _headerView.setText(header); - _adap.notifyDataSetChanged(); - } - } - } - // LogWriter only processes queue every 10 seconds - _handler.postDelayed(this, 10*1000); + if (savedInstanceState != null) { + int selected = savedInstanceState.getInt(SELECTED_LEVEL); + actionBar.setSelectedNavigationItem(selected); } } - /** fixme plurals */ - private static String getHeader(int sz, boolean errorsOnly) { - if (errorsOnly) { - if (sz == 0) - return "No error messages"; - if (sz == 1) - return "1 error message"; - return sz + " error messages, newest first"; - } - if (sz == 0) - return "No messages"; - if (sz == 1) - return "1 message"; - return sz + " messages, newest first"; + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt(SELECTED_LEVEL, + getSupportActionBar().getSelectedNavigationIndex()); } } diff --git a/src/net/i2p/android/router/fragment/LogFragment.java b/src/net/i2p/android/router/fragment/LogFragment.java new file mode 100644 index 0000000000000000000000000000000000000000..2a9fe63d5fa287cce7b3c9c5b3515f3edf3d3fd3 --- /dev/null +++ b/src/net/i2p/android/router/fragment/LogFragment.java @@ -0,0 +1,154 @@ +package net.i2p.android.router.fragment; + +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.app.ListFragment; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; +import java.util.Collections; +import java.util.List; +import net.i2p.I2PAppContext; +import net.i2p.android.router.R; +import net.i2p.android.router.util.Util; + +public class LogFragment extends ListFragment { + + String _logLevel; + private Handler _handler; + private Runnable _updater; + private ArrayAdapter<String> _adap; + private TextView _headerView; + + public static final String LOG_LEVEL = "log_level"; + private static final int MAX = 250; + + public static LogFragment newInstance(String level) { + LogFragment f = new LogFragment(); + Bundle args = new Bundle(); + args.putString(LOG_LEVEL, level); + f.setArguments(args); + return f; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) + { + super.onActivityCreated(savedInstanceState); + + // Grab context if router has started, otherwise create new + // FIXME dup contexts, locking, ... + List<String> msgs; + String header; + I2PAppContext ctx = I2PAppContext.getCurrentContext(); + if (ctx != null) { + Bundle args = getArguments(); + _logLevel = args.getString(LOG_LEVEL); + if ("ERROR".equals(_logLevel)) { + msgs = ctx.logManager().getBuffer().getMostRecentCriticalMessages(); + } else { + msgs = ctx.logManager().getBuffer().getMostRecentMessages(); + } + int sz = msgs.size(); + header = getHeader(sz, ("ERROR".equals(_logLevel))); + if (sz > 1) { + Collections.reverse(msgs); + } + } else { + //msgs = Collections.EMPTY_LIST; + msgs = Collections.emptyList(); + header = "No messages, router has not started yet."; + } + + // set the header + _headerView = (TextView) getActivity().getLayoutInflater().inflate(R.layout.logs_header, null); + _headerView.setText(header); + ListView lv = getListView(); + lv.addHeaderView(_headerView, "", false); + _adap = new ArrayAdapter<String>(getActivity(), R.layout.logs_list_item, msgs); + setListAdapter(_adap); + +/*** + // set the callback + lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + public void onItemClick(AdapterView parent, View view, int pos, long id) { + // make it bigger or something + } + }); +***/ + + _handler = new Handler(); + _updater = new Updater(); + } + + @Override + public void onStart() { + super.onStart(); + _handler.removeCallbacks(_updater); + _handler.postDelayed(_updater, 10*1000); + } + + @Override + public void onStop() { + super.onStop(); + _handler.removeCallbacks(_updater); + } + + private class Updater implements Runnable { + private int counter; + + public void run() { + I2PAppContext ctx = I2PAppContext.getCurrentContext(); + if (ctx != null) { + List<String> msgs; + if ("ERROR".equals(_logLevel)) { + msgs = ctx.logManager().getBuffer().getMostRecentCriticalMessages(); + } else { + msgs = ctx.logManager().getBuffer().getMostRecentMessages(); + } + int sz = msgs.size(); + if (sz > 0) { + Collections.reverse(msgs); + String oldNewest = _adap.getCount() > 0 ? _adap.getItem(0) : null; + boolean changed = false; + for (int i = 0; i < sz; i++) { + String newItem = msgs.get(i); + if (newItem.equals(oldNewest)) + break; + _adap.insert(newItem, i); + changed = true; + } + int newSz = _adap.getCount(); + for (int i = newSz - 1; i > MAX; i--) { + _adap.remove(_adap.getItem(i)); + } + if (changed) { + // fixme update header + newSz = _adap.getCount(); + String header = getHeader(newSz, (_logLevel == "ERROR")); + _headerView.setText(header); + _adap.notifyDataSetChanged(); + } + } + } + // LogWriter only processes queue every 10 seconds + _handler.postDelayed(this, 10*1000); + } + } + + /** fixme plurals */ + private static String getHeader(int sz, boolean errorsOnly) { + if (errorsOnly) { + if (sz == 0) + return "No error messages"; + if (sz == 1) + return "1 error message"; + return sz + " error messages, newest first"; + } + if (sz == 0) + return "No messages"; + if (sz == 1) + return "1 message"; + return sz + " messages, newest first"; + } +}