diff options
-rw-r--r-- | res/layout/browser_add_bookmark.xml | 3 | ||||
-rw-r--r-- | res/menu/bookmarkscontext.xml | 10 | ||||
-rw-r--r-- | res/values/strings.xml | 8 | ||||
-rw-r--r-- | src/com/android/browser/AddBookmarkPage.java | 118 | ||||
-rw-r--r-- | src/com/android/browser/BookmarkUtils.java | 18 | ||||
-rw-r--r-- | src/com/android/browser/BrowserBookmarksPage.java | 163 |
6 files changed, 191 insertions, 129 deletions
diff --git a/res/layout/browser_add_bookmark.xml b/res/layout/browser_add_bookmark.xml index 58b7a6b..0eaf526 100644 --- a/res/layout/browser_add_bookmark.xml +++ b/res/layout/browser_add_bookmark.xml @@ -93,7 +93,8 @@ android:textAppearance="?android:attr/textAppearanceMedium" /> </TableRow> - <TableRow> + <TableRow + android:id="@+id/row_address"> <TextView android:id="@+id/addressText" android:layout_height="wrap_content" diff --git a/res/menu/bookmarkscontext.xml b/res/menu/bookmarkscontext.xml index c58d459..4d7ec7a 100644 --- a/res/menu/bookmarkscontext.xml +++ b/res/menu/bookmarkscontext.xml @@ -15,7 +15,8 @@ --> <menu xmlns:android="http://schemas.android.com/apk/res/android"> - <group android:id="@+id/CONTEXT_MENU"> + <group android:id="@+id/BOOKMARK_CONTEXT_MENU" + android:visible="false"> <item android:id="@+id/open_context_menu_id" android:title="@string/open_bookmark"/> <item android:id="@+id/new_window_context_menu_id" @@ -33,4 +34,11 @@ <item android:id="@+id/homepage_context_menu_id" android:title="@string/set_as_homepage"/> </group> + <group android:id="@+id/FOLDER_CONTEXT_MENU" + android:visible="false"> + <item android:id="@+id/edit_context_menu_id" + android:title="@string/edit_folder"/> + <item android:id="@+id/delete_context_menu_id" + android:title="@string/delete_folder"/> + </group> </menu> diff --git a/res/values/strings.xml b/res/values/strings.xml index 7d27dec..e98d9d5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -131,6 +131,10 @@ <!-- Default name for a new folder and label for a button that allows the user to create a new folder in the add bookmark dialog --> <string name="new_folder">New folder</string> + <!-- Context menu item to edit a folder [CHAR LIMIT=50] --> + <string name="edit_folder">Edit folder</string> + <!-- Context menu item to delete a folder [CHAR LIMIT=50] --> + <string name="delete_folder">Delete folder</string> <!-- Label stating that the currently open folder has no subfolders in the add bookmark dialog [CHAR-LIMIT=none]--> <string name="no_subfolders">No subfolders</string> @@ -230,6 +234,10 @@ <string name="webarchive_saved">Web archive saved.</string> <!-- Toast informing the user that saving the page has failed. --> <string name="webarchive_failed">Failed to save web archive.</string> + <!-- The number of bookmarks in a folder [CHAR LIMT=50] --> + <string name="contextheader_folder_bookmarkcount"><xliff:g id="bookmark_count">%d</xliff:g> bookmarks</string> + <!-- No bookmarks in the folder [CHAR LIMIT=50] --> + <string name="contextheader_folder_empty">Empty folder</string> <!-- Context Menu item open the currently selected link in the current window.--> <string name="contextmenu_openlink">Open</string> diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java index 25c9217..de256a8 100644 --- a/src/com/android/browser/AddBookmarkPage.java +++ b/src/com/android/browser/AddBookmarkPage.java @@ -25,7 +25,6 @@ import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.CursorLoader; -import android.content.Intent; import android.content.Loader; import android.content.SharedPreferences; import android.content.res.Resources; @@ -35,6 +34,7 @@ import android.graphics.drawable.Drawable; import android.net.ParseException; import android.net.Uri; import android.net.WebAddress; +import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -60,7 +60,6 @@ import android.widget.Toast; import java.net.URI; import java.net.URISyntaxException; -import java.util.ArrayList; import java.util.Stack; public class AddBookmarkPage extends Activity @@ -74,6 +73,9 @@ public class AddBookmarkPage extends Activity public static final String REMOVE_THUMBNAIL = "remove_thumbnail"; public static final String USER_AGENT = "user_agent"; + /* package */ static final String EXTRA_EDIT_BOOKMARK = "bookmark"; + /* package */ static final String EXTRA_IS_FOLDER = "is_folder"; + private static final int MAX_CRUMBS_SHOWN = 2; private final String LOGTAG = "Bookmarks"; @@ -89,6 +91,7 @@ public class AddBookmarkPage extends Activity private TextView mButton; private View mCancelButton; private boolean mEditingExisting; + private boolean mEditingFolder; private Bundle mMap; private String mTouchIconUrl; private String mOriginalUrl; @@ -238,6 +241,9 @@ public class AddBookmarkPage extends Activity PopupMenu popup = new PopupMenu(this, mFolder); popup.getMenuInflater().inflate(R.menu.folder_choice, popup.getMenu()); + if (mEditingFolder) { + popup.getMenu().removeItem(R.id.home_screen); + } popup.setOnMenuItemClickListener(this); popup.show(); } else if (v == mAddNewFolder) { @@ -501,11 +507,15 @@ public class AddBookmarkPage extends Activity mFakeTitle = (TextView) findViewById(R.id.fake_title); if (mMap != null) { - Bundle b = mMap.getBundle("bookmark"); + Bundle b = mMap.getBundle(EXTRA_EDIT_BOOKMARK); if (b != null) { + mEditingFolder = mMap.getBoolean(EXTRA_IS_FOLDER, false); mMap = b; mEditingExisting = true; mFakeTitle.setText(R.string.edit_bookmark); + if (mEditingFolder) { + findViewById(R.id.row_address).setVisibility(View.GONE); + } } else { int gravity = mMap.getInt("gravity", -1); if (gravity != -1) { @@ -648,6 +658,28 @@ public class AddBookmarkPage extends Activity } } + private static class UpdateBookmarkTask extends AsyncTask<ContentValues, Void, Void> { + Context mContext; + Long mId; + + public UpdateBookmarkTask(Context context, long id) { + mContext = context; + mId = id; + } + + @Override + protected Void doInBackground(ContentValues... params) { + if (params.length != 1) { + throw new IllegalArgumentException("No ContentValues provided!"); + } + Uri uri = ContentUris.withAppendedId(BookmarkUtils.getBookmarksUri(mContext), mId); + mContext.getContentResolver().update( + uri, + params[0], null, null); + return null; + } + } + private void createHandler() { if (mHandler == null) { mHandler = new Handler() { @@ -691,7 +723,7 @@ public class AddBookmarkPage extends Activity boolean emptyTitle = title.length() == 0; boolean emptyUrl = unfilteredUrl.trim().length() == 0; Resources r = getResources(); - if (emptyTitle || emptyUrl) { + if (emptyTitle || (emptyUrl && !mEditingFolder)) { if (emptyTitle) { mTitle.setError(r.getText(R.string.bookmark_needs_title)); } @@ -702,36 +734,38 @@ public class AddBookmarkPage extends Activity } String url = unfilteredUrl.trim(); - try { - // We allow bookmarks with a javascript: scheme, but these will in most cases - // fail URI parsing, so don't try it if that's the kind of bookmark we have. - - if (!url.toLowerCase().startsWith("javascript:")) { - URI uriObj = new URI(url); - String scheme = uriObj.getScheme(); - if (!Bookmarks.urlHasAcceptableScheme(url)) { - // If the scheme was non-null, let the user know that we - // can't save their bookmark. If it was null, we'll assume - // they meant http when we parse it in the WebAddress class. - if (scheme != null) { - mAddress.setError(r.getText(R.string.bookmark_cannot_save_url)); - return false; - } - WebAddress address; - try { - address = new WebAddress(unfilteredUrl); - } catch (ParseException e) { - throw new URISyntaxException("", ""); - } - if (address.getHost().length() == 0) { - throw new URISyntaxException("", ""); + if (!mEditingFolder) { + try { + // We allow bookmarks with a javascript: scheme, but these will in most cases + // fail URI parsing, so don't try it if that's the kind of bookmark we have. + + if (!url.toLowerCase().startsWith("javascript:")) { + URI uriObj = new URI(url); + String scheme = uriObj.getScheme(); + if (!Bookmarks.urlHasAcceptableScheme(url)) { + // If the scheme was non-null, let the user know that we + // can't save their bookmark. If it was null, we'll assume + // they meant http when we parse it in the WebAddress class. + if (scheme != null) { + mAddress.setError(r.getText(R.string.bookmark_cannot_save_url)); + return false; + } + WebAddress address; + try { + address = new WebAddress(unfilteredUrl); + } catch (ParseException e) { + throw new URISyntaxException("", ""); + } + if (address.getHost().length() == 0) { + throw new URISyntaxException("", ""); + } + url = address.toString(); } - url = address.toString(); } + } catch (URISyntaxException e) { + mAddress.setError(r.getText(R.string.bookmark_url_not_valid)); + return false; } - } catch (URISyntaxException e) { - mAddress.setError(r.getText(R.string.bookmark_url_not_valid)); - return false; } if (mSaveToHomeScreen) { @@ -741,13 +775,20 @@ public class AddBookmarkPage extends Activity boolean urlUnmodified = url.equals(mOriginalUrl); if (mEditingExisting) { - mMap.putString(BrowserContract.Bookmarks.TITLE, title); - mMap.putString(BrowserContract.Bookmarks.URL, url); - mMap.putBoolean(REMOVE_THUMBNAIL, !urlUnmodified); - // FIXME: This does not work yet - mMap.putLong(BrowserContract.Bookmarks.PARENT, mCurrentFolder); - setResult(RESULT_OK, (new Intent()).setAction( - getIntent().toString()).putExtras(mMap)); + Long id = mMap.getLong(BrowserContract.Bookmarks._ID); + ContentValues values = new ContentValues(); + values.put(BrowserContract.Bookmarks.TITLE, title); + values.put(BrowserContract.Bookmarks.PARENT, mCurrentFolder); + if (!mEditingFolder) { + values.put(BrowserContract.Bookmarks.URL, url); + if (!urlUnmodified) { + values.putNull(BrowserContract.Bookmarks.THUMBNAIL); + } + } + if (values.size() > 0) { + new UpdateBookmarkTask(getApplicationContext(), id).execute(values); + } + setResult(RESULT_OK); } else { Bitmap thumbnail; Bitmap favicon; @@ -794,5 +835,4 @@ public class AddBookmarkPage extends Activity } return true; } - } diff --git a/src/com/android/browser/BookmarkUtils.java b/src/com/android/browser/BookmarkUtils.java index 751c0b3..a63b90f 100644 --- a/src/com/android/browser/BookmarkUtils.java +++ b/src/com/android/browser/BookmarkUtils.java @@ -18,6 +18,7 @@ package com.android.browser; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; @@ -29,8 +30,10 @@ import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.net.Uri; +import android.preference.PreferenceManager; import android.provider.Browser; -import android.util.Log; +import android.provider.BrowserContract; +import android.text.TextUtils; class BookmarkUtils { private final static String LOGTAG = "BookmarkUtils"; @@ -165,4 +168,17 @@ class BookmarkUtils { canvas.drawBitmap(favicon, null, r, p); } + /* package */ static Uri getBookmarksUri(Context context) { + Uri uri = BrowserContract.Bookmarks.CONTENT_URI; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + String accountType = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_TYPE, null); + String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null); + if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { + uri = uri.buildUpon() + .appendQueryParameter(BrowserContract.Bookmarks.PARAM_ACCOUNT_NAME, accountName) + .appendQueryParameter(BrowserContract.Bookmarks.PARAM_ACCOUNT_TYPE, accountType) + .build(); + } + return uri; + } }; diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java index 4370885..4887f3f 100644 --- a/src/com/android/browser/BrowserBookmarksPage.java +++ b/src/com/android/browser/BrowserBookmarksPage.java @@ -24,7 +24,6 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.ContentResolver; import android.content.ContentUris; -import android.content.ContentValues; import android.content.Context; import android.content.CursorLoader; import android.content.DialogInterface; @@ -36,6 +35,7 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.provider.BrowserContract; @@ -75,7 +75,6 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener, OnItemSelectedListener, BreadCrumbView.Controller, OnClickListener, OnMenuItemClickListener { - static final int BOOKMARKS_SAVE = 1; static final String LOGTAG = "browser"; static final int LOADER_BOOKMARKS = 1; @@ -98,7 +97,6 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte ListView mList; BrowserBookmarksAdapter mAdapter; boolean mDisableNewWindow; - BookmarkItem mContextHeader; boolean mCanceled = false; boolean mEnableContextMenu = true; boolean mShowRootFolder = false; @@ -331,42 +329,60 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte return BitmapFactory.decodeByteArray(data, 0, data.length); } + private MenuItem.OnMenuItemClickListener mContextItemClickListener = + new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + return onContextItemSelected(item); + } + }; + @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; Cursor cursor = mAdapter.getItem(info.position); boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; - if (isFolder) return; final Activity activity = getActivity(); MenuInflater inflater = activity.getMenuInflater(); inflater.inflate(R.menu.bookmarkscontext, menu); - - if (mDisableNewWindow) { - menu.findItem(R.id.new_window_context_menu_id).setVisible(false); + if (isFolder) { + menu.setGroupVisible(R.id.FOLDER_CONTEXT_MENU, true); + } else { + menu.setGroupVisible(R.id.BOOKMARK_CONTEXT_MENU, true); + if (mDisableNewWindow) { + menu.findItem(R.id.new_window_context_menu_id).setVisible(false); + } } + BookmarkItem header = new BookmarkItem(activity); + populateBookmarkItem(cursor, header, isFolder); + new LookupBookmarkCount(getActivity(), header) + .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); + menu.setHeaderView(header); - if (mContextHeader == null) { - mContextHeader = new BookmarkItem(activity); - } else if (mContextHeader.getParent() != null) { - ((ViewGroup) mContextHeader.getParent()).removeView(mContextHeader); + int count = menu.size(); + for (int i = 0; i < count; i++) { + menu.getItem(i).setOnMenuItemClickListener(mContextItemClickListener); } - - populateBookmarkItem(cursor, mContextHeader); - - menu.setHeaderView(mContextHeader); } - private void populateBookmarkItem(Cursor cursor, BookmarkItem item) { - String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); - item.setUrl(url); + private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder) { item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); - Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); - if (bitmap == null) { - bitmap = CombinedBookmarkHistoryView.getIconListenerSet().getFavicon(url); + if (isFolder) { + item.setUrl(null); + Bitmap bitmap = + BitmapFactory.decodeResource(getResources(), R.drawable.ic_folder); + item.setFavicon(bitmap); + } else { + String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); + item.setUrl(url); + Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); + if (bitmap == null) { + bitmap = CombinedBookmarkHistoryView.getIconListenerSet().getFavicon(url); + } + item.setFavicon(bitmap); } - item.setFavicon(bitmap); } /** @@ -566,73 +582,14 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte item.putParcelable(BrowserContract.Bookmarks.FAVICON, BitmapFactory.decodeByteArray(data, 0, data.length)); } - item.putInt("id", cursor.getInt(BookmarksLoader.COLUMN_INDEX_ID)); + item.putLong(BrowserContract.Bookmarks._ID, + cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); item.putLong(BrowserContract.Bookmarks.PARENT, cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT)); - intent.putExtra("bookmark", item); - startActivityForResult(intent, BOOKMARKS_SAVE); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - switch(requestCode) { - case BOOKMARKS_SAVE: - if (resultCode == Activity.RESULT_OK) { - Bundle extras; - if (data != null && (extras = data.getExtras()) != null) { - // If there are extras, then we need to save - // the edited bookmark. This is done in updateRow() - String title = extras.getString(BrowserContract.Bookmarks.TITLE); - String url = extras.getString(BrowserContract.Bookmarks.URL); - if (title != null && url != null) { - updateRow(extras); - } - } - } - break; - } - } - - /** - * Update a row in the database with new information. - * @param map Bundle storing id, title and url of new information - */ - public void updateRow(Bundle map) { - - // Find the record - int id = map.getInt("id"); - int position = -1; - Cursor cursor = mAdapter.getCursor(); - for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { - if (cursor.getInt(BookmarksLoader.COLUMN_INDEX_ID) == id) { - position = cursor.getPosition(); - break; - } - } - if (position < 0) { - return; - } - - cursor.moveToPosition(position); - ContentValues values = new ContentValues(); - String title = map.getString(BrowserContract.Bookmarks.TITLE); - if (!title.equals(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE))) { - values.put(BrowserContract.Bookmarks.TITLE, title); - } - String url = map.getString(BrowserContract.Bookmarks.URL); - if (!url.equals(cursor.getString(BookmarksLoader.COLUMN_INDEX_URL))) { - values.put(BrowserContract.Bookmarks.URL, url); - } - - if (map.getBoolean(AddBookmarkPage.REMOVE_THUMBNAIL)) { - values.putNull(BrowserContract.Bookmarks.THUMBNAIL); - } - - if (values.size() > 0) { - getActivity().getContentResolver().update( - ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id), - values, null, null); - } + intent.putExtra(AddBookmarkPage.EXTRA_EDIT_BOOKMARK, item); + intent.putExtra(AddBookmarkPage.EXTRA_IS_FOLDER, + cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1); + startActivity(intent); } private void displayRemoveBookmarkDialog(final int position) { @@ -779,4 +736,36 @@ public class BrowserBookmarksPage extends Fragment implements View.OnCreateConte } } } + + private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> { + Context mContext; + BookmarkItem mHeader; + + public LookupBookmarkCount(Context context, BookmarkItem header) { + mContext = context; + mHeader = header; + } + + @Override + protected Integer doInBackground(Long... params) { + if (params.length != 1) { + throw new IllegalArgumentException("Missing folder id!"); + } + Uri uri = BookmarkUtils.getBookmarksUri(mContext); + Cursor c = mContext.getContentResolver().query(uri, + null, BrowserContract.Bookmarks.PARENT + "=?", + new String[] {params[0].toString()}, null); + return c.getCount(); + } + + @Override + protected void onPostExecute(Integer result) { + if (result > 0) { + mHeader.setUrl(mContext.getString(R.string.contextheader_folder_bookmarkcount, + result)); + } else if (result == 0) { + mHeader.setUrl(mContext.getString(R.string.contextheader_folder_empty)); + } + } + } } |