~ubuntu-branches/ubuntu/quantal/netbeans/quantal

« back to all changes in this revision

Viewing changes to versioncontrol/mercurial/src/org/netbeans/modules/mercurial/ui/diff/DiffFileTable.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
6
 * The contents of this file are subject to the terms of either the GNU
 
7
 * General Public License Version 2 only ("GPL") or the Common
 
8
 * Development and Distribution License("CDDL") (collectively, the
 
9
 * "License"). You may not use this file except in compliance with the
 
10
 * License. You can obtain a copy of the License at
 
11
 * http://www.netbeans.org/cddl-gplv2.html
 
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 
13
 * specific language governing permissions and limitations under the
 
14
 * License.  When distributing the software, include this License Header
 
15
 * Notice in each file and include the License file at
 
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 
17
 * particular file as subject to the "Classpath" exception as provided
 
18
 * by Sun in the GPL Version 2 section of the License file that
 
19
 * accompanied this code. If applicable, add the following below the
 
20
 * License Header, with the fields enclosed by brackets [] replaced by
 
21
 * your own identifying information:
 
22
 * "Portions Copyrighted [year] [name of copyright owner]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * The Original Software is NetBeans. The Initial Developer of the Original
 
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
 
28
 * Microsystems, Inc. All Rights Reserved.
 
29
 *
 
30
 * If you wish your version of this file to be governed by only the CDDL
 
31
 * or only the GPL Version 2, indicate your decision by adding
 
32
 * "[Contributor] elects to include this software in this distribution
 
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 
34
 * single choice of license, a recipient has the option to distribute
 
35
 * your version of this file under either the CDDL, the GPL Version 2 or
 
36
 * to extend the choice of license to its licensees as provided above.
 
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 
38
 * Version 2 license, then the option applies only if the new code is
 
39
 * made subject to such option by the copyright holder.
 
40
 */
 
41
package org.netbeans.modules.mercurial.ui.diff;
 
42
 
 
43
import org.openide.explorer.view.NodeTableModel;
 
44
import org.openide.util.NbBundle;
 
45
import org.openide.nodes.Node;
 
46
import org.openide.nodes.PropertySupport;
 
47
import org.openide.ErrorManager;
 
48
import org.openide.windows.TopComponent;
 
49
import org.netbeans.modules.versioning.util.TableSorter;
 
50
import org.netbeans.modules.versioning.util.FilePathCellRenderer;
 
51
 
 
52
import javax.swing.event.*;
 
53
import javax.swing.*;
 
54
import javax.swing.table.DefaultTableCellRenderer;
 
55
import java.awt.event.MouseListener;
 
56
import java.awt.event.KeyEvent;
 
57
import java.awt.event.ActionEvent;
 
58
import java.awt.event.MouseEvent;
 
59
import java.awt.Color;
 
60
import java.awt.Point;
 
61
import java.awt.Component;
 
62
import java.util.*;
 
63
import java.lang.reflect.InvocationTargetException;
 
64
import java.io.File;
 
65
 
 
66
/**
 
67
 * 
 
68
 * @author Maros Sandor
 
69
 */
 
