BrowserBookmarksPage.java revision ba6d7b853c32ad6c3be26c443daa61f322bcfdc2
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.browser; 18 19import android.app.Activity; 20import android.app.AlertDialog; 21import android.content.DialogInterface; 22import android.content.Intent; 23import android.net.Uri; 24import android.os.Bundle; 25import android.os.Handler; 26import android.os.Message; 27import android.os.ServiceManager; 28import android.provider.Browser; 29import android.text.IClipboard; 30import android.util.Log; 31import android.view.ContextMenu; 32import android.view.KeyEvent; 33import android.view.Menu; 34import android.view.MenuInflater; 35import android.view.MenuItem; 36import android.view.View; 37import android.view.ViewGroup; 38import android.view.ContextMenu.ContextMenuInfo; 39import android.widget.AdapterView; 40import android.widget.ListView; 41 42/** 43 * View showing the user's bookmarks in the browser. 44 */ 45public class BrowserBookmarksPage extends Activity implements 46 View.OnCreateContextMenuListener { 47 48 private BrowserBookmarksAdapter mBookmarksAdapter; 49 private static final int BOOKMARKS_SAVE = 1; 50 private boolean mMaxTabsOpen; 51 private BookmarkItem mContextHeader; 52 private AddNewBookmark mAddHeader; 53 private boolean mCanceled = false; 54 private boolean mCreateShortcut; 55 56 private final static String LOGTAG = "browser"; 57 58 59 @Override 60 public boolean onContextItemSelected(MenuItem item) { 61 // It is possible that the view has been canceled when we get to 62 // this point as back has a higher priority 63 if (mCanceled) { 64 return true; 65 } 66 AdapterView.AdapterContextMenuInfo i = 67 (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); 68 // If we have no menu info, we can't tell which item was selected. 69 if (i == null) { 70 return true; 71 } 72 73 switch (item.getItemId()) { 74 case R.id.new_context_menu_id: 75 saveCurrentPage(); 76 break; 77 case R.id.open_context_menu_id: 78 loadUrl(i.position); 79 break; 80 case R.id.edit_context_menu_id: 81 editBookmark(i.position); 82 break; 83 case R.id.delete_context_menu_id: 84 displayRemoveBookmarkDialog(i.position); 85 break; 86 case R.id.new_window_context_menu_id: 87 openInNewWindow(i.position); 88 break; 89 case R.id.send_context_menu_id: 90 Browser.sendString(BrowserBookmarksPage.this, getUrl(i.position)); 91 break; 92 case R.id.copy_url_context_menu_id: 93 copy(getUrl(i.position)); 94 95 default: 96 return super.onContextItemSelected(item); 97 } 98 return true; 99 } 100 101 @Override 102 public void onCreateContextMenu(ContextMenu menu, View v, 103 ContextMenuInfo menuInfo) { 104 AdapterView.AdapterContextMenuInfo i = 105 (AdapterView.AdapterContextMenuInfo) menuInfo; 106 107 MenuInflater inflater = getMenuInflater(); 108 inflater.inflate(R.menu.bookmarkscontext, menu); 109 110 if (0 == i.position) { 111 menu.setGroupVisible(R.id.CONTEXT_MENU, false); 112 if (mAddHeader == null) { 113 mAddHeader = new AddNewBookmark(BrowserBookmarksPage.this); 114 } else if (mAddHeader.getParent() != null) { 115 ((ViewGroup) mAddHeader.getParent()). 116 removeView(mAddHeader); 117 } 118 ((AddNewBookmark) i.targetView).copyTo(mAddHeader); 119 menu.setHeaderView(mAddHeader); 120 return; 121 } 122 menu.setGroupVisible(R.id.ADD_MENU, false); 123 BookmarkItem b = (BookmarkItem) i.targetView; 124 if (mContextHeader == null) { 125 mContextHeader = new BookmarkItem(BrowserBookmarksPage.this); 126 } else if (mContextHeader.getParent() != null) { 127 ((ViewGroup) mContextHeader.getParent()). 128 removeView(mContextHeader); 129 } 130 b.copyTo(mContextHeader); 131 menu.setHeaderView(mContextHeader); 132 133 if (mMaxTabsOpen) { 134 menu.findItem(R.id.new_window_context_menu_id).setVisible( 135 false); 136 } 137 } 138 139 /** 140 * Create a new BrowserBookmarksPage. 141 */ 142 @Override 143 protected void onCreate(Bundle icicle) { 144 super.onCreate(icicle); 145 146 setContentView(R.layout.browser_bookmarks_page); 147 setTitle(R.string.browser_bookmarks_page_bookmarks_text); 148 149 if (Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction())) { 150 mCreateShortcut = true; 151 } 152 153 mBookmarksAdapter = new BrowserBookmarksAdapter(this, 154 getIntent().getStringExtra("title"), mCreateShortcut); 155 mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false); 156 157 ListView listView = (ListView) findViewById(R.id.list); 158 listView.setAdapter(mBookmarksAdapter); 159 listView.setDrawSelectorOnTop(false); 160 listView.setVerticalScrollBarEnabled(true); 161 listView.setOnItemClickListener(mListener); 162 163 if (!mCreateShortcut) { 164 listView.setOnCreateContextMenuListener(this); 165 } 166 } 167 168 private static final int SAVE_CURRENT_PAGE = 1000; 169 private final Handler mHandler = new Handler() { 170 @Override 171 public void handleMessage(Message msg) { 172 if (msg.what == SAVE_CURRENT_PAGE) { 173 saveCurrentPage(); 174 } 175 } 176 }; 177 178 private AdapterView.OnItemClickListener mListener = new AdapterView.OnItemClickListener() { 179 public void onItemClick(AdapterView parent, View v, int position, long id) { 180 // It is possible that the view has been canceled when we get to 181 // this point as back has a higher priority 182 if (mCanceled) { 183 android.util.Log.e("browser", "item clicked when dismising"); 184 return; 185 } 186 if (!mCreateShortcut) { 187 if (0 == position) { 188 // XXX: Work-around for a framework issue. 189 mHandler.sendEmptyMessage(SAVE_CURRENT_PAGE); 190 } else { 191 loadUrl(position); 192 } 193 } else { 194 final Intent intent = new Intent(); 195 intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_VIEW, 196 Uri.parse(getUrl(position)))); 197 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getBookmarkTitle(position)); 198 intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, 199 Intent.ShortcutIconResource.fromContext(BrowserBookmarksPage.this, 200 R.drawable.ic_launcher_browser)); 201 setResult(RESULT_OK, intent); 202 finish(); 203 } 204 } 205 }; 206 207 private void saveCurrentPage() { 208 Intent i = new Intent(BrowserBookmarksPage.this, 209 AddBookmarkPage.class); 210 i.putExtras(getIntent()); 211 startActivityForResult(i, BOOKMARKS_SAVE); 212 } 213 214 private void loadUrl(int position) { 215 setResult(RESULT_OK, (new Intent()).setAction(getUrl(position))); 216 finish(); 217 } 218 219 @Override 220 public boolean onCreateOptionsMenu(Menu menu) { 221 boolean result = super.onCreateOptionsMenu(menu); 222 if (!mCreateShortcut) { 223 MenuInflater inflater = getMenuInflater(); 224 inflater.inflate(R.menu.bookmarks, menu); 225 return true; 226 } 227 return result; 228 } 229 230 @Override 231 public boolean onOptionsItemSelected(MenuItem item) { 232 switch (item.getItemId()) { 233 case R.id.new_context_menu_id: 234 saveCurrentPage(); 235 break; 236 237 default: 238 return super.onOptionsItemSelected(item); 239 } 240 return true; 241 } 242 243 private void openInNewWindow(int position) { 244 Bundle b = new Bundle(); 245 b.putBoolean("new_window", true); 246 setResult(RESULT_OK, 247 (new Intent()).setAction(getUrl(position)).putExtras(b)); 248 249 finish(); 250 } 251 252 253 private void editBookmark(int position) { 254 Intent intent = new Intent(BrowserBookmarksPage.this, 255 AddBookmarkPage.class); 256 intent.putExtra("bookmark", getRow(position)); 257 startActivityForResult(intent, BOOKMARKS_SAVE); 258 } 259 260 @Override 261 protected void onActivityResult(int requestCode, int resultCode, 262 Intent data) { 263 switch(requestCode) { 264 case BOOKMARKS_SAVE: 265 if (resultCode == RESULT_OK) { 266 Bundle extras; 267 if (data != null && (extras = data.getExtras()) != null) { 268 // If there are extras, then we need to save 269 // the edited bookmark. This is done in updateRow() 270 String title = extras.getString("title"); 271 String url = extras.getString("url"); 272 if (title != null && url != null) { 273 mBookmarksAdapter.updateRow(extras); 274 } 275 } else { 276 // extras == null then a new bookmark was added to 277 // the database. 278 refreshList(); 279 } 280 } 281 break; 282 default: 283 break; 284 } 285 } 286 287 private void displayRemoveBookmarkDialog(int position) { 288 // Put up a dialog asking if the user really wants to 289 // delete the bookmark 290 final int deletePos = position; 291 new AlertDialog.Builder(this) 292 .setTitle(R.string.delete_bookmark) 293 .setIcon(R.drawable.ssl_icon) 294 .setMessage(getText(R.string.delete_bookmark_warning).toString().replace( 295 "%s", getBookmarkTitle(deletePos))) 296 .setPositiveButton(R.string.ok, 297 new DialogInterface.OnClickListener() { 298 public void onClick(DialogInterface dialog, int whichButton) { 299 deleteBookmark(deletePos); 300 } 301 }) 302 .setNegativeButton(R.string.cancel, null) 303 .show(); 304 } 305 306 /** 307 * Refresh the shown list after the database has changed. 308 */ 309 public void refreshList() { 310 mBookmarksAdapter.refreshList(); 311 } 312 313 /** 314 * Return a hashmap representing the currently highlighted row. 315 */ 316 public Bundle getRow(int position) { 317 return mBookmarksAdapter.getRow(position); 318 } 319 320 /** 321 * Return the url of the currently highlighted row. 322 */ 323 public String getUrl(int position) { 324 return mBookmarksAdapter.getUrl(position); 325 } 326 327 private void copy(CharSequence text) { 328 try { 329 IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard")); 330 if (clip != null) { 331 clip.setClipboardText(text); 332 } 333 } catch (android.os.RemoteException e) { 334 Log.e(LOGTAG, "Copy failed", e); 335 } 336 } 337 338 public String getBookmarkTitle(int position) { 339 return mBookmarksAdapter.getTitle(position); 340 } 341 342 /** 343 * Delete the currently highlighted row. 344 */ 345 public void deleteBookmark(int position) { 346 mBookmarksAdapter.deleteRow(position); 347 } 348 349 public boolean dispatchKeyEvent(KeyEvent event) { 350 if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.isDown()) { 351 setResult(RESULT_CANCELED); 352 mCanceled = true; 353 } 354 return super.dispatchKeyEvent(event); 355 } 356} 357