2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
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]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
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.
42
package org.netbeans.modules.versioning.system.cvss.ui.history;
44
import org.openide.explorer.view.TreeTableView;
45
import org.openide.explorer.ExplorerManager;
46
import org.openide.nodes.Node;
47
import org.openide.nodes.PropertySupport;
48
import org.openide.nodes.AbstractNode;
49
import org.openide.nodes.Children;
50
import org.openide.util.lookup.Lookups;
51
import org.openide.util.NbBundle;
52
import org.openide.ErrorManager;
53
import org.netbeans.modules.versioning.system.cvss.CvsModuleConfig;
56
import javax.swing.text.Style;
57
import javax.swing.text.StyleConstants;
58
import javax.swing.text.Document;
59
import javax.swing.text.BadLocationException;
60
import javax.swing.tree.DefaultTreeCellRenderer;
61
import java.lang.reflect.InvocationTargetException;
63
import java.util.List;
64
import java.util.logging.Logger;
65
import java.util.logging.Level;
66
import java.beans.PropertyVetoException;
68
import java.awt.event.*;
71
* Treetable to show results of Search History action.
73
* @author Maros Sandor
75
class DiffTreeTable extends TreeTableView implements MouseListener, MouseMotionListener {
77
private RevisionsRootNode rootNode;
80
public DiffTreeTable() {
81
treeTable.setShowHorizontalLines(true);
82
treeTable.setShowVerticalLines(false);
83
setRootVisible(false);
84
setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
85
setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
88
DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
89
renderer.setOpenIcon(null);
90
renderer.setClosedIcon(null);
91
renderer.setLeafIcon(null);
92
tree.setCellRenderer(renderer);
94
treeTable.addMouseListener(this);
95
treeTable.addMouseMotionListener(this);
98
private SearchHistoryPanel.DispRevision getRevisionWithTagsAt(Point p) {
99
SearchHistoryPanel.DispRevision drev = getRevisionWithPropertyAt(p, "tagsRevision");
100
if (drev != null && drev.getBranches() != null && drev.getBranches().size() + drev.getTags().size() > 1) {
106
private SearchHistoryPanel.DispRevision getRevisionWithPropertyAt(Point p, String property) {
107
int row = treeTable.rowAtPoint(p);
108
int column = treeTable.columnAtPoint(p);
109
if (row == -1 || column == -1) return null;
110
Object o = treeTable.getValueAt(row, column);
111
if (o instanceof Node.Property) {
112
Node.Property tags = (Node.Property) o;
113
return (SearchHistoryPanel.DispRevision) tags.getValue(property);
118
public void mouseClicked(MouseEvent e) {
119
Point p = e.getPoint();
120
SearchHistoryPanel.DispRevision drev = getRevisionWithTagsAt(p);
122
Window w = SwingUtilities.windowForComponent(treeTable);
123
SwingUtilities.convertPointToScreen(p, treeTable);
126
SummaryView.showAllTags(w, p, drev);
128
drev = getRevisionWithPropertyAt(p, "messageRevision"); // NOI18N
130
Window w = SwingUtilities.windowForComponent(treeTable);
131
SwingUtilities.convertPointToScreen(p, treeTable);
132
if ((p.x -= 150) < 0) p.x = 10;
133
p.y += treeTable.getRowHeight() * 3 / 2;
134
showMessage(w, p, drev);
138
private void showMessage(Window w, Point p, SearchHistoryPanel.DispRevision drev) {
139
final JTextPane tp = new JTextPane();
140
tp.setBackground(SummaryView.darker(UIManager.getColor("List.background"))); // NOI18N
141
tp.setBorder(BorderFactory.createEmptyBorder(6, 8, 0, 0));
142
tp.setEditable(false);
144
Style headerStyle = tp.addStyle("headerStyle", null); // NOI18N
145
StyleConstants.setBold(headerStyle, true);
147
Document doc = tp.getDocument();
149
doc.insertString(doc.getLength(), NbBundle.getMessage(DiffTreeTable.class, "CTL_MessageWindow_Title") + "\n\n", headerStyle); // NOI18N
150
doc.insertString(doc.getLength(), drev.getRevision().getMessage() + "\n", null); // NOI18N
151
} catch (BadLocationException e) {
152
Logger.getLogger(DiffTreeTable.class.getName()).log(Level.WARNING, "Internal error creating commit message popup", e); // NOI18N
155
Dimension dim = tp.getPreferredSize();
156
tp.setPreferredSize(new Dimension(dim.width * 7 / 6, dim.height));
157
final JScrollPane jsp = new JScrollPane(tp);
158
jsp.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));
160
TooltipWindow ttw = new TooltipWindow(w, jsp);
161
ttw.addComponentListener(new ComponentAdapter() {
162
public void componentShown(ComponentEvent e) {
163
tp.scrollRectToVisible(new Rectangle(0, 0, 1, 1));
169
public void mouseDragged(MouseEvent e) {
172
public void mouseMoved(MouseEvent e) {
173
if (getRevisionWithTagsAt(e.getPoint()) != null || getRevisionWithPropertyAt(e.getPoint(), "messageRevision") != null) { // NOI18N
174
treeTable.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
176
treeTable.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
180
public void mousePressed(MouseEvent e) {
183
public void mouseReleased(MouseEvent e) {
186
public void mouseEntered(MouseEvent e) {
189
public void mouseExited(MouseEvent e) {
192
private void setupColumns() {
193
ResourceBundle loc = NbBundle.getBundle(DiffTreeTable.class);
194
Node.Property [] columns;
195
if (CvsModuleConfig.getDefault().getPreferences().getBoolean(CvsModuleConfig.PROP_SEARCHHISTORY_FETCHTAGS, true)) {
196
columns = new Node.Property[6];
197
columns[4] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_TAGS, List.class, loc.getString("LBL_DiffTree_Column_Tags"), loc.getString("LBL_DiffTree_Column_Tags_Desc"));
198
columns[5] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_MESSAGE, String.class, loc.getString("LBL_DiffTree_Column_Message"), loc.getString("LBL_DiffTree_Column_Message_Desc"));
200
columns = new Node.Property[5];
201
columns[4] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_MESSAGE, String.class, loc.getString("LBL_DiffTree_Column_Message"), loc.getString("LBL_DiffTree_Column_Message_Desc"));
203
columns[0] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_NAME, String.class, "", ""); // NOI18N
204
columns[0].setValue("TreeColumnTTV", Boolean.TRUE); // NOI18N
205
columns[1] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_LOCATION, String.class, loc.getString("LBL_DiffTree_Column_Location"), loc.getString("LBL_DiffTree_Column_Location_Desc"));
206
columns[2] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_DATE, String.class, loc.getString("LBL_DiffTree_Column_Time"), loc.getString("LBL_DiffTree_Column_Time_Desc"));
207
columns[3] = new ColumnDescriptor(RevisionNode.COLUMN_NAME_USERNAME, String.class, loc.getString("LBL_DiffTree_Column_Username"), loc.getString("LBL_DiffTree_Column_Username_Desc"));
208
setProperties(columns);
211
private void setDefaultColumnSizes() {
212
SwingUtilities.invokeLater(new Runnable() {
214
int width = getWidth();
215
if (CvsModuleConfig.getDefault().getPreferences().getBoolean(CvsModuleConfig.PROP_SEARCHHISTORY_FETCHTAGS, true)) {
216
if (treeTable.getColumnModel().getColumnCount() != 6) return;
217
treeTable.getColumnModel().getColumn(0).setPreferredWidth(width * 15 / 100);
218
treeTable.getColumnModel().getColumn(1).setPreferredWidth(width * 15 / 100);
219
treeTable.getColumnModel().getColumn(2).setPreferredWidth(width * 10 / 100);
220
treeTable.getColumnModel().getColumn(3).setPreferredWidth(width * 10 / 100);
221
treeTable.getColumnModel().getColumn(4).setPreferredWidth(width * 10 / 100);
222
treeTable.getColumnModel().getColumn(5).setPreferredWidth(width * 40 / 100);
224
if (treeTable.getColumnModel().getColumnCount() != 5) return;
225
treeTable.getColumnModel().getColumn(0).setPreferredWidth(width * 20 / 100);
226
treeTable.getColumnModel().getColumn(1).setPreferredWidth(width * 20 / 100);
227
treeTable.getColumnModel().getColumn(2).setPreferredWidth(width * 10 / 100);
228
treeTable.getColumnModel().getColumn(3).setPreferredWidth(width * 10 / 100);
229
treeTable.getColumnModel().getColumn(4).setPreferredWidth(width * 40 / 100);
235
void setSelection(int idx) {
236
treeTable.getSelectionModel().setValueIsAdjusting(false);
237
treeTable.scrollRectToVisible(treeTable.getCellRect(idx, 1, true));
238
treeTable.getSelectionModel().setSelectionInterval(idx, idx);
241
void setSelection(SearchHistoryPanel.ResultsContainer container) {
242
RevisionNode node = (RevisionNode) getNode(rootNode, container);
243
if (node == null) return;
244
ExplorerManager em = ExplorerManager.find(this);
246
em.setSelectedNodes(new Node [] { node });
247
} catch (PropertyVetoException e) {
248
ErrorManager.getDefault().notify(e);
252
void setSelection(SearchHistoryPanel.DispRevision revision) {
253
RevisionNode node = (RevisionNode) getNode(rootNode, revision);
254
if (node == null) return;
255
ExplorerManager em = ExplorerManager.find(this);
257
em.setSelectedNodes(new Node [] { node });
258
} catch (PropertyVetoException e) {
259
ErrorManager.getDefault().notify(e);
263
private Node getNode(Node node, Object obj) {
264
Object object = node.getLookup().lookup(obj.getClass());
265
if (obj.equals(object)) return node;
266
Enumeration children = node.getChildren().nodes();
267
while (children.hasMoreElements()) {
268
Node child = (Node) children.nextElement();
269
Node result = getNode(child, obj);
270
if (result != null) return result;
275
public int [] getSelection() {
276
return treeTable.getSelectedRows();
279
public int getRowCount() {
280
return treeTable.getRowCount();
283
private static class ColumnDescriptor extends PropertySupport.ReadOnly {
285
public ColumnDescriptor(String name, Class type, String displayName, String shortDescription) {
286
super(name, type, displayName, shortDescription);
289
public Object getValue() throws IllegalAccessException, InvocationTargetException {
294
public void addNotify() {
296
ExplorerManager em = ExplorerManager.find(this);
297
em.setRootContext(rootNode);
298
setDefaultColumnSizes();
301
public void setResults(List results) {
302
this.results = results;
303
rootNode = new RevisionsRootNode();
304
ExplorerManager em = ExplorerManager.find(this);
306
em.setRootContext(rootNode);
310
private class RevisionsRootNode extends AbstractNode {
312
public RevisionsRootNode() {
313
super(new RevisionsRootNodeChildren(), Lookups.singleton(results));
316
public String getName() {
317
return "revision"; // NOI18N
320
public String getDisplayName() {
321
return NbBundle.getMessage(DiffTreeTable.class, "LBL_DiffTree_Column_Name"); // NOI18N
324
public String getShortDescription() {
325
return NbBundle.getMessage(DiffTreeTable.class, "LBL_DiffTree_Column_Name_Desc"); // NOI18N
329
private class RevisionsRootNodeChildren extends Children.Keys {
331
public RevisionsRootNodeChildren() {
334
protected void addNotify() {
338
protected void removeNotify() {
339
setKeys(Collections.EMPTY_SET);
342
private void refreshKeys() {
346
protected Node[] createNodes(Object key) {
348
if (key instanceof SearchHistoryPanel.ResultsContainer) {
349
node = new RevisionNode((SearchHistoryPanel.ResultsContainer) key);
350
} else { // key instanceof SearchHistoryPanel.DispRevision
351
node = new RevisionNode(((SearchHistoryPanel.DispRevision) key));
353
return new Node[] { node };