This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 218850
Collapse All | Expand All

(-)a/versioning.util/src/org/netbeans/modules/versioning/history/SummaryCellRenderer.java (-211 / +378 lines)
Lines 85-98 Link Here
85
import org.netbeans.api.editor.mimelookup.MimeLookup;
85
import org.netbeans.api.editor.mimelookup.MimeLookup;
86
import org.netbeans.api.editor.mimelookup.MimePath;
86
import org.netbeans.api.editor.mimelookup.MimePath;
87
import org.netbeans.api.editor.settings.FontColorSettings;
87
import org.netbeans.api.editor.settings.FontColorSettings;
88
import org.netbeans.modules.versioning.history.AbstractSummaryView.LogEntry;
88
import org.netbeans.modules.versioning.history.AbstractSummaryView.LogEntry.Event;
89
import org.netbeans.modules.versioning.history.AbstractSummaryView.LogEntry.Event;
89
import org.netbeans.modules.versioning.history.AbstractSummaryView.RevisionItem;
90
import org.netbeans.modules.versioning.history.AbstractSummaryView.RevisionItem;
90
import org.netbeans.modules.versioning.history.AbstractSummaryView.SummaryViewMaster.SearchHighlight;
91
import org.netbeans.modules.versioning.history.AbstractSummaryView.SummaryViewMaster.SearchHighlight;
91
import org.netbeans.modules.versioning.util.Utils;
92
import org.netbeans.modules.versioning.util.Utils;
92
import org.netbeans.modules.versioning.util.VCSHyperlinkProvider;
93
import org.netbeans.modules.versioning.util.VCSHyperlinkProvider;
93
import org.netbeans.modules.versioning.util.VCSHyperlinkSupport;
94
import org.netbeans.modules.versioning.util.VCSHyperlinkSupport;
95
import org.netbeans.modules.versioning.util.VCSHyperlinkSupport.IssueLinker;
94
import org.netbeans.modules.versioning.util.VCSKenaiAccessor;
96
import org.netbeans.modules.versioning.util.VCSKenaiAccessor;
95
import org.openide.ErrorManager;
97
import org.openide.ErrorManager;
98
import org.openide.util.Exceptions;
96
import org.openide.util.Lookup;
99
import org.openide.util.Lookup;
97
import org.openide.util.NbBundle;
100
import org.openide.util.NbBundle;
98
101
Lines 250-268 Link Here
250
        return kenaiUser;
253
        return kenaiUser;
251
    }
254
    }
252
255
256
    /**
257
     * Composite panel for displaying revision, author, commit message and other
258
     * info.
259
     */
260
    public class RevisionItemCell extends JPanel {
261
262
        private JTextPane authorControl;
263
        private JTextPane dateControl;
264
        private JTextPane revisionControl;
265
        private JTextPane commitMessageControl;
266
        private JPanel northPanel;
267
        private JPanel authorDatePanel;
268
269
        public RevisionItemCell () {
270
271
            northPanel = new javax.swing.JPanel();
272
            authorDatePanel = new javax.swing.JPanel();
273
            dateControl = new JTextPane();
274
            authorControl = new JTextPane();
275
            revisionControl = new JTextPane();
276
            commitMessageControl = new JTextPane();
277
278
            this.setBorder(null);
279
            this.setLayout(new BorderLayout(0, 0));
280
            this.add(commitMessageControl, java.awt.BorderLayout.CENTER);
281
            this.add(northPanel, java.awt.BorderLayout.NORTH);
282
            initTextPane(dateControl);
283
            initTextPane(authorControl);
284
            initTextPane(revisionControl);
285
            initTextPane(commitMessageControl);
286
287
288
            northPanel.setBorder(BorderFactory.createEmptyBorder());
289
            northPanel.setLayout(new BorderLayout(5, 0));
290
            northPanel.add(authorDatePanel, java.awt.BorderLayout.EAST);
291
            northPanel.add(revisionControl, java.awt.BorderLayout.CENTER);
292
293
            authorDatePanel.setLayout(new BorderLayout(5, 0));
294
            authorDatePanel.setBorder(BorderFactory.createEmptyBorder());
295
            authorDatePanel.add(authorControl, BorderLayout.CENTER);
296
            authorDatePanel.add(dateControl, BorderLayout.EAST);
297
298
            northPanel.setOpaque(false);
299
            revisionControl.setOpaque(false);
300
            dateControl.setOpaque(false);
301
            authorControl.setOpaque(false);
302
            commitMessageControl.setOpaque(false);
303
            authorDatePanel.setOpaque(false);
304
305
            this.setFocusable(false);
306
            northPanel.setFocusable(false);
307
            authorDatePanel.setFocusable(false);
308
309
        }
310
311
        public JTextPane getAuthorControl () {
312
            return authorControl;
313
        }
314
315
        public JTextPane getDateControl () {
316
            return dateControl;
317
        }
318
319
        public JTextPane getRevisionControl () {
320
            return revisionControl;
321
        }
322
323
        public JTextPane getCommitMessageControl () {
324
            return commitMessageControl;
325
        }
326
327
        public JPanel getNorthPanel () {
328
            return northPanel;
329
        }
330
331
        public void initTextPane (JTextPane pane) {
332
            pane.setBorder(null);
333
            pane.setLayout(null);
334
            //fix for nimbus laf
335
            pane.setOpaque(false);
336
            pane.setBackground(new Color(0, 0, 0, 0));
337
        }
338
    }
