Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Nebula » [Grid, GridViewer][PATCH] rowspan support
[Grid, GridViewer][PATCH] rowspan support [message #594408] Wed, 15 April 2009 16:16
Claes Rosell is currently offline Claes RosellFriend
Messages: 17
Registered: July 2009
Junior Member
Hi.

I would like to contribute a patch that enables rowspan in the Grid and
GridViewer components of Nebula.

The rowspan support will need a lot of testing, I have only tested the
things that was needed for our project and so far it looks good. I hope
this patch can help others who also is in need of this functionality.

I tried to do a "small impact" patch, some changes may seem a bit
hackish for this reason. Like the small change in
DefaultCellRenderer.java, which minimizes the code changes in the
algorithm of Grid, and the getColumn(GridItem, Point) method of Grid.java.

Totally this patch affects four files. One of those files concerns the
GridViewer, the other three files are related to the Grid.

Any feedback is welcome.

Best regards
/Claes Rosell


---------------------------------------------

Index: src/org/eclipse/nebula/widgets/grid/internal/DefaultCellRend erer.java
============================================================ =======
RCS file:
/cvsroot/technology/org.eclipse.swt.nebula/org.eclipse.nebul a.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/ DefaultCellRenderer.java,v
retrieving revision 1.13
diff -u -r1.13 DefaultCellRenderer.java
---
src/org/eclipse/nebula/widgets/grid/internal/DefaultCellRend erer.java 8
Jan 2008 16:22:31 -0000 1.13
+++
src/org/eclipse/nebula/widgets/grid/internal/DefaultCellRend erer.java 15
Apr 2009 15:33:04 -0000
@@ -260,8 +260,8 @@

if (isCellFocus())
{
- Rectangle focusRect = new Rectangle(getBounds().x -1,
getBounds().y - 1, getBounds().width,
- getBounds().height + 1);
+ Rectangle focusRect = new Rectangle(getBounds().x,
getBounds().y, getBounds().width - 1,
+ getBounds().height);


gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_ FOREGROUND));
gc.drawRectangle(focusRect);
Index: src/org/eclipse/nebula/jface/gridviewer/GridColumnLabelProvi der.java
============================================================ =======
RCS file:
/cvsroot/technology/org.eclipse.swt.nebula/org.eclipse.nebul a.widgets.grid/src/org/eclipse/nebula/jface/gridviewer/GridC olumnLabelProvider.java,v
retrieving revision 1.2
diff -u -r1.2 GridColumnLabelProvider.java
---
src/org/eclipse/nebula/jface/gridviewer/GridColumnLabelProvi der.java 10
Apr 2009 11:38:28 -0000 1.2
+++
src/org/eclipse/nebula/jface/gridviewer/GridColumnLabelProvi der.java 15
Apr 2009 15:33:03 -0000
@@ -37,6 +37,30 @@
public String getRowHeaderText(Object element) {
return null;
}
+
+ /**
+ * Returns the number of columns this element should span
+ *
+ * @param element
+ * the model element
+ * @return colSpan
+ */
+ public int getColumnSpan(Object element)
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the number of rows this element should span
+ *
+ * @param element
+ * the model element
+ * @return rowSpan
+ */
+ public int getRowSpan(Object element)
+ {
+ return 0;
+ }


/**
@@ -44,11 +68,20 @@
*/
public void update(ViewerCell cell) {
super.update(cell);
- String rowText = getRowHeaderText(cell.getElement());

+ Object element = cell.getElement();
+
+ String rowText = getRowHeaderText(element);
+ int colSpan = getColumnSpan(element);
+ int rowSpan = getRowSpan(element);
+
+ GridItem gridItem = (GridItem)cell.getViewerRow().getItem();
if (rowText != null) {
- ((GridItem) cell.getViewerRow().getItem()).setHeaderText(rowText);
+ gridItem.setHeaderText(rowText);
}
+
+ gridItem.setColumnSpan(cell.getColumnIndex(), colSpan);
+ gridItem.setRowSpan(cell.getColumnIndex(), rowSpan);
}

}
Index: src/org/eclipse/nebula/widgets/grid/GridItem.java
============================================================ =======
RCS file:
/cvsroot/technology/org.eclipse.swt.nebula/org.eclipse.nebul a.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridItem. java,v
retrieving revision 1.23
diff -u -r1.23 GridItem.java
--- src/org/eclipse/nebula/widgets/grid/GridItem.java 10 Apr 2009
11:38:28 -0000 1.23
+++ src/org/eclipse/nebula/widgets/grid/GridItem.java 15 Apr 2009
15:33:04 -0000
@@ -72,6 +72,11 @@
private ArrayList columnSpans = new ArrayList();

/**
+ * List of row spaning.
+ */
+ private ArrayList rowSpans = new ArrayList();
+
+ /**
* Default background color.
*/
private Color defaultBackground;
@@ -512,7 +517,26 @@
width += parent.getColumn(columnIndex + i).getWidth();
}

