BrowserBookmarksPage.java revision 8af906474c84854598da1886edacfd5f10cae70f
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.app.Fragment; 22import android.app.LoaderManager; 23import android.content.ClipData; 24import android.content.ClipboardManager; 25import android.content.ContentResolver; 26import android.content.ContentUris; 27import android.content.ContentValues; 28import android.content.Context; 29import android.content.CursorLoader; 30import android.content.DialogInterface; 31import android.content.Intent; 32import android.content.Loader; 33import android.content.SharedPreferences; 34import android.content.SharedPreferences.Editor; 35import android.database.Cursor; 36import android.graphics.Bitmap; 37import android.graphics.BitmapFactory; 38import android.net.Uri; 39import android.os.Bundle; 40import android.preference.PreferenceManager; 41import android.provider.BrowserContract; 42import android.provider.BrowserContract.Accounts; 43import android.text.TextUtils; 44import android.view.ContextMenu; 45import android.view.ContextMenu.ContextMenuInfo; 46import android.view.LayoutInflater; 47import android.view.MenuInflater; 48import android.view.MenuItem; 49import android.view.View; 50import android.view.ViewGroup; 51import android.webkit.WebIconDatabase.IconListener; 52import android.widget.Adapter; 53import android.widget.AdapterView; 54import android.widget.AdapterView.OnItemClickListener; 55import android.widget.AdapterView.OnItemSelectedListener; 56import android.widget.GridView; 57import android.widget.ListView; 58import android.widget.Toast; 59 60/** 61 * View showing the user's bookmarks in the browser. 62 */ 63public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener, 64 LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener, 65 OnItemSelectedListener { 66 67 static final int BOOKMARKS_SAVE = 1; 68 static final String LOGTAG = "browser"; 69 70 static final int LOADER_BOOKMARKS = 1; 71 static final int LOADER_ACCOUNTS_THEN_BOOKMARKS = 2; 72 73 static final String EXTRA_SHORTCUT = "create_shortcut"; 74 static final String EXTRA_DISABLE_WINDOW = "disable_new_window"; 75 76 static final String ACCOUNT_NAME_UNSYNCED = "Unsynced"; 77 78 public static final String PREF_ACCOUNT_TYPE = "acct_type"; 79 public static final String PREF_ACCOUNT_NAME = "acct_name"; 80 81 static final String DEFAULT_ACCOUNT = "local"; 82 static final int VIEW_THUMBNAILS = 1; 83 static final int VIEW_LIST = 2; 84 static final String PREF_SELECTED_VIEW = "bookmarks_view"; 85 86 BookmarksHistoryCallbacks mCallbacks; 87 GridView mGrid; 88 ListView mList; 89 BrowserBookmarksAdapter mAdapter; 90 boolean mDisableNewWindow; 91 BookmarkItem mContextHeader; 92 boolean mCanceled = false; 93 boolean mCreateShortcut; 94 View mEmptyView; 95 int mCurrentView; 96 97 BreadCrumbView mCrumbs; 98 99 static BrowserBookmarksPage newInstance(BookmarksHistoryCallbacks cb, 100 BreadCrumbView crumbs, Bundle args) { 101 BrowserBookmarksPage bbp = new BrowserBookmarksPage(); 102 bbp.mCallbacks = cb; 103 bbp.setArguments(args); 104 bbp.mCrumbs = crumbs; 105 return bbp; 106 } 107 108 @Override 109 public Loader<Cursor> onCreateLoader(int id, Bundle args) { 110 switch (id) { 111 case LOADER_BOOKMARKS: { 112 String accountType = null; 113 String accountName = null; 114 if (args != null) { 115 accountType = args.getString(BookmarksLoader.ARG_ACCOUNT_TYPE); 116 accountName = args.getString(BookmarksLoader.ARG_ACCOUNT_NAME); 117 } 118 BookmarksLoader bl = new BookmarksLoader(getActivity(), accountType, accountName); 119 if (mCrumbs != null) { 120 Uri uri = (Uri) mCrumbs.getTopData(); 121 if (uri != null) { 122 bl.setUri(uri); 123 } 124 } 125 return bl; 126 } 127 case LOADER_ACCOUNTS_THEN_BOOKMARKS: { 128 return new CursorLoader(getActivity(), Accounts.CONTENT_URI, 129 new String[] { Accounts.ACCOUNT_TYPE, Accounts.ACCOUNT_NAME }, null, null, 130 null); 131 } 132 } 133 throw new UnsupportedOperationException("Unknown loader id " + id); 134 } 135 136 @Override 137 public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 138 switch (loader.getId()) { 139 case LOADER_BOOKMARKS: { 140 // Set the visibility of the empty vs. content views 141 if (cursor == null || cursor.getCount() == 0) { 142 mEmptyView.setVisibility(View.VISIBLE); 143 mGrid.setVisibility(View.GONE); 144 mList.setVisibility(View.GONE); 145 } else { 146 mEmptyView.setVisibility(View.GONE); 147 setupBookmarkView(); 148 } 149 150 // Give the new data to the adapter 151 mAdapter.changeCursor(cursor); 152 break; 153 } 154 155 case LOADER_ACCOUNTS_THEN_BOOKMARKS: { 156 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( 157 getActivity()); 158 String storedAccountType = prefs.getString(PREF_ACCOUNT_TYPE, null); 159 String storedAccountName = prefs.getString(PREF_ACCOUNT_NAME, null); 160 String accountType = 161 TextUtils.isEmpty(storedAccountType) ? DEFAULT_ACCOUNT : storedAccountType; 162 String accountName = 163 TextUtils.isEmpty(storedAccountName) ? DEFAULT_ACCOUNT : storedAccountName; 164 165 Bundle args = null; 166 if (cursor == null || !cursor.moveToFirst()) { 167 // No accounts, set the prefs to the default 168 accountType = DEFAULT_ACCOUNT; 169 accountName = DEFAULT_ACCOUNT; 170 } else { 171 int accountPosition = -1; 172 173 if (!DEFAULT_ACCOUNT.equals(accountType) && 174 !DEFAULT_ACCOUNT.equals(accountName)) { 175 // Check to see if the account in prefs still exists 176 cursor.moveToFirst(); 177 do { 178 if (accountType.equals(cursor.getString(0)) 179 && accountName.equals(cursor.getString(1))) { 180 accountPosition = cursor.getPosition(); 181 break; 182 } 183 } while (cursor.moveToNext()); 184 } 185 186 if (accountPosition == -1) { 187 if (!(DEFAULT_ACCOUNT.equals(accountType) 188 && DEFAULT_ACCOUNT.equals(accountName))) { 189 // No account is set in prefs and there is at least one, 190 // so pick the first one as the default 191 cursor.moveToFirst(); 192 accountType = cursor.getString(0); 193 accountName = cursor.getString(1); 194 } 195 } 196 197 args = new Bundle(); 198 args.putString(BookmarksLoader.ARG_ACCOUNT_TYPE, accountType); 199 args.putString(BookmarksLoader.ARG_ACCOUNT_NAME, accountName); 200 } 201 202 // The stored account name wasn't found, update the stored account with a valid one 203 if (!accountType.equals(storedAccountType) 204 || !accountName.equals(storedAccountName)) { 205 prefs.edit() 206 .putString(PREF_ACCOUNT_TYPE, accountType) 207 .putString(PREF_ACCOUNT_NAME, accountName) 208 .apply(); 209 } 210 getLoaderManager().initLoader(LOADER_BOOKMARKS, args, this); 211 212 break; 213 } 214 } 215 } 216 217 long getFolderId() { 218 LoaderManager manager = getLoaderManager(); 219 BookmarksLoader loader = 220 (BookmarksLoader) ((Loader)(manager.getLoader(LOADER_BOOKMARKS))); 221 222 Uri uri = loader.getUri(); 223 if (uri != null) { 224 try { 225 return ContentUris.parseId(uri); 226 } catch (NumberFormatException nfx) { 227 return -1; 228 } 229 } 230 return -1; 231 } 232 233 public void onFolderChange(int level, Object data) { 234 Uri uri = (Uri) data; 235 if (uri == null) { 236 // top level 237 uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER; 238 } 239 LoaderManager manager = getLoaderManager(); 240 BookmarksLoader loader = 241 (BookmarksLoader) ((Loader) manager.getLoader(LOADER_BOOKMARKS)); 242 loader.setUri(uri); 243 loader.forceLoad(); 244 245 } 246 247 @Override 248 public boolean onContextItemSelected(MenuItem item) { 249 final Activity activity = getActivity(); 250 // It is possible that the view has been canceled when we get to 251 // this point as back has a higher priority 252 if (mCanceled) { 253 return false; 254 } 255 AdapterView.AdapterContextMenuInfo i = 256 (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); 257 // If we have no menu info, we can't tell which item was selected. 258 if (i == null) { 259 return false; 260 } 261 262 switch (item.getItemId()) { 263 case R.id.open_context_menu_id: 264 loadUrl(i.position); 265 break; 266 case R.id.edit_context_menu_id: 267 editBookmark(i.position); 268 break; 269 case R.id.shortcut_context_menu_id: 270 activity.sendBroadcast(createShortcutIntent(i.position)); 271 break; 272 case R.id.delete_context_menu_id: 273 displayRemoveBookmarkDialog(i.position); 274 break; 275 case R.id.new_window_context_menu_id: 276 openInNewWindow(i.position); 277 break; 278 case R.id.share_link_context_menu_id: { 279 Cursor cursor = (Cursor) mAdapter.getItem(i.position); 280 Controller.sharePage(activity, 281 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE), 282 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL), 283 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON), 284 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_THUMBNAIL)); 285 break; 286 } 287 case R.id.copy_url_context_menu_id: 288 copy(getUrl(i.position)); 289 break; 290 case R.id.homepage_context_menu_id: { 291 BrowserSettings.getInstance().setHomePage(activity, getUrl(i.position)); 292 Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show(); 293 break; 294 } 295 // Only for the Most visited page 296 case R.id.save_to_bookmarks_menu_id: { 297 Cursor cursor = (Cursor) mAdapter.getItem(i.position); 298 String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 299 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 300 // If the site is bookmarked, the item becomes remove from 301 // bookmarks. 302 Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name); 303 break; 304 } 305 default: 306 return super.onContextItemSelected(item); 307 } 308 return true; 309 } 310 311 Bitmap getBitmap(Cursor cursor, int columnIndex) { 312 byte[] data = cursor.getBlob(columnIndex); 313 if (data == null) { 314 return null; 315 } 316 return BitmapFactory.decodeByteArray(data, 0, data.length); 317 } 318 319 @Override 320 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 321 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; 322 Cursor cursor = (Cursor) mAdapter.getItem(info.position); 323 boolean isFolder 324 = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 325 if (isFolder) return; 326 327 final Activity activity = getActivity(); 328 MenuInflater inflater = activity.getMenuInflater(); 329 inflater.inflate(R.menu.bookmarkscontext, menu); 330 331 if (mDisableNewWindow) { 332 menu.findItem(R.id.new_window_context_menu_id).setVisible(false); 333 } 334 335 if (mContextHeader == null) { 336 mContextHeader = new BookmarkItem(activity); 337 } else if (mContextHeader.getParent() != null) { 338 ((ViewGroup) mContextHeader.getParent()).removeView(mContextHeader); 339 } 340 341 populateBookmarkItem(cursor, mContextHeader); 342 343 menu.setHeaderView(mContextHeader); 344 } 345 346 private void populateBookmarkItem(Cursor cursor, BookmarkItem item) { 347 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 348 item.setUrl(url); 349 item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 350 Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 351 if (bitmap == null) { 352 bitmap = CombinedBookmarkHistoryView.getIconListenerSet().getFavicon(url); 353 } 354 item.setFavicon(bitmap); 355 } 356 357 /** 358 * Create a new BrowserBookmarksPage. 359 */ 360 @Override 361 public void onCreate(Bundle icicle) { 362 super.onCreate(icicle); 363 364 Bundle args = getArguments(); 365 mCreateShortcut = args == null ? false : args.getBoolean(EXTRA_SHORTCUT, false); 366 mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false); 367 } 368 369 @Override 370 public View onCreateView(LayoutInflater inflater, ViewGroup container, 371 Bundle savedInstanceState) { 372 Context context = getActivity(); 373 374 View root = inflater.inflate(R.layout.bookmarks, container, false); 375 mEmptyView = root.findViewById(android.R.id.empty); 376 377 mGrid = (GridView) root.findViewById(R.id.grid); 378 mGrid.setOnItemClickListener(this); 379 mGrid.setColumnWidth(Controller.getDesiredThumbnailWidth(getActivity())); 380 if (!mCreateShortcut) { 381 mGrid.setOnCreateContextMenuListener(this); 382 } 383 mList = (ListView) root.findViewById(R.id.list); 384 mList.setOnItemClickListener(this); 385 if (!mCreateShortcut) { 386 mList.setOnCreateContextMenuListener(this); 387 registerForContextMenu(mList); 388 } 389 390 // Start the loaders 391 LoaderManager lm = getLoaderManager(); 392 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 393 mCurrentView = 394 prefs.getInt(PREF_SELECTED_VIEW, BrowserBookmarksPage.VIEW_THUMBNAILS); 395 mAdapter = new BrowserBookmarksAdapter(getActivity(), mCurrentView); 396 String accountType = prefs.getString(PREF_ACCOUNT_TYPE, DEFAULT_ACCOUNT); 397 String accountName = prefs.getString(PREF_ACCOUNT_NAME, DEFAULT_ACCOUNT); 398 if (!TextUtils.isEmpty(accountType) && !TextUtils.isEmpty(accountName)) { 399 // There is an account set, load up that one 400 Bundle args = null; 401 if (!DEFAULT_ACCOUNT.equals(accountType) && !DEFAULT_ACCOUNT.equals(accountName)) { 402 args = new Bundle(); 403 args.putString(BookmarksLoader.ARG_ACCOUNT_TYPE, accountType); 404 args.putString(BookmarksLoader.ARG_ACCOUNT_NAME, accountName); 405 } 406 lm.restartLoader(LOADER_BOOKMARKS, args, this); 407 } else { 408 // No account set, load the account list first 409 lm.restartLoader(LOADER_ACCOUNTS_THEN_BOOKMARKS, null, this); 410 } 411 412 // Add our own listener in case there are favicons that have yet to be loaded. 413 CombinedBookmarkHistoryView.getIconListenerSet().addListener(this); 414 415 return root; 416 } 417 418 @Override 419 public void onReceivedIcon(String url, Bitmap icon) { 420 // A new favicon has been loaded, so let anything attached to the adapter know about it 421 // so new icons will be loaded. 422 mAdapter.notifyDataSetChanged(); 423 } 424 425 @Override 426 public void onItemClick(AdapterView parent, View v, int position, long id) { 427 // It is possible that the view has been canceled when we get to 428 // this point as back has a higher priority 429 if (mCanceled) { 430 android.util.Log.e(LOGTAG, "item clicked when dismissing"); 431 return; 432 } 433 434 if (mCreateShortcut) { 435 Intent intent = createShortcutIntent(position); 436 // the activity handles the intent in startActivityFromFragment 437 startActivity(intent); 438 return; 439 } 440 441 Cursor cursor = (Cursor) mAdapter.getItem(position); 442 boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 443 if (!isFolder) { 444 mCallbacks.onUrlSelected(getUrl(position), false); 445 } else { 446 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 447 LoaderManager manager = getLoaderManager(); 448 BookmarksLoader loader = 449 (BookmarksLoader) ((Loader) manager.getLoader(LOADER_BOOKMARKS)); 450 Uri uri = ContentUris.withAppendedId( 451 BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id); 452 if (mCrumbs != null) { 453 // update crumbs 454 mCrumbs.pushView(title, uri); 455 } 456 loader.setUri(uri); 457 loader.forceLoad(); 458 } 459 } 460 461 @Override 462 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 463 Adapter adapter = parent.getAdapter(); 464 String accountType = "com.google"; 465 String accountName = adapter.getItem(position).toString(); 466 467 Bundle args = null; 468 if (ACCOUNT_NAME_UNSYNCED.equals(accountName)) { 469 accountType = DEFAULT_ACCOUNT; 470 accountName = DEFAULT_ACCOUNT; 471 } else { 472 args = new Bundle(); 473 args.putString(BookmarksLoader.ARG_ACCOUNT_TYPE, accountType); 474 args.putString(BookmarksLoader.ARG_ACCOUNT_NAME, accountName); 475 } 476 477 // Remember the selection for later 478 PreferenceManager.getDefaultSharedPreferences(getActivity()).edit() 479 .putString(PREF_ACCOUNT_TYPE, accountType) 480 .putString(PREF_ACCOUNT_NAME, accountName) 481 .apply(); 482 483 getLoaderManager().restartLoader(LOADER_BOOKMARKS, args, this); 484 } 485 486 @Override 487 public void onNothingSelected(AdapterView<?> parent) { 488 // Do nothing 489 } 490 491 private Intent createShortcutIntent(int position) { 492 Cursor cursor = (Cursor) mAdapter.getItem(position); 493 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 494 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 495 Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON); 496 Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 497 return BookmarkUtils.createAddToHomeIntent(getActivity(), url, title, touchIcon, favicon); 498 } 499 500 private void loadUrl(int position) { 501 mCallbacks.onUrlSelected(getUrl(position), false); 502 } 503 504 private void openInNewWindow(int position) { 505 mCallbacks.onUrlSelected(getUrl(position), true); 506 } 507 508 private void editBookmark(int position) { 509 Intent intent = new Intent(getActivity(), AddBookmarkPage.class); 510 Cursor cursor = (Cursor) mAdapter.getItem(position); 511 Bundle item = new Bundle(); 512 item.putString(BrowserContract.Bookmarks.TITLE, 513 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 514 item.putString(BrowserContract.Bookmarks.URL, 515 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL)); 516 byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON); 517 if (data != null) { 518 item.putParcelable(BrowserContract.Bookmarks.FAVICON, 519 BitmapFactory.decodeByteArray(data, 0, data.length)); 520 } 521 item.putInt("id", cursor.getInt(BookmarksLoader.COLUMN_INDEX_ID)); 522 item.putLong(BrowserContract.Bookmarks.PARENT, 523 cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT)); 524 intent.putExtra("bookmark", item); 525 startActivityForResult(intent, BOOKMARKS_SAVE); 526 } 527 528 @Override 529 public void onActivityResult(int requestCode, int resultCode, Intent data) { 530 switch(requestCode) { 531 case BOOKMARKS_SAVE: 532 if (resultCode == Activity.RESULT_OK) { 533 Bundle extras; 534 if (data != null && (extras = data.getExtras()) != null) { 535 // If there are extras, then we need to save 536 // the edited bookmark. This is done in updateRow() 537 String title = extras.getString(BrowserContract.Bookmarks.TITLE); 538 String url = extras.getString(BrowserContract.Bookmarks.URL); 539 if (title != null && url != null) { 540 updateRow(extras); 541 } 542 } 543 } 544 break; 545 } 546 } 547 548 /** 549 * Update a row in the database with new information. 550 * @param map Bundle storing id, title and url of new information 551 */ 552 public void updateRow(Bundle map) { 553 554 // Find the record 555 int id = map.getInt("id"); 556 int position = -1; 557 Cursor cursor = mAdapter.getCursor(); 558 for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { 559 if (cursor.getInt(BookmarksLoader.COLUMN_INDEX_ID) == id) { 560 position = cursor.getPosition(); 561 break; 562 } 563 } 564 if (position < 0) { 565 return; 566 } 567 568 cursor.moveToPosition(position); 569 ContentValues values = new ContentValues(); 570 String title = map.getString(BrowserContract.Bookmarks.TITLE); 571 if (!title.equals(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE))) { 572 values.put(BrowserContract.Bookmarks.TITLE, title); 573 } 574 String url = map.getString(BrowserContract.Bookmarks.URL); 575 if (!url.equals(cursor.getString(BookmarksLoader.COLUMN_INDEX_URL))) { 576 values.put(BrowserContract.Bookmarks.URL, url); 577 } 578 579 if (map.getBoolean(AddBookmarkPage.REMOVE_THUMBNAIL)) { 580 values.putNull(BrowserContract.Bookmarks.THUMBNAIL); 581 } 582 583 if (values.size() > 0) { 584 getActivity().getContentResolver().update( 585 ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id), 586 values, null, null); 587 } 588 } 589 590 private void displayRemoveBookmarkDialog(final int position) { 591 // Put up a dialog asking if the user really wants to 592 // delete the bookmark 593 Cursor cursor = (Cursor) mAdapter.getItem(position); 594 Context context = getActivity(); 595 final ContentResolver resolver = context.getContentResolver(); 596 final Uri uri = ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, 597 cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); 598 599 new AlertDialog.Builder(context) 600 .setTitle(R.string.delete_bookmark) 601 .setIcon(android.R.drawable.ic_dialog_alert) 602 .setMessage(context.getString(R.string.delete_bookmark_warning, 603 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE))) 604 .setPositiveButton(R.string.ok, 605 new DialogInterface.OnClickListener() { 606 @Override 607 public void onClick(DialogInterface dialog, int whichButton) { 608 resolver.delete(uri, null, null); 609 } 610 }) 611 .setNegativeButton(R.string.cancel, null) 612 .show(); 613 } 614 615 private String getUrl(int position) { 616 Cursor cursor = (Cursor) mAdapter.getItem(position); 617 return cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 618 } 619 620 private void copy(CharSequence text) { 621 ClipboardManager cm = (ClipboardManager) getActivity().getSystemService( 622 Context.CLIPBOARD_SERVICE); 623 cm.setPrimaryClip(ClipData.newRawUri(null, null, Uri.parse(text.toString()))); 624 } 625 626 void selectView(int view) { 627 if (view == mCurrentView) { 628 return; 629 } 630 mCurrentView = view; 631 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); 632 Editor edit = prefs.edit(); 633 edit.putInt(PREF_SELECTED_VIEW, mCurrentView); 634 edit.apply(); 635 if (mEmptyView.getVisibility() == View.VISIBLE) { 636 return; 637 } 638 setupBookmarkView(); 639 } 640 641 private void setupBookmarkView() { 642 mAdapter.selectView(mCurrentView); 643 switch (mCurrentView) { 644 case VIEW_THUMBNAILS: 645 mList.setAdapter(null); 646 mGrid.setAdapter(mAdapter); 647 mGrid.setVisibility(View.VISIBLE); 648 mList.setVisibility(View.GONE); 649 break; 650 case VIEW_LIST: 651 mGrid.setAdapter(null); 652 mList.setAdapter(mAdapter); 653 mGrid.setVisibility(View.GONE); 654 mList.setVisibility(View.VISIBLE); 655 break; 656 } 657 } 658} 659