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