339
253
    private class RevisionRenderer extends JPanel implements ListCellRenderer {
340
    private class RevisionRenderer extends JPanel implements ListCellRenderer {
254
341
255
        private String id;
342
        private String id;
256
        private final Style selectedStyle;
257
        private final Style normalStyle;
258
        private final Style indentStyle;
259
        private final Style noindentStyle;
260
        private final Style issueHyperlinkStyle;
261
        private final Style linkStyle;
262
        private final Style authorStyle;
263
        private final Style hiliteStyle;
264
        private boolean lastSelection = false;
343
        private boolean lastSelection = false;
265
        private final JTextPane textPane;
344
        private final RevisionItemCell revisionCell = new RevisionItemCell();
266
        private final JButton expandButton;
345
        private final JButton expandButton;
267
        private String commitMessage = ""; //NOI18N
346
        private String commitMessage = ""; //NOI18N
268
        private boolean lastMessageExpanded;
347
        private boolean lastMessageExpanded;
Lines 272-317 Link Here
272
351
273
        public RevisionRenderer() {
352
        public RevisionRenderer() {
274
            selectionForeground = new JList().getSelectionForeground();
353
            selectionForeground = new JList().getSelectionForeground();
275
            textPane = new JTextPane();
276
            expandButton = new LinkButton(ICON_COLLAPSED);
354
            expandButton = new LinkButton(ICON_COLLAPSED);
277
            expandButton.setBorder(BorderFactory.createEmptyBorder());
355
            expandButton.setBorder(BorderFactory.createEmptyBorder());
278
356
279
            selectedStyle = textPane.addStyle("selected", null); //NOI18N
357
            this.setBorder(BorderFactory.createMatteBorder(3, 0, 0, 0, UIManager.getColor("List.background"))); //NOI18N
280
            StyleConstants.setForeground(selectedStyle, selectionForeground);
358
            this.setLayout(new BorderLayout(3, 0));
281
            StyleConstants.setBackground(selectedStyle, selectionBackground);
282
            normalStyle = textPane.addStyle("normal", null); //NOI18N
283
            StyleConstants.setForeground(normalStyle, UIManager.getColor("List.foreground")); //NOI18N
284
            indentStyle = textPane.addStyle("indent", null); //NOI18N
285
            StyleConstants.setLeftIndent(indentStyle, 50);
286
            noindentStyle = textPane.addStyle("noindent", null); //NOI18N
287
            StyleConstants.setLeftIndent(noindentStyle, 0);
288
359
289
            issueHyperlinkStyle = textPane.addStyle("issuehyperlink", normalStyle); //NOI18N
290
            StyleConstants.setForeground(issueHyperlinkStyle, Color.BLUE);
291
            StyleConstants.setUnderline(issueHyperlinkStyle, true);
292
293
            linkStyle = textPane.addStyle("link", normalStyle); //NOI18N
294
            StyleConstants.setForeground(linkStyle, Color.BLUE);
295
            StyleConstants.setBold(linkStyle, true);
296
297
            authorStyle = textPane.addStyle("author", normalStyle); //NOI18N
298
            StyleConstants.setForeground(authorStyle, Color.BLUE);
299
300
            hiliteStyle = textPane.addStyle("hilite", normalStyle); //NOI18N
301
            
302
            Color c = (Color) searchHiliteAttrs.getAttribute(StyleConstants.Background);
303
            if (c != null) StyleConstants.setBackground(hiliteStyle, c);
304
            c = (Color) searchHiliteAttrs.getAttribute(StyleConstants.Foreground);
305
            if (c != null) StyleConstants.setForeground(hiliteStyle, c);
306
307
            textPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
308
            setLayout(new BorderLayout(0, 0));
309
            setBorder(BorderFactory.createMatteBorder(3, 0, 0, 0, UIManager.getColor("List.background"))); //NOI18N
310
            
311
            add(expandButton, BorderLayout.WEST);
312
            expandButton.setMaximumSize(expandButton.getPreferredSize());
360
            expandButton.setMaximumSize(expandButton.getPreferredSize());
313
            expandButton.setMinimumSize(expandButton.getPreferredSize());
361
            expandButton.setMinimumSize(expandButton.getPreferredSize());
314
            add(textPane, BorderLayout.CENTER);
362
            this.add(expandButton, BorderLayout.WEST);
363
            this.add(revisionCell, BorderLayout.CENTER);
315
        }
364
        }
316
365
317
        @Override
366
        @Override
Lines 319-350 Link Here
319
            AbstractSummaryView.RevisionItem item = (AbstractSummaryView.RevisionItem) value;
368
            AbstractSummaryView.RevisionItem item = (AbstractSummaryView.RevisionItem) value;
320
            AbstractSummaryView.LogEntry entry = item.getUserData();
369
            AbstractSummaryView.LogEntry entry = item.getUserData();
321
370
322
            StyledDocument sd = textPane.getStyledDocument();
323
            Collection<SearchHighlight> highlights = summaryView.getMaster().getSearchHighlights();
371
            Collection<SearchHighlight> highlights = summaryView.getMaster().getSearchHighlights();
324
            if (sd.getLength() == 0 || selected != lastSelection || item.messageExpanded != lastMessageExpanded || item.revisionExpanded != lastRevisionExpanded
372
            if (revisionCell.getRevisionControl().getStyledDocument().getLength() == 0 || revisionCell.getDateControl().getStyledDocument().getLength() == 0 || revisionCell.getAuthorControl().getStyledDocument().getLength() == 0 || revisionCell.getCommitMessageControl().getStyledDocument().getLength() == 0 || selected != lastSelection || item.messageExpanded != lastMessageExpanded || item.revisionExpanded != lastRevisionExpanded
325
                    || !highlights.equals(lastHighlights)) {
373
                    || !highlights.equals(lastHighlights)) {
326
                lastSelection = selected;
374
                lastSelection = selected;
327
                lastMessageExpanded = item.messageExpanded;
375
                lastMessageExpanded = item.messageExpanded;
328
                lastRevisionExpanded = item.revisionExpanded;
376
                lastRevisionExpanded = item.revisionExpanded;
329
                lastHighlights = highlights;
377
                lastHighlights = highlights;
330
378
331
                Style style;
332
                Color backgroundColor;
379
                Color backgroundColor;
333
                Color foregroundColor;
334
380
335
                if (selected) {
381
                if (selected) {
336
                    foregroundColor = selectionForeground;
337
                    backgroundColor = selectionBackground;
382
                    backgroundColor = selectionBackground;
338
                    style = selectedStyle;
339
                } else {
383
                } else {
340
                    foregroundColor = UIManager.getColor("List.foreground"); //NOI18N
341
                    backgroundColor = UIManager.getColor("List.background"); //NOI18N
384
                    backgroundColor = UIManager.getColor("List.background"); //NOI18N
342
                    backgroundColor = entry.isLessInteresting() ? darkerUninteresting(backgroundColor) : darker(backgroundColor);
385
                    backgroundColor = entry.isLessInteresting() ? darkerUninteresting(backgroundColor) : darker(backgroundColor);
343
                    style = normalStyle;
344
                }
386
                }
345
                textPane.setOpaque(false);
387
                this.setBackground(backgroundColor);
346
                textPane.setBackground(new Color(0, 0, 0, 0));
388
                revisionCell.setBackground(backgroundColor);
347
                setBackground(backgroundColor);
389
348
                if (item.revisionExpanded) {
390
                if (item.revisionExpanded) {
349
                    expandButton.setIcon(ICON_EXPANDED);
391
                    expandButton.setIcon(ICON_EXPANDED);
350
                } else {
392
                } else {
Lines 357-522 Link Here
357
                }
399
                }
358
400
359
                try {
401
                try {
360
                    // clear document
402
                    addRevision(revisionCell.getRevisionControl(), item, selected, highlights);
361
                    sd.remove(0, sd.getLength());
403
                    addCommitMessage(revisionCell.getCommitMessageControl(), item, selected, highlights);
362
                    sd.setParagraphAttributes(0, sd.getLength(), noindentStyle, false);
404
                    addAuthor(revisionCell.getAuthorControl(), item, selected, highlights);
363
405
                    addDate(revisionCell.getDateControl(), item, selected, highlights);
364
                    // add revision
365
                    sd.insertString(0, item.getUserData().getRevision(), null);
366
                    sd.setCharacterAttributes(0, sd.getLength(), normalStyle, false);
367
                    if (!selected) {
368
                        for (AbstractSummaryView.LogEntry.RevisionHighlight highlight : item.getUserData().getRevisionHighlights()) {
369
                            Style s = textPane.addStyle(null, normalStyle);
370
                            StyleConstants.setForeground(s, highlight.getForeground());
371
                            StyleConstants.setBackground(s, highlight.getBackground());
372
                            sd.setCharacterAttributes(highlight.getStart(), highlight.getLength(), s, false);
373
                        }
374
                        for (SearchHighlight highlight : highlights) {
375
                            if (highlight.getKind() == SearchHighlight.Kind.REVISION) {
376
                                int doclen = sd.getLength();
377
                                String highlightMessage = highlight.getSearchText();
378
                                String revisionText = item.getUserData().getRevision().toLowerCase();
379
                                int idx = revisionText.indexOf(highlightMessage);
380
                                if (idx > -1) {
381
                                    sd.setCharacterAttributes(doclen - revisionText.length() + idx, highlightMessage.length(), hiliteStyle, false);
382
                                }
383
                            }
384
                        }
385
                    }
386
387
                    // add author
388
                    sd.insertString(sd.getLength(), FIELDS_SEPARATOR, style);
389
                    String author = entry.getAuthor();
390
                    VCSHyperlinkSupport.StyledDocumentHyperlink l = linkerSupport.getLinker(VCSHyperlinkSupport.AuthorLinker.class, id);
391
                    if(l == null) {
392
                        VCSKenaiAccessor.KenaiUser kenaiUser = getKenaiUser(author);
393
                        if (kenaiUser != null) {
394
                            l = new VCSHyperlinkSupport.AuthorLinker(kenaiUser, authorStyle, sd, author);
395
                            linkerSupport.add(l, id);
396
                        }
397
                    }
398
                    int pos = sd.getLength();
399
                    if(l != null) {
400
                        l.insertString(sd, selected ? style : null);
401
                    } else {
402
                        sd.insertString(sd.getLength(), author, style);
403
                    }
404
                    if (!selected) {
405
                        for (SearchHighlight highlight : highlights) {
406
                            if (highlight.getKind() == SearchHighlight.Kind.AUTHOR) {
407
                                int doclen = sd.getLength();
408
                                String highlightMessage = highlight.getSearchText();
409
                                String authorText = sd.getText(pos, doclen - pos).toLowerCase();
410
                                int idx = authorText.indexOf(highlightMessage);
411
                                if (idx > -1) {
412
                                    sd.setCharacterAttributes(doclen - authorText.length() + idx, highlightMessage.length(), hiliteStyle, false);
413
                                }
414
                            }
415
                        }
416
                    }
417
418
                    // add date
419
                    sd.insertString(sd.getLength(), FIELDS_SEPARATOR + entry.getDate(), null);
420
421
                    // add commit msg
422
                    boolean messageChanged = !entry.getMessage().equals(commitMessage);
423
                    commitMessage = entry.getMessage();
424
                    if (commitMessage.endsWith("\n")) commitMessage = commitMessage.substring(0, commitMessage.length() - 1); //NOI18N
425
                    sd.insertString(sd.getLength(), "\n", null); //NOI18N
426
                    int nlc, i;
427
                    for (i = 0, nlc = -1; i != -1 ; i = commitMessage.indexOf('\n', i + 1), nlc++);
428
                    if (nlc > 0 && !item.messageExpanded) {
429
                        commitMessage = commitMessage.substring(0, commitMessage.indexOf("\n")); //NOI18N
430
                    }
431
432
                    // compute issue hyperlinks
433
                    l = linkerSupport.getLinker(VCSHyperlinkSupport.IssueLinker.class, id);
434
                    if (messageChanged) {
435
                        lastWidth = -1;
436
                        if (l != null) {
437
                            // must reinitialize issue linker to paint the new message
438
                            linkerSupport.remove(l, id);
439
                            l = null;
440
                        }
441
                    }
442
                    if(l == null) {
443
                        for (VCSHyperlinkProvider hp : getHyperlinkProviders()) {
444
                            l = VCSHyperlinkSupport.IssueLinker.create(hp, issueHyperlinkStyle, summaryView.getRoot(), sd, commitMessage);
445
                            if(l != null) {
446
                                linkerSupport.add(l, id);
447
                                break; // get the first one
448
                            }
449
                        }
450
                    }
451
                    pos = sd.getLength();
452
                    if(l != null) {
453
                        l.insertString(sd, style);
454
                    } else {
455
                        sd.insertString(sd.getLength(), commitMessage, style);
456
                    }
457
458
                    // tooltip for message
459
                    MessageTooltip mtt = linkerSupport.getLinker(MessageTooltip.class, id);
460
                    if (messageChanged) {
461
                        linkerSupport.remove(mtt, id);
462
                        mtt = null;
463
                    }
464
                    if (mtt == null) {
465
                        linkerSupport.add(new MessageTooltip(entry.getMessage(), pos, sd.getLength()), id);
466
                    }
467
                    
468
                    // paint first line of commit message bold
469
                    int lineEnd = sd.getText(pos, sd.getLength() - pos).indexOf("\n");
470
                    if (lineEnd == -1) {
471
                        lineEnd = sd.getLength() - pos;
472
                    }
473
                    Style s = textPane.addStyle(null, style);
474
                    StyleConstants.setBold(s, true);
475
                    sd.setCharacterAttributes(pos, lineEnd, s, false);
476
                    int msglen = commitMessage.length();
477
                    int doclen = sd.getLength();
478
479
                    if (nlc > 0 && !item.messageExpanded) {
480
                        l = linkerSupport.getLinker(ExpandMsgHyperlink.class, id);
481
                        if (l == null) {
482
                            l = new ExpandMsgHyperlink(item, sd.getLength(), id);
483
                            linkerSupport.add(l, id);
484
                        }
485
                        l.insertString(sd, linkStyle);
486
                    }
487
                    
488
489
                    if (!selected) {
490
                        for (SearchHighlight highlight : highlights) {
491
                            if (highlight.getKind() == SearchHighlight.Kind.MESSAGE) {
492
                                String highlightMessage = highlight.getSearchText();
493
                                int idx = commitMessage.toLowerCase().indexOf(highlightMessage);
494
                                if (idx == -1) {
495
                                    if (nlc > 0 && !item.messageExpanded && entry.getMessage().toLowerCase().contains(highlightMessage)) {
496
                                        sd.setCharacterAttributes(doclen, sd.getLength(), hiliteStyle, false);
497
                                    }
498
                                } else {
499
                                    sd.setCharacterAttributes(doclen - msglen + idx, highlightMessage.length(), hiliteStyle, false);
500
                                }
501
                            }
502
                        }
503
                    }
504
505
                    if (selected) {
506
                        sd.setCharacterAttributes(0, Integer.MAX_VALUE, style, false);
507
                    }
508
                } catch (BadLocationException e) {
406
                } catch (BadLocationException e) {
509
                    ErrorManager.getDefault().notify(e);
407
                    ErrorManager.getDefault().notify(e);
510
                }
408
                }
511
            }
409
            }
512
            lastWidth = resizePane(textPane.getText(), list, lastWidth);
410
            lastWidth = resizePane(revisionCell.getCommitMessageControl().getText(), list, lastWidth);
513
411
514
            return this;
412
            return this;
515
        }
413
        }