- return new Rectangle(origin.x, origin.y, width - 1, getHeight());
+ int indexOfCurrentItem = parent.getIndexOfItem(this);
+
+ GridItem item = parent.getItem(indexOfCurrentItem);
+ int height = item.getHeight();
+ span = getRowSpan(columnIndex);
+
+ for (int i = 1; i <= span; i++)
+ {
+ /* We will probably need another escape condition here */
+ if(parent.getItems().length <= indexOfCurrentItem + i) {
+ break;
+ }
+
+ item = parent.getItem(indexOfCurrentItem + i);
+ if(item.isVisible()) {
+ height += item.getHeight() + 1;
+ }
+ }
+
+ return new Rectangle(origin.x, origin.y, width - 1, height);
}

/**
@@ -582,6 +606,31 @@
}

/**
+ * Returns the row span for the given column index in the receiver.
+ *
+ * @param index the row index
+ * @return the number of row spanned (0 equals no row spanned)
+ * @throws org.eclipse.swt.SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that
+ * created the receiver</li>
+ * </ul>
+ */
+ public int getRowSpan(int index)
+ {
+ checkWidget();
+ if( index >= 0 && index < rowSpans.size()) {
+ Integer i = (Integer)rowSpans.get(index);
+ if(i != null) {
+ return i.intValue();
+ }
+ }
+
+ return 0;
+ }
+
+ /**
* Returns the font that the receiver will use to paint textual
information
* for this item.
*
@@ -1094,6 +1143,27 @@
}

/**
+ * Sets the row spanning for the row at the given index to span the
+ * given number of subsequent rows.
+ *
+ * @param index row index that should span
+ * @param span number of subsequent rows to span
+ * @throws org.eclipse.swt.SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that
+ * created the receiver</li>
+ * </ul>
+ */
+ public void setRowSpan(int index, int span)
+ {
+ checkWidget();
+ rowSpans.set(index, new Integer(span));
+ parent.setHasSpanning(true);
+ parent.redraw();
+ }
+
+ /**
* Sets the expanded state of the receiver.
* <p>
*
@@ -1835,6 +1905,7 @@
ensureSize(images);
ensureSize(texts);
ensureSize(columnSpans);
+ ensureSize(rowSpans);
ensureSize(tooltips);
}

@@ -1933,6 +2004,7 @@
checks.clear();
checkable.clear();
columnSpans.clear();
+ rowSpans.clear();
fonts.clear();
foregrounds.clear();
grayeds.clear();
Index: src/org/eclipse/nebula/widgets/grid/Grid.java
============================================================ =======
RCS file:
/cvsroot/technology/org.eclipse.swt.nebula/org.eclipse.nebul a.widgets.grid/src/org/eclipse/nebula/widgets/grid/Grid.java ,v
retrieving revision 1.64
diff -u -r1.64 Grid.java
--- src/org/eclipse/nebula/widgets/grid/Grid.java 10 Apr 2009 11:38:28
-0000 1.64
+++ src/org/eclipse/nebula/widgets/grid/Grid.java 15 Apr 2009 15:33:04 -0000
@@ -12,10 +12,16 @@

import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.Vector;

+import javax.swing.CellRendererPane;
+
import org.eclipse.nebula.widgets.grid.internal.DefaultBottomLeftRe nderer;
import
org.eclipse.nebula.widgets.grid.internal.DefaultColumnGroupH eaderRenderer;
import org.eclipse.nebula.widgets.grid.internal.DefaultDropPointRen derer;
@@ -65,6 +71,7 @@
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TypedListener;

@@ -1190,6 +1197,29 @@
*/
public GridColumn getColumn(Point point)
{
+ return getColumn(null, point);
+ }
+
+ /**
+ * Returns the column at the given point and a known item in the
receiver or null if no such
+ * column exists. The point is in the coordinate system of the
receiver.
+ *
+ * @param item a known GridItem
+ * @param point the point used to locate the column
+ * @return the column at the given point
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
+ * </ul>
+ * @throws org.eclipse.swt.SWTException
+ * <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that
+ * created the receiver</li>
+ * </ul>
+ */
+ private GridColumn getColumn(GridItem item, Point point)
+ {
checkWidget();
if (point == null)
{
@@ -1238,7 +1268,10 @@
if (hasSpanning)
{
// special logic for column spanning
- GridItem item = getItem(point);
+ if(item == null) {
+ item = getItem(point);
+ }
+
if (item != null)
{
int displayColIndex =
displayOrderedColumns.indexOf(overThis);
@@ -1783,6 +1816,8 @@
y2 += headerHeight;
}

+ GridItem itemToReturn = null;
+
int row=getTopIndex();
while(row<items.size() && y2<=getClientArea().height)
{
@@ -1793,7 +1828,8 @@

if (p.y >= y2 && p.y < y2+currItemHeight+1)
{
- return currItem;
+ itemToReturn = currItem;
+ break;
}

y2 += currItemHeight +1;
@@ -1801,7 +1837,36 @@
row++;
}

- return null;
+ if (hasSpanning)
+ {
+ if (itemToReturn != null)
+ {
+ int itemIndex = this.getIndexOfItem(itemToReturn);
+
+ GridColumn gridColumn = getColumn(itemToReturn, point);
+ int displayColIndex =
displayOrderedColumns.indexOf(gridColumn);
+
+
+ // track back all previous columns and check their spanning
+ for (int i = 0; i < itemIndex; i++)
+ {
+ GridItem gridItem = this.getItem(i);
+ if (gridItem.isVisible() == false)
+ {
+ continue;
+ }
+ int span = gridItem.getRowSpan(displayColIndex);
+
+ if (i + span >= itemIndex)
+ {
+ itemToReturn = gridItem;
+ break;
+ }
+ }
+ }
+ }
+
+ return itemToReturn;
}

/**
@@ -1946,6 +2011,18 @@
checkWidget();
return (GridItem[])items.toArray(new GridItem[items.size()]);
}
+
+ /**
+ *
+ * @param item
+ * @return t
+ */
+ public int getIndexOfItem(GridItem item)
+ {
+ checkWidget();
+
+ return items.indexOf(item);
+ }

/**
* Returns the line color.
@@ -5121,6 +5198,7 @@
int insertMarkPosX2 = -1;
int insertMarkPosY = -1;
boolean insertMarkPosFound = false;
+ Map doNotDrawMap = new HashMap();

e.gc.setBackground(getBackground());
this.drawBackground(e.gc,0,0,getSize().x,getSize().y);
@@ -5158,7 +5236,6 @@

for (int i = 0; i < visibleRows; i++)
{
-
x = 0;

x -= getHScrollSelectionInPixels();
@@ -5184,20 +5261,21 @@
{
boolean cellInRowSelected = false;

+ // Get the columns that should not be draw becouse if
spanning
+ Set columnsNotToDraw = (Set)doNotDrawMap.get(item);
+ if(columnsNotToDraw == null) {
+ columnsNotToDraw = new HashSet();
+ doNotDrawMap.put(item, columnsNotToDraw);
+ }

if (rowHeaderVisible)
{
-
// row header is actually painted later
x += rowHeaderWidth;
}

int focusY = y;

- // This variable is used to count how many columns are
- // skipped because the previous column spanned over them
- int skipBecauseSpanned = 0;
-
int colIndex = 0;

// draw regular cells for each column
@@ -5209,22 +5287,40 @@
if (!column.isVisible())
{
colIndex++;
- if (skipBecauseSpanned > 0)
- {
- skipBecauseSpanned--;
- }
continue;
}
+
+ int width = column.getWidth();

- if (skipBecauseSpanned == 0)
+ if(columnsNotToDraw.contains(new Integer(colIndex))
== false)
{
- skipBecauseSpanned =
item.getColumnSpan(indexOf(column));
+ int indexOfColumn = indexOf(column);

- int width = column.getWidth();
+ int nrRowsToSpan = item.getRowSpan(indexOfColumn);
+ int nrColumnsToSpan =
item.getColumnSpan(indexOfColumn);
+ int rowIndex = getIndexOfItem(item);
+
+ for(int rowCounter = 0 ; rowCounter <= nrRowsToSpan;
rowCounter++)
+ {
+ Item tempItem = this.getItem(rowIndex + rowCounter);
+
+ Set tempSet = (Set)doNotDrawMap.get(tempItem);
+ if(tempSet == null) {
+ tempSet = new HashSet();
+ doNotDrawMap.put(tempItem, tempSet);
+ }
+
+ for(int colCounter = 0 ; colCounter <=
nrColumnsToSpan; colCounter++)
+ {
+ if(colCounter != 0 || rowCounter != 0) {
+ tempSet.add(new Integer(colIndex + colCounter));
+ }
+ }
+ }

- if (skipBecauseSpanned > 0)
+ if (nrColumnsToSpan > 0)
{
- for (int j = 0; j < skipBecauseSpanned; j++)
+ for (int j = 0; j < nrColumnsToSpan; j++)
{
if (getColumnCount() <= colIndex + j + 1)
{
@@ -5239,10 +5335,11 @@

if (x + width >= 0 && x < getClientArea().width )
{
+ Rectangle boundOfColumn =
item.getBounds(indexOf(column));

- column.getCellRenderer().setBounds(x, y,
width, item.getHeight());
+ column.getCellRenderer().setBounds(x, y,
width, boundOfColumn.height);

- e.gc.setClipping(new Rectangle(x -1,y -1,width
+1,item.getHeight() + 2));
+ e.gc.setClipping(new Rectangle(x -1,y -1,width
+1, boundOfColumn.height + 2));

column.getCellRenderer().setRow(i + 1);

@@ -5306,17 +5403,10 @@
insertMarkPosFound = true;
}
}
-
-
- x += width;
-
- }
- else
- {
- skipBecauseSpanned--;
}
- colIndex++;

+ x += width;
+ colIndex++;
}

if (x < getClientArea().width)
Previous Topic:grid widget part of SWT
Next Topic:[Grid, GridViewer][PATCH] rowspan support
Goto Forum:
  


Current Time: Thu Apr 25 01:21:14 GMT 2024

Powered by FUDForum. Page generated in 0.03570 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top