Initial Contribution
This commit is contained in:
331
src/com/android/settings/quicklaunch/BookmarkPicker.java
Normal file
331
src/com/android/settings/quicklaunch/BookmarkPicker.java
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.quicklaunch;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import android.app.ListActivity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.SimpleAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Activity to pick a bookmark that will be returned to the caller.
|
||||
* <p>
|
||||
* Currently, bookmarks are either:
|
||||
* <li> Activities that are in the launcher
|
||||
* <li> Activities that are within an app that is capable of being launched with
|
||||
* the {@link Intent#ACTION_CREATE_SHORTCUT}.
|
||||
*/
|
||||
public class BookmarkPicker extends ListActivity implements SimpleAdapter.ViewBinder {
|
||||
|
||||
private static final String TAG = "BookmarkPicker";
|
||||
|
||||
/** Extra in the returned intent from this activity. */
|
||||
public static final String EXTRA_TITLE = "com.android.settings.quicklaunch.TITLE";
|
||||
|
||||
/** Extra that should be provided, and will be returned. */
|
||||
public static final String EXTRA_SHORTCUT = "com.android.settings.quicklaunch.SHORTCUT";
|
||||
|
||||
/**
|
||||
* The request code for the screen to create a bookmark that is WITHIN an
|
||||
* application. For example, Gmail can return a bookmark for the inbox
|
||||
* folder.
|
||||
*/
|
||||
private static final int REQUEST_CREATE_SHORTCUT = 1;
|
||||
|
||||
/** Intent used to get all the activities that are launch-able */
|
||||
private static Intent sLaunchIntent;
|
||||
/** Intent used to get all the activities that are {@link #REQUEST_CREATE_SHORTCUT}-able */
|
||||
private static Intent sShortcutIntent;
|
||||
|
||||
/**
|
||||
* List of ResolveInfo for activities that we can bookmark (either directly
|
||||
* to the activity, or by launching the activity and it returning a bookmark
|
||||
* WITHIN that application).
|
||||
*/
|
||||
private List<ResolveInfo> mResolveList;
|
||||
|
||||
// List adapter stuff
|
||||
private static final String KEY_TITLE = "TITLE";
|
||||
private static final String KEY_RESOLVE_INFO = "RESOLVE_INFO";
|
||||
private static final String sKeys[] = new String[] { KEY_TITLE, KEY_RESOLVE_INFO };
|
||||
private static final int sResourceIds[] = new int[] { R.id.title, R.id.icon };
|
||||
private SimpleAdapter mMyAdapter;
|
||||
|
||||
/** Display those activities that are launch-able */
|
||||
private static final int DISPLAY_MODE_LAUNCH = 0;
|
||||
/** Display those activities that are able to have bookmarks WITHIN the application */
|
||||
private static final int DISPLAY_MODE_SHORTCUT = 1;
|
||||
private int mDisplayMode = DISPLAY_MODE_LAUNCH;
|
||||
|
||||
private Handler mUiHandler = new Handler();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
updateListAndAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
menu.add(0, DISPLAY_MODE_LAUNCH, 0, R.string.quick_launch_display_mode_applications)
|
||||
.setIcon(R.drawable.ic_menu_archive);
|
||||
menu.add(0, DISPLAY_MODE_SHORTCUT, 0, R.string.quick_launch_display_mode_shortcuts)
|
||||
.setIcon(R.drawable.ic_menu_goto);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(DISPLAY_MODE_LAUNCH).setVisible(mDisplayMode != DISPLAY_MODE_LAUNCH);
|
||||
menu.findItem(DISPLAY_MODE_SHORTCUT).setVisible(mDisplayMode != DISPLAY_MODE_SHORTCUT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
|
||||
case DISPLAY_MODE_LAUNCH:
|
||||
mDisplayMode = DISPLAY_MODE_LAUNCH;
|
||||
break;
|
||||
|
||||
case DISPLAY_MODE_SHORTCUT:
|
||||
mDisplayMode = DISPLAY_MODE_SHORTCUT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
updateListAndAdapter();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ensureIntents() {
|
||||
if (sLaunchIntent == null) {
|
||||
sLaunchIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
sShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be called from the UI thread.
|
||||
*/
|
||||
private void updateListAndAdapter() {
|
||||
// Get the activities in a separate thread
|
||||
new Thread("data updater") {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (BookmarkPicker.this) {
|
||||
/*
|
||||
* Don't touch any of the lists that are being used by the
|
||||
* adapter in this thread!
|
||||
*/
|
||||
ArrayList<ResolveInfo> newResolveList = new ArrayList<ResolveInfo>();
|
||||
ArrayList<Map<String, ?>> newAdapterList = new ArrayList<Map<String, ?>>();
|
||||
|
||||
fillResolveList(newResolveList);
|
||||
Collections.sort(newResolveList,
|
||||
new ResolveInfo.DisplayNameComparator(getPackageManager()));
|
||||
|
||||
fillAdapterList(newAdapterList, newResolveList);
|
||||
|
||||
updateAdapterToUseNewLists(newAdapterList, newResolveList);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private void updateAdapterToUseNewLists(final ArrayList<Map<String, ?>> newAdapterList,
|
||||
final ArrayList<ResolveInfo> newResolveList) {
|
||||
// Post this back on the UI thread
|
||||
mUiHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
/*
|
||||
* SimpleAdapter does not support changing the lists after it
|
||||
* has been created. We just create a new instance.
|
||||
*/
|
||||
mMyAdapter = createResolveAdapter(newAdapterList);
|
||||
mResolveList = newResolveList;
|
||||
setListAdapter(mMyAdapter);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all activities matching our current display mode.
|
||||
*
|
||||
* @param list The list to fill.
|
||||
*/
|
||||
private void fillResolveList(List<ResolveInfo> list) {
|
||||
ensureIntents();
|
||||
PackageManager pm = getPackageManager();
|
||||
list.clear();
|
||||
|
||||
if (mDisplayMode == DISPLAY_MODE_LAUNCH) {
|
||||
list.addAll(pm.queryIntentActivities(sLaunchIntent, 0));
|
||||
} else if (mDisplayMode == DISPLAY_MODE_SHORTCUT) {
|
||||
list.addAll(pm.queryIntentActivities(sShortcutIntent, 0));
|
||||
}
|
||||
}
|
||||
|
||||
private SimpleAdapter createResolveAdapter(List<Map<String, ?>> list) {
|
||||
SimpleAdapter adapter = new SimpleAdapter(this, list,
|
||||
R.layout.bookmark_picker_item, sKeys, sResourceIds);
|
||||
adapter.setViewBinder(this);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
private void fillAdapterList(List<Map<String, ?>> list,
|
||||
List<ResolveInfo> resolveList) {
|
||||
list.clear();
|
||||
int resolveListSize = resolveList.size();
|
||||
for (int i = 0; i < resolveListSize; i++) {
|
||||
ResolveInfo info = resolveList.get(i);
|
||||
/*
|
||||
* Simple adapter craziness. For each item, we need to create a map
|
||||
* from a key to its value (the value can be any object--the view
|
||||
* binder will take care of filling the View with a representation
|
||||
* of that object).
|
||||
*/
|
||||
Map<String, Object> map = new TreeMap<String, Object>();
|
||||
map.put(KEY_TITLE, getResolveInfoTitle(info));
|
||||
map.put(KEY_RESOLVE_INFO, info);
|
||||
list.add(map);
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the title for a resolve info. */
|
||||
private String getResolveInfoTitle(ResolveInfo info) {
|
||||
CharSequence label = info.loadLabel(getPackageManager());
|
||||
if (label == null) label = info.activityInfo.name;
|
||||
return label != null ? label.toString() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
if (position >= mResolveList.size()) return;
|
||||
|
||||
ResolveInfo info = mResolveList.get(position);
|
||||
|
||||
switch (mDisplayMode) {
|
||||
|
||||
case DISPLAY_MODE_LAUNCH:
|
||||
// We can go ahead and return the clicked info's intent
|
||||
Intent intent = getIntentForResolveInfo(info, Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
finish(intent, getResolveInfoTitle(info));
|
||||
break;
|
||||
|
||||
case DISPLAY_MODE_SHORTCUT:
|
||||
// Start the shortcut activity so the user can pick the actual intent
|
||||
// (example: Gmail's shortcut activity shows a list of mailboxes)
|
||||
startShortcutActivity(info);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Intent getIntentForResolveInfo(ResolveInfo info, String action) {
|
||||
Intent intent = new Intent(action);
|
||||
ActivityInfo ai = info.activityInfo;
|
||||
intent.setClassName(ai.packageName, ai.name);
|
||||
return intent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an activity to get a shortcut.
|
||||
* <p>
|
||||
* For example, Gmail has an activity that lists the available labels. It
|
||||
* returns a shortcut intent for going directly to this label.
|
||||
*/
|
||||
private void startShortcutActivity(ResolveInfo info) {
|
||||
Intent intent = getIntentForResolveInfo(info, Intent.ACTION_CREATE_SHORTCUT);
|
||||
startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
|
||||
|
||||
// Will get a callback to onActivityResult
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode != RESULT_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (requestCode) {
|
||||
|
||||
case REQUEST_CREATE_SHORTCUT:
|
||||
if (data != null) {
|
||||
finish((Intent) data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT),
|
||||
data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the activity and returns the given data.
|
||||
*/
|
||||
private void finish(Intent intent, String title) {
|
||||
// Give back what was given to us (it will have the shortcut, for example)
|
||||
intent.putExtras(getIntent());
|
||||
// Put our information
|
||||
intent.putExtra(EXTRA_TITLE, title);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean setViewValue(View view, Object data, String textRepresentation) {
|
||||
if (view.getId() == R.id.icon) {
|
||||
Drawable icon = ((ResolveInfo) data).loadIcon(getPackageManager());
|
||||
if (icon != null) {
|
||||
((ImageView) view).setImageDrawable(icon);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
347
src/com/android/settings/quicklaunch/QuickLaunchSettings.java
Normal file
347
src/com/android/settings/quicklaunch/QuickLaunchSettings.java
Normal file
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.quicklaunch;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.provider.Settings.Bookmarks;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
/**
|
||||
* Settings activity for quick launch.
|
||||
* <p>
|
||||
* Shows a list of possible shortcuts, the current application each is bound to,
|
||||
* and allows choosing a new bookmark for a shortcut.
|
||||
*/
|
||||
public class QuickLaunchSettings extends PreferenceActivity implements
|
||||
AdapterView.OnItemLongClickListener, DialogInterface.OnClickListener {
|
||||
|
||||
private static final String TAG = "QuickLaunchSettings";
|
||||
|
||||
private static final String KEY_SHORTCUT_CATEGORY = "shortcut_category";
|
||||
|
||||
private static final int DIALOG_CLEAR_SHORTCUT = 0;
|
||||
|
||||
private static final int REQUEST_PICK_BOOKMARK = 1;
|
||||
|
||||
private static final int COLUMN_SHORTCUT = 0;
|
||||
private static final int COLUMN_TITLE = 1;
|
||||
private static final String[] sProjection = new String[] {
|
||||
Bookmarks.SHORTCUT, Bookmarks.TITLE
|
||||
};
|
||||
private static final String sShortcutSelection = Bookmarks.SHORTCUT + "=?";
|
||||
|
||||
private Handler mUiHandler = new Handler();
|
||||
|
||||
private static final String DEFAULT_BOOKMARK_FOLDER = "@default";
|
||||
/** Cursor for Bookmarks provider. */
|
||||
private Cursor mBookmarksCursor;
|
||||
/** Listens for changes to Bookmarks provider. */
|
||||
private BookmarksObserver mBookmarksObserver;
|
||||
/** Used to keep track of which shortcuts have bookmarks. */
|
||||
private SparseBooleanArray mBookmarkedShortcuts;
|
||||
|
||||
/** Preference category to hold the shortcut preferences. */
|
||||
private PreferenceCategory mShortcutCategory;
|
||||
/** Mapping of a shortcut to its preference. */
|
||||
private SparseArray<ShortcutPreference> mShortcutToPreference;
|
||||
|
||||
/** The bookmark title of the shortcut that is being cleared. */
|
||||
private CharSequence mClearDialogBookmarkTitle;
|
||||
private static final String CLEAR_DIALOG_BOOKMARK_TITLE = "CLEAR_DIALOG_BOOKMARK_TITLE";
|
||||
/** The shortcut that is being cleared. */
|
||||
private char mClearDialogShortcut;
|
||||
private static final String CLEAR_DIALOG_SHORTCUT = "CLEAR_DIALOG_SHORTCUT";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
addPreferencesFromResource(R.xml.quick_launch_settings);
|
||||
|
||||
mShortcutCategory = (PreferenceCategory) findPreference(KEY_SHORTCUT_CATEGORY);
|
||||
mShortcutToPreference = new SparseArray<ShortcutPreference>();
|
||||
mBookmarksObserver = new BookmarksObserver(mUiHandler);
|
||||
initShortcutPreferences();
|
||||
mBookmarksCursor = managedQuery(Bookmarks.CONTENT_URI, sProjection, null, null);
|
||||
getListView().setOnItemLongClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
getContentResolver().registerContentObserver(Bookmarks.CONTENT_URI, true,
|
||||
mBookmarksObserver);
|
||||
refreshShortcuts();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
getContentResolver().unregisterContentObserver(mBookmarksObserver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle state) {
|
||||
super.onRestoreInstanceState(state);
|
||||
|
||||
// Restore the clear dialog's info
|
||||
mClearDialogBookmarkTitle = state.getString(CLEAR_DIALOG_BOOKMARK_TITLE);
|
||||
mClearDialogShortcut = (char) state.getInt(CLEAR_DIALOG_SHORTCUT, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
// Save the clear dialog's info
|
||||
outState.putCharSequence(CLEAR_DIALOG_BOOKMARK_TITLE, mClearDialogBookmarkTitle);
|
||||
outState.putInt(CLEAR_DIALOG_SHORTCUT, mClearDialogShortcut);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
|
||||
case DIALOG_CLEAR_SHORTCUT: {
|
||||
// Create the dialog for clearing a shortcut
|
||||
return new AlertDialog.Builder(this)
|
||||
.setTitle(getString(R.string.quick_launch_clear_dialog_title))
|
||||
.setIcon(R.drawable.ic_dialog_alert)
|
||||
.setMessage(getString(R.string.quick_launch_clear_dialog_message,
|
||||
mClearDialogShortcut, mClearDialogBookmarkTitle))
|
||||
.setPositiveButton(R.string.quick_launch_clear_ok_button, this)
|
||||
.setNegativeButton(R.string.quick_launch_clear_cancel_button, this)
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
return super.onCreateDialog(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPrepareDialog(int id, Dialog dialog) {
|
||||
switch (id) {
|
||||
|
||||
case DIALOG_CLEAR_SHORTCUT: {
|
||||
AlertDialog alertDialog = (AlertDialog) dialog;
|
||||
alertDialog.setMessage(getString(R.string.quick_launch_clear_dialog_message,
|
||||
mClearDialogShortcut, mClearDialogBookmarkTitle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showClearDialog(ShortcutPreference pref) {
|
||||
|
||||
if (!pref.hasBookmark()) return;
|
||||
|
||||
mClearDialogBookmarkTitle = pref.getTitle();
|
||||
mClearDialogShortcut = pref.getShortcut();
|
||||
showDialog(DIALOG_CLEAR_SHORTCUT);
|
||||
}
|
||||
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (mClearDialogShortcut > 0 && which == AlertDialog.BUTTON1) {
|
||||
// Clear the shortcut
|
||||
clearShortcut(mClearDialogShortcut);
|
||||
}
|
||||
mClearDialogBookmarkTitle = null;
|
||||
mClearDialogShortcut = 0;
|
||||
}
|
||||
|
||||
private void clearShortcut(char shortcut) {
|
||||
getContentResolver().delete(Bookmarks.CONTENT_URI, sShortcutSelection,
|
||||
new String[] { String.valueOf((int) shortcut) });
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
|
||||
if (!(preference instanceof ShortcutPreference)) return false;
|
||||
|
||||
// Open the screen to pick a bookmark for this shortcut
|
||||
ShortcutPreference pref = (ShortcutPreference) preference;
|
||||
Intent intent = new Intent(this, BookmarkPicker.class);
|
||||
intent.putExtra(BookmarkPicker.EXTRA_SHORTCUT, pref.getShortcut());
|
||||
startActivityForResult(intent, REQUEST_PICK_BOOKMARK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onItemLongClick(AdapterView parent, View view, int position, long id) {
|
||||
|
||||
// Open the clear shortcut dialog
|
||||
Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem(position);
|
||||
if (!(pref instanceof ShortcutPreference)) return false;
|
||||
showClearDialog((ShortcutPreference) pref);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode != RESULT_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestCode == REQUEST_PICK_BOOKMARK) {
|
||||
|
||||
// Returned from the 'pick bookmark for this shortcut' screen
|
||||
if (data == null) {
|
||||
Log.w(TAG, "Result from bookmark picker does not have an intent.");
|
||||
return;
|
||||
}
|
||||
|
||||
String title = data.getStringExtra(BookmarkPicker.EXTRA_TITLE);
|
||||
char shortcut = data.getCharExtra(BookmarkPicker.EXTRA_SHORTCUT, (char) 0);
|
||||
updateShortcut(shortcut, title, data);
|
||||
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateShortcut(char shortcut, String title, Intent intent) {
|
||||
|
||||
// Update the bookmark for a shortcut
|
||||
Bookmarks.add(getContentResolver(), intent, title.toString(), DEFAULT_BOOKMARK_FOLDER,
|
||||
shortcut, 0);
|
||||
}
|
||||
|
||||
private ShortcutPreference getOrCreatePreference(char shortcut) {
|
||||
ShortcutPreference pref = mShortcutToPreference.get(shortcut);
|
||||
if (pref != null) {
|
||||
return pref;
|
||||
} else {
|
||||
Log.w(TAG, "Unknown shortcut '" + shortcut + "', creating preference anyway");
|
||||
return createPreference(shortcut);
|
||||
}
|
||||
}
|
||||
|
||||
private ShortcutPreference createPreference(char shortcut) {
|
||||
ShortcutPreference pref = new ShortcutPreference(QuickLaunchSettings.this, shortcut);
|
||||
mShortcutCategory.addPreference(pref);
|
||||
mShortcutToPreference.put(shortcut, pref);
|
||||
return pref;
|
||||
}
|
||||
|
||||
private void initShortcutPreferences() {
|
||||
|
||||
/** Whether the shortcut has been seen already. The array index is the shortcut. */
|
||||
SparseBooleanArray shortcutSeen = new SparseBooleanArray();
|
||||
KeyCharacterMap keyMap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
|
||||
|
||||
// Go through all the key codes and create a preference for the appropriate keys
|
||||
for (int keyCode = KeyEvent.MAX_KEYCODE - 1; keyCode >= 0; keyCode--) {
|
||||
// Get the label for the primary char on the key that produces this key code
|
||||
char shortcut = (char) Character.toLowerCase(keyMap.getDisplayLabel(keyCode));
|
||||
if (shortcut == 0 || shortcutSeen.get(shortcut, false)) continue;
|
||||
// TODO: need a to tell if the current keyboard can produce this key code, for now
|
||||
// only allow the letter or digits
|
||||
if (!Character.isLetterOrDigit(shortcut)) continue;
|
||||
shortcutSeen.put(shortcut, true);
|
||||
|
||||
createPreference(shortcut);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void refreshShortcuts() {
|
||||
Cursor c = mBookmarksCursor;
|
||||
if (c == null) {
|
||||
// Haven't finished querying yet
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c.requery()) {
|
||||
Log.e(TAG, "Could not requery cursor when refreshing shortcuts.");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* We use the previous bookmarked shortcuts array to filter out those
|
||||
* shortcuts that had bookmarks before this method call, and don't after
|
||||
* (so we can set the preferences to be without bookmarks).
|
||||
*/
|
||||
SparseBooleanArray noLongerBookmarkedShortcuts = mBookmarkedShortcuts;
|
||||
SparseBooleanArray newBookmarkedShortcuts = new SparseBooleanArray();
|
||||
while (c.moveToNext()) {
|
||||
char shortcut = Character.toLowerCase((char) c.getInt(COLUMN_SHORTCUT));
|
||||
if (shortcut == 0) continue;
|
||||
|
||||
ShortcutPreference pref = getOrCreatePreference(shortcut);
|
||||
pref.setTitle(c.getString(COLUMN_TITLE));
|
||||
pref.setSummary(getString(R.string.quick_launch_shortcut,
|
||||
String.valueOf(shortcut)));
|
||||
pref.setHasBookmark(true);
|
||||
|
||||
newBookmarkedShortcuts.put(shortcut, true);
|
||||
if (noLongerBookmarkedShortcuts != null) {
|
||||
// After this loop, the shortcuts with value true in this array
|
||||
// will no longer have bookmarks
|
||||
noLongerBookmarkedShortcuts.put(shortcut, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (noLongerBookmarkedShortcuts != null) {
|
||||
for (int i = noLongerBookmarkedShortcuts.size() - 1; i >= 0; i--) {
|
||||
if (noLongerBookmarkedShortcuts.valueAt(i)) {
|
||||
// True, so there is no longer a bookmark for this shortcut
|
||||
char shortcut = (char) noLongerBookmarkedShortcuts.keyAt(i);
|
||||
ShortcutPreference pref = mShortcutToPreference.get(shortcut);
|
||||
if (pref != null) {
|
||||
pref.setHasBookmark(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mBookmarkedShortcuts = newBookmarkedShortcuts;
|
||||
|
||||
c.deactivate();
|
||||
}
|
||||
|
||||
private class BookmarksObserver extends ContentObserver {
|
||||
|
||||
public BookmarksObserver(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
super.onChange(selfChange);
|
||||
|
||||
refreshShortcuts();
|
||||
}
|
||||
}
|
||||
}
|
151
src/com/android/settings/quicklaunch/ShortcutPreference.java
Normal file
151
src/com/android/settings/quicklaunch/ShortcutPreference.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.quicklaunch;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.preference.Preference;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Preference type for a shortcut in {@link QuickLaunchSettings}.
|
||||
*/
|
||||
public class ShortcutPreference extends Preference implements Comparable<Preference> {
|
||||
|
||||
private static Object sStaticVarsLock = new Object();
|
||||
|
||||
// These static fields are used across all instances of ShortcutPreference.
|
||||
// There will be many ShortcutPreference instances (~36 for US).
|
||||
private static String STRING_ASSIGN_APPLICATION;
|
||||
private static String STRING_NO_SHORTCUT;
|
||||
|
||||
private static int sDimAlpha;
|
||||
private static ColorStateList sRegularTitleColor;
|
||||
private static ColorStateList sDimTitleColor;
|
||||
private static ColorStateList sRegularSummaryColor;
|
||||
private static ColorStateList sDimSummaryColor;
|
||||
|
||||
private char mShortcut;
|
||||
private boolean mHasBookmark;
|
||||
|
||||
public ShortcutPreference(Context context, char shortcut) {
|
||||
super(context);
|
||||
|
||||
synchronized (sStaticVarsLock) {
|
||||
// Init statics. This should only happen for the first ShortcutPreference created,
|
||||
// the rest will already have them initialized.
|
||||
if (STRING_ASSIGN_APPLICATION == null) {
|
||||
STRING_ASSIGN_APPLICATION = context.getString(R.string.quick_launch_assign_application);
|
||||
STRING_NO_SHORTCUT = context.getString(R.string.quick_launch_no_shortcut);
|
||||
|
||||
TypedValue outValue = new TypedValue();
|
||||
context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true);
|
||||
sDimAlpha = (int) (outValue.getFloat() * 255);
|
||||
}
|
||||
}
|
||||
|
||||
mShortcut = shortcut;
|
||||
|
||||
setWidgetLayoutResource(R.layout.preference_widget_shortcut);
|
||||
}
|
||||
|
||||
public char getShortcut() {
|
||||
return mShortcut;
|
||||
}
|
||||
|
||||
public void setShortcut(char shortcut) {
|
||||
if (shortcut != mShortcut) {
|
||||
mShortcut = shortcut;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasBookmark() {
|
||||
return mHasBookmark;
|
||||
}
|
||||
|
||||
public void setHasBookmark(boolean hasBookmark) {
|
||||
if (hasBookmark != mHasBookmark) {
|
||||
mHasBookmark = hasBookmark;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle() {
|
||||
return mHasBookmark ? super.getTitle() : STRING_ASSIGN_APPLICATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mHasBookmark ? super.getSummary() : STRING_NO_SHORTCUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
super.onBindView(view);
|
||||
|
||||
TextView shortcutView = (TextView) view.findViewById(R.id.shortcut);
|
||||
if (shortcutView != null) {
|
||||
shortcutView.setText(String.valueOf(mShortcut));
|
||||
}
|
||||
|
||||
TextView titleView = (TextView) view.findViewById(android.R.id.title);
|
||||
|
||||
synchronized (sStaticVarsLock) {
|
||||
if (sRegularTitleColor == null) {
|
||||
sRegularTitleColor = titleView.getTextColors();
|
||||
sDimTitleColor = sRegularTitleColor.withAlpha(sDimAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
ColorStateList color = mHasBookmark ? sRegularTitleColor : sDimTitleColor;
|
||||
if (color != null) {
|
||||
titleView.setTextColor(color);
|
||||
}
|
||||
|
||||
TextView summaryView = (TextView) view.findViewById(android.R.id.summary);
|
||||
|
||||
synchronized (sStaticVarsLock) {
|
||||
if (sRegularSummaryColor == null) {
|
||||
sRegularSummaryColor = summaryView.getTextColors();
|
||||
sDimSummaryColor = sRegularSummaryColor.withAlpha(sDimAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
color = mHasBookmark ? sRegularSummaryColor : sDimSummaryColor;
|
||||
if (color != null) {
|
||||
summaryView.setTextColor(color);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int compareTo(Preference another) {
|
||||
if (!(another instanceof ShortcutPreference)) return super.compareTo(another);
|
||||
|
||||
// Letters before digits
|
||||
char other = ((ShortcutPreference) another).mShortcut;
|
||||
if (Character.isDigit(mShortcut) && Character.isLetter(other)) return 1;
|
||||
else if (Character.isDigit(other) && Character.isLetter(mShortcut)) return -1;
|
||||
else return mShortcut - other;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user