KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > versioning > system > cvss > ui > history > SummaryView


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.versioning.system.cvss.ui.history;
21
22 import org.netbeans.lib.cvsclient.command.log.LogInformation;
23 import org.netbeans.lib.cvsclient.command.update.UpdateCommand;
24 import org.netbeans.modules.versioning.system.cvss.util.Utils;
25 import org.netbeans.modules.versioning.system.cvss.util.Context;
26 import org.netbeans.modules.versioning.system.cvss.ui.actions.log.SearchHistoryAction;
27 import org.netbeans.modules.versioning.system.cvss.ui.actions.update.GetCleanAction;
28 import org.netbeans.modules.versioning.system.cvss.ui.actions.update.UpdateExecutor;
29 import org.netbeans.modules.versioning.system.cvss.CvsVersioningSystem;
30 import org.netbeans.modules.versioning.system.cvss.ExecutorGroup;
31 import org.netbeans.modules.versioning.system.cvss.VersionsCache;
32 import org.netbeans.api.project.ProjectUtils;
33 import org.netbeans.api.project.Project;
34 import org.netbeans.api.project.ui.OpenProjects;
35 import org.netbeans.api.editor.mimelookup.MimeLookup;
36 import org.netbeans.api.editor.mimelookup.MimePath;
37 import org.netbeans.api.editor.settings.FontColorSettings;
38 import org.openide.ErrorManager;
39 import org.openide.filesystems.FileObject;
40 import org.openide.filesystems.FileUtil;
41 import org.openide.cookies.ViewCookie;
42 import org.openide.util.NbBundle;
43 import org.openide.util.RequestProcessor;
44
45 import javax.swing.*;
46 import javax.swing.text.*;
47 import java.util.*;
48 import java.util.List JavaDoc;
49 import java.util.logging.Logger JavaDoc;
50 import java.util.logging.Level JavaDoc;
51 import java.awt.*;
52 import java.awt.geom.Rectangle2D JavaDoc;
53 import java.awt.event.*;
54 import java.text.DateFormat JavaDoc;
55 import java.io.File JavaDoc;
56
57 /**
58  * Shows Search History results in a JList.
59  *
60  * @author Maros Sandor
61  */