516
        
414
517
        @SuppressWarnings("empty-statement")
415
        @SuppressWarnings("empty-statement")
518
        private int resizePane(String text, JList list, int lastWidth) {
416
        private int resizePane (String text, JList list, int lastWidth) {
519
            if(text == null) {
417
            if (text == null) {
520
                text = ""; //NOI18N
418
                text = ""; //NOI18N
521
            }
419
            }
522
            int width = summaryView.getMaster().getComponent().getWidth();
420
            int width = summaryView.getMaster().getComponent().getWidth();
Lines 525-549 Link Here
525
                FontMetrics fm = list.getFontMetrics(list.getFont());
423
                FontMetrics fm = list.getFontMetrics(list.getFont());
526
                int lines = 0;
424
                int lines = 0;
527
                for (String row : rows) {
425
                for (String row : rows) {
528
                    Rectangle2D rect = fm.getStringBounds(row, textPane.getGraphics());
426
                    Rectangle2D rect = fm.getStringBounds(row, revisionCell.getGraphics());
529
                    lines += (int) (rect.getWidth() / (width - 80) + 1);
427
                    lines += (int) (rect.getWidth() / (width - 80) + 1);
530
                }
428
                }
531
                int ph = fm.getHeight() * lines + 9;
429
                int ph = fm.getHeight() * (lines + 1) + 4;
532
                textPane.setPreferredSize(new Dimension(width - 50 - ICON_COLLAPSED.getIconWidth(), ph));
430
                revisionCell.setPreferredSize(new Dimension(width - 50 - ICON_COLLAPSED.getIconWidth(), ph));
533
                setPreferredSize(textPane.getPreferredSize());
431
                setPreferredSize(revisionCell.getPreferredSize());
534
            }
432
            }