70
class DiffFileTable implements MouseListener, ListSelectionListener, AncestorListener {
 
71
    
 
72
    private NodeTableModel tableModel;
 
73
    private JTable table;
 
74
    private JScrollPane     component;
 
75
    private Node [] nodes = new Node[0];
 
76
    
 
77
    private String []   tableColumns; 
 
78
    private TableSorter sorter;
 
79
 
 
80
    /**
 
81
     * Defines labels for Diff view table columns.
 
82
     */ 
 
83
    private static final Map<String, String[]> columnLabels = new HashMap<String, String[]>(4);
 
84
 
 
85
    {
 
86
        ResourceBundle loc = NbBundle.getBundle(DiffFileTable.class);
 
87
        columnLabels.put(DiffNode.COLUMN_NAME_NAME, new String [] {
 
88
                loc.getString("CTL_DiffTable_Column_Name_Title"), 
 
89
                loc.getString("CTL_DiffTable_Column_Name_Desc")});
 
90
        columnLabels.put(DiffNode.COLUMN_NAME_PROPERTY, new String [] {
 
91
                loc.getString("CTL_DiffTable_Column_Property_Title"), 
 
92
                loc.getString("CTL_DiffTable_Column_Property_Desc")});
 
93
        columnLabels.put(DiffNode.COLUMN_NAME_STATUS, new String [] { 
 
94
                loc.getString("CTL_DiffTable_Column_Status_Title"), 
 
95
                loc.getString("CTL_DiffTable_Column_Status_Desc")});
 
96
        columnLabels.put(DiffNode.COLUMN_NAME_LOCATION, new String [] { 
 
97
                loc.getString("CTL_DiffTable_Column_Location_Title"), 
 
98
                loc.getString("CTL_DiffTable_Column_Location_Desc")});
 
99
    }
 
100
 
 
101
    
 
102
    
 
103
    private static final Comparator NodeComparator = new Comparator() {
 
104
        public int compare(Object o1, Object o2) {
 
105
            Node.Property p1 = (Node.Property) o1;
 
106
            Node.Property p2 = (Node.Property) o2;
 
107
            String sk1 = (String) p1.getValue("sortkey"); // NOI18N
 
108
            if (sk1 != null) {
 
109
                String sk2 = (String) p2.getValue("sortkey"); // NOI18N
 
110
                return sk1.compareToIgnoreCase(sk2);
 
111
            } else {
 
112
                try {
 
113
                    String s1 = (String) p1.getValue();
 
114
                    String s2 = (String) p2.getValue();
 
115
                    return s1.compareToIgnoreCase(s2);
 
116
                } catch (Exception e) {
 
117
                    ErrorManager.getDefault().notify(e);
 
118
                    return 0;
 
119
                }
 
120
            }
 
121
        }
 
122
    };
 
123
    private final MultiDiffPanel master;
 
124
 
 
125
    public DiffFileTable(MultiDiffPanel master) {
 
126
        this.master = master;
 
127
        tableModel = new NodeTableModel();
 
128
        sorter = new TableSorter(tableModel);
 
129
        sorter.setColumnComparator(Node.Property.class, DiffFileTable.NodeComparator);
 
130
        table = new JTable(sorter);
 
131
        table.getSelectionModel().addListSelectionListener(this);
 
132
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 
133
        sorter.setTableHeader(table.getTableHeader());
 
134
        table.setRowHeight(table.getRowHeight() * 6 / 5);
 
135
        component = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
 
136
        component.getViewport().setBackground(table.getBackground());
 
137
        Color borderColor = UIManager.getColor("scrollpane_border"); // NOI18N
 
138
        if (borderColor == null) borderColor = UIManager.getColor("controlShadow"); // NOI18N
 
139
        component.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, borderColor));
 
140
        table.addMouseListener(this);
 
141
        table.setDefaultRenderer(Node.Property.class, new DiffTableCellRenderer());
 
142
        table.getSelectionModel().addListSelectionListener(this);
 
143
        table.addAncestorListener(this);
 
144
        table.getAccessibleContext().setAccessibleName(NbBundle.getMessage(DiffFileTable.class, "ACSN_DiffTable")); // NOI18N
 
145
        table.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(DiffFileTable.class, "ACSD_DiffTable")); // NOI18N
 
146
        setColumns(new String[] {
 
147
            DiffNode.COLUMN_NAME_NAME,
 
148
            DiffNode.COLUMN_NAME_PROPERTY,
 
149
            DiffNode.COLUMN_NAME_STATUS,
 
150
            DiffNode.COLUMN_NAME_LOCATION}
 
151
        );
 
152
        table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ).put(
 
153
                KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.SHIFT_DOWN_MASK ), "org.openide.actions.PopupAction");
 
154
        table.getActionMap().put("org.openide.actions.PopupAction", new AbstractAction() {
 
155
            public void actionPerformed(ActionEvent e) {
 
156
                showPopup(org.netbeans.modules.versioning.util.Utils.getPositionForPopup(table));
 
157
            }
 
158
        });
 
159
    }
 