62 class SummaryView implements MouseListener, ComponentListener, MouseMotionListener {
63
64     private static final double DARKEN_FACTOR = 0.95;
65
66     private final SearchHistoryPanel master;
67     
68     private JList resultsList;
69     private JScrollPane scrollPane;
70
71     private final List JavaDoc dispResults;
72     private String JavaDoc message;
73     private AttributeSet searchHiliteAttrs;
74
75     public SummaryView(SearchHistoryPanel master, List JavaDoc results) {
76         this.master = master;
77         this.dispResults = expandResults(results);
78         FontColorSettings fcs = MimeLookup.getLookup(MimePath.get("text/x-java")).lookup(FontColorSettings.class); // NOI18N
79
searchHiliteAttrs = fcs.getFontColors("highlight-search"); // NOI18N
80
message = master.getCriteria().getCommitMessage();
81         resultsList = new JList(new SummaryListModel());
82         resultsList.setFixedCellHeight(-1);
83         resultsList.addMouseListener(this);
84         resultsList.addMouseMotionListener(this);
85         resultsList.setCellRenderer(new SummaryCellRenderer());
86         resultsList.getAccessibleContext().setAccessibleName(NbBundle.getMessage(SummaryView.class, "ACSN_SummaryView_List")); // NOI18N
87
resultsList.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(SummaryView.class, "ACSD_SummaryView_List")); // NOI18N
88
scrollPane = new JScrollPane(resultsList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
89         master.addComponentListener(this);
90     }
91
92     public void componentResized(ComponentEvent e) {
93         int [] selection = resultsList.getSelectedIndices();
94         resultsList.setModel(new SummaryListModel());
95         resultsList.setSelectedIndices(selection);
96     }
97
98     public void componentHidden(ComponentEvent e) {
99         // not interested
100
}
101
102     public void componentMoved(ComponentEvent e) {
103         // not interested
104
}
105
106     public void componentShown(ComponentEvent e) {
107         // not interested
108
}
109     
110     private static List JavaDoc expandResults(List JavaDoc results) {
111         ArrayList newResults = new ArrayList(results.size());
112         for (Iterator i = results.iterator(); i.hasNext();) {
113             Object JavaDoc o = i.next();
114             if (o instanceof SearchHistoryPanel.ResultsContainer) {
115                 newResults.add(o);
116                 SearchHistoryPanel.ResultsContainer container = (SearchHistoryPanel.ResultsContainer) o;
117                 for (Iterator j = container.getRevisions().iterator(); j.hasNext();) {
118                     SearchHistoryPanel.DispRevision revision = (SearchHistoryPanel.DispRevision) j.next();
119                     if (revision.getRevision().getNumber() != VersionsCache.REVISION_CURRENT && !revision.isBranchRoot()) {
120                         newResults.add(revision);
121                     }
122                 }
123                 for (Iterator j = container.getRevisions().iterator(); j.hasNext();) {
124                     SearchHistoryPanel.DispRevision revision = (SearchHistoryPanel.DispRevision) j.next();
125                     addResults(newResults, revision, 1);
126                 }
127             } else {
128                 SearchHistoryPanel.DispRevision revision = (SearchHistoryPanel.DispRevision) o;
129                 if (revision.getRevision().getNumber() != VersionsCache.REVISION_CURRENT && !revision.isBranchRoot()) {
130                     newResults.add(revision);
131                 }
132                 addResults(newResults, revision, 0);
133             }
134         }
135         return newResults;
136     }
137
138     private static void addResults(ArrayList newResults, SearchHistoryPanel.DispRevision dispRevision, int indentation) {
139         dispRevision.setIndentation(indentation);
140         List JavaDoc children = dispRevision.getChildren();
141         if (children != null) {
142             for (Iterator i = children.iterator(); i.hasNext();) {
143                 SearchHistoryPanel.DispRevision revision = (SearchHistoryPanel.DispRevision) i.next();
144                 if (!revision.isBranchRoot()) {
145                     newResults.add(revision);
146                 }
147             }
148             for (Iterator i = children.iterator(); i.hasNext();) {
149                 SearchHistoryPanel.DispRevision revision = (SearchHistoryPanel.DispRevision) i.next();
150                 addResults(newResults, revision, indentation + 1);
151             }
152         }
153     }
154
155     public void mouseClicked(MouseEvent e) {
156         int idx = resultsList.locationToIndex(e.getPoint());
157         if (idx == -1) return;
158         Rectangle rect = resultsList.getCellBounds(idx, idx);
159         Point p = new Point(e.getX() - rect.x, e.getY() - rect.y);
160         Rectangle diffBounds = (Rectangle) resultsList.getClientProperty("Summary-Diff-" + idx); // NOI18N
161
if (diffBounds != null && diffBounds.contains(p)) {
162             diffPrevious(idx);
163         }
164         diffBounds = (Rectangle) resultsList.getClientProperty("Summary-Acp-" + idx); // NOI18N
165
if (diffBounds != null && diffBounds.contains(p)) {
166             associatedChangesInProject(idx);
167         }
168         diffBounds = (Rectangle) resultsList.getClientProperty("Summary-Acop-" + idx); // NOI18N
169
if (diffBounds != null && diffBounds.contains(p)) {
170             associatedChangesInOpenProjects(idx);
171         }
172         diffBounds = (Rectangle) resultsList.getClientProperty("Summary-tagsLink-" + idx); // NOI18N
173
if (diffBounds != null && diffBounds.contains(p)) {
174             showAlltags(e.getPoint(), idx);
175         }
176     }
177
178     public static void showAllTags(Window w, Point p, SearchHistoryPanel.DispRevision drev) {
179
180         final JTextPane tp = new JTextPane();
181         tp.setBackground(darker(UIManager.getColor("List.background"))); // NOI18N
182
tp.setBorder(BorderFactory.createEmptyBorder(6, 8, 0, 0));
183         tp.setEditable(false);
184
185         Style headerStyle = tp.addStyle("headerStyle", null); // NOI18N
186
StyleConstants.setBold(headerStyle, true);
187         Style unmodifiedBranchStyle = tp.addStyle("unmodifiedBranchStyle", null); // NOI18N
188
StyleConstants.setForeground(unmodifiedBranchStyle, Color.GRAY);
189             
190         String JavaDoc modifiedBranches = drev.getRevision().getBranches();
191                     
192         Document doc = tp.getDocument();
193         try {
194             List JavaDoc<String JavaDoc> tags;
195                 
196             doc.insertString(doc.getLength(), NbBundle.getMessage(SummaryView.class, "CTL_TagsWindow_BranchesLabel") + "\n", headerStyle); // NOI18N
197
tags = drev.getBranches();
198             for (String JavaDoc tag : tags) {
199                 if (modifiedBranches == null || (modifiedBranches.indexOf(tag.substring(tag.indexOf("(") + 1, tag.indexOf(")")))) == -1) { // NOI18N
200
doc.insertString(doc.getLength(), tag + "\n", unmodifiedBranchStyle); // NOI18N
201
} else {
202                     doc.insertString(doc.getLength(), tag + "\n", null); // NOI18N
203
}
204             }
205             if (tags.size() == 0) {
206                 doc.insertString(doc.getLength(), NbBundle.getMessage(SummaryView.class, "CTL_TagsWindow_NoBranchesLabel") + "\n", unmodifiedBranchStyle); // NOI18N
207
}
208
209             doc.insertString(doc.getLength(), "\n" + NbBundle.getMessage(SummaryView.class, "CTL_TagsWindow_TagsLabel") + "\n", headerStyle); // NOI18N
210
StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
211             tags = drev.getTags();
212             for (String JavaDoc tag : tags) {
213                 sb.append(tag);
214                 sb.append('\n'); // NOI18N
215
}
216             doc.insertString(doc.getLength(), sb.toString(), null);
217
218             if (tags.size() == 0) {
219                 doc.insertString(doc.getLength(), NbBundle.getMessage(SummaryView.class, "CTL_TagsWindow_NoTagsLabel"), unmodifiedBranchStyle); // NOI18N
220
}
221                 
222         } catch (BadLocationException e) {
223             Logger.getLogger(SummaryView.class.getName()).log(Level.WARNING, "Internal error creating tag list", e); // NOI18N
224
}
225             
226         Dimension dim = tp.getPreferredSize();
227         tp.setPreferredSize(new Dimension(dim.width * 7 / 6, dim.height));
228         final JScrollPane jsp = new JScrollPane(tp);
229         jsp.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));
230
231         TooltipWindow ttw = new TooltipWindow(w, jsp);
232         ttw.addComponentListener(new ComponentAdapter() {
233             public void componentShown(ComponentEvent e) {
234                 tp.scrollRectToVisible(new Rectangle(0, 0, 1, 1));
235             }
236         });
237         ttw.show(p);
238     }
239     
240     private void showAlltags(Point p, int idx) {
241         Object JavaDoc o = dispResults.get(idx);
242         if (o instanceof SearchHistoryPanel.DispRevision) {
243             SwingUtilities.convertPointToScreen(p, resultsList);
244             p.x += 10;
245             showAllTags(SwingUtilities.windowForComponent(scrollPane), p, (SearchHistoryPanel.DispRevision) o);
246         }
247     }
248
249     public void mouseEntered(MouseEvent e) {
250         // not interested
251
}
252
253     public void mouseExited(MouseEvent e) {
254         // not interested
255
}
256
257     public void mousePressed(MouseEvent e) {
258         if (e.isPopupTrigger()) {
259             onPopup(e);
260         }
261     }
262
263     public void mouseReleased(MouseEvent e) {
264         if (e.isPopupTrigger()) {
265             onPopup(e);
266         }
267     }
268
269     public void mouseDragged(MouseEvent e) {
270     }
271
272     public void mouseMoved(MouseEvent e) {
273         int idx = resultsList.locationToIndex(e.getPoint());
274         if (idx == -1) return;
275         Rectangle rect = resultsList.getCellBounds(idx, idx);
276         Point p = new Point(e.getX() - rect.x, e.getY() - rect.y);
277         Rectangle diffBounds = (Rectangle) resultsList.getClientProperty("Summary-Diff-" + idx); // NOI18N
278
if (diffBounds != null && diffBounds.contains(p)) {
279             resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
280             return;
281         }
282         diffBounds = (Rectangle) resultsList.getClientProperty("Summary-Acp-" + idx); // NOI18N
283
if (diffBounds != null && diffBounds.contains(p)) {
284             resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
285             return;
286         }
287         diffBounds = (Rectangle) resultsList.getClientProperty("Summary-Acop-" + idx); // NOI18N
288
if (diffBounds != null && diffBounds.contains(p)) {
289             resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
290             return;
291         }
292         diffBounds = (Rectangle) resultsList.getClientProperty("Summary-tagsLink-" + idx); // NOI18N
293
if (diffBounds != null && diffBounds.contains(p)) {
294             resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
295             return;
296         }
297         resultsList.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
298     }
299
300     private void onPopup(MouseEvent e) {
301         int [] sel = resultsList.getSelectedIndices();
302         if (sel.length == 0) {
303             int idx = resultsList.locationToIndex(e.getPoint());
304             if (idx == -1) return;
305             resultsList.setSelectedIndex(idx);
306             sel = new int [] { idx };
307         }
308         final int [] selection = sel;
309
310         JPopupMenu menu = new JPopupMenu();
311         
312         String JavaDoc previousRevision = null;
313         SearchHistoryPanel.ResultsContainer container = null;
314         SearchHistoryPanel.DispRevision drev = null;
315         Object JavaDoc revCon = dispResults.get(selection[0]);
316         if (revCon instanceof SearchHistoryPanel.ResultsContainer) {
317             container = (SearchHistoryPanel.ResultsContainer) dispResults.get(selection[0]);
318         } else {
319             drev = (SearchHistoryPanel.DispRevision) dispResults.get(selection[0]);
320             previousRevision = Utils.previousRevision(drev.getRevision().getNumber().trim());
321         }
322         if (container != null) {
323             String JavaDoc eldest = container.getEldestRevision();
324             menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, "CTL_SummaryView_Diff", eldest, container.getNewestRevision())) { // NOI18N
325
public void actionPerformed(ActionEvent e) {
326                     diffPrevious(selection[0]);
327                 }
328             }));
329         } else {
330             if (previousRevision != null) {
331                 menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, "CTL_SummaryView_DiffToPrevious", previousRevision)) { // NOI18N
332
{
333                         setEnabled(selection.length == 1 && dispResults.get(selection[0]) instanceof SearchHistoryPanel.DispRevision);
334                     }
335                     public void actionPerformed(ActionEvent e) {
336                         diffPrevious(selection[0]);
337                     }
338                 }));
339             }
340         }
341         menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, "CTL_SummaryView_RollbackChange")) { // NOI18N
342
{
343                 setEnabled(someRevisions(selection));
344             }
345             public void actionPerformed(ActionEvent e) {
346                 rollbackChange(selection);
347             }
348         }));
349         if (drev != null) {
350             if (!"dead".equals(drev.getRevision().getState())) { // NOI18N
351
menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, "CTL_SummaryView_RollbackTo", drev.getRevision().getNumber())) { // NOI18N
352
{
353                         setEnabled(selection.length == 1 && dispResults.get(selection[0]) instanceof SearchHistoryPanel.DispRevision);
354                     }
355                     public void actionPerformed(ActionEvent e) {
356                         rollback(selection[0]);
357                     }
358                 }));
359                 menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, "CTL_SummaryView_View", drev.getRevision().getNumber())) { // NOI18N
360
{
361                         setEnabled(selection.length == 1 && dispResults.get(selection[0]) instanceof SearchHistoryPanel.DispRevision);
362                     }
363                     public void actionPerformed(ActionEvent e) {
364                         RequestProcessor.getDefault().post(new Runnable JavaDoc() {
365                             public void run() {
366                                 view(selection[0]);
367                             }
368                         });
369                     }
370                 }));
371                 
372             }
373
374             Project prj = master.getProject(drev.getRevision().getLogInfoHeader().getFile());
375             if (prj != null) {
376                 String JavaDoc prjName = ProjectUtils.getInformation(prj).getDisplayName();
377                 menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, "CTL_Action_AssociateChangesInProject", prjName)) { // NOI18N
378
{
379                         setEnabled(selection.length == 1 && dispResults.get(selection[0]) instanceof SearchHistoryPanel.DispRevision);
380                     }
381                     public void actionPerformed(ActionEvent e) {
382                         associatedChangesInProject(selection[0]);
383                     }
384                 }));
385             }
386             menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, "CTL_Action_AssociateChangesInOpenProjects")) { // NOI18N
387
{
388                     setEnabled(selection.length == 1 && dispResults.get(selection[0]) instanceof SearchHistoryPanel.DispRevision);
389                 }
390                 public void actionPerformed(ActionEvent e) {
391                     associatedChangesInOpenProjects(selection[0]);
392                 }
393             }));
394         }
395
396         menu.show(e.getComponent(), e.getX(), e.getY());
397     }
398
399     private boolean someRevisions(int[] selection) {
400         for (int i = 0; i < selection.length; i++) {
401             Object JavaDoc revCon = dispResults.get(selection[i]);
402             if (revCon instanceof SearchHistoryPanel. DispRevision) {
403                 return true;
404             }
405         }
406         return false;
407     }
408
409     private void rollbackChange(int [] selection) {
410         List JavaDoc changes = new ArrayList();
411         for (int i = 0; i < selection.length; i++) {
412             int idx = selection[i];
413             Object JavaDoc o = dispResults.get(idx);
414             if (o instanceof SearchHistoryPanel.DispRevision) {
415                 SearchHistoryPanel.DispRevision drev = (SearchHistoryPanel.DispRevision) o;
416                 changes.add(drev.getRevision());
417             }
418         }
419         rollbackChanges((LogInformation.Revision[]) changes.toArray(new LogInformation.Revision[changes.size()]));
420     }
421
422     private static void rollbackChange(LogInformation.Revision change, ExecutorGroup group) {
423         UpdateCommand cmd = new UpdateCommand();
424         cmd.setFiles(new File JavaDoc [] { change.getLogInfoHeader().getFile() });
425         cmd.setMergeRevision1(change.getNumber());
426         cmd.setMergeRevision2(Utils.previousRevision(change.getNumber()));
427         group.addExecutors(UpdateExecutor.splitCommand(cmd, CvsVersioningSystem.getInstance(), null, null));
428     }
429
430     static void rollbackChanges(LogInformation.Revision [] changes) {
431         ExecutorGroup group = new ExecutorGroup(NbBundle.getMessage(SummaryView.class, "MSG_SummaryView_RollingBackChange")); // NOI18N
432
for (int i = 0; i < changes.length; i++) {
433             rollbackChange(changes[i], group);
434         }
435         group.execute();
436     }
437     
438     private void rollback(int idx) {
439         Object JavaDoc o = dispResults.get(idx);
440         if (o instanceof SearchHistoryPanel.DispRevision) {
441             SearchHistoryPanel.DispRevision drev = (SearchHistoryPanel.DispRevision) o;
442             String JavaDoc revision = drev.getRevision().getNumber().trim();
443             File JavaDoc file = drev.getRevision().getLogInfoHeader().getFile();
444             GetCleanAction.rollback(file, revision);
445         }
446     }
447
448
449     private void view(int idx) {
450         Object JavaDoc o = dispResults.get(idx);
451         if (o instanceof SearchHistoryPanel.DispRevision) {
452             SearchHistoryPanel.DispRevision drev = (SearchHistoryPanel.DispRevision) o;
453             FileObject fo = FileUtil.toFileObject(drev.getRevision().getLogInfoHeader().getFile());
454             org.netbeans.modules.versioning.util.Utils.openFile(fo, drev.getRevision().getNumber());
455         }
456     }
457     private void diffPrevious(int idx) {
458         Object JavaDoc o = dispResults.get(idx);
459         if (o instanceof SearchHistoryPanel.DispRevision) {
460             SearchHistoryPanel.DispRevision drev = (SearchHistoryPanel.DispRevision) o;
461             master.showDiff(drev);
462         } else {
463             SearchHistoryPanel.ResultsContainer container = (SearchHistoryPanel.ResultsContainer) o;
464             master.showDiff(container);
465         }
466     }
467
468     private void associatedChangesInOpenProjects(int idx) {
469         Object JavaDoc o = dispResults.get(idx);
470         if (o instanceof SearchHistoryPanel.DispRevision) {
471             SearchHistoryPanel.DispRevision drev = (SearchHistoryPanel.DispRevision) o;
472             Project [] projects = OpenProjects.getDefault().getOpenProjects();
473             int n = projects.length;
474             SearchHistoryAction.openSearch(
475                     (n == 1) ? ProjectUtils.getInformation(projects[0]).getDisplayName() :
476                     NbBundle.getMessage(SummaryView.class, "CTL_FindAssociateChanges_OpenProjects_Title", Integer.toString(n)), // NOI18N
477
drev.getRevision().getMessage().trim(), drev.getRevision().getAuthor(), drev.getRevision().getDate());
478         }
479     }
480
481     private void associatedChangesInProject(int idx) {
482         Object JavaDoc o = dispResults.get(idx);
483         if (o instanceof SearchHistoryPanel.DispRevision) {
484             SearchHistoryPanel.DispRevision drev = (SearchHistoryPanel.DispRevision) o;
485             File JavaDoc file = drev.getRevision().getLogInfoHeader().getFile();
486             Project project = master.getProject(file);
487             Context context = Utils.getProjectsContext(new Project[] { master.getProject(file) });
488             SearchHistoryAction.openSearch(
489                     context,
490                     ProjectUtils.getInformation(project).getDisplayName(),
491                     drev.getRevision().getMessage().trim(), drev.getRevision().getAuthor(), drev.getRevision().getDate());
492         }
493     }
494     
495     public JComponent getComponent() {
496         return scrollPane;
497     }
498
499     /**
500      * @return Collection<Object> currently selected items in the view or an empty Collection.
501      */

502     List JavaDoc<Object JavaDoc> getSelection() {
503         List JavaDoc<Object JavaDoc> selection = new ArrayList<Object JavaDoc>();
504         for (int i : resultsList.getSelectedIndices()) {
505             selection.add(dispResults.get(i));
506         }
507         return selection;
508     }
509
510     private class SummaryListModel extends AbstractListModel {
511
512         public int getSize() {
513             return dispResults.size();
514         }
515
516         public Object JavaDoc getElementAt(int index) {
517             return dispResults.get(index);
518         }
519     }
520     
521     private static Color darker(Color c) {
522         return new Color(Math.max((int)(c.getRed() * DARKEN_FACTOR), 0),
523              Math.max((int)(c.getGreen() * DARKEN_FACTOR), 0),
524              Math.max((int)(c.getBlue() * DARKEN_FACTOR), 0));
525     }
526     
527     private class SummaryCellRenderer extends JPanel implements ListCellRenderer {
528
529         private static final String JavaDoc FIELDS_SEPARATOR = " "; // NOI18N
530

531         private Style selectedStyle;
532         private Style normalStyle;
533         private Style branchStyle;
534         private Style filenameStyle;
535         private Style indentStyle;
536         private Style noindentStyle;
537         private Style hiliteStyle;
538         
539         private JTextPane textPane = new JTextPane();
540         private JPanel actionsPane = new JPanel();
541         private final JPanel tagsPanel;
542         private final JPanel actionsPanel;
543         
544         private DateFormat JavaDoc defaultFormat;
545         
546         private int index;
547         private final HyperlinkLabel tagsLink;
548         private final HyperlinkLabel diffLink;
549         private final HyperlinkLabel acpLink;
550         private final HyperlinkLabel acopLink;
551         
552         private final JLabel tagsLabel;
553         private final JLabel diffToLabel;
554         private final JLabel findCommitInLabel;
555         private final JLabel commaLabel;
556
557         public SummaryCellRenderer() {
558             selectedStyle = textPane.addStyle("selected", null); // NOI18N
559
StyleConstants.setForeground(selectedStyle, UIManager.getColor("List.selectionForeground")); // NOI18N
560
normalStyle = textPane.addStyle("normal", null); // NOI18N
561
StyleConstants.setForeground(normalStyle, UIManager.getColor("List.foreground")); // NOI18N
562
branchStyle = textPane.addStyle("normal", null); // NOI18N
563
StyleConstants.setForeground(branchStyle, Color.GRAY); // NOI18N
564
filenameStyle = textPane.addStyle("filename", normalStyle); // NOI18N
565
StyleConstants.setBold(filenameStyle, true);
566             indentStyle = textPane.addStyle("indent", null); // NOI18N
567
StyleConstants.setLeftIndent(indentStyle, 50);
568             noindentStyle = textPane.addStyle("noindent", null); // NOI18N
569
StyleConstants.setLeftIndent(noindentStyle, 0);
570             defaultFormat = DateFormat.getDateTimeInstance();
571
572             hiliteStyle = textPane.addStyle("hilite", normalStyle); // NOI18N
573
Color c = (Color) searchHiliteAttrs.getAttribute(StyleConstants.Background);
574             if (c != null) StyleConstants.setBackground(hiliteStyle, c);
575             c = (Color) searchHiliteAttrs.getAttribute(StyleConstants.Foreground);
576             if (c != null) StyleConstants.setForeground(hiliteStyle, c);
577
578             setLayout(new BorderLayout());
579             add(textPane);
580             add(actionsPane, BorderLayout.PAGE_END);
581             
582             actionsPane.setLayout(new BorderLayout());
583             actionsPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
584             
585             tagsPanel = new JPanel();
586             tagsPanel.setLayout(new FlowLayout(FlowLayout.LEADING, 2, 5));
587             actionsPanel = new JPanel();
588             actionsPanel.setLayout(new FlowLayout(FlowLayout.TRAILING, 2, 5));
589             actionsPane.add(tagsPanel, BorderLayout.WEST);
590             actionsPane.add(actionsPanel);
591             
592             tagsLabel = new JLabel();
593             tagsLink = new HyperlinkLabel();
594             tagsPanel.add(tagsLabel);
595             tagsLabel.setBorder(BorderFactory.createEmptyBorder(0, 50 - 2, 0, 0)); // -2 flowlayout hgap
596
tagsPanel.add(tagsLink);
597             
598             diffToLabel = new JLabel(NbBundle.getMessage(SummaryView.class, "CTL_Action_DiffTo")); // NOI18N
599
actionsPanel.add(diffToLabel);
600             diffLink = new HyperlinkLabel();
601             diffLink.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 8));
602             actionsPanel.add(diffLink);
603
604             acopLink = new HyperlinkLabel();
605             acpLink = new HyperlinkLabel();
606
607             findCommitInLabel = new JLabel(NbBundle.getMessage(SummaryView.class, "CTL_Action_FindCommitIn")); // NOI18N
608
actionsPanel.add(findCommitInLabel);
609             actionsPanel.add(acpLink);
610             
611             commaLabel = new JLabel(","); // NOI18N
612
actionsPanel.add(commaLabel);
613             actionsPanel.add(acopLink);
614             
615             textPane.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
616         }
617                 
618         public Component getListCellRendererComponent(JList list, Object JavaDoc value, int index, boolean isSelected, boolean cellHasFocus) {
619             if (value instanceof SearchHistoryPanel.ResultsContainer) {
620                 renderContainer((SearchHistoryPanel.ResultsContainer) value, index, isSelected);
621             } else {
622                 renderRevision(list, (SearchHistoryPanel.DispRevision) value, index, isSelected);
623             }
624             return this;
625         }
626
627         private void renderContainer(SearchHistoryPanel.ResultsContainer container, int index, boolean isSelected) {
628
629             StyledDocument sd = textPane.getStyledDocument();
630
631             Style style;
632             if (isSelected) {
633                 textPane.setBackground(UIManager.getColor("List.selectionBackground")); // NOI18N
634
actionsPane.setBackground(UIManager.getColor("List.selectionBackground")); // NOI18N
635
style = selectedStyle;
636             } else {
637                 Color c = UIManager.getColor("List.background"); // NOI18N
638
textPane.setBackground((index & 1) == 0 ? c : darker(c));
639                 actionsPane.setBackground((index & 1) == 0 ? c : darker(c));
640                 style = normalStyle;
641             }
642             
643             try {
644                 sd.remove(0, sd.getLength());
645                 sd.setCharacterAttributes(0, Integer.MAX_VALUE, style, true);
646                 sd.insertString(0, container.getName(), null);
647                 sd.setCharacterAttributes(0, sd.getLength(), filenameStyle, false);
648                 sd.insertString(sd.getLength(), FIELDS_SEPARATOR + container.getPath(), null);
649                 sd.setCharacterAttributes(0, sd.getLength(), style, false);
650                 sd.setParagraphAttributes(0, sd.getLength(), noindentStyle, false);
651             } catch (BadLocationException e) {
652                 ErrorManager.getDefault().notify(e);
653             }
654             actionsPane.setVisible(false);
655         }
656
657         private void renderRevision(JList list, SearchHistoryPanel.DispRevision dispRevision, final int index, boolean isSelected) {
658             Style style;
659             StyledDocument sd = textPane.getStyledDocument();
660
661             this.index = index;
662             
663             Color backgroundColor;
664             Color foregroundColor;
665             
666             if (isSelected) {
667                 foregroundColor = UIManager.getColor("List.selectionForeground"); // NOI18N
668
backgroundColor = UIManager.getColor("List.selectionBackground"); // NOI18N
669
style = selectedStyle;
670             } else {
671                 foregroundColor = UIManager.getColor("List.foreground"); // NOI18N
672
backgroundColor = UIManager.getColor("List.background"); // NOI18N
673
backgroundColor = (index & 1) == 0 ? backgroundColor : darker(backgroundColor);
674                 style = normalStyle;
675             }
676             textPane.setBackground(backgroundColor);
677             actionsPane.setBackground(backgroundColor);
678             tagsPanel.setBackground(backgroundColor);
679             actionsPanel.setBackground(backgroundColor);
680             
681             LogInformation.Revision revision = dispRevision.getRevision();
682             String JavaDoc commitMessage = revision.getMessage();
683             if (commitMessage.endsWith("\n")) commitMessage = commitMessage.substring(0, commitMessage.length() - 1); // NOI18N
684
int indentation = dispRevision.getIndentation();
685             try {
686                 sd.remove(0, sd.getLength());
687                 sd.setCharacterAttributes(0, Integer.MAX_VALUE, style, true);
688                 if (indentation == 0) {
689                     sd.insertString(0, dispRevision.getRevision().getLogInfoHeader().getFile().getName(), style);
690                     sd.setCharacterAttributes(0, sd.getLength(), filenameStyle, false);
691                     sd.insertString(sd.getLength(), FIELDS_SEPARATOR + dispRevision.getName().substring(0, dispRevision.getName().lastIndexOf('/')) + "\n", style); // NOI18N
692
}
693                 StringBuilder JavaDoc headerMessageBuilder = new StringBuilder JavaDoc();
694                 headerMessageBuilder.append(revision.getNumber());
695                 headerMessageBuilder.append(FIELDS_SEPARATOR);
696                 headerMessageBuilder.append(defaultFormat.format(revision.getDate()));
697                 headerMessageBuilder.append(FIELDS_SEPARATOR);
698                 headerMessageBuilder.append(revision.getAuthor());
699                 String JavaDoc branch = getBranch(dispRevision);
700                 
701                 String JavaDoc headerMessage = headerMessageBuilder.toString();
702                 sd.insertString(sd.getLength(), headerMessage, style);
703
704                 if (branch != null) {
705                     sd.insertString(sd.getLength(), FIELDS_SEPARATOR + branch, branchStyle);
706                 }
707                 if ("dead".equalsIgnoreCase(dispRevision.getRevision().getState())) { // NOI18N
708
sd.insertString(sd.getLength(), FIELDS_SEPARATOR + NbBundle.getMessage(SummaryView.class, "MSG_SummaryView_DeadState"), style); // NOI18N
709
}
710                 sd.insertString(sd.getLength(), "\n", style); // NOI18N
711

712                 sd.insertString(sd.getLength(), commitMessage, style);
713                 if (message != null && !isSelected) {
714                     int idx = revision.getMessage().indexOf(message);
715                     if (idx != -1) {
716                         int len = commitMessage.length();
717                         int doclen = sd.getLength();
718                         sd.setCharacterAttributes(doclen - len + idx, message.length(), hiliteStyle, false);
719                     }
720                 }
721                 if (indentation > 0) {
722                     sd.setParagraphAttributes(0, sd.getLength(), indentStyle, false);
723                 } else {
724                     sd.setParagraphAttributes(0, sd.getLength(), noindentStyle, false);
725                 }
726             } catch (BadLocationException e) {
727                 ErrorManager.getDefault().notify(e);
728             }
729             
730             if (commitMessage != null) {
731                 int width = master.getWidth();
732                 if (width > 0) {
733                     FontMetrics fm = list.getFontMetrics(list.getFont());
734                     Rectangle2D JavaDoc rect = fm.getStringBounds(commitMessage, textPane.getGraphics());
735                     int nlc, i;
736                     for (nlc = -1, i = 0; i != -1 ; i = commitMessage.indexOf('\n', i + 1), nlc++); // NOI18N
737
if (indentation == 0) nlc++;
738                     int lines = (int) (rect.getWidth() / (width - 80) + 1);
739                     int ph = fm.getHeight() * (lines + nlc + 1) + 4; // + 4 text pane border
740
textPane.setPreferredSize(new Dimension(width - 50, ph));
741                 }
742             }
743             
744             actionsPane.setVisible(true);
745
746             List JavaDoc<String JavaDoc> tags = new ArrayList<String JavaDoc>(dispRevision.getBranches());
747             tags.addAll(dispRevision.getTags());
748             if (tags.size() > 0) {
749                 tagsLabel.setVisible(true);
750                 String JavaDoc tagInfo = tags.get(0);
751                 tagsLabel.setForeground(isSelected ? foregroundColor : Color.GRAY);
752                 if (tags.size() > 1) {
753                     tagInfo += ","; // NOI18N
754
tagsLink.setVisible(true);
755                     tagsLink.set("...", foregroundColor, backgroundColor); // NOI18N
756
} else {
757                     tagsLink.setVisible(false);
758                 }
759                 tagsLabel.setText(tagInfo);
760             } else {
761                 tagsLabel.setVisible(false);
762                 tagsLink.setVisible(false);
763             }
764
765             String JavaDoc prev = Utils.previousRevision(dispRevision.getRevision().getNumber());
766             if (prev != null) {
767                 diffToLabel.setVisible(true);
768                 diffLink.setVisible(true);
769                 diffToLabel.setForeground(foregroundColor);
770                 diffLink.set(prev, foregroundColor, backgroundColor);
771             } else {
772                 diffToLabel.setVisible(false);
773                 diffLink.setVisible(false);
774             }
775
776             Project [] projects = OpenProjects.getDefault().getOpenProjects();
777             if (projects.length > 0) {
778                 acopLink.setVisible(true);
779                 acopLink.set(NbBundle.getMessage(SummaryView.class, "CTL_Action_FindCommitInOpenProjects"), foregroundColor, backgroundColor); // NOI18N
780
} else {
781                 acopLink.setVisible(false);
782             }
783             
784             Project prj = master.getProject(dispRevision.getRevision().getLogInfoHeader().getFile());
785             if (prj != null) {
786                 String JavaDoc prjName = ProjectUtils.getInformation(prj).getDisplayName();
787                 acpLink.setVisible(true);
788                 acpLink.set("\"" + prjName + "\"", foregroundColor, backgroundColor); // NOI18N
789
} else {
790                 acpLink.setVisible(false);
791             }
792
793             if (acpLink.isVisible() || acopLink.isVisible()) {
794                 findCommitInLabel.setVisible(true);
795                 findCommitInLabel.setForeground(foregroundColor);
796                 if (acopLink.isVisible() && acopLink.isVisible()) {
797                     commaLabel.setVisible(true);
798                     commaLabel.setForeground(foregroundColor);
799                 } else {
800                     commaLabel.setVisible(false);
801                 }
802             } else {
803                 commaLabel.setVisible(false);
804                 findCommitInLabel.setVisible(false);
805             }
806         }
807
808         protected void paintComponent(Graphics g) {
809             super.paintComponent(g);
810             Rectangle apb = actionsPane.getBounds();
811             Rectangle lkb = actionsPanel.getBounds();
812             if (diffLink.isVisible()) {
813                 Rectangle bounds = diffLink.getBounds();
814                 bounds.setBounds(bounds.x + lkb.x, bounds.y + apb.y + lkb.y, bounds.width, bounds.height);
815                 resultsList.putClientProperty("Summary-Diff-" + index, bounds); // NOI18N
816
}
817             if (acpLink.isVisible()) {
818                 Rectangle bounds = acpLink.getBounds();
819                 bounds.setBounds(bounds.x + lkb.x, bounds.y + apb.y + lkb.y, bounds.width, bounds.height);
820                 resultsList.putClientProperty("Summary-Acp-" + index, bounds); // NOI18N
821
}
822             if (acopLink.isVisible()) {
823                 Rectangle bounds = acopLink.getBounds();
824                 bounds.setBounds(bounds.x + lkb.x, bounds.y + apb.y + lkb.y, bounds.width, bounds.height);
825                 resultsList.putClientProperty("Summary-Acop-" + index, bounds); // NOI18N
826
}
827             if (tagsLink.isVisible()) {
828                 Rectangle tpb = tagsPanel.getBounds();
829                 Rectangle bounds = tagsLink.getBounds();
830                 bounds.setBounds(bounds.x + tpb.x, bounds.y + apb.y + tpb.y, bounds.width, bounds.height);
831                 resultsList.putClientProperty("Summary-tagsLink-" + index, bounds); // NOI18N
832
}
833         }
834     }
835     
836     private String JavaDoc getBranch(SearchHistoryPanel.DispRevision revision) {
837         String JavaDoc number = revision.getRevision().getNumber();
838         int idx = number.lastIndexOf('.');
839         if (idx == number.indexOf('.')) return null;
840         int idx2 = number.lastIndexOf('.', idx - 1);
841         String JavaDoc branchNumber = number.substring(0, idx2) + ".0" + number.substring(idx2, idx); // NOI18N
842
List JavaDoc<LogInformation.SymName> names = revision.getRevision().getLogInfoHeader().getSymNamesForRevision(branchNumber);
843         if (names.size() != 1) return null;
844         return names.get(0).getName();
845     }
846
847     private static class HyperlinkLabel extends JLabel {
848
849         public HyperlinkLabel() {
850             setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
851         }
852
853         public void set(String JavaDoc text, Color foreground, Color background) {
854             StringBuilder JavaDoc sb = new StringBuilder JavaDoc(100);
855             if (foreground.equals(UIManager.getColor("List.foreground"))) { // NOI18N
856
sb.append("<html><a HREF=\"\">"); // NOI18N
857
sb.append(text);
858                 sb.append("</a>"); // NOI18N
859
} else {
860                 sb.append("<html><a HREF=\"\" style=\"color:"); // NOI18N
861
sb.append("rgb("); // NOI18N
862
sb.append(foreground.getRed());
863                 sb.append(","); // NOI18N
864
sb.append(foreground.getGreen());
865                 sb.append(","); // NOI18N
866
sb.append(foreground.getBlue());
867                 sb.append(")"); // NOI18N
868
sb.append("\">"); // NOI18N
869
sb.append(text);
870                 sb.append("</a>"); // NOI18N
871
}
872             setText(sb.toString());
873             setBackground(background);
874         }
875     }
876 }
877
Popular Tags