1 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 ; 49 import java.util.logging.Logger ; 50 import java.util.logging.Level ; 51 import java.awt.*; 52 import java.awt.geom.Rectangle2D ; 53 import java.awt.event.*; 54 import java.text.DateFormat ; 55 import java.io.File ; 56 57 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 dispResults; 72 private String message; 73 private AttributeSet searchHiliteAttrs; 74 75 public SummaryView(SearchHistoryPanel master, List results) { 76 this.master = master; 77 this.dispResults = expandResults(results); 78 FontColorSettings fcs = MimeLookup.getLookup(MimePath.get("text/x-java")).lookup(FontColorSettings.class); searchHiliteAttrs = fcs.getFontColors("highlight-search"); 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")); resultsList.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(SummaryView.class, "ACSD_SummaryView_List")); 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 } 101 102 public void componentMoved(ComponentEvent e) { 103 } 105 106 public void componentShown(ComponentEvent e) { 107 } 109 110 private static List expandResults(List results) { 111 ArrayList newResults = new ArrayList(results.size()); 112 for (Iterator i = results.iterator(); i.hasNext();) { 113 Object 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 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); if (diffBounds != null && diffBounds.contains(p)) { 162 diffPrevious(idx); 163 } 164 diffBounds = (Rectangle) resultsList.getClientProperty("Summary-Acp-" + idx); if (diffBounds != null && diffBounds.contains(p)) { 166 associatedChangesInProject(idx); 167 } 168 diffBounds = (Rectangle) resultsList.getClientProperty("Summary-Acop-" + idx); if (diffBounds != null && diffBounds.contains(p)) { 170 associatedChangesInOpenProjects(idx); 171 } 172 diffBounds = (Rectangle) resultsList.getClientProperty("Summary-tagsLink-" + idx); 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"))); tp.setBorder(BorderFactory.createEmptyBorder(6, 8, 0, 0)); 183 tp.setEditable(false); 184 185 Style headerStyle = tp.addStyle("headerStyle", null); StyleConstants.setBold(headerStyle, true); 187 Style unmodifiedBranchStyle = tp.addStyle("unmodifiedBranchStyle", null); StyleConstants.setForeground(unmodifiedBranchStyle, Color.GRAY); 189 190 String modifiedBranches = drev.getRevision().getBranches(); 191 192 Document doc = tp.getDocument(); 193 try { 194 List <String > tags; 195 196 doc.insertString(doc.getLength(), NbBundle.getMessage(SummaryView.class, "CTL_TagsWindow_BranchesLabel") + "\n", headerStyle); tags = drev.getBranches(); 198 for (String tag : tags) { 199 if (modifiedBranches == null || (modifiedBranches.indexOf(tag.substring(tag.indexOf("(") + 1, tag.indexOf(")")))) == -1) { doc.insertString(doc.getLength(), tag + "\n", unmodifiedBranchStyle); } else { 202 doc.insertString(doc.getLength(), tag + "\n", null); } 204 } 205 if (tags.size() == 0) { 206 doc.insertString(doc.getLength(), NbBundle.getMessage(SummaryView.class, "CTL_TagsWindow_NoBranchesLabel") + "\n", unmodifiedBranchStyle); } 208 209 doc.insertString(doc.getLength(), "\n" + NbBundle.getMessage(SummaryView.class, "CTL_TagsWindow_TagsLabel") + "\n", headerStyle); StringBuilder sb = new StringBuilder (); 211 tags = drev.getTags(); 212 for (String tag : tags) { 213 sb.append(tag); 214 sb.append('\n'); } 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); } 221 222 } catch (BadLocationException e) { 223 Logger.getLogger(SummaryView.class.getName()).log(Level.WARNING, "Internal error creating tag list", e); } 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 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 } 252 253 public void mouseExited(MouseEvent e) { 254 } 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); 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); 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); 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); 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 previousRevision = null; 313 SearchHistoryPanel.ResultsContainer container = null; 314 SearchHistoryPanel.DispRevision drev = null; 315 Object 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 eldest = container.getEldestRevision(); 324 menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, "CTL_SummaryView_Diff", eldest, container.getNewestRevision())) { 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)) { { 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")) { { 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())) { menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, "CTL_SummaryView_RollbackTo", drev.getRevision().getNumber())) { { 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())) { { 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 () { 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 prjName = ProjectUtils.getInformation(prj).getDisplayName(); 377 menu.add(new JMenuItem(new AbstractAction(NbBundle.getMessage(SummaryView.class, "CTL_Action_AssociateChangesInProject", prjName)) { { 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")) { { 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 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 changes = new ArrayList(); 411 for (int i = 0; i < selection.length; i++) { 412 int idx = selection[i]; 413 Object 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 [] { 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")); 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 o = dispResults.get(idx); 440 if (o instanceof SearchHistoryPanel.DispRevision) { 441 SearchHistoryPanel.DispRevision drev = (SearchHistoryPanel.DispRevision) o; 442 String revision = drev.getRevision().getNumber().trim(); 443 File file = drev.getRevision().getLogInfoHeader().getFile(); 444 GetCleanAction.rollback(file, revision); 445 } 446 } 447 448 449 private void view(int idx) { 450 Object 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 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 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)), drev.getRevision().getMessage().trim(), drev.getRevision().getAuthor(), drev.getRevision().getDate()); 478 } 479 } 480 481 private void associatedChangesInProject(int idx) { 482 Object o = dispResults.get(idx); 483 if (o instanceof SearchHistoryPanel.DispRevision) { 484 SearchHistoryPanel.DispRevision drev = (SearchHistoryPanel.DispRevision) o; 485 File 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 502 List <Object > getSelection() { 503 List <Object > selection = new ArrayList<Object >(); 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 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 FIELDS_SEPARATOR = " "; 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 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); StyleConstants.setForeground(selectedStyle, UIManager.getColor("List.selectionForeground")); normalStyle = textPane.addStyle("normal", null); StyleConstants.setForeground(normalStyle, UIManager.getColor("List.foreground")); branchStyle = textPane.addStyle("normal", null); StyleConstants.setForeground(branchStyle, Color.GRAY); filenameStyle = textPane.addStyle("filename", normalStyle); StyleConstants.setBold(filenameStyle, true); 566 indentStyle = textPane.addStyle("indent", null); StyleConstants.setLeftIndent(indentStyle, 50); 568 noindentStyle = textPane.addStyle("noindent", null); StyleConstants.setLeftIndent(noindentStyle, 0); 570 defaultFormat = DateFormat.getDateTimeInstance(); 571 572 hiliteStyle = textPane.addStyle("hilite", normalStyle); 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)); tagsPanel.add(tagsLink); 597 598 diffToLabel = new JLabel(NbBundle.getMessage(SummaryView.class, "CTL_Action_DiffTo")); 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")); actionsPanel.add(findCommitInLabel); 609 actionsPanel.add(acpLink); 610 611 commaLabel = new JLabel(","); 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 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")); actionsPane.setBackground(UIManager.getColor("List.selectionBackground")); style = selectedStyle; 636 } else { 637 Color c = UIManager.getColor("List.background"); 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"); backgroundColor = UIManager.getColor("List.selectionBackground"); style = selectedStyle; 670 } else { 671 foregroundColor = UIManager.getColor("List.foreground"); backgroundColor = UIManager.getColor("List.background"); 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 commitMessage = revision.getMessage(); 683 if (commitMessage.endsWith("\n")) commitMessage = commitMessage.substring(0, commitMessage.length() - 1); 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); } 693 StringBuilder headerMessageBuilder = new StringBuilder (); 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 branch = getBranch(dispRevision); 700 701 String 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())) { sd.insertString(sd.getLength(), FIELDS_SEPARATOR + NbBundle.getMessage(SummaryView.class, "MSG_SummaryView_DeadState"), style); } 710 sd.insertString(sd.getLength(), "\n", style); 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 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++); if (indentation == 0) nlc++; 738 int lines = (int) (rect.getWidth() / (width - 80) + 1); 739 int ph = fm.getHeight() * (lines + nlc + 1) + 4; textPane.setPreferredSize(new Dimension(width - 50, ph)); 741 } 742 } 743 744 actionsPane.setVisible(true); 745 746 List <String > tags = new ArrayList<String >(dispRevision.getBranches()); 747 tags.addAll(dispRevision.getTags()); 748 if (tags.size() > 0) { 749 tagsLabel.setVisible(true); 750 String tagInfo = tags.get(0); 751 tagsLabel.setForeground(isSelected ? foregroundColor : Color.GRAY); 752 if (tags.size() > 1) { 753 tagInfo += ","; tagsLink.setVisible(true); 755 tagsLink.set("...", foregroundColor, backgroundColor); } else { 757 tagsLink.setVisible(false); 758 } 759 tagsLabel.setText(tagInfo); 760 } else { 761 tagsLabel.setVisible(false); 762 tagsLink.setVisible(false); 763 } 764 765 String 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); } else { 781 acopLink.setVisible(false); 782 } 783 784 Project prj = master.getProject(dispRevision.getRevision().getLogInfoHeader().getFile()); 785 if (prj != null) { 786 String prjName = ProjectUtils.getInformation(prj).getDisplayName(); 787 acpLink.setVisible(true); 788 acpLink.set("\"" + prjName + "\"", foregroundColor, backgroundColor); } 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); } 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); } 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); } 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); } 833 } 834 } 835 836 private String getBranch(SearchHistoryPanel.DispRevision revision) { 837 String 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 branchNumber = number.substring(0, idx2) + ".0" + number.substring(idx2, idx); List <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 text, Color foreground, Color background) { 854 StringBuilder sb = new StringBuilder (100); 855 if (foreground.equals(UIManager.getColor("List.foreground"))) { sb.append("<html><a HREF=\"\">"); sb.append(text); 858 sb.append("</a>"); } else { 860 sb.append("<html><a HREF=\"\" style=\"color:"); sb.append("rgb("); sb.append(foreground.getRed()); 863 sb.append(","); sb.append(foreground.getGreen()); 865 sb.append(","); sb.append(foreground.getBlue()); 867 sb.append(")"); sb.append("\">"); sb.append(text); 870 sb.append("</a>"); } 872 setText(sb.toString()); 873 setBackground(background); 874 } 875 } 876 } 877 | Popular Tags |