BrowserBookmarksPage.java revision e3063ae6057d572f47515ee47974810cefcc063d
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 com.android.browser.BreadCrumbView.Crumb; 20 21import android.app.Activity; 22import android.app.Fragment; 23import android.app.LoaderManager; 24import android.content.ClipData; 25import android.content.ClipboardManager; 26import android.content.ContentUris; 27import android.content.Context; 28import android.content.Intent; 29import android.content.Loader; 30import android.content.SharedPreferences; 31import android.content.SharedPreferences.Editor; 32import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 33import android.content.res.Configuration; 34import android.content.res.Resources; 35import android.database.Cursor; 36import android.graphics.Bitmap; 37import android.graphics.BitmapFactory; 38import android.net.Uri; 39import android.os.AsyncTask; 40import android.os.Bundle; 41import android.preference.PreferenceManager; 42import android.provider.BrowserContract; 43import android.provider.BrowserContract.ChromeSyncColumns; 44import android.view.ContextMenu; 45import android.view.ContextMenu.ContextMenuInfo; 46import android.view.LayoutInflater; 47import android.view.Menu; 48import android.view.MenuInflater; 49import android.view.MenuItem; 50import android.view.View; 51import android.view.ViewGroup; 52import android.webkit.WebIconDatabase.IconListener; 53import android.widget.AdapterView; 54import android.widget.AdapterView.OnItemClickListener; 55import android.widget.GridView; 56import android.widget.ListView; 57import android.widget.PopupMenu.OnMenuItemClickListener; 58import android.widget.Toast; 59 60interface BookmarksPageCallbacks { 61 // Return true if handled 62 boolean onBookmarkSelected(Cursor c, boolean isFolder); 63 // Return true if handled 64 boolean onOpenInNewWindow(Cursor c); 65 void onFolderChanged(int level, Uri uri); 66} 67 68/** 69 * View showing the user's bookmarks in the browser. 70 */ 71public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener, 72 LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener, 73 BreadCrumbView.Controller, OnMenuItemClickListener, OnSharedPreferenceChangeListener { 74 75 static final String LOGTAG = "browser"; 76 77 static final int LOADER_BOOKMARKS = 1; 78 79 static final String EXTRA_DISABLE_WINDOW = "disable_new_window"; 80 81 static final String ACCOUNT_NAME_UNSYNCED = "Unsynced"; 82 83 public static final String PREF_ACCOUNT_TYPE = "acct_type"; 84 public static final String PREF_ACCOUNT_NAME = "acct_name"; 85 86 static final int VIEW_THUMBNAILS = 1; 87 static final int VIEW_LIST = 2; 88 static final String PREF_SELECTED_VIEW = "bookmarks_view"; 89 90 BookmarksPageCallbacks mCallbacks; 91 View mRoot; 92 GridView mGrid; 93 ListView mList; 94 BrowserBookmarksAdapter mAdapter; 95 boolean mDisableNewWindow; 96 boolean mCanceled = false; 97 boolean mEnableContextMenu = true; 98 boolean mShowRootFolder = false; 99 View mEmptyView; 100 int mCurrentView; 101 View mHeader; 102 ViewGroup mHeaderContainer; 103 BreadCrumbView mCrumbs; 104 int mCrumbVisibility = View.VISIBLE; 105 int mCrumbMaxVisible = -1; 106 boolean mCrumbBackButton = false; 107 108 static BrowserBookmarksPage newInstance(BookmarksPageCallbacks cb, 109 Bundle args, ViewGroup headerContainer) { 110 BrowserBookmarksPage bbp = new BrowserBookmarksPage(); 111 bbp.mCallbacks = cb; 112 bbp.mHeaderContainer = headerContainer; 113 bbp.setArguments(args); 114 return bbp; 115 } 116 117 @Override 118 public Loader<Cursor> onCreateLoader(int id, Bundle args) { 119 switch (id) { 120 case LOADER_BOOKMARKS: { 121 SharedPreferences prefs = PreferenceManager 122 .getDefaultSharedPreferences(getActivity()); 123 String accountType = prefs.getString(PREF_ACCOUNT_TYPE, null); 124 String accountName = prefs.getString(PREF_ACCOUNT_NAME, null); 125 BookmarksLoader bl = new BookmarksLoader(getActivity(), 126 accountType, accountName); 127 if (mCrumbs != null) { 128 Uri uri = (Uri) mCrumbs.getTopData(); 129 if (uri != null) { 130 bl.setUri(uri); 131 } 132 } 133 return bl; 134 } 135 } 136 throw new UnsupportedOperationException("Unknown loader id " + id); 137 } 138 139 @Override 140 public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 141 switch (loader.getId()) { 142 case LOADER_BOOKMARKS: { 143 // Set the visibility of the empty vs. content views 144 if (cursor == null || cursor.getCount() == 0) { 145 mEmptyView.setVisibility(View.VISIBLE); 146 mGrid.setVisibility(View.GONE); 147 mList.setVisibility(View.GONE); 148 } else { 149 mEmptyView.setVisibility(View.GONE); 150 setupBookmarkView(); 151 } 152 153 // Give the new data to the adapter 154 mAdapter.changeCursor(cursor); 155 break; 156 } 157 } 158 } 159 160 @Override 161 public void onLoaderReset(Loader<Cursor> loader) { 162 onLoadFinished(loader, null); 163 } 164 165 long getFolderId() { 166 LoaderManager manager = getLoaderManager(); 167 BookmarksLoader loader = 168 (BookmarksLoader) ((Loader<?>)manager.getLoader(LOADER_BOOKMARKS)); 169 170 Uri uri = loader.getUri(); 171 if (uri != null) { 172 try { 173 return ContentUris.parseId(uri); 174 } catch (NumberFormatException nfx) { 175 return -1; 176 } 177 } 178 return -1; 179 } 180 181 @Override 182 public boolean onContextItemSelected(MenuItem item) { 183 final Activity activity = getActivity(); 184 // It is possible that the view has been canceled when we get to 185 // this point as back has a higher priority 186 if (mCanceled) { 187 return false; 188 } 189 AdapterView.AdapterContextMenuInfo i = 190 (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); 191 // If we have no menu info, we can't tell which item was selected. 192 if (i == null) { 193 return false; 194 } 195 196 switch (item.getItemId()) { 197 case R.id.open_context_menu_id: 198 loadUrl(i.position); 199 break; 200 case R.id.edit_context_menu_id: 201 editBookmark(i.position); 202 break; 203 case R.id.shortcut_context_menu_id: 204 Cursor c = mAdapter.getItem(i.position); 205 activity.sendBroadcast(createShortcutIntent(getActivity(), c)); 206 break; 207 case R.id.delete_context_menu_id: 208 displayRemoveBookmarkDialog(i.position); 209 break; 210 case R.id.new_window_context_menu_id: 211 openInNewWindow(i.position); 212 break; 213 case R.id.share_link_context_menu_id: { 214 Cursor cursor = mAdapter.getItem(i.position); 215 Controller.sharePage(activity, 216 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE), 217 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL), 218 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON), 219 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_THUMBNAIL)); 220 break; 221 } 222 case R.id.copy_url_context_menu_id: 223 copy(getUrl(i.position)); 224 break; 225 case R.id.homepage_context_menu_id: { 226 BrowserSettings.getInstance().setHomePage(activity, getUrl(i.position)); 227 Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show(); 228 break; 229 } 230 // Only for the Most visited page 231 case R.id.save_to_bookmarks_menu_id: { 232 Cursor cursor = mAdapter.getItem(i.position); 233 String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 234 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 235 // If the site is bookmarked, the item becomes remove from 236 // bookmarks. 237 Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name); 238 break; 239 } 240 default: 241 return super.onContextItemSelected(item); 242 } 243 return true; 244 } 245 246 static Bitmap getBitmap(Cursor cursor, int columnIndex) { 247 byte[] data = cursor.getBlob(columnIndex); 248 if (data == null) { 249 return null; 250 } 251 return BitmapFactory.decodeByteArray(data, 0, data.length); 252 } 253 254 private MenuItem.OnMenuItemClickListener mContextItemClickListener = 255 new MenuItem.OnMenuItemClickListener() { 256 @Override 257 public boolean onMenuItemClick(MenuItem item) { 258 return onContextItemSelected(item); 259 } 260 }; 261 262 @Override 263 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 264 inflater.inflate(R.menu.bookmark, menu); 265 } 266 267 @Override 268 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 269 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; 270 Cursor cursor = mAdapter.getItem(info.position); 271 if (!canEdit(cursor)) { 272 return; 273 } 274 boolean isFolder 275 = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 276 277 final Activity activity = getActivity(); 278 MenuInflater inflater = activity.getMenuInflater(); 279 inflater.inflate(R.menu.bookmarkscontext, menu); 280 if (isFolder) { 281 menu.setGroupVisible(R.id.FOLDER_CONTEXT_MENU, true); 282 } else { 283 menu.setGroupVisible(R.id.BOOKMARK_CONTEXT_MENU, true); 284 if (mDisableNewWindow) { 285 menu.findItem(R.id.new_window_context_menu_id).setVisible(false); 286 } 287 } 288 BookmarkItem header = new BookmarkItem(activity); 289 populateBookmarkItem(cursor, header, isFolder); 290 menu.setHeaderView(header); 291 292 int count = menu.size(); 293 for (int i = 0; i < count; i++) { 294 menu.getItem(i).setOnMenuItemClickListener(mContextItemClickListener); 295 } 296 } 297 298 boolean canEdit(Cursor c) { 299 String unique = c.getString(BookmarksLoader.COLUMN_INDEX_SERVER_UNIQUE); 300 return !ChromeSyncColumns.FOLDER_NAME_OTHER_BOOKMARKS.equals(unique); 301 } 302 303 private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder) { 304 item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 305 if (isFolder) { 306 item.setUrl(null); 307 Bitmap bitmap = 308 BitmapFactory.decodeResource(getResources(), R.drawable.ic_folder_holo_dark); 309 item.setFavicon(bitmap); 310 new LookupBookmarkCount(getActivity(), item) 311 .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); 312 } else { 313 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 314 item.setUrl(url); 315 Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 316 if (bitmap == null) { 317 bitmap = CombinedBookmarkHistoryView.getIconListenerSet().getFavicon(url); 318 } 319 item.setFavicon(bitmap); 320 } 321 } 322 323 /** 324 * Create a new BrowserBookmarksPage. 325 */ 326 @Override 327 public void onCreate(Bundle icicle) { 328 super.onCreate(icicle); 329 330 setHasOptionsMenu(true); 331 332 Bundle args = getArguments(); 333 mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false); 334 } 335 336 @Override 337 public View onCreateView(LayoutInflater inflater, ViewGroup container, 338 Bundle savedInstanceState) { 339 Context context = getActivity(); 340 341 mRoot = inflater.inflate(R.layout.bookmarks, container, false); 342 mEmptyView = mRoot.findViewById(android.R.id.empty); 343 344 mGrid = (GridView) mRoot.findViewById(R.id.grid); 345 mGrid.setOnItemClickListener(this); 346 mGrid.setColumnWidth(Controller.getDesiredThumbnailWidth(getActivity())); 347 mList = (ListView) mRoot.findViewById(R.id.list); 348 mList.setOnItemClickListener(this); 349 setEnableContextMenu(mEnableContextMenu); 350 351 // Prep the header 352 ViewGroup hc = mHeaderContainer; 353 if (hc == null) { 354 hc = (ViewGroup) mRoot.findViewById(R.id.header_container); 355 hc.setVisibility(View.VISIBLE); 356 } 357 mHeader = inflater.inflate(R.layout.bookmarks_header, hc, false); 358 hc.addView(mHeader); 359 mCrumbs = (BreadCrumbView) mHeader.findViewById(R.id.crumbs); 360 mCrumbs.setController(this); 361 mCrumbs.setUseBackButton(mCrumbBackButton); 362 mCrumbs.setMaxVisible(mCrumbMaxVisible); 363 mCrumbs.setVisibility(mCrumbVisibility); 364 String name = getString(R.string.bookmarks); 365 mCrumbs.pushView(name, false, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER); 366 if (mCallbacks != null) { 367 mCallbacks.onFolderChanged(1, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER); 368 } 369 // Start the loaders 370 LoaderManager lm = getLoaderManager(); 371 SharedPreferences prefs = PreferenceManager 372 .getDefaultSharedPreferences(getActivity()); 373 prefs.registerOnSharedPreferenceChangeListener(this); 374 mCurrentView = 375 prefs.getInt(PREF_SELECTED_VIEW, BrowserBookmarksPage.VIEW_THUMBNAILS); 376 mAdapter = new BrowserBookmarksAdapter(getActivity(), mCurrentView); 377 lm.restartLoader(LOADER_BOOKMARKS, null, this); 378 379 // Add our own listener in case there are favicons that have yet to be loaded. 380 CombinedBookmarkHistoryView.getIconListenerSet().addListener(this); 381 382 return mRoot; 383 } 384 385 @Override 386 public void onDestroyView() { 387 super.onDestroyView(); 388 SharedPreferences prefs = PreferenceManager 389 .getDefaultSharedPreferences(getActivity()); 390 prefs.unregisterOnSharedPreferenceChangeListener(this); 391 if (mHeaderContainer != null) { 392 mHeaderContainer.removeView(mHeader); 393 } 394 mCrumbs.setController(null); 395 mCrumbs = null; 396 getLoaderManager().destroyLoader(LOADER_BOOKMARKS); 397 mAdapter = null; 398 CombinedBookmarkHistoryView.getIconListenerSet().removeListener(this); 399 } 400 401 @Override 402 public void onReceivedIcon(String url, Bitmap icon) { 403 // A new favicon has been loaded, so let anything attached to the adapter know about it 404 // so new icons will be loaded. 405 mAdapter.notifyDataSetChanged(); 406 } 407 408 @Override 409 public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 410 // It is possible that the view has been canceled when we get to 411 // this point as back has a higher priority 412 if (mCanceled) { 413 android.util.Log.e(LOGTAG, "item clicked when dismissing"); 414 return; 415 } 416 417 Cursor cursor = mAdapter.getItem(position); 418 boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 419 if (mCallbacks != null && 420 mCallbacks.onBookmarkSelected(cursor, isFolder)) { 421 return; 422 } 423 424 if (isFolder) { 425 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 426 Uri uri = ContentUris.withAppendedId( 427 BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id); 428 if (mCrumbs != null) { 429 // update crumbs 430 mCrumbs.pushView(title, uri); 431 } 432 loadFolder(uri); 433 } 434 } 435 436 /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) { 437 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 438 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 439 Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON); 440 Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 441 return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon); 442 } 443 444 private void loadUrl(int position) { 445 if (mCallbacks != null) { 446 mCallbacks.onBookmarkSelected(mAdapter.getItem(position), false); 447 } 448 } 449 450 private void openInNewWindow(int position) { 451 if (mCallbacks != null) { 452 Cursor c = mAdapter.getItem(position); 453 boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1; 454 if (isFolder) { 455 long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID); 456 new OpenAllInTabsTask(id).execute(); 457 } else { 458 mCallbacks.onOpenInNewWindow(c); 459 } 460 } 461 } 462 463 class OpenAllInTabsTask extends AsyncTask<Void, Void, Cursor> { 464 long mFolderId; 465 public OpenAllInTabsTask(long id) { 466 mFolderId = id; 467 } 468 469 @Override 470 protected Cursor doInBackground(Void... params) { 471 Context c = getActivity(); 472 if (c == null) return null; 473 return c.getContentResolver().query(BookmarkUtils.getBookmarksUri(c), 474 BookmarksLoader.PROJECTION, BrowserContract.Bookmarks.PARENT + "=?", 475 new String[] { Long.toString(mFolderId) }, null); 476 } 477 478 @Override 479 protected void onPostExecute(Cursor result) { 480 if (mCallbacks != null) { 481 while (result.moveToNext()) { 482 mCallbacks.onOpenInNewWindow(result); 483 } 484 } 485 } 486 487 } 488 489 private void editBookmark(int position) { 490 Intent intent = new Intent(getActivity(), AddBookmarkPage.class); 491 Cursor cursor = mAdapter.getItem(position); 492 Bundle item = new Bundle(); 493 item.putString(BrowserContract.Bookmarks.TITLE, 494 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 495 item.putString(BrowserContract.Bookmarks.URL, 496 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL)); 497 byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON); 498 if (data != null) { 499 item.putParcelable(BrowserContract.Bookmarks.FAVICON, 500 BitmapFactory.decodeByteArray(data, 0, data.length)); 501 } 502 item.putLong(BrowserContract.Bookmarks._ID, 503 cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); 504 item.putLong(BrowserContract.Bookmarks.PARENT, 505 cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT)); 506 intent.putExtra(AddBookmarkPage.EXTRA_EDIT_BOOKMARK, item); 507 intent.putExtra(AddBookmarkPage.EXTRA_IS_FOLDER, 508 cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1); 509 startActivity(intent); 510 } 511 512 private void displayRemoveBookmarkDialog(final int position) { 513 // Put up a dialog asking if the user really wants to 514 // delete the bookmark 515 Cursor cursor = mAdapter.getItem(position); 516 long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID); 517 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 518 Context context = getActivity(); 519 BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null); 520 } 521 522 private String getUrl(int position) { 523 return getUrl(mAdapter.getItem(position)); 524 } 525 526 /* package */ static String getUrl(Cursor c) { 527 return c.getString(BookmarksLoader.COLUMN_INDEX_URL); 528 } 529 530 private void copy(CharSequence text) { 531 ClipboardManager cm = (ClipboardManager) getActivity().getSystemService( 532 Context.CLIPBOARD_SERVICE); 533 cm.setPrimaryClip(ClipData.newRawUri(null, Uri.parse(text.toString()))); 534 } 535 536 @Override 537 public boolean onOptionsItemSelected(MenuItem item) { 538 switch (item.getItemId()) { 539 case R.id.thumbnail_view: 540 selectView(VIEW_THUMBNAILS); 541 return true; 542 case R.id.list_view: 543 selectView(VIEW_LIST); 544 return true; 545 } 546 return super.onOptionsItemSelected(item); 547 } 548 549 @Override 550 public void onConfigurationChanged(Configuration newConfig) { 551 super.onConfigurationChanged(newConfig); 552 Resources res = getActivity().getResources(); 553 int horizontalSpacing = (int) res.getDimension(R.dimen.combo_horizontalSpacing); 554 mGrid.setHorizontalSpacing(horizontalSpacing); 555 int paddingLeftRight = (int) res.getDimension(R.dimen.combo_paddingLeftRight); 556 int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop); 557 mRoot.setPadding(paddingLeftRight, paddingTop, 558 paddingLeftRight, 0); 559 } 560 561 @Override 562 public void onPrepareOptionsMenu(Menu menu) { 563 super.onPrepareOptionsMenu(menu); 564 menu.findItem(R.id.list_view).setVisible(mCurrentView != VIEW_LIST); 565 menu.findItem(R.id.thumbnail_view).setVisible(mCurrentView != VIEW_THUMBNAILS); 566 } 567 568 void selectView(int view) { 569 if (view == mCurrentView) { 570 return; 571 } 572 mCurrentView = view; 573 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); 574 Editor edit = prefs.edit(); 575 edit.putInt(PREF_SELECTED_VIEW, mCurrentView); 576 edit.apply(); 577 if (mEmptyView.getVisibility() == View.VISIBLE) { 578 return; 579 } 580 setupBookmarkView(); 581 } 582 583 private void setupBookmarkView() { 584 mAdapter.selectView(mCurrentView); 585 switch (mCurrentView) { 586 case VIEW_THUMBNAILS: 587 mList.setAdapter(null); 588 mGrid.setAdapter(mAdapter); 589 mGrid.setVisibility(View.VISIBLE); 590 mList.setVisibility(View.GONE); 591 break; 592 case VIEW_LIST: 593 mGrid.setAdapter(null); 594 mList.setAdapter(mAdapter); 595 mGrid.setVisibility(View.GONE); 596 mList.setVisibility(View.VISIBLE); 597 break; 598 } 599 } 600 601 /** 602 * BreadCrumb controller callback 603 */ 604 @Override 605 public void onTop(int level, Object data) { 606 Uri uri = (Uri) data; 607 if (uri == null) { 608 // top level 609 uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER; 610 } 611 loadFolder(uri); 612 } 613 614 /** 615 * @param uri 616 */ 617 private void loadFolder(Uri uri) { 618 LoaderManager manager = getLoaderManager(); 619 BookmarksLoader loader = 620 (BookmarksLoader) ((Loader<?>) manager.getLoader(LOADER_BOOKMARKS)); 621 loader.setUri(uri); 622 loader.forceLoad(); 623 if (mCallbacks != null) { 624 mCallbacks.onFolderChanged(mCrumbs.getTopLevel(), uri); 625 } 626 } 627 628 @Override 629 public boolean onMenuItemClick(MenuItem item) { 630 switch (item.getItemId()) { 631 case R.id.list_view: 632 selectView(BrowserBookmarksPage.VIEW_LIST); 633 return true; 634 case R.id.thumbnail_view: 635 selectView(BrowserBookmarksPage.VIEW_THUMBNAILS); 636 return true; 637 } 638 return false; 639 } 640 641 public boolean onBackPressed() { 642 if (canGoBack()) { 643 mCrumbs.popView(); 644 return true; 645 } 646 return false; 647 } 648 649 private boolean canGoBack() { 650 Crumb c = mCrumbs.getTopCrumb(); 651 return c != null && c.canGoBack; 652 } 653 654 public void setCallbackListener(BookmarksPageCallbacks callbackListener) { 655 mCallbacks = callbackListener; 656 } 657 658 public void setEnableContextMenu(boolean enable) { 659 mEnableContextMenu = enable; 660 if (mGrid != null) { 661 if (mEnableContextMenu) { 662 registerForContextMenu(mGrid); 663 } else { 664 unregisterForContextMenu(mGrid); 665 mGrid.setLongClickable(false); 666 } 667 } 668 if (mList != null) { 669 if (mEnableContextMenu) { 670 registerForContextMenu(mList); 671 } else { 672 unregisterForContextMenu(mList); 673 mList.setLongClickable(false); 674 } 675 } 676 } 677 678 private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> { 679 Context mContext; 680 BookmarkItem mHeader; 681 682 public LookupBookmarkCount(Context context, BookmarkItem header) { 683 mContext = context; 684 mHeader = header; 685 } 686 687 @Override 688 protected Integer doInBackground(Long... params) { 689 if (params.length != 1) { 690 throw new IllegalArgumentException("Missing folder id!"); 691 } 692 Uri uri = BookmarkUtils.getBookmarksUri(mContext); 693 Cursor c = mContext.getContentResolver().query(uri, 694 null, BrowserContract.Bookmarks.PARENT + "=?", 695 new String[] {params[0].toString()}, null); 696 return c.getCount(); 697 } 698 699 @Override 700 protected void onPostExecute(Integer result) { 701 if (result > 0) { 702 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_bookmarkcount, 703 result)); 704 } else if (result == 0) { 705 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_empty)); 706 } 707 } 708 } 709 710 public void setBreadCrumbVisibility(int visibility) { 711 mCrumbVisibility = visibility; 712 if (mCrumbs != null) { 713 mCrumbs.setVisibility(mCrumbVisibility); 714 } 715 } 716 717 public void setBreadCrumbUseBackButton(boolean use) { 718 mCrumbBackButton = use; 719 if (mCrumbs != null) { 720 mCrumbs.setUseBackButton(mCrumbBackButton); 721 } 722 } 723 724 public void setBreadCrumbMaxVisible(int max) { 725 mCrumbMaxVisible = max; 726 if (mCrumbs != null) { 727 mCrumbs.setMaxVisible(mCrumbMaxVisible); 728 } 729 } 730 731 @Override 732 public void onSharedPreferenceChanged( 733 SharedPreferences sharedPreferences, String key) { 734 if (PREF_ACCOUNT_NAME.equals(key) || PREF_ACCOUNT_TYPE.equals(key)) { 735 mCrumbs.setController(null); 736 mCrumbs.clear(); 737 LoaderManager lm = getLoaderManager(); 738 lm.restartLoader(LOADER_BOOKMARKS, null, this); 739 mCrumbs.setController(this); 740 String name = getString(R.string.bookmarks); 741 mCrumbs.pushView(name, false, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER); 742 if (mCallbacks != null) { 743 mCallbacks.onFolderChanged(1, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER); 744 } 745 } 746 } 747} 748