QuickLaunchSettings.java revision ec598cb91c02c035d19ccd8a9f17e2bf8da9da5a
1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/*
2afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
4afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * you may not use this file except in compliance with the License.
6afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * You may obtain a copy of the License at
7afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
8afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
10afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * See the License for the specific language governing permissions and
14afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * limitations under the License.
15afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
16afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
17afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpackage com.android.settings.quicklaunch;
18afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
19afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.AlertDialog;
20afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.app.Dialog;
21afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.DialogInterface;
22afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
23ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischerimport android.content.pm.PackageManager;
24ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischerimport android.content.pm.ResolveInfo;
25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.database.ContentObserver;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.database.Cursor;
27afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Bundle;
28afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Handler;
29afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.preference.Preference;
30afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.preference.PreferenceActivity;
31afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.preference.PreferenceGroup;
32afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.preference.PreferenceScreen;
33afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.provider.Settings.Bookmarks;
34afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.Log;
35afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.SparseArray;
36afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.SparseBooleanArray;
37afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.KeyCharacterMap;
38afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.KeyEvent;
39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.View;
40afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.AdapterView;
41afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
42afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport com.android.settings.R;
43afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
44ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischerimport java.net.URISyntaxException;
45ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer
46afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/**
47afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Settings activity for quick launch.
48afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * <p>
49afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Shows a list of possible shortcuts, the current application each is bound to,
50afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * and allows choosing a new bookmark for a shortcut.
51afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
52afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpublic class QuickLaunchSettings extends PreferenceActivity implements
53afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        AdapterView.OnItemLongClickListener, DialogInterface.OnClickListener {
54afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
55afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String TAG = "QuickLaunchSettings";
56afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String KEY_SHORTCUT_CATEGORY = "shortcut_category";
58afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
59afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int DIALOG_CLEAR_SHORTCUT = 0;
60afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
61afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int REQUEST_PICK_BOOKMARK = 1;
62afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
63afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int COLUMN_SHORTCUT = 0;
64afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int COLUMN_TITLE = 1;
65afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final int COLUMN_INTENT = 2;
66afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String[] sProjection = new String[] {
67afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            Bookmarks.SHORTCUT, Bookmarks.TITLE, Bookmarks.INTENT
68afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    };
69afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String sShortcutSelection = Bookmarks.SHORTCUT + "=?";
70afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
71afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private Handler mUiHandler = new Handler();
72afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
73afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String DEFAULT_BOOKMARK_FOLDER = "@quicklaunch";
74afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /** Cursor for Bookmarks provider. */
75afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private Cursor mBookmarksCursor;
76afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /** Listens for changes to Bookmarks provider. */
77afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private BookmarksObserver mBookmarksObserver;
78afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /** Used to keep track of which shortcuts have bookmarks. */
79afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private SparseBooleanArray mBookmarkedShortcuts;
80afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
81afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /** Preference category to hold the shortcut preferences. */
82afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private PreferenceGroup mShortcutGroup;
83afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /** Mapping of a shortcut to its preference. */
84afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private SparseArray<ShortcutPreference> mShortcutToPreference;
85afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
86afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /** The bookmark title of the shortcut that is being cleared. */
87afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private CharSequence mClearDialogBookmarkTitle;
88afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String CLEAR_DIALOG_BOOKMARK_TITLE = "CLEAR_DIALOG_BOOKMARK_TITLE";
89afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    /** The shortcut that is being cleared. */
90afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private char mClearDialogShortcut;
91afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String CLEAR_DIALOG_SHORTCUT = "CLEAR_DIALOG_SHORTCUT";
92afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
93afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
94afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void onCreate(Bundle savedInstanceState) {
95afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onCreate(savedInstanceState);
96afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
97afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        addPreferencesFromResource(R.xml.quick_launch_settings);
98afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
99afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mShortcutGroup = (PreferenceGroup) findPreference(KEY_SHORTCUT_CATEGORY);
100afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mShortcutToPreference = new SparseArray<ShortcutPreference>();
101afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mBookmarksObserver = new BookmarksObserver(mUiHandler);
102afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        initShortcutPreferences();
103afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mBookmarksCursor = managedQuery(Bookmarks.CONTENT_URI, sProjection, null, null);
104afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        getListView().setOnItemLongClickListener(this);
105afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
106afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
107afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
108afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void onResume() {
109afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onResume();
110afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        getContentResolver().registerContentObserver(Bookmarks.CONTENT_URI, true,
111afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                mBookmarksObserver);
112afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        refreshShortcuts();
113afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
114afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
115afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
116afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void onPause() {
117afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onPause();
118afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        getContentResolver().unregisterContentObserver(mBookmarksObserver);
119afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
120afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
121afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
122afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void onRestoreInstanceState(Bundle state) {
123afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onRestoreInstanceState(state);
124afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
125afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Restore the clear dialog's info
126afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mClearDialogBookmarkTitle = state.getString(CLEAR_DIALOG_BOOKMARK_TITLE);
127afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mClearDialogShortcut = (char) state.getInt(CLEAR_DIALOG_SHORTCUT, 0);
128afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
129afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
130afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
131afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void onSaveInstanceState(Bundle outState) {
132afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onSaveInstanceState(outState);
133afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
134afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Save the clear dialog's info
135afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        outState.putCharSequence(CLEAR_DIALOG_BOOKMARK_TITLE, mClearDialogBookmarkTitle);
136afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        outState.putInt(CLEAR_DIALOG_SHORTCUT, mClearDialogShortcut);
137afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
138afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
139afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
140afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected Dialog onCreateDialog(int id) {
141afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        switch (id) {
142afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
143afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case DIALOG_CLEAR_SHORTCUT: {
144afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // Create the dialog for clearing a shortcut
145afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return new AlertDialog.Builder(this)
146afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        .setTitle(getString(R.string.quick_launch_clear_dialog_title))
147afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
148afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        .setMessage(getString(R.string.quick_launch_clear_dialog_message,
149afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                                mClearDialogShortcut, mClearDialogBookmarkTitle))
150afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        .setPositiveButton(R.string.quick_launch_clear_ok_button, this)
151afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        .setNegativeButton(R.string.quick_launch_clear_cancel_button, this)
152afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        .create();
153afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
154afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
155afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
156afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return super.onCreateDialog(id);
157afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
158afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
159afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
160afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void onPrepareDialog(int id, Dialog dialog) {
161afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        switch (id) {
162afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
163afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            case DIALOG_CLEAR_SHORTCUT: {
164afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                AlertDialog alertDialog = (AlertDialog) dialog;
165afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                alertDialog.setMessage(getString(R.string.quick_launch_clear_dialog_message,
166afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        mClearDialogShortcut, mClearDialogBookmarkTitle));
167afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
168afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
169afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
170afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
171afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void showClearDialog(ShortcutPreference pref) {
172afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
173afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!pref.hasBookmark()) return;
174afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
175afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mClearDialogBookmarkTitle = pref.getTitle();
176afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mClearDialogShortcut = pref.getShortcut();
177afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        showDialog(DIALOG_CLEAR_SHORTCUT);
178afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
179afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
180afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public void onClick(DialogInterface dialog, int which) {
181afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (mClearDialogShortcut > 0 && which == AlertDialog.BUTTON1) {
182afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Clear the shortcut
183afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            clearShortcut(mClearDialogShortcut);
184afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
185afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mClearDialogBookmarkTitle = null;
186afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mClearDialogShortcut = 0;
187afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
188afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
189afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void clearShortcut(char shortcut) {
190afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        getContentResolver().delete(Bookmarks.CONTENT_URI, sShortcutSelection,
191afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                new String[] { String.valueOf((int) shortcut) });
192afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
193afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
194afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
195afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
196afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!(preference instanceof ShortcutPreference)) return false;
197afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
198afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Open the screen to pick a bookmark for this shortcut
199afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ShortcutPreference pref = (ShortcutPreference) preference;
200afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Intent intent = new Intent(this, BookmarkPicker.class);
201afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        intent.putExtra(BookmarkPicker.EXTRA_SHORTCUT, pref.getShortcut());
202afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        startActivityForResult(intent, REQUEST_PICK_BOOKMARK);
203afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
204afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return true;
205afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
206afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
207afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    public boolean onItemLongClick(AdapterView parent, View view, int position, long id) {
208afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
209afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Open the clear shortcut dialog
210afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem(position);
211afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!(pref instanceof ShortcutPreference)) return false;
212afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        showClearDialog((ShortcutPreference) pref);
213afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return true;
214afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
215afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
216afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
217afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
218afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (resultCode != RESULT_OK) {
219afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return;
220afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
221afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
222afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (requestCode == REQUEST_PICK_BOOKMARK) {
223afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
224afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Returned from the 'pick bookmark for this shortcut' screen
225afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (data == null) {
226afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                Log.w(TAG, "Result from bookmark picker does not have an intent.");
227afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                return;
228afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
229afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
230afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            String title = data.getStringExtra(BookmarkPicker.EXTRA_TITLE);
231afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            char shortcut = data.getCharExtra(BookmarkPicker.EXTRA_SHORTCUT, (char) 0);
232afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            updateShortcut(shortcut, data);
233afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
234afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
235afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            super.onActivityResult(requestCode, resultCode, data);
236afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
237afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
238afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
239afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void updateShortcut(char shortcut, Intent intent) {
240afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Update the bookmark for a shortcut
241afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Pass an empty title so it gets resolved each time this bookmark is
242afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // displayed (since the locale could change after we insert into the provider).
243afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Bookmarks.add(getContentResolver(), intent, "", DEFAULT_BOOKMARK_FOLDER, shortcut, 0);
244afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
245afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
246afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private ShortcutPreference getOrCreatePreference(char shortcut) {
247afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ShortcutPreference pref = mShortcutToPreference.get(shortcut);
248afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (pref != null) {
249afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return pref;
250afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } else {
251afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            Log.w(TAG, "Unknown shortcut '" + shortcut + "', creating preference anyway");
252afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return createPreference(shortcut);
253afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
254afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
255afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
256afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private ShortcutPreference createPreference(char shortcut) {
257afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        ShortcutPreference pref = new ShortcutPreference(QuickLaunchSettings.this, shortcut);
258afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mShortcutGroup.addPreference(pref);
259afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mShortcutToPreference.put(shortcut, pref);
260afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        return pref;
261afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
262afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
263afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void initShortcutPreferences() {
264afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
265afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /** Whether the shortcut has been seen already.  The array index is the shortcut. */
266afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        SparseBooleanArray shortcutSeen = new SparseBooleanArray();
267afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        KeyCharacterMap keyMap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
268afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
269afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // Go through all the key codes and create a preference for the appropriate keys
270afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        for (int keyCode = KeyEvent.getMaxKeyCode() - 1; keyCode >= 0; keyCode--) {
271afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Get the label for the primary char on the key that produces this key code
272afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            char shortcut = (char) Character.toLowerCase(keyMap.getDisplayLabel(keyCode));
273afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (shortcut == 0 || shortcutSeen.get(shortcut, false)) continue;
274afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // TODO: need a to tell if the current keyboard can produce this key code, for now
275afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // only allow the letter or digits
276afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (!Character.isLetterOrDigit(shortcut)) continue;
277afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            shortcutSeen.put(shortcut, true);
278afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
279afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            createPreference(shortcut);
280afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
281afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
282afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
283afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private synchronized void refreshShortcuts() {
284afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        Cursor c = mBookmarksCursor;
285afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (c == null) {
286afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            // Haven't finished querying yet
287afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return;
288afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
289afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
290afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (!c.requery()) {
291afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            Log.e(TAG, "Could not requery cursor when refreshing shortcuts.");
292afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return;
293afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
294afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
295afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /**
296afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * We use the previous bookmarked shortcuts array to filter out those
297afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * shortcuts that had bookmarks before this method call, and don't after
298afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * (so we can set the preferences to be without bookmarks).
299afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
300afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        SparseBooleanArray noLongerBookmarkedShortcuts = mBookmarkedShortcuts;
301afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        SparseBooleanArray newBookmarkedShortcuts = new SparseBooleanArray();
302afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        while (c.moveToNext()) {
303afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            char shortcut = Character.toLowerCase((char) c.getInt(COLUMN_SHORTCUT));
304afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (shortcut == 0) continue;
305afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
306afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            ShortcutPreference pref = getOrCreatePreference(shortcut);
307ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer            CharSequence title = Bookmarks.getTitle(this, c);
308ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer
309ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer            /*
310ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer             * The title retrieved from Bookmarks.getTitle() will be in
311ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer             * the original boot locale, not the current locale.
312ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer             * Try to look up a localized title from the PackageManager.
313ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer             */
314ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer            int intentColumn = c.getColumnIndex(Bookmarks.INTENT);
315ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer            String intentUri = c.getString(intentColumn);
316ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer            PackageManager packageManager = getPackageManager();
317ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer            try {
318ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer                Intent intent = Intent.getIntent(intentUri);
319ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer                ResolveInfo info = packageManager.resolveActivity(intent, 0);
320ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer                if (info != null) {
321ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer                    title = info.loadLabel(packageManager);
322ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer                }
323ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer            } catch (URISyntaxException e) {
324ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer                // Just use the non-localized title, then.
325ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer            }
326ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer
327ec598cb91c02c035d19ccd8a9f17e2bf8da9da5aEric Fischer            pref.setTitle(title);
328afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            pref.setSummary(getString(R.string.quick_launch_shortcut,
329afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    String.valueOf(shortcut)));
330afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            pref.setHasBookmark(true);
331afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
332afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            newBookmarkedShortcuts.put(shortcut, true);
333afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            if (noLongerBookmarkedShortcuts != null) {
334afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // After this loop, the shortcuts with value true in this array
335afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                // will no longer have bookmarks
336afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                noLongerBookmarkedShortcuts.put(shortcut, false);
337afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
338afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
339afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
340afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        if (noLongerBookmarkedShortcuts != null) {
341afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            for (int i = noLongerBookmarkedShortcuts.size() - 1; i >= 0; i--) {
342afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                if (noLongerBookmarkedShortcuts.valueAt(i)) {
343afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    // True, so there is no longer a bookmark for this shortcut
344afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    char shortcut = (char) noLongerBookmarkedShortcuts.keyAt(i);
345afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    ShortcutPreference pref = mShortcutToPreference.get(shortcut);
346afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    if (pref != null) {
347afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                        pref.setHasBookmark(false);
348afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                    }
349afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                }
350afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            }
351afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
352afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
353afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        mBookmarkedShortcuts = newBookmarkedShortcuts;
354afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
355afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        c.deactivate();
356afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
357afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
358afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private class BookmarksObserver extends ContentObserver {
359afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
360afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public BookmarksObserver(Handler handler) {
361afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            super(handler);
362afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
363afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
364afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        @Override
365afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        public void onChange(boolean selfChange) {
366afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            super.onChange(selfChange);
367afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
368afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            refreshShortcuts();
369afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
370afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
371afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
372