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.modules.versioning.system.cvss.util.Utils; 24 import org.netbeans.modules.versioning.system.cvss.ui.actions.diff.DiffStreamSource; 25 import org.netbeans.modules.versioning.system.cvss.VersionsCache; 26 import org.netbeans.modules.versioning.util.NoContentPanel; 27 import org.netbeans.api.diff.DiffView; 28 import org.netbeans.api.diff.Diff; 29 import org.openide.explorer.ExplorerManager; 30 import org.openide.nodes.Node; 31 import org.openide.util.NbBundle; 32 import org.openide.util.RequestProcessor; 33 import org.openide.util.Cancellable; 34 import org.openide.ErrorManager; 35 36 import javax.swing.*; 37 import javax.swing.event.AncestorListener ; 38 import javax.swing.event.AncestorEvent ; 39 import java.util.*; 40 import java.util.List ; 41 import java.beans.PropertyChangeListener ; 42 import java.beans.PropertyChangeEvent ; 43 import java.io.IOException ; 44 import java.awt.*; 45 46 51 class DiffResultsView implements AncestorListener , PropertyChangeListener { 52 53 private final SearchHistoryPanel parent; 54 55 private DiffTreeTable treeView; 56 private JSplitPane diffView; 57 58 private ShowDiffTask currentTask; 59 private RequestProcessor.Task currentShowDiffTask; 60 61 private DiffView currentDiff; 62 private int currentDifferenceIndex; 63 private int currentIndex; 64 private boolean dividerSet; 65 66 public DiffResultsView(SearchHistoryPanel parent, List results) { 67 this.parent = parent; 68 treeView = new DiffTreeTable(); 69 treeView.setResults(results); 70 treeView.addAncestorListener(this); 71 72 diffView = new JSplitPane(JSplitPane.VERTICAL_SPLIT); 73 diffView.setTopComponent(treeView); 74 setBottomComponent(new NoContentPanel(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_NoRevisions"))); } 76 77 public void ancestorAdded(AncestorEvent event) { 78 ExplorerManager em = ExplorerManager.find(treeView); 79 em.addPropertyChangeListener(this); 80 if (!dividerSet) { 81 SwingUtilities.invokeLater(new Runnable () { 82 public void run() { 83 dividerSet = true; 84 diffView.setDividerLocation(0.33); 85 } 86 }); 87 } 88 } 89 90 public void ancestorMoved(AncestorEvent event) { 91 } 92 93 public void ancestorRemoved(AncestorEvent event) { 94 ExplorerManager em = ExplorerManager.find(treeView); 95 em.removePropertyChangeListener(this); 96 cancelBackgroundTasks(); 97 } 98 99 public void propertyChange(PropertyChangeEvent evt) { 100 if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) { 101 final Node [] nodes = (Node[]) evt.getNewValue(); 102 currentDifferenceIndex = 0; 103 if (nodes.length == 0) { 104 showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_NoRevisions")); parent.refreshComponents(false); 106 return; 107 } 108 else if (nodes.length > 2) { 109 showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_TooManyRevisions")); parent.refreshComponents(false); 111 return; 112 } 113 114 Runnable runnable = new Runnable () { 116 public void run() { 117 if (treeView.getSelection().length == 0) return; 118 SearchHistoryPanel.ResultsContainer container1 = nodes[0].getLookup().lookup(SearchHistoryPanel.ResultsContainer.class); 119 SearchHistoryPanel.DispRevision r1 = nodes[0].getLookup().lookup(SearchHistoryPanel.DispRevision.class); 120 try { 121 if (r1 == null || !r1.isBranchRoot()) { 122 currentIndex = treeView.getSelection()[0]; 123 if (nodes.length == 1) { 124 if (container1 != null) { 125 showContainerDiff(container1, onSelectionshowLastDifference); 126 } 127 else if (r1 != null) { 128 showRevisionDiff(r1, onSelectionshowLastDifference); 129 } 130 } else if (nodes.length == 2) { 131 SearchHistoryPanel.DispRevision r2 = nodes[1].getLookup().lookup(SearchHistoryPanel.DispRevision.class); 132 if (r2.isBranchRoot()) throw new Exception (); 133 if (r2.getRevision().getLogInfoHeader() != r1.getRevision().getLogInfoHeader()) { 134 throw new Exception (); 135 } 136 String revision1 = r1.getRevision().getNumber(); 137 String revision2 = r2.getRevision().getNumber(); 138 if (SearchHistoryPanel.compareRevisions(revision1, revision2) == 1) { 139 revision2 = r1.getRevision().getNumber(); 140 revision1 = r2.getRevision().getNumber(); 141 } 142 showDiff(r1.getRevision().getLogInfoHeader(), revision1, revision2, false); 143 } 144 } else { 145 showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_IllegalSelection")); } 147 } catch (Exception e) { 148 showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_IllegalSelection")); parent.refreshComponents(false); 150 return; 151 } 152 } 153 }; 154 SwingUtilities.invokeLater(runnable); 155 } 156 } 157 158 private void showDiffError(String s) { 159 setBottomComponent(new NoContentPanel(s)); 160 } 161 162 private void setBottomComponent(Component component) { 163 int dl = diffView.getDividerLocation(); 164 diffView.setBottomComponent(component); 165 diffView.setDividerLocation(dl); 166 } 167 168 private void showDiff(LogInformation header, String revision1, String revision2, boolean showLastDifference) { 169 synchronized(this) { 170 cancelBackgroundTasks(); 171 currentTask = new ShowDiffTask(header, revision1, revision2, showLastDifference); 172 currentShowDiffTask = RequestProcessor.getDefault().create(currentTask); 173 currentShowDiffTask.schedule(0); 174 } 175 } 176 177 private synchronized void cancelBackgroundTasks() { 178 if (currentShowDiffTask != null && !currentShowDiffTask.isFinished()) { 179 currentShowDiffTask.cancel(); currentTask.cancel(); 181 } 182 } 183 184 private boolean onSelectionshowLastDifference; 185 186 private void setDiffIndex(int idx, boolean showLastDifference) { 187 currentIndex = idx; 188 onSelectionshowLastDifference = showLastDifference; 189 treeView.setSelection(idx); 190 } 191 192 private void showRevisionDiff(SearchHistoryPanel.DispRevision rev, boolean showLastDifference) { 193 String revision2 = rev.getRevision().getNumber(); 194 String revision1; 195 if (revision2 == VersionsCache.REVISION_CURRENT) { 196 SearchHistoryPanel.ResultsContainer container = findParent(rev); 197 SearchHistoryPanel.DispRevision newest = container.getRevisions().get(1); 198 revision1 = newest.getRevision().getNumber(); 199 } else { 200 revision1 = Utils.previousRevision(revision2); 201 } 202 showDiff(rev.getRevision().getLogInfoHeader(), revision1, revision2, showLastDifference); 203 } 204 205 private SearchHistoryPanel.ResultsContainer findParent(SearchHistoryPanel.DispRevision rev) { 206 List results = parent.getDispResults(); 207 for (Object o : results) { 208 if (o instanceof SearchHistoryPanel.ResultsContainer) { 209 SearchHistoryPanel.ResultsContainer container = (SearchHistoryPanel.ResultsContainer) o; 210 if (container.getRevisions().contains(rev)) return container; 211 } 212 } 213 return null; 214 } 215 216 private void showContainerDiff(SearchHistoryPanel.ResultsContainer container, boolean showLastDifference) { 217 List revs = container.getRevisions(); 218 SearchHistoryPanel.DispRevision newest = (SearchHistoryPanel.DispRevision) revs.get(1); 219 showDiff(newest.getRevision().getLogInfoHeader(), container.getEldestRevision(), newest.getRevision().getNumber(), showLastDifference); 220 } 221 222 void onNextButton() { 223 if (currentDiff != null) { 224 if (++currentDifferenceIndex >= currentDiff.getDifferenceCount()) { 225 if (++currentIndex >= treeView.getRowCount()) currentIndex = 0; 226 setDiffIndex(currentIndex, false); 227 } else { 228 currentDiff.setCurrentDifference(currentDifferenceIndex); 229 } 230 } else { 231 if (++currentIndex >= treeView.getRowCount()) currentIndex = 0; 232 setDiffIndex(currentIndex, false); 233 } 234 } 235 236 void onPrevButton() { 237 if (currentDiff != null) { 238 if (--currentDifferenceIndex < 0) { 239 if (--currentIndex < 0) currentIndex = treeView.getRowCount() - 1; 240 setDiffIndex(currentIndex, true); 241 } else { 242 currentDiff.setCurrentDifference(currentDifferenceIndex); 243 } 244 } else { 245 if (--currentIndex < 0) currentIndex = treeView.getRowCount() - 1; 246 setDiffIndex(currentIndex, true); 247 } 248 } 249 250 boolean isNextEnabled() { 251 if (currentDiff != null) { 252 return currentIndex < treeView.getRowCount() - 1 || currentDifferenceIndex < currentDiff.getDifferenceCount() - 1; 253 } else { 254 return false; 255 } 256 } 257 258 boolean isPrevEnabled() { 259 return currentIndex > 0 || currentDifferenceIndex > 0; 260 } 261 262 267 void select(SearchHistoryPanel.DispRevision revision) { 268 treeView.requestFocusInWindow(); 269 treeView.setSelection(revision); 270 } 271 272 void select(SearchHistoryPanel.ResultsContainer container) { 273 treeView.requestFocusInWindow(); 274 treeView.setSelection(container); 275 } 276 277 280 List <Object > getSelection() { 281 Node [] nodes = ExplorerManager.find(treeView).getSelectedNodes(); 282 List <Object > selection = new ArrayList<Object >(nodes.length); 283 for (Node node : nodes) { 284 RevisionNode rnode = (RevisionNode) node; 285 if (rnode.getContainer() != null) { 286 selection.add(rnode.getContainer()); 287 } else { 288 selection.add(rnode.getDispRevision()); 289 } 290 } 291 return selection; 292 } 293 294 private class ShowDiffTask implements Runnable , Cancellable { 295 296 private final LogInformation header; 297 private final String revision1; 298 private final String revision2; 299 private boolean showLastDifference; 300 private volatile boolean cancelled; 301 private Thread thread; 302 303 public ShowDiffTask(LogInformation header, String revision1, String revision2, boolean showLastDifference) { 304 this.header = header; 305 this.revision1 = revision1; 306 this.revision2 = revision2; 307 this.showLastDifference = showLastDifference; 308 } 309 310 public void run() { 311 thread = Thread.currentThread(); 312 final Diff diff = Diff.getDefault(); 313 final DiffStreamSource s1 = new DiffStreamSource(header.getFile(), revision1, revision1 == VersionsCache.REVISION_CURRENT ? 314 NbBundle.getMessage(DiffResultsView.class, "LBL_DiffPanel_LocalCopy") : revision1); final DiffStreamSource s2 = new DiffStreamSource(header.getFile(), revision2, revision2 == VersionsCache.REVISION_CURRENT ? 316 NbBundle.getMessage(DiffResultsView.class, "LBL_DiffPanel_LocalCopy") : revision2); 318 s1.getMIMEType(); if (cancelled) { 321 return; 322 } 323 324 s2.getMIMEType(); if (cancelled) { 326 return; 327 } 328 329 if (currentTask != this) return; 330 331 SwingUtilities.invokeLater(new Runnable () { 332 public void run() { 333 try { 334 if (cancelled) { 335 return; 336 } 337 final DiffView view = diff.createDiff(s1, s2); 338 if (currentTask == ShowDiffTask.this) { 339 currentDiff = view; 340 setBottomComponent(currentDiff.getComponent()); 341 if (currentDiff.getDifferenceCount() > 0) { 342 currentDifferenceIndex = showLastDifference ? currentDiff.getDifferenceCount() - 1 : 0; 343 currentDiff.setCurrentDifference(currentDifferenceIndex); 344 } 345 parent.refreshComponents(false); 346 } 347 } catch (IOException e) { 348 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 349 } 350 } 351 }); 352 } 353 354 public boolean cancel() { 355 cancelled = true; 356 if (thread != null) { 357 thread.interrupt(); 358 } 359 return true; 360 } 361 } 362 363 public JComponent getComponent() { 364 return diffView; 365 } 366 } 367 368 | Popular Tags |