[[project @ 17] christian.koestlin**20090120193543 Ignore-this: 3124e57567b4f4081532376d3390277d ContentProvider for VncSettings Activities for listing, editing, viewing and deleting ... of VncSettings. ] addfile ./androidVNC/res/layout/edit_setting.xml addfile ./androidVNC/res/layout/vnc_setting_row.xml addfile ./androidVNC/src/android/androidVNC/Provider.java adddir ./androidVNC/src/android/androidVNC/gui addfile ./androidVNC/src/android/androidVNC/gui/DeleteVncSettingsActivity.java addfile ./androidVNC/src/android/androidVNC/gui/EditVncSettingsActivity.java addfile ./androidVNC/src/android/androidVNC/gui/InsertVncSettingsActivity.java addfile ./androidVNC/src/android/androidVNC/gui/ListVncSettingsActivity.java addfile ./androidVNC/src/android/androidVNC/gui/View2UriLinker.java adddir ./androidVNC/src/android/androidVNC/gui/links addfile ./androidVNC/src/android/androidVNC/gui/links/BijectiveMapping.java addfile ./androidVNC/src/android/androidVNC/gui/links/Colormodel2IntegerMapping.java addfile ./androidVNC/src/android/androidVNC/gui/links/Link.java addfile ./androidVNC/src/android/androidVNC/gui/links/SpinnerLink.java addfile ./androidVNC/src/android/androidVNC/gui/links/TextViewLink.java hunk ./androidVNC/AndroidManifest.xml 5 - - - - - - + + + hunk ./androidVNC/AndroidManifest.xml 11 - + + + hunk ./androidVNC/AndroidManifest.xml 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + hunk ./androidVNC/AndroidManifest.xml 48 - + + + + + hunk ./androidVNC/res/layout/edit_setting.xml 1 + + + + + + + + + + + + + + + + + + + + + hunk ./androidVNC/res/layout/vnc_setting_row.xml 1 + + + + + + hunk ./androidVNC/res/values/strings.xml 17 + new + edit + delete hunk ./androidVNC/src/android/androidVNC/COLORMODEL.java 4 +import java.io.Serializable; hunk ./androidVNC/src/android/androidVNC/COLORMODEL.java 6 -public enum COLORMODEL { +public enum COLORMODEL implements Serializable { hunk ./androidVNC/src/android/androidVNC/Provider.java 1 +package android.androidVNC; + +import java.util.HashMap; + +import android.app.Activity; +import android.content.ContentProvider; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.SQLException; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.database.sqlite.SQLiteQueryBuilder; +import android.net.Uri; +import android.provider.BaseColumns; +import android.text.TextUtils; +import android.util.Log; + +public class Provider extends ContentProvider { + + private static final String ALL = "settings"; + private static final int ALL_MATCHCODE = 1; + private static final String ONE = ALL + "/#"; + private static final int ONE_MATCHCODE = 2; + + public static final String AUTHORITY = "android.androidVNC.Provider"; + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + ALL); + public static final String CONTENT_ALL_TYPE = "vnd.android.cursor.dir/vnd.vnc.config"; + public static final String CONTENT_ONE_TYPE = "vnd.android.cursor.item/vnd.vnc.config"; + + private static UriMatcher matcher; + + static { + matcher = new UriMatcher(ALL_MATCHCODE); + matcher.addURI(AUTHORITY, ALL, ALL_MATCHCODE); + matcher.addURI(AUTHORITY, ONE, ONE_MATCHCODE); + } + + private DatabaseHelper fDatabase; + + @Override + public boolean onCreate() { + fDatabase = new DatabaseHelper(getContext()); + return true; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { + SQLiteQueryBuilder qb = fDatabase.getQueryBuilder(); + + switch (matcher.match(uri)) { + case ALL_MATCHCODE: + break; + case ONE_MATCHCODE: + qb.appendWhere(VncSettings._ID + "=" + uri.getPathSegments().get(1)); + break; + default: + throw new RuntimeException("illegal uri"); + } + Cursor res = qb.query(fDatabase.getReadableDatabase(), null, null, null, null, null, null); + res.setNotificationUri(getContext().getContentResolver(), uri); + return res; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + if (matcher.match(uri) != ONE_MATCHCODE) { + throw new RuntimeException("nyi"); + } + + String segment = uri.getPathSegments().get(1); // contains rowId + getContext().getContentResolver().notifyChange(uri, null); + return fDatabase.getWritableDatabase().delete(TABLE_NAME, VncSettings._ID + "=" + segment, null); + } + + @Override + public String getType(Uri uri) { + switch (matcher.match(uri)) { + case ALL_MATCHCODE: + return CONTENT_ALL_TYPE; + case ONE_MATCHCODE: + return CONTENT_ONE_TYPE; + default: + throw new RuntimeException("no match"); + } + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + if (matcher.match(uri) != ALL_MATCHCODE) { + throw new IllegalArgumentException("insert must be done on the list resource"); + } + + SQLiteDatabase db = fDatabase.getWritableDatabase(); + long id = db.insert(TABLE_NAME, VncSettings.HOST, values); + if (id > 0) { + Uri newUri = ContentUris.withAppendedId(CONTENT_URI, id); + getContext().getContentResolver().notifyChange(newUri, null); + return newUri; + + } + throw new SQLException("could not insert element"); + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + if (matcher.match(uri) != ONE_MATCHCODE) { + throw new IllegalArgumentException("update must be called on an item"); + } + + String id = uri.getPathSegments().get(1); + return fDatabase.getWritableDatabase().update(TABLE_NAME, values, VncSettings._ID + "=" + id + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs); + } + + private static final String TABLE_NAME = "vncsettings"; + + public static class VncSettings implements BaseColumns { + public static final String HOST = "host"; + public static final String PORT = "port"; + public static final String PASSWORD = "password"; + public static final String COLORMODEL = "colormodel"; + private final Cursor fCursor; + private static final HashMap fIndexMap = new HashMap(); + + public static VncSettings getHelper(Activity activity, Uri uri) { + Cursor c = activity.managedQuery(uri, null, null, null, null); + if (!c.moveToFirst()) { + return null; + } + return new VncSettings(c); + } + + public String getString(String key) { + return fCursor.getString(getIndex(key)); + } + + public int getInt(String key) { + return fCursor.getInt(getIndex(key)); + } + + private VncSettings(Cursor c) { + fCursor = c; + } + + private int getIndex(String key) { + int idx = -1; + if (fIndexMap.containsKey(key)) { + idx = fIndexMap.get(key).intValue(); + } else { + idx = fCursor.getColumnIndex(key); + if (idx != -1) { + fIndexMap.put(key, new Integer(idx)); + } + } + + if (idx == -1) { + throw new RuntimeException("index for row " + key + " not found"); + } + return idx; + } + } + + private static class DatabaseHelper extends SQLiteOpenHelper { + private static final String DATABASE_NAME = "vnc_settings.db"; + private static final int DATABASE_VERSION = 3; + + DatabaseHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + public SQLiteQueryBuilder getQueryBuilder() { + SQLiteQueryBuilder res = new SQLiteQueryBuilder(); + res.setTables(TABLE_NAME); + return res; + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + VncSettings._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + VncSettings.HOST + " TEXT," + VncSettings.PORT + " TEXT," + VncSettings.PASSWORD + " TEXT," + VncSettings.COLORMODEL + " INTEGER" + ");"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + Log.w(getClass().getName(), "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); + db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); + onCreate(db); + } + } +} hunk ./androidVNC/src/android/androidVNC/R.java 17 - public static final int buttonGO=0x7f060004; - public static final int colorformat=0x7f060003; - public static final int groupScaling=0x7f060009; - public static final int itemCenterMouse=0x7f060006; - public static final int itemColorMode=0x7f060007; - public static final int itemCtrlAltDel=0x7f060012; - public static final int itemDisconnect=0x7f060011; - public static final int itemFitToScreen=0x7f06000b; - public static final int itemInfo=0x7f060005; - public static final int itemInputFitToScreen=0x7f06000d; - public static final int itemInputMode=0x7f06000c; - public static final int itemInputMouse=0x7f06000f; - public static final int itemInputPan=0x7f06000e; - public static final int itemInputTouchPanTrackballMouse=0x7f060010; - public static final int itemOneToOne=0x7f06000a; - public static final int itemScaling=0x7f060008; - public static final int textIP=0x7f060000; - public static final int textPASSWORD=0x7f060002; - public static final int textPORT=0x7f060001; + public static final int buttonGO=0x7f060008; + public static final int colorformat=0x7f060007; + public static final int edit_colorformat=0x7f060003; + public static final int edit_ip=0x7f060000; + public static final int edit_password=0x7f060002; + public static final int edit_port=0x7f060001; + public static final int groupScaling=0x7f06000f; + public static final int itemCenterMouse=0x7f06000c; + public static final int itemColorMode=0x7f06000d; + public static final int itemCtrlAltDel=0x7f060018; + public static final int itemDisconnect=0x7f060017; + public static final int itemFitToScreen=0x7f060011; + public static final int itemInfo=0x7f06000b; + public static final int itemInputFitToScreen=0x7f060013; + public static final int itemInputMode=0x7f060012; + public static final int itemInputMouse=0x7f060015; + public static final int itemInputPan=0x7f060014; + public static final int itemInputTouchPanTrackballMouse=0x7f060016; + public static final int itemOneToOne=0x7f060010; + public static final int itemScaling=0x7f06000e; + public static final int textIP=0x7f060004; + public static final int textPASSWORD=0x7f060006; + public static final int textPORT=0x7f060005; + public static final int vnc_setting_host=0x7f060009; + public static final int vnc_setting_port=0x7f06000a; hunk ./androidVNC/src/android/androidVNC/R.java 45 - public static final int main=0x7f030001; + public static final int edit_setting=0x7f030001; + public static final int main=0x7f030002; + public static final int vnc_setting_row=0x7f030003; hunk ./androidVNC/src/android/androidVNC/R.java 65 + public static final int menu_delete=0x7f040010; + public static final int menu_edit=0x7f04000f; + public static final int menu_new=0x7f04000e; hunk ./androidVNC/src/android/androidVNC/VncCanvasActivity.java 23 +import android.androidVNC.Provider.VncSettings; hunk ./androidVNC/src/android/androidVNC/VncCanvasActivity.java 27 +import android.content.Intent; hunk ./androidVNC/src/android/androidVNC/VncCanvasActivity.java 62 - hunk ./androidVNC/src/android/androidVNC/VncCanvasActivity.java 66 - Bundle extras = getIntent().getExtras(); - String host = extras.getString(VncConstants.HOST); - if (host == null) - host = extras.getString(VncConstants.IP); - int port = extras.getInt(VncConstants.PORT); - if (port == 0) - port = 5900; + Intent intent = getIntent(); + String host = null; + int port = 5900; + String password = null; + COLORMODEL colorModel = COLORMODEL.C64; + String repeaterID = null; + + if (intent.getData() != null) { + VncSettings settings = VncSettings.getHelper(this, intent.getData()); + host = settings.getString(VncSettings.HOST); + port = Integer.parseInt(settings.getString(VncSettings.PORT)); + password = settings.getString(VncSettings.PASSWORD); + colorModel = COLORMODEL.values()[settings.getInt(VncSettings.COLORMODEL)]; + repeaterID = ""; + } else { + Bundle extras = getIntent().getExtras(); + host = extras.getString(VncConstants.HOST); + if (host == null) + host = extras.getString(VncConstants.IP); + port = extras.getInt(VncConstants.PORT); + if (port == 0) + port = 5900; hunk ./androidVNC/src/android/androidVNC/VncCanvasActivity.java 89 - // Parse a HOST:PORT entry - if (host.indexOf(':') > -1) { - String p = host.substring(host.indexOf(':') + 1); - try { - port = Integer.parseInt(p); - } catch (Exception e) { - } - host = host.substring(0, host.indexOf(':')); + // Parse a HOST:PORT entry + if (host.indexOf(':') > -1) { + String p = host.substring(host.indexOf(':') + 1); + try { + port = Integer.parseInt(p); + } catch (Exception e) { + } + host = host.substring(0, host.indexOf(':')); + } + password = extras.getString(VncConstants.PASSWORD); + repeaterID = extras.getString(VncConstants.ID); + colorModel = (COLORMODEL)extras.getSerializable(VncConstants.COLORMODEL); hunk ./androidVNC/src/android/androidVNC/VncCanvasActivity.java 102 - - String password = extras.getString(VncConstants.PASSWORD); - String repeaterID = extras.getString(VncConstants.ID); - - vncCanvas = new VncCanvas(this, host, port, password, repeaterID, (COLORMODEL)extras.getSerializable(VncConstants.COLORMODEL)); + vncCanvas = new VncCanvas(this, host, port, password, repeaterID, colorModel); hunk ./androidVNC/src/android/androidVNC/VncCanvasActivity.java 196 + default: + throw new IllegalArgumentException("unknown id" + id); hunk ./androidVNC/src/android/androidVNC/gui/DeleteVncSettingsActivity.java 1 +package android.androidVNC.gui; + +import android.app.Activity; +import android.net.Uri; +import android.os.Bundle; + +public class DeleteVncSettingsActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Uri uri = getIntent().getData(); + getContentResolver().delete(uri, null, null); + finish(); + } + +} hunk ./androidVNC/src/android/androidVNC/gui/EditVncSettingsActivity.java 1 +package android.androidVNC.gui; + +import android.androidVNC.COLORMODEL; +import android.androidVNC.R; +import android.androidVNC.Provider.VncSettings; +import android.androidVNC.gui.links.Colormodel2IntegerMapping; +import android.androidVNC.gui.links.SpinnerLink; +import android.androidVNC.gui.links.TextViewLink; +import android.app.Activity; +import android.net.Uri; +import android.os.Bundle; +import android.widget.ArrayAdapter; +import android.widget.Spinner; +import android.widget.TextView; + +public class EditVncSettingsActivity extends Activity { + private TextView fHost; + private TextView fPort; + private TextView fPassword; + private Spinner fColorformat; + + View2UriLinker fLinker = new View2UriLinker(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.edit_setting); + + Uri uri = getIntent().getData(); + VncSettings helper = VncSettings.getHelper(this, uri); + fHost = (TextView)findViewById(R.id.edit_ip); + fLinker.add(new TextViewLink(this, helper, fHost, uri, VncSettings.HOST)); + + fPort = (TextView)findViewById(R.id.edit_port); + fLinker.add(new TextViewLink(this, helper, fPort, uri, VncSettings.PORT)); + + fPassword = (TextView)findViewById(R.id.edit_password); + fLinker.add(new TextViewLink(this, helper, fPassword, uri, VncSettings.PASSWORD)); + + fColorformat = (Spinner)findViewById(R.id.edit_colorformat); + ArrayAdapter colorSpinnerAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, COLORMODEL.values()); + fColorformat.setAdapter(colorSpinnerAdapter); + fLinker.add(new SpinnerLink(this, helper, fColorformat, uri, VncSettings.COLORMODEL, new Colormodel2IntegerMapping())); + } + + @Override + protected void onPause() { + super.onPause(); + + fLinker.copyFromGui2Model(); + } + +} hunk ./androidVNC/src/android/androidVNC/gui/InsertVncSettingsActivity.java 1 +package android.androidVNC.gui; + +import android.androidVNC.Provider; +import android.app.Activity; +import android.content.ContentValues; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; + +public class InsertVncSettingsActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ContentValues values = new ContentValues(); + Uri uri = getContentResolver().insert(Provider.CONTENT_URI, values); + if (uri == null) { + setResult(RESULT_CANCELED); + finish(); + return; + } + setResult(RESULT_OK, new Intent().setData(uri)); + finish(); + } + +} hunk ./androidVNC/src/android/androidVNC/gui/ListVncSettingsActivity.java 1 +package android.androidVNC.gui; + +import android.androidVNC.Provider; +import android.androidVNC.R; +import android.androidVNC.Provider.VncSettings; +import android.app.ListActivity; +import android.content.ContentUris; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.view.ContextMenu; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ContextMenu.ContextMenuInfo; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.SimpleCursorAdapter; +import android.widget.AdapterView.AdapterContextMenuInfo; + +public class ListVncSettingsActivity extends ListActivity { + + private static final int MENU_ITEM_NEW = Menu.FIRST; + + private static final int MENU_ITEM_EDIT = MENU_ITEM_NEW+1; + + private static final int MENU_ITEM_DELETE = MENU_ITEM_EDIT+1; + + private static final int INSERT_NEW = 1; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getListView().setOnCreateContextMenuListener(this); + + Intent intent = getIntent(); + if (intent.getData() == null) { + intent.setData(Provider.CONTENT_URI); + } + Cursor cursor = managedQuery(getIntent().getData(), null, null, null, null); + SimpleCursorAdapter adapter = + new SimpleCursorAdapter(this, + R.layout.vnc_setting_row, + cursor, + new String[] { Provider.VncSettings.HOST, Provider.VncSettings.PORT }, + new int[] { R.id.vnc_setting_host, R.id.vnc_setting_port }); + setListAdapter(adapter); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + view(ContentUris.withAppendedId(Provider.CONTENT_URI, id)); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + AdapterView.AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; + Cursor cursor = (Cursor) getListAdapter().getItem(info.position); + menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex(VncSettings.HOST))); + menu.add(0, MENU_ITEM_EDIT, 0, R.string.menu_edit); + menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_delete); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); + + Uri uri = ContentUris.withAppendedId(Provider.CONTENT_URI, info.id); + switch (item.getItemId()) { + case MENU_ITEM_NEW: + makeNew(); + return true; + case MENU_ITEM_EDIT: + edit(uri); + return true; + case MENU_ITEM_DELETE: + delete(uri); + return true; + } + return false; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + boolean res = super.onCreateOptionsMenu(menu); + if (res) { + menu.add(0, MENU_ITEM_NEW, 0, getString(R.string.menu_new)).setIcon(android.R.drawable.ic_menu_add); + } + return res; + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + switch (item.getItemId()) { + case MENU_ITEM_NEW: + makeNew(); + return true; + } + return super.onMenuItemSelected(featureId, item); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case INSERT_NEW: + edit(data.getData()); + break; + } + } + + private void makeNew() { + startActivityForResult(new Intent(Intent.ACTION_INSERT, Provider.CONTENT_URI), INSERT_NEW); + } + + private void view(Uri uri) { + startActivity(new Intent(Intent.ACTION_VIEW, uri)); + } + private void edit(Uri uri) { + startActivity(new Intent(Intent.ACTION_EDIT, uri)); + } + + private void delete(Uri uri) { + startActivity(new Intent(Intent.ACTION_DELETE, uri)); + } + +} hunk ./androidVNC/src/android/androidVNC/gui/View2UriLinker.java 1 +package android.androidVNC.gui; + +import java.util.ArrayList; + +import android.androidVNC.gui.links.Link; + +public class View2UriLinker { + + ArrayList fLinks = new ArrayList(); + + public void add(Link l) { + fLinks.add(l); + } + + public void copyFromGui2Model() { + for (Link l : fLinks) { + l.copyFromGui2Model(); + } + } + +} hunk ./androidVNC/src/android/androidVNC/gui/links/BijectiveMapping.java 1 +package android.androidVNC.gui.links; + +public interface BijectiveMapping { + T to(S v); + S from(T v); +} + hunk ./androidVNC/src/android/androidVNC/gui/links/Colormodel2IntegerMapping.java 1 - +package android.androidVNC.gui.links; + +import android.androidVNC.COLORMODEL; + +public class Colormodel2IntegerMapping implements BijectiveMapping { + public Integer from(COLORMODEL v) { + int idx = 0; + for (COLORMODEL c : COLORMODEL.values()) { + if (v == c) { + return idx; + } + idx++; + } + throw new RuntimeException("no mapping found"); + } + + public COLORMODEL to(Integer v) { + return COLORMODEL.values()[v]; + } +} hunk ./androidVNC/src/android/androidVNC/gui/links/Link.java 1 - +package android.androidVNC.gui.links; + +public interface Link { + void copyFromGui2Model(); +} hunk ./androidVNC/src/android/androidVNC/gui/links/SpinnerLink.java 1 - +package android.androidVNC.gui.links; + +import android.androidVNC.Provider.VncSettings; +import android.androidVNC.gui.EditVncSettingsActivity; +import android.content.ContentValues; +import android.net.Uri; +import android.view.View; +import android.widget.AdapterView; +import android.widget.Spinner; + +public class SpinnerLink implements Link { +public SpinnerLink(final EditVncSettingsActivity activity, VncSettings helper, Spinner spinner, final Uri uri, final String key, final BijectiveMapping bijectiveMapping) { + selectObject(spinner, bijectiveMapping.to(helper.getInt(key))); + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + public void onItemSelected(AdapterView adapterView, View view, int index, long arg) { + int value = bijectiveMapping.from((T)adapterView.getSelectedItem()); + ContentValues contentValues = new ContentValues(); + contentValues.put(key, value); + activity.getContentResolver().update(uri, contentValues, null, null); + } + public void onNothingSelected(AdapterView arg0) { + } + }); + } + + private void selectObject(Spinner spinner, Object object) { + for (int i=0; i