Java tutorial
/******************************************************************************* * Copyright (c) ? * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Charles O'Farrell - implementation (based on subclipse) * StefanC - jobs framework, code cleanup * Andrei Loskutov - bug fixes *******************************************************************************/ package com.vectrace.MercurialEclipse.annotations; import java.lang.reflect.InvocationTargetException; import java.text.DateFormat; import java.util.Date; import java.util.HashMap; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.action.IAction; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.text.IInformationControl; import org.eclipse.jface.text.IInformationControlCreator; import org.eclipse.jface.text.revisions.Revision; import org.eclipse.jface.text.revisions.RevisionInformation; import org.eclipse.jface.text.source.LineRange; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Shell; import org.eclipse.team.ui.TeamOperation; import org.eclipse.team.ui.TeamUI; import org.eclipse.team.ui.history.IHistoryPage; import org.eclipse.team.ui.history.IHistoryView; import org.eclipse.ui.IEditorDescriptor; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.texteditor.ITextEditorExtension4; import com.vectrace.MercurialEclipse.MercurialEclipsePlugin; import com.vectrace.MercurialEclipse.SafeUiJob; import com.vectrace.MercurialEclipse.commands.HgAnnotateClient; import com.vectrace.MercurialEclipse.history.MercurialHistoryPage; import com.vectrace.MercurialEclipse.model.ChangeSet; import com.vectrace.MercurialEclipse.team.cache.MercurialStatusCache; import com.vectrace.MercurialEclipse.utils.ResourceUtils; public class ShowAnnotationOperation extends TeamOperation { public static final class MercurialRevision extends Revision { private final CommitterColors colors; private final ChangeSet entry; private final AnnotateBlock block; private MercurialRevision(CommitterColors colors, ChangeSet entry, AnnotateBlock block) { this.colors = colors; this.entry = entry; this.block = block; Assert.isNotNull(colors); Assert.isNotNull(entry); Assert.isNotNull(block); } @Override public Object getHoverInfo() { return entry.getAuthor() + " " + getId() + " " //$NON-NLS-1$//$NON-NLS-2$ + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT).format(block.getDate()) + "\n\n" + //$NON-NLS-1$ (entry.getComment() != null ? entry.getComment() : ""); //$NON-NLS-1$ } /** * @return the entry */ public ChangeSet getChangeSet() { return entry; } @Override public String getAuthor() { return block.getChangeSet().getPerson(); } @Override public String getId() { return block.getChangeSet().getName(); } @Override public Date getDate() { return block.getDate(); } @Override public RGB getColor() { return colors.getCommitterRGB(getAuthor()); } } private static final String DEFAULT_TEXT_EDITOR_ID = EditorsUI.DEFAULT_TEXT_EDITOR_ID; private final IResource res; public ShowAnnotationOperation(IWorkbenchPart part, IResource remoteFile) { super(part); this.res = remoteFile; } public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask(null, 100); try { if (!MercurialStatusCache.getInstance().isSupervised(res)) { return; } final AnnotateBlocks annotateBlocks = HgAnnotateClient.execute(res); // this is not needed if there is no live annotate final RevisionInformation information = createRevisionInformation(annotateBlocks, monitor); // We aren't running from a UI thread new SafeUiJob(Messages.getString("ShowAnnotationOperation.job.name")) { //$NON-NLS-1$ @Override protected IStatus runSafe(IProgressMonitor moni) { moni.beginTask(Messages.getString("ShowAnnotationOperation.beginAnnotation"), //$NON-NLS-1$ IProgressMonitor.UNKNOWN); final ITextEditorExtension4 editor = getEditor(); if (editor != null) { editor.showRevisionInformation(information, HgPristineCopyQuickDiffProvider.HG_REFERENCE_PROVIDER); final IWorkbenchPage page = getPart().getSite().getPage(); showHistoryView(page, (ITextEditor) editor); page.activate((ITextEditor) editor); } moni.done(); return super.runSafe(moni); } }.schedule(); } catch (Exception e) { MercurialEclipsePlugin.logError(e); } finally { monitor.done(); } } /** * Shows the history view, creating it if necessary, but does not give it focus. * * @param page the workbench page to operate in * @param editor the editor that is showing the file * @return the history view * @throws PartInitException */ private IHistoryView showHistoryView(IWorkbenchPage page, ITextEditor editor) { Object object = res; if (object == null) { object = editor.getEditorInput(); } IHistoryView historyView = TeamUI.showHistoryFor(page, object, null); IHistoryPage historyPage = historyView.getHistoryPage(); if (historyPage instanceof MercurialHistoryPage) { MercurialHistoryPage mercurialHistoryPage = (MercurialHistoryPage) historyPage; // We need to call link to ensure that the history page gets linked // even if the page input did not change mercurialHistoryPage.linkWithEditor(); } return historyView; } @Override protected IAction getGotoAction() { return super.getGotoAction(); } private ITextEditorExtension4 getEditor() { IEditorReference[] references = MercurialEclipsePlugin.getActivePage().getEditorReferences(); IResource resource = res; if (resource == null) { return null; } IWorkbenchPage page = getPart().getSite().getPage(); for (int i = 0; i < references.length; i++) { IEditorReference reference = references[i]; try { if (resource.equals(reference.getEditorInput().getAdapter(IFile.class))) { IEditorPart editor = reference.getEditor(false); if (editor instanceof ITextEditorExtension4) { return (ITextEditorExtension4) editor; } // editor opened is not a text editor - reopen file using // the // defualt text editor IEditorPart part = page.openEditor(new FileEditorInput((IFile) resource), DEFAULT_TEXT_EDITOR_ID, true, IWorkbenchPage.MATCH_NONE); if (part instanceof ITextEditorExtension4) { return (ITextEditorExtension4) part; } } } catch (PartInitException e) { MercurialEclipsePlugin.logError(e); } } // no existing editor references found, try to open a new editor for the // file try { IEditorDescriptor descrptr = IDE.getEditorDescriptor((IFile) resource); // try to open the associated editor only if its an internal // editor if (descrptr.isInternal()) { IEditorPart part = ResourceUtils.openEditor(page, (IFile) resource); if (part instanceof ITextEditorExtension4) { return (ITextEditorExtension4) part; } // editor opened is not a text editor - close it // NB: editor should not be closed as it could be opened by user before // page.closeEditor(part, false); } // open file in default text editor IEditorPart part = IDE.openEditor(page, (IFile) resource, DEFAULT_TEXT_EDITOR_ID); if (part instanceof ITextEditorExtension4) { return (ITextEditorExtension4) part; } } catch (PartInitException e) { MercurialEclipsePlugin.logError(e); } return null; } private RevisionInformation createRevisionInformation(final AnnotateBlocks annotateBlocks, IProgressMonitor monitor) { RevisionInformation info = new RevisionInformation(); final class AnnotationControlCreator implements IInformationControlCreator { private final String statusFieldText; public AnnotationControlCreator(String statusFieldText) { this.statusFieldText = statusFieldText; } public IInformationControl createInformationControl(Shell parent) { return new SourceViewerInformationControl(parent, SWT.TOOL, SWT.NONE, JFaceResources.DEFAULT_FONT, statusFieldText); } } info.setHoverControlCreator( new AnnotationControlCreator(Messages.getString("ShowAnnotationOperation.pressF2ForFocus"))); //$NON-NLS-1$ info.setInformationPresenterControlCreator(new AnnotationControlCreator(null)); final CommitterColors colors = CommitterColors.getDefault(); HashMap<String, Revision> sets = new HashMap<String, Revision>(); for (final AnnotateBlock block : annotateBlocks.getAnnotateBlocks()) { ChangeSet logEntry = block.getChangeSet(); Revision revision = sets.get(logEntry.getNode()); if (revision == null) { revision = new MercurialRevision(colors, logEntry, block); sets.put(logEntry.getNode(), revision); info.addRevision(revision); } revision.addRange(new LineRange(block.getStartLine(), block.getEndLine() - block.getStartLine() + 1)); } return info; } }