1 12 package org.eclipse.team.internal.ccvs.ui.operations; 13 14 import java.io.*; 15 import java.util.*; 16 17 import org.eclipse.core.resources.*; 18 import org.eclipse.core.runtime.*; 19 import org.eclipse.jface.dialogs.IDialogConstants; 20 import org.eclipse.jface.dialogs.MessageDialogWithToggle; 21 import org.eclipse.jface.preference.IPreferenceStore; 22 import org.eclipse.jface.resource.JFaceResources; 23 import org.eclipse.jface.text.IInformationControl; 24 import org.eclipse.jface.text.IInformationControlCreator; 25 import org.eclipse.jface.text.revisions.Revision; 26 import org.eclipse.jface.text.revisions.RevisionInformation; 27 import org.eclipse.jface.text.source.LineRange; 28 import org.eclipse.osgi.util.NLS; 29 import org.eclipse.swt.SWT; 30 import org.eclipse.swt.graphics.RGB; 31 import org.eclipse.swt.widgets.Display; 32 import org.eclipse.swt.widgets.Shell; 33 import org.eclipse.team.core.TeamException; 34 import org.eclipse.team.core.variants.IResourceVariant; 35 import org.eclipse.team.internal.ccvs.core.*; 36 import org.eclipse.team.internal.ccvs.core.client.*; 37 import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; 38 import org.eclipse.team.internal.ccvs.core.client.listeners.AnnotateListener; 39 import org.eclipse.team.internal.ccvs.core.connection.CVSServerException; 40 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; 41 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; 42 import org.eclipse.team.internal.ccvs.core.util.KnownRepositories; 43 import org.eclipse.team.internal.ccvs.ui.*; 44 import org.eclipse.team.internal.ccvs.ui.Policy; 45 import org.eclipse.team.internal.core.TeamPlugin; 46 import org.eclipse.team.internal.ui.Utils; 47 import org.eclipse.team.ui.TeamUI; 48 import org.eclipse.team.ui.history.*; 49 import org.eclipse.ui.*; 50 import org.eclipse.ui.editors.text.EditorsUI; 51 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor; 52 53 import com.ibm.icu.text.DateFormat; 54 55 59 public class ShowAnnotationOperation extends CVSOperation { 60 61 private final ICVSResource fCVSResource; 62 private final String fRevision; 63 private final boolean fBinary; 64 65 public ShowAnnotationOperation(IWorkbenchPart part, ICVSResource cvsResource, String revision, boolean binary) { 66 super(part); 67 fCVSResource= cvsResource; 68 fRevision= revision; 69 fBinary = binary; 70 } 71 72 75 protected void execute(IProgressMonitor monitor) throws CVSException, InterruptedException { 76 77 final boolean useLiveAnnotate= isKnownUseLiveAnnotate(); 78 final boolean useView= isKnownUseView(); 79 80 monitor.beginTask(null, 80 + (useView ? 0 : 20) + (useLiveAnnotate ? 0 : 20)); 81 82 final AnnotateListener listener= new AnnotateListener(); 84 fetchAnnotation(listener, fCVSResource, fRevision, Policy.subMonitorFor(monitor, 80)); 85 86 if (!useLiveAnnotate || fCVSResource.getIResource() == null) 90 fetchContents(listener, Policy.subMonitorFor(monitor, 20)); 91 92 final RevisionInformation information; 94 if (!useView) 95 information= createRevisionInformation(listener, Policy.subMonitorFor(monitor, 20)); 96 else 97 information= null; 98 99 final Display display= getPart().getSite().getShell().getDisplay(); 101 display.asyncExec(new Runnable () { 102 public void run() { 103 boolean useQuickDiffAnnotate = promptForQuickDiffAnnotate(); 107 if (useQuickDiffAnnotate){ 108 try { 109 final AbstractDecoratedTextEditor editor= getEditor(listener); 111 if (editor != null) { 112 editor.showRevisionInformation(information, "org.eclipse.quickdiff.providers.CVSReferenceProvider"); final IWorkbenchPage page= getPart().getSite().getPage(); 114 showHistoryView(page, editor); 115 page.activate(editor); 116 } 117 } catch (PartInitException e) { 118 CVSException.wrapException(e); 119 } 120 } else 121 showView(listener); 122 } 123 }); 124 125 monitor.done(); 126 } 127 128 136 private IHistoryView showHistoryView(IWorkbenchPage page, AbstractDecoratedTextEditor editor) throws PartInitException { 137 Object object = fCVSResource.getIResource(); 138 if (object == null) 139 object = editor.getEditorInput(); 140 IHistoryView historyView= TeamUI.showHistoryFor(page, object, null); 141 IHistoryPage historyPage = historyView.getHistoryPage(); 142 if (historyPage instanceof CVSHistoryPage){ 143 CVSHistoryPage cvsHistoryPage = (CVSHistoryPage) historyPage; 144 cvsHistoryPage.setMode(CVSHistoryPage.REMOTE_MODE); 145 cvsHistoryPage.linkWithEditor(); 148 } 149 return historyView; 150 } 151 152 155 protected String getTaskName() { 156 return CVSUIMessages.ShowAnnotationOperation_taskName; 157 } 158 159 protected boolean hasCharset(ICVSResource cvsResource, InputStream contents) { 160 try { 161 return TeamPlugin.getCharset(cvsResource.getName(), contents) != null; 162 } catch (IOException e) { 163 return true; 165 } 166 } 167 168 174 protected void showView(final AnnotateListener listener) { 175 final IWorkbench workbench= PlatformUI.getWorkbench(); 176 final IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); 177 178 final String defaultPerspectiveID= promptForPerspectiveSwitch(); 179 180 if (defaultPerspectiveID != null) { 181 try { 182 workbench.showPerspective(defaultPerspectiveID, window); 183 } catch (WorkbenchException e) { 184 Utils.handleError(window.getShell(), e, CVSUIMessages.ShowAnnotationOperation_0, e.getMessage()); 185 } 186 } 187 188 try { 189 final AnnotateView view = AnnotateView.openInActivePerspective(); 190 view.showAnnotations(fCVSResource, listener.getCvsAnnotateBlocks(), listener.getContents()); 191 } catch (PartInitException e) { 192 CVSUIPlugin.log(e); 193 } catch (CVSException e) { 194 CVSUIPlugin.log(e); 195 } 196 } 197 198 private AbstractDecoratedTextEditor getEditor(AnnotateListener listener) throws PartInitException { 199 IResource resource= fCVSResource.getIResource(); 200 if (resource instanceof IFile){ 201 return RevisionAnnotationController.openEditor(getPart().getSite().getPage(), (IFile)resource); 202 } 203 if (fCVSResource instanceof ICVSRemoteResource) { 204 return RevisionAnnotationController.openEditor(getPart().getSite().getPage(), fCVSResource, new RemoteAnnotationStorage((ICVSRemoteFile)fCVSResource, listener.getContents())); 205 } 206 return null; 207 } 208 209 private void fetchAnnotation(AnnotateListener listener, ICVSResource cvsResource, String revision, IProgressMonitor monitor) throws CVSException { 210 211 monitor = Policy.monitorFor(monitor); 212 monitor.beginTask(null, 100); 213 214 final ICVSFolder folder = cvsResource.getParent(); 215 final FolderSyncInfo info = folder.getFolderSyncInfo(); 216 final ICVSRepositoryLocation location = KnownRepositories.getInstance().getRepository(info.getRoot()); 217 218 final Session session = new Session(location, folder, true ); 219 session.open(Policy.subMonitorFor(monitor, 10), false ); 220 try { 221 final Command.QuietOption quietness = CVSProviderPlugin.getPlugin().getQuietness(); 222 try { 223 CVSProviderPlugin.getPlugin().setQuietness(Command.VERBOSE); 224 List localOptions = new ArrayList(); 225 if (revision != null) { 226 localOptions.add(Annotate.makeRevisionOption(revision)); 227 } 228 if (fBinary) { 229 localOptions.add(Annotate.FORCE_BINARY_ANNOTATE); 230 } 231 final IStatus status = Command.ANNOTATE.execute(session, Command.NO_GLOBAL_OPTIONS, (LocalOption[]) localOptions.toArray(new LocalOption[localOptions.size()]), new ICVSResource[]{cvsResource}, listener, Policy.subMonitorFor(monitor, 90)); 232 if (status.getCode() == CVSStatus.SERVER_ERROR) { 233 throw new CVSServerException(status); 234 } 235 } finally { 236 CVSProviderPlugin.getPlugin().setQuietness(quietness); 237 monitor.done(); 238 } 239 } finally { 240 session.close(); 241 } 242 } 243 244 private RevisionInformation createRevisionInformation(final AnnotateListener listener, IProgressMonitor monitor) throws CVSException { 245 Map logEntriesByRevision= new HashMap(); 246 if (fCVSResource instanceof ICVSFile) { 247 try { 248 ILogEntry[] logEntries= ((ICVSFile) fCVSResource).getLogEntries(monitor); 249 for (int i= 0; i < logEntries.length; i++) { 250 ILogEntry entry= logEntries[i]; 251 logEntriesByRevision.put(entry.getRevision(), entry); 252 } 253 } catch (CVSException e) { 254 throw e; 255 } catch (TeamException e) { 256 throw CVSException.wrapException(e); 258 } 259 } 260 261 final CommitterColors colors= CommitterColors.getDefault(); 262 RevisionInformation info= new RevisionInformation(); 263 264 class AnnotationControlCreator implements IInformationControlCreator { 265 private final boolean showTooltipAffordance; 266 267 public AnnotationControlCreator(boolean showTooltipAffordance) { 268 this.showTooltipAffordance = showTooltipAffordance; 269 } 270 271 public IInformationControl createInformationControl(Shell parent) { 272 String statusFieldText = showTooltipAffordance ? EditorsUI.getTooltipAffordanceString() : null; 273 return new SourceViewerInformationControl(parent, SWT.TOOL, 274 SWT.NONE, JFaceResources.DEFAULT_FONT, statusFieldText); 275 } 276 } 277 278 info.setHoverControlCreator(new AnnotationControlCreator(true)); 279 info.setInformationPresenterControlCreator(new AnnotationControlCreator(false)); 280 281 HashMap sets= new HashMap(); 282 List annotateBlocks= listener.getCvsAnnotateBlocks(); 283 for (Iterator blocks= annotateBlocks.iterator(); blocks.hasNext();) { 284 final CVSAnnotateBlock block= (CVSAnnotateBlock) blocks.next(); 285 final String revisionString= block.getRevision(); 286 Revision revision= (Revision) sets.get(revisionString); 287 if (revision == null) { 288 final ILogEntry entry= (ILogEntry) logEntriesByRevision.get(revisionString); 289 if (entry == null) 290 continue; 291 292 revision= new Revision() { 293 private String fCommitter= null; 294 295 public Object getHoverInfo() { 296 if (entry != null) 297 return entry.getAuthor() + " " + entry.getRevision() + " " + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT).format(entry.getDate()) + "\n\n" + entry.getComment(); 300 return block.toString().substring(0, block.toString().indexOf(" (")); } 302 303 private String getCommitterId() { 304 if (fCommitter == null) 305 fCommitter= block.toString().substring(0, block.toString().indexOf(' ')); 306 return fCommitter; 307 } 308 309 public String getId() { 310 return revisionString; 311 } 312 313 public Date getDate() { 314 return entry.getDate(); 315 } 316 317 public RGB getColor() { 318 return colors.getCommitterRGB(getCommitterId()); 319 } 320 321 public String getAuthor() { 322 return getCommitterId(); 323 } 324 }; 325 sets.put(revisionString, revision); 326 info.addRevision(revision); 327 } 328 revision.addRange(new LineRange(block.getStartLine(), block.getEndLine() - block.getStartLine() + 1)); 329 } 330 331 return info; 332 } 333 334 private void fetchContents(final AnnotateListener listener, IProgressMonitor monitor) { 335 try { 336 if (hasCharset(fCVSResource, listener.getContents())) { 337 listener.setContents(getRemoteContents(fCVSResource, monitor)); 338 } 339 } catch (CoreException e) { 340 CVSUIPlugin.log(e); 342 } 343 } 344 345 private InputStream getRemoteContents(ICVSResource resource, IProgressMonitor monitor) throws CoreException { 346 347 final ICVSRemoteResource remote = CVSWorkspaceRoot.getRemoteResourceFor(resource); 348 if (remote == null) { 349 return new ByteArrayInputStream(new byte[0]); 350 } 351 final IStorage storage = ((IResourceVariant)remote).getStorage(monitor); 352 if (storage == null) { 353 return new ByteArrayInputStream(new byte[0]); 354 } 355 return storage.getContents(); 356 } 357 358 362 private String promptForPerspectiveSwitch() { 363 final IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); 365 final String option = store.getString(ICVSUIConstants.PREF_CHANGE_PERSPECTIVE_ON_SHOW_ANNOTATIONS); 366 final String desiredID = store.getString(ICVSUIConstants.PREF_DEFAULT_PERSPECTIVE_FOR_SHOW_ANNOTATIONS); 367 368 if (option.equals(MessageDialogWithToggle.ALWAYS)) 369 return desiredID; 371 if (option.equals(MessageDialogWithToggle.NEVER)) 372 return null; 374 final IPerspectiveRegistry registry= PlatformUI.getWorkbench().getPerspectiveRegistry(); 376 final IPerspectiveDescriptor desired = registry.findPerspectiveWithId(desiredID); 377 final IWorkbenchPage page = CVSUIPlugin.getActivePage(); 378 379 if (page != null) { 380 final IPerspectiveDescriptor current = page.getPerspective(); 381 if (current != null && current.getId().equals(desiredID)) { 382 return null; } 384 } 385 386 if (desired != null) { 387 388 String message;; 389 String desc = desired.getDescription(); 390 if (desc == null) { 391 message = NLS.bind(CVSUIMessages.ShowAnnotationOperation_2, new String [] { desired.getLabel() }); 392 } else { 393 message = NLS.bind(CVSUIMessages.ShowAnnotationOperation_3, new String [] { desired.getLabel(), desc }); 394 } 395 final MessageDialogWithToggle m = MessageDialogWithToggle.openYesNoQuestion( 397 Utils.getShell(null), 398 CVSUIMessages.ShowAnnotationOperation_1, 399 message, 400 CVSUIMessages.ShowAnnotationOperation_4, 401 false , 402 store, 403 ICVSUIConstants.PREF_CHANGE_PERSPECTIVE_ON_SHOW_ANNOTATIONS); 404 405 final int result = m.getReturnCode(); 406 switch (result) { 407 case IDialogConstants.YES_ID: 409 case IDialogConstants.OK_ID : 410 return desiredID; 411 case IDialogConstants.NO_ID : 413 return null; 414 } 415 } 416 return null; 417 } 418 419 private boolean isKnownUseView() { 420 final IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); 422 final String option = store.getString(ICVSUIConstants.PREF_USE_QUICKDIFFANNOTATE); 423 424 return option.equals(MessageDialogWithToggle.NEVER); 425 } 426 427 private boolean isKnownUseLiveAnnotate() { 428 final IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); 430 final String option = store.getString(ICVSUIConstants.PREF_USE_QUICKDIFFANNOTATE); 431 432 return option.equals(MessageDialogWithToggle.ALWAYS); 433 } 434 435 439 private boolean promptForQuickDiffAnnotate(){ 440 final IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); 442 final String option = store.getString(ICVSUIConstants.PREF_USE_QUICKDIFFANNOTATE); 443 444 if (option.equals(MessageDialogWithToggle.ALWAYS)) 445 return true; else if (option.equals(MessageDialogWithToggle.NEVER)) 447 return false; 449 final MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoQuestion(Utils.getShell(null), CVSUIMessages.ShowAnnotationOperation_QDAnnotateTitle, 450 CVSUIMessages.ShowAnnotationOperation_QDAnnotateMessage,CVSUIMessages.ShowAnnotationOperation_4, false, store, ICVSUIConstants.PREF_USE_QUICKDIFFANNOTATE); 451 452 final int result = dialog.getReturnCode(); 453 switch (result) { 454 case IDialogConstants.YES_ID: 456 case IDialogConstants.OK_ID : 457 return true; 458 } 459 return false; 460 } 461 } 462 | Popular Tags |