535
            return width;
433
            return width;
536
        }
434
        }
435
436
        private void addRevision (JTextPane pane, RevisionItem item, boolean selected, Collection<SearchHighlight> highlights) throws BadLocationException {
437
            StyledDocument sd = pane.getStyledDocument();
438
            // clear document
439
            clearSD(pane, sd);
440
441
            Style selectedStyle = createSelectedStyle(pane);
442
            Style normalStyle = createNormalStyle(pane);
443
            Style hiliteStyle = createHiliteStyleStyle(pane, normalStyle, searchHiliteAttrs);
444
            Style style;
445
            if (selected) {
446
                style = selectedStyle;
447
            } else {
448
                style = normalStyle;
449
            }
450
451
452
            // add revision
453
            sd.insertString(0, item.getUserData().getRevision(), style);
454
            if (!selected) {
455
                for (AbstractSummaryView.LogEntry.RevisionHighlight highlight : item.getUserData().getRevisionHighlights()) {
456
                    Style s = pane.addStyle(null, normalStyle);
457
                    StyleConstants.setForeground(s, highlight.getForeground());
458
                    StyleConstants.setBackground(s, highlight.getBackground());
459
                    sd.setCharacterAttributes(highlight.getStart(), highlight.getLength(), s, false);
460
                }
461
                for (SearchHighlight highlight : highlights) {
462
                    if (highlight.getKind() == SearchHighlight.Kind.REVISION) {
463
                        int doclen = sd.getLength();
464
                        String highlightMessage = highlight.getSearchText();
465
                        String revisionText = item.getUserData().getRevision().toLowerCase();
466
                        int idx = revisionText.indexOf(highlightMessage);
467
                        if (idx > -1) {
468
                            sd.setCharacterAttributes(doclen - revisionText.length() + idx, highlightMessage.length(), hiliteStyle, false);
469
                        }
470
                    }
471
                }
472
            }
473
        }
