BrowserBookmarksPage.java revision c0fdde99a36be4eed618a2c71cec84c7bcb95626
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.content.SharedPreferences; 24import android.content.SharedPreferences.Editor; 25import android.graphics.Bitmap; 26import android.graphics.BitmapFactory; 27import android.graphics.Canvas; 28import android.graphics.Color; 29import android.graphics.Paint; 30import android.graphics.Path; 31import android.graphics.PorterDuff; 32import android.graphics.PorterDuffXfermode; 33import android.graphics.Rect; 34import android.graphics.RectF; 35import android.net.Uri; 36import android.os.Bundle; 37import android.os.Handler; 38import android.os.Message; 39import android.os.ServiceManager; 40import android.provider.Browser; 41import android.text.IClipboard; 42import android.util.Log; 43import android.view.ContextMenu; 44import android.view.Menu; 45import android.view.MenuInflater; 46import android.view.MenuItem; 47import android.view.View; 48import android.view.ViewGroup; 49import android.view.ContextMenu.ContextMenuInfo; 50import android.widget.AdapterView; 51import android.widget.GridView; 52import android.widget.ListView; 53import android.widget.Toast; 54 55/*package*/ enum BookmarkViewMode { NONE, GRID, LIST } 56/** 57 * View showing the user's bookmarks in the browser. 58 */ 59public class BrowserBookmarksPage extends Activity implements 60 View.OnCreateContextMenuListener { 61 62 private BookmarkViewMode mViewMode = BookmarkViewMode.NONE; 63 private GridView mGridPage; 64 private ListView mVerticalList; 65 private BrowserBookmarksAdapter mBookmarksAdapter; 66 private static final int BOOKMARKS_SAVE = 1; 67 private boolean mDisableNewWindow; 68 private BookmarkItem mContextHeader; 69 private AddNewBookmark mAddHeader; 70 private boolean mCanceled = false; 71 private boolean mCreateShortcut; 72 private boolean mMostVisited; 73 private View mEmptyView; 74 // XXX: There is no public string defining this intent so if Home changes 75 // the value, we have to update this string. 76 private static final String INSTALL_SHORTCUT = 77 "com.android.launcher.action.INSTALL_SHORTCUT"; 78 79 private final static String LOGTAG = "browser"; 80 private final static String PREF_BOOKMARK_VIEW_MODE = "pref_bookmark_view_mode"; 81 private final static String PREF_MOST_VISITED_VIEW_MODE = "pref_most_visited_view_mode"; 82 83 @Override 84 public boolean onContextItemSelected(MenuItem item) { 85 // It is possible that the view has been canceled when we get to 86 // this point as back has a higher priority 87 if (mCanceled) { 88 return true; 89 } 90 AdapterView.AdapterContextMenuInfo i = 91 (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); 92 // If we have no menu info, we can't tell which item was selected. 93 if (i == null) { 94 return true; 95 } 96 97 switch (item.getItemId()) { 98 case R.id.new_context_menu_id: 99 saveCurrentPage(); 100 break; 101 case R.id.open_context_menu_id: 102 loadUrl(i.position); 103 break; 104 case R.id.edit_context_menu_id: 105 editBookmark(i.position); 106 break; 107 case R.id.shortcut_context_menu_id: 108 final Intent send = createShortcutIntent(i.position); 109 send.setAction(INSTALL_SHORTCUT); 110 sendBroadcast(send); 111 break; 112 case R.id.delete_context_menu_id: 113 if (mMostVisited) { 114 Browser.deleteFromHistory(getContentResolver(), 115 getUrl(i.position)); 116 refreshList(); 117 } else { 118 displayRemoveBookmarkDialog(i.position); 119 } 120 break; 121 case R.id.new_window_context_menu_id: 122 openInNewWindow(i.position); 123 break; 124 case R.id.share_link_context_menu_id: 125 BrowserActivity.sharePage(BrowserBookmarksPage.this, 126 mBookmarksAdapter.getTitle(i.position), getUrl(i.position), 127 getFavicon(i.position), 128 mBookmarksAdapter.getScreenshot(i.position)); 129 break; 130 case R.id.copy_url_context_menu_id: 131 copy(getUrl(i.position)); 132 break; 133 case R.id.homepage_context_menu_id: 134 BrowserSettings.getInstance().setHomePage(this, 135 getUrl(i.position)); 136 Toast.makeText(this, R.string.homepage_set, 137 Toast.LENGTH_LONG).show(); 138 break; 139 // Only for the Most visited page 140 case R.id.save_to_bookmarks_menu_id: 141 boolean isBookmark; 142 String name; 143 String url; 144 if (mViewMode == BookmarkViewMode.GRID) { 145 isBookmark = mBookmarksAdapter.getIsBookmark(i.position); 146 name = mBookmarksAdapter.getTitle(i.position); 147 url = mBookmarksAdapter.getUrl(i.position); 148 } else { 149 HistoryItem historyItem = ((HistoryItem) i.targetView); 150 isBookmark = historyItem.isBookmark(); 151 name = historyItem.getName(); 152 url = historyItem.getUrl(); 153 } 154 // If the site is bookmarked, the item becomes remove from 155 // bookmarks. 156 if (isBookmark) { 157 Bookmarks.removeFromBookmarks(this, getContentResolver(), url, name); 158 } else { 159 Browser.saveBookmark(this, name, url); 160 } 161 break; 162 default: 163 return super.onContextItemSelected(item); 164 } 165 return true; 166 } 167 168 @Override 169 public void onCreateContextMenu(ContextMenu menu, View v, 170 ContextMenuInfo menuInfo) { 171 AdapterView.AdapterContextMenuInfo i = 172 (AdapterView.AdapterContextMenuInfo) menuInfo; 173 174 MenuInflater inflater = getMenuInflater(); 175 if (mMostVisited) { 176 inflater.inflate(R.menu.historycontext, menu); 177 } else { 178 inflater.inflate(R.menu.bookmarkscontext, menu); 179 } 180 181 if (0 == i.position && !mMostVisited) { 182 menu.setGroupVisible(R.id.CONTEXT_MENU, false); 183 if (mAddHeader == null) { 184 mAddHeader = new AddNewBookmark(BrowserBookmarksPage.this); 185 } else if (mAddHeader.getParent() != null) { 186 ((ViewGroup) mAddHeader.getParent()). 187 removeView(mAddHeader); 188 } 189 mAddHeader.setUrl(getIntent().getStringExtra("url")); 190 menu.setHeaderView(mAddHeader); 191 return; 192 } 193 if (mMostVisited) { 194 if ((mViewMode == BookmarkViewMode.LIST 195 && ((HistoryItem) i.targetView).isBookmark()) 196 || mBookmarksAdapter.getIsBookmark(i.position)) { 197 MenuItem item = menu.findItem( 198 R.id.save_to_bookmarks_menu_id); 199 item.setTitle(R.string.remove_from_bookmarks); 200 } 201 } else { 202 // The historycontext menu has no ADD_MENU group. 203 menu.setGroupVisible(R.id.ADD_MENU, false); 204 } 205 if (mDisableNewWindow) { 206 menu.findItem(R.id.new_window_context_menu_id).setVisible( 207 false); 208 } 209 if (mContextHeader == null) { 210 mContextHeader = new BookmarkItem(BrowserBookmarksPage.this); 211 } else if (mContextHeader.getParent() != null) { 212 ((ViewGroup) mContextHeader.getParent()). 213 removeView(mContextHeader); 214 } 215 if (mViewMode == BookmarkViewMode.GRID) { 216 mBookmarksAdapter.populateBookmarkItem(mContextHeader, 217 i.position); 218 } else { 219 BookmarkItem b = (BookmarkItem) i.targetView; 220 b.copyTo(mContextHeader); 221 } 222 menu.setHeaderView(mContextHeader); 223 } 224 225 /** 226 * Create a new BrowserBookmarksPage. 227 */ 228 @Override 229 protected void onCreate(Bundle icicle) { 230 super.onCreate(icicle); 231 232 if (Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction())) { 233 mCreateShortcut = true; 234 } 235 mDisableNewWindow = getIntent().getBooleanExtra("disable_new_window", 236 false); 237 mMostVisited = getIntent().getBooleanExtra("mostVisited", false); 238 239 if (mCreateShortcut) { 240 setTitle(R.string.browser_bookmarks_page_bookmarks_text); 241 } 242 mHandler.obtainMessage(CREATE_ADAPTER).sendToTarget(); 243 244 setContentView(R.layout.empty_history); 245 mEmptyView = findViewById(R.id.empty_view); 246 mEmptyView.setVisibility(View.GONE); 247 248 SharedPreferences p = getPreferences(MODE_PRIVATE); 249 250 // See if the user has set a preference for the view mode of their 251 // bookmarks. Otherwise default to grid mode. 252 BookmarkViewMode preference = BookmarkViewMode.NONE; 253 if (mMostVisited) { 254 // For the most visited page, only use list mode. 255 preference = BookmarkViewMode.LIST; 256 } else { 257 preference = BookmarkViewMode.values()[p.getInt( 258 PREF_BOOKMARK_VIEW_MODE, BookmarkViewMode.GRID.ordinal())]; 259 } 260 switchViewMode(preference); 261 } 262 263 /** 264 * Set the ContentView to be either the grid of thumbnails or the vertical 265 * list. 266 */ 267 private void switchViewMode(BookmarkViewMode viewMode) { 268 if (mViewMode == viewMode) { 269 return; 270 } 271 272 mViewMode = viewMode; 273 274 // Update the preferences to make the new view mode sticky. 275 Editor ed = getPreferences(MODE_PRIVATE).edit(); 276 if (mMostVisited) { 277 ed.putInt(PREF_MOST_VISITED_VIEW_MODE, mViewMode.ordinal()); 278 } else { 279 ed.putInt(PREF_BOOKMARK_VIEW_MODE, mViewMode.ordinal()); 280 } 281 ed.commit(); 282 283 if (mBookmarksAdapter != null) { 284 mBookmarksAdapter.switchViewMode(viewMode); 285 } 286 if (mViewMode == BookmarkViewMode.GRID) { 287 if (mGridPage == null) { 288 mGridPage = new GridView(this); 289 if (mBookmarksAdapter != null) { 290 mGridPage.setAdapter(mBookmarksAdapter); 291 } 292 mGridPage.setOnItemClickListener(mListener); 293 mGridPage.setNumColumns(GridView.AUTO_FIT); 294 mGridPage.setColumnWidth( 295 BrowserActivity.getDesiredThumbnailWidth(this)); 296 mGridPage.setFocusable(true); 297 mGridPage.setFocusableInTouchMode(true); 298 mGridPage.setSelector(android.R.drawable.gallery_thumb); 299 float density = getResources().getDisplayMetrics().density; 300 mGridPage.setVerticalSpacing((int) (14 * density)); 301 mGridPage.setHorizontalSpacing((int) (8 * density)); 302 mGridPage.setStretchMode(GridView.STRETCH_SPACING); 303 mGridPage.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET); 304 mGridPage.setDrawSelectorOnTop(true); 305 if (mMostVisited) { 306 mGridPage.setEmptyView(mEmptyView); 307 } 308 if (!mCreateShortcut) { 309 mGridPage.setOnCreateContextMenuListener(this); 310 } 311 } 312 addContentView(mGridPage, FULL_SCREEN_PARAMS); 313 if (mVerticalList != null) { 314 ViewGroup parent = (ViewGroup) mVerticalList.getParent(); 315 if (parent != null) { 316 parent.removeView(mVerticalList); 317 } 318 } 319 } else { 320 if (null == mVerticalList) { 321 ListView listView = new ListView(this); 322 if (mBookmarksAdapter != null) { 323 listView.setAdapter(mBookmarksAdapter); 324 } 325 listView.setDrawSelectorOnTop(false); 326 listView.setVerticalScrollBarEnabled(true); 327 listView.setOnItemClickListener(mListener); 328 if (mMostVisited) { 329 listView.setEmptyView(mEmptyView); 330 } 331 if (!mCreateShortcut) { 332 listView.setOnCreateContextMenuListener(this); 333 } 334 mVerticalList = listView; 335 } 336 addContentView(mVerticalList, FULL_SCREEN_PARAMS); 337 if (mGridPage != null) { 338 ViewGroup parent = (ViewGroup) mGridPage.getParent(); 339 if (parent != null) { 340 parent.removeView(mGridPage); 341 } 342 } 343 } 344 } 345 346 private static final ViewGroup.LayoutParams FULL_SCREEN_PARAMS 347 = new ViewGroup.LayoutParams( 348 ViewGroup.LayoutParams.MATCH_PARENT, 349 ViewGroup.LayoutParams.MATCH_PARENT); 350 351 private static final int SAVE_CURRENT_PAGE = 1000; 352 private static final int CREATE_ADAPTER = 1001; 353 private final Handler mHandler = new Handler() { 354 @Override 355 public void handleMessage(Message msg) { 356 switch (msg.what) { 357 case SAVE_CURRENT_PAGE: 358 saveCurrentPage(); 359 break; 360 case CREATE_ADAPTER: 361 Intent intent = getIntent(); 362 mBookmarksAdapter = new BrowserBookmarksAdapter( 363 BrowserBookmarksPage.this, 364 intent.getStringExtra("url"), 365 intent.getStringExtra("title"), 366 (Bitmap) intent.getParcelableExtra("thumbnail"), 367 mCreateShortcut, 368 mMostVisited); 369 mBookmarksAdapter.switchViewMode(mViewMode); 370 if (mGridPage != null) { 371 mGridPage.setAdapter(mBookmarksAdapter); 372 } 373 if (mVerticalList != null) { 374 mVerticalList.setAdapter(mBookmarksAdapter); 375 } 376 break; 377 } 378 } 379 }; 380 381 private AdapterView.OnItemClickListener mListener = new AdapterView.OnItemClickListener() { 382 public void onItemClick(AdapterView parent, View v, int position, long id) { 383 // It is possible that the view has been canceled when we get to 384 // this point as back has a higher priority 385 if (mCanceled) { 386 android.util.Log.e(LOGTAG, "item clicked when dismissing"); 387 return; 388 } 389 if (!mCreateShortcut) { 390 if (0 == position && !mMostVisited) { 391 // XXX: Work-around for a framework issue. 392 mHandler.sendEmptyMessage(SAVE_CURRENT_PAGE); 393 } else { 394 loadUrl(position); 395 } 396 } else { 397 final Intent intent = createShortcutIntent(position); 398 setResultToParent(RESULT_OK, intent); 399 finish(); 400 } 401 } 402 }; 403 404 private Intent createShortcutIntent(int position) { 405 String url = getUrl(position); 406 String title = getBookmarkTitle(position); 407 Bitmap touchIcon = getTouchIcon(position); 408 409 final Intent i = new Intent(); 410 final Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, 411 Uri.parse(url)); 412 long urlHash = url.hashCode(); 413 long uniqueId = (urlHash << 32) | shortcutIntent.hashCode(); 414 shortcutIntent.putExtra(Browser.EXTRA_APPLICATION_ID, 415 Long.toString(uniqueId)); 416 i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); 417 i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title); 418 // Use the apple-touch-icon if available 419 if (touchIcon != null) { 420 // Make a copy so we can modify the pixels. 421 Bitmap copy = touchIcon.copy(Bitmap.Config.ARGB_8888, true); 422 Canvas canvas = new Canvas(copy); 423 424 // Construct a path from a round rect. This will allow drawing with 425 // an inverse fill so we can punch a hole using the round rect. 426 Path path = new Path(); 427 path.setFillType(Path.FillType.INVERSE_WINDING); 428 RectF rect = new RectF(0, 0, touchIcon.getWidth(), 429 touchIcon.getHeight()); 430 rect.inset(1, 1); 431 path.addRoundRect(rect, 8f, 8f, Path.Direction.CW); 432 433 // Construct a paint that clears the outside of the rectangle and 434 // draw. 435 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 436 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 437 canvas.drawPath(path, paint); 438 439 i.putExtra(Intent.EXTRA_SHORTCUT_ICON, copy); 440 } else { 441 Bitmap favicon = getFavicon(position); 442 if (favicon == null) { 443 i.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, 444 Intent.ShortcutIconResource.fromContext( 445 BrowserBookmarksPage.this, 446 R.drawable.ic_launcher_shortcut_browser_bookmark)); 447 } else { 448 Bitmap icon = BitmapFactory.decodeResource(getResources(), 449 R.drawable.ic_launcher_shortcut_browser_bookmark_icon); 450 451 // Make a copy of the regular icon so we can modify the pixels. 452 Bitmap copy = icon.copy(Bitmap.Config.ARGB_8888, true); 453 Canvas canvas = new Canvas(copy); 454 455 // Make a Paint for the white background rectangle and for 456 // filtering the favicon. 457 Paint p = new Paint(Paint.ANTI_ALIAS_FLAG 458 | Paint.FILTER_BITMAP_FLAG); 459 p.setStyle(Paint.Style.FILL_AND_STROKE); 460 p.setColor(Color.WHITE); 461 462 final float density = 463 getResources().getDisplayMetrics().density; 464 // Create a rectangle that is slightly wider than the favicon 465 final float iconSize = 16 * density; // 16x16 favicon 466 final float padding = 2 * density; // white padding around icon 467 final float rectSize = iconSize + 2 * padding; 468 469 final Rect iconBounds = 470 new Rect(0, 0, icon.getWidth(), icon.getHeight()); 471 final float x = iconBounds.exactCenterX() - (rectSize / 2); 472 // Note: Subtract 2 dip from the y position since the box is 473 // slightly higher than center. Use padding since it is already 474 // 2 * density. 475 final float y = iconBounds.exactCenterY() - (rectSize / 2) 476 - padding; 477 RectF r = new RectF(x, y, x + rectSize, y + rectSize); 478 479 // Draw a white rounded rectangle behind the favicon 480 canvas.drawRoundRect(r, 2, 2, p); 481 482 // Draw the favicon in the same rectangle as the rounded 483 // rectangle but inset by the padding 484 // (results in a 16x16 favicon). 485 r.inset(padding, padding); 486 canvas.drawBitmap(favicon, null, r, p); 487 i.putExtra(Intent.EXTRA_SHORTCUT_ICON, copy); 488 } 489 } 490 // Do not allow duplicate items 491 i.putExtra("duplicate", false); 492 return i; 493 } 494 495 private void saveCurrentPage() { 496 Intent i = new Intent(BrowserBookmarksPage.this, 497 AddBookmarkPage.class); 498 i.putExtras(getIntent()); 499 startActivityForResult(i, BOOKMARKS_SAVE); 500 } 501 502 private void loadUrl(int position) { 503 Intent intent = (new Intent()).setAction(getUrl(position)); 504 setResultToParent(RESULT_OK, intent); 505 finish(); 506 } 507 508 @Override 509 public boolean onCreateOptionsMenu(Menu menu) { 510 boolean result = super.onCreateOptionsMenu(menu); 511 if (!mCreateShortcut && !mMostVisited) { 512 MenuInflater inflater = getMenuInflater(); 513 inflater.inflate(R.menu.bookmarks, menu); 514 return true; 515 } 516 return result; 517 } 518 519 @Override 520 public boolean onPrepareOptionsMenu(Menu menu) { 521 boolean result = super.onPrepareOptionsMenu(menu); 522 if (mCreateShortcut || mMostVisited || mBookmarksAdapter == null 523 || mBookmarksAdapter.getCount() == 0) { 524 // No need to show the menu if there are no items. 525 return result; 526 } 527 MenuItem switchItem = menu.findItem(R.id.switch_mode_menu_id); 528 int titleResId; 529 int iconResId; 530 if (mViewMode == BookmarkViewMode.GRID) { 531 titleResId = R.string.switch_to_list; 532 iconResId = R.drawable.ic_menu_list; 533 } else { 534 titleResId = R.string.switch_to_thumbnails; 535 iconResId = R.drawable.ic_menu_thumbnail; 536 } 537 switchItem.setTitle(titleResId); 538 switchItem.setIcon(iconResId); 539 return true; 540 } 541 542 @Override 543 public boolean onOptionsItemSelected(MenuItem item) { 544 switch (item.getItemId()) { 545 case R.id.new_context_menu_id: 546 saveCurrentPage(); 547 break; 548 549 case R.id.switch_mode_menu_id: 550 if (mViewMode == BookmarkViewMode.GRID) { 551 switchViewMode(BookmarkViewMode.LIST); 552 } else { 553 switchViewMode(BookmarkViewMode.GRID); 554 } 555 break; 556 557 default: 558 return super.onOptionsItemSelected(item); 559 } 560 return true; 561 } 562 563 private void openInNewWindow(int position) { 564 Bundle b = new Bundle(); 565 b.putBoolean("new_window", true); 566 setResultToParent(RESULT_OK, 567 (new Intent()).setAction(getUrl(position)).putExtras(b)); 568 569 finish(); 570 } 571 572 573 private void editBookmark(int position) { 574 Intent intent = new Intent(BrowserBookmarksPage.this, 575 AddBookmarkPage.class); 576 intent.putExtra("bookmark", getRow(position)); 577 startActivityForResult(intent, BOOKMARKS_SAVE); 578 } 579 580 @Override 581 protected void onActivityResult(int requestCode, int resultCode, 582 Intent data) { 583 switch(requestCode) { 584 case BOOKMARKS_SAVE: 585 if (resultCode == RESULT_OK) { 586 Bundle extras; 587 if (data != null && (extras = data.getExtras()) != null) { 588 // If there are extras, then we need to save 589 // the edited bookmark. This is done in updateRow() 590 String title = extras.getString("title"); 591 String url = extras.getString("url"); 592 if (title != null && url != null) { 593 mBookmarksAdapter.updateRow(extras); 594 } 595 } else { 596 // extras == null then a new bookmark was added to 597 // the database. 598 refreshList(); 599 } 600 } 601 break; 602 default: 603 break; 604 } 605 } 606 607 private void displayRemoveBookmarkDialog(int position) { 608 // Put up a dialog asking if the user really wants to 609 // delete the bookmark 610 final int deletePos = position; 611 new AlertDialog.Builder(this) 612 .setTitle(R.string.delete_bookmark) 613 .setIcon(android.R.drawable.ic_dialog_alert) 614 .setMessage(getText(R.string.delete_bookmark_warning).toString().replace( 615 "%s", getBookmarkTitle(deletePos))) 616 .setPositiveButton(R.string.ok, 617 new DialogInterface.OnClickListener() { 618 public void onClick(DialogInterface dialog, int whichButton) { 619 deleteBookmark(deletePos); 620 } 621 }) 622 .setNegativeButton(R.string.cancel, null) 623 .show(); 624 } 625 626 /** 627 * Refresh the shown list after the database has changed. 628 */ 629 private void refreshList() { 630 mBookmarksAdapter.refreshList(); 631 } 632 633 /** 634 * Return a hashmap representing the currently highlighted row. 635 */ 636 public Bundle getRow(int position) { 637 return mBookmarksAdapter == null ? null 638 : mBookmarksAdapter.getRow(position); 639 } 640 641 /** 642 * Return the url of the currently highlighted row. 643 */ 644 public String getUrl(int position) { 645 return mBookmarksAdapter == null ? null 646 : mBookmarksAdapter.getUrl(position); 647 } 648 649 /** 650 * Return the favicon of the currently highlighted row. 651 */ 652 public Bitmap getFavicon(int position) { 653 return mBookmarksAdapter == null ? null 654 : mBookmarksAdapter.getFavicon(position); 655 } 656 657 private Bitmap getTouchIcon(int position) { 658 return mBookmarksAdapter == null ? null 659 : mBookmarksAdapter.getTouchIcon(position); 660 } 661 662 private void copy(CharSequence text) { 663 try { 664 IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard")); 665 if (clip != null) { 666 clip.setClipboardText(text); 667 } 668 } catch (android.os.RemoteException e) { 669 Log.e(LOGTAG, "Copy failed", e); 670 } 671 } 672 673 public String getBookmarkTitle(int position) { 674 return mBookmarksAdapter == null ? null 675 : mBookmarksAdapter.getTitle(position); 676 } 677 678 /** 679 * Delete the currently highlighted row. 680 */ 681 public void deleteBookmark(int position) { 682 if (mBookmarksAdapter == null) return; 683 mBookmarksAdapter.deleteRow(position); 684 } 685 686 @Override 687 public void onBackPressed() { 688 setResultToParent(RESULT_CANCELED, null); 689 mCanceled = true; 690 super.onBackPressed(); 691 } 692 693 // This Activity is generally a sub-Activity of 694 // CombinedBookmarkHistoryActivity. In that situation, we need to pass our 695 // result code up to our parent. However, if someone calls this Activity 696 // directly, then this has no parent, and it needs to set it on itself. 697 private void setResultToParent(int resultCode, Intent data) { 698 Activity parent = getParent(); 699 if (parent == null) { 700 setResult(resultCode, data); 701 } else { 702 ((CombinedBookmarkHistoryActivity) parent).setResultFromChild( 703 resultCode, data); 704 } 705 } 706} 707