diff --git a/res/drawable/delete.png b/res/drawable/delete.png new file mode 100644 index 0000000..f3e53d7 Binary files /dev/null and b/res/drawable/delete.png differ diff --git a/res/drawable/edit.png b/res/drawable/edit.png new file mode 100644 index 0000000..d3e64b2 Binary files /dev/null and b/res/drawable/edit.png differ diff --git a/res/layout/script_list_item.xml b/res/layout/script_list_item.xml index 43fc022..bed7969 100644 --- a/res/layout/script_list_item.xml +++ b/res/layout/script_list_item.xml @@ -1,8 +1,49 @@ - + android:layout_height="wrap_content" + android:orientation="horizontal" > - \ No newline at end of file + + + + + + + + + + + + + + + + + diff --git a/src/at/pardus/android/webview/gm/WebViewGmImpl.java b/src/at/pardus/android/webview/gm/WebViewGmImpl.java index 41de1be..16e55de 100644 --- a/src/at/pardus/android/webview/gm/WebViewGmImpl.java +++ b/src/at/pardus/android/webview/gm/WebViewGmImpl.java @@ -27,6 +27,7 @@ import android.view.MenuItem; import android.view.Window; import at.pardus.android.webview.gm.model.ScriptId; +import at.pardus.android.webview.gm.store.ScriptStore; import at.pardus.android.webview.gm.store.ScriptStoreSQLite; import at.pardus.android.webview.gm.store.ui.ScriptBrowser; import at.pardus.android.webview.gm.store.ui.ScriptEditor; @@ -42,52 +43,84 @@ public class WebViewGmImpl extends ScriptManagerActivity { private Stack placeHistory = new Stack(); private SharedPreferences preferences; + + private boolean startBrowser; private static final Integer LIST = 1; private static final Integer BROWSER = 2; + + public WebViewGmImpl() { + startBrowser=true; + } + + public WebViewGmImpl(boolean startBrowser) { + this.startBrowser=startBrowser; + } @Override public void openScriptList() { - if (scriptList == null) { - if (scriptStore == null) { - scriptStore = new ScriptStoreSQLite(this); - scriptStore.open(); - } - scriptList = new ScriptList(this, scriptStore); - } + getScriptList(); setTitle(R.string.webviewgm_impl_app_name); - setContentView(scriptList.getScriptList()); + setContentView(getScriptList ().getScriptList()); placeHistory.push(LIST); } + + protected final ScriptList getScriptList() { + if (scriptList == null) + scriptList = createScriptList(); + return scriptList; + } + + protected ScriptList createScriptList() { + return new ScriptList(this, getScriptStore()); + } @Override public void openScriptEditor(ScriptId scriptId) { - if (scriptEditor == null) { - if (scriptStore == null) { - scriptStore = new ScriptStoreSQLite(this); - scriptStore.open(); - } - scriptEditor = new ScriptEditor(this, scriptStore); - } - setContentView(scriptEditor.getEditForm(scriptId)); + setContentView(getScriptEditor().getEditForm(scriptId)); placeHistory.push(null); } + + protected final ScriptEditor getScriptEditor() { + if (scriptEditor == null) + scriptEditor = createScriptEditor (); + return scriptEditor; + } + + protected ScriptEditor createScriptEditor() { + return new ScriptEditor(this, getScriptStore()); + } @Override public void openScriptBrowser() { - if (scriptBrowser == null) { - if (scriptStore == null) { - scriptStore = new ScriptStoreSQLite(this); - scriptStore.open(); - } - scriptBrowser = new ScriptBrowser(this, scriptStore, - preferences.getString("lastUrl", "http://userscripts.org/")); - } - setContentView(scriptBrowser.getBrowser()); + setContentView(getScriptBrowser().getBrowser()); placeHistory.push(BROWSER); } - + + protected final ScriptBrowser getScriptBrowser() { + if (scriptBrowser == null) + scriptBrowser = createScriptBrowser(); + return scriptBrowser; + } + + protected ScriptBrowser createScriptBrowser() { + return new ScriptBrowser(this, getScriptStore(), + preferences.getString("lastUrl", "http://userscripts.org/")); + } + + protected final ScriptStore getScriptStore() { + if (scriptStore == null) { + scriptStore = createScriptStore(); + scriptStore.open(); + } + return scriptStore != null ? scriptStore : createScriptStore(); + } + + protected ScriptStoreSQLite createScriptStore() { + return new ScriptStoreSQLite(this); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); @@ -113,7 +146,8 @@ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_PROGRESS); preferences = getSharedPreferences("P", Context.MODE_PRIVATE); - openScriptBrowser(); + if(startBrowser) + openScriptBrowser(); } @Override diff --git a/src/at/pardus/android/webview/gm/store/ScriptStore.java b/src/at/pardus/android/webview/gm/store/ScriptStore.java index 79089a5..89119c5 100644 --- a/src/at/pardus/android/webview/gm/store/ScriptStore.java +++ b/src/at/pardus/android/webview/gm/store/ScriptStore.java @@ -86,6 +86,15 @@ public interface ScriptStore { */ public void delete(ScriptId id); + /** + * Tells if an user script is enabled. + * + * @param id + * the ID of the script + * @return true if enabled + */ + public boolean isEnabled(ScriptId id); + /** * Gets all names of values stored by a user script. * diff --git a/src/at/pardus/android/webview/gm/store/ScriptStoreSQLite.java b/src/at/pardus/android/webview/gm/store/ScriptStoreSQLite.java index 403f9c9..b18dd28 100644 --- a/src/at/pardus/android/webview/gm/store/ScriptStoreSQLite.java +++ b/src/at/pardus/android/webview/gm/store/ScriptStoreSQLite.java @@ -51,7 +51,7 @@ public class ScriptStoreSQLite implements ScriptStore { @Override public Script[] get(String url) { - Script[] scripts = cache.get(url); + ScriptData[] scripts = cache.get(url); if (scripts == null) { if (dbHelper == null) { Log.w(TAG, "Cannot get user scripts (database not available)"); @@ -107,6 +107,19 @@ public void enable(ScriptId id) { dbHelper.updateScriptEnabled(id, true); initCache(); } + + @Override + public boolean isEnabled(ScriptId id) { + if (dbHelper == null) { + Log.e(TAG, "Cannot get user script (database not available)"); + return false; + } + ScriptData[] scripts = dbHelper.selectScripts(new ScriptId[] { id }, null); + if (scripts.length == 0) { + return false; + } + return scripts[0].enabled; + } @Override public void disable(ScriptId id) { @@ -334,7 +347,7 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { * @return an array of matching script objects; an empty array if none * found */ - public Script[] selectScripts(ScriptId[] ids, Boolean enabled) { + public ScriptData[] selectScripts(ScriptId[] ids, Boolean enabled) { String selectionStr = null, selectionIdStr = null; String[] selectionArgsArr = null, selectionIdArgsArr = null; if (ids != null || enabled != null) { @@ -342,7 +355,7 @@ public Script[] selectScripts(ScriptId[] ids, Boolean enabled) { List selectionArgs = new ArrayList(); if (ids != null) { if (ids.length == 0) { - return new Script[0]; + return new ScriptData[0]; } makeScriptIdSelectionArgs(ids, selection, selectionArgs); selectionIdStr = selection.toString(); @@ -368,7 +381,7 @@ public Script[] selectScripts(ScriptId[] ids, Boolean enabled) { selectionIdStr, selectionIdArgsArr); Cursor cursor = db.query(TBL_SCRIPT, COLS_SCRIPT, selectionStr, selectionArgsArr, null, null, null); - Script[] scriptsArr = new Script[cursor.getCount()]; + ScriptData[] scriptsArr = new ScriptData[cursor.getCount()]; int i = 0; while (cursor.moveToNext()) { String name = cursor.getString(0); @@ -392,11 +405,12 @@ public Script[] selectScripts(ScriptId[] ids, Boolean enabled) { int unwrap = cursor.getInt(8); String version = cursor.getString(9); String content = cursor.getString(10); + boolean isEnabled = cursor.getInt(11) != 0; // TODO add require and resource data - scriptsArr[i] = new Script(name, namespace, excludeArr, + scriptsArr[i] = new ScriptData(name, namespace, excludeArr, includeArr, matchArr, description, downloadurl, updateurl, installurl, icon, runat, unwrap == 1, - version, content); + version, content, isEnabled); i++; } cursor.close(); @@ -760,6 +774,27 @@ public void deleteValue(ScriptId id, String name) { } } + + /** + * An entry in the cache script. It contains some status information as + * well as the script itself (which is meant to be immutable). + */ + private static class ScriptData extends Script { + + public boolean enabled; + + public ScriptData(String name, String namespace, String[] exclude, + String[] include, String[] match, String description, + String downloadurl, String updateurl, String installurl, + String icon, String runAt, boolean unwrap, String version, + String content, boolean enabled) { + super(name, namespace, exclude, include, match, description, + downloadurl, updateurl, installurl, icon, runAt, unwrap, version, + content); + this.enabled = enabled; + } + + } /** * Cache of user scripts matching most recently accessed URLs and all @@ -769,14 +804,14 @@ private static class ScriptCache { private static final int CACHE_SIZE = 62; - private LinkedHashMap urlScripts = new LinkedHashMap( + private LinkedHashMap urlScripts = new LinkedHashMap( CACHE_SIZE + 2, 1.0f, true) { private static final long serialVersionUID = 1L; @Override protected boolean removeEldestEntry( - Map.Entry eldest) { + Map.Entry eldest) { return size() > CACHE_SIZE; } @@ -792,7 +827,7 @@ protected boolean removeEldestEntry( * @return if the URL is cached either the found user scripts or an * empty array; if the URL is not cached then null */ - public synchronized Script[] get(String url) { + public synchronized ScriptData[] get(String url) { return urlScripts.get(url); } @@ -804,7 +839,7 @@ public synchronized Script[] get(String url) { * @param scripts * the user scripts to execute at that URL */ - public synchronized void put(String url, Script[] scripts) { + public synchronized void put(String url, ScriptData[] scripts) { urlScripts.put(url, scripts); } diff --git a/src/at/pardus/android/webview/gm/store/ui/ScriptList.java b/src/at/pardus/android/webview/gm/store/ui/ScriptList.java index fc5e7ad..0b0b6d5 100644 --- a/src/at/pardus/android/webview/gm/store/ui/ScriptList.java +++ b/src/at/pardus/android/webview/gm/store/ui/ScriptList.java @@ -16,11 +16,18 @@ package at.pardus.android.webview.gm.store.ui; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; +import android.widget.BaseAdapter; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.ListAdapter; import android.widget.ListView; +import android.widget.TextView; import at.pardus.android.webview.gm.model.Script; import at.pardus.android.webview.gm.model.ScriptId; import at.pardus.android.webview.gm.store.ScriptStore; @@ -31,6 +38,148 @@ */ public class ScriptList { + class Listener implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { + + ScriptAdapter scriptAdapter; + + Script script; + + View row; + + View delete; + + View edit; + + public Listener(ScriptAdapter scriptAdapter, Script script, View row) { + this.scriptAdapter = scriptAdapter; + this.script = script; + this.row = row; + + CheckBox active; + + delete = row.findViewById(R.id.sli_delete); + edit = row.findViewById(R.id.sli_edit); + active = (CheckBox) row.findViewById(R.id.sli_active); + + delete.setOnClickListener(this); + edit.setOnClickListener(this); + active.setOnCheckedChangeListener(this); + } + + public void update(Script script) { + this.script = script; + } + + @Override + public void onClick (View view) { + if (view == delete) { + scriptStore.delete(script); + scriptAdapter.refresh(); + } else if (view == edit) + activity.openScriptEditor(script); + + } + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) + scriptStore.enable(script); + else + scriptStore.disable(script); + } + } + + static class Holder { + + Script script; + + CheckBox active; + + TextView name; + + TextView description; + + Listener listener; + + public Holder(View view, Listener listener) { + this.listener = listener; + + active = (CheckBox) view.findViewById(R.id.sli_active); + name = (TextView) view.findViewById(R.id.sli_name); + description = (TextView) view.findViewById(R.id.sli_description); + } + + public void fill(ScriptStore scriptStore, Script script) { + this.script = script; + + listener.update(script); + active.setChecked(scriptStore.isEnabled(script)); + name.setText(script.getName()); + description.setText(script.getDescription()); + } + } + + class ScriptAdapter extends BaseAdapter { + + /// The full (unfiltered) list of items. + Script script []; + + /// The script store + ScriptStore scriptStore; + + public ScriptAdapter(ScriptStore scriptStore) { + this.scriptStore = scriptStore; + + script = scriptStore.getAll(); + } + + public void refresh () + { + script = scriptStore.getAll(); + notifyDataSetChanged(); + } + + @Override + public int getCount () { + return script.length; + } + + @Override + public Script getItem (int position) { + return script [position]; + } + + @Override + public long getItemId (int position) { + return position; + } + + @Override + public View getView (int position, View row, ViewGroup parent) { + LayoutInflater inflater; + Listener listener; + Holder holder; + Script script; + + script = getItem(position); + holder = row != null ? (Holder) row.getTag() : null; + if (holder == null) { + inflater = activity.getLayoutInflater(); + + row = inflater.inflate (R.layout.script_list_item, parent, false); + + listener = new Listener(this, script, row); + holder = new Holder (row, listener); + row.setTag (holder); + } + + holder.fill (scriptStore, script); + + return row; + } + } + + protected ScriptManagerActivity activity; protected ScriptStore scriptStore; @@ -43,14 +192,20 @@ public class ScriptList { * @return the updated list view */ public View getScriptList() { - // TODO separate look (or list) for disabled scripts - Script[] scripts = scriptStore.getAll(); - scriptList.setAdapter(new ArrayAdapter