/*
   * (non-Javadoc) Method declared on Layout.
   */
  public void layout(final Composite c, boolean flush) {

    // System.out.println("manualResizing=" + manualResizing);
    // System.out.println("layout=" + this.hashCode());
    if (manualResizing) {
      return;
    }

    // System.out.println("TableViewerCreatorLayout layout " + toString() + " "+ (i++) );

    if (fillHorizontal || continuousLayout) {
      initColumnsControlListener();
    }

    if (layoutExecutionLimiter == null) {
      // layoutExecutionLimiter = new ExecutionLimiter(this.timeBetweenTwoLayouts, true) {
      //
      // @Override
      // public void execute(boolean isFinalExecution) {

      if (c.isDisposed()) {
        return;
      }

      // c.getDisplay().syncExec(new Runnable() {
      //
      // /* (non-Javadoc)
      // * @see java.lang.Runnable#run()
      // */
      // public void run() {
      //
      if (!firstTime && !continuousLayout) {
        return;
      }

      try {
        if (tableViewerCreator.getTable().isDisposed()) {
          return;
        }
        tableViewerCreator.getTable().setLayout(null);

        layout(c);

      } finally {
        if (!tableViewerCreator.getTable().isDisposed()) {
          tableViewerCreator.getTable().setLayout(TableViewerCreatorLayout.this);
        }
      }
    }

    // });
    // }
    //
    // };
    // }

    // layoutExecutionLimiter.startIfExecutable();

  }
  /** DOC amaumont Comment method "initColumnsControlListener". */
  private void initColumnsControlListener() {

    if (columnControlListenersInitialized) {
      return;
    }

    columnControlListenersInitialized = true;

    ControlListener controlListener =
        new ControlListener() {

          public void controlMoved(ControlEvent e) {
            // System.out.println("COntrol moved");
          }

          public void controlResized(ControlEvent e) {
            // System.out.println("TableColumn controlResized");
            controlResizedExecute(e);
          }
        };

    final Table table = tableViewerCreator.getTable();
    TableColumn[] tableColumns = table.getColumns();
    for (int i = 0; i < tableColumns.length; i++) {
      tableColumns[i].addControlListener(controlListener);
    }
  }
 /**
  * Add columns width.
  *
  * @return width of table
  */
 private int computeCurrentTableWidth() {
   TableColumn[] tableColumns = tableViewerCreator.getTable().getColumns();
   int width = 0;
   for (int i = 0; i < tableColumns.length; i++) {
     width += tableColumns[i].getWidth();
   }
   return width;
 }
  /** DOC amaumont Comment method "init". */
  private void init() {
    this.asyncThreadingForManualColumnResizingFalse =
        new AsynchronousThreading(
            500,
            false,
            tableViewerCreator.getCompositeParent().getDisplay(),
            new Runnable() {

              public void run() {
                // System.out.println("manualResizing = false !!!!!!!!!!!!!!!!!!!!!!!!!!");
                manualResizing = false;
                // tableViewerCreator.layout();
              }
            });
  }
  /** DOC amaumont Comment method "init". */
  private void init() {

    this.table = tableViewerCreator.getTable();

    final Listener storeCursorPositionListener =
        new Listener() {

          public void handleEvent(Event event) {
            cursorPositionAtMouseDown = new Point(event.x, event.y);
          }
        };
    table.addListener(SWT.MouseDown, storeCursorPositionListener);

    Listener dragDetectlistener =
        new Listener() {

          public void handleEvent(Event event) {

            int columnIndex = getColumnIndex(cursorPositionAtMouseDown);

            if (isColumnSelection(columnIndex)) {
              draggingOnSelectionColumn = true;
              itemIndexAtDraggingStart = getItemIndex(cursorPositionAtMouseDown);
              setShellCursor(true);
            }
          }
        };
    table.addListener(SWT.DragDetect, dragDetectlistener);

    final Listener resetDraggingListener =
        new Listener() {

          public void handleEvent(Event event) {
            if (draggingOnSelectionColumn) {
              draggingOnSelectionColumn = false;
              Point pointCursor = getCursorPositionFromTableOrigin(event);
              int columnIndex = getColumnIndex(pointCursor);
              if (!isColumnSelection(columnIndex)) {
                setShellCursor(false);
              }
            }
          }
        };

    table.addListener(SWT.FocusOut, resetDraggingListener);
    table.getDisplay().addFilter(SWT.MouseUp, resetDraggingListener);

    final Listener mouseMoveListener =
        new Listener() {

          public void handleEvent(Event event) {
            Point pointCursor = getCursorPositionFromTableOrigin(event);

            int columnIndex = getColumnIndex(pointCursor);
            // System.out.println("handleEvent " + draggingOnSelectionColumn + " " + columnIndex);
            if (!draggingOnSelectionColumn) {
              if (event.widget != table) {
                if (!(event.widget instanceof Table)) {
                  // System.out.println("isColumnSelection");
                  setShellCursor(false);
                }
                return;
              }
              if (isColumnSelection(columnIndex)) {
                setShellCursor(true);
              } else {
                // System.out.println("setShellCursor(false)");
                setShellCursor(false);
              }

            } else {

              setShellCursor(true);
              if (columnIndex == -1) {
                pointCursor.x = 0;
              }

              int currentItemIndexUnderCursor = getItemIndex(pointCursor);
              if (currentItemIndexUnderCursor != -1) {
                int indexStart = 0;
                int indexEnd = 0;
                if (currentItemIndexUnderCursor >= itemIndexAtDraggingStart) {
                  indexStart = itemIndexAtDraggingStart;
                  indexEnd = currentItemIndexUnderCursor;
                } else {
                  indexStart = currentItemIndexUnderCursor;
                  indexEnd = itemIndexAtDraggingStart;
                }

                int countSelected = indexEnd - indexStart + 1;
                int[] selection = new int[countSelected];
                for (int i = 0; i < countSelected; i++) {
                  selection[i] = i + indexStart;
                }

                boolean selectionHasChanged =
                    !Arrays.equals(tableViewerCreator.getTable().getSelectionIndices(), selection);
                if (selectionHasChanged) {
                  tableViewerCreator.getSelectionHelper().setSelection(selection);
                }
              }
            }
          }
        };

    table.getDisplay().addFilter(SWTFacade.MouseMove, mouseMoveListener);

    table.addDisposeListener(
        new DisposeListener() {

          public void widgetDisposed(DisposeEvent e) {
            table.removeListener(SWT.MouseDown, storeCursorPositionListener);
            table.removeListener(SWT.MouseDown, resetDraggingListener);
            table.removeListener(SWT.FocusOut, resetDraggingListener);
            table.removeDisposeListener(this);
            table.getDisplay().removeFilter(SWT.MouseUp, resetDraggingListener);
            table.getDisplay().removeFilter(SWTFacade.MouseMove, mouseMoveListener);
            if (tableCursor != null) {
              tableCursor.dispose();
            }
            if (imageSelectionCursor != null) {
              imageSelectionCursor.dispose();
            }
          }
        });
  }
 /**
  * DOC amaumont MouseTableSelectionHelper constructor comment.
  *
  * @param table
  */
 public MouseTableSelectionHelper(TableViewerCreatorNotModifiable tableViewerCreator) {
   this.tableViewerCreator = tableViewerCreator;
   this.firstColumnMasked = tableViewerCreator.isFirstColumnMasked();
   init();
 }
  /**
   * DOC amaumont Comment method "resizeControl".
   *
   * @param e
   */
  private synchronized void controlResizedExecute(ControlEvent e) {
    final TableColumn currentTableColumn = (TableColumn) e.widget;
    if (!WindowSystem.isGTK() && !columnsResizingByLayout && (fillHorizontal || continuousLayout)) {
      // System.out.println("controlResizedExecute");
      if (continuousLayout && !fillHorizontal) {
        // asyncThreadingForManualColumnResizingFalse.interrupt();
        // if (!fillHorizontal) {
        // manualResizing = false;
        // }
      }
      if (!manualResizing) {
        manualResizing = true;
        final Table table = currentTableColumn.getParent();
        Rectangle bounds = table.getClientArea();
        // System.out.println("currentTableColumn.getWidth()=" + currentTableColumn.getWidth());
        // System.out.println("columnsResizingByLayout=" + columnsResizingByLayout);
        // System.out.println("currentTableColumn.hashCode()=" + currentTableColumn.hashCode());

        if (table.getHorizontalBar().getSelection() == 0) {
          if (!WindowSystem.isGTK()) {
            changeColumnLayoutData(currentTableColumn, bounds);
          }

          lastDisplayedWidth = bounds.width + widthAdjustValue;
          // System.out.println("lastWidth="+lastDisplayedWidth);
          // System.out.println("referenceWidth="+referenceWidth);

          referenceWidth = computeCurrentTableWidth();

          TableColumn[] tableColumns = table.getColumns();
          if (fillHorizontal && tableColumns.length - 1 >= 0) {
            int widthAll = referenceWidth;

            int indexLastColumn = tableColumns.length - 1;
            TableColumn lastTableColumn = tableColumns[indexLastColumn];
            TableViewerCreatorColumnNotModifiable tableViewerCreatorColumn =
                (TableViewerCreatorColumnNotModifiable)
                    tableViewerCreator.getColumns().get(indexLastColumn);

            ColumnLayoutData columnLayoutData = columnsLayoutData.get(indexLastColumn);
            int minimumWidth = 0;
            if (columnLayoutData instanceof ColumnWeightData) {
              minimumWidth = ((ColumnWeightData) columnLayoutData).minimumWidth;
            } else if (columnLayoutData instanceof ColumnPixelData) {
              minimumWidth = ((ColumnPixelData) columnLayoutData).width;
            }

            int widthLastColumn = lastTableColumn.getWidth();
            int newColumnWidth = lastDisplayedWidth - (widthAll - widthLastColumn);
            if (newColumnWidth > minimumWidth) {
              if (referenceWidth - widthLastColumn < lastDisplayedWidth) {
                if (newColumnWidth > 0) {
                  // System.out.println("change");
                  lastTableColumn.setWidth(newColumnWidth);
                  changeColumnLayoutData(lastTableColumn, bounds);
                }
              } else {
                int width = tableViewerCreatorColumn.getWidth();
                // System.out.println("weight=" + weight);
                // System.out.println("width=" + width);
                if (columnLayoutData instanceof ColumnWeightData) {
                  lastTableColumn.setWidth(width);
                  changeColumnLayoutData(lastTableColumn, bounds);
                }
              }
            }
            referenceWidth = computeCurrentTableWidth() + widthAdjustValue;
            // System.out.println("referenceWidth=" + referenceWidth);
          }
        }
        if (continuousLayout && !fillHorizontal) {
          // asyncThreadingForManualColumnResizingFalse.start();
          Runnable runable =
              new Runnable() {

                public void run() {
                  try {
                    synchronized (this) {
                      wait(500);
                      manualResizing = false;
                    }

                  } catch (InterruptedException e) {
                    manualResizing = false;
                  }
                }
              };
          new Thread(runable).start();
        }
      }

      if (fillHorizontal) {
        manualResizing = false;
      }

      tableViewerCreator.redrawTableEditorControls();
    }
  }