blob: f938ff9a2a33440245bb1bd69b28b6552a771df4 [file] [log] [blame]
The Android Open Source Projectba6d7b82008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.browser;
18
19import android.app.Activity;
20import android.app.AlertDialog;
21import android.content.DialogInterface;
22import android.content.Intent;
23import android.net.Uri;
24import android.os.Bundle;
25import android.os.Handler;
26import android.os.Message;
27import android.os.ServiceManager;
28import android.provider.Browser;
29import android.text.IClipboard;
30import android.util.Log;
31import android.view.ContextMenu;
32import android.view.KeyEvent;
33import android.view.Menu;
34import android.view.MenuInflater;
35import android.view.MenuItem;
36import android.view.View;
37import android.view.ViewGroup;
38import android.view.ContextMenu.ContextMenuInfo;
39import android.widget.AdapterView;
40import android.widget.ListView;
41
42/**
43 * View showing the user's bookmarks in the browser.
44 */
45public class BrowserBookmarksPage extends Activity implements
46 View.OnCreateContextMenuListener {
47
48 private BrowserBookmarksAdapter mBookmarksAdapter;
49 private static final int BOOKMARKS_SAVE = 1;
50 private boolean mMaxTabsOpen;
51 private BookmarkItem mContextHeader;
52 private AddNewBookmark mAddHeader;
53 private boolean mCanceled = false;
54 private boolean mCreateShortcut;
55
56 private final static String LOGTAG = "browser";
57
58
59 @Override
60 public boolean onContextItemSelected(MenuItem item) {
61 // It is possible that the view has been canceled when we get to
62 // this point as back has a higher priority
63 if (mCanceled) {
64 return true;
65 }
66 AdapterView.AdapterContextMenuInfo i =
67 (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
68 // If we have no menu info, we can't tell which item was selected.
69 if (i == null) {
70 return true;
71 }
72
73 switch (item.getItemId()) {
74 case R.id.new_context_menu_id:
75 saveCurrentPage();
76 break;
77 case R.id.open_context_menu_id:
78 loadUrl(i.position);
79 break;
80 case R.id.edit_context_menu_id:
81 editBookmark(i.position);
82 break;
83 case R.id.delete_context_menu_id:
84 displayRemoveBookmarkDialog(i.position);
85 break;
86 case R.id.new_window_context_menu_id:
87 openInNewWindow(i.position);
88 break;
89 case R.id.send_context_menu_id:
90 Browser.sendString(BrowserBookmarksPage.this, getUrl(i.position));
91 break;
92 case R.id.copy_url_context_menu_id:
93 copy(getUrl(i.position));
94
95 default:
96 return super.onContextItemSelected(item);
97 }
98 return true;
99 }
100
101 @Override
102 public void onCreateContextMenu(ContextMenu menu, View v,
103 ContextMenuInfo menuInfo) {
104 AdapterView.AdapterContextMenuInfo i =
105 (AdapterView.AdapterContextMenuInfo) menuInfo;
106
107 MenuInflater inflater = getMenuInflater();
108 inflater.inflate(R.menu.bookmarkscontext, menu);
109
110 if (0 == i.position) {
111 menu.setGroupVisible(R.id.CONTEXT_MENU, false);
112 if (mAddHeader == null) {
113 mAddHeader = new AddNewBookmark(BrowserBookmarksPage.this);
114 } else if (mAddHeader.getParent() != null) {
115 ((ViewGroup) mAddHeader.getParent()).
116 removeView(mAddHeader);
117 }
118 ((AddNewBookmark) i.targetView).copyTo(mAddHeader);
119 menu.setHeaderView(mAddHeader);
120 return;
121 }
122 menu.setGroupVisible(R.id.ADD_MENU, false);
123 BookmarkItem b = (BookmarkItem) i.targetView;
124 if (mContextHeader == null) {
125 mContextHeader = new BookmarkItem(BrowserBookmarksPage.this);
126 } else if (mContextHeader.getParent() != null) {
127 ((ViewGroup) mContextHeader.getParent()).
128 removeView(mContextHeader);
129 }
130 b.copyTo(mContextHeader);
131 menu.setHeaderView(mContextHeader);
132
133 if (mMaxTabsOpen) {
134 menu.findItem(R.id.new_window_context_menu_id).setVisible(
135 false);
136 }
137 }
138
139 /**
140 * Create a new BrowserBookmarksPage.
141 */
142 @Override
143 protected void onCreate(Bundle icicle) {
144 super.onCreate(icicle);
145
146 setContentView(R.layout.browser_bookmarks_page);
147 setTitle(R.string.browser_bookmarks_page_bookmarks_text);
148
149 if (Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction())) {
150 mCreateShortcut = true;
151 }
152
153 mBookmarksAdapter = new BrowserBookmarksAdapter(this,
154 getIntent().getStringExtra("title"), mCreateShortcut);
155 mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false);
156
157 ListView listView = (ListView) findViewById(R.id.list);
158 listView.setAdapter(mBookmarksAdapter);
159 listView.setDrawSelectorOnTop(false);
160 listView.setVerticalScrollBarEnabled(true);
161 listView.setOnItemClickListener(mListener);
162
163 if (!mCreateShortcut) {
164 listView.setOnCreateContextMenuListener(this);
165 }
166 }
167
168 private static final int SAVE_CURRENT_PAGE = 1000;
169 private final Handler mHandler = new Handler() {
170 @Override
171 public void handleMessage(Message msg) {
172 if (msg.what == SAVE_CURRENT_PAGE) {
173 saveCurrentPage();
174 }
175 }
176 };
177
178 private AdapterView.OnItemClickListener mListener = new AdapterView.OnItemClickListener() {
179 public void onItemClick(AdapterView parent, View v, int position, long id) {
180 // It is possible that the view has been canceled when we get to
181 // this point as back has a higher priority
182 if (mCanceled) {
183 android.util.Log.e("browser", "item clicked when dismising");
184 return;
185 }
186 if (!mCreateShortcut) {
187 if (0 == position) {
188 // XXX: Work-around for a framework issue.
189 mHandler.sendEmptyMessage(SAVE_CURRENT_PAGE);
190 } else {
191 loadUrl(position);
192 }
193 } else {
194 final Intent intent = new Intent();
195 intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_VIEW,
196 Uri.parse(getUrl(position))));
197 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getBookmarkTitle(position));
198 intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
199 Intent.ShortcutIconResource.fromContext(BrowserBookmarksPage.this,
200 R.drawable.ic_launcher_browser));
201 setResult(RESULT_OK, intent);
202 finish();
203 }
204 }
205 };
206
207 private void saveCurrentPage() {
208 Intent i = new Intent(BrowserBookmarksPage.this,
209 AddBookmarkPage.class);
210 i.putExtras(getIntent());
211 startActivityForResult(i, BOOKMARKS_SAVE);
212 }
213
214 private void loadUrl(int position) {
215 setResult(RESULT_OK, (new Intent()).setAction(getUrl(position)));
216 finish();
217 }
218
219 @Override
220 public boolean onCreateOptionsMenu(Menu menu) {
221 boolean result = super.onCreateOptionsMenu(menu);
222 if (!mCreateShortcut) {
223 MenuInflater inflater = getMenuInflater();
224 inflater.inflate(R.menu.bookmarks, menu);
225 return true;
226 }
227 return result;
228 }
229
230 @Override
231 public boolean onOptionsItemSelected(MenuItem item) {
232 switch (item.getItemId()) {
233 case R.id.new_context_menu_id:
234 saveCurrentPage();
235 break;
236
237 default:
238 return super.onOptionsItemSelected(item);
239 }
240 return true;
241 }
242
243 private void openInNewWindow(int position) {
244 Bundle b = new Bundle();
245 b.putBoolean("new_window", true);
246 setResult(RESULT_OK,
247 (new Intent()).setAction(getUrl(position)).putExtras(b));
248
249 finish();
250 }
251
252
253 private void editBookmark(int position) {
254 Intent intent = new Intent(BrowserBookmarksPage.this,
255 AddBookmarkPage.class);
256 intent.putExtra("bookmark", getRow(position));
257 startActivityForResult(intent, BOOKMARKS_SAVE);
258 }
259
260 @Override
261 protected void onActivityResult(int requestCode, int resultCode,
262 Intent data) {
263 switch(requestCode) {
264 case BOOKMARKS_SAVE:
265 if (resultCode == RESULT_OK) {
266 Bundle extras;
267 if (data != null && (extras = data.getExtras()) != null) {
268 // If there are extras, then we need to save
269 // the edited bookmark. This is done in updateRow()
270 String title = extras.getString("title");
271 String url = extras.getString("url");
272 if (title != null && url != null) {
273 mBookmarksAdapter.updateRow(extras);
274 }
275 } else {
276 // extras == null then a new bookmark was added to
277 // the database.
278 refreshList();
279 }
280 }
281 break;
282 default:
283 break;
284 }
285 }
286
287 private void displayRemoveBookmarkDialog(int position) {
288 // Put up a dialog asking if the user really wants to
289 // delete the bookmark
290 final int deletePos = position;
291 new AlertDialog.Builder(this)
292 .setTitle(R.string.delete_bookmark)
293 .setIcon(R.drawable.ssl_icon)
294 .setMessage(getText(R.string.delete_bookmark_warning).toString().replace(
295 "%s", getBookmarkTitle(deletePos)))
296 .setPositiveButton(R.string.ok,
297 new DialogInterface.OnClickListener() {
298 public void onClick(DialogInterface dialog, int whichButton) {
299 deleteBookmark(deletePos);
300 }
301 })
302 .setNegativeButton(R.string.cancel, null)
303 .show();
304 }
305
306 /**
307 * Refresh the shown list after the database has changed.
308 */
309 public void refreshList() {
310 mBookmarksAdapter.refreshList();
311 }
312
313 /**
314 * Return a hashmap representing the currently highlighted row.
315 */
316 public Bundle getRow(int position) {
317 return mBookmarksAdapter.getRow(position);
318 }
319
320 /**
321 * Return the url of the currently highlighted row.
322 */
323 public String getUrl(int position) {
324 return mBookmarksAdapter.getUrl(position);
325 }
326
327 private void copy(CharSequence text) {
328 try {
329 IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
330 if (clip != null) {
331 clip.setClipboardText(text);
332 }
333 } catch (android.os.RemoteException e) {
334 Log.e(LOGTAG, "Copy failed", e);
335 }
336 }
337
338 public String getBookmarkTitle(int position) {
339 return mBookmarksAdapter.getTitle(position);
340 }
341
342 /**
343 * Delete the currently highlighted row.
344 */
345 public void deleteBookmark(int position) {
346 mBookmarksAdapter.deleteRow(position);
347 }
348
349 public boolean dispatchKeyEvent(KeyEvent event) {
350 if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.isDown()) {
351 setResult(RESULT_CANCELED);
352 mCanceled = true;
353 }
354 return super.dispatchKeyEvent(event);
355 }
356}