474
475
        private void addAuthor (JTextPane pane, RevisionItem item, boolean selected, Collection<SearchHighlight> highlights) throws BadLocationException {
476
            LogEntry entry = item.getUserData();
477
            StyledDocument sd = pane.getStyledDocument();
478
            clearSD(pane, sd);
479
            Style selectedStyle = createSelectedStyle(pane);
480
            Style normalStyle = createNormalStyle(pane);
481
            Style style;
482
            if (selected) {
483
                style = selectedStyle;
484
            } else {
485
                style = normalStyle;
486
            }
487
            Style authorStyle = createAuthorStyle(pane, normalStyle);
488
            Style hiliteStyle = createHiliteStyleStyle(pane, normalStyle, searchHiliteAttrs);
489
            String author = entry.getAuthor();
490
            VCSHyperlinkSupport.StyledDocumentHyperlink l = linkerSupport.getLinker(VCSHyperlinkSupport.AuthorLinker.class, id);
491
            if (l == null) {
492
                VCSKenaiAccessor.KenaiUser kenaiUser = getKenaiUser(author);
493
                if (kenaiUser != null) {
494
                    l = new VCSHyperlinkSupport.AuthorLinker(kenaiUser, authorStyle, sd, author);
495
                    linkerSupport.add(l, id);
496
                }
497
            }
498
            int pos = sd.getLength();
499
            if (l != null) {
500
                l.insertString(sd, selected ? style : null);
501
            } else {
502
                sd.insertString(sd.getLength(), author, style);
503
            }
504
            if (!selected) {
505
                for (SearchHighlight highlight : highlights) {
506
                    if (highlight.getKind() == SearchHighlight.Kind.AUTHOR) {
507
                        int doclen = sd.getLength();
508
                        String highlightMessage = highlight.getSearchText();
509
                        String authorText = sd.getText(pos, doclen - pos).toLowerCase();
510
                        int idx = authorText.indexOf(highlightMessage);
511
                        if (idx > -1) {
512
                            sd.setCharacterAttributes(doclen - authorText.length() + idx, highlightMessage.length(), hiliteStyle, false);
513
                        }
514
                    }
515
                }
516
            }
517
        }
