if(!menuSelectedTrack.isNotDownloaded()) { popupMenu.popUp(menuSelectedTrack, table.toDisplay(e.x, e.y+10)); }
popupMenu.popUp(menuSelectedTrack, table.toDisplay(e.x, e.y+10));
  public TrackTable(Composite composite, TrackDatabase trackDatabase, SkinManager skinManager) {    display = composite.getDisplay();    this.trackDatabase = trackDatabase;    basicSkinable = new BasicSkinable(this.display);    table = new Table(composite, SWT.FULL_SELECTION);    table.setEnabled(false);    final TableColumn artistCol = new TableColumn(table, SWT.LEFT);    artistCol.setWidth(200);    addColumnListener(artistCol, comparator = new TrackComparator() {      public int compareTrack(Track track0, Track track1) {        currentSortColumn = table.indexOf(artistCol);        currentSortDirection = !this.getDirection();        return magicStringCompare(track0.getArtist(), track1.getArtist());      }            });    skinManager.addItem(artistCol, "TrackTable.Heading.Artist");     final TableColumn trackCol = new TableColumn(table, SWT.LEFT);    trackCol.setWidth(200);    addColumnListener(trackCol, new TrackComparator() {      public int compareTrack(Track track0, Track track1) {        currentSortColumn = table.indexOf(trackCol);        currentSortDirection = !this.getDirection();        return magicStringCompare(track0.getTitle(), track1.getTitle());      }            });    skinManager.addItem(trackCol, "TrackTable.Heading.Track");     final TableColumn ratingCol = new TableColumn(table, SWT.LEFT);    ratingCol.setWidth(90);    // Setting the alighnment to left doesn't seem to make a difference for images on GTK    ratingCol.setAlignment(SWT.LEFT);    addColumnListener(ratingCol, new TrackComparator() {      public int compareTrack(Track track0, Track track1) {        currentSortColumn = table.indexOf(ratingCol);        currentSortDirection = !this.getDirection();        String state0 = track0.getState();        String state1 = track1.getState();        if (!state0.startsWith("%") || !state1.startsWith("%")) {          int compare = magicStringCompare(state0, state1);          if (compare != 0)            return compare;        }        return magicStringCompare(track0.getArtist(), track1.getArtist());      }            });    skinManager.addItem(ratingCol, "TrackTable.Heading.Rating");    final TableColumn playsCol = new TableColumn(table, SWT.LEFT);    playsCol.setAlignment(SWT.LEFT);    playsCol.setWidth(50);    addColumnListener(playsCol, new TrackComparator() {      public int compareTrack(Track track0, Track track1) {        currentSortColumn = table.indexOf(playsCol);        currentSortDirection = !this.getDirection();        int plays0 = track0.getNoOfTimesPlayed();        int plays1 = track1.getNoOfTimesPlayed();        if (plays0 < plays1) return -1;        if (plays0 > plays1) return 1;        return magicStringCompare(track0.getArtist(), track1.getArtist());      }            });    skinManager.addItem(playsCol, "TrackTable.Heading.Plays");    final TableColumn lastPlayedCol = new TableColumn(table, SWT.LEFT);    lastPlayedCol.setWidth(120);    addColumnListener(lastPlayedCol, new TrackComparator() {      public int compareTrack(Track track0, Track track1) {        currentSortColumn = table.indexOf(lastPlayedCol);        currentSortDirection = !this.getDirection();        return track0.getLastPlayed().compareTo(track1.getLastPlayed());      }            });    table.setHeaderVisible(true);    skinManager.addItem(lastPlayedCol, "TrackTable.Heading.Last");     final TableColumn licenseCol = new TableColumn(table, SWT.LEFT);    licenseCol.setWidth(60);    addColumnListener(licenseCol, new TrackComparator() {      public int compareTrack(Track track0, Track track1) {        currentSortColumn = table.indexOf(licenseCol);        currentSortDirection = !this.getDirection();        int compare = licenseIndex.get(track0).compareTo(licenseIndex.get(track1));        if (compare != 0)          return compare;        return magicStringCompare(track0.getArtist(), track1.getArtist());      }            });    skinManager.addItem(licenseCol, "TrackTable.Heading.License");    skinManager.add(basicSkinable, "TrackTable");    GridData gridData = new GridData();    gridData.horizontalAlignment = GridData.FILL;    gridData.grabExcessHorizontalSpace = true;    gridData.verticalAlignment = GridData.FILL;    gridData.grabExcessVerticalSpace = true;    gridData.horizontalSpan = 3;    table.setLayoutData(gridData);    table.pack();//    This code updates table items as they get selected and unselected. It would be good//    if the background colour for selected items could be predicted however there doesn't//    appear to be an easy way to find this colour.//    //    table.addSelectionListener(new SelectionAdapter() {//      private TableItem[] selection;//      private void update(TableItem[] tableItems) {//        if (tableItems != null)//          for (int i = 0 ; i < tableItems.length; i++) {//            TableItem tableItem = tableItems[i];//            Track track = (Track) hashByTableItem.get(tableItems[i]);//            if (track != null)//              updateTableItem(tableItem, track);//          }//      }//      public void widgetSelected(SelectionEvent e) {//        update(selection);//        selection = table.getSelection();//        update(selection);//      }//    });        DragSource source = new DragSource(table, DND.DROP_COPY);    source.setTransfer(new Transfer[] { FileTransfer.getInstance() });    source.addDragListener(new DragSourceListener() {            /** The track that we're dragging. */      private Track track;            public void dragStart(DragSourceEvent e) {        track = clickedTrack;        e.doit = track != null;      }            public void dragSetData(DragSourceEvent e) {        try {          e.data = new String[] { track.getFile().getAbsoluteFile().getAbsolutePath() };        }        catch (Exception ex) {          ex.printStackTrace();        }      }             public void dragFinished(DragSourceEvent e) {      }    });    table.addMouseListener(new MouseAdapter() {      public void mouseDown(MouseEvent e)       {        // Carbon tables have some extra column margin width.        // Table.EXTRA_WIDTH is hardcoded to 24, and of course not public.        // There are also about 4 pixels around the edges for the focus ring.        final int margin = Client.isMac() ? 24 : 0;        final int gutter = Client.isMac() ? 4 : 0;                // On Mac OS X, column header selection is broken. We need to check        // here for a column header hit to provide sort-on-click:        final int header = table.getHeaderHeight();        if (e.y > gutter && e.y < gutter + header - 1 && Client.isMac()) {          // Mysteriously we receive the initial mouse down event after the          // resize events when the user resizes columns by dragging.          // Check the event timestamp against the last column resize event          // (Naturally the timestamps are unsigned 32-bit integers, which          // Java doesn't support. Thanks Java!)          if (((long)e.time & 0xffffffffL) < ((long)columnAdjustTime & 0xffffffffL))            return;          final int sizeHandle = 4; // Resizing columns          int colStart = gutter;          for(int i = 0; i < table.getColumnCount(); i++ ) {            int colWidth = table.getColumn(i).getWidth() + margin;            if( e.x >= colStart && e.x - colStart < colWidth - sizeHandle ) {              System.out.println("mouseDown column hit on " + i);              setSortColumn(i);              return;            }            colStart += colWidth;          }          System.out.println("mouseDown couldn't find a column");        }        int colZeroWidth = table.getColumn(0).getWidth() + margin;        int colOneWidth = table.getColumn(1).getWidth() + margin;        int colTwoWidth = table.getColumn(2).getWidth() + margin;                int colTwoX = gutter + (margin / 2) + colZeroWidth + colOneWidth;                TableItem item = table.getItem(new Point(margin, e.y));        if (item == null)          clickedTrack = null;        else          clickedTrack = (Track) hashByTableItem.get(item);          // If the user clicked on the rating column, then bring up the          // pop-up menu.          // NOTE: WIDTH OF RATING ICON IS HARD-CODED HERE!        System.out.println("mouseDown: " + e.x + "," + e.y +          "  widths " + colZeroWidth + "," + colOneWidth + "," + colTwoWidth +          "  colTwoX " + colTwoX);        if (e.x >= colTwoX && e.x < (colTwoX+colTwoWidth) && e.x < (colTwoX+80)) {          if (popupMenu != null && clickedTrack != null) {            menuSelectedTrack = clickedTrack;              // Select and scroll to the selected track.            select(selected, true);              // Put the menu 10 pixels below the mouse position so there is less risk of              // choosing "THIS SUX" accidentally.            if(!menuSelectedTrack.isNotDownloaded()) {                popupMenu.popUp(menuSelectedTrack, table.toDisplay(e.x, e.y+10));            }              // Note: We will now receive a 'widgetSelected' event.  This will call              // select(selected, false) - this will ensure the correct track is              // highlighted, because menuSelectedTrack overrides the 'selected' track.          }        }      }    });    table.addSelectionListener(new SelectionAdapter() {      public void widgetSelected(SelectionEvent e) {          // Prevent the track table from ever having a track other than the          // currently playing one selected by switching back to the currently          // playing one whenever a track is selected.          // (Unless there is a track selected by the pop-up menu.)        if (menuSelectedTrack == null)          select(selected, false);      }    });  }