Merge "Import revised translations.  DO NOT MERGE" into ics-mr0
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 4bb64f7..c4aef8b 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -37,6 +37,8 @@
     <dimen name="workspace_divider_padding_top">12dp</dimen>
     <dimen name="workspace_divider_padding_bottom">12dp</dimen>
 
+    <dimen name="app_icon_padding_top">6dp</dimen>
+
     <!-- height of the bottom row of controls -->
     <dimen name="button_bar_height">68dip</dimen>
     <!-- Because portal animations go beyond the bounds of an icon, we need
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index 1b806a6..544b970 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -29,6 +29,8 @@
     <dimen name="folder_cell_width">96dp</dimen>
     <dimen name="folder_cell_height">96dp</dimen>
 
+    <dimen name="app_icon_padding_top">4dp</dimen>
+
 <!-- AppsCustomize -->
     <dimen name="apps_customize_tab_bar_height">56dp</dimen>
     <dimen name="apps_customize_cell_width">96dp</dimen>
diff --git a/res/values-sw600dp/styles.xml b/res/values-sw600dp/styles.xml
index 31c2abd..0609002 100644
--- a/res/values-sw600dp/styles.xml
+++ b/res/values-sw600dp/styles.xml
@@ -23,7 +23,7 @@
         <item name="android:drawablePadding">0dp</item>
         <item name="android:paddingLeft">4dp</item>
         <item name="android:paddingRight">4dp</item>
-        <item name="android:paddingTop">4dp</item>
+        <item name="android:paddingTop">@dimen/app_icon_padding_top</item>
         <item name="android:paddingBottom">4dp</item>
         <item name="android:textSize">13sp</item>
     </style>
@@ -38,7 +38,7 @@
         <item name="android:drawablePadding">0dp</item>
         <item name="android:paddingLeft">4dp</item>
         <item name="android:paddingRight">4dp</item>
-        <item name="android:paddingTop">4dp</item>
+        <item name="android:paddingTop">@dimen/app_icon_padding_top</item>
         <item name="android:paddingBottom">4dp</item>
         <item name="android:textSize">13sp</item>
     </style>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 27e00b3..124cf16 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -42,6 +42,8 @@
     <dimen name="hotseat_height_gap">-1dp</dimen>
     <dimen name="workspace_overscroll_drawable_padding">0dp</dimen>
 
+    <dimen name="app_icon_padding_top">8dp</dimen>
+
 <!-- QSB -->
     <dimen name="toolbar_button_vertical_padding">0dip</dimen>
     <dimen name="toolbar_button_horizontal_padding">12dip</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 04bddf1..f575f00 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -72,7 +72,7 @@
         <item name="android:drawablePadding">8dp</item>
         <item name="android:paddingLeft">4dp</item>
         <item name="android:paddingRight">4dp</item>
-        <item name="android:paddingTop">8dp</item>
+        <item name="android:paddingTop">@dimen/app_icon_padding_top</item>
         <item name="android:paddingBottom">4dp</item>
     </style>
 
@@ -80,7 +80,7 @@
         <item name="android:drawablePadding">2dp</item>
         <item name="android:paddingLeft">4dp</item>
         <item name="android:paddingRight">4dp</item>
-        <item name="android:paddingTop">6dp</item>
+        <item name="android:paddingTop">@dimen/app_icon_padding_top</item>
         <item name="android:paddingBottom">4dp</item>
     </style>
 
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 4718b31..ed9d0cf 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -202,7 +202,6 @@
     // Dimens
     private int mContentWidth;
     private int mAppIconSize;
-    private int mMaxWidgetSpan, mMinWidgetSpan;
     private int mWidgetCountX, mWidgetCountY;
     private int mWidgetWidthGap, mWidgetHeightGap;
     private final int mWidgetPreviewIconPaddedDimension;
@@ -223,7 +222,7 @@
     // Previews & outlines
     ArrayList<AppsCustomizeAsyncTask> mRunningTasks;
     private HolographicOutlineHelper mHolographicOutlineHelper;
-    private static final int sPageSleepDelay = 200;
+    private static final int sPageSleepDelay = 150;
 
     public AppsCustomizePagedView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -259,11 +258,6 @@
         a.recycle();
         mWidgetSpacingLayout = new PagedViewCellLayout(getContext());
 
-        // The max widget span is the length N, such that NxN is the largest bounds that the widget
-        // preview can be before applying the widget scaling
-        mMinWidgetSpan = 1;
-        mMaxWidgetSpan = 3;
-
         // The padding on the non-matched dimension for the default widget preview icons
         // (top + bottom)
         mWidgetPreviewIconPaddedDimension =
@@ -355,6 +349,12 @@
         mSaveInstanceStateItemIndex = index;
     }
 
+    private void updatePageCounts() {
+        mNumWidgetPages = (int) Math.ceil(mWidgets.size() /
+                (float) (mWidgetCountX * mWidgetCountY));
+        mNumAppsPages = (int) Math.ceil((float) mApps.size() / (mCellCountX * mCellCountY));
+    }
+
     protected void onDataReady(int width, int height) {
         // Note that we transpose the counts in portrait so that we get a similar layout
         boolean isLandscape = getResources().getConfiguration().orientation ==
@@ -376,9 +376,7 @@
         mWidgetSpacingLayout.calculateCellCount(width, height, maxCellCountX, maxCellCountY);
         mCellCountX = mWidgetSpacingLayout.getCellCountX();
         mCellCountY = mWidgetSpacingLayout.getCellCountY();
-        mNumWidgetPages = (int) Math.ceil(mWidgets.size() /
-                (float) (mWidgetCountX * mWidgetCountY));
-        mNumAppsPages = (int) Math.ceil((float) mApps.size() / (mCellCountX * mCellCountY));
+        updatePageCounts();
 
         // Force a measure to update recalculate the gaps
         int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST);
@@ -390,6 +388,7 @@
         int page = getPageForComponent(mSaveInstanceStateItemIndex);
         invalidatePageData(Math.max(0, page));
 
+        // Calculate the position for the cling punch through
         int[] offset = new int[2];
         int[] pos = mWidgetSpacingLayout.estimateCellPosition(mClingFocusedX, mClingFocusedY);
         mLauncher.getDragLayer().getLocationInDragLayer(this, offset);
@@ -455,6 +454,7 @@
         mWidgets.addAll(shortcuts);
         Collections.sort(mWidgets,
                 new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager));
+        updatePageCounts();
 
         if (wasEmpty) {
             // The next layout pass will trigger data-ready if both widgets and apps are set, so request
@@ -605,7 +605,6 @@
                             !layout.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY);
                 }
             }
-            // TODO-APPS_CUSTOMIZE: We need to handle this for folders as well later.
             if (showOutOfSpaceMessage) {
                 mLauncher.showOutOfSpaceMessage();
             }
@@ -636,10 +635,6 @@
         }
     }
 
-    public void setCurrentPageToWidgets() {
-        invalidatePageData(0);
-    }
-
     protected void snapToPage(int whichPage, int delta, int duration) {
         super.snapToPage(whichPage, delta, duration);
         updateCurrentTab(whichPage);
@@ -1300,6 +1295,7 @@
     public void setApps(ArrayList<ApplicationInfo> list) {
         mApps = list;
         Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR);
+        updatePageCounts();
 
         // The next layout pass will trigger data-ready if both widgets and apps are set, so 
         // request a layout to do this test and invalidate the page data when ready.
@@ -1319,6 +1315,7 @@
     @Override
     public void addApps(ArrayList<ApplicationInfo> list) {
         addAppsWithoutInvalidate(list);
+        updatePageCounts();
         invalidatePageData();
     }
     private int findAppByComponent(List<ApplicationInfo> list, ApplicationInfo item) {
@@ -1346,6 +1343,7 @@
     @Override
     public void removeApps(ArrayList<ApplicationInfo> list) {
         removeAppsWithoutInvalidate(list);
+        updatePageCounts();
         invalidatePageData();
     }
     @Override
@@ -1355,6 +1353,8 @@
         // place in the list.
         removeAppsWithoutInvalidate(list);
         addAppsWithoutInvalidate(list);
+        updatePageCounts();
+
         invalidatePageData();
     }
 
@@ -1401,6 +1401,9 @@
     public void surrender() {
         // TODO: If we are in the middle of any process (ie. for holographic outlines, etc) we
         // should stop this now.
+
+        // Stop all background tasks
+        cancelAllTasks();
     }
 
     /*
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index 404b088..3690c12 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -75,8 +75,6 @@
     }
     void selectWidgetsTab() {
         setContentTypeImmediate(AppsCustomizePagedView.ContentType.Widgets);
-        mAppsCustomizePane.setCurrentPageToWidgets();
-
         setCurrentTabByTag(WIDGETS_TAB_TAG);
     }
 
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index ad87fa6..54fdcc5 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -218,6 +218,7 @@
         });
         mCrosshairsAnimator.getAnimator().setInterpolator(mEaseOutInterpolator);
 
+        mDragCell[0] = mDragCell[1] = -1;
         for (int i = 0; i < mDragOutlines.length; i++) {
             mDragOutlines[i] = new Point(-1, -1);
         }
@@ -1171,13 +1172,13 @@
         result[1] = Math.max(0, result[1]); // Snap to top
     }
 
-    void visualizeDropLocation(
-            View v, Bitmap dragOutline, int originX, int originY, int spanX, int spanY) {
+    void visualizeDropLocation(View v, Bitmap dragOutline, int originX, int originY,
+            int spanX, int spanY, Point dragOffset, Rect dragRegion) {
 
         final int oldDragCellX = mDragCell[0];
         final int oldDragCellY = mDragCell[1];
         final int[] nearest = findNearestVacantArea(originX, originY, spanX, spanY, v, mDragCell);
-        if (v != null) {
+        if (v != null && dragOffset == null) {
             mDragCenter.set(originX + (v.getWidth() / 2), originY + (v.getHeight() / 2));
         } else {
             mDragCenter.set(originX, originY);
@@ -1198,7 +1199,7 @@
             int left = topLeft[0];
             int top = topLeft[1];
 
-            if (v != null) {
+            if (v != null && dragOffset == null) {
                 // When drawing the drag outline, it did not account for margin offsets
                 // added by the view's parent.
                 MarginLayoutParams lp = (MarginLayoutParams) v.getLayoutParams();
@@ -1213,11 +1214,19 @@
                 left += ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap)
                         - dragOutline.getWidth()) / 2;
             } else {
-                // Center the drag outline in the cell
-                left += ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap)
-                        - dragOutline.getWidth()) / 2;
-                top += ((mCellHeight * spanY) + ((spanY - 1) * mHeightGap)
-                        - dragOutline.getHeight()) / 2;
+                if (dragOffset != null && dragRegion != null) {
+                    // Center the drag region *horizontally* in the cell and apply a drag
+                    // outline offset
+                    left += dragOffset.x + ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap)
+                             - dragRegion.width()) / 2;
+                    top += dragOffset.y;
+                } else {
+                    // Center the drag outline in the cell
+                    left += ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap)
+                            - dragOutline.getWidth()) / 2;
+                    top += ((mCellHeight * spanY) + ((spanY - 1) * mHeightGap)
+                            - dragOutline.getHeight()) / 2;
+                }
             }
 
             final int oldIndex = mDragOutlineCurrent;
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index 82aa30f..ee054ab 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -16,10 +16,9 @@
 
 package com.android.launcher2;
 
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.Handler;
@@ -187,7 +186,7 @@
         int dragLayerX = loc[0];
         int dragLayerY = loc[1];
 
-        startDrag(b, dragLayerX, dragLayerY, source, dragInfo, dragAction, dragRegion);
+        startDrag(b, dragLayerX, dragLayerY, source, dragInfo, dragAction, null, dragRegion);
         b.recycle();
 
         if (dragAction == DRAG_ACTION_MOVE) {
@@ -214,7 +213,7 @@
         int dragLayerX = loc[0];
         int dragLayerY = loc[1];
 
-        startDrag(bmp, dragLayerX, dragLayerY, source, dragInfo, dragAction, dragRegion);
+        startDrag(bmp, dragLayerX, dragLayerY, source, dragInfo, dragAction, null, dragRegion);
 
         if (dragAction == DRAG_ACTION_MOVE) {
             v.setVisibility(View.GONE);
@@ -235,7 +234,7 @@
      */
     public void startDrag(Bitmap b, int dragLayerX, int dragLayerY,
             DragSource source, Object dragInfo, int dragAction) {
-        startDrag(b, dragLayerX, dragLayerY, source, dragInfo, dragAction, null);
+        startDrag(b, dragLayerX, dragLayerY, source, dragInfo, dragAction, null, null);
     }
 
     /**
@@ -253,7 +252,7 @@
      *          Makes dragging feel more precise, e.g. you can clip out a transparent border
      */
     public void startDrag(Bitmap b, int dragLayerX, int dragLayerY,
-            DragSource source, Object dragInfo, int dragAction, Rect dragRegion) {
+            DragSource source, Object dragInfo, int dragAction, Point dragOffset, Rect dragRegion) {
         if (PROFILE_DRAWING_DURING_DRAG) {
             android.os.Debug.startMethodTracing("Launcher");
         }
@@ -290,6 +289,9 @@
         final DragView dragView = mDragObject.dragView = new DragView(mLauncher, b, registrationX,
                 registrationY, 0, 0, b.getWidth(), b.getHeight());
 
+        if (dragOffset != null) {
+            dragView.setDragVisualizeOffset(new Point(dragOffset));
+        }
         if (dragRegion != null) {
             dragView.setDragRegion(new Rect(dragRegion));
         }
diff --git a/src/com/android/launcher2/DragView.java b/src/com/android/launcher2/DragView.java
index 386cb55..dd94175 100644
--- a/src/com/android/launcher2/DragView.java
+++ b/src/com/android/launcher2/DragView.java
@@ -24,11 +24,9 @@
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.Point;
 import android.graphics.Rect;
-import android.os.IBinder;
 import android.view.View;
-import android.view.WindowManager;
-import android.view.WindowManagerImpl;
 import android.view.animation.DecelerateInterpolator;
 
 import com.android.launcher.R;
@@ -39,6 +37,7 @@
     private int mRegistrationX;
     private int mRegistrationY;
 
+    private Point mDragVisualizeOffset = null;
     private Rect mDragRegion = null;
     private DragLayer mDragLayer = null;
     private boolean mHasDrawn = false;
@@ -135,6 +134,14 @@
         return mDragRegion.height();
     }
 
+    public void setDragVisualizeOffset(Point p) {
+        mDragVisualizeOffset = p;
+    }
+
+    public Point getDragVisualizeOffset() {
+        return mDragVisualizeOffset;
+    }
+
     public void setDragRegion(Rect r) {
         mDragRegion = r;
     }
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index cde5d94..8945076 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -136,12 +136,6 @@
         icon.mFolder = folder;
         Resources res = launcher.getResources();
 
-        // We need to reload the static values when configuration changes in case they are
-        // different in another configuration
-        if (sStaticValuesDirty) {
-            sSharedFolderLeaveBehind = res.getDrawable(R.drawable.portal_ring_rest);
-        }
-
         icon.mFolderRingAnimator = new FolderRingAnimator(launcher, icon);
         folderInfo.addListener(icon);
 
@@ -184,6 +178,7 @@
                 sPreviewPadding = res.getDimensionPixelSize(R.dimen.folder_preview_padding);
                 sSharedOuterRingDrawable = res.getDrawable(R.drawable.portal_ring_outer_holo);
                 sSharedInnerRingDrawable = res.getDrawable(R.drawable.portal_ring_inner_holo);
+                sSharedFolderLeaveBehind = res.getDrawable(R.drawable.portal_ring_rest);
                 sStaticValuesDirty = false;
             }
         }
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index d1f9617..e4f1fe8 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -17,12 +17,12 @@
 package com.android.launcher2;
 
 import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 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;
@@ -40,6 +40,7 @@
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.Point;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -1784,7 +1785,7 @@
                 v.getWidth() + padding, v.getHeight() + padding, Bitmap.Config.ARGB_8888);
 
         canvas.setBitmap(b);
-        drawDragView(v, canvas, padding, false);
+        drawDragView(v, canvas, padding, true);
         mOutlineHelper.applyMediumExpensiveOutlineWithBlur(b, canvas, outlineColor, outlineColor);
         canvas.setBitmap(null);
         return b;
@@ -1866,6 +1867,8 @@
     }
 
     public void beginDragShared(View child, DragSource source) {
+        Resources r = getResources();
+
         // We need to add extra padding to the bitmap to make room for the glow effect
         final int bitmapPadding = HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS;
 
@@ -1878,17 +1881,22 @@
         final int dragLayerX = (int) mTempXY[0] + (child.getWidth() - bmpWidth) / 2;
         int dragLayerY = mTempXY[1] - bitmapPadding / 2;
 
+        Point dragVisualizeOffset = null;
         Rect dragRect = null;
-        if (child instanceof BubbleTextView) {
-            int iconSize = getResources().getDimensionPixelSize(R.dimen.app_icon_size);
+        if (child instanceof BubbleTextView || child instanceof PagedViewIcon) {
+            int iconSize = r.getDimensionPixelSize(R.dimen.app_icon_size);
+            int iconPaddingTop = r.getDimensionPixelSize(R.dimen.app_icon_padding_top);
             int top = child.getPaddingTop();
             int left = (bmpWidth - iconSize) / 2;
             int right = left + iconSize;
             int bottom = top + iconSize;
             dragLayerY += top;
+            // Note: The drag region is used to calculate drag layer offsets, but the
+            // dragVisualizeOffset in addition to the dragRect (the size) to position the outline.
+            dragVisualizeOffset = new Point(-bitmapPadding / 2, iconPaddingTop - bitmapPadding / 2);
             dragRect = new Rect(left, top, right, bottom);
         } else if (child instanceof FolderIcon) {
-            int previewSize = getResources().getDimensionPixelSize(R.dimen.folder_preview_size);
+            int previewSize = r.getDimensionPixelSize(R.dimen.folder_preview_size);
             dragRect = new Rect(0, 0, child.getWidth(), previewSize);
         }
 
@@ -1899,7 +1907,7 @@
         }
 
         mDragController.startDrag(b, dragLayerX, dragLayerY, source, child.getTag(),
-                DragController.DRAG_ACTION_MOVE, dragRect);
+                DragController.DRAG_ACTION_MOVE, dragVisualizeOffset, dragRect);
         b.recycle();
     }
 
@@ -2354,13 +2362,13 @@
             showOutlines();
             layout.setIsDragOccuring(true);
             layout.onDragEnter();
-            layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1);
+            layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1, null, null);
 
             return true;
         }
         case DragEvent.ACTION_DRAG_LOCATION:
             // Visualize the drop location
-            layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1);
+            layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1, null, null);
             return true;
         case DragEvent.ACTION_DROP: {
             // Try and add any shortcuts
@@ -2727,7 +2735,8 @@
             if (!mCreateUserFolderOnDrop && !isOverFolder) {
                 mDragTargetLayout.visualizeDropLocation(child, mDragOutline,
                         (int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1],
-                        item.spanX, item.spanY);
+                        item.spanX, item.spanY, d.dragView.getDragVisualizeOffset(),
+                        d.dragView.getDragRegion());
             }
         }
     }