/**
  * Returns the image stored at the given column index in the receiver, or null if the image has
  * not been set or if the column does not exist.
  *
  * @param index the column index
  * @return the image stored at the given column index in the receiver
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Image getImage(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   return getImageInternal(index);
 }
 private int getSpacing(final int index) {
   int result = 0;
   if (parent.hasColumnImages(index)) {
     result = parent.getCellSpacing();
   }
   return result;
 }
 /**
  * Gets the image indent.
  *
  * @return the indent
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public int getImageIndent() {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   // [rh] The only method to manipulate the image indent (setImageIndent) is
   // deprecated and thus not implemented, therefore we can safely return 0
   return 0;
 }
 final void clear() {
   data = null;
   checked = false;
   grayed = false;
   parent.updateScrollBars();
   if ((parent.style & SWT.VIRTUAL) != 0) {
     cached = false;
     parent.redraw();
   }
 }
 private int getHeight(final int index) {
   int result = 0;
   int columnCount = parent.getColumnCount();
   boolean singleColumn = index == 0 && columnCount == 0;
   boolean columnInRange = index >= 0 && index < columnCount;
   if (singleColumn || columnInRange) {
     result = parent.getItemHeight();
   }
   return result;
 }
 /**
  * Returns the text stored at the given column index in the receiver, or empty string if the text
  * has not been set.
  *
  * @param index the column index
  * @return the text stored at the given column index in the receiver
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public String getText(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   String result = "";
   if (data != null && index >= 0 && index < data.length && data[index] != null) {
     result = data[index].text;
   }
   return result;
 }
 /**
  * Returns <code>true</code> if the receiver is grayed, and false otherwise. When the parent does
  * not have the <code>CHECK</code> style, return false.
  *
  * @return the grayed state of the checkbox
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public boolean getGrayed() {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   boolean result = false;
   if ((parent.style & SWT.CHECK) != 0) {
     result = grayed;
   }
   return result;
 }
 private int getLeft(final int index) {
   int result = 0;
   int columnCount = parent.getColumnCount();
   if (index == 0 && columnCount == 0) {
     result = getCheckWidth(index) - parent.leftOffset;
   } else if (index >= 0 && index < columnCount) {
     // TODO [rh] consider applying the leftOffset already in Column#getLeft()
     int columnLeft = parent.getColumn(index).getLeft();
     result = getCheckWidth(index) + columnLeft - parent.leftOffset;
   }
   return result;
 }
 /**
  * Returns the foreground color that the receiver will use to draw.
  *
  * @return the receiver's foreground color
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Color getForeground() {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   Color result;
   if (foreground == null) {
     result = parent.getForeground();
   } else {
     result = foreground;
   }
   return result;
 }
 /**
  * Returns the font that the receiver will use to paint textual information for this item.
  *
  * @return the receiver's font
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Font getFont() {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   Font result;
   if (font == null) {
     result = parent.getFont();
   } else {
     result = font;
   }
   return result;
 }
 /**
  * Returns a rectangle describing the size and location relative to its parent of an image at a
  * column in the table. An empty rectangle is returned if index exceeds the index of the table's
  * last column.
  *
  * @param index the index that specifies the column
  * @return the receiver's bounding image rectangle
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Rectangle getImageBounds(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   int itemIndex = parent.indexOf(this);
   Rectangle cellPadding = parent.getCellPadding();
   int left = getLeft(index) + cellPadding.x;
   int top = getTop(itemIndex);
   int width = getImageWidth(index);
   int height = getHeight(index);
   return new Rectangle(left, top, width, height);
 }
 /**
  * Sets the font that the receiver will use to paint textual information for this item to the font
  * specified by the argument, or to the default font for that kind of control if the argument is
  * null.
  *
  * @param font the new font (or null)
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setFont(final Font font) {
   checkWidget();
   if (font != null && font.isDisposed()) {
     error(SWT.ERROR_INVALID_ARGUMENT);
   }
   if (!equals(this.font, font)) {
     this.font = font;
     markCached();
     if (parent.getColumnCount() == 0) {
       parent.updateScrollBars();
     }
     parent.redraw();
   }
 }
 /**
  * Returns the font that the receiver will use to paint textual information for the specified cell
  * in this item.
  *
  * @param index the column index
  * @return the receiver's font
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Font getFont(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   Font result = getFont();
   if (data != null
       && index >= 0
       && index < data.length
       && data[index] != null
       && data[index].font != null) {
     result = data[index].font;
   }
   return result;
 }
 /**
  * Sets the font that the receiver will use to paint textual information for the specified cell in
  * this item to the font specified by the argument, or to the default font for that kind of
  * control if the argument is null.
  *
  * @param index the column index
  * @param font the new font (or null)
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setFont(final int index, final Font font) {
   checkWidget();
   if (font != null && font.isDisposed()) {
     error(SWT.ERROR_INVALID_ARGUMENT);
   }
   int count = Math.max(1, parent.getColumnCount());
   if (index >= 0 && index < count) {
     ensureData(index, count);
     if (!equals(font, data[index].font)) {
       data[index].font = font;
       markCached();
       parent.redraw();
     }
   }
 }
 /**
  * Returns the foreground color at the given column index in the receiver.
  *
  * @param index the column index
  * @return the foreground color
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Color getForeground(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   Color result = getForeground();
   if (data != null
       && index >= 0
       && index < data.length
       && data[index] != null
       && data[index].foreground != null) {
     result = data[index].foreground;
   }
   return result;
 }
 /**
  * Sets the foreground color at the given column index in the receiver to the color specified by
  * the argument, or to the default system color for the item if the argument is null.
  *
  * @param index the column index
  * @param color the new color (or null)
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setForeground(final int index, final Color color) {
   checkWidget();
   if (color != null && color.isDisposed()) {
     error(SWT.ERROR_INVALID_ARGUMENT);
   }
   int count = Math.max(1, parent.getColumnCount());
   if (index >= 0 && index < count) {
     ensureData(index, count);
     if (!equals(data[index].foreground, color)) {
       data[index].foreground = color;
       markCached();
       parent.redraw();
     }
   }
 }
 private int getImageWidth(final int index) {
   int result = 0;
   Image image = getImage(index);
   if (image != null) {
     result = parent.getItemImageSize().x;
   }
   return result;
 }
 private int getTextWidth(final int index) {
   int result = 0;
   String text = getText(index);
   if (text.length() > 0) {
     result = Graphics.stringExtent(parent.getFont(), text).x;
   }
   return result;
 }
 final void removeData(final int index) {
   if (data != null && parent.getColumnCount() > 1) {
     Data[] newData = new Data[data.length - 1];
     System.arraycopy(data, 0, newData, 0, index);
     int offSet = data.length - index - 1;
     System.arraycopy(data, index + 1, newData, index, offSet);
     data = newData;
   }
 }
 /**
  * Sets the receiver's text at a column
  *
  * @param index the column index
  * @param text the new text
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_NULL_ARGUMENT - if the text is null
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setText(final int index, final String text) {
   checkWidget();
   if (text == null) {
     SWT.error(SWT.ERROR_NULL_ARGUMENT);
   }
   int count = Math.max(1, parent.getColumnCount());
   if (index >= 0 && index < count) {
     ensureData(index, count);
     if (!text.equals(data[index].text)) {
       data[index].text = text;
       markCached();
       if (parent.getColumnCount() == 0) {
         parent.updateScrollBars();
       }
       parent.redraw();
     }
   }
 }
 /**
  * Sets the receiver's foreground color to the color specified by the argument, or to the default
  * system color for the item if the argument is null.
  *
  * @param color the new color (or null)
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setForeground(final Color color) {
   checkWidget();
   if (color != null && color.isDisposed()) {
     error(SWT.ERROR_INVALID_ARGUMENT);
   }
   if (!equals(foreground, color)) {
     foreground = color;
     markCached();
     parent.redraw();
   }
 }
 /**
  * Returns a rectangle describing the receiver's size and location relative to its parent at a
  * column in the table.
  *
  * @param index the index that specifies the column
  * @return the receiver's bounding column rectangle
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Rectangle getBounds(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   Rectangle result;
   int columnCount = parent.getColumnCount();
   if (columnCount > 0 && (index < 0 || index >= columnCount)) {
     result = new Rectangle(0, 0, 0, 0);
   } else {
     Rectangle textBounds = getTextBounds(index);
     int left = getLeft(index);
     int itemIndex = parent.indexOf(this);
     int top = getTop(itemIndex);
     int width = 0;
     if (index == 0 && columnCount == 0) {
       Rectangle imageBounds = getImageBounds(index);
       int spacing = getSpacing(index);
       int paddingWidth = parent.getCellPadding().width;
       width = imageBounds.width + spacing + textBounds.width + paddingWidth;
     } else if (index >= 0 && index < columnCount) {
       width = parent.getColumn(index).getWidth() - getCheckWidth(index);
     }
     int height = getHeight(index);
     result = new Rectangle(left, top, width, height);
   }
   return result;
 }
 /**
  * Returns a rectangle describing the size and location relative to its parent of the text at a
  * column in the table. An empty rectangle is returned if index exceeds the index of the table's
  * last column.
  *
  * @param index the index that specifies the column
  * @return the receiver's bounding text rectangle
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Rectangle getTextBounds(final int index) {
   checkWidget();
   int itemIndex = parent.indexOf(this);
   if (!parent.checkData(this, itemIndex)) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   int left = 0;
   int top = 0;
   int width = 0;
   Rectangle cellPadding = parent.getCellPadding();
   if (index == 0 && parent.getColumnCount() == 0) {
     int imageWidth = 0;
     int spacing = 0;
     if (parent.hasColumnImages(0)) {
       imageWidth = parent.getItemImageSize().x;
       spacing = getSpacing(0);
     }
     left = getLeft(0) + cellPadding.x + imageWidth + spacing;
     top = getTop(itemIndex);
     Font font = getFont();
     width = Graphics.stringExtent(font, getText(0)).x;
   } else if (itemIndex != -1 && index < parent.getColumnCount()) {
     int imageWidth = 0;
     if (parent.hasColumnImages(index)) {
       imageWidth = parent.getItemImageSize().x;
     }
     int spacing = getSpacing(index);
     left = getLeft(index) + cellPadding.x + imageWidth + spacing;
     top = getTop(itemIndex);
     width = getColumnWidth(index) - cellPadding.width - imageWidth - spacing;
     if (width < 0) {
       width = 0;
     }
   }
   int height = getHeight(index);
   return new Rectangle(left, top, width, height);
 }
 /**
  * Sets the receiver's image at a column.
  *
  * @param index the column index
  * @param image the new image
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the image has been disposed
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setImage(final int index, final Image image) {
   checkWidget();
   if (image != null && image.isDisposed()) {
     error(SWT.ERROR_INVALID_ARGUMENT);
   }
   int count = Math.max(1, parent.getColumnCount());
   if (index >= 0 && index < count) {
     ensureData(index, count);
     if (!equals(data[index].image, image)) {
       parent.updateColumnImageCount(index, data[index].image, image);
       data[index].image = image;
       parent.updateItemImageSize(image);
       markCached();
       if (parent.getColumnCount() == 0) {
         parent.updateScrollBars();
       }
       parent.redraw();
     }
   }
 }
 private int getColumnWidth(final int index) {
   TableColumn column = parent.getColumn(index);
   return column.getWidth() - getCheckWidth(index);
 }
 private int getTop(final int itemIndex) {
   int relativeItemIndex = itemIndex - parent.getTopIndex();
   int headerHeight = parent.getHeaderHeight();
   int itemHeight = parent.getItemHeight();
   return headerHeight + relativeItemIndex * itemHeight;
 }
 final int getCheckWidth(final int index) {
   return parent.getCheckWidth(index);
 }
 final int getPackWidth(final int index) {
   return getImageWidth(index)
       + getSpacing(index)
       + getTextWidth(index)
       + parent.getCellPadding().width;
 }
 void releaseParent() {
   parent.destroyItem(this, parent.indexOf(this));
 }