1 19 20 package org.netbeans.modules.versioning.system.cvss.ui.actions.diff; 21 22 import org.netbeans.api.diff.Diff; 23 import org.netbeans.api.diff.DiffView; 24 import org.netbeans.api.diff.StreamSource; 25 import org.netbeans.modules.versioning.system.cvss.*; 26 import org.netbeans.modules.versioning.system.cvss.ui.actions.update.UpdateExecutor; 27 import org.netbeans.modules.versioning.system.cvss.ui.actions.commit.CommitAction; 28 import org.netbeans.modules.versioning.system.cvss.util.Utils; 29 import org.netbeans.modules.versioning.system.cvss.util.Context; 30 import org.netbeans.modules.versioning.util.VersioningListener; 31 import org.netbeans.modules.versioning.util.VersioningEvent; 32 import org.netbeans.modules.versioning.util.DelegatingUndoRedo; 33 import org.netbeans.lib.cvsclient.command.update.UpdateCommand; 34 import org.netbeans.lib.cvsclient.command.GlobalOptions; 35 import org.openide.util.NbBundle; 36 import org.openide.util.RequestProcessor; 37 import org.openide.util.lookup.Lookups; 38 import org.openide.ErrorManager; 39 import org.openide.LifecycleManager; 40 import org.openide.awt.UndoRedo; 41 import org.openide.nodes.Node; 42 import org.openide.nodes.AbstractNode; 43 import org.openide.nodes.Children; 44 import org.openide.windows.TopComponent; 45 import org.openide.windows.WindowManager; 46 import org.openide.filesystems.FileObject; 47 import org.openide.filesystems.FileUtil; 48 49 import javax.swing.*; 50 import javax.swing.plaf.basic.BasicComboBoxRenderer ; 51 import javax.swing.border.CompoundBorder ; 52 import java.io.IOException ; 53 import java.io.File ; 54 import java.util.*; 55 import java.util.List ; 56 import java.awt.event.*; 57 import java.awt.*; 58 import java.awt.image.BufferedImage ; 59 60 65 public class DiffMainPanel extends javax.swing.JPanel implements ActionListener, VersioningListener, DiffSetupSource { 66 67 71 private Setup[] setups; 72 73 private final DelegatingUndoRedo delegatingUndoRedo = new DelegatingUndoRedo(); 74 75 78 private final Context context; 79 80 private int displayStatuses; 81 82 85 private final String contextName; 86 87 private int currentType; 88 private int currentDifferenceIndex; 89 private int currentIndex = -1; 90 91 private RequestProcessor.Task prepareTask; 92 private DiffPrepareTask dpt; 93 94 private AbstractAction nextAction; 95 private AbstractAction prevAction; 96 97 private static final RequestProcessor rp = new RequestProcessor("CVS-VersioningView", 1); 100 103 private RequestProcessor.Task refreshTask; 104 105 private ExecutorGroup group; 106 private volatile boolean executed; 107 108 private JComponent diffView; 109 110 113 public DiffMainPanel(Context context, int initialType, String contextName, ExecutorGroup group) { 114 this.context = context; 115 this.contextName = contextName; 116 this.group = group; 117 currentType = initialType; 118 initComponents(); 119 setupComponents(); 120 refreshSetups(); 121 refreshComponents(); 122 refreshTask = rp.create(new RefreshViewTask()); 123 } 124 125 129 public DiffMainPanel(File file, String rev1, String rev2) { 130 context = null; 131 contextName = file.getName(); 132 initComponents(); 133 setupComponents(); 134 localToggle.setVisible(false); 135 remoteToggle.setVisible(false); 136 allToggle.setVisible(false); 137 navigationCombo.setVisible(false); 138 refreshButton.setVisible(false); 139 updateButton.setVisible(false); 140 commitButton.setVisible(false); 141 142 setups = new Setup[] { 144 new Setup(file, rev1, rev2) 145 }; 146 setDiffIndex(0, 0); 147 dpt = new DiffPrepareTask(setups); 148 prepareTask = RequestProcessor.getDefault().post(dpt); 149 } 150 151 UndoRedo getUndoRedo() { 152 return delegatingUndoRedo; 153 } 154 155 158 void componentClosed() { 159 setups = null; 160 if (prepareTask != null) { 161 prepareTask.cancel(); 162 } 163 } 164 165 public synchronized void setGroup(ExecutorGroup group) { 166 this.group = group; 167 if (executed) { 168 group.executed(); 169 } 170 } 171 172 void requestActive() { 173 if (diffView != null) { 174 diffView.requestFocusInWindow(); 175 } 176 } 177 178 private static class ColoredComboRenderer extends BasicComboBoxRenderer { 179 180 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 181 if (isSelected) { 182 value = ((Setup) value).getBaseFile().getName(); 183 } 184 return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 185 } 186 } 187 188 private void setupComponents() { 189 controlsToolbar.putClientProperty("JToolBar.isRollover", Boolean.TRUE); controlsToolbar.setLayout(new DiffMainPanel.ToolbarLayout()); 191 192 navigationCombo.addActionListener(this); 193 navigationCombo.setRenderer(new ColoredComboRenderer()); 194 refreshButton.addActionListener(this); 195 updateButton.addActionListener(this); 196 commitButton.addActionListener(this); 197 localToggle.addActionListener(this); 198 remoteToggle.addActionListener(this); 199 allToggle.addActionListener(this); 200 201 refreshButton.setToolTipText(NbBundle.getMessage(DiffMainPanel.class, "MSG_RefreshDiff_Tooltip")); 202 updateButton.setToolTipText(NbBundle.getMessage(DiffMainPanel.class, "MSG_UpdateDiff_Tooltip", contextName)); 203 commitButton.setToolTipText(NbBundle.getMessage(DiffMainPanel.class, "MSG_CommitDiff_Tooltip", contextName)); 204 ButtonGroup grp = new ButtonGroup(); 205 grp.add(localToggle); 206 grp.add(remoteToggle); 207 grp.add(allToggle); 208 if (currentType == Setup.DIFFTYPE_LOCAL) localToggle.setSelected(true); 209 else if (currentType == Setup.DIFFTYPE_REMOTE) remoteToggle.setSelected(true); 210 else if (currentType == Setup.DIFFTYPE_ALL) allToggle.setSelected(true); 211 212 nextAction = new AbstractAction(null, new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/versioning/system/cvss/resources/icons/diff-next.png"))) { { 214 putValue(Action.SHORT_DESCRIPTION, java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle"). 215 getString("CTL_DiffPanel_Next_Tooltip")); 216 } 217 public void actionPerformed(ActionEvent e) { 218 onNextButton(); 219 } 220 }; 221 prevAction = new AbstractAction(null, new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/versioning/system/cvss/resources/icons/diff-prev.png"))) { { 223 putValue(Action.SHORT_DESCRIPTION, java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle"). 224 getString("CTL_DiffPanel_Prev_Tooltip")); 225 } 226 public void actionPerformed(ActionEvent e) { 227 onPrevButton(); 228 } 229 }; 230 nextButton.setAction(nextAction); 231 prevButton.setAction(prevAction); 232 } 233 234 private void refreshComponents() { 235 DiffView view = setups != null ? setups[currentIndex].getView() : null; 236 if (view != null) { 237 nextAction.setEnabled(currentIndex < setups.length - 1 || currentDifferenceIndex < view.getDifferenceCount() - 1); 238 } else { 239 nextAction.setEnabled(false); 240 } 241 prevAction.setEnabled(currentIndex > 0 || currentDifferenceIndex > 0); 242 } 243 244 public void addNotify() { 245 super.addNotify(); 246 if (refreshTask != null) { 247 CvsVersioningSystem.getInstance().getStatusCache().addVersioningListener(this); 248 } 249 JComponent parent = (JComponent) getParent(); 250 parent.getActionMap().put("jumpNext", nextAction); parent.getActionMap().put("jumpPrev", prevAction); } 253 254 public void removeNotify() { 255 CvsVersioningSystem.getInstance().getStatusCache().removeVersioningListener(this); 256 super.removeNotify(); 257 } 258 259 public void versioningEvent(VersioningEvent event) { 261 if (event.getId() == FileStatusCache.EVENT_FILE_STATUS_CHANGED) { 262 if (!affectsView(event)) return; 263 if (CvsVersioningSystem.getInstance().getParameter(CvsVersioningSystem.PARAM_BATCH_REFRESH_RUNNING) != null) { 264 refreshTask.schedule(1000); 265 } else { 266 refreshTask.schedule(200); 267 } 268 } else if (event.getId() == CvsVersioningSystem.EVENT_PARAM_CHANGED) { 269 if (event.getParams()[0].equals(CvsVersioningSystem.PARAM_BATCH_REFRESH_RUNNING)) { 270 if (CvsVersioningSystem.getInstance().getParameter(CvsVersioningSystem.PARAM_BATCH_REFRESH_RUNNING) == null) { 271 refreshTask.schedule(0); 272 } 273 } 274 } 275 } 276 277 private boolean affectsView(VersioningEvent event) { 278 File file = (File ) event.getParams()[0]; 279 FileInformation oldInfo = (FileInformation) event.getParams()[1]; 280 FileInformation newInfo = (FileInformation) event.getParams()[2]; 281 if (oldInfo == null) { 282 if ((newInfo.getStatus() & displayStatuses) == 0) return false; 283 } else { 284 if ((oldInfo.getStatus() & displayStatuses) + (newInfo.getStatus() & displayStatuses) == 0) return false; 285 } 286 return context.contains(file); 287 } 288 289 private void setDiffIndex(int idx, int location) { 290 currentIndex = idx; 291 DiffView view = setups[currentIndex].getView(); 292 293 TopComponent tc = (TopComponent) getClientProperty(TopComponent.class); 295 if (tc != null) { 296 Node node = Node.EMPTY; 297 File baseFile = setups[currentIndex].getBaseFile(); 298 if (baseFile != null) { 299 FileObject fo = FileUtil.toFileObject(baseFile); 300 if (fo != null) { 301 node = new AbstractNode(Children.LEAF, Lookups.singleton(fo)); 302 } 303 } 304 tc.setActivatedNodes(new Node[] {node}); 305 } 306 307 boolean focus = false; 308 removeDiffComponent(); 309 if (view != null) { 310 if (location == -1) { 311 location = view.getDifferenceCount() - 1; 312 } 313 if (location >=0 && location < view.getDifferenceCount()) { 314 view.setCurrentDifference(location); 315 } 316 diffView = (JComponent) view.getComponent(); 317 diffView.getActionMap().put("jumpNext", nextAction); diffView.getActionMap().put("jumpPrev", prevAction); Component toc = WindowManager.getDefault().getRegistry().getActivated(); 320 if (SwingUtilities.isDescendingFrom(this, toc)) { 321 focus = true; 322 } 323 } else { 324 diffView = new SourcesUnavailableComponent(NbBundle.getMessage(DiffMainPanel.class, "MSG_DiffPanel_NoContent")); 325 } 326 add(diffView); 327 delegatingUndoRedo.setDiffView(diffView); 328 329 currentDifferenceIndex = location; 330 if (navigationCombo.isVisible()) { 331 navigationCombo.setSelectedIndex(currentIndex); 332 } 333 refreshComponents(); 334 revalidate(); 335 repaint(); 336 if (focus) { 337 diffView.requestFocusInWindow(); 338 } 339 } 340 341 private void removeDiffComponent() { 342 if (diffView != null) { 343 remove(diffView); 344 diffView = null; 345 } 346 } 347 348 public void actionPerformed(ActionEvent e) { 349 Object source = e.getSource(); 350 if (source == navigationCombo) onNavigationCombo(); 351 else if (source == refreshButton) onRefreshButton(); 352 else if (source == updateButton) onUpdateButton(); 353 else if (source == commitButton) onCommitButton(); 354 else if (source == localToggle || source == remoteToggle || source == allToggle) onDiffTypeChanged(); 355 } 356 357 private void onRefreshButton() { 358 LifecycleManager.getDefault().saveAll(); 359 refreshSetups(); 360 executeUpdateCommand(true); 361 } 362 363 private void onUpdateButton() { 364 LifecycleManager.getDefault().saveAll(); 365 executeUpdateCommand(false); 366 } 367 368 private void onCommitButton() { 369 LifecycleManager.getDefault().saveAll(); 370 CommitAction.invokeCommit(contextName, context, null); 371 } 372 373 private void executeUpdateCommand(boolean doNoChanges) { 375 if (context == null || context.getRootFiles().length == 0) return; 376 UpdateCommand cmd = new UpdateCommand(); 377 String msg; 378 if (doNoChanges) { 379 msg = NbBundle.getMessage(DiffMainPanel.class, "BK0001"); 380 } else { 381 msg = NbBundle.getMessage(DiffMainPanel.class, "BK0002"); 382 } 383 cmd.setDisplayName(msg); 384 GlobalOptions options = CvsVersioningSystem.createGlobalOptions(); 385 if (context.getExclusions().size() > 0) { 386 options.setExclusions((File []) context.getExclusions().toArray(new File [context.getExclusions().size()])); 387 } 388 cmd.setFiles(context.getRootFiles()); 389 cmd.setBuildDirectories(true); 390 cmd.setPruneDirectories(true); 391 options.setDoNoChanges(doNoChanges); 392 393 ExecutorGroup group = new ExecutorGroup(msg); 394 group.addExecutors(UpdateExecutor.splitCommand(cmd, CvsVersioningSystem.getInstance(), options, contextName)); 395 group.execute(); 396 } 397 398 399 private void onNextButton() { 400 if (navigationCombo.isVisible()) { 401 currentIndex = navigationCombo.getSelectedIndex(); 402 } 403 404 DiffView view = setups[currentIndex].getView(); 405 if (view != null) { 406 int visibleDiffernce = view.getCurrentDifference(); 407 if (visibleDiffernce < view.getDifferenceCount() - 1) { 408 currentDifferenceIndex = Math.max(currentDifferenceIndex, visibleDiffernce); 409 } 410 if (++currentDifferenceIndex >= view.getDifferenceCount()) { 411 if (++currentIndex >= setups.length) { 412 currentIndex--; 413 } else { 414 setDiffIndex(currentIndex, 0); 415 } 416 } else { 417 view.setCurrentDifference(currentDifferenceIndex); 418 } 419 } else { 420 if (++currentIndex >= setups.length) currentIndex = 0; 421 setDiffIndex(currentIndex, 0); 422 } 423 refreshComponents(); 424 } 425 426 private void onPrevButton() { 427 DiffView view = setups[currentIndex].getView(); 428 if (view != null) { 429 if (--currentDifferenceIndex < 0) { 430 if (--currentIndex < 0) { 431 currentIndex++; 432 } else { 433 setDiffIndex(currentIndex, -1); 434 } 435 } else { 436 view.setCurrentDifference(currentDifferenceIndex); 437 } 438 } else { 439 if (--currentIndex < 0) currentIndex = setups.length - 1; 440 setDiffIndex(currentIndex, -1); 441 } 442 refreshComponents(); 443 } 444 445 private void onNavigationCombo() { 446 int idx = navigationCombo.getSelectedIndex(); 447 if (idx != currentIndex) setDiffIndex(idx, 0); 448 } 449 450 453 public Collection getSetups() { 454 if (setups == null) { 455 return Collections.EMPTY_SET; 456 } else { 457 return Arrays.asList(setups); 458 } 459 } 460 461 public String getSetupDisplayName() { 462 return contextName; 463 } 464 465 466 private void refreshSetups() { 467 if (dpt != null) { 468 prepareTask.cancel(); 469 } 470 471 File [] files; 472 switch (currentType) { 473 case Setup.DIFFTYPE_LOCAL: 474 displayStatuses = FileInformation.STATUS_LOCAL_CHANGE; 475 break; 476 case Setup.DIFFTYPE_REMOTE: 477 displayStatuses = FileInformation.STATUS_REMOTE_CHANGE; 478 break; 479 case Setup.DIFFTYPE_ALL: 480 displayStatuses = FileInformation.STATUS_LOCAL_CHANGE | FileInformation.STATUS_REMOTE_CHANGE; 481 break; 482 default: 483 throw new IllegalStateException ("Unknown DIFF type:" + currentType); } 485 files = DiffExecutor.getModifiedFiles(context, displayStatuses); 486 487 Setup [] newSetups = new Setup[files.length]; 488 for (int i = 0; i < newSetups.length; i++) { 489 File file = files[i]; 490 newSetups[i] = new Setup(file, currentType); 491 } 492 Arrays.sort(newSetups, new SetupsComparator()); 493 494 setups = newSetups; 495 navigationCombo.setModel(new DefaultComboBoxModel(setups)); 496 497 if (setups.length == 0) { 498 String noContentLabel; 499 switch (currentType) { 500 case Setup.DIFFTYPE_LOCAL: 501 noContentLabel = NbBundle.getMessage(DiffMainPanel.class, "MSG_DiffPanel_NoLocalChanges"); 502 break; 503 case Setup.DIFFTYPE_REMOTE: 504 noContentLabel = NbBundle.getMessage(DiffMainPanel.class, "MSG_DiffPanel_NoRemoteChanges"); 505 break; 506 case Setup.DIFFTYPE_ALL: 507 noContentLabel = NbBundle.getMessage(DiffMainPanel.class, "MSG_DiffPanel_NoAllChanges"); 508 break; 509 default: 510 throw new IllegalStateException ("Unknown DIFF type:" + currentType); } 512 setups = null; 513 navigationCombo.setModel(new DefaultComboBoxModel(new Object [] { noContentLabel })); 514 navigationCombo.setEnabled(false); 515 navigationCombo.setPreferredSize(null); 516 Dimension dim = navigationCombo.getPreferredSize(); 517 navigationCombo.setPreferredSize(new Dimension(dim.width + 1, dim.height)); 518 removeDiffComponent(); 519 diffView = new SourcesUnavailableComponent(noContentLabel); 520 add(diffView); 521 nextAction.setEnabled(false); 522 prevAction.setEnabled(false); 523 revalidate(); 524 repaint(); 525 executed(); 526 } else { 527 navigationCombo.setEnabled(true); 528 navigationCombo.setPreferredSize(null); 529 Dimension dim = navigationCombo.getPreferredSize(); 530 navigationCombo.setPreferredSize(new Dimension(dim.width + 1, dim.height)); 531 setDiffIndex(0, 0); 532 dpt = new DiffPrepareTask(setups); 533 prepareTask = RequestProcessor.getDefault().post(dpt); 534 } 535 } 536 537 private void onDiffTypeChanged() { 538 if (localToggle.isSelected()) { 539 if (currentType == Setup.DIFFTYPE_LOCAL) return; 540 currentType = Setup.DIFFTYPE_LOCAL; 541 } else if (remoteToggle.isSelected()) { 542 if (currentType == Setup.DIFFTYPE_REMOTE) return; 543 currentType = Setup.DIFFTYPE_REMOTE; 544 } else if (allToggle.isSelected()) { 545 if (currentType == Setup.DIFFTYPE_ALL) return; 546 currentType = Setup.DIFFTYPE_ALL; 547 } 548 refreshSetups(); 549 } 550 551 556 private void initComponents() { 558 controlsToolbar = new javax.swing.JToolBar (); 559 allToggle = new javax.swing.JToggleButton (); 560 localToggle = new javax.swing.JToggleButton (); 561 remoteToggle = new javax.swing.JToggleButton (); 562 navigationCombo = new javax.swing.JComboBox (); 563 nextButton = new javax.swing.JButton (); 564 prevButton = new javax.swing.JButton (); 565 jPanel1 = new javax.swing.JPanel (); 566 refreshButton = new javax.swing.JButton (); 567 updateButton = new javax.swing.JButton (); 568 commitButton = new javax.swing.JButton (); 569 570 setLayout(new java.awt.BorderLayout ()); 571 572 controlsToolbar.setFloatable(false); 573 allToggle.setText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_All")); 574 allToggle.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_All_Tooltip")); 575 controlsToolbar.add(allToggle); 576 577 localToggle.setText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_Local")); 578 localToggle.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_Local_Tooltip")); 579 controlsToolbar.add(localToggle); 580 581 remoteToggle.setText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_Remote")); 582 remoteToggle.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_Remote_Tooltip")); 583 controlsToolbar.add(remoteToggle); 584 585 controlsToolbar.add(navigationCombo); 586 587 nextButton.setIcon(new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/versioning/system/cvss/resources/icons/diff-next.png"))); 588 nextButton.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_Next_Tooltip")); 589 nextButton.setEnabled(false); 590 controlsToolbar.add(nextButton); 591 592 prevButton.setIcon(new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/versioning/system/cvss/resources/icons/diff-prev.png"))); 593 prevButton.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_Prev_Tooltip")); 594 prevButton.setEnabled(false); 595 controlsToolbar.add(prevButton); 596 597 jPanel1.setMaximumSize(new java.awt.Dimension (15, 1)); 598 jPanel1.setPreferredSize(new java.awt.Dimension (15, 1)); 599 controlsToolbar.add(jPanel1); 600 601 refreshButton.setIcon(new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/versioning/system/cvss/resources/icons/refresh.png"))); 602 refreshButton.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_Prev_Tooltip")); 603 controlsToolbar.add(refreshButton); 604 605 updateButton.setIcon(new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/versioning/system/cvss/resources/icons/update.png"))); 606 updateButton.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_Prev_Tooltip")); 607 controlsToolbar.add(updateButton); 608 609 commitButton.setIcon(new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/versioning/system/cvss/resources/icons/commit.png"))); 610 commitButton.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/versioning/system/cvss/ui/actions/diff/Bundle").getString("CTL_DiffPanel_Prev_Tooltip")); 611 controlsToolbar.add(commitButton); 612 613 add(controlsToolbar, java.awt.BorderLayout.NORTH); 614 615 } 616 618 private javax.swing.JToggleButton allToggle; 620 private javax.swing.JButton commitButton; 621 private javax.swing.JToolBar controlsToolbar; 622 private javax.swing.JPanel jPanel1; 623 private javax.swing.JToggleButton localToggle; 624 private javax.swing.JComboBox navigationCombo; 625 private javax.swing.JButton nextButton; 626 private javax.swing.JButton prevButton; 627 private javax.swing.JButton refreshButton; 628 private javax.swing.JToggleButton remoteToggle; 629 private javax.swing.JButton updateButton; 630 632 633 private class DiffPrepareTask implements Runnable { 634 635 private final Setup[] prepareSetups; 636 637 public DiffPrepareTask(Setup [] prepareSetups) { 638 this.prepareSetups = prepareSetups; 639 } 640 641 public void run() { 642 final Diff diff = Diff.getDefault(); 643 try { 644 for (int i = 0; i < prepareSetups.length; i++) { 645 if (prepareSetups != setups) return; 646 try { 647 prepareSetups[i].initSources(group); final int fi = i; 649 StreamSource ss1 = prepareSetups[fi].getFirstSource(); 650 StreamSource ss2 = prepareSetups[fi].getSecondSource(); 651 final DiffView view = diff.createDiff(ss1, ss2); 653 SwingUtilities.invokeLater(new Runnable () { 654 public void run() { 655 prepareSetups[fi].setView(view); 656 if (prepareSetups != setups) { 657 return; 658 } 659 if (currentIndex == fi) { 660 setDiffIndex(fi, 0); 661 } 662 } 663 }); 664 } catch (IOException e) { 665 ErrorManager.getDefault().notify(e); 666 } 667 } 668 } finally { 669 executed(); 670 } 671 } 672 } 673 674 private synchronized void executed() { 675 if (group != null) { 676 group.executed(); 677 } else { 678 executed = true; 680 } 681 } 682 683 private static class SourcesUnavailableComponent extends JComponent { 684 685 public SourcesUnavailableComponent(String message) { 686 JLabel label = new JLabel(message); 687 setLayout(new BorderLayout()); 688 label.setHorizontalAlignment(JLabel.CENTER); 689 add(label, BorderLayout.CENTER); 690 } 691 } 692 693 703 private class ToolbarLayout implements LayoutManager { 704 705 706 private int TOOLBAR_HEIGHT_ADJUSTMENT = 10; 707 708 private int TOOLBAR_SEPARATOR_MIN_WIDTH = 12; 709 710 711 private int toolbarHeight = -1; 712 713 714 private Dimension parentSize; 715 716 private Set adjusted = new HashSet(); 717 718 public void removeLayoutComponent(Component comp) { 719 } 720 721 public void layoutContainer(Container parent) { 722 Rectangle [] sizes = layout(parent); 723 for (int i = 0; i < sizes.length; i++) { 724 JComponent comp = (JComponent) parent.getComponent(i); 725 if (comp.isVisible()) { 726 comp.setBounds(sizes[i]); 727 } 728 } 729 } 730 731 private Rectangle [] layout(Container parent) { 732 Dimension dim = DiffMainPanel.this.getSize(); 733 Dimension max = parent.getSize(); 734 int rowOffset = 0; 735 int maxHeigth = 0; 736 737 List sizes = new ArrayList(); 738 int components = parent.getComponentCount(); 739 int horizont = 0; 740 for (int i = 0; i < components; i++) { 741 Rectangle rect = new Rectangle(); 742 JComponent comp = (JComponent) parent.getComponent(i); 743 if (comp.isVisible()) { 744 rect.setLocation(horizont, rowOffset); 745 if (comp instanceof AbstractButton) { 746 adjustToobarButton((AbstractButton)comp); 747 } else { 748 adjustToolbarComponentSize((JComponent)comp); 749 } 750 Dimension pref = comp.getPreferredSize(); 751 int width = pref.width; 752 if (comp instanceof JSeparator && ((dim.height - dim.width) <= 0)) { 753 width = Math.max(width, TOOLBAR_SEPARATOR_MIN_WIDTH); 754 } 755 756 int height = getToolbarHeight(dim) -1; 758 maxHeigth = Math.max(maxHeigth, height); 759 rect.setSize(width, height); horizont += width; 761 if (horizont > max.width) { 762 rowOffset += maxHeigth + 2; 763 horizont = 0; 764 maxHeigth = 0; 765 } 766 } 767 sizes.add(rect); 768 } 769 return (Rectangle[]) sizes.toArray(new Rectangle[sizes.size()]); 770 } 771 772 public void addLayoutComponent(String name, Component comp) { 773 } 774 775 public Dimension minimumLayoutSize(Container parent) { 776 777 Dimension dim = DiffMainPanel.this.getSize(); 779 int height = getToolbarHeight(dim); 780 781 int components = parent.getComponentCount(); 782 int horizont = 0; 783 for (int i = 0; i<components; i++) { 784 Component comp = parent.getComponent(i); 785 if (comp.isVisible() == false) continue; 786 if (comp instanceof AbstractButton) { 787 adjustToobarButton((AbstractButton)comp); 788 } else { 789 adjustToolbarComponentSize((JComponent)comp); 790 } 791 Dimension pref = comp.getPreferredSize(); 792 int width = pref.width; 793 if (comp instanceof JSeparator && ((dim.height - dim.width) <= 0)) { 794 width = Math.max(width, TOOLBAR_SEPARATOR_MIN_WIDTH); 795 } 796 horizont += width; 797 } 798 799 return new Dimension(horizont, height); 800 } 801 802 public Dimension preferredLayoutSize(Container parent) { 803 Rectangle [] bounds = layout(parent); 804 Rectangle union = new Rectangle(); 805 for (int i = 0; i < bounds.length; i++) { 806 union.add(bounds[i]); 807 } 808 return new Dimension(union.width, union.height); 809 } 810 811 815 private int getToolbarHeight(Dimension parent) { 816 817 if (parentSize == null || (parentSize.equals(parent) == false)) { 818 parentSize = parent; 819 toolbarHeight = -1; 820 } 821 822 if (toolbarHeight == -1) { 823 BufferedImage image = new BufferedImage (1,1,BufferedImage.TYPE_BYTE_GRAY); 824 Graphics2D g = image.createGraphics(); 825 UIDefaults def = UIManager.getLookAndFeelDefaults(); 826 827 int height = 0; 828 String [] fonts = {"Label.font", "Button.font", "ToggleButton.font"}; for (int i=0; i<fonts.length; i++) { 830 Font f = def.getFont(fonts[i]); 831 FontMetrics fm = g.getFontMetrics(f); 832 height = Math.max(height, fm.getHeight()); 833 } 834 toolbarHeight = height + TOOLBAR_HEIGHT_ADJUSTMENT; 835 } 836 837 return toolbarHeight; 838 } 839 840 841 842 private void adjustToobarButton(final AbstractButton button) { 843 844 if (adjusted.contains(button)) return; 845 846 if (button instanceof JToggleButton == false) { 850 button.setContentAreaFilled(false); 851 button.setMargin(new Insets(0, 3, 0, 3)); 852 button.setBorderPainted(false); 853 button.addMouseListener(new MouseAdapter() { 854 public void mouseEntered(MouseEvent e) { 855 button.setContentAreaFilled(true); 856 button.setBorderPainted(true); 857 } 858 859 public void mouseExited(MouseEvent e) { 860 button.setContentAreaFilled(false); 861 button.setBorderPainted(false); 862 } 863 }); 864 } 865 866 adjustToolbarComponentSize(button); 867 } 868 869 private void adjustToolbarComponentSize(JComponent button) { 870 871 if (adjusted.contains(button)) return; 872 873 if (button.getBorder() instanceof CompoundBorder ) { Dimension pref = button.getPreferredSize(); 876 877 if ("Windows".equals(UIManager.getLookAndFeel().getID())) { pref.width += 9; 880 } 881 button.setPreferredSize(pref); 882 } 883 884 adjusted.add(button); 885 } 886 } 887 888 private static class SetupsComparator extends Utils.ByImportanceComparator { 889 890 private FileStatusCache cache; 891 892 public SetupsComparator() { 893 cache = CvsVersioningSystem.getInstance().getStatusCache(); 894 } 895 896 public int compare(Object o1, Object o2) { 897 File file1 = ((Setup) o1).getBaseFile(); 898 File file2 = ((Setup) o2).getBaseFile(); 899 int cmp = super.compare(cache.getStatus(file1), cache.getStatus(file2)); 900 if (cmp == 0) { 901 return file1.getName().compareToIgnoreCase(file2.getName()); 902 } 903 return cmp; 904 } 905 } 906 907 private class RefreshViewTask implements Runnable { 908 public void run() { 909 SwingUtilities.invokeLater(new Runnable () { 910 public void run() { 911 refreshSetups(); 912 } 913 }); 914 } 915 } 916 } 917 | Popular Tags |