blob: 522d37e404f265ed774a1982488700db6e4963b9 [file] [log] [blame]
The Android Open Source Project0c908882009-03-03 19:32:16 -08001/*
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;
Jeff Hamilton64144e42010-08-18 16:31:59 -050021import android.app.Fragment;
Jeff Hamilton84029622010-08-05 14:29:28 -050022import android.app.LoaderManager;
Dianne Hackborneb07b172010-08-26 22:18:14 -070023import android.content.ClipData;
Michael Kolbbef7a752010-08-25 17:11:35 -070024import android.content.ClipboardManager;
Jeff Hamilton1a805652010-09-07 12:36:30 -070025import android.content.ContentResolver;
Jeff Hamilton84029622010-08-05 14:29:28 -050026import android.content.ContentUris;
27import android.content.ContentValues;
Dianne Hackborn80f32622010-08-05 14:17:53 -070028import android.content.Context;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050029import android.content.CursorLoader;
The Android Open Source Project0c908882009-03-03 19:32:16 -080030import android.content.DialogInterface;
31import android.content.Intent;
Jeff Hamilton84029622010-08-05 14:29:28 -050032import android.content.Loader;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050033import android.content.SharedPreferences;
Jeff Hamilton84029622010-08-05 14:29:28 -050034import android.database.Cursor;
The Android Open Source Project0c908882009-03-03 19:32:16 -080035import android.graphics.Bitmap;
Jeff Hamilton84029622010-08-05 14:29:28 -050036import android.graphics.BitmapFactory;
37import android.net.Uri;
The Android Open Source Project0c908882009-03-03 19:32:16 -080038import android.os.Bundle;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050039import android.preference.PreferenceManager;
Jeff Hamilton69bd7072010-08-17 12:38:22 -050040import android.provider.BrowserContract;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050041import android.provider.BrowserContract.Accounts;
42import android.text.TextUtils;
The Android Open Source Project0c908882009-03-03 19:32:16 -080043import android.view.ContextMenu;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050044import android.view.ContextMenu.ContextMenuInfo;
Jeff Hamilton64144e42010-08-18 16:31:59 -050045import android.view.LayoutInflater;
The Android Open Source Project0c908882009-03-03 19:32:16 -080046import android.view.MenuInflater;
47import android.view.MenuItem;
48import android.view.View;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050049import android.view.ViewGroup;
Patrick Scottc1cf63a2010-03-09 16:02:08 -050050import android.webkit.WebIconDatabase.IconListener;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050051import android.widget.Adapter;
The Android Open Source Project0c908882009-03-03 19:32:16 -080052import android.widget.AdapterView;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050053import android.widget.AdapterView.OnItemClickListener;
54import android.widget.AdapterView.OnItemSelectedListener;
Jeff Hamilton84029622010-08-05 14:29:28 -050055import android.widget.GridView;
56import android.widget.Toast;
The Android Open Source Project0c908882009-03-03 19:32:16 -080057
58/**
59 * View showing the user's bookmarks in the browser.
60 */
Jeff Hamilton64144e42010-08-18 16:31:59 -050061public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
Michael Kolb370a4f32010-10-06 10:45:32 -070062 LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener,
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050063 OnItemSelectedListener {
The Android Open Source Project0c908882009-03-03 19:32:16 -080064
Jeff Hamilton84029622010-08-05 14:29:28 -050065 static final int BOOKMARKS_SAVE = 1;
66 static final String LOGTAG = "browser";
Nicolas Catania095292f2010-03-15 09:00:14 -070067
Jeff Hamilton84029622010-08-05 14:29:28 -050068 static final int LOADER_BOOKMARKS = 1;
Jeff Hamiltona9bad832010-09-24 11:05:30 -050069 static final int LOADER_ACCOUNTS_THEN_BOOKMARKS = 2;
Jeff Hamilton84029622010-08-05 14:29:28 -050070
Michael Kolb801ecb72010-08-25 12:57:38 -070071 static final String EXTRA_SHORTCUT = "create_shortcut";
72 static final String EXTRA_DISABLE_WINDOW = "disable_new_window";
73
Jeff Hamilton70c77692010-09-21 19:11:24 -050074 static final String ACCOUNT_NAME_UNSYNCED = "Unsynced";
Michael Kolbe421c242010-10-04 19:29:01 -070075
Jeff Hamilton7f6cf3e2010-09-17 17:22:21 -050076 public static final String PREF_ACCOUNT_TYPE = "acct_type";
77 public static final String PREF_ACCOUNT_NAME = "acct_name";
Jeff Hamiltondb90aa82010-09-16 03:38:04 -050078
79 static final String DEFAULT_ACCOUNT = "local";
80
Jeff Hamilton64144e42010-08-18 16:31:59 -050081 BookmarksHistoryCallbacks mCallbacks;
Jeff Hamilton84029622010-08-05 14:29:28 -050082 GridView mGrid;
83 BrowserBookmarksAdapter mAdapter;
84 boolean mDisableNewWindow;
85 BookmarkItem mContextHeader;
86 boolean mCanceled = false;
87 boolean mCreateShortcut;
88 View mEmptyView;
Jeff Hamilton84029622010-08-05 14:29:28 -050089
Michael Kolb370a4f32010-10-06 10:45:32 -070090 BreadCrumbView mCrumbs;
91
92 static BrowserBookmarksPage newInstance(BookmarksHistoryCallbacks cb,
93 BreadCrumbView crumbs, Bundle args) {
Michael Kolbe421c242010-10-04 19:29:01 -070094 BrowserBookmarksPage bbp = new BrowserBookmarksPage();
95 bbp.mCallbacks = cb;
96 bbp.setArguments(args);
Michael Kolb370a4f32010-10-06 10:45:32 -070097 bbp.mCrumbs = crumbs;
Michael Kolbe421c242010-10-04 19:29:01 -070098 return bbp;
99 }
100
Jeff Hamilton84029622010-08-05 14:29:28 -0500101 @Override
102 public Loader<Cursor> onCreateLoader(int id, Bundle args) {
103 switch (id) {
104 case LOADER_BOOKMARKS: {
Jeff Hamilton1a805652010-09-07 12:36:30 -0700105 String accountType = null;
106 String accountName = null;
Jeff Hamilton84029622010-08-05 14:29:28 -0500107 if (args != null) {
Jeff Hamilton1a805652010-09-07 12:36:30 -0700108 accountType = args.getString(BookmarksLoader.ARG_ACCOUNT_TYPE);
109 accountName = args.getString(BookmarksLoader.ARG_ACCOUNT_NAME);
Jeff Hamilton84029622010-08-05 14:29:28 -0500110 }
Michael Kolb370a4f32010-10-06 10:45:32 -0700111 BookmarksLoader bl = new BookmarksLoader(getActivity(), accountType, accountName);
112 if (mCrumbs != null) {
113 Uri uri = (Uri) mCrumbs.getTopData();
114 if (uri != null) {
115 bl.setUri(uri);
116 }
117 }
118 return bl;
Jeff Hamilton84029622010-08-05 14:29:28 -0500119 }
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500120 case LOADER_ACCOUNTS_THEN_BOOKMARKS: {
121 return new CursorLoader(getActivity(), Accounts.CONTENT_URI,
122 new String[] { Accounts.ACCOUNT_TYPE, Accounts.ACCOUNT_NAME }, null, null,
123 null);
124 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500125 }
126 throw new UnsupportedOperationException("Unknown loader id " + id);
127 }
128
129 @Override
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500130 public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
131 switch (loader.getId()) {
132 case LOADER_BOOKMARKS: {
133 // Set the visibility of the empty vs. content views
134 if (cursor == null || cursor.getCount() == 0) {
135 mEmptyView.setVisibility(View.VISIBLE);
136 mGrid.setVisibility(View.GONE);
137 } else {
138 mEmptyView.setVisibility(View.GONE);
139 mGrid.setVisibility(View.VISIBLE);
140 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500141
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500142 // Give the new data to the adapter
143 mAdapter.changeCursor(cursor);
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500144 break;
145 }
146
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500147 case LOADER_ACCOUNTS_THEN_BOOKMARKS: {
148 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
149 getActivity());
150 String storedAccountType = prefs.getString(PREF_ACCOUNT_TYPE, null);
151 String storedAccountName = prefs.getString(PREF_ACCOUNT_NAME, null);
152 String accountType =
153 TextUtils.isEmpty(storedAccountType) ? DEFAULT_ACCOUNT : storedAccountType;
154 String accountName =
155 TextUtils.isEmpty(storedAccountName) ? DEFAULT_ACCOUNT : storedAccountName;
156
157 Bundle args = null;
158 if (cursor == null || !cursor.moveToFirst()) {
159 // No accounts, set the prefs to the default
160 accountType = DEFAULT_ACCOUNT;
161 accountName = DEFAULT_ACCOUNT;
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500162 } else {
163 int accountPosition = -1;
164
165 if (!DEFAULT_ACCOUNT.equals(accountType) &&
166 !DEFAULT_ACCOUNT.equals(accountName)) {
167 // Check to see if the account in prefs still exists
168 cursor.moveToFirst();
169 do {
170 if (accountType.equals(cursor.getString(0))
171 && accountName.equals(cursor.getString(1))) {
172 accountPosition = cursor.getPosition();
173 break;
174 }
175 } while (cursor.moveToNext());
176 }
177
178 if (accountPosition == -1) {
Jeff Hamiltona9bad832010-09-24 11:05:30 -0500179 if (!(DEFAULT_ACCOUNT.equals(accountType)
Jeff Hamilton70c77692010-09-21 19:11:24 -0500180 && DEFAULT_ACCOUNT.equals(accountName))) {
Jeff Hamilton70c77692010-09-21 19:11:24 -0500181 // No account is set in prefs and there is at least one,
182 // so pick the first one as the default
183 cursor.moveToFirst();
184 accountType = cursor.getString(0);
185 accountName = cursor.getString(1);
Jeff Hamilton70c77692010-09-21 19:11:24 -0500186 }
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500187 }
188
189 args = new Bundle();
190 args.putString(BookmarksLoader.ARG_ACCOUNT_TYPE, accountType);
191 args.putString(BookmarksLoader.ARG_ACCOUNT_NAME, accountName);
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500192 }
Jeff Hamiltona9bad832010-09-24 11:05:30 -0500193
194 // The stored account name wasn't found, update the stored account with a valid one
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500195 if (!accountType.equals(storedAccountType)
196 || !accountName.equals(storedAccountName)) {
197 prefs.edit()
198 .putString(PREF_ACCOUNT_TYPE, accountType)
199 .putString(PREF_ACCOUNT_NAME, accountName)
200 .apply();
201 }
Jeff Hamiltona9bad832010-09-24 11:05:30 -0500202 getLoaderManager().initLoader(LOADER_BOOKMARKS, args, this);
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500203
204 break;
205 }
206 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500207 }
208
Michael Kolb370a4f32010-10-06 10:45:32 -0700209 long getFolderId() {
210 LoaderManager manager = getLoaderManager();
211 BookmarksLoader loader =
212 (BookmarksLoader) ((Loader)(manager.getLoader(LOADER_BOOKMARKS)));
213
214 Uri uri = loader.getUri();
215 if (uri != null) {
216 try {
217 return ContentUris.parseId(uri);
218 } catch (NumberFormatException nfx) {
219 return -1;
220 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500221 }
Michael Kolb370a4f32010-10-06 10:45:32 -0700222 return -1;
223 }
224
225 public void onFolderChange(int level, Object data) {
226 Uri uri = (Uri) data;
227 if (uri == null) {
228 // top level
229 uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER;
230 }
231 LoaderManager manager = getLoaderManager();
232 BookmarksLoader loader =
233 (BookmarksLoader) ((Loader) manager.getLoader(LOADER_BOOKMARKS));
234 loader.setUri(uri);
235 loader.forceLoad();
236
Jeff Hamilton84029622010-08-05 14:29:28 -0500237 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800238
239 @Override
240 public boolean onContextItemSelected(MenuItem item) {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500241 final Activity activity = getActivity();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800242 // It is possible that the view has been canceled when we get to
Nicolas Catania095292f2010-03-15 09:00:14 -0700243 // this point as back has a higher priority
The Android Open Source Project0c908882009-03-03 19:32:16 -0800244 if (mCanceled) {
245 return true;
246 }
Nicolas Catania095292f2010-03-15 09:00:14 -0700247 AdapterView.AdapterContextMenuInfo i =
The Android Open Source Project0c908882009-03-03 19:32:16 -0800248 (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
249 // If we have no menu info, we can't tell which item was selected.
250 if (i == null) {
251 return true;
252 }
Nicolas Catania095292f2010-03-15 09:00:14 -0700253
The Android Open Source Project0c908882009-03-03 19:32:16 -0800254 switch (item.getItemId()) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800255 case R.id.open_context_menu_id:
256 loadUrl(i.position);
257 break;
258 case R.id.edit_context_menu_id:
259 editBookmark(i.position);
260 break;
261 case R.id.shortcut_context_menu_id:
Jeff Hamilton64144e42010-08-18 16:31:59 -0500262 activity.sendBroadcast(createShortcutIntent(i.position));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800263 break;
264 case R.id.delete_context_menu_id:
Jeff Hamilton84029622010-08-05 14:29:28 -0500265 displayRemoveBookmarkDialog(i.position);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800266 break;
267 case R.id.new_window_context_menu_id:
268 openInNewWindow(i.position);
269 break;
Jeff Hamilton84029622010-08-05 14:29:28 -0500270 case R.id.share_link_context_menu_id: {
271 Cursor cursor = (Cursor) mAdapter.getItem(i.position);
Jeff Hamilton64144e42010-08-18 16:31:59 -0500272 BrowserActivity.sharePage(activity,
Jeff Hamilton84029622010-08-05 14:29:28 -0500273 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE),
274 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL),
275 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON),
276 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_THUMBNAIL));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800277 break;
Jeff Hamilton84029622010-08-05 14:29:28 -0500278 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800279 case R.id.copy_url_context_menu_id:
280 copy(getUrl(i.position));
Leon Scrogginsfeb941d2009-05-28 17:27:38 -0400281 break;
Jeff Hamilton84029622010-08-05 14:29:28 -0500282 case R.id.homepage_context_menu_id: {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500283 BrowserSettings.getInstance().setHomePage(activity, getUrl(i.position));
284 Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
Leon Scrogginsfeb941d2009-05-28 17:27:38 -0400285 break;
Jeff Hamilton84029622010-08-05 14:29:28 -0500286 }
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400287 // Only for the Most visited page
Jeff Hamilton84029622010-08-05 14:29:28 -0500288 case R.id.save_to_bookmarks_menu_id: {
289 Cursor cursor = (Cursor) mAdapter.getItem(i.position);
290 String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
291 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400292 // If the site is bookmarked, the item becomes remove from
293 // bookmarks.
Jeff Hamilton64144e42010-08-18 16:31:59 -0500294 Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name);
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400295 break;
Jeff Hamilton84029622010-08-05 14:29:28 -0500296 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800297 default:
298 return super.onContextItemSelected(item);
299 }
300 return true;
301 }
302
Jeff Hamilton84029622010-08-05 14:29:28 -0500303 Bitmap getBitmap(Cursor cursor, int columnIndex) {
304 byte[] data = cursor.getBlob(columnIndex);
305 if (data == null) {
306 return null;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800307 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500308 return BitmapFactory.decodeByteArray(data, 0, data.length);
309 }
310
311 @Override
312 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
313 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
Leon Scroggins5e8a40f2010-09-27 17:13:35 -0400314 Cursor cursor = (Cursor) mAdapter.getItem(info.position);
315 boolean isFolder
316 = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
317 if (isFolder) return;
Michael Kolb801ecb72010-08-25 12:57:38 -0700318
Jeff Hamilton64144e42010-08-18 16:31:59 -0500319 final Activity activity = getActivity();
320 MenuInflater inflater = activity.getMenuInflater();
Jeff Hamilton84029622010-08-05 14:29:28 -0500321 inflater.inflate(R.menu.bookmarkscontext, menu);
322
323 if (mDisableNewWindow) {
324 menu.findItem(R.id.new_window_context_menu_id).setVisible(false);
325 }
326
327 if (mContextHeader == null) {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500328 mContextHeader = new BookmarkItem(activity);
Jeff Hamilton84029622010-08-05 14:29:28 -0500329 } else if (mContextHeader.getParent() != null) {
330 ((ViewGroup) mContextHeader.getParent()).removeView(mContextHeader);
331 }
332
Leon Scroggins5e8a40f2010-09-27 17:13:35 -0400333 populateBookmarkItem(cursor, mContextHeader);
Jeff Hamilton84029622010-08-05 14:29:28 -0500334
335 menu.setHeaderView(mContextHeader);
336 }
337
Leon Scroggins5e8a40f2010-09-27 17:13:35 -0400338 private void populateBookmarkItem(Cursor cursor, BookmarkItem item) {
Jeff Hamilton84029622010-08-05 14:29:28 -0500339 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
340 item.setUrl(url);
341 item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
342 Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
343 if (bitmap == null) {
Michael Kolbe421c242010-10-04 19:29:01 -0700344 bitmap = CombinedBookmarkHistoryView.getIconListenerSet().getFavicon(url);
Jeff Hamilton84029622010-08-05 14:29:28 -0500345 }
346 item.setFavicon(bitmap);
347 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800348
349 /**
350 * Create a new BrowserBookmarksPage.
Nicolas Catania095292f2010-03-15 09:00:14 -0700351 */
The Android Open Source Project0c908882009-03-03 19:32:16 -0800352 @Override
Jeff Hamilton64144e42010-08-18 16:31:59 -0500353 public void onCreate(Bundle icicle) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800354 super.onCreate(icicle);
355
Jeff Hamilton64144e42010-08-18 16:31:59 -0500356 Bundle args = getArguments();
357 mCreateShortcut = args == null ? false : args.getBoolean("create_shortcut", false);
358 mDisableNewWindow = args == null ? false : args.getBoolean("disable_new_window", false);
359 }
Leon Scrogginsd87f85e2009-08-18 14:13:31 -0400360
Jeff Hamilton64144e42010-08-18 16:31:59 -0500361 @Override
Jeff Hamilton64144e42010-08-18 16:31:59 -0500362 public View onCreateView(LayoutInflater inflater, ViewGroup container,
363 Bundle savedInstanceState) {
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500364 Context context = getActivity();
365
Jeff Hamilton64144e42010-08-18 16:31:59 -0500366 View root = inflater.inflate(R.layout.bookmarks, container, false);
367 mEmptyView = root.findViewById(android.R.id.empty);
Leon Scrogginsd87f85e2009-08-18 14:13:31 -0400368
Jeff Hamilton64144e42010-08-18 16:31:59 -0500369 mGrid = (GridView) root.findViewById(R.id.grid);
Jeff Hamilton84029622010-08-05 14:29:28 -0500370 mGrid.setOnItemClickListener(this);
Jeff Hamilton64144e42010-08-18 16:31:59 -0500371 mGrid.setColumnWidth(BrowserActivity.getDesiredThumbnailWidth(getActivity()));
Jeff Hamilton84029622010-08-05 14:29:28 -0500372 if (!mCreateShortcut) {
373 mGrid.setOnCreateContextMenuListener(this);
Ben Murdoch328ea872009-09-16 13:33:29 +0100374 }
Patrick Scottf49ecd62010-04-09 12:43:26 -0400375
Jeff Hamilton64144e42010-08-18 16:31:59 -0500376 mAdapter = new BrowserBookmarksAdapter(getActivity());
Jeff Hamilton84029622010-08-05 14:29:28 -0500377 mGrid.setAdapter(mAdapter);
378
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500379 // Start the loaders
380 LoaderManager lm = getLoaderManager();
381 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
Jeff Hamiltona9bad832010-09-24 11:05:30 -0500382 String accountType = prefs.getString(PREF_ACCOUNT_TYPE, DEFAULT_ACCOUNT);
383 String accountName = prefs.getString(PREF_ACCOUNT_NAME, DEFAULT_ACCOUNT);
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500384 if (!TextUtils.isEmpty(accountType) && !TextUtils.isEmpty(accountName)) {
385 // There is an account set, load up that one
386 Bundle args = null;
387 if (!DEFAULT_ACCOUNT.equals(accountType) && !DEFAULT_ACCOUNT.equals(accountName)) {
388 args = new Bundle();
389 args.putString(BookmarksLoader.ARG_ACCOUNT_TYPE, accountType);
390 args.putString(BookmarksLoader.ARG_ACCOUNT_NAME, accountName);
391 }
Jeff Hamilton70c77692010-09-21 19:11:24 -0500392 lm.restartLoader(LOADER_BOOKMARKS, args, this);
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500393 } else {
Jeff Hamiltona9bad832010-09-24 11:05:30 -0500394 // No account set, load the account list first
Jeff Hamilton70c77692010-09-21 19:11:24 -0500395 lm.restartLoader(LOADER_ACCOUNTS_THEN_BOOKMARKS, null, this);
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500396 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500397
398 // Add our own listener in case there are favicons that have yet to be loaded.
Michael Kolbe421c242010-10-04 19:29:01 -0700399 CombinedBookmarkHistoryView.getIconListenerSet().addListener(this);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800400
Jeff Hamilton64144e42010-08-18 16:31:59 -0500401 return root;
402 }
Michael Kolb801ecb72010-08-25 12:57:38 -0700403
Nicolas Catania095292f2010-03-15 09:00:14 -0700404 @Override
Jeff Hamilton84029622010-08-05 14:29:28 -0500405 public void onReceivedIcon(String url, Bitmap icon) {
406 // A new favicon has been loaded, so let anything attached to the adapter know about it
407 // so new icons will be loaded.
408 mAdapter.notifyDataSetChanged();
Nicolas Catania095292f2010-03-15 09:00:14 -0700409 }
410
Jeff Hamilton84029622010-08-05 14:29:28 -0500411 @Override
412 public void onItemClick(AdapterView parent, View v, int position, long id) {
413 // It is possible that the view has been canceled when we get to
414 // this point as back has a higher priority
415 if (mCanceled) {
416 android.util.Log.e(LOGTAG, "item clicked when dismissing");
417 return;
418 }
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500419
Jeff Hamilton84029622010-08-05 14:29:28 -0500420 if (mCreateShortcut) {
Michael Kolb801ecb72010-08-25 12:57:38 -0700421 Intent intent = createShortcutIntent(position);
422 // the activity handles the intent in startActivityFromFragment
423 startActivity(intent);
Ben Murdoch328ea872009-09-16 13:33:29 +0100424 return;
425 }
426
Jeff Hamilton84029622010-08-05 14:29:28 -0500427 Cursor cursor = (Cursor) mAdapter.getItem(position);
428 boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
429 if (!isFolder) {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500430 mCallbacks.onUrlSelected(getUrl(position), false);
Leon Scroggins892df312009-07-14 14:48:02 -0400431 } else {
Michael Kolb370a4f32010-10-06 10:45:32 -0700432 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
Jeff Hamilton84029622010-08-05 14:29:28 -0500433 LoaderManager manager = getLoaderManager();
Michael Kolb801ecb72010-08-25 12:57:38 -0700434 BookmarksLoader loader =
Jeff Hamilton84029622010-08-05 14:29:28 -0500435 (BookmarksLoader) ((Loader) manager.getLoader(LOADER_BOOKMARKS));
Jeff Hamilton84029622010-08-05 14:29:28 -0500436 Uri uri = ContentUris.withAppendedId(
437 BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id);
Michael Kolb370a4f32010-10-06 10:45:32 -0700438 if (mCrumbs != null) {
439 // update crumbs
440 mCrumbs.pushView(title, uri);
441 }
Jeff Hamilton84029622010-08-05 14:29:28 -0500442 loader.setUri(uri);
443 loader.forceLoad();
Leon Scrogginsa5d669e2009-08-05 14:07:58 -0400444 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800445 }
446
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500447 @Override
448 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
449 Adapter adapter = parent.getAdapter();
450 String accountType = "com.google";
451 String accountName = adapter.getItem(position).toString();
452
Jeff Hamilton70c77692010-09-21 19:11:24 -0500453 Bundle args = null;
454 if (ACCOUNT_NAME_UNSYNCED.equals(accountName)) {
455 accountType = DEFAULT_ACCOUNT;
456 accountName = DEFAULT_ACCOUNT;
457 } else {
458 args = new Bundle();
459 args.putString(BookmarksLoader.ARG_ACCOUNT_TYPE, accountType);
460 args.putString(BookmarksLoader.ARG_ACCOUNT_NAME, accountName);
461 }
462
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500463 // Remember the selection for later
464 PreferenceManager.getDefaultSharedPreferences(getActivity()).edit()
465 .putString(PREF_ACCOUNT_TYPE, accountType)
466 .putString(PREF_ACCOUNT_NAME, accountName)
467 .apply();
468
Jeff Hamiltondb90aa82010-09-16 03:38:04 -0500469 getLoaderManager().restartLoader(LOADER_BOOKMARKS, args, this);
470 }
471
472 @Override
473 public void onNothingSelected(AdapterView<?> parent) {
474 // Do nothing
475 }
476
Patrick Scott3918d442009-08-04 13:22:29 -0400477 private Intent createShortcutIntent(int position) {
Jeff Hamilton84029622010-08-05 14:29:28 -0500478 Cursor cursor = (Cursor) mAdapter.getItem(position);
479 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
Michael Kolbccaa8962010-10-20 17:03:10 -0700480 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
Jeff Hamilton84029622010-08-05 14:29:28 -0500481 Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON);
482 Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
Jeff Hamilton64144e42010-08-18 16:31:59 -0500483 return BookmarkUtils.createAddToHomeIntent(getActivity(), url, title, touchIcon, favicon);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800484 }
485
The Android Open Source Project0c908882009-03-03 19:32:16 -0800486 private void loadUrl(int position) {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500487 mCallbacks.onUrlSelected(getUrl(position), false);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800488 }
489
The Android Open Source Project0c908882009-03-03 19:32:16 -0800490 private void openInNewWindow(int position) {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500491 mCallbacks.onUrlSelected(getUrl(position), true);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800492 }
Nicolas Catania095292f2010-03-15 09:00:14 -0700493
The Android Open Source Project0c908882009-03-03 19:32:16 -0800494 private void editBookmark(int position) {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500495 Intent intent = new Intent(getActivity(), AddBookmarkPage.class);
Jeff Hamilton84029622010-08-05 14:29:28 -0500496 Cursor cursor = (Cursor) mAdapter.getItem(position);
497 Bundle item = new Bundle();
Michael Kolbbef7a752010-08-25 17:11:35 -0700498 item.putString(BrowserContract.Bookmarks.TITLE,
Jeff Hamilton84029622010-08-05 14:29:28 -0500499 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
Michael Kolbbef7a752010-08-25 17:11:35 -0700500 item.putString(BrowserContract.Bookmarks.URL,
Jeff Hamilton84029622010-08-05 14:29:28 -0500501 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL));
502 byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON);
503 if (data != null) {
Michael Kolbbef7a752010-08-25 17:11:35 -0700504 item.putParcelable(BrowserContract.Bookmarks.FAVICON,
Jeff Hamilton84029622010-08-05 14:29:28 -0500505 BitmapFactory.decodeByteArray(data, 0, data.length));
506 }
507 item.putInt("id", cursor.getInt(BookmarksLoader.COLUMN_INDEX_ID));
Leon Scroggins III052ce662010-09-13 14:44:16 -0400508 item.putLong(BrowserContract.Bookmarks.PARENT,
509 cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT));
Jeff Hamilton84029622010-08-05 14:29:28 -0500510 intent.putExtra("bookmark", item);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800511 startActivityForResult(intent, BOOKMARKS_SAVE);
512 }
513
514 @Override
Jeff Hamilton64144e42010-08-18 16:31:59 -0500515 public void onActivityResult(int requestCode, int resultCode, Intent data) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800516 switch(requestCode) {
517 case BOOKMARKS_SAVE:
Jeff Hamilton64144e42010-08-18 16:31:59 -0500518 if (resultCode == Activity.RESULT_OK) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800519 Bundle extras;
520 if (data != null && (extras = data.getExtras()) != null) {
521 // If there are extras, then we need to save
522 // the edited bookmark. This is done in updateRow()
523 String title = extras.getString("title");
524 String url = extras.getString("url");
525 if (title != null && url != null) {
Jeff Hamilton84029622010-08-05 14:29:28 -0500526 updateRow(extras);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800527 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800528 }
529 }
530 break;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800531 }
532 }
Nicolas Catania095292f2010-03-15 09:00:14 -0700533
Jeff Hamilton84029622010-08-05 14:29:28 -0500534 /**
Michael Kolb801ecb72010-08-25 12:57:38 -0700535 * Update a row in the database with new information.
Jeff Hamilton84029622010-08-05 14:29:28 -0500536 * @param map Bundle storing id, title and url of new information
537 */
538 public void updateRow(Bundle map) {
539
540 // Find the record
Michael Kolbbef7a752010-08-25 17:11:35 -0700541 int id = map.getInt("id");
Jeff Hamilton84029622010-08-05 14:29:28 -0500542 int position = -1;
543 Cursor cursor = mAdapter.getCursor();
544 for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
545 if (cursor.getInt(BookmarksLoader.COLUMN_INDEX_ID) == id) {
546 position = cursor.getPosition();
547 break;
548 }
549 }
550 if (position < 0) {
551 return;
552 }
553
554 cursor.moveToPosition(position);
555 ContentValues values = new ContentValues();
Michael Kolbbef7a752010-08-25 17:11:35 -0700556 String title = map.getString(BrowserContract.Bookmarks.TITLE);
557 if (!title.equals(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE))) {
558 values.put(BrowserContract.Bookmarks.TITLE, title);
Jeff Hamilton84029622010-08-05 14:29:28 -0500559 }
Michael Kolbbef7a752010-08-25 17:11:35 -0700560 String url = map.getString(BrowserContract.Bookmarks.URL);
561 if (!url.equals(cursor.getString(BookmarksLoader.COLUMN_INDEX_URL))) {
562 values.put(BrowserContract.Bookmarks.URL, url);
Jeff Hamilton84029622010-08-05 14:29:28 -0500563 }
564
565 if (map.getBoolean("invalidateThumbnail") == true) {
Michael Kolbbef7a752010-08-25 17:11:35 -0700566 values.putNull(BrowserContract.Bookmarks.THUMBNAIL);
Jeff Hamilton84029622010-08-05 14:29:28 -0500567 }
568
569 if (values.size() > 0) {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500570 getActivity().getContentResolver().update(
Jeff Hamilton8ce956c2010-08-17 11:13:53 -0500571 ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id),
572 values, null, null);
Jeff Hamilton84029622010-08-05 14:29:28 -0500573 }
574 }
575
576 private void displayRemoveBookmarkDialog(final int position) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800577 // Put up a dialog asking if the user really wants to
578 // delete the bookmark
Jeff Hamilton84029622010-08-05 14:29:28 -0500579 Cursor cursor = (Cursor) mAdapter.getItem(position);
Jeff Hamilton64144e42010-08-18 16:31:59 -0500580 Context context = getActivity();
Jeff Hamilton1a805652010-09-07 12:36:30 -0700581 final ContentResolver resolver = context.getContentResolver();
582 final Uri uri = ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI,
583 cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
584
Jeff Hamilton64144e42010-08-18 16:31:59 -0500585 new AlertDialog.Builder(context)
The Android Open Source Project0c908882009-03-03 19:32:16 -0800586 .setTitle(R.string.delete_bookmark)
587 .setIcon(android.R.drawable.ic_dialog_alert)
Jeff Hamilton1a805652010-09-07 12:36:30 -0700588 .setMessage(context.getString(R.string.delete_bookmark_warning,
589 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)))
Nicolas Catania095292f2010-03-15 09:00:14 -0700590 .setPositiveButton(R.string.ok,
The Android Open Source Project0c908882009-03-03 19:32:16 -0800591 new DialogInterface.OnClickListener() {
Jeff Hamiltona9bad832010-09-24 11:05:30 -0500592 @Override
The Android Open Source Project0c908882009-03-03 19:32:16 -0800593 public void onClick(DialogInterface dialog, int whichButton) {
Jeff Hamilton1a805652010-09-07 12:36:30 -0700594 resolver.delete(uri, null, null);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800595 }
596 })
597 .setNegativeButton(R.string.cancel, null)
598 .show();
599 }
600
Jeff Hamilton84029622010-08-05 14:29:28 -0500601 private String getUrl(int position) {
602 Cursor cursor = (Cursor) mAdapter.getItem(position);
603 return cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800604 }
Michael Kolb801ecb72010-08-25 12:57:38 -0700605
The Android Open Source Project0c908882009-03-03 19:32:16 -0800606 private void copy(CharSequence text) {
Jeff Hamilton64144e42010-08-18 16:31:59 -0500607 ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(
608 Context.CLIPBOARD_SERVICE);
Dianne Hackborneb07b172010-08-26 22:18:14 -0700609 cm.setPrimaryClip(ClipData.newRawUri(null, null, Uri.parse(text.toString())));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800610 }
Michael Kolb370a4f32010-10-06 10:45:32 -0700611
The Android Open Source Project0c908882009-03-03 19:32:16 -0800612}