1 /******************************************************************************* 2 * Copyright (c) 2006, 2015 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation 14 * - fix in bug: 195908,198035,215069,215735,227421 15 *******************************************************************************/ 16 17 package org.eclipse.jface.viewers; 18 19 import java.util.Objects; 20 21 import org.eclipse.swt.custom.StyleRange; 22 import org.eclipse.swt.graphics.Color; 23 import org.eclipse.swt.graphics.Font; 24 import org.eclipse.swt.graphics.Image; 25 import org.eclipse.swt.graphics.Rectangle; 26 import org.eclipse.swt.widgets.Control; 27 import org.eclipse.swt.widgets.Item; 28 import org.eclipse.swt.widgets.Widget; 29 30 /** 31 * The ViewerCell is the JFace representation of a cell entry in a ViewerRow. 32 * 33 * @since 3.3 34 * 35 */ 36 public class ViewerCell { 37 private int columnIndex; 38 39 private ViewerRow row; 40 41 private Object element; 42 43 /** 44 * Constant denoting the cell above current one (value is 1). 45 */ 46 public static int ABOVE = 1; 47 48 /** 49 * Constant denoting the cell below current one (value is 2). 50 */ 51 public static int BELOW = 1 << 1; 52 53 /** 54 * Constant denoting the cell to the left of the current one (value is 4). 55 */ 56 public static int LEFT = 1 << 2; 57 58 /** 59 * Constant denoting the cell to the right of the current one (value is 8). 60 */ 61 public static int RIGHT = 1 << 3; 62 63 /** 64 * Create a new instance of the receiver on the row. 65 * 66 * @param row 67 * @param columnIndex 68 */ ViewerCell(ViewerRow row, int columnIndex, Object element)69 ViewerCell(ViewerRow row, int columnIndex, Object element) { 70 this.row = row; 71 this.columnIndex = columnIndex; 72 this.element = element; 73 } 74 75 /** 76 * Get the index of the cell. 77 * 78 * @return the index 79 */ getColumnIndex()80 public int getColumnIndex() { 81 return columnIndex; 82 } 83 84 /** 85 * Get the bounds of the cell. 86 * 87 * @return {@link Rectangle} 88 */ getBounds()89 public Rectangle getBounds() { 90 return row.getBounds(columnIndex); 91 } 92 93 /** 94 * Get the element this row represents. 95 * 96 * @return {@link Object} 97 */ getElement()98 public Object getElement() { 99 if (element != null) { 100 return element; 101 } 102 103 if (row != null) { 104 return row.getElement(); 105 } 106 107 return null; 108 } 109 110 /** 111 * Return the text for the cell. 112 * 113 * @return {@link String} 114 */ getText()115 public String getText() { 116 return row.getText(columnIndex); 117 } 118 119 /** 120 * Return the Image for the cell. 121 * 122 * @return {@link Image} or <code>null</code> 123 */ getImage()124 public Image getImage() { 125 return row.getImage(columnIndex); 126 } 127 128 /** 129 * Set the background color of the cell. 130 * 131 * @param background color to set 132 */ setBackground(Color background)133 public void setBackground(Color background) { 134 row.setBackground(columnIndex, background); 135 136 } 137 138 /** 139 * Set the foreground color of the cell. 140 * 141 * @param foreground color to set 142 */ setForeground(Color foreground)143 public void setForeground(Color foreground) { 144 row.setForeground(columnIndex, foreground); 145 146 } 147 148 /** 149 * Set the font of the cell. 150 * 151 * @param font font to set 152 */ setFont(Font font)153 public void setFont(Font font) { 154 row.setFont(columnIndex, font); 155 156 } 157 158 /** 159 * Set the text for the cell. 160 * 161 * @param text text to set 162 */ setText(String text)163 public void setText(String text) { 164 row.setText(columnIndex, text); 165 166 } 167 168 /** 169 * Set the Image for the cell. 170 * 171 * @param image image to set 172 */ setImage(Image image)173 public void setImage(Image image) { 174 row.setImage(columnIndex, image); 175 176 } 177 178 /** 179 * Set the style ranges to be applied on the text label Note: Requires 180 * {@link StyledCellLabelProvider} with owner draw enabled. 181 * 182 * @param styleRanges 183 * the styled ranges 184 * 185 * @since 3.4 186 */ setStyleRanges(StyleRange[] styleRanges)187 public void setStyleRanges(StyleRange[] styleRanges) { 188 row.setStyleRanges(columnIndex, styleRanges); 189 } 190 191 /** 192 * Returns the style ranges to be applied on the text label or 193 * <code>null</code> if no style ranges have been set. 194 * 195 * @return styleRanges the styled ranges 196 * 197 * @since 3.4 198 */ getStyleRanges()199 public StyleRange[] getStyleRanges() { 200 return row.getStyleRanges(columnIndex); 201 } 202 203 /** 204 * Set the columnIndex. 205 * 206 * @param column the column index to set 207 */ setColumn(int column)208 void setColumn(int column) { 209 columnIndex = column; 210 211 } 212 213 /** 214 * Set the row to rowItem and the columnIndex to column. 215 * 216 * @param rowItem the row item to set 217 * @param column the column index to set 218 * @param element the element to set 219 */ update(ViewerRow rowItem, int column, Object element)220 void update(ViewerRow rowItem, int column, Object element) { 221 row = rowItem; 222 columnIndex = column; 223 this.element = element; 224 } 225 226 /** 227 * Return the item for the receiver. 228 * 229 * @return {@link Item} 230 */ getItem()231 public Widget getItem() { 232 return row.getItem(); 233 } 234 235 /** 236 * Get the control for this cell. 237 * 238 * @return {@link Control} 239 */ getControl()240 public Control getControl() { 241 return row.getControl(); 242 } 243 244 /** 245 * Get the current index. This can be different from the original index when 246 * columns are reordered 247 * 248 * @return the current index (as shown in the UI) 249 * @since 3.4 250 */ getVisualIndex()251 public int getVisualIndex() { 252 return row.getVisualIndex(getColumnIndex()); 253 } 254 255 /** 256 * Returns the specified neighbor of this cell, or <code>null</code> if no 257 * neighbor exists in the given direction. Direction constants can be 258 * combined by bitwise OR; for example, this method will return the cell to 259 * the upper-left of the current cell by passing {@link #ABOVE} | 260 * {@link #LEFT}. If <code>sameLevel</code> is <code>true</code>, only cells 261 * in sibling rows (under the same parent) will be considered. 262 * 263 * @param directionMask 264 * the direction mask used to identify the requested neighbor 265 * cell 266 * @param sameLevel 267 * if <code>true</code>, only consider cells from sibling rows 268 * @return the requested neighbor cell, or <code>null</code> if not found 269 */ getNeighbor(int directionMask, boolean sameLevel)270 public ViewerCell getNeighbor(int directionMask, boolean sameLevel) { 271 ViewerRow row; 272 273 if ((directionMask & ABOVE) == ABOVE) { 274 row = this.row.getNeighbor(ViewerRow.ABOVE, sameLevel); 275 } else if ((directionMask & BELOW) == BELOW) { 276 row = this.row.getNeighbor(ViewerRow.BELOW, sameLevel); 277 } else { 278 row = this.row; 279 } 280 281 if (row != null) { 282 int columnIndex; 283 columnIndex = getVisualIndex(); 284 285 int modifier = 0; 286 287 if ((directionMask & LEFT) == LEFT) { 288 modifier = -1; 289 } else if ((directionMask & RIGHT) == RIGHT) { 290 modifier = 1; 291 } else { 292 return row.getCellAtVisualIndex(columnIndex); 293 } 294 295 columnIndex += modifier; 296 297 if (columnIndex >= 0 && columnIndex < row.getColumnCount()) { 298 ViewerCell cell = row.getCellAtVisualIndex(columnIndex); 299 while (cell != null && columnIndex < row.getColumnCount() - 1 && columnIndex > 0) { 300 if (cell.isVisible()) { 301 break; 302 } 303 304 columnIndex += modifier; 305 cell = row.getCellAtVisualIndex(columnIndex); 306 } 307 308 return cell; 309 } 310 } 311 312 return null; 313 } 314 315 /** 316 * @return the row 317 */ getViewerRow()318 public ViewerRow getViewerRow() { 319 return row; 320 } 321 322 /** 323 * The location and bounds of the area where the text is drawn depends on 324 * various things (image displayed, control with SWT.CHECK) 325 * 326 * @return The bounds of the of the text area. May return <code>null</code> 327 * if the underlying widget implementation doesn't provide this 328 * information 329 * @since 3.4 330 */ getTextBounds()331 public Rectangle getTextBounds() { 332 return row.getTextBounds(columnIndex); 333 } 334 335 /** 336 * Returns the location and bounds of the area where the image is drawn 337 * 338 * @return The bounds of the of the image area. May return <code>null</code> 339 * if the underlying widget implementation doesn't provide this 340 * information 341 * @since 3.4 342 */ getImageBounds()343 public Rectangle getImageBounds() { 344 return row.getImageBounds(columnIndex); 345 } 346 347 /** 348 * Gets the foreground color of the cell. 349 * 350 * @return the foreground of the cell or <code>null</code> for the default 351 * foreground 352 * 353 * @since 3.4 354 */ getForeground()355 public Color getForeground() { 356 return row.getForeground(columnIndex); 357 } 358 359 /** 360 * Gets the background color of the cell. 361 * 362 * @return the background of the cell or <code>null</code> for the default 363 * background 364 * 365 * @since 3.4 366 */ getBackground()367 public Color getBackground() { 368 return row.getBackground(columnIndex); 369 } 370 371 /** 372 * Gets the font of the cell. 373 * 374 * @return the font of the cell or <code>null</code> for the default font 375 * 376 * @since 3.4 377 */ getFont()378 public Font getFont() { 379 return row.getFont(columnIndex); 380 } 381 382 @Override hashCode()383 public int hashCode() { 384 final int prime = 31; 385 int result = 1; 386 result = prime * result + columnIndex; 387 return prime * result + Objects.hashCode(row); 388 } 389 390 @Override equals(Object obj)391 public boolean equals(Object obj) { 392 if (this == obj) 393 return true; 394 if (obj == null) 395 return false; 396 if (getClass() != obj.getClass()) 397 return false; 398 final ViewerCell other = (ViewerCell) obj; 399 return columnIndex == other.columnIndex && Objects.equals(row, other.row); 400 } 401 isVisible()402 private boolean isVisible() { 403 return row.isColumnVisible(columnIndex); 404 } 405 406 /** 407 * Scroll the cell into view 408 * 409 * @return true if the cell was scrolled into view 410 * @since 3.5 411 */ scrollIntoView()412 public boolean scrollIntoView() { 413 return row.scrollCellIntoView(columnIndex); 414 } 415 } 416