518
519
        private void addDate (JTextPane pane, RevisionItem item, boolean selected, Collection<SearchHighlight> highlights) throws BadLocationException {
520
521
            LogEntry entry = item.getUserData();
522
            StyledDocument sd = pane.getStyledDocument();
523
            // clear document
524
            clearSD(pane, sd);
525
526
            Style selectedStyle = createSelectedStyle(pane);
527
            Style normalStyle = createNormalStyle(pane);
528
            Style style;
529
            if (selected) {
530
                style = selectedStyle;
531
            } else {
532
                style = normalStyle;
533
            }
534
535
            // add date
536
            sd.insertString(sd.getLength(), entry.getDate(), style);
537
        }
538
539
        private void addCommitMessage (JTextPane pane, RevisionItem item, boolean selected, Collection<SearchHighlight> highlights) throws BadLocationException {
540
            LogEntry entry = item.getUserData();
541
            StyledDocument sd = pane.getStyledDocument();
542
            clearSD(pane, sd);
543
            Style selectedStyle = createSelectedStyle(pane);
544
            Style normalStyle = createNormalStyle(pane);
545
            Style linkStyle = createLinkStyle(pane, normalStyle);
546
            Style hiliteStyle = createHiliteStyleStyle(pane, normalStyle, searchHiliteAttrs);
547
            Style issueHyperlinkStyle = createIssueHyperlinkStyle(pane, normalStyle);
548
            Style style;
549
            if (selected) {
550
                style = selectedStyle;
551
            } else {
552
                style = normalStyle;
553
            }
554
            boolean messageChanged = !entry.getMessage().equals(commitMessage);
555
            commitMessage = entry.getMessage();
556
            if (commitMessage.endsWith("\n")) {
557
                commitMessage = commitMessage.substring(0, commitMessage.length() - 1); //NOI18N
558
            }
559
            int nlc;
560
            int i;
561
            for (i = 0, nlc = -1; i != -1; i = commitMessage.indexOf('\n', i + 1), nlc++);
562
            if (nlc > 0 && !item.messageExpanded) {
563
                commitMessage = commitMessage.substring(0, commitMessage.indexOf("\n")); //NOI18N
564
            }
565
            int pos = 0;
566
            IssueLinker l = linkerSupport.getLinker(VCSHyperlinkSupport.IssueLinker.class, id);
567
            if (messageChanged) {
568
                lastWidth = -1;
569
                if (l != null) {
570
                    // must reinitialize issue linker to paint the new message
571
                    linkerSupport.remove(l, id);
572
                    l = null;
573
                }
574
            }
575
            if (l == null) {
576
                for (VCSHyperlinkProvider hp : getHyperlinkProviders()) {
577
                    l = VCSHyperlinkSupport.IssueLinker.create(hp, issueHyperlinkStyle, summaryView.getRoot(), sd, commitMessage);
578
                    if (l != null) {
579
                        linkerSupport.add(l, id);
580
                        break; // get the first one
581
                    }
582
                }
583
            }
584
            if (l != null) {
585
                l.insertString(sd, style);
586
            } else {
587
                sd.insertString(sd.getLength(), commitMessage, style);
588
            }
589
            MessageTooltip mtt = linkerSupport.getLinker(MessageTooltip.class, id);
590
            if (messageChanged) {
591
                linkerSupport.remove(mtt, id);
592
                mtt = null;
593
            }
594
            if (mtt == null) {
595
                linkerSupport.add(new MessageTooltip(entry.getMessage(), pos, sd.getLength()), id);
596
            }
597
            int lineEnd = sd.getText(pos, sd.getLength() - pos).indexOf("\n");
598
            if (lineEnd == -1) {
599
                lineEnd = sd.getLength() - pos;
600
            }
601
            Style s = pane.addStyle(null, style);
602
            StyleConstants.setBold(s, true);
603
            sd.setCharacterAttributes(pos, lineEnd, s, false);
604
            int msglen = commitMessage.length();
605
            int doclen = sd.getLength();
606
            if (nlc > 0 && !item.messageExpanded) {
607
                ExpandMsgHyperlink el = linkerSupport.getLinker(ExpandMsgHyperlink.class, id);
608
                if (el == null) {
609
                    el = new ExpandMsgHyperlink(item, sd.getLength(), id);
610
                    linkerSupport.add(el, id);
611
                }
612
                el.insertString(sd, linkStyle);
613
            }
614
            if (!selected) {
615
                for (SearchHighlight highlight : highlights) {
616
                    if (highlight.getKind() == SearchHighlight.Kind.MESSAGE) {
617
                        String highlightMessage = highlight.getSearchText();
618
                        int idx = commitMessage.toLowerCase().indexOf(highlightMessage);
619
                        if (idx == -1) {
620
                            if (nlc > 0 && !item.messageExpanded && entry.getMessage().toLowerCase().contains(highlightMessage)) {
621
                                sd.setCharacterAttributes(doclen, sd.getLength(), hiliteStyle, false);
622
                            }
623
                        } else {
624
                            sd.setCharacterAttributes(doclen - msglen + idx, highlightMessage.length(), hiliteStyle, false);
625
                        }
626
                    }
627
                }
628
            }
629
            if (selected) {
630
                sd.setCharacterAttributes(0, Integer.MAX_VALUE, style, false);
631
            }
632
        }