160
 
 
161
    void setDefaultColumnSizes() {
 
162
        SwingUtilities.invokeLater(new Runnable() {
 
163
            public void run() {
 
164
                int width = table.getWidth();
 
165
                if (tableColumns.length == 3) {
 
166
                    for (int i = 0; i < tableColumns.length; i++) {
 
167
                        if (DiffNode.COLUMN_NAME_LOCATION.equals(tableColumns[i])) {
 
168
                            table.getColumnModel().getColumn(i).setPreferredWidth(width * 60 / 100);
 
169
                        } else {
 
170
                            table.getColumnModel().getColumn(i).setPreferredWidth(width * 20 / 100);
 
171
                        }
 
172
                    }
 
173
                } else if (tableColumns.length == 4) {
 
174
                    for (int i = 0; i < tableColumns.length; i++) {
 
175
                        if (DiffNode.COLUMN_NAME_LOCATION.equals(tableColumns[i])) {
 
176
                            table.getColumnModel().getColumn(i).setPreferredWidth(width * 55 / 100);
 
177
                        } else {
 
178
                            table.getColumnModel().getColumn(i).setPreferredWidth(width * 15 / 100);
 
179
                        }
 
180
                    }
 
181
                }
 
182
            }
 
183
        });
 
184
    }
 
185
 
 
186
    public void ancestorAdded(AncestorEvent event) {
 
187
        setDefaultColumnSizes();
 
188
    }
 
189
 
 
190
    public void ancestorMoved(AncestorEvent event) {
 
191
    }
 
192
 
 
193
    public void ancestorRemoved(AncestorEvent event) {
 
194
    }
 
195
 
 
196
    public JComponent getComponent() {
 
197
        return component;
 
198
    }
 
199
    
 
200
    /**
 
201
     * Sets visible columns in the Versioning table.
 
202
     * 
 
203
     * @param columns array of column names, they must be one of SyncFileNode.COLUMN_NAME_XXXXX constants.  
 
204
     */ 
 
205
    final void setColumns(String [] columns) {
 
206
        if (Arrays.equals(columns, tableColumns)) return;
 
207
        setModelProperties(columns);
 
208
        tableColumns = columns;
 
209
        for (int i = 0; i < tableColumns.length; i++) {
 
210
            sorter.setColumnComparator(i, null);
 
211
            sorter.setSortingStatus(i, TableSorter.NOT_SORTED);
 
212
            if (DiffNode.COLUMN_NAME_STATUS.equals(tableColumns[i])) {
 
213
                sorter.setSortingStatus(i, TableSorter.ASCENDING);
 
214
                break;
 
215
            }
 
216
        }
 
217
        setDefaultColumnSizes();        
 
218
    }
 
219
        
 
220
    private void setModelProperties(String [] columns) {
 
221
        Node.Property [] properties = new Node.Property[columns.length];
 
222
        for (int i = 0; i < columns.length; i++) {
 
223
            String column = columns[i];
 
224
            String [] labels = (String[]) columnLabels.get(column);
 
225
            properties[i] = new ColumnDescriptor(column, String.class, labels[0], labels[1]);  
 
226
        }
 
227
        tableModel.setProperties(properties);
 
228
    }
 
229
 
 
230
    void setTableModel(Node [] nodes) {
 
231
        this.nodes = nodes;
 
232
        tableModel.setNodes(nodes);
 
233
    }
 
234
 
 
235
    void focus() {
 
236
        table.requestFocus();
 
237
    }
 
238
 
 
239
    void setSelectedIndex(int currentIndex) {
 
240
        if (currentIndex == table.getSelectedRow()) return;
 
241
        table.getSelectionModel().setSelectionInterval(currentIndex, currentIndex);
 
242
        table.scrollRectToVisible(table.getCellRect(currentIndex, 0, true));
 
243
    }
 
244
 
 
245
    public int getSelectedIndex() {
 
246
        return table.getSelectedRow();
 
247
    }
 
248
 
 
249
    public int getSelectedModelIndex() {
 
250
        return getModelIndex(table.getSelectedRow());
 
251
    }
 
252
 
 
253
    public int getModelIndex(int viewIndex) {
 
254
        return viewIndex != -1 ? sorter.modelIndex(viewIndex) : -1;
 
255
    }
 
256
 
 
257
    public JTable getTable() {
 
258
        return table;
 
259
    }
 
260
 
 
261
    private static class ColumnDescriptor extends PropertySupport.ReadOnly {
 
262
        
 
263
        @SuppressWarnings("unchecked")
 
264
        public ColumnDescriptor(String name, Class type, String displayName, String shortDescription) {
 
265
            super(name, type, displayName, shortDescription);
 
266
        }
 
267
 
 
268
        public Object getValue() throws IllegalAccessException, InvocationTargetException {
 
269
            return null;
 
270
        }
 
271
    }
 
