1 19 20 package org.netbeans.modules.subversion.ui.history; 21 22 import javax.swing.event.DocumentEvent ; 23 import javax.swing.event.DocumentListener ; 24 import org.openide.util.RequestProcessor; 25 import org.openide.util.NbBundle; 26 import org.openide.explorer.ExplorerManager; 27 import org.openide.nodes.Node; 28 import org.openide.windows.TopComponent; 29 import org.openide.awt.Mnemonics; 30 import org.netbeans.modules.subversion.ui.diff.DiffSetupSource; 31 import org.netbeans.modules.subversion.ui.diff.Setup; 32 import org.netbeans.modules.versioning.util.NoContentPanel; 33 import org.netbeans.modules.subversion.util.SvnUtils; 34 import org.tigris.subversion.svnclientadapter.SVNRevision; 35 import org.tigris.subversion.svnclientadapter.SVNUrl; 36 37 import javax.swing.*; 38 import java.io.File ; 39 import java.util.*; 40 import java.beans.PropertyChangeEvent ; 41 import java.beans.PropertyChangeListener ; 42 import java.awt.event.KeyEvent ; 43 import java.awt.event.ActionEvent ; 44 import java.awt.event.ActionListener ; 45 import java.awt.Dimension ; 46 47 52 class SearchHistoryPanel extends javax.swing.JPanel implements ExplorerManager.Provider, PropertyChangeListener , ActionListener , DiffSetupSource, DocumentListener { 53 54 private final File [] roots; 55 private final SVNUrl repositoryUrl; 56 private final SearchCriteriaPanel criteria; 57 58 private Divider divider; 59 private Action searchAction; 60 private SearchExecutor currentSearch; 61 private RequestProcessor.Task currentSearchTask; 62 63 private boolean criteriaVisible; 64 private boolean searchInProgress; 65 private List<RepositoryRevision> results; 66 private SummaryView summaryView; 67 private DiffResultsView diffView; 68 69 private AbstractAction nextAction; 70 private AbstractAction prevAction; 71 72 73 public SearchHistoryPanel(File [] roots, SearchCriteriaPanel criteria) { 74 this.roots = roots; 75 this.repositoryUrl = null; 76 this.criteria = criteria; 77 criteriaVisible = true; 78 explorerManager = new ExplorerManager (); 79 initComponents(); 80 setupComponents(); 81 refreshComponents(true); 82 } 83 84 public SearchHistoryPanel(SVNUrl repositoryUrl, File localRoot, SearchCriteriaPanel criteria) { 85 this.repositoryUrl = repositoryUrl; 86 this.roots = new File [] { localRoot }; 87 this.criteria = criteria; 88 criteriaVisible = true; 89 explorerManager = new ExplorerManager (); 90 initComponents(); 91 setupComponents(); 92 refreshComponents(true); 93 } 94 95 private void setupComponents() { 96 remove(jPanel1); 97 98 divider = new Divider(this); 99 java.awt.GridBagConstraints gridBagConstraints; 100 gridBagConstraints = new java.awt.GridBagConstraints (); 101 gridBagConstraints.gridy = 2; 102 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 103 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 104 gridBagConstraints.weightx = 1.0; 105 gridBagConstraints.insets = new java.awt.Insets (2, 0, 2, 0); 106 add(divider, gridBagConstraints); 107 108 searchCriteriaPanel.add(criteria); 109 searchAction = new AbstractAction(NbBundle.getMessage(SearchHistoryPanel.class, "CTL_Search")) { { 111 putValue(Action.SHORT_DESCRIPTION, NbBundle.getMessage(SearchHistoryPanel.class, "TT_Search")); } 113 public void actionPerformed(ActionEvent e) { 114 search(); 115 } 116 }; 117 getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "search"); getActionMap().put("search", searchAction); bSearch.setAction(searchAction); 120 Mnemonics.setLocalizedText(bSearch, NbBundle.getMessage(SearchHistoryPanel.class, "CTL_Search")); 122 Dimension d1 = tbSummary.getPreferredSize(); 123 Dimension d2 = tbDiff.getPreferredSize(); 124 if (d1.width > d2.width) { 125 tbDiff.setPreferredSize(d1); 126 } 127 128 nextAction = new AbstractAction(null, new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/subversion/resources/icons/diff-next.png"))) { { 130 putValue(Action.SHORT_DESCRIPTION, java.util.ResourceBundle.getBundle("org/netbeans/modules/subversion/ui/diff/Bundle"). getString("CTL_DiffPanel_Next_Tooltip")); } 133 public void actionPerformed(ActionEvent e) { 134 diffView.onNextButton(); 135 } 136 }; 137 prevAction = new AbstractAction(null, new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/subversion/resources/icons/diff-prev.png"))) { { 139 putValue(Action.SHORT_DESCRIPTION, java.util.ResourceBundle.getBundle("org/netbeans/modules/subversion/ui/diff/Bundle"). getString("CTL_DiffPanel_Prev_Tooltip")); } 142 public void actionPerformed(ActionEvent e) { 143 diffView.onPrevButton(); 144 } 145 }; 146 bNext.setAction(nextAction); 147 bPrev.setAction(prevAction); 148 149 criteria.tfFrom.getDocument().addDocumentListener(this); 150 criteria.tfTo.getDocument().addDocumentListener(this); 151 152 getActionMap().put("jumpNext", nextAction); getActionMap().put("jumpPrev", prevAction); } 155 156 public void actionPerformed(ActionEvent e) { 157 if (e.getID() == Divider.DIVIDER_CLICKED) { 158 criteriaVisible = !criteriaVisible; 159 refreshComponents(false); 160 } 161 } 162 163 private ExplorerManager explorerManager; 164 165 public void propertyChange(PropertyChangeEvent evt) { 166 if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) { 167 TopComponent tc = (TopComponent) SwingUtilities.getAncestorOfClass(TopComponent.class, this); 168 if (tc == null) return; 169 tc.setActivatedNodes((Node[]) evt.getNewValue()); 170 } 171 } 172 173 public void addNotify() { 174 super.addNotify(); 175 explorerManager.addPropertyChangeListener(this); 176 } 177 178 public void removeNotify() { 179 explorerManager.removePropertyChangeListener(this); 180 super.removeNotify(); 181 } 182 183 public ExplorerManager getExplorerManager () { 184 return explorerManager; 185 } 186 187 final void refreshComponents(boolean refreshResults) { 188 if (refreshResults) { 189 resultsPanel.removeAll(); 190 if (results == null) { 191 if (searchInProgress) { 192 resultsPanel.add(new NoContentPanel(NbBundle.getMessage(SearchHistoryPanel.class, "LBL_SearchHistory_Searching"))); } else { 194 resultsPanel.add(new NoContentPanel(NbBundle.getMessage(SearchHistoryPanel.class, "LBL_SearchHistory_NoResults"))); } 196 } else { 197 if (tbSummary.isSelected()) { 198 if (summaryView == null) { 199 summaryView = new SummaryView(this, results); 200 } 201 resultsPanel.add(summaryView.getComponent()); 202 } else { 203 if (diffView == null) { 204 diffView = new DiffResultsView(this, results); 205 } 206 resultsPanel.add(diffView.getComponent()); 207 } 208 } 209 resultsPanel.revalidate(); 210 resultsPanel.repaint(); 211 } 212 nextAction.setEnabled(!tbSummary.isSelected() && diffView != null && diffView.isNextEnabled()); 213 prevAction.setEnabled(!tbSummary.isSelected() && diffView != null && diffView.isPrevEnabled()); 214 215 divider.setArrowDirection(criteriaVisible ? Divider.UP : Divider.DOWN); 216 searchCriteriaPanel.setVisible(criteriaVisible); 217 bSearch.setVisible(criteriaVisible); 218 revalidate(); 219 repaint(); 220 } 221 222 public void setResults(List<RepositoryRevision> newResults) { 223 setResults(newResults, false); 224 } 225 226 private void setResults(List<RepositoryRevision> newResults, boolean searching) { 227 this.results = newResults; 228 this.searchInProgress = searching; 229 summaryView = null; 230 diffView = null; 231 refreshComponents(true); 232 } 233 234 public SVNUrl getRepositoryUrl() { 235 return repositoryUrl; 236 } 237 238 public SVNUrl getSearchRepositoryRootUrl() { 239 if (repositoryUrl != null) return repositoryUrl; 240 return SvnUtils.getRepositoryRootUrl(roots[0]); 241 } 242 243 public File [] getRoots() { 244 return roots; 245 } 246 247 public SearchCriteriaPanel getCriteria() { 248 return criteria; 249 } 250 251 private synchronized void search() { 252 if (currentSearchTask != null) { 253 currentSearchTask.cancel(); 254 } 255 setResults(null, true); 256 currentSearch = new SearchExecutor(this); 257 currentSearchTask = RequestProcessor.getDefault().create(currentSearch); 258 currentSearchTask.schedule(0); 259 } 260 261 void executeSearch() { 262 search(); 263 } 264 265 void showDiff(RepositoryRevision.Event revision) { 266 tbDiff.setSelected(true); 267 refreshComponents(true); 268 diffView.select(revision); 269 } 270 271 public void showDiff(RepositoryRevision container) { 272 tbDiff.setSelected(true); 273 refreshComponents(true); 274 diffView.select(container); 275 } 276 277 282 public Collection getSetups() { 283 if (results == null) { 284 return Collections.EMPTY_SET; 285 } 286 if (tbDiff.isSelected()) { 287 return diffView.getSetups(); 288 } else { 289 return summaryView.getSetups(); 290 } 291 } 292 293 Collection getSetups(RepositoryRevision [] revisions, RepositoryRevision.Event [] events) { 294 long fromRevision = Long.MAX_VALUE; 295 long toRevision = Long.MIN_VALUE; 296 Set<File > filesToDiff = new HashSet<File >(); 297 298 for (RepositoryRevision revision : revisions) { 299 long rev = revision.getLog().getRevision().getNumber(); 300 if (rev > toRevision) toRevision = rev; 301 if (rev < fromRevision) fromRevision = rev; 302 List<RepositoryRevision.Event> evs = revision.getEvents(); 303 for (RepositoryRevision.Event event : evs) { 304 File file = event.getFile(); 305 if (file != null) { 306 filesToDiff.add(file); 307 } 308 } 309 } 310 311 for (RepositoryRevision.Event event : events) { 312 long rev = event.getLogInfoHeader().getLog().getRevision().getNumber(); 313 if (rev > toRevision) toRevision = rev; 314 if (rev < fromRevision) fromRevision = rev; 315 if (event.getFile() != null) { 316 filesToDiff.add(event.getFile()); 317 } 318 } 319 320 List<Setup> setups = new ArrayList<Setup>(); 321 for (File file : filesToDiff) { 322 Setup setup = new Setup(file, Long.toString(fromRevision - 1), Long.toString(toRevision)); 323 setups.add(setup); 324 } 325 return setups; 326 } 327 328 public String getSetupDisplayName() { 329 return null; 330 } 331 332 public static int compareRevisions(String r1, String r2) { 333 StringTokenizer st1 = new StringTokenizer(r1, "."); StringTokenizer st2 = new StringTokenizer(r2, "."); for (;;) { 336 if (!st1.hasMoreTokens()) { 337 return st2.hasMoreTokens() ? -1 : 0; 338 } 339 if (!st2.hasMoreTokens()) { 340 return st1.hasMoreTokens() ? 1 : 0; 341 } 342 int n1 = Integer.parseInt(st1.nextToken()); 343 int n2 = Integer.parseInt(st2.nextToken()); 344 if (n1 != n2) return n2 - n1; 345 } 346 } 347 348 353 private void initComponents() { 355 java.awt.GridBagConstraints gridBagConstraints; 356 357 buttonGroup1 = new javax.swing.ButtonGroup (); 358 searchCriteriaPanel = new javax.swing.JPanel (); 359 bSearch = new javax.swing.JButton (); 360 jPanel1 = new javax.swing.JPanel (); 361 jToolBar1 = new javax.swing.JToolBar (); 362 tbSummary = new javax.swing.JToggleButton (); 363 tbDiff = new javax.swing.JToggleButton (); 364 jSeparator2 = new javax.swing.JSeparator (); 365 bNext = new javax.swing.JButton (); 366 bPrev = new javax.swing.JButton (); 367 resultsPanel = new javax.swing.JPanel (); 368 369 setLayout(new java.awt.GridBagLayout ()); 370 371 setBorder(javax.swing.BorderFactory.createEmptyBorder(8, 8, 0, 8)); 372 searchCriteriaPanel.setLayout(new java.awt.BorderLayout ()); 373 374 gridBagConstraints = new java.awt.GridBagConstraints (); 375 gridBagConstraints.gridx = 0; 376 gridBagConstraints.gridy = 0; 377 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 378 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 379 gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; 380 gridBagConstraints.weightx = 1.0; 381 add(searchCriteriaPanel, gridBagConstraints); 382 383 bSearch.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/subversion/ui/history/Bundle").getString("TT_Search")); 384 gridBagConstraints = new java.awt.GridBagConstraints (); 385 gridBagConstraints.gridx = 0; 386 gridBagConstraints.gridy = 1; 387 gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; 388 add(bSearch, gridBagConstraints); 389 390 jPanel1.setPreferredSize(new java.awt.Dimension (10, 6)); 391 gridBagConstraints = new java.awt.GridBagConstraints (); 392 gridBagConstraints.gridy = 2; 393 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 394 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 395 gridBagConstraints.weightx = 1.0; 396 gridBagConstraints.insets = new java.awt.Insets (0, 0, 2, 0); 397 add(jPanel1, gridBagConstraints); 398 399 jToolBar1.setFloatable(false); 400 jToolBar1.setRollover(true); 401 buttonGroup1.add(tbSummary); 402 tbSummary.setSelected(true); 403 org.openide.awt.Mnemonics.setLocalizedText(tbSummary, java.util.ResourceBundle.getBundle("org/netbeans/modules/subversion/ui/history/Bundle").getString("CTL_ShowSummary")); 404 tbSummary.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/subversion/ui/history/Bundle").getString("TT_Summary")); 405 tbSummary.addActionListener(new java.awt.event.ActionListener () { 406 public void actionPerformed(java.awt.event.ActionEvent evt) { 407 onViewToggle(evt); 408 } 409 }); 410 411 jToolBar1.add(tbSummary); 412 413 buttonGroup1.add(tbDiff); 414 org.openide.awt.Mnemonics.setLocalizedText(tbDiff, java.util.ResourceBundle.getBundle("org/netbeans/modules/subversion/ui/history/Bundle").getString("CTL_ShowDiff")); 415 tbDiff.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/subversion/ui/history/Bundle").getString("TT_ShowDiff")); 416 tbDiff.addActionListener(new java.awt.event.ActionListener () { 417 public void actionPerformed(java.awt.event.ActionEvent evt) { 418 onViewToggle(evt); 419 } 420 }); 421 422 jToolBar1.add(tbDiff); 423 424 jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL); 425 jSeparator2.setMaximumSize(new java.awt.Dimension (2, 32767)); 426 jToolBar1.add(jSeparator2); 427 428 bNext.setIcon(new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/subversion/resources/icons/diff-next.png"))); 429 jToolBar1.add(bNext); 430 bNext.getAccessibleContext().setAccessibleName(java.util.ResourceBundle.getBundle("org/netbeans/modules/subversion/ui/history/Bundle").getString("ACSN_NextDifference")); 431 432 bPrev.setIcon(new javax.swing.ImageIcon (getClass().getResource("/org/netbeans/modules/subversion/resources/icons/diff-prev.png"))); 433 jToolBar1.add(bPrev); 434 bPrev.getAccessibleContext().setAccessibleName(java.util.ResourceBundle.getBundle("org/netbeans/modules/subversion/ui/history/Bundle").getString("ACSN_PrevDifference")); 435 436 gridBagConstraints = new java.awt.GridBagConstraints (); 437 gridBagConstraints.gridy = 3; 438 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 439 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 440 add(jToolBar1, gridBagConstraints); 441 442 resultsPanel.setLayout(new java.awt.BorderLayout ()); 443 444 gridBagConstraints = new java.awt.GridBagConstraints (); 445 gridBagConstraints.gridx = 0; 446 gridBagConstraints.gridy = 4; 447 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 448 gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; 449 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 450 gridBagConstraints.weightx = 1.0; 451 gridBagConstraints.weighty = 1.0; 452 gridBagConstraints.insets = new java.awt.Insets (8, 0, 8, 0); 453 add(resultsPanel, gridBagConstraints); 454 455 } 457 private void onViewToggle(java.awt.event.ActionEvent evt) { refreshComponents(true); 459 } 461 public void insertUpdate(DocumentEvent e) { 462 validateUserInput(); 463 } 464 465 public void removeUpdate(DocumentEvent e) { 466 validateUserInput(); 467 } 468 469 public void changedUpdate(DocumentEvent e) { 470 validateUserInput(); 471 } 472 473 private void validateUserInput() { 474 SVNRevision from = criteria.getFrom(); 475 if(from == null && criteria.tfFrom.getText().trim().length() > 0) { 476 bSearch.setEnabled(false); 477 return; 478 } 479 SVNRevision to = criteria.getTo(); 480 if(to == null && criteria.tfTo.getText().trim().length() > 0) { 481 bSearch.setEnabled(false); 482 return; 483 } 484 bSearch.setEnabled(true); 485 } 486 487 private javax.swing.JButton bNext; 489 private javax.swing.JButton bPrev; 490 private javax.swing.JButton bSearch; 491 private javax.swing.ButtonGroup buttonGroup1; 492 private javax.swing.JPanel jPanel1; 493 private javax.swing.JSeparator jSeparator2; 494 private javax.swing.JToolBar jToolBar1; 495 private javax.swing.JPanel resultsPanel; 496 private javax.swing.JPanel searchCriteriaPanel; 497 private javax.swing.JToggleButton tbDiff; 498 private javax.swing.JToggleButton tbSummary; 499 501 } 502 | Popular Tags |