diff options
-rw-r--r-- | res/layout-xlarge/external_widget_drop_list_item.xml | 39 | ||||
-rw-r--r-- | res/values/strings.xml | 7 | ||||
-rw-r--r-- | src/com/android/launcher2/CustomizePagedView.java | 8 | ||||
-rw-r--r-- | src/com/android/launcher2/InstallShortcutReceiver.java | 4 | ||||
-rw-r--r-- | src/com/android/launcher2/InstallWidgetReceiver.java | 161 | ||||
-rw-r--r-- | src/com/android/launcher2/Launcher.java | 59 | ||||
-rw-r--r-- | src/com/android/launcher2/LauncherModel.java | 79 | ||||
-rw-r--r-- | src/com/android/launcher2/PendingAddItemInfo.java | 13 | ||||
-rw-r--r-- | src/com/android/launcher2/Workspace.java | 109 |
9 files changed, 381 insertions, 98 deletions
diff --git a/res/layout-xlarge/external_widget_drop_list_item.xml b/res/layout-xlarge/external_widget_drop_list_item.xml new file mode 100644 index 000000000..84f40eddf --- /dev/null +++ b/res/layout-xlarge/external_widget_drop_list_item.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 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. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + + android:layout_width="match_parent" + android:layout_height="64dp"> + <ImageView + android:id="@+id/provider_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginLeft="20dp" + android:maxWidth="32dp" + android:maxHeight="32dp" + android:scaleType="fitCenter" + android:src="@drawable/ic_launcher_application" /> + <TextView + android:id="@+id/provider" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginLeft="5dp" + android:gravity="center_vertical" + android:textSize="18sp" /> +</LinearLayout> diff --git a/res/values/strings.xml b/res/values/strings.xml index 5c8f3621f..f26dfc855 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -77,6 +77,13 @@ <!-- The format string for the dimensions of a widget in the drawer --> <string name="widget_dims_format" translatable="false">%1$d x %2$d</string> + <!-- External-drop widget pick label format string [CHAR_LIMIT=25] --> + <string name="external_drop_widget_pick_format" translatable="false">%1$s (%2$d x %3$d)</string> + <!-- External-drop widget error string --> + <string name="external_drop_widget_error">Could not install clipboard item</string> + <!-- External-drop widget pick title --> + <string name="external_drop_widget_pick_title">Select widget to create</string> + <!-- Folders --> <skip /> <!-- Label of Folder name field in Rename folder dialog box --> diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java index 28de3883d..4cce81e97 100644 --- a/src/com/android/launcher2/CustomizePagedView.java +++ b/src/com/android/launcher2/CustomizePagedView.java @@ -581,12 +581,8 @@ public class CustomizePagedView extends PagedView final int count = list.size(); layout.removeAllViews(); for (int i = 0; i < count; ++i) { - AppWidgetProviderInfo info = (AppWidgetProviderInfo) list.get(i); - PendingAddWidgetInfo createItemInfo = new PendingAddWidgetInfo(); - createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET; - createItemInfo.componentName = info.provider; - createItemInfo.minWidth = info.minWidth; - createItemInfo.minHeight = info.minHeight; + final AppWidgetProviderInfo info = (AppWidgetProviderInfo) list.get(i); + final PendingAddWidgetInfo createItemInfo = new PendingAddWidgetInfo(info, null, null); LinearLayout l = (LinearLayout) mInflater.inflate( R.layout.customize_paged_view_widget, layout, false); diff --git a/src/com/android/launcher2/InstallShortcutReceiver.java b/src/com/android/launcher2/InstallShortcutReceiver.java index 8d72531d5..ac50f6605 100644 --- a/src/com/android/launcher2/InstallShortcutReceiver.java +++ b/src/com/android/launcher2/InstallShortcutReceiver.java @@ -29,6 +29,10 @@ public class InstallShortcutReceiver extends BroadcastReceiver { public static final String ACTION_INSTALL_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT"; + // A mime-type representing shortcut data + public static final String SHORTCUT_MIMETYPE = + "com.android.launcher/shortcut"; + private final int[] mCoordinates = new int[2]; public void onReceive(Context context, Intent data) { diff --git a/src/com/android/launcher2/InstallWidgetReceiver.java b/src/com/android/launcher2/InstallWidgetReceiver.java index e6a9a696c..970c6a5be 100644 --- a/src/com/android/launcher2/InstallWidgetReceiver.java +++ b/src/com/android/launcher2/InstallWidgetReceiver.java @@ -16,6 +16,25 @@ package com.android.launcher2; +import java.util.List; + +import android.appwidget.AppWidgetProviderInfo; +import android.content.ClipData; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.database.DataSetObserver; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ListAdapter; +import android.widget.TextView; + +import com.android.launcher.R; + /** * We will likely flesh this out later, to handle allow external apps to place widgets, but for now, @@ -24,11 +43,153 @@ package com.android.launcher2; public class InstallWidgetReceiver { public static final String ACTION_INSTALL_WIDGET = "com.android.launcher.action.INSTALL_WIDGET"; + public static final String ACTION_SUPPORTS_CLIPDATA_MIMETYPE = + "com.android.launcher.action.SUPPORTS_CLIPDATA_MIMETYPE"; // Currently not exposed. Put into Intent when we want to make it public. // TEMP: Should we call this "EXTRA_APPWIDGET_PROVIDER"? public static final String EXTRA_APPWIDGET_COMPONENT = "com.android.launcher.extra.widget.COMPONENT"; + public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA_MIME_TYPE = + "com.android.launcher.extra.widget.CONFIGURATION_DATA_MIME_TYPE"; public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA = "com.android.launcher.extra.widget.CONFIGURATION_DATA"; + + /** + * A simple data class that contains per-item information that the adapter below can reference. + */ + public static class WidgetMimeTypeHandlerData { + public ResolveInfo resolveInfo; + public AppWidgetProviderInfo widgetInfo; + + public WidgetMimeTypeHandlerData(ResolveInfo rInfo, AppWidgetProviderInfo wInfo) { + resolveInfo = rInfo; + widgetInfo = wInfo; + } + } + + /** + * The ListAdapter which presents all the valid widgets that can be created for a given drop. + */ + public static class WidgetListAdapter implements ListAdapter, DialogInterface.OnClickListener { + private LayoutInflater mInflater; + private Launcher mLauncher; + private String mMimeType; + private ClipData mClipData; + private List<WidgetMimeTypeHandlerData> mActivities; + private CellLayout mTargetLayout; + private int mTargetLayoutScreen; + private int[] mTargetLayoutPos; + + public WidgetListAdapter(Launcher l, String mimeType, ClipData data, + List<WidgetMimeTypeHandlerData> list, CellLayout target, + int targetScreen, int[] targetPos) { + mLauncher = l; + mMimeType = mimeType; + mClipData = data; + mActivities = list; + mTargetLayout = target; + mTargetLayoutScreen = targetScreen; + mTargetLayoutPos = targetPos; + } + + @Override + public void registerDataSetObserver(DataSetObserver observer) { + } + + @Override + public void unregisterDataSetObserver(DataSetObserver observer) { + } + + @Override + public int getCount() { + return mActivities.size(); + } + + @Override + public Object getItem(int position) { + return null; + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + final Context context = parent.getContext(); + final PackageManager packageManager = context.getPackageManager(); + + // Lazy-create inflater + if (mInflater == null) { + mInflater = LayoutInflater.from(context); + } + + // Use the convert-view where possible + if (convertView == null) { + convertView = mInflater.inflate(R.layout.external_widget_drop_list_item, parent, + false); + } + + final WidgetMimeTypeHandlerData data = mActivities.get(position); + final ResolveInfo resolveInfo = data.resolveInfo; + final AppWidgetProviderInfo widgetInfo = data.widgetInfo; + + // Set the icon + Drawable d = resolveInfo.loadIcon(packageManager); + ImageView i = (ImageView) convertView.findViewById(R.id.provider_icon); + i.setImageDrawable(d); + + // Set the text + final CharSequence component = resolveInfo.loadLabel(packageManager); + final int[] widgetSpan = new int[2]; + mTargetLayout.rectToCell(widgetInfo.minWidth, widgetInfo.minHeight, widgetSpan); + TextView t = (TextView) convertView.findViewById(R.id.provider); + t.setText(context.getString(R.string.external_drop_widget_pick_format, + component, widgetSpan[0], widgetSpan[1])); + + return convertView; + } + + @Override + public int getItemViewType(int position) { + return 0; + } + + @Override + public int getViewTypeCount() { + return 1; + } + + @Override + public boolean isEmpty() { + return mActivities.isEmpty(); + } + + @Override + public boolean areAllItemsEnabled() { + return false; + } + + @Override + public boolean isEnabled(int position) { + return true; + } + + @Override + public void onClick(DialogInterface dialog, int which) { + final LauncherModel model = mLauncher.getModel(); + final AppWidgetProviderInfo widgetInfo = mActivities.get(which).widgetInfo; + + final PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo(widgetInfo, mMimeType, + mClipData); + mLauncher.addAppWidgetFromDrop(createInfo, mTargetLayoutScreen, mTargetLayoutPos); + } + } } diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 0ac42ddfe..549303d03 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -17,8 +17,13 @@ package com.android.launcher2; -import com.android.common.Search; -import com.android.launcher.R; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import android.animation.Animator; import android.animation.AnimatorSet; @@ -35,17 +40,19 @@ import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; +import android.content.ClipData; +import android.content.ClipDescription; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.content.IntentFilter; import android.content.Intent.ShortcutIconResource; +import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; @@ -78,9 +85,9 @@ import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; +import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.view.WindowManager; -import android.view.View.OnLongClickListener; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.view.inputmethod.InputMethodManager; @@ -89,18 +96,13 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.PopupWindow; import android.widget.TabHost; -import android.widget.TextView; -import android.widget.Toast; import android.widget.TabHost.OnTabChangeListener; import android.widget.TabHost.TabContentFactory; +import android.widget.TextView; +import android.widget.Toast; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import com.android.common.Search; +import com.android.launcher.R; /** * Default launcher application. @@ -1461,8 +1463,33 @@ public final class Launcher extends Activity intent.setComponent(appWidget.configure); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); if (info != null) { - intent.putExtra(InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA, - info.configurationData); + if (info.mimeType != null && !info.mimeType.isEmpty()) { + intent.putExtra( + InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA_MIME_TYPE, + info.mimeType); + + final String mimeType = info.mimeType; + final ClipData clipData = (ClipData) info.configurationData; + final ClipDescription clipDesc = clipData.getDescription(); + for (int i = 0; i < clipDesc.getMimeTypeCount(); ++i) { + if (clipDesc.getMimeType(i).equals(mimeType)) { + final ClipData.Item item = clipData.getItem(i); + final CharSequence stringData = item.getText(); + final Uri uriData = item.getUri(); + final Intent intentData = item.getIntent(); + final String key = + InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA; + if (uriData != null) { + intent.putExtra(key, uriData); + } else if (intentData != null) { + intent.putExtra(key, intentData); + } else if (stringData != null) { + intent.putExtra(key, stringData); + } + break; + } + } + } } startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET); diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index 423a9d1fa..713268ad6 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -16,7 +16,14 @@ package com.android.launcher2; -import com.android.launcher.R; +import java.lang.ref.WeakReference; +import java.net.URISyntaxException; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; @@ -45,14 +52,8 @@ import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; -import java.lang.ref.WeakReference; -import java.net.URISyntaxException; -import java.text.Collator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; +import com.android.launcher.R; +import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData; /** * Maintains in-memory state of the Launcher. It is expected that there should be only one @@ -1529,28 +1530,6 @@ public class LauncherModel extends BroadcastReceiver { } /** - * Ensures that a given shortcut intent actually has all the fields that we need to create a - * proper ShortcutInfo. - */ - boolean validateShortcutIntent(Intent data) { - // We don't require Intent.EXTRA_SHORTCUT_ICON, since we can pull a default fallback icon - return InstallShortcutReceiver.ACTION_INSTALL_SHORTCUT.equals(data.getAction()) && - (data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME) != null) && - (data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT) != null); - } - - /** - * Ensures that a given widget intent actually has all the fields that we need to create a - * proper widget. - */ - boolean validateWidgetIntent(Intent data) { - // We don't require Intent.EXTRA_APPWIDGET_CONFIGURATION_DATA, since that will just be - // forwarded onto the widget's configuration activity if it exists - return InstallWidgetReceiver.ACTION_INSTALL_WIDGET.equals(data.getAction()) && - (data.getStringExtra(InstallWidgetReceiver.EXTRA_APPWIDGET_COMPONENT) != null); - } - - /** * Attempts to find an AppWidgetProviderInfo that matches the given component. */ AppWidgetProviderInfo findAppWidgetProviderInfoWithComponent(Context context, @@ -1565,6 +1544,44 @@ public class LauncherModel extends BroadcastReceiver { return null; } + /** + * Returns a list of all the widgets that can handle configuration with a particular mimeType. + */ + List<WidgetMimeTypeHandlerData> resolveWidgetsForMimeType(Context context, String mimeType) { + final PackageManager packageManager = context.getPackageManager(); + final List<WidgetMimeTypeHandlerData> supportedConfigurationActivities = + new ArrayList<WidgetMimeTypeHandlerData>(); + + final Intent supportsIntent = + new Intent(InstallWidgetReceiver.ACTION_SUPPORTS_CLIPDATA_MIMETYPE); + supportsIntent.setType(mimeType); + + // Create a set of widget configuration components that we can test against + final List<AppWidgetProviderInfo> widgets = + AppWidgetManager.getInstance(context).getInstalledProviders(); + final HashMap<ComponentName, AppWidgetProviderInfo> configurationComponentToWidget = + new HashMap<ComponentName, AppWidgetProviderInfo>(); + for (AppWidgetProviderInfo info : widgets) { + configurationComponentToWidget.put(info.configure, info); + } + + // Run through each of the intents that can handle this type of clip data, and cross + // reference them with the components that are actual configuration components + final List<ResolveInfo> activities = packageManager.queryIntentActivities(supportsIntent, + PackageManager.MATCH_DEFAULT_ONLY); + for (ResolveInfo info : activities) { + final ActivityInfo activityInfo = info.activityInfo; + final ComponentName infoComponent = new ComponentName(activityInfo.packageName, + activityInfo.name); + if (configurationComponentToWidget.containsKey(infoComponent)) { + supportedConfigurationActivities.add( + new InstallWidgetReceiver.WidgetMimeTypeHandlerData(info, + configurationComponentToWidget.get(infoComponent))); + } + } + return supportedConfigurationActivities; + } + ShortcutInfo infoFromShortcutIntent(Context context, Intent data, Bitmap fallbackIcon) { Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); diff --git a/src/com/android/launcher2/PendingAddItemInfo.java b/src/com/android/launcher2/PendingAddItemInfo.java index b7a76f494..7b564e051 100644 --- a/src/com/android/launcher2/PendingAddItemInfo.java +++ b/src/com/android/launcher2/PendingAddItemInfo.java @@ -16,6 +16,7 @@ package com.android.launcher2; +import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.os.Parcelable; @@ -35,5 +36,17 @@ class PendingAddWidgetInfo extends PendingAddItemInfo { // Any configuration data that we want to pass to a configuration activity when // starting up a widget + String mimeType; Parcelable configurationData; + + public PendingAddWidgetInfo(AppWidgetProviderInfo i, String dataMimeType, Parcelable data) { + itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET; + componentName = i.provider; + minWidth = i.minWidth; + minHeight = i.minHeight; + if (dataMimeType != null && data != null) { + mimeType = dataMimeType; + configurationData = data; + } + } }
\ No newline at end of file diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index ddf441a21..4679c645d 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -16,17 +16,20 @@ package com.android.launcher2; -import com.android.launcher.R; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; import android.animation.Animator; +import android.animation.Animator.AnimatorListener; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; -import android.animation.Animator.AnimatorListener; import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.app.AlertDialog; import android.app.WallpaperManager; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; @@ -59,8 +62,8 @@ import android.view.animation.DecelerateInterpolator; import android.widget.TextView; import android.widget.Toast; -import java.util.ArrayList; -import java.util.HashSet; +import com.android.launcher.R; +import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData; /** * The workspace is a wide area with a wallpaper and a finite number of pages. @@ -1371,6 +1374,7 @@ public class Workspace extends SmoothPagedView */ @Override public boolean onDragEvent(DragEvent event) { + final ClipDescription desc = event.getClipDescription(); final CellLayout layout = (CellLayout) getChildAt(mCurrentPage); final int[] pos = new int[2]; layout.getLocationOnScreen(pos); @@ -1387,23 +1391,19 @@ public class Workspace extends SmoothPagedView return false; } - ClipDescription desc = event.getClipDescription(); - if (desc.filterMimeTypes(ClipDescription.MIMETYPE_TEXT_INTENT) != null) { - // Create the drag outline - // We need to add extra padding to the bitmap to make room for the glow effect - final Canvas canvas = new Canvas(); - final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS; - mDragOutline = createExternalDragOutline(canvas, bitmapPadding); + // Create the drag outline + // We need to add extra padding to the bitmap to make room for the glow effect + final Canvas canvas = new Canvas(); + final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS; + mDragOutline = createExternalDragOutline(canvas, bitmapPadding); - // Show the current page outlines to indicate that we can accept this drop - showOutlines(); - layout.setHover(true); - layout.onDragEnter(); - layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1); + // Show the current page outlines to indicate that we can accept this drop + showOutlines(); + layout.setHover(true); + layout.onDragEnter(); + layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1); - return true; - } - break; + return true; case DragEvent.ACTION_DRAG_LOCATION: // Visualize the drop location layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1); @@ -1420,39 +1420,58 @@ public class Workspace extends SmoothPagedView int newDropCount = 0; final LauncherModel model = mLauncher.getModel(); final ClipData data = event.getClipData(); - final int itemCount = data.getItemCount(); - for (int i = 0; i < itemCount; ++i) { - final Intent intent = data.getItem(i).getIntent(); - if (intent != null) { - Object info = null; - if (model.validateShortcutIntent(intent)) { - info = model.infoFromShortcutIntent(mContext, intent, data.getIcon()); - } else if (model.validateWidgetIntent(intent)) { - final ComponentName component = ComponentName.unflattenFromString( - intent.getStringExtra(InstallWidgetReceiver.EXTRA_APPWIDGET_COMPONENT)); - final AppWidgetProviderInfo appInfo = - model.findAppWidgetProviderInfoWithComponent(mContext, component); - - PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo(); - createInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET; - createInfo.componentName = appInfo.provider; - createInfo.minWidth = appInfo.minWidth; - createInfo.minHeight = appInfo.minHeight; - createInfo.configurationData = intent.getParcelableExtra( - InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA); - info = createInfo; - } - if (info != null) { - onDropExternal(x, y, info, layout); - newDropCount++; + // We assume that the mime types are ordered in descending importance of + // representation. So we enumerate the list of mime types and alert the + // user if any widgets can handle the drop. Only the most preferred + // representation will be handled. + pos[0] = x; + pos[1] = y; + final int mimeTypeCount = desc.getMimeTypeCount(); + for (int j = 0; j < mimeTypeCount; ++j) { + final String mimeType = desc.getMimeType(j); + + if (mimeType.equals(InstallShortcutReceiver.SHORTCUT_MIMETYPE)) { + final Intent intent = data.getItem(j).getIntent(); + Object info = model.infoFromShortcutIntent(mContext, intent, data.getIcon()); + onDropExternal(x, y, info, layout); + } else { + final List<WidgetMimeTypeHandlerData> widgets = + model.resolveWidgetsForMimeType(mContext, mimeType); + final int numWidgets = widgets.size(); + + if (numWidgets == 0) { + continue; + } else if (numWidgets == 1) { + // If there is only one item, then go ahead and add and configure + // that widget + final AppWidgetProviderInfo widgetInfo = widgets.get(0).widgetInfo; + final PendingAddWidgetInfo createInfo = + new PendingAddWidgetInfo(widgetInfo, mimeType, data); + mLauncher.addAppWidgetFromDrop(createInfo, mCurrentPage, pos); + } else if (numWidgets > 1) { + // Show the widget picker dialog if there is more than one widget + // that can handle this data type + final InstallWidgetReceiver.WidgetListAdapter adapter = + new InstallWidgetReceiver.WidgetListAdapter(mLauncher, mimeType, + data, widgets, layout, mCurrentPage, pos); + final AlertDialog.Builder builder = + new AlertDialog.Builder(mContext); + builder.setAdapter(adapter, adapter); + builder.setCancelable(true); + builder.setTitle(mContext.getString( + R.string.external_drop_widget_pick_title)); + builder.setIcon(R.drawable.ic_no_applications); + builder.show(); } } + newDropCount++; + break; } // Show error message if we couldn't accept any of the items if (newDropCount <= 0) { - Toast.makeText(mContext, "Only Shortcut Intents accepted.", + Toast.makeText(mContext, mContext.getString(R.string.external_drop_widget_error), Toast.LENGTH_SHORT).show(); } |