633
634
        private Style createNormalStyle (JTextPane textPane) {
635
            Style normalStyle = textPane.addStyle("normal", null); //NOI18N
636
            StyleConstants.setForeground(normalStyle, UIManager.getColor("List.foreground")); //NOI18N
637
            return normalStyle;
638
        }
639
640
        private Style createIssueHyperlinkStyle (JTextPane textPane, Style normalStyle) {
641
            Style issueHyperlinkStyle = textPane.addStyle("issuehyperlink", normalStyle); //NOI18N
642
            StyleConstants.setForeground(issueHyperlinkStyle, Color.BLUE);
643
            StyleConstants.setUnderline(issueHyperlinkStyle, true);
644
            return issueHyperlinkStyle;
645
        }
646
647
        private Style createAuthorStyle (JTextPane textPane, Style normalStyle) {
648
            Style authorStyle = textPane.addStyle("author", normalStyle); //NOI18N
649
            StyleConstants.setForeground(authorStyle, Color.BLUE);
650
            return authorStyle;
651
        }
652
653
        private Style createLinkStyle (JTextPane textPane, Style normalStyle) {
654
            Style linkStyle = textPane.addStyle("link", normalStyle); //NOI18N
655
            StyleConstants.setForeground(linkStyle, Color.BLUE);
656
            StyleConstants.setBold(linkStyle, true);
657
            return linkStyle;
658
        }
659
660
        private Style createNoindentStyle (JTextPane textPane) {
661
            Style noindentStyle = textPane.addStyle("noindent", null); //NOI18N
662
            StyleConstants.setLeftIndent(noindentStyle, 0);
663
            return noindentStyle;
664
        }
665
666
        private Style createSelectedStyle (JTextPane textPane) {
667
            Style selectedStyle = textPane.addStyle("selected", null); //NOI18N
668
            StyleConstants.setForeground(selectedStyle, selectionForeground);
669
            StyleConstants.setBackground(selectedStyle, selectionBackground);
670
            return selectedStyle;
671
        }
