diff options
Diffstat (limited to 'src/com/android/browser/BrowserBookmarksPage.java')
-rw-r--r-- | src/com/android/browser/BrowserBookmarksPage.java | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java new file mode 100644 index 0000000..7708e8b --- /dev/null +++ b/src/com/android/browser/BrowserBookmarksPage.java @@ -0,0 +1,385 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * 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. + */ + +package com.android.browser; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.ServiceManager; +import android.provider.Browser; +import android.text.IClipboard; +import android.util.Log; +import android.view.ContextMenu; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.ContextMenu.ContextMenuInfo; +import android.widget.AdapterView; +import android.widget.ListView; + +/** + * View showing the user's bookmarks in the browser. + */ +public class BrowserBookmarksPage extends Activity implements + View.OnCreateContextMenuListener { + + private BrowserBookmarksAdapter mBookmarksAdapter; + private static final int BOOKMARKS_SAVE = 1; + private boolean mMaxTabsOpen; + private BookmarkItem mContextHeader; + private AddNewBookmark mAddHeader; + private boolean mCanceled = false; + private boolean mCreateShortcut; + // XXX: There is no public string defining this intent so if Home changes + // the value, we have to update this string. + private static final String INSTALL_SHORTCUT = + "com.android.launcher.action.INSTALL_SHORTCUT"; + + private final static String LOGTAG = "browser"; + + + @Override + public boolean onContextItemSelected(MenuItem item) { + // It is possible that the view has been canceled when we get to + // this point as back has a higher priority + if (mCanceled) { + return true; + } + AdapterView.AdapterContextMenuInfo i = + (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); + // If we have no menu info, we can't tell which item was selected. + if (i == null) { + return true; + } + + switch (item.getItemId()) { + case R.id.new_context_menu_id: + saveCurrentPage(); + break; + case R.id.open_context_menu_id: + loadUrl(i.position); + break; + case R.id.edit_context_menu_id: + editBookmark(i.position); + break; + case R.id.shortcut_context_menu_id: + final Intent send = createShortcutIntent(getUrl(i.position), + getBookmarkTitle(i.position)); + send.setAction(INSTALL_SHORTCUT); + sendBroadcast(send); + break; + case R.id.delete_context_menu_id: + displayRemoveBookmarkDialog(i.position); + break; + case R.id.new_window_context_menu_id: + openInNewWindow(i.position); + break; + case R.id.send_context_menu_id: + Browser.sendString(BrowserBookmarksPage.this, getUrl(i.position)); + break; + case R.id.copy_url_context_menu_id: + copy(getUrl(i.position)); + + default: + return super.onContextItemSelected(item); + } + return true; + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + AdapterView.AdapterContextMenuInfo i = + (AdapterView.AdapterContextMenuInfo) menuInfo; + + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.bookmarkscontext, menu); + + if (0 == i.position) { + menu.setGroupVisible(R.id.CONTEXT_MENU, false); + if (mAddHeader == null) { + mAddHeader = new AddNewBookmark(BrowserBookmarksPage.this); + } else if (mAddHeader.getParent() != null) { + ((ViewGroup) mAddHeader.getParent()). + removeView(mAddHeader); + } + ((AddNewBookmark) i.targetView).copyTo(mAddHeader); + menu.setHeaderView(mAddHeader); + return; + } + menu.setGroupVisible(R.id.ADD_MENU, false); + BookmarkItem b = (BookmarkItem) i.targetView; + if (mContextHeader == null) { + mContextHeader = new BookmarkItem(BrowserBookmarksPage.this); + } else if (mContextHeader.getParent() != null) { + ((ViewGroup) mContextHeader.getParent()). + removeView(mContextHeader); + } + b.copyTo(mContextHeader); + menu.setHeaderView(mContextHeader); + + if (mMaxTabsOpen) { + menu.findItem(R.id.new_window_context_menu_id).setVisible( + false); + } + } + + /** + * Create a new BrowserBookmarksPage. + */ + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + + setContentView(R.layout.browser_bookmarks_page); + setTitle(R.string.browser_bookmarks_page_bookmarks_text); + + if (Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction())) { + mCreateShortcut = true; + } + + mBookmarksAdapter = new BrowserBookmarksAdapter(this, + getIntent().getStringExtra("url"), mCreateShortcut); + mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false); + + ListView listView = (ListView) findViewById(R.id.list); + listView.setAdapter(mBookmarksAdapter); + listView.setDrawSelectorOnTop(false); + listView.setVerticalScrollBarEnabled(true); + listView.setOnItemClickListener(mListener); + + if (!mCreateShortcut) { + listView.setOnCreateContextMenuListener(this); + } + } + + private static final int SAVE_CURRENT_PAGE = 1000; + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + if (msg.what == SAVE_CURRENT_PAGE) { + saveCurrentPage(); + } + } + }; + + private AdapterView.OnItemClickListener mListener = new AdapterView.OnItemClickListener() { + public void onItemClick(AdapterView parent, View v, int position, long id) { + // It is possible that the view has been canceled when we get to + // this point as back has a higher priority + if (mCanceled) { + android.util.Log.e("browser", "item clicked when dismising"); + return; + } + if (!mCreateShortcut) { + if (0 == position) { + // XXX: Work-around for a framework issue. + mHandler.sendEmptyMessage(SAVE_CURRENT_PAGE); + } else { + loadUrl(position); + } + } else { + final Intent intent = createShortcutIntent(getUrl(position), + getBookmarkTitle(position)); + setResultToParent(RESULT_OK, intent); + finish(); + } + } + }; + + private Intent createShortcutIntent(String url, String title) { + final Intent i = new Intent(); + i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_VIEW, + Uri.parse(url))); + i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title); + i.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, + Intent.ShortcutIconResource.fromContext(BrowserBookmarksPage.this, + R.drawable.ic_launcher_browser)); + // Do not allow duplicate items + i.putExtra("duplicate", false); + return i; + } + + private void saveCurrentPage() { + Intent i = new Intent(BrowserBookmarksPage.this, + AddBookmarkPage.class); + i.putExtras(getIntent()); + startActivityForResult(i, BOOKMARKS_SAVE); + } + + private void loadUrl(int position) { + Intent intent = (new Intent()).setAction(getUrl(position)); + setResultToParent(RESULT_OK, intent); + finish(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + boolean result = super.onCreateOptionsMenu(menu); + if (!mCreateShortcut) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.bookmarks, menu); + return true; + } + return result; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.new_context_menu_id: + saveCurrentPage(); + break; + + default: + return super.onOptionsItemSelected(item); + } + return true; + } + + private void openInNewWindow(int position) { + Bundle b = new Bundle(); + b.putBoolean("new_window", true); + setResultToParent(RESULT_OK, + (new Intent()).setAction(getUrl(position)).putExtras(b)); + + finish(); + } + + + private void editBookmark(int position) { + Intent intent = new Intent(BrowserBookmarksPage.this, + AddBookmarkPage.class); + intent.putExtra("bookmark", getRow(position)); + startActivityForResult(intent, BOOKMARKS_SAVE); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, + Intent data) { + switch(requestCode) { + case BOOKMARKS_SAVE: + if (resultCode == 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("title"); + String url = extras.getString("url"); + if (title != null && url != null) { + mBookmarksAdapter.updateRow(extras); + } + } else { + // extras == null then a new bookmark was added to + // the database. + refreshList(); + } + } + break; + default: + break; + } + } + + private void displayRemoveBookmarkDialog(int position) { + // Put up a dialog asking if the user really wants to + // delete the bookmark + final int deletePos = position; + new AlertDialog.Builder(this) + .setTitle(R.string.delete_bookmark) + .setIcon(android.R.drawable.ic_dialog_alert) + .setMessage(getText(R.string.delete_bookmark_warning).toString().replace( + "%s", getBookmarkTitle(deletePos))) + .setPositiveButton(R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + deleteBookmark(deletePos); + } + }) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + /** + * Refresh the shown list after the database has changed. + */ + public void refreshList() { + mBookmarksAdapter.refreshList(); + } + + /** + * Return a hashmap representing the currently highlighted row. + */ + public Bundle getRow(int position) { + return mBookmarksAdapter.getRow(position); + } + + /** + * Return the url of the currently highlighted row. + */ + public String getUrl(int position) { + return mBookmarksAdapter.getUrl(position); + } + + private void copy(CharSequence text) { + try { + IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard")); + if (clip != null) { + clip.setClipboardText(text); + } + } catch (android.os.RemoteException e) { + Log.e(LOGTAG, "Copy failed", e); + } + } + + public String getBookmarkTitle(int position) { + return mBookmarksAdapter.getTitle(position); + } + + /** + * Delete the currently highlighted row. + */ + public void deleteBookmark(int position) { + mBookmarksAdapter.deleteRow(position); + } + + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.isDown()) { + setResultToParent(RESULT_CANCELED, null); + mCanceled = true; + } + return super.dispatchKeyEvent(event); + } + + // This Activity is generally a sub-Activity of CombinedHistoryActivity. In + // that situation, we need to pass our result code up to our parent. + // However, if someone calls this Activity directly, then this has no + // parent, and it needs to set it on itself. + private void setResultToParent(int resultCode, Intent data) { + Activity a = getParent() == null ? this : getParent(); + a.setResult(resultCode, data); + } +} |