272
 
 
273
    private void showPopup(final MouseEvent e) {
 
274
        int row = table.rowAtPoint(e.getPoint());
 
275
        if (row != -1) {
 
276
            boolean makeRowSelected = true;
 
277
            int [] selectedrows = table.getSelectedRows();
 
278
 
 
279
            for (int i = 0; i < selectedrows.length; i++) {
 
280
                if (row == selectedrows[i]) {
 
281
                    makeRowSelected = false;
 
282
                    break;
 
283
                }
 
284
            }
 
285
            if (makeRowSelected) {
 
286
                table.getSelectionModel().setSelectionInterval(row, row);
 
287
            }
 
288
        }
 
289
        SwingUtilities.invokeLater(new Runnable() {
 
290
            public void run() {
 
291
                // invoke later so the selection on the table will be set first
 
292
//                JPopupMenu menu = getPopup();
 
293
//                menu.show(table, e.getX(), e.getY());
 
294
            }
 
295
        });
 
296
    }
 
297
 
 
298
    private void showPopup(Point p) {
 
299
//        JPopupMenu menu = getPopup();
 
300
//        menu.show(table, p.x, p.y);
 
301
    }
 
302
 
 
303
    private JPopupMenu getPopup() {
 
304
        JPopupMenu menu = new JPopupMenu();
 
305
        JMenuItem item;
 
306
        return menu;
 
307
    }
 
308
 
 
309
    public void mouseEntered(MouseEvent e) {
 
310
    }
 
311
 
 
312
    public void mouseExited(MouseEvent e) {
 
313
    }
 
314
 
 
315
    public void mousePressed(MouseEvent e) {
 
316
        if (e.isPopupTrigger()) {
 
317
            showPopup(e);
 
318
        }
 
319
    }
 
320
 
 
321
    public void mouseReleased(MouseEvent e) {
 
322
        if (e.isPopupTrigger()) {
 
323
            showPopup(e);
 
324
        }
 
325
    }
 
326
 
 
327
    public void mouseClicked(MouseEvent e) {
 
328
/*
 
329
        if (SwingUtilities.isLeftMouseButton(e) && MouseUtils.isDoubleClick(e)) {
 
330
            int row = table.rowAtPoint(e.getPoint());
 
331
            if (row == -1) return;
 
332
            row = sorter.modelIndex(row);
 
333
            Action action = nodes[row].getPreferredAction();
 
334
            if (action == null || !action.isEnabled()) action = new OpenInEditorAction();
 
335
            if (action.isEnabled()) {
 
336
                action.actionPerformed(new ActionEvent(this, 0, "")); // NOI18N
 
337
            }
 
338
        }
 
339
*/
 
340
    }
 
341
 
 
342
    public void valueChanged(ListSelectionEvent e) {
 
343
        final TopComponent tc = (TopComponent) SwingUtilities.getAncestorOfClass(TopComponent.class,  table);
 
344
        if (tc == null) return; // table is no longer in component hierarchy
 
345
        master.setSelectedIndex(table.getSelectedRow());
 
346
    }
 
347
    
 
348
    private class DiffTableCellRenderer extends DefaultTableCellRenderer {
 
349
        
 
350
        private FilePathCellRenderer pathRenderer = new FilePathCellRenderer();
 
351
        
 
352
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
 
353
            Component renderer;
 
354
            int modelColumnIndex = table.convertColumnIndexToModel(column);
 
355
            if (modelColumnIndex == 0) {
 
356
                Node node = nodes[sorter.modelIndex(row)];
 
357
                if (!isSelected) {
 
358
                    value = "<html>" + node.getHtmlDisplayName(); // NOI18N
 
359
                }
 
360
            }
 
361
            if (modelColumnIndex == 2) {
 
362
                renderer = pathRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
 
363
            } else {
 
364
                renderer = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
 
365
            }
 
366
            if (renderer instanceof JComponent) {
 
367
                File file = nodes[sorter.modelIndex(row)].getLookup().lookup(File.class); 
 
368
                String path = file != null ? file.getAbsolutePath() : null; 
 
369
                ((JComponent) renderer).setToolTipText(path);
 
370
            }
 
371
            return renderer;
 
372
        }
 
373
    }
 
374
}