BrowserBookmarksPage.java revision d18ac4b36b057a6a403cb060dfc10761b7394548
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.Fragment; 21import android.app.LoaderManager; 22import android.content.ClipData; 23import android.content.ClipboardManager; 24import android.content.ContentUris; 25import android.content.Context; 26import android.content.CursorLoader; 27import android.content.Intent; 28import android.content.Loader; 29import android.content.SharedPreferences; 30import android.content.res.Configuration; 31import android.content.res.Resources; 32import android.database.Cursor; 33import android.graphics.Bitmap; 34import android.graphics.BitmapFactory; 35import android.net.Uri; 36import android.os.AsyncTask; 37import android.os.Bundle; 38import android.provider.BrowserContract; 39import android.provider.BrowserContract.Accounts; 40import android.view.ActionMode; 41import android.view.ContextMenu; 42import android.view.ContextMenu.ContextMenuInfo; 43import android.view.LayoutInflater; 44import android.view.MenuInflater; 45import android.view.MenuItem; 46import android.view.View; 47import android.view.ViewGroup; 48import android.widget.ExpandableListView; 49import android.widget.ExpandableListView.OnChildClickListener; 50import android.widget.ImageView; 51import android.widget.LinearLayout; 52import android.widget.Toast; 53 54import com.android.browser.BookmarkDragHandler.BookmarkDragController; 55import com.android.browser.BookmarkDragHandler.BookmarkDragState; 56import com.android.browser.provider.BrowserProvider2; 57import com.android.browser.view.BookmarkExpandableView; 58import com.android.browser.view.BookmarkExpandableView.BookmarkContextMenuInfo; 59 60import org.json.JSONException; 61import org.json.JSONObject; 62 63import java.util.HashMap; 64 65interface BookmarksPageCallbacks { 66 // Return true if handled 67 boolean onBookmarkSelected(Cursor c, boolean isFolder); 68 // Return true if handled 69 boolean onOpenInNewWindow(String... urls); 70} 71 72/** 73 * View showing the user's bookmarks in the browser. 74 */ 75public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener, 76 LoaderManager.LoaderCallbacks<Cursor>, BreadCrumbView.Controller, 77 OnChildClickListener { 78 79 public static class ExtraDragState { 80 public int childPosition; 81 public int groupPosition; 82 } 83 84 static final String LOGTAG = "browser"; 85 86 static final int LOADER_ACCOUNTS = 1; 87 static final int LOADER_BOOKMARKS = 100; 88 89 static final String EXTRA_DISABLE_WINDOW = "disable_new_window"; 90 static final String PREF_GROUP_STATE = "bbp_group_state"; 91 92 static final String ACCOUNT_TYPE = "account_type"; 93 static final String ACCOUNT_NAME = "account_name"; 94 95 public static final int VIEW_THUMBNAILS = 1; 96 public static final int VIEW_LIST = 2; 97 98 BookmarksPageCallbacks mCallbacks; 99 View mRoot; 100 BookmarkExpandableView mGrid; 101 boolean mDisableNewWindow; 102 boolean mEnableContextMenu = true; 103 View mEmptyView; 104 View mHeader; 105 HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>(); 106 BookmarkDragHandler mDragHandler; 107 JSONObject mState; 108 109 @Override 110 public Loader<Cursor> onCreateLoader(int id, Bundle args) { 111 if (id == LOADER_ACCOUNTS) { 112 return new AccountsLoader(getActivity()); 113 } else if (id >= LOADER_BOOKMARKS) { 114 String accountType = args.getString(ACCOUNT_TYPE); 115 String accountName = args.getString(ACCOUNT_NAME); 116 BookmarksLoader bl = new BookmarksLoader(getActivity(), 117 accountType, accountName); 118 return bl; 119 } else { 120 throw new UnsupportedOperationException("Unknown loader id " + id); 121 } 122 } 123 124 @Override 125 public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 126 if (loader.getId() == LOADER_ACCOUNTS) { 127 LoaderManager lm = getLoaderManager(); 128 int id = LOADER_BOOKMARKS; 129 while (cursor.moveToNext()) { 130 String accountName = cursor.getString(0); 131 String accountType = cursor.getString(1); 132 Bundle args = new Bundle(); 133 args.putString(ACCOUNT_NAME, accountName); 134 args.putString(ACCOUNT_TYPE, accountType); 135 BrowserBookmarksAdapter adapter = new BrowserBookmarksAdapter( 136 getActivity(), VIEW_THUMBNAILS); 137 mBookmarkAdapters.put(id, adapter); 138 boolean expand = true; 139 try { 140 expand = mState.getBoolean(accountName != null ? accountName 141 : BookmarkExpandableView.LOCAL_ACCOUNT_NAME); 142 } catch (JSONException e) {} // no state for accountName 143 mGrid.addAccount(accountName, adapter, expand); 144 lm.restartLoader(id, args, this); 145 id++; 146 } 147 // TODO: Figure out what a reload of these means 148 // Currently, a reload is triggered whenever bookmarks change 149 // This is less than ideal 150 // It also causes UI flickering as a new adapter is created 151 // instead of re-using an existing one when the account_name is the 152 // same. 153 // For now, this is a one-shot load 154 getLoaderManager().destroyLoader(LOADER_ACCOUNTS); 155 } else if (loader.getId() >= LOADER_BOOKMARKS) { 156 BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId()); 157 adapter.changeCursor(cursor); 158 } 159 } 160 161 @Override 162 public void onLoaderReset(Loader<Cursor> loader) { 163 } 164 165 @Override 166 public boolean onContextItemSelected(MenuItem item) { 167 if (!(item.getMenuInfo() instanceof BookmarkContextMenuInfo)) { 168 return false; 169 } 170 BookmarkContextMenuInfo i = (BookmarkContextMenuInfo) item.getMenuInfo(); 171 // If we have no menu info, we can't tell which item was selected. 172 if (i == null) { 173 return false; 174 } 175 176 if (handleContextItem(item.getItemId(), i.groupPosition, i.childPosition)) { 177 return true; 178 } 179 return super.onContextItemSelected(item); 180 } 181 182 public boolean handleContextItem(int itemId, int groupPosition, 183 int childPosition) { 184 final Activity activity = getActivity(); 185 BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition); 186 187 switch (itemId) { 188 case R.id.open_context_menu_id: 189 loadUrl(adapter, childPosition); 190 break; 191 case R.id.edit_context_menu_id: 192 editBookmark(adapter, childPosition); 193 break; 194 case R.id.shortcut_context_menu_id: 195 Cursor c = adapter.getItem(childPosition); 196 activity.sendBroadcast(createShortcutIntent(getActivity(), c)); 197 break; 198 case R.id.delete_context_menu_id: 199 displayRemoveBookmarkDialog(adapter, childPosition); 200 break; 201 case R.id.new_window_context_menu_id: 202 openInNewWindow(adapter, childPosition); 203 break; 204 case R.id.share_link_context_menu_id: { 205 Cursor cursor = adapter.getItem(childPosition); 206 Controller.sharePage(activity, 207 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE), 208 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL), 209 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON), 210 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_THUMBNAIL)); 211 break; 212 } 213 case R.id.copy_url_context_menu_id: 214 copy(getUrl(adapter, childPosition)); 215 break; 216 case R.id.homepage_context_menu_id: { 217 BrowserSettings.getInstance().setHomePage(getUrl(adapter, childPosition)); 218 Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show(); 219 break; 220 } 221 // Only for the Most visited page 222 case R.id.save_to_bookmarks_menu_id: { 223 Cursor cursor = adapter.getItem(childPosition); 224 String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 225 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 226 // If the site is bookmarked, the item becomes remove from 227 // bookmarks. 228 Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name); 229 break; 230 } 231 default: 232 return false; 233 } 234 return true; 235 } 236 237 static Bitmap getBitmap(Cursor cursor, int columnIndex) { 238 byte[] data = cursor.getBlob(columnIndex); 239 if (data == null) { 240 return null; 241 } 242 return BitmapFactory.decodeByteArray(data, 0, data.length); 243 } 244 245 private MenuItem.OnMenuItemClickListener mContextItemClickListener = 246 new MenuItem.OnMenuItemClickListener() { 247 @Override 248 public boolean onMenuItemClick(MenuItem item) { 249 return onContextItemSelected(item); 250 } 251 }; 252 253 @Override 254 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 255 BookmarkContextMenuInfo info = (BookmarkContextMenuInfo) menuInfo; 256 BrowserBookmarksAdapter adapter = getChildAdapter(info.groupPosition); 257 Cursor cursor = adapter.getItem(info.childPosition); 258 if (!canEdit(cursor)) { 259 return; 260 } 261 boolean isFolder 262 = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 263 264 final Activity activity = getActivity(); 265 MenuInflater inflater = activity.getMenuInflater(); 266 inflater.inflate(R.menu.bookmarkscontext, menu); 267 if (isFolder) { 268 menu.setGroupVisible(R.id.FOLDER_CONTEXT_MENU, true); 269 } else { 270 menu.setGroupVisible(R.id.BOOKMARK_CONTEXT_MENU, true); 271 if (mDisableNewWindow) { 272 menu.findItem(R.id.new_window_context_menu_id).setVisible(false); 273 } 274 } 275 BookmarkItem header = new BookmarkItem(activity); 276 header.setEnableScrolling(true); 277 populateBookmarkItem(cursor, header, isFolder); 278 menu.setHeaderView(header); 279 280 int count = menu.size(); 281 for (int i = 0; i < count; i++) { 282 menu.getItem(i).setOnMenuItemClickListener(mContextItemClickListener); 283 } 284 } 285 286 boolean canEdit(Cursor c) { 287 int type = c.getInt(BookmarksLoader.COLUMN_INDEX_TYPE); 288 return type == BrowserContract.Bookmarks.BOOKMARK_TYPE_BOOKMARK 289 || type == BrowserContract.Bookmarks.BOOKMARK_TYPE_FOLDER; 290 } 291 292 private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder) { 293 item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 294 if (isFolder) { 295 item.setUrl(null); 296 Bitmap bitmap = 297 BitmapFactory.decodeResource(getResources(), R.drawable.ic_folder_holo_dark); 298 item.setFavicon(bitmap); 299 new LookupBookmarkCount(getActivity(), item) 300 .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); 301 } else { 302 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 303 item.setUrl(url); 304 Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 305 item.setFavicon(bitmap); 306 } 307 } 308 309 /** 310 * Create a new BrowserBookmarksPage. 311 */ 312 @Override 313 public void onCreate(Bundle icicle) { 314 super.onCreate(icicle); 315 SharedPreferences prefs = BrowserSettings.getInstance().getPreferences(); 316 try { 317 mState = new JSONObject(prefs.getString(PREF_GROUP_STATE, "{}")); 318 } catch (JSONException e) { 319 // Parse failed, clear preference and start with empty state 320 prefs.edit().remove(PREF_GROUP_STATE).apply(); 321 mState = new JSONObject(); 322 } 323 Bundle args = getArguments(); 324 mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false); 325 setHasOptionsMenu(true); 326 if (mCallbacks == null && getActivity() instanceof CombinedBookmarksCallbacks) { 327 mCallbacks = new CombinedBookmarksCallbackWrapper( 328 (CombinedBookmarksCallbacks) getActivity()); 329 } 330 } 331 332 @Override 333 public void onPause() { 334 super.onPause(); 335 try { 336 mState = mGrid.saveGroupState(); 337 // Save state 338 SharedPreferences prefs = BrowserSettings.getInstance().getPreferences(); 339 prefs.edit() 340 .putString(PREF_GROUP_STATE, mState.toString()) 341 .apply(); 342 } catch (JSONException e) { 343 // Not critical, ignore 344 } 345 } 346 347 private static class CombinedBookmarksCallbackWrapper 348 implements BookmarksPageCallbacks { 349 350 private CombinedBookmarksCallbacks mCombinedCallback; 351 352 private CombinedBookmarksCallbackWrapper(CombinedBookmarksCallbacks cb) { 353 mCombinedCallback = cb; 354 } 355 356 @Override 357 public boolean onOpenInNewWindow(String... urls) { 358 mCombinedCallback.openInNewTab(urls); 359 return true; 360 } 361 362 @Override 363 public boolean onBookmarkSelected(Cursor c, boolean isFolder) { 364 if (isFolder) { 365 return false; 366 } 367 mCombinedCallback.openUrl(BrowserBookmarksPage.getUrl(c)); 368 return true; 369 } 370 }; 371 372 @Override 373 public View onCreateView(LayoutInflater inflater, ViewGroup container, 374 Bundle savedInstanceState) { 375 mRoot = inflater.inflate(R.layout.bookmarks, container, false); 376 mEmptyView = mRoot.findViewById(android.R.id.empty); 377 378 mGrid = (BookmarkExpandableView) mRoot.findViewById(R.id.grid); 379 mGrid.setOnChildClickListener(this); 380 mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail); 381 mGrid.setBreadcrumbController(this); 382 setEnableContextMenu(mEnableContextMenu); 383 mDragHandler = new BookmarkDragHandler(getActivity(), mDragController, 384 mGrid.getDragAdapter()); 385 386 // Start the loaders 387 LoaderManager lm = getLoaderManager(); 388 lm.restartLoader(LOADER_ACCOUNTS, null, this); 389 390 return mRoot; 391 } 392 393 @Override 394 public void onDestroyView() { 395 super.onDestroyView(); 396 mGrid.setBreadcrumbController(null); 397 mGrid.clearAccounts(); 398 LoaderManager lm = getLoaderManager(); 399 lm.destroyLoader(LOADER_ACCOUNTS); 400 for (int id : mBookmarkAdapters.keySet()) { 401 lm.destroyLoader(id); 402 } 403 mBookmarkAdapters.clear(); 404 } 405 406 private BrowserBookmarksAdapter getChildAdapter(int groupPosition) { 407 return mGrid.getChildAdapter(groupPosition); 408 } 409 410 private BreadCrumbView getBreadCrumbs(int groupPosition) { 411 return mGrid.getBreadCrumbs(groupPosition); 412 } 413 414 @Override 415 public boolean onChildClick(ExpandableListView parent, View v, 416 int groupPosition, int childPosition, long id) { 417 BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition); 418 Cursor cursor = adapter.getItem(childPosition); 419 boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 420 if (mCallbacks != null && 421 mCallbacks.onBookmarkSelected(cursor, isFolder)) { 422 return true; 423 } 424 425 if (isFolder) { 426 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 427 Uri uri = ContentUris.withAppendedId( 428 BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id); 429 BreadCrumbView crumbs = getBreadCrumbs(groupPosition); 430 if (crumbs != null) { 431 // update crumbs 432 crumbs.pushView(title, uri); 433 crumbs.setVisibility(View.VISIBLE); 434 } 435 loadFolder(groupPosition, uri); 436 } 437 return true; 438 } 439 440 /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) { 441 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 442 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 443 Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON); 444 Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 445 return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon); 446 } 447 448 private void loadUrl(BrowserBookmarksAdapter adapter, int position) { 449 if (mCallbacks != null && adapter != null) { 450 mCallbacks.onBookmarkSelected(adapter.getItem(position), false); 451 } 452 } 453 454 private void openInNewWindow(BrowserBookmarksAdapter adapter, int position) { 455 if (mCallbacks != null) { 456 Cursor c = adapter.getItem(position); 457 boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1; 458 if (isFolder) { 459 long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID); 460 new OpenAllInTabsTask(id).execute(); 461 } else { 462 mCallbacks.onOpenInNewWindow(BrowserBookmarksPage.getUrl(c)); 463 } 464 } 465 } 466 467 class OpenAllInTabsTask extends AsyncTask<Void, Void, Cursor> { 468 long mFolderId; 469 public OpenAllInTabsTask(long id) { 470 mFolderId = id; 471 } 472 473 @Override 474 protected Cursor doInBackground(Void... params) { 475 Context c = getActivity(); 476 if (c == null) return null; 477 return c.getContentResolver().query(BookmarkUtils.getBookmarksUri(c), 478 BookmarksLoader.PROJECTION, BrowserContract.Bookmarks.PARENT + "=?", 479 new String[] { Long.toString(mFolderId) }, null); 480 } 481 482 @Override 483 protected void onPostExecute(Cursor result) { 484 if (mCallbacks != null && result.getCount() > 0) { 485 String[] urls = new String[result.getCount()]; 486 int i = 0; 487 while (result.moveToNext()) { 488 urls[i++] = BrowserBookmarksPage.getUrl(result); 489 } 490 mCallbacks.onOpenInNewWindow(urls); 491 } 492 } 493 494 } 495 496 private void editBookmark(BrowserBookmarksAdapter adapter, int position) { 497 Intent intent = new Intent(getActivity(), AddBookmarkPage.class); 498 Cursor cursor = adapter.getItem(position); 499 Bundle item = new Bundle(); 500 item.putString(BrowserContract.Bookmarks.TITLE, 501 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 502 item.putString(BrowserContract.Bookmarks.URL, 503 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL)); 504 byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON); 505 if (data != null) { 506 item.putParcelable(BrowserContract.Bookmarks.FAVICON, 507 BitmapFactory.decodeByteArray(data, 0, data.length)); 508 } 509 item.putLong(BrowserContract.Bookmarks._ID, 510 cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); 511 item.putLong(BrowserContract.Bookmarks.PARENT, 512 cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT)); 513 intent.putExtra(AddBookmarkPage.EXTRA_EDIT_BOOKMARK, item); 514 intent.putExtra(AddBookmarkPage.EXTRA_IS_FOLDER, 515 cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1); 516 startActivity(intent); 517 } 518 519 private void displayRemoveBookmarkDialog(BrowserBookmarksAdapter adapter, 520 int position) { 521 // Put up a dialog asking if the user really wants to 522 // delete the bookmark 523 Cursor cursor = adapter.getItem(position); 524 long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID); 525 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 526 Context context = getActivity(); 527 BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null); 528 } 529 530 private String getUrl(BrowserBookmarksAdapter adapter, int position) { 531 return getUrl(adapter.getItem(position)); 532 } 533 534 /* package */ static String getUrl(Cursor c) { 535 return c.getString(BookmarksLoader.COLUMN_INDEX_URL); 536 } 537 538 private void copy(CharSequence text) { 539 ClipboardManager cm = (ClipboardManager) getActivity().getSystemService( 540 Context.CLIPBOARD_SERVICE); 541 cm.setPrimaryClip(ClipData.newRawUri(null, Uri.parse(text.toString()))); 542 } 543 544 @Override 545 public void onConfigurationChanged(Configuration newConfig) { 546 super.onConfigurationChanged(newConfig); 547 Resources res = getActivity().getResources(); 548 mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail); 549 int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop); 550 mRoot.setPadding(0, paddingTop, 0, 0); 551 getActivity().invalidateOptionsMenu(); 552 } 553 554 /** 555 * BreadCrumb controller callback 556 */ 557 @Override 558 public void onTop(BreadCrumbView view, int level, Object data) { 559 int groupPosition = (Integer) view.getTag(R.id.group_position); 560 Uri uri = (Uri) data; 561 if (uri == null) { 562 // top level 563 uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER; 564 } 565 loadFolder(groupPosition, uri); 566 if (level <= 1) { 567 view.setVisibility(View.GONE); 568 } else { 569 view.setVisibility(View.VISIBLE); 570 } 571 } 572 573 /** 574 * @param uri 575 */ 576 private void loadFolder(int groupPosition, Uri uri) { 577 LoaderManager manager = getLoaderManager(); 578 // This assumes groups are ordered the same as loaders 579 BookmarksLoader loader = (BookmarksLoader) ((Loader<?>) 580 manager.getLoader(LOADER_BOOKMARKS + groupPosition)); 581 loader.setUri(uri); 582 loader.forceLoad(); 583 } 584 585 public void setCallbackListener(BookmarksPageCallbacks callbackListener) { 586 mCallbacks = callbackListener; 587 } 588 589 public void setEnableContextMenu(boolean enable) { 590 mEnableContextMenu = enable; 591 if (mGrid != null) { 592 if (mEnableContextMenu) { 593 registerForContextMenu(mGrid); 594 } else { 595 unregisterForContextMenu(mGrid); 596 mGrid.setLongClickable(false); 597 } 598 } 599 } 600 601 private BookmarkDragController mDragController = new BookmarkDragController() { 602 603 @Override 604 public boolean startDrag(Cursor item) { 605 return canEdit(item); 606 } 607 608 @Override 609 public ViewGroup getActionModeView(ActionMode mode, 610 BookmarkDragState state) { 611 LayoutInflater inflater = LayoutInflater.from(getActivity()); 612 LinearLayout view = (LinearLayout) inflater.inflate( 613 R.layout.bookmarks_drag_actionmode, null); 614 view.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE); 615 ExtraDragState extraState = (ExtraDragState) state.extraState; 616 BrowserBookmarksAdapter adapter = getChildAdapter(extraState.groupPosition); 617 Cursor c = adapter.getItem(extraState.childPosition); 618 boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 619 if (isFolder) { 620 view.findViewById(R.id.open_context_menu_id).setVisibility(View.GONE); 621 ImageView iv = (ImageView) view.findViewById( 622 R.id.new_window_context_menu_id); 623 iv.setImageResource(R.drawable.ic_windows_holo_dark); 624 } 625 return view; 626 } 627 628 @Override 629 public void actionItemClicked(View v, BookmarkDragState state) { 630 if (v.getId() == R.id.info) { 631 mGrid.showContextMenuForState(state); 632 } else { 633 ExtraDragState extraState = (ExtraDragState) state.extraState; 634 handleContextItem(v.getId(), extraState.groupPosition, 635 extraState.childPosition); 636 } 637 } 638 }; 639 640 private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> { 641 Context mContext; 642 BookmarkItem mHeader; 643 644 public LookupBookmarkCount(Context context, BookmarkItem header) { 645 mContext = context.getApplicationContext(); 646 mHeader = header; 647 } 648 649 @Override 650 protected Integer doInBackground(Long... params) { 651 if (params.length != 1) { 652 throw new IllegalArgumentException("Missing folder id!"); 653 } 654 Uri uri = BookmarkUtils.getBookmarksUri(mContext); 655 Cursor c = mContext.getContentResolver().query(uri, 656 null, BrowserContract.Bookmarks.PARENT + "=?", 657 new String[] {params[0].toString()}, null); 658 return c.getCount(); 659 } 660 661 @Override 662 protected void onPostExecute(Integer result) { 663 if (result > 0) { 664 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_bookmarkcount, 665 result)); 666 } else if (result == 0) { 667 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_empty)); 668 } 669 } 670 } 671 672 static class AccountsLoader extends CursorLoader { 673 674 static String[] ACCOUNTS_PROJECTION = new String[] { 675 Accounts.ACCOUNT_NAME, 676 Accounts.ACCOUNT_TYPE 677 }; 678 679 public AccountsLoader(Context context) { 680 super(context, Accounts.CONTENT_URI 681 .buildUpon() 682 .appendQueryParameter(BrowserProvider2.PARAM_ALLOW_EMPTY_ACCOUNTS, "false") 683 .build(), 684 ACCOUNTS_PROJECTION, null, null, null); 685 } 686 687 } 688} 689