Fixing folder bugs:

-> Folders were not loading with ordering properly persisted
-> When an item was put in the trash directly from a folder
   it was trying to remove the item from the folder again, sometimes
   removing an extra item from the folder
-> Making sure the FolderIcon always shows the _last_ 4 items;
   this was not working when the launcher was being restarted
-> Fixed a tiny rotation bug in the FolderIcon

Change-Id: I27423f17fd2f2b396f844c055f1e7abb4f4d5d19
diff --git a/src/com/android/launcher2/DeleteZone.java b/src/com/android/launcher2/DeleteZone.java
index fdd4125..5d9b5db 100644
--- a/src/com/android/launcher2/DeleteZone.java
+++ b/src/com/android/launcher2/DeleteZone.java
@@ -112,12 +112,6 @@
             if (item instanceof LauncherAppWidgetInfo) {
                 mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
             }
-        } else if (source instanceof Folder) {
-            final Folder folder = (Folder) source;
-            final FolderInfo folderInfo = (FolderInfo) folder.getInfo();
-            // Item must be a ShortcutInfo otherwise it couldn't have been in the folder
-            // in the first place.
-            folderInfo.remove((ShortcutInfo)item);
         }
 
         if (item instanceof FolderInfo) {
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index a4aeec4..3411f27 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -25,7 +25,6 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.content.Context;
-import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
@@ -81,6 +80,8 @@
     private int mMaxCountX;
     private int mMaxCountY;
     private Rect mNewSize = new Rect();
+    private ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
+    boolean mItemsInvalidated = false;
 
     /**
      * Used to inflate the Workspace from XML.
@@ -213,9 +214,10 @@
     void bind(FolderInfo info) {
         mInfo = info;
         ArrayList<ShortcutInfo> children = info.contents;
+        setupContentForNumItems(children.size());
         for (int i = 0; i < children.size(); i++) {
             ShortcutInfo child = (ShortcutInfo) children.get(i);
-            onAdd(child);
+            createAndAddShortcut(child);
         }
         mInfo.addListener(this);
     }
@@ -460,25 +462,27 @@
 
         int countX = mContent.getCountX();
         int countY = mContent.getCountY();
-        if (countX * countY < count) {
-            // Current grid is too small, expand it
-            if (countX <= countY && countX < mMaxCountX) {
-                countX++;
-            } else if (countY < mMaxCountY) {
-                countY++;
-            }
-            if (countY == 0) countY++;
+        boolean done = false;
 
-            mContent.setGridSize(countX, countY);
-        } else if ((countX - 1) * countY >= count || (countY - 1) * countX >= count) {
-            // Current grid is too big, shrink it
-            if (countX <= countY) {
-                countY--;
-            } else {
-                countX--;
+        while (!done) {
+            int oldCountX = countX;
+            int oldCountY = countY;
+            if (countX * countY < count) {
+                // Current grid is too small, expand it
+                if (countX <= countY && countX < mMaxCountX) {
+                    countX++;
+                } else if (countY < mMaxCountY) {
+                    countY++;
+                }
+                if (countY == 0) countY++;
+            } else if ((countY - 1) * countX >= count && countY >= countX) {
+                countY = Math.max(0, countY - 1);
+            } else if ((countX - 1) * countY >= count) {
+                countX = Math.max(0, countX - 1);
             }
-            mContent.setGridSize(countX, countY);
+            done = countX == oldCountX && countY == oldCountY;
         }
+        mContent.setGridSize(countX, countY);
         arrangeChildren(list);
     }
 
@@ -531,7 +535,6 @@
     }
 
     private void setupContentForNumItems(int count) {
-
         setupContentDimension(count);
 
         CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
@@ -561,10 +564,14 @@
             info.cellY = vacant[1];
             boolean insert = false;
             mContent.addViewToCellLayout(v, insert ? 0 : -1, (int)info.id, lp, true);
+            LauncherModel.addOrMoveItemInDatabase(mLauncher, info, mInfo.id, 0,
+                    info.cellX, info.cellY);
         }
+        mItemsInvalidated = true;
     }
 
     public void onAdd(ShortcutInfo item) {
+        mItemsInvalidated = true;
         if (!findAndSetEmptyCells(item)) {
             // The current layout is full, can we expand it?
             setupContentForNumItems(getItemCount() + 1);
@@ -581,19 +588,6 @@
         return mContent.getChildrenLayout().getChildAt(index);
     }
 
-    private ArrayList<View> getItemsInReadingOrder() {
-        ArrayList<View> list = new ArrayList<View>();
-        for (int j = 0; j < mContent.getCountY(); j++) {
-            for (int i = 0; i < mContent.getCountX(); i++) {
-                View v = mContent.getChildAt(i, j);
-                if (v != null) {
-                    list.add(v);
-                }
-            }
-        }
-        return list;
-    }
-
     private void onCloseComplete() {
         if (mRearrangeOnClose) {
             setupContentForNumItems(getItemCount());
@@ -602,6 +596,7 @@
     }
 
     public void onRemove(ShortcutInfo item) {
+        mItemsInvalidated = true;
         View v = mContent.getChildAt(mDragItemPosition[0], mDragItemPosition[1]);
         mContent.removeView(v);
         if (mState == STATE_ANIMATING) {
@@ -610,4 +605,20 @@
             setupContentForNumItems(getItemCount());
         }
     }
+
+    public ArrayList<View> getItemsInReadingOrder() {
+        if (mItemsInvalidated) {
+            mItemsInReadingOrder.clear();
+            for (int j = 0; j < mContent.getCountY(); j++) {
+                for (int i = 0; i < mContent.getCountX(); i++) {
+                    View v = mContent.getChildAt(i, j);
+                    if (v != null) {
+                        mItemsInReadingOrder.add(v);
+                    }
+                }
+            }
+            mItemsInvalidated = false;
+        }
+        return mItemsInReadingOrder;
+    }
 }
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index f49297e..939dc44 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher2;
 
+import java.util.ArrayList;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
@@ -27,6 +29,7 @@
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
+import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.TextView;
@@ -265,13 +268,14 @@
         int yShift = (mOriginalHeight - d.getIntrinsicHeight()) / 2;
         canvas.translate(xShift, yShift);
 
-        for (int i = Math.max(0, mFolder.getItemCount() - NUM_ITEMS_IN_PREVIEW);
-                i < mFolder.getItemCount(); i++) {
-            v = (TextView) mFolder.getItemAt(i);
+        ArrayList<View> items = mFolder.getItemsInReadingOrder();
+        int firstItemIndex = Math.max(0, items.size() - NUM_ITEMS_IN_PREVIEW);
+        for (int i = firstItemIndex; i < mFolder.getItemCount(); i++) {
+            v = (TextView) items.get(i);
             d = v.getCompoundDrawables()[1];
 
             canvas.translate(d.getIntrinsicWidth() / 2, d.getIntrinsicHeight() / 2);
-            canvas.rotate(i == 0 ? ICON_ANGLE : -ICON_ANGLE);
+            canvas.rotate(i == firstItemIndex ? ICON_ANGLE : -ICON_ANGLE);
             canvas.translate(-d.getIntrinsicWidth() / 2, -d.getIntrinsicHeight() / 2);
 
             if (d != null) {