672
673
        private Style createHiliteStyleStyle (JTextPane textPane, Style normalStyle, AttributeSet searchHiliteAttrs) {
674
            Style hiliteStyle = textPane.addStyle("hilite", normalStyle); //NOI18N
675
676
            Color c = (Color) searchHiliteAttrs.getAttribute(StyleConstants.Background);
677
            if (c != null) {
678
                StyleConstants.setBackground(hiliteStyle, c);
679
            }
680
            c = (Color) searchHiliteAttrs.getAttribute(StyleConstants.Foreground);
681
            if (c != null) {
682
                StyleConstants.setForeground(hiliteStyle, c);
683
            }
684
685
            return hiliteStyle;
686
        }
537
        
687
        
538
        @Override
688
        @Override
539
        public void paint(Graphics g) {
689
        public void paint(Graphics g) {
540
            super.paint(g);
690
            super.paint(g);
541
            linkerSupport.computeBounds(textPane, id);
691
            linkerSupport.computeBounds(revisionCell.getCommitMessageControl(), id);
692
542
            ExpandLink link = linkerSupport.getLinker(ExpandLink.class, id);
693
            ExpandLink link = linkerSupport.getLinker(ExpandLink.class, id);
543
            if (link != null) {
694
            if (link != null) {
544
                link.computeBounds(expandButton);
695
                link.computeBounds(expandButton);
545
            }
696
            }
546
        }
697
        }
698
699
        private void clearSD (JTextPane pane, StyledDocument sd) {
700
            try {
701
                Style noindentStyle = createNoindentStyle(pane);
702
703
                sd.remove(0, sd.getLength());
704
                sd.setParagraphAttributes(0, sd.getLength(), noindentStyle, false);
705
            } catch (BadLocationException ex) {
706
                Exceptions.printStackTrace(ex);
707
            }
708
        }
547
    }
709
    }
548
    
710
    
549
    private static class MessageTooltip extends VCSHyperlinkSupport.Hyperlink {
711
    private static class MessageTooltip extends VCSHyperlinkSupport.Hyperlink {
Lines 1049-1054 Link Here
1049
                Rectangle endr = mtv.getBounds();
1211
                Rectangle endr = mtv.getBounds();
1050
1212
1051
                bounds = new Rectangle(tpBounds.x + startr.x, startr.y, endr.x - startr.x, startr.height);
1213
                bounds = new Rectangle(tpBounds.x + startr.x, startr.y, endr.x - startr.x, startr.height);
1214
                // NOTE the textPane is positioned within a parent panel so the relative bound has to be modified too
1215
                // FIXME this is an ugly hack because the public API of org.netbeans.modules.versioning.util.VCSHyperlinkSupport should stay stable
1216
                // SOLUTION: add parameter 'rootPane' to the computeBounds method and translate from bottom to top of the component hiearchy
1217
                bounds.translate(textPane.getX(), textPane.getY());
1218
                bounds.translate(textPane.getParent().getX(), textPane.getParent().getY());
1052
            } catch (BadLocationException ex) {
1219
            } catch (BadLocationException ex) {
1053
                throw new RuntimeException(ex);
1220
                throw new RuntimeException(ex);
1054
            }
1221
            }
(-)a/versioning.util/src/org/netbeans/modules/versioning/util/VCSHyperlinkSupport.java (-1 / +4 lines)
Lines 240-245 Link Here
240
                    Rectangle startr = tui.modelToView(textPane, docstart[i], Position.Bias.Forward).getBounds();
240
                    Rectangle startr = tui.modelToView(textPane, docstart[i], Position.Bias.Forward).getBounds();
241
                    Rectangle endr = tui.modelToView(textPane, docend[i], Position.Bias.Backward).getBounds();
241
                    Rectangle endr = tui.modelToView(textPane, docend[i], Position.Bias.Backward).getBounds();
242
                    this.bounds[i] = new Rectangle(tpBounds.x + startr.x, startr.y, endr.x - startr.x, startr.height);
242
                    this.bounds[i] = new Rectangle(tpBounds.x + startr.x, startr.y, endr.x - startr.x, startr.height);
243
                    //NOTE the textPane is positioned within a parent panel so the origin has to be modified too
244
                    this.bounds[i].translate(textPane.getX(), textPane.getY());
243
                } catch (BadLocationException ex) { }
245
                } catch (BadLocationException ex) { }
244
            }
246
            }
245
        }
247
        }
Lines 316-322 Link Here
316
                }
318
                }
317
                this.bounds = new Rectangle(tpBounds.x + startr.x, startr.y, endr.x - startr.x, startr.height);
319
                this.bounds = new Rectangle(tpBounds.x + startr.x, startr.y, endr.x - startr.x, startr.height);
318
            } catch (BadLocationException ex) {
320
            } catch (BadLocationException ex) {
319
                Exceptions.printStackTrace(ex);
321
                  // FIXME exception occurs when teamserver is used
322
                  //Exceptions.printStackTrace(ex);
320
            }
323
            }
321
        }
324
        }
322
325

Return to bug 218850