Bug 581534 - Performance grouping: incorrect group states with freeze

Signed-off-by: Dirk Fauth <dirk.fauth@googlemail.com>

Change-Id: I4b13643bd171b3af42b419ed490e46c1ffbdf567
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/freeze/CompositeFreezeLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/freeze/CompositeFreezeLayer.java
index 0b4546a..878aa20 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/freeze/CompositeFreezeLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/freeze/CompositeFreezeLayer.java
@@ -256,14 +256,23 @@
             startColumn = 0;
         }
 
+        // special condition, group frozen while in scrolled state and group is
+        // only partially visible
+        if (columnPosition == 0 && startColumn < 0) {
+            startColumnLayout = 0;
+            endColumn += this.viewportLayer.getOriginColumnPosition() - this.viewportLayer.getMinimumOriginColumnPosition();
+        }
+
         int start = startColumn;
         int end = endColumn;
         if (isFrozen() && endColumnLayout == 1) {
-            int scrollAdjust = 0;
+            int numberOfNotVisibleColumns = 0;
             if (this.freezeLayer.getTopLeftPosition().columnPosition >= 0) {
-                scrollAdjust = this.freezeLayer.getUnderlyingLayerByPosition(0, 0).getStartXOfColumnPosition(this.freezeLayer.getTopLeftPosition().columnPosition);
+                numberOfNotVisibleColumns = this.freezeLayer.getTopLeftPosition().columnPosition;
             }
-            end = endColumn - this.viewportLayer.getScrollableLayer().getColumnPositionByX(this.viewportLayer.getOrigin().getX() - scrollAdjust);
+
+            int toLocal = this.viewportLayer.underlyingToLocalColumnPosition(this.viewportLayer.getScrollableLayer(), endColumn);
+            end = toLocal + numberOfNotVisibleColumns;
         }
 
         ILayer startLayer = null;
@@ -291,10 +300,10 @@
                 }
             }
         } else {
-            startLayer = getChildLayerByLayoutCoordinate(startColumnLayout, 1);
-            startX = this.freezeLayer.getStartXOfColumnPosition(start);
+            int startColumnToUse = start < 0 ? 0 : start;
+            startX = this.freezeLayer.getStartXOfColumnPosition(startColumnToUse);
             int freezeWidth = 0;
-            int column = start;
+            int column = startColumnToUse;
             for (; column < this.freezeLayer.getColumnCount(); column++) {
                 freezeWidth += this.freezeLayer.getColumnWidthByPosition(column);
             }
@@ -386,14 +395,23 @@
             startRow = 0;
         }
 
+        // special condition, group frozen while in scrolled state and group is
+        // only partially visible
+        if (rowPosition == 0 && startRow < 0) {
+            startRowLayout = 0;
+            endRow += this.viewportLayer.getOriginRowPosition() - this.viewportLayer.getMinimumOriginRowPosition();
+        }
+
         int start = startRow;
         int end = endRow;
         if (isFrozen() && endRowLayout == 1) {
-            int scrollAdjust = 0;
+            int numberOfNotVisibleRows = 0;
             if (this.freezeLayer.getTopLeftPosition().rowPosition >= 0) {
-                scrollAdjust = this.freezeLayer.getUnderlyingLayerByPosition(0, 0).getStartYOfRowPosition(this.freezeLayer.getTopLeftPosition().rowPosition);
+                numberOfNotVisibleRows = this.freezeLayer.getTopLeftPosition().rowPosition;
             }
-            end = endRow - this.viewportLayer.getScrollableLayer().getRowPositionByY(this.viewportLayer.getOrigin().getY() - scrollAdjust);
+
+            int toLocal = this.viewportLayer.underlyingToLocalRowPosition(this.viewportLayer.getScrollableLayer(), endRow);
+            end = toLocal + numberOfNotVisibleRows;
         }
 
         ILayer startLayer = null;
@@ -421,10 +439,10 @@
                 }
             }
         } else {
-            startLayer = getChildLayerByLayoutCoordinate(1, startRowLayout);
-            startY = this.freezeLayer.getStartYOfRowPosition(start);
+            int startRowToUse = start < 0 ? 0 : start;
+            startY = this.freezeLayer.getStartYOfRowPosition(startRowToUse);
             int freezeHeight = 0;
-            int row = start;
+            int row = startRowToUse;
             for (; row < this.freezeLayer.getRowCount(); row++) {
                 freezeHeight += this.freezeLayer.getRowHeightByPosition(row);
             }
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ViewportLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ViewportLayer.java
index 14edbbc..38abe1d 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ViewportLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/viewport/ViewportLayer.java
@@ -363,8 +363,10 @@
 
     /**
      * @return The origin column position
+     *
+     * @since 2.1
      */
-    private int getOriginColumnPosition() {
+    public int getOriginColumnPosition() {
         // special handling for column resizing to 0
         // used e.g. with the ResizeColumnHideShowLayer in combination
         // with percentage sizing
@@ -380,8 +382,10 @@
 
     /**
      * @return The origin row position
+     *
+     * @since 2.1
      */
-    private int getOriginRowPosition() {
+    public int getOriginRowPosition() {
         return this.scrollableLayer.getRowPositionByY(getOrigin().getY());
     }