BrowserBookmarksPage.java revision ba6d7b853c32ad6c3be26c443daa61f322bcfdc2
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.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}
357