| /******************************************************************************* |
| * Copyright (c) 2006, 2011 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.team.internal.ui.history; |
| |
| import java.io.InputStream; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.*; |
| |
| import org.eclipse.compare.CompareConfiguration; |
| import org.eclipse.compare.ITypedElement; |
| import org.eclipse.compare.structuremergeviewer.DiffNode; |
| import org.eclipse.compare.structuremergeviewer.ICompareInput; |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.jface.action.*; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.util.OpenStrategy; |
| import org.eclipse.jface.viewers.*; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.*; |
| import org.eclipse.team.core.TeamException; |
| import org.eclipse.team.core.TeamStatus; |
| import org.eclipse.team.core.history.IFileHistory; |
| import org.eclipse.team.core.history.IFileRevision; |
| import org.eclipse.team.internal.core.history.LocalFileHistory; |
| import org.eclipse.team.internal.core.history.LocalFileRevision; |
| import org.eclipse.team.internal.ui.*; |
| import org.eclipse.team.internal.ui.actions.*; |
| import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement; |
| import org.eclipse.team.ui.history.*; |
| import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput; |
| import org.eclipse.ui.*; |
| import org.eclipse.ui.part.IPageSite; |
| import org.eclipse.ui.progress.IProgressConstants; |
| |
| import com.ibm.icu.text.SimpleDateFormat; |
| import com.ibm.icu.util.Calendar; |
| |
| public class LocalHistoryPage extends HistoryPage implements IHistoryCompareAdapter { |
| |
| public static final int ON = 1; |
| public static final int OFF = 2; |
| public static final int ALWAYS = 4; |
| |
| /* private */ IFile file; |
| /* private */ IFileRevision currentFileRevision; |
| |
| // cached for efficiency |
| /* private */ LocalFileHistory localFileHistory; |
| |
| /* private */ TreeViewer treeViewer; |
| |
| /* private */boolean shutdown = false; |
| |
| //grouping on |
| private boolean groupingOn = true; |
| |
| //toggle constants for default click action |
| private int compareMode = OFF; |
| |
| protected LocalFileHistoryTableProvider historyTableProvider; |
| private RefreshFileHistory refreshFileHistoryJob; |
| private Composite localComposite; |
| private Action groupByDateMode; |
| private Action collapseAll; |
| private Action compareModeAction; |
| private Action getContentsAction; |
| private CompareRevisionAction compareAction; |
| private OpenRevisionAction openAction; |
| private OpenWithMenu openWithMenu; |
| |
| private HistoryResourceListener resourceListener; |
| |
| private IFileRevision currentSelection; |
| |
| private final class LocalHistoryContentProvider implements ITreeContentProvider { |
| public Object[] getElements(Object inputElement) { |
| if (inputElement instanceof IFileHistory) { |
| // The entries of already been fetch so return them |
| IFileHistory fileHistory = (IFileHistory) inputElement; |
| return fileHistory.getFileRevisions(); |
| } |
| if (inputElement instanceof IFileRevision[]) { |
| return (IFileRevision[]) inputElement; |
| } |
| if (inputElement instanceof AbstractHistoryCategory[]){ |
| return (AbstractHistoryCategory[]) inputElement; |
| } |
| return new Object[0]; |
| } |
| |
| public void dispose() { |
| // Nothing to do |
| } |
| |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| // Nothing to do |
| } |
| |
| public Object[] getChildren(Object parentElement) { |
| if (parentElement instanceof AbstractHistoryCategory){ |
| return ((AbstractHistoryCategory) parentElement).getRevisions(); |
| } |
| |
| return new Object[0]; |
| } |
| |
| public Object getParent(Object element) { |
| return null; |
| } |
| |
| public boolean hasChildren(Object element) { |
| if (element instanceof AbstractHistoryCategory){ |
| return ((AbstractHistoryCategory) element).hasRevisions(); |
| } |
| return false; |
| } |
| } |
| |
| private class LocalFileHistoryTableProvider extends LocalHistoryTableProvider { |
| protected IFileRevision adaptToFileRevision(Object element) { |
| // Get the log entry for the provided object |
| IFileRevision entry = null; |
| if (element instanceof IFileRevision) { |
| entry = (IFileRevision) element; |
| } else if (element instanceof IAdaptable) { |
| entry = (IFileRevision) ((IAdaptable) element).getAdapter(IFileRevision.class); |
| } else if (element instanceof AbstractHistoryCategory){ |
| IFileRevision[] revisions = ((AbstractHistoryCategory) element).getRevisions(); |
| if (revisions.length > 0) |
| entry = revisions[0]; |
| } |
| return entry; |
| } |
| private long getCurrentRevision() { |
| if (file != null) { |
| return file.getLocalTimeStamp(); |
| } |
| return -1; |
| } |
| |
| protected long getModificationDate(Object element) { |
| IFileRevision entry = adaptToFileRevision(element); |
| if (entry != null) |
| return entry.getTimestamp(); |
| return -1; |
| } |
| |
| protected boolean isCurrentEdition(Object element) { |
| IFileRevision entry = adaptToFileRevision(element); |
| if (entry == null) |
| return false; |
| long timestamp = entry.getTimestamp(); |
| long tempCurrentTimeStamp = getCurrentRevision(); |
| return (tempCurrentTimeStamp != -1 && tempCurrentTimeStamp==timestamp); |
| } |
| |
| protected boolean isDeletedEdition(Object element) { |
| IFileRevision entry = adaptToFileRevision(element); |
| return (!entry.exists()); |
| } |
| } |
| |
| private class RefreshFileHistory extends Job { |
| public RefreshFileHistory() { |
| super(TeamUIMessages.LocalHistoryPage_FetchLocalHistoryMessage); |
| } |
| public IStatus run(IProgressMonitor monitor) { |
| try { |
| IStatus status = Status.OK_STATUS; |
| // Assign the instance variable to a local so it does not get cleared well we are refreshing |
| LocalFileHistory fileHistory = localFileHistory; |
| if (fileHistory == null || shutdown) |
| return status; |
| try { |
| fileHistory.refresh(Policy.subMonitorFor(monitor, 50)); |
| } catch (CoreException ex) { |
| status = new TeamStatus(ex.getStatus().getSeverity(), TeamUIPlugin.ID, ex.getStatus().getCode(), ex.getMessage(), ex, file); |
| } |
| |
| update(fileHistory.getFileRevisions(), Policy.subMonitorFor(monitor, 50)); |
| |
| if (status != Status.OK_STATUS ) { |
| this.setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE); |
| this.setProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY, Boolean.TRUE); |
| } |
| |
| if (Policy.DEBUG_HISTORY) { |
| String time = new SimpleDateFormat("m:ss.SSS").format(new Date(System.currentTimeMillis())); //$NON-NLS-1$ |
| System.out.println(time + ": RefreshFileHistoryJob#run finished, status: " + status); //$NON-NLS-1$ |
| } |
| |
| return status; |
| } finally { |
| monitor.done(); |
| } |
| } |
| } |
| |
| private class HistoryResourceListener implements IResourceChangeListener { |
| public void resourceChanged(IResourceChangeEvent event) { |
| IResourceDelta root = event.getDelta(); |
| |
| if (file == null) |
| return; |
| |
| IResourceDelta resourceDelta = root.findMember(file.getFullPath()); |
| if (resourceDelta != null){ |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| refresh(); |
| } |
| }); |
| } |
| } |
| } |
| |
| public LocalHistoryPage(int compareMode) { |
| super(); |
| this.compareMode = compareMode; |
| } |
| |
| public LocalHistoryPage() { |
| super(); |
| } |
| |
| public boolean inputSet() { |
| currentFileRevision = null; |
| IFile tempFile = getFile(); |
| this.file = tempFile; |
| if (tempFile == null) |
| return false; |
| |
| //blank current input only after we're sure that we have a file |
| //to fetch history for |
| this.treeViewer.setInput(null); |
| |
| localFileHistory = new LocalFileHistory(file, !getHistoryPageSite().isModal()); |
| |
| if (refreshFileHistoryJob == null) |
| refreshFileHistoryJob = new RefreshFileHistory(); |
| |
| //always refresh the history if the input gets set |
| refreshHistory(true); |
| return true; |
| } |
| |
| protected IFile getFile() { |
| return LocalHistoryPageSource.getFile(getInput()); |
| } |
| |
| private void refreshHistory(boolean refetch) { |
| if (Policy.DEBUG_HISTORY) { |
| String time = new SimpleDateFormat("m:ss.SSS").format(new Date(System.currentTimeMillis())); //$NON-NLS-1$ |
| System.out.println(time + ": LocalHistoryPage#refreshHistory, refetch = " + refetch); //$NON-NLS-1$ |
| } |
| |
| if (refreshFileHistoryJob.getState() != Job.NONE){ |
| refreshFileHistoryJob.cancel(); |
| } |
| IHistoryPageSite parentSite = getHistoryPageSite(); |
| Utils.schedule(refreshFileHistoryJob, getWorkbenchSite(parentSite)); |
| } |
| |
| private IWorkbenchPartSite getWorkbenchSite(IHistoryPageSite parentSite) { |
| IWorkbenchPart part = parentSite.getPart(); |
| if (part != null) |
| return part.getSite(); |
| return null; |
| } |
| |
| public void createControl(Composite parent) { |
| |
| localComposite = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| localComposite.setLayout(layout); |
| GridData data = new GridData(GridData.FILL_BOTH); |
| data.grabExcessVerticalSpace = true; |
| localComposite.setLayoutData(data); |
| |
| treeViewer = createTree(localComposite); |
| |
| contributeActions(); |
| |
| IHistoryPageSite parentSite = getHistoryPageSite(); |
| if (parentSite != null && parentSite instanceof DialogHistoryPageSite && treeViewer != null) |
| parentSite.setSelectionProvider(treeViewer); |
| |
| resourceListener = new HistoryResourceListener(); |
| ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceListener, IResourceChangeEvent.POST_CHANGE); |
| |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(localComposite, IHelpContextIds.LOCAL_HISTORY_PAGE); |
| } |
| |
| private void contributeActions() { |
| final IPreferenceStore store = TeamUIPlugin.getPlugin().getPreferenceStore(); |
| //Group by Date |
| groupByDateMode = new Action(TeamUIMessages.LocalHistoryPage_GroupRevisionsByDateAction, TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_DATES_CATEGORY)){ |
| public void run() { |
| groupingOn = !groupingOn; |
| store.setValue(IPreferenceIds.PREF_GROUPBYDATE_MODE, groupingOn); |
| refreshHistory(false); |
| } |
| }; |
| groupingOn = store.getBoolean(IPreferenceIds.PREF_GROUPBYDATE_MODE); |
| groupByDateMode.setChecked(groupingOn); |
| groupByDateMode.setToolTipText(TeamUIMessages.LocalHistoryPage_GroupRevisionsByDateTip); |
| groupByDateMode.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_DATES_CATEGORY)); |
| groupByDateMode.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_DATES_CATEGORY)); |
| |
| //Collapse All |
| collapseAll = new Action(TeamUIMessages.LocalHistoryPage_CollapseAllAction, TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_COLLAPSE_ALL)) { |
| public void run() { |
| treeViewer.collapseAll(); |
| } |
| }; |
| collapseAll.setToolTipText(TeamUIMessages.LocalHistoryPage_CollapseAllTip); |
| collapseAll.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_COLLAPSE_ALL)); |
| collapseAll.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_COLLAPSE_ALL)); |
| |
| IHistoryPageSite historyPageSite = getHistoryPageSite(); |
| if (!historyPageSite.isModal()) { |
| //Compare Mode Action |
| if ((compareMode & ALWAYS) == 0) { |
| compareModeAction = new Action(TeamUIMessages.LocalHistoryPage_CompareModeAction,TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_COMPARE_VIEW)) { |
| public void run() { |
| // switch the mode |
| compareMode = compareMode == ON ? OFF : ON; |
| compareModeAction.setChecked(compareMode == ON); |
| } |
| }; |
| compareModeAction.setToolTipText(TeamUIMessages.LocalHistoryPage_CompareModeTip); |
| compareModeAction.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_COMPARE_VIEW)); |
| compareModeAction.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_COMPARE_VIEW)); |
| compareModeAction.setChecked(compareMode == ON); |
| |
| getContentsAction = getContextMenuAction(TeamUIMessages.LocalHistoryPage_GetContents, true /* needs progress */, new IWorkspaceRunnable() { |
| public void run(IProgressMonitor monitor) throws CoreException { |
| monitor.beginTask(null, 100); |
| try { |
| if(confirmOverwrite()) { |
| IStorage currentStorage = currentSelection.getStorage(new SubProgressMonitor(monitor, 50)); |
| InputStream in = currentStorage.getContents(); |
| (file).setContents(in, false, true, new SubProgressMonitor(monitor, 50)); |
| } |
| } catch (TeamException e) { |
| throw new CoreException(e.getStatus()); |
| } finally { |
| monitor.done(); |
| } |
| } |
| }); |
| } |
| |
| //TODO: Doc help |
| //PlatformUI.getWorkbench().getHelpSystem().setHelp(getContentsAction, ); |
| |
| // Click Compare action |
| compareAction = createCompareAction(); |
| compareAction.setEnabled(!treeViewer.getSelection().isEmpty()); |
| treeViewer.getTree().addSelectionListener(new SelectionAdapter(){ |
| public void widgetSelected(SelectionEvent e) { |
| compareAction.setCurrentFileRevision(getCurrentFileRevision()); |
| compareAction.selectionChanged((IStructuredSelection) treeViewer.getSelection()); |
| } |
| }); |
| |
| // Only add the open action if compare mode is not always on |
| if (!((compareMode & (ALWAYS | ON)) == (ALWAYS | ON))) { |
| openAction = new OpenRevisionAction(TeamUIMessages.LocalHistoryPage_OpenAction, this); |
| openAction.setEnabled(!treeViewer.getSelection().isEmpty()); |
| treeViewer.getTree().addSelectionListener(new SelectionAdapter(){ |
| public void widgetSelected(SelectionEvent e) { |
| openAction.selectionChanged((IStructuredSelection) treeViewer.getSelection()); |
| } |
| }); |
| |
| // Add 'Open With...' sub-menu |
| openWithMenu = new OpenWithMenu(this); |
| treeViewer.getTree().addSelectionListener(new SelectionAdapter(){ |
| public void widgetSelected(SelectionEvent e) { |
| openWithMenu.selectionChanged((IStructuredSelection) treeViewer.getSelection()); |
| } |
| }); |
| } |
| |
| new OpenAndLinkWithEditorHelper(treeViewer) { |
| protected void open(ISelection selection, boolean activate) { |
| if (getSite() != null && selection instanceof IStructuredSelection) { |
| IStructuredSelection structuredSelection= (IStructuredSelection)selection; |
| if ((compareMode & ON) > 0){ |
| StructuredSelection sel= new StructuredSelection(new Object[] { getCurrentFileRevision(), structuredSelection.getFirstElement() }); |
| compareAction.selectionChanged(sel); |
| compareAction.run(); |
| } else { |
| //Pass in the entire structured selection to allow for multiple editor openings |
| if (openAction != null) { |
| openAction.selectionChanged(structuredSelection); |
| openAction.run(); |
| } |
| } |
| } |
| } |
| |
| protected void activate(ISelection selection) { |
| int currentMode= OpenStrategy.getOpenMethod(); |
| try { |
| OpenStrategy.setOpenMethod(OpenStrategy.DOUBLE_CLICK); |
| open(selection, true); |
| } finally { |
| OpenStrategy.setOpenMethod(currentMode); |
| } |
| } |
| |
| protected void linkToEditor(ISelection selection) { |
| // XXX: Not yet implemented, see http://bugs.eclipse.org/324185 |
| } |
| }; |
| |
| //Contribute actions to popup menu |
| MenuManager menuMgr = new MenuManager(); |
| Menu menu = menuMgr.createContextMenu(treeViewer.getTree()); |
| menuMgr.addMenuListener(new IMenuListener() { |
| public void menuAboutToShow(IMenuManager menuMgr) { |
| fillTableMenu(menuMgr); |
| } |
| }); |
| menuMgr.setRemoveAllWhenShown(true); |
| treeViewer.getTree().setMenu(menu); |
| |
| //Don't add the object contribution menu items if this page is hosted in a dialog |
| IWorkbenchPart part = historyPageSite.getPart(); |
| if (part != null) { |
| IWorkbenchPartSite workbenchPartSite = part.getSite(); |
| workbenchPartSite.registerContextMenu(menuMgr, treeViewer); |
| } |
| IPageSite pageSite = historyPageSite.getWorkbenchPageSite(); |
| if (pageSite != null) { |
| IActionBars actionBars = pageSite.getActionBars(); |
| // Contribute toggle text visible to the toolbar drop-down |
| IMenuManager actionBarsMenu = actionBars.getMenuManager(); |
| if (actionBarsMenu != null){ |
| actionBarsMenu.removeAll(); |
| } |
| actionBars.updateActionBars(); |
| } |
| } |
| |
| //Create the local tool bar |
| IToolBarManager tbm = historyPageSite.getToolBarManager(); |
| if (tbm != null) { |
| String fileNameQualifier = getFileNameQualifier(); |
| //Add groups |
| tbm.add(new Separator(fileNameQualifier+"grouping")); //$NON-NLS-1$ |
| tbm.appendToGroup(fileNameQualifier+"grouping", groupByDateMode); //$NON-NLS-1$ |
| tbm.add(new Separator(fileNameQualifier+"collapse")); //$NON-NLS-1$ |
| tbm.appendToGroup(fileNameQualifier+"collapse", collapseAll); //$NON-NLS-1$ |
| if (compareModeAction != null) |
| tbm.appendToGroup(fileNameQualifier+"collapse", compareModeAction); //$NON-NLS-1$ |
| tbm.update(false); |
| } |
| |
| } |
| |
| protected CompareRevisionAction createCompareAction() { |
| return new CompareRevisionAction(this); |
| } |
| |
| private String getFileNameQualifier() { |
| if (file != null) |
| return file.getFullPath().toString(); |
| |
| return ""; //$NON-NLS-1$ |
| } |
| |
| protected void fillTableMenu(IMenuManager manager) { |
| // file actions go first (view file) |
| IHistoryPageSite parentSite = getHistoryPageSite(); |
| manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
| |
| if (file != null && !parentSite.isModal()){ |
| if (openAction != null) |
| manager.add(openAction); |
| if (openWithMenu != null) { |
| MenuManager openWithSubmenu = new MenuManager( |
| TeamUIMessages.LocalHistoryPage_OpenWithMenu); |
| openWithSubmenu.add(openWithMenu); |
| manager.add(openWithSubmenu); |
| } |
| if (compareAction != null) |
| manager.add(compareAction); |
| if (getContentsAction != null) { |
| ISelection sel = treeViewer.getSelection(); |
| if (!sel.isEmpty()) { |
| if (sel instanceof IStructuredSelection) { |
| IStructuredSelection tempSelection = (IStructuredSelection) sel; |
| if (tempSelection.size() == 1) { |
| manager.add(new Separator("getContents")); //$NON-NLS-1$ |
| manager.add(getContentsAction); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Creates the tree that displays the local file revisions |
| * |
| * @param parent the parent composite to contain the group |
| * @return the group control |
| */ |
| protected TreeViewer createTree(Composite parent) { |
| historyTableProvider = new LocalFileHistoryTableProvider(); |
| TreeViewer viewer = historyTableProvider.createTree(parent); |
| viewer.setContentProvider(new LocalHistoryContentProvider()); |
| return viewer; |
| } |
| |
| public Control getControl() { |
| return localComposite; |
| } |
| |
| public void setFocus() { |
| localComposite.setFocus(); |
| } |
| |
| public String getDescription() { |
| if (getFile() != null) |
| return getFile().getFullPath().toString(); |
| return null; |
| } |
| |
| public String getName() { |
| if (getFile() != null) |
| return getFile().getName(); |
| return ""; //$NON-NLS-1$ |
| } |
| |
| public boolean isValidInput(Object object) { |
| return object instanceof IFile; |
| } |
| |
| public void refresh() { |
| refreshHistory(true); |
| } |
| |
| public Object getAdapter(Class adapter) { |
| if(adapter == IHistoryCompareAdapter.class) { |
| return this; |
| } |
| return null; |
| } |
| |
| public void dispose() { |
| shutdown = true; |
| |
| if (resourceListener != null){ |
| ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceListener); |
| resourceListener = null; |
| } |
| |
| //Cancel any incoming |
| if (refreshFileHistoryJob != null) { |
| if (refreshFileHistoryJob.getState() != Job.NONE) { |
| refreshFileHistoryJob.cancel(); |
| } |
| } |
| } |
| |
| public IFileRevision getCurrentFileRevision() { |
| if (currentFileRevision != null) |
| return currentFileRevision; |
| |
| if (file != null) |
| currentFileRevision = new LocalFileRevision(file); |
| |
| return currentFileRevision; |
| } |
| |
| private Action getContextMenuAction(String title, final boolean needsProgressDialog, final IWorkspaceRunnable action) { |
| return new Action(title) { |
| public void run() { |
| try { |
| if (file == null) return; |
| ISelection selection = treeViewer.getSelection(); |
| if (!(selection instanceof IStructuredSelection)) return; |
| IStructuredSelection ss = (IStructuredSelection)selection; |
| Object o = ss.getFirstElement(); |
| |
| if (o instanceof AbstractHistoryCategory) |
| return; |
| |
| currentSelection = (IFileRevision)o; |
| if(needsProgressDialog) { |
| PlatformUI.getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() { |
| public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| try { |
| action.run(monitor); |
| } catch (CoreException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| }); |
| } else { |
| try { |
| action.run(null); |
| } catch (CoreException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| } catch (InvocationTargetException e) { |
| IHistoryPageSite parentSite = getHistoryPageSite(); |
| Utils.handleError(parentSite.getShell(), e, null, null); |
| } catch (InterruptedException e) { |
| // Do nothing |
| } |
| } |
| |
| public boolean isEnabled() { |
| ISelection selection = treeViewer.getSelection(); |
| if (!(selection instanceof IStructuredSelection)) return false; |
| IStructuredSelection ss = (IStructuredSelection)selection; |
| if(ss.size() != 1) return false; |
| return true; |
| } |
| }; |
| } |
| |
| private boolean confirmOverwrite() { |
| if (file != null && file.exists()) { |
| String title = TeamUIMessages.LocalHistoryPage_OverwriteTitle; |
| String msg = TeamUIMessages.LocalHistoryPage_OverwriteMessage; |
| IHistoryPageSite parentSite = getHistoryPageSite(); |
| final MessageDialog dialog = new MessageDialog(parentSite.getShell(), title, null, msg, MessageDialog.QUESTION, new String[] {IDialogConstants.YES_LABEL, IDialogConstants.CANCEL_LABEL}, 0); |
| final int[] result = new int[1]; |
| parentSite.getShell().getDisplay().syncExec(new Runnable() { |
| public void run() { |
| result[0] = dialog.open(); |
| } |
| }); |
| if (result[0] != 0) { |
| // cancel |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| public void setClickAction(boolean compare) { |
| compareMode = compare ? ON : OFF; |
| if (compareModeAction != null) |
| compareModeAction.setChecked(compareMode == ON); |
| } |
| |
| public ICompareInput getCompareInput(Object object) { |
| if (object instanceof IFileRevision){ |
| IFileRevision selectedFileRevision = (IFileRevision)object; |
| ITypedElement fileElement = SaveableCompareEditorInput.createFileElement(file); |
| FileRevisionTypedElement right = new FileRevisionTypedElement(selectedFileRevision); |
| DiffNode node = new DiffNode(fileElement, right); |
| return node; |
| } |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.team.ui.history.IHistoryCompareAdapter#prepareInput(org.eclipse.compare.structuremergeviewer.ICompareInput, org.eclipse.compare.CompareConfiguration, org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) { |
| Object right = input.getRight(); |
| if (right != null) { |
| String label = getLabel(right); |
| if (label != null) |
| configuration.setRightLabel(label); |
| Image image = getImage(right); |
| if (image != null) |
| configuration.setRightImage(image); |
| } |
| Object left = input.getLeft(); |
| if (left != null) { |
| String label = getLabel(left); |
| if (label != null) |
| configuration.setLeftLabel(label); |
| Image image = getImage(left); |
| if (image != null) |
| configuration.setLeftImage(image); |
| } |
| } |
| |
| protected Image getImage(Object right) { |
| if (right instanceof FileRevisionTypedElement || right instanceof LocalFileRevision || right instanceof IFileRevision) { |
| return historyTableProvider.getRevisionImage(); |
| } |
| if (right instanceof ITypedElement) { |
| ITypedElement te = (ITypedElement) right; |
| return te.getImage(); |
| } |
| return null; |
| } |
| |
| protected String getLabel(Object object) { |
| if (object instanceof IFileRevision) { |
| IFileRevision revision = (IFileRevision) object; |
| long timestamp = revision.getTimestamp(); |
| if (timestamp > 0) |
| return NLS.bind(TeamUIMessages.LocalHistoryPage_0, historyTableProvider.getDateFormat().format(new Date(timestamp))); |
| } |
| if (object instanceof FileRevisionTypedElement) { |
| FileRevisionTypedElement e = (FileRevisionTypedElement) object; |
| return getLabel(e.getRevision()); |
| } |
| if (object instanceof LocalResourceTypedElement) { |
| return TeamUIMessages.LocalHistoryPage_1; |
| } |
| return null; |
| } |
| |
| /** |
| * Method invoked from a background thread to update the viewer with the given revisions. |
| * @param revisions the revisions for the file |
| * @param monitor a progress monitor |
| */ |
| protected void update(final IFileRevision[] revisions, IProgressMonitor monitor) { |
| // Group the revisions (if appropriate) before running in the UI thread |
| final AbstractHistoryCategory[] categories = groupRevisions(revisions, monitor); |
| // Update the tree in the UI thread |
| Utils.asyncExec(new Runnable() { |
| public void run() { |
| if (Policy.DEBUG_HISTORY) { |
| String time = new SimpleDateFormat("m:ss.SSS").format(new Date(System.currentTimeMillis())); //$NON-NLS-1$ |
| System.out.println(time + ": LocalHistoryPage#update, the tree is being updated in the UI thread"); //$NON-NLS-1$ |
| } |
| if (categories != null) { |
| Object[] elementsToExpand = mapExpandedElements(categories, treeViewer.getExpandedElements()); |
| treeViewer.getTree().setRedraw(false); |
| treeViewer.setInput(categories); |
| //if user is switching modes and already has expanded elements |
| //selected try to expand those, else expand all |
| if (elementsToExpand.length > 0) |
| treeViewer.setExpandedElements(elementsToExpand); |
| else { |
| treeViewer.expandAll(); |
| Object[] el = treeViewer.getExpandedElements(); |
| if (el != null && el.length > 0) { |
| treeViewer.setSelection(new StructuredSelection(el[0])); |
| treeViewer.getTree().deselectAll(); |
| } |
| } |
| treeViewer.getTree().setRedraw(true); |
| } else { |
| if (revisions.length > 0) { |
| treeViewer.setInput(revisions); |
| } else { |
| treeViewer.setInput(new AbstractHistoryCategory[] {getErrorMessage()}); |
| } |
| } |
| } |
| }, treeViewer); |
| } |
| |
| private AbstractHistoryCategory[] groupRevisions(IFileRevision[] revisions, IProgressMonitor monitor) { |
| if (groupingOn) |
| return sortRevisions(revisions, monitor); |
| return null; |
| } |
| |
| private Object[] mapExpandedElements(AbstractHistoryCategory[] categories, Object[] expandedElements) { |
| //store the names of the currently expanded categories in a map |
| HashMap elementMap = new HashMap(); |
| for (int i=0; i<expandedElements.length; i++){ |
| elementMap.put(((DateHistoryCategory)expandedElements[i]).getName(), null); |
| } |
| |
| //Go through the new categories and keep track of the previously expanded ones |
| ArrayList expandable = new ArrayList(); |
| for (int i = 0; i<categories.length; i++){ |
| //check to see if this category is currently expanded |
| if (elementMap.containsKey(categories[i].getName())){ |
| expandable.add(categories[i]); |
| } |
| } |
| return expandable.toArray(new Object[expandable.size()]); |
| } |
| |
| private AbstractHistoryCategory[] sortRevisions(IFileRevision[] revisions, IProgressMonitor monitor) { |
| |
| try { |
| monitor.beginTask(null, 100); |
| //Create the 4 categories |
| DateHistoryCategory[] tempCategories = new DateHistoryCategory[4]; |
| //Get a calendar instance initialized to the current time |
| Calendar currentCal = Calendar.getInstance(); |
| tempCategories[0] = new DateHistoryCategory(TeamUIMessages.HistoryPage_Today, currentCal, null); |
| //Get yesterday |
| Calendar yesterdayCal = Calendar.getInstance(); |
| yesterdayCal.roll(Calendar.DAY_OF_YEAR, -1); |
| tempCategories[1] = new DateHistoryCategory(TeamUIMessages.HistoryPage_Yesterday, yesterdayCal, null); |
| //Get this month |
| Calendar monthCal = Calendar.getInstance(); |
| monthCal.set(Calendar.DAY_OF_MONTH, 1); |
| tempCategories[2] = new DateHistoryCategory(TeamUIMessages.HistoryPage_ThisMonth, monthCal, yesterdayCal); |
| //Everything before after week is previous |
| tempCategories[3] = new DateHistoryCategory(TeamUIMessages.HistoryPage_Previous, null, monthCal); |
| |
| ArrayList finalCategories = new ArrayList(); |
| for (int i = 0; i<tempCategories.length; i++){ |
| tempCategories[i].collectFileRevisions(revisions, false); |
| if (tempCategories[i].hasRevisions()) |
| finalCategories.add(tempCategories[i]); |
| } |
| |
| if (finalCategories.size() == 0){ |
| //no revisions found for the current mode, so add a message category |
| finalCategories.add(getErrorMessage()); |
| } |
| |
| return (AbstractHistoryCategory[])finalCategories.toArray(new AbstractHistoryCategory[finalCategories.size()]); |
| } finally { |
| monitor.done(); |
| } |
| } |
| |
| private MessageHistoryCategory getErrorMessage(){ |
| MessageHistoryCategory messageCategory = new MessageHistoryCategory(getNoChangesMessage()); |
| return messageCategory; |
| } |
| |
| protected String getNoChangesMessage() { |
| return TeamUIMessages.LocalHistoryPage_NoRevisionsFound; |
| } |
| } |