BrowserBookmarksPage.java revision 522a438d69486914a364c2fe0934c08269b1129f
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 } 398 399 @Override 400 public void onReceivedIcon(String url, Bitmap icon) { 401 // A new favicon has been loaded, so let anything attached to the adapter know about it 402 // so new icons will be loaded. 403 mAdapter.notifyDataSetChanged(); 404 } 405 406 @Override 407 public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 408 // It is possible that the view has been canceled when we get to 409 // this point as back has a higher priority 410 if (mCanceled) { 411 android.util.Log.e(LOGTAG, "item clicked when dismissing"); 412 return; 413 } 414 415 Cursor cursor = mAdapter.getItem(position); 416 boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 417 if (mCallbacks != null && 418 mCallbacks.onBookmarkSelected(cursor, isFolder)) { 419 return; 420 } 421 422 if (isFolder) { 423 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 424 Uri uri = ContentUris.withAppendedId( 425 BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id); 426 if (mCrumbs != null) { 427 // update crumbs 428 mCrumbs.pushView(title, uri); 429 } 430 loadFolder(uri); 431 } 432 } 433 434 /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) { 435 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 436 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 437 Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON); 438 Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 439 return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon); 440 } 441 442 private void loadUrl(int position) { 443 if (mCallbacks != null) { 444 mCallbacks.onBookmarkSelected(mAdapter.getItem(position), false); 445 } 446 } 447 448 private void openInNewWindow(int position) { 449 if (mCallbacks != null) { 450 Cursor c = mAdapter.getItem(position); 451 boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1; 452 if (isFolder) { 453 long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID); 454 new OpenAllInTabsTask(id).execute(); 455 } else { 456 mCallbacks.onOpenInNewWindow(c); 457 } 458 } 459 } 460 461 class OpenAllInTabsTask extends AsyncTask<Void, Void, Cursor> { 462 long mFolderId; 463 public OpenAllInTabsTask(long id) { 464 mFolderId = id; 465 } 466 467 @Override 468 protected Cursor doInBackground(Void... params) { 469 Context c = getActivity(); 470 if (c == null) return null; 471 return c.getContentResolver().query(BookmarkUtils.getBookmarksUri(c), 472 BookmarksLoader.PROJECTION, BrowserContract.Bookmarks.PARENT + "=?", 473 new String[] { Long.toString(mFolderId) }, null); 474 } 475 476 @Override 477 protected void onPostExecute(Cursor result) { 478 if (mCallbacks != null) { 479 while (result.moveToNext()) { 480 mCallbacks.onOpenInNewWindow(result); 481 } 482 } 483 } 484 485 } 486 487 private void editBookmark(int position) { 488 Intent intent = new Intent(getActivity(), AddBookmarkPage.class); 489 Cursor cursor = mAdapter.getItem(position); 490 Bundle item = new Bundle(); 491 item.putString(BrowserContract.Bookmarks.TITLE, 492 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 493 item.putString(BrowserContract.Bookmarks.URL, 494 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL)); 495 byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON); 496 if (data != null) { 497 item.putParcelable(BrowserContract.Bookmarks.FAVICON, 498 BitmapFactory.decodeByteArray(data, 0, data.length)); 499 } 500 item.putLong(BrowserContract.Bookmarks._ID, 501 cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); 502 item.putLong(BrowserContract.Bookmarks.PARENT, 503 cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT)); 504 intent.putExtra(AddBookmarkPage.EXTRA_EDIT_BOOKMARK, item); 505 intent.putExtra(AddBookmarkPage.EXTRA_IS_FOLDER, 506 cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1); 507 startActivity(intent); 508 } 509 510 private void displayRemoveBookmarkDialog(final int position) { 511 // Put up a dialog asking if the user really wants to 512 // delete the bookmark 513 Cursor cursor = mAdapter.getItem(position); 514 long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID); 515 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 516 Context context = getActivity(); 517 BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null); 518 } 519 520 private String getUrl(int position) { 521 return getUrl(mAdapter.getItem(position)); 522 } 523 524 /* package */ static String getUrl(Cursor c) { 525 return c.getString(BookmarksLoader.COLUMN_INDEX_URL); 526 } 527 528 private void copy(CharSequence text) { 529 ClipboardManager cm = (ClipboardManager) getActivity().getSystemService( 530 Context.CLIPBOARD_SERVICE); 531 cm.setPrimaryClip(ClipData.newRawUri(null, Uri.parse(text.toString()))); 532 } 533 534 @Override 535 public boolean onOptionsItemSelected(MenuItem item) { 536 switch (item.getItemId()) { 537 case R.id.thumbnail_view: 538 selectView(VIEW_THUMBNAILS); 539 return true; 540 case R.id.list_view: 541 selectView(VIEW_LIST); 542 return true; 543 } 544 return super.onOptionsItemSelected(item); 545 } 546 547 @Override 548 public void onConfigurationChanged(Configuration newConfig) { 549 super.onConfigurationChanged(newConfig); 550 Resources res = getActivity().getResources(); 551 int horizontalSpacing = (int) res.getDimension(R.dimen.combo_horizontalSpacing); 552 mGrid.setHorizontalSpacing(horizontalSpacing); 553 int paddingLeftRight = (int) res.getDimension(R.dimen.combo_paddingLeftRight); 554 int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop); 555 mRoot.setPadding(paddingLeftRight, paddingTop, 556 paddingLeftRight, 0); 557 } 558 559 @Override 560 public void onPrepareOptionsMenu(Menu menu) { 561 super.onPrepareOptionsMenu(menu); 562 menu.findItem(R.id.list_view).setVisible(mCurrentView != VIEW_LIST); 563 menu.findItem(R.id.thumbnail_view).setVisible(mCurrentView != VIEW_THUMBNAILS); 564 } 565 566 void selectView(int view) { 567 if (view == mCurrentView) { 568 return; 569 } 570 mCurrentView = view; 571 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); 572 Editor edit = prefs.edit(); 573 edit.putInt(PREF_SELECTED_VIEW, mCurrentView); 574 edit.apply(); 575 if (mEmptyView.getVisibility() == View.VISIBLE) { 576 return; 577 } 578 setupBookmarkView(); 579 } 580 581 private void setupBookmarkView() { 582 mAdapter.selectView(mCurrentView); 583 switch (mCurrentView) { 584 case VIEW_THUMBNAILS: 585 mList.setAdapter(null); 586 mGrid.setAdapter(mAdapter); 587 mGrid.setVisibility(View.VISIBLE); 588 mList.setVisibility(View.GONE); 589 break; 590 case VIEW_LIST: 591 mGrid.setAdapter(null); 592 mList.setAdapter(mAdapter); 593 mGrid.setVisibility(View.GONE); 594 mList.setVisibility(View.VISIBLE); 595 break; 596 } 597 } 598 599 /** 600 * BreadCrumb controller callback 601 */ 602 @Override 603 public void onTop(int level, Object data) { 604 Uri uri = (Uri) data; 605 if (uri == null) { 606 // top level 607 uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER; 608 } 609 loadFolder(uri); 610 } 611 612 /** 613 * @param uri 614 */ 615 private void loadFolder(Uri uri) { 616 LoaderManager manager = getLoaderManager(); 617 BookmarksLoader loader = 618 (BookmarksLoader) ((Loader<?>) manager.getLoader(LOADER_BOOKMARKS)); 619 loader.setUri(uri); 620 loader.forceLoad(); 621 if (mCallbacks != null) { 622 mCallbacks.onFolderChanged(mCrumbs.getTopLevel(), uri); 623 } 624 } 625 626 @Override 627 public boolean onMenuItemClick(MenuItem item) { 628 switch (item.getItemId()) { 629 case R.id.list_view: 630 selectView(BrowserBookmarksPage.VIEW_LIST); 631 return true; 632 case R.id.thumbnail_view: 633 selectView(BrowserBookmarksPage.VIEW_THUMBNAILS); 634 return true; 635 } 636 return false; 637 } 638 639 public boolean onBackPressed() { 640 if (canGoBack()) { 641 mCrumbs.popView(); 642 return true; 643 } 644 return false; 645 } 646 647 private boolean canGoBack() { 648 Crumb c = mCrumbs.getTopCrumb(); 649 return c != null && c.canGoBack; 650 } 651 652 public void setCallbackListener(BookmarksPageCallbacks callbackListener) { 653 mCallbacks = callbackListener; 654 } 655 656 public void setEnableContextMenu(boolean enable) { 657 mEnableContextMenu = enable; 658 if (mGrid != null) { 659 if (mEnableContextMenu) { 660 registerForContextMenu(mGrid); 661 } else { 662 unregisterForContextMenu(mGrid); 663 mGrid.setLongClickable(false); 664 } 665 } 666 if (mList != null) { 667 if (mEnableContextMenu) { 668 registerForContextMenu(mList); 669 } else { 670 unregisterForContextMenu(mList); 671 mList.setLongClickable(false); 672 } 673 } 674 } 675 676 private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> { 677 Context mContext; 678 BookmarkItem mHeader; 679 680 public LookupBookmarkCount(Context context, BookmarkItem header) { 681 mContext = context; 682 mHeader = header; 683 } 684 685 @Override 686 protected Integer doInBackground(Long... params) { 687 if (params.length != 1) { 688 throw new IllegalArgumentException("Missing folder id!"); 689 } 690 Uri uri = BookmarkUtils.getBookmarksUri(mContext); 691 Cursor c = mContext.getContentResolver().query(uri, 692 null, BrowserContract.Bookmarks.PARENT + "=?", 693 new String[] {params[0].toString()}, null); 694 return c.getCount(); 695 } 696 697 @Override 698 protected void onPostExecute(Integer result) { 699 if (result > 0) { 700 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_bookmarkcount, 701 result)); 702 } else if (result == 0) { 703 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_empty)); 704 } 705 } 706 } 707 708 public void setBreadCrumbVisibility(int visibility) { 709 mCrumbVisibility = visibility; 710 if (mCrumbs != null) { 711 mCrumbs.setVisibility(mCrumbVisibility); 712 } 713 } 714 715 public void setBreadCrumbUseBackButton(boolean use) { 716 mCrumbBackButton = use; 717 if (mCrumbs != null) { 718 mCrumbs.setUseBackButton(mCrumbBackButton); 719 } 720 } 721 722 public void setBreadCrumbMaxVisible(int max) { 723 mCrumbMaxVisible = max; 724 if (mCrumbs != null) { 725 mCrumbs.setMaxVisible(mCrumbMaxVisible); 726 } 727 } 728 729 @Override 730 public void onSharedPreferenceChanged( 731 SharedPreferences sharedPreferences, String key) { 732 if (PREF_ACCOUNT_NAME.equals(key) || PREF_ACCOUNT_TYPE.equals(key)) { 733 mCrumbs.setController(null); 734 mCrumbs.clear(); 735 LoaderManager lm = getLoaderManager(); 736 lm.restartLoader(LOADER_BOOKMARKS, null, this); 737 mCrumbs.setController(this); 738 String name = getString(R.string.bookmarks); 739 mCrumbs.pushView(name, false, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER); 740 if (mCallbacks != null) { 741 mCallbacks.onFolderChanged(1, BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER); 742 } 743 } 744 } 745} 746