1 13 14 package org.eclipse.team.internal.ccvs.ui; 15 16 import java.io.InputStream ; 17 import java.lang.reflect.InvocationTargetException ; 18 import java.util.*; 19 20 import org.eclipse.compare.*; 21 import org.eclipse.compare.structuremergeviewer.DiffNode; 22 import org.eclipse.compare.structuremergeviewer.ICompareInput; 23 import org.eclipse.core.resources.*; 24 import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; 25 import org.eclipse.core.resources.mapping.ResourceChangeValidator; 26 import org.eclipse.core.runtime.*; 27 import org.eclipse.core.runtime.jobs.Job; 28 import org.eclipse.jface.action.*; 29 import org.eclipse.jface.dialogs.IDialogConstants; 30 import org.eclipse.jface.dialogs.MessageDialog; 31 import org.eclipse.jface.operation.IRunnableWithProgress; 32 import org.eclipse.jface.preference.IPreferenceStore; 33 import org.eclipse.jface.text.*; 34 import org.eclipse.jface.text.revisions.Revision; 35 import org.eclipse.jface.text.source.*; 36 import org.eclipse.jface.util.IOpenEventListener; 37 import org.eclipse.jface.util.OpenStrategy; 38 import org.eclipse.jface.viewers.*; 39 import org.eclipse.osgi.util.NLS; 40 import org.eclipse.swt.SWT; 41 import org.eclipse.swt.custom.SashForm; 42 import org.eclipse.swt.custom.StyledText; 43 import org.eclipse.swt.events.*; 44 import org.eclipse.swt.graphics.Image; 45 import org.eclipse.swt.layout.GridData; 46 import org.eclipse.swt.widgets.*; 47 import org.eclipse.team.core.RepositoryProvider; 48 import org.eclipse.team.core.TeamException; 49 import org.eclipse.team.core.history.*; 50 import org.eclipse.team.core.variants.IResourceVariant; 51 import org.eclipse.team.internal.ccvs.core.*; 52 import org.eclipse.team.internal.ccvs.core.client.Command; 53 import org.eclipse.team.internal.ccvs.core.client.Update; 54 import org.eclipse.team.internal.ccvs.core.filehistory.*; 55 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; 56 import org.eclipse.team.internal.ccvs.core.resources.RemoteFile; 57 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; 58 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; 59 import org.eclipse.team.internal.ccvs.ui.actions.CVSAction; 60 import org.eclipse.team.internal.ccvs.ui.actions.MoveRemoteTagAction; 61 import org.eclipse.team.internal.ccvs.ui.operations.*; 62 import org.eclipse.team.internal.core.history.LocalFileRevision; 63 import org.eclipse.team.internal.ui.TeamUIMessages; 64 import org.eclipse.team.internal.ui.Utils; 65 import org.eclipse.team.internal.ui.actions.CompareRevisionAction; 66 import org.eclipse.team.internal.ui.actions.OpenRevisionAction; 67 import org.eclipse.team.internal.ui.history.*; 68 import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement; 69 import org.eclipse.team.ui.history.*; 70 import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput; 71 import org.eclipse.ui.*; 72 import org.eclipse.ui.editors.text.EditorsUI; 73 import org.eclipse.ui.editors.text.TextSourceViewerConfiguration; 74 import org.eclipse.ui.ide.IDE; 75 import org.eclipse.ui.part.IPageSite; 76 import org.eclipse.ui.progress.IProgressConstants; 77 import org.eclipse.ui.texteditor.*; 78 79 import com.ibm.icu.text.DateFormat; 80 import com.ibm.icu.util.Calendar; 81 82 public class CVSHistoryPage extends HistoryPage implements IAdaptable, IHistoryCompareAdapter { 83 84 ICVSFile file; 85 ICVSFile previousFile; 86 IFileRevision currentFileRevision; 87 private ITypedElement fileElement; 88 89 CVSFileHistory cvsFileHistory; 91 IFileRevision[] entries; 92 93 CVSHistoryTableProvider historyTableProvider; 94 95 TreeViewer treeViewer; 96 TextViewer textViewer; 97 TableViewer tagViewer; 98 99 CompareRevisionAction compareAction; 100 OpenRevisionAction openAction; 101 102 private CVSHistoryFilterAction cvsHistoryFilter; 103 private IAction toggleTextAction; 104 private IAction toggleTextWrapAction; 105 private IAction toggleListAction; 106 private IAction toggleFilterAction; 107 private IAction toggleSearchAction; 108 private TextViewerAction copyAction; 109 private TextViewerAction selectAllAction; 110 private Action getContentsAction; 111 private Action getRevisionAction; 112 private Action refreshAction; 113 114 private Action tagWithExistingAction; 115 private Action localMode; 116 private Action remoteMode; 117 private Action remoteLocalMode; 118 private Action groupByDateMode; 119 private Action collapseAll; 120 private Action compareModeAction; 121 122 private SashForm sashForm; 123 private SashForm innerSashForm; 124 private SashForm searchSashForm; 125 126 private Image branchImage; 127 private Image versionImage; 128 129 protected IFileRevision currentSelection; 130 131 RefreshCVSFileHistory refreshCVSFileHistoryJob; 132 133 boolean shutdown = false; 134 135 boolean localFilteredOut = false; 136 boolean remoteFilteredOut = false; 137 138 private HistoryResourceListener resourceListener; 139 140 private boolean compareMode = false; 142 143 public final static int REMOTE_LOCAL_MODE = 0; 145 public final static int REMOTE_MODE = 1; 146 public final static int LOCAL_MODE = 2; 147 148 private int currentFilerMode = 0; 150 151 private Text searchField; 153 154 private boolean groupingOn; 156 private CVSHistoryFilter historyFilter; 157 private CVSHistorySearchFilter searchFilter; 158 private RevisionAnnotationController rulerSelectionListener; 159 160 private int refreshRequest = 0; 161 private DateFormat dateTimeFormat; 162 private String description; 163 164 public CVSHistoryPage(Object object) { 165 this.file = getCVSFile(object); 166 } 167 168 public void createControl(Composite parent) { 169 initializeImages(); 170 171 sashForm = new SashForm(parent, SWT.VERTICAL); 172 sashForm.setLayoutData(new GridData(GridData.FILL_BOTH)); 173 174 treeViewer = createTree(sashForm); 175 innerSashForm = new SashForm(sashForm, SWT.HORIZONTAL); 176 tagViewer = createTagTable(innerSashForm); 177 textViewer = createText(innerSashForm); 178 179 searchSashForm = new SashForm(sashForm, SWT.HORIZONTAL); 180 searchField = new Text(searchSashForm, SWT.SEARCH); 182 searchField.setText(CVSUIMessages.CVSHistoryPage_EnterSearchTerm); 183 final SearchHistoryTable searchHistoryTable = new SearchHistoryTable(); 184 searchField.addModifyListener(new ModifyListener() { 185 public void modifyText(ModifyEvent e){ 186 Display.getDefault().timerExec(1000, searchHistoryTable); 187 } 188 }); 189 190 sashForm.setWeights(new int[] {65, 20, 15}); 191 innerSashForm.setWeights(new int[] {50, 50}); 192 193 contributeActions(); 194 195 setViewerVisibility(); 196 197 IHistoryPageSite parentSite = getHistoryPageSite(); 198 if (parentSite != null && parentSite instanceof DialogHistoryPageSite && treeViewer != null) 199 parentSite.setSelectionProvider(treeViewer); 200 201 resourceListener = new HistoryResourceListener(); 202 ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceListener, IResourceChangeEvent.POST_CHANGE); 203 204 PlatformUI.getWorkbench().getHelpSystem().setHelp(sashForm, IHelpContextIds.RESOURCE_HISTORY_VIEW); 205 } 206 207 private TextViewer createText(SashForm parent) { 208 SourceViewer result = new SourceViewer(parent, null, null, true, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.READ_ONLY); 209 result.getTextWidget().setIndent(2); 210 result.configure(new TextSourceViewerConfiguration(EditorsUI.getPreferenceStore()) { 211 protected Map getHyperlinkDetectorTargets(ISourceViewer sourceViewer) { 212 return Collections.singletonMap("org.eclipse.ui.DefaultTextEditor", new IAdaptable() { 214 public Object getAdapter(Class adapter) { 215 if(adapter==IFile.class && getInput() instanceof IFile) { 216 return getInput(); 217 } else if(adapter==IFileHistory.class && getInput() instanceof IFileHistory) { 218 return getInput(); 219 } 220 return Platform.getAdapterManager().getAdapter(CVSHistoryPage.this, adapter); 221 } 222 }); 223 } 224 }); 225 226 result.addSelectionChangedListener(new ISelectionChangedListener() { 227 public void selectionChanged(SelectionChangedEvent event) { 228 copyAction.update(); 229 } 230 }); 231 result.setTextDoubleClickStrategy( 232 new DefaultTextDoubleClickStrategy(), 233 IDocument.DEFAULT_CONTENT_TYPE); 234 result.activatePlugins(); 235 return result; 236 } 237 238 private TableViewer createTagTable(SashForm parent) { 239 Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); 240 TableViewer result = new TableViewer(table); 241 TableLayout layout = new TableLayout(); 242 layout.addColumnData(new ColumnWeightData(100)); 243 table.setLayout(layout); 244 result.setContentProvider(new SimpleContentProvider() { 245 public Object [] getElements(Object inputElement) { 246 if (inputElement == null) 247 return new Object [0]; 248 ITag[] tags = (ITag[]) inputElement; 249 return tags; 250 } 251 }); 252 result.setLabelProvider(new LabelProvider() { 253 public Image getImage(Object element) { 254 if (element == null) 255 return null; 256 ITag tag = (ITag) element; 257 if (!(tag instanceof CVSTag)) 258 return null; 259 260 switch (((CVSTag)tag).getType()) { 261 case CVSTag.BRANCH: 262 case CVSTag.HEAD: 263 return branchImage; 264 case CVSTag.VERSION: 265 return versionImage; 266 } 267 return null; 268 } 269 270 public String getText(Object element) { 271 return ((ITag) element).getName(); 272 } 273 }); 274 result.setComparator(new ViewerComparator() { 275 public int compare(Viewer viewer, Object e1, Object e2) { 276 if (!(e1 instanceof ITag) || !(e2 instanceof ITag)) 277 return super.compare(viewer, e1, e2); 278 CVSTag tag1 = (CVSTag) e1; 279 CVSTag tag2 = (CVSTag) e2; 280 int type1 = tag1.getType(); 281 int type2 = tag2.getType(); 282 if (type1 != type2) { 283 return type2 - type1; 284 } 285 return super.compare(viewer, tag1, tag2); 286 } 287 }); 288 return result; 289 } 290 291 public void setFocus() { 292 sashForm.setFocus(); 293 if (refreshRequest != 0) { 294 refresh(refreshRequest); 295 refreshRequest = 0; 296 } 297 } 298 299 protected void contributeActions() { 300 CVSUIPlugin plugin = CVSUIPlugin.getPlugin(); 301 302 refreshAction = new Action(CVSUIMessages.HistoryView_refreshLabel, plugin.getImageDescriptor(ICVSUIConstants.IMG_REFRESH_ENABLED)) { 304 public void run() { 305 refresh(); 306 } 307 }; 308 refreshAction.setToolTipText(CVSUIMessages.HistoryView_refresh); 309 refreshAction.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_REFRESH_DISABLED)); 310 refreshAction.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_REFRESH)); 311 312 final IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); 314 localMode = new Action(CVSUIMessages.CVSHistoryPage_LocalModeAction, plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALMODE)) { 315 public void run() { 316 if (isChecked()){ 317 store.setValue(ICVSUIConstants.PREF_REVISION_MODE, LOCAL_MODE); 318 updateFilterMode(LOCAL_MODE); 319 } else 320 setChecked(true); 321 } 322 }; 323 localMode.setToolTipText(CVSUIMessages.CVSHistoryPage_LocalModeTooltip); 324 localMode.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALMODE_DISABLED)); 325 localMode.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALMODE)); 326 327 remoteMode = new Action(CVSUIMessages.CVSHistoryPage_RemoteModeAction, plugin.getImageDescriptor(ICVSUIConstants.IMG_REMOTEMODE)) { 329 public void run() { 330 if (isChecked()){ 331 store.setValue(ICVSUIConstants.PREF_REVISION_MODE, REMOTE_MODE); 332 updateFilterMode(REMOTE_MODE); 333 } else 334 setChecked(true); 335 } 336 }; 337 remoteMode.setToolTipText(CVSUIMessages.CVSHistoryPage_RemoteModeTooltip); 338 remoteMode.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_REMOTEMODE_DISABLED)); 339 remoteMode.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_REMOTEMODE)); 340 341 remoteLocalMode = new Action(CVSUIMessages.CVSHistoryPage_CombinedModeAction, plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALREMOTE_MODE)) { 343 public void run() { 344 if (isChecked()){ 345 store.setValue(ICVSUIConstants.PREF_REVISION_MODE, REMOTE_LOCAL_MODE); 346 updateFilterMode(REMOTE_LOCAL_MODE); 347 } else 348 setChecked(true); 349 } 350 }; 351 remoteLocalMode.setToolTipText(CVSUIMessages.CVSHistoryPage_CombinedModeTooltip); 352 remoteLocalMode.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALREMOTE_MODE_DISABLED)); 353 remoteLocalMode.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_LOCALREMOTE_MODE)); 354 355 updateFilterMode(store.getInt(ICVSUIConstants.PREF_REVISION_MODE)); 357 358 groupByDateMode = new Action(CVSUIMessages.CVSHistoryPage_GroupByDate, CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_DATES_CATEGORY)){ 360 public void run() { 361 groupingOn = !groupingOn; 362 store.setValue(ICVSUIConstants.PREF_GROUPBYDATE_MODE, groupingOn); 363 refreshHistory(false, false, CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE); 364 } 365 }; 366 groupingOn = store.getBoolean(ICVSUIConstants.PREF_GROUPBYDATE_MODE); 367 groupByDateMode.setChecked(groupingOn); 368 groupByDateMode.setToolTipText(CVSUIMessages.CVSHistoryPage_GroupByDate); 369 groupByDateMode.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_DATES_CATEGORY)); 370 groupByDateMode.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_DATES_CATEGORY)); 371 372 collapseAll = new Action(CVSUIMessages.CVSHistoryPage_CollapseAllAction, plugin.getImageDescriptor(ICVSUIConstants.IMG_COLLAPSE_ALL)) { 374 public void run() { 375 treeViewer.collapseAll(); 376 } 377 }; 378 collapseAll.setToolTipText(CVSUIMessages.CVSHistoryPage_CollapseAllTooltip); 379 collapseAll.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_COLLAPSE_ALL)); 380 collapseAll.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_COLLAPSE_ALL)); 381 382 compareModeAction = new Action(CVSUIMessages.CVSHistoryPage_CompareModeToggleAction,plugin.getImageDescriptor(ICVSUIConstants.IMG_COMPARE_VIEW)) { 384 public void run() { 385 compareMode = !compareMode; 386 compareModeAction.setChecked(compareMode); 387 } 388 }; 389 compareModeAction.setToolTipText(CVSUIMessages.CVSHistoryPage_CompareModeTooltip); 390 compareModeAction.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_COMPARE_VIEW)); 391 compareModeAction.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_COMPARE_VIEW)); 392 compareModeAction.setChecked(false); 393 394 compareAction = new CompareRevisionAction(CVSUIMessages.CVSHistoryPage_CompareRevisionAction); 396 treeViewer.getTree().addSelectionListener(new SelectionAdapter(){ 397 public void widgetSelected(SelectionEvent e) { 398 compareAction.setCurrentFileRevision(getCurrentFileRevision()); 400 compareAction.selectionChanged((IStructuredSelection) treeViewer.getSelection()); 401 } 402 }); 403 compareAction.setPage(this); 404 405 openAction = new OpenRevisionAction(CVSUIMessages.CVSHistoryPage_OpenAction); 406 treeViewer.getTree().addSelectionListener(new SelectionAdapter(){ 407 public void widgetSelected(SelectionEvent e) { 408 openAction.selectionChanged((IStructuredSelection) treeViewer.getSelection()); 409 } 410 }); 411 openAction.setPage(this); 412 413 OpenStrategy handler = new OpenStrategy(treeViewer.getTree()); 414 handler.addOpenListener(new IOpenEventListener() { 415 public void handleOpen(SelectionEvent e) { 416 if (getSite() != null) { 417 StructuredSelection tableStructuredSelection = (StructuredSelection) treeViewer.getSelection(); 418 if (compareMode){ 419 StructuredSelection sel = new StructuredSelection(new Object [] {getCurrentFileRevision(), tableStructuredSelection.getFirstElement()}); 420 compareAction.selectionChanged(sel); 421 compareAction.run(); 422 } else { 423 StructuredSelection sel = tableStructuredSelection; 425 openAction.selectionChanged(sel); 426 openAction.run(); 427 } 428 } 429 } 430 }); 431 432 getContentsAction = getContextMenuAction(CVSUIMessages.HistoryView_getContentsAction, true , new IWorkspaceRunnable() { 433 public void run(IProgressMonitor monitor) throws CoreException { 434 monitor.beginTask(null, 100); 435 try { 436 if(confirmOverwrite() && validateChange()) { 437 IStorage currentStorage = currentSelection.getStorage(new SubProgressMonitor(monitor, 50)); 438 InputStream in = currentStorage.getContents(); 439 ((IFile)file.getIResource()).setContents(in, false, true, new SubProgressMonitor(monitor, 50)); 440 } 441 } catch (TeamException e) { 442 throw new CoreException(e.getStatus()); 443 } finally { 444 monitor.done(); 445 } 446 } 447 }); 448 PlatformUI.getWorkbench().getHelpSystem().setHelp(getContentsAction, IHelpContextIds.GET_FILE_CONTENTS_ACTION); 449 450 getRevisionAction = getContextMenuAction(CVSUIMessages.HistoryView_getRevisionAction, true , new IWorkspaceRunnable() { 451 public void run(IProgressMonitor monitor) throws CoreException { 452 ICVSRemoteFile remoteFile = (ICVSRemoteFile) CVSWorkspaceRoot.getRemoteResourceFor(((CVSFileRevision) currentSelection).getCVSRemoteFile()); 453 try { 454 if(confirmOverwrite() && validateChange()) { 455 CVSTag revisionTag = new CVSTag(remoteFile.getRevision(), CVSTag.VERSION); 456 457 if(CVSAction.checkForMixingTags(getHistoryPageSite().getShell(), new IResource[] {file.getIResource()}, revisionTag)) { 458 new UpdateOperation( 459 null, 460 new IResource[] {file.getIResource()}, 461 new Command.LocalOption[] {Update.IGNORE_LOCAL_CHANGES}, 462 revisionTag) 463 .run(monitor); 464 465 Display.getDefault().asyncExec(new Runnable () { 466 public void run() { 467 refresh(); 468 } 469 }); 470 } 471 } 472 } catch (InvocationTargetException e) { 473 CVSException.wrapException(e); 474 } catch (InterruptedException e) { 475 } 477 } 478 }); 479 PlatformUI.getWorkbench().getHelpSystem().setHelp(getRevisionAction, IHelpContextIds.GET_FILE_REVISION_ACTION); 480 481 final IActionDelegate tagActionDelegate = new MoveRemoteTagAction() { 483 protected ICVSResource[] getSelectedCVSResources() { 484 ICVSResource[] resources = super.getSelectedCVSResources(); 485 if (resources == null || resources.length == 0) { 486 ArrayList logEntrieFiles = null; 487 IStructuredSelection selection = getSelection(); 488 if (!selection.isEmpty()) { 489 logEntrieFiles = new ArrayList(); 490 Iterator elements = selection.iterator(); 491 while (elements.hasNext()) { 492 Object next = elements.next(); 493 if (next instanceof CVSFileRevision) { 494 logEntrieFiles.add(((CVSFileRevision)next).getCVSRemoteFile()); 495 continue; 496 } 497 if (next instanceof IAdaptable) { 498 IAdaptable a = (IAdaptable) next; 499 Object adapter = a.getAdapter(ICVSResource.class); 500 if (adapter instanceof ICVSResource) { 501 logEntrieFiles.add(((ILogEntry)adapter).getRemoteFile()); 502 continue; 503 } 504 } 505 } 506 } 507 if (logEntrieFiles != null && !logEntrieFiles.isEmpty()) { 508 return (ICVSResource[])logEntrieFiles.toArray(new ICVSResource[logEntrieFiles.size()]); 509 } 510 } 511 return resources; 512 } 513 517 protected ITagOperation createTagOperation() { 518 return new TagInRepositoryOperation(getTargetPart(), getSelectedRemoteResources()) { 519 public void execute(IProgressMonitor monitor) throws CVSException, InterruptedException { 520 super.execute(monitor); 521 Display.getDefault().asyncExec(new Runnable () { 522 public void run() { 523 if( ! wasCancelled()) { 524 refresh(); 525 } 526 } 527 }); 528 }; 529 }; 530 } 531 }; 532 tagWithExistingAction = getContextMenuAction(CVSUIMessages.HistoryView_tagWithExistingAction, false , new IWorkspaceRunnable() { 533 public void run(IProgressMonitor monitor) throws CoreException { 534 tagActionDelegate.selectionChanged(tagWithExistingAction, treeViewer.getSelection()); 535 tagActionDelegate.run(tagWithExistingAction); 536 } 537 }); 538 PlatformUI.getWorkbench().getHelpSystem().setHelp(getRevisionAction, IHelpContextIds.TAG_WITH_EXISTING_ACTION); 539 540 toggleTextAction = new Action(TeamUIMessages.GenericHistoryView_ShowCommentViewer) { 542 public void run() { 543 setViewerVisibility(); 544 store.setValue(ICVSUIConstants.PREF_SHOW_COMMENTS, toggleTextAction.isChecked()); 545 } 546 }; 547 toggleTextAction.setChecked(store.getBoolean(ICVSUIConstants.PREF_SHOW_COMMENTS)); 548 550 toggleTextWrapAction = new Action(TeamUIMessages.GenericHistoryView_WrapComments) { 552 public void run() { 553 setViewerVisibility(); 554 store.setValue(ICVSUIConstants.PREF_WRAP_COMMENTS, toggleTextWrapAction.isChecked()); 555 } 556 }; 557 toggleTextWrapAction.setChecked(store.getBoolean(ICVSUIConstants.PREF_WRAP_COMMENTS)); 558 560 toggleListAction = new Action(TeamUIMessages.GenericHistoryView_ShowTagViewer) { 562 public void run() { 563 setViewerVisibility(); 564 store.setValue(ICVSUIConstants.PREF_SHOW_TAGS, toggleListAction.isChecked()); 565 } 566 }; 567 toggleListAction.setChecked(store.getBoolean(ICVSUIConstants.PREF_SHOW_TAGS)); 568 570 toggleSearchAction= new Action(CVSUIMessages.CVSHistoryPage_ShowSearchField) { 572 public void run() { 573 setViewerVisibility(); 574 store.setValue(ICVSUIConstants.PREF_SHOW_SEARCH, toggleSearchAction.isChecked()); 575 if (!toggleSearchAction.isChecked()){ 576 if (searchFilter != null) 577 treeViewer.removeFilter(searchFilter); 578 } else { 579 searchField.setText(CVSUIMessages.CVSHistoryPage_EnterSearchTerm); 580 searchField.selectAll(); 581 searchField.setFocus(); 582 } 583 } 584 }; 585 toggleSearchAction.setChecked(store.getBoolean(ICVSUIConstants.PREF_SHOW_SEARCH)); 586 588 toggleFilterAction = new Action(CVSUIMessages.CVSHistoryPage_NoFilter){ 589 public void run(){ 590 if (historyFilter != null) 591 treeViewer.removeFilter(historyFilter); 592 historyFilter = null; 593 String old = CVSHistoryPage.this.description; 594 CVSHistoryPage.this.description = null; 595 CVSHistoryPage.this.firePropertyChange(CVSHistoryPage.this, P_NAME, old, getName()); 596 toggleFilterAction.setEnabled(false); 597 } 598 }; 599 toggleFilterAction.setEnabled(historyFilter != null); 600 601 cvsHistoryFilter = new CVSHistoryFilterAction(this); 603 cvsHistoryFilter.setText(CVSUIMessages.CVSHistoryPage_FilterOn); 604 cvsHistoryFilter.init(treeViewer); 605 cvsHistoryFilter.setToolTipText(CVSUIMessages.CVSHistoryPage_FilterHistoryTooltip); 606 cvsHistoryFilter.setImageDescriptor(CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_FILTER_HISTORY)); 607 608 MenuManager menuMgr = new MenuManager(); 610 Menu menu = menuMgr.createContextMenu(treeViewer.getTree()); 611 menuMgr.addMenuListener(new IMenuListener() { 612 public void menuAboutToShow(IMenuManager menuMgr) { 613 fillTableMenu(menuMgr); 614 } 615 }); 616 menuMgr.setRemoveAllWhenShown(true); 617 treeViewer.getTree().setMenu(menu); 618 IHistoryPageSite parentSite = getHistoryPageSite(); 620 if (!parentSite.isModal()) { 621 IWorkbenchPart part = parentSite.getPart(); 622 if (part != null) { 623 IWorkbenchPartSite workbenchPartSite = part.getSite(); 624 workbenchPartSite.registerContextMenu(menuMgr, treeViewer); 625 } 626 IPageSite pageSite = parentSite.getWorkbenchPageSite(); 627 if (pageSite != null) { 628 IActionBars actionBars = pageSite.getActionBars(); 629 IMenuManager actionBarsMenu = actionBars.getMenuManager(); 631 if (actionBarsMenu != null){ 632 actionBarsMenu.add(toggleTextWrapAction); 633 actionBarsMenu.add(new Separator()); 634 actionBarsMenu.add(toggleTextAction); 635 actionBarsMenu.add(toggleListAction); 636 actionBarsMenu.add(new Separator()); 637 actionBarsMenu.add(toggleSearchAction); 638 actionBarsMenu.add(new Separator()); 639 actionBarsMenu.add(cvsHistoryFilter); 640 actionBarsMenu.add(toggleFilterAction); 641 } 642 copyAction = new TextViewerAction(textViewer, ITextOperationTarget.COPY); 644 copyAction.setText(CVSUIMessages.HistoryView_copy); 645 actionBars.setGlobalActionHandler(ITextEditorActionConstants.COPY, copyAction); 646 647 selectAllAction = new TextViewerAction(textViewer, ITextOperationTarget.SELECT_ALL); 648 selectAllAction.setText(CVSUIMessages.HistoryView_selectAll); 649 actionBars.setGlobalActionHandler(ITextEditorActionConstants.SELECT_ALL, selectAllAction); 650 651 actionBars.updateActionBars(); 652 } 653 } 654 655 656 657 IToolBarManager tbm = parentSite.getToolBarManager(); 659 if (tbm != null) { 660 String fileNameQualifier = getFileNameQualifier(); 661 tbm.add(new Separator(fileNameQualifier + "grouping")); tbm.appendToGroup(fileNameQualifier+"grouping", groupByDateMode); tbm.add(new Separator(fileNameQualifier+"modes")); tbm.appendToGroup(fileNameQualifier+"modes", remoteLocalMode); tbm.appendToGroup(fileNameQualifier+"modes", localMode); tbm.appendToGroup(fileNameQualifier+"modes", remoteMode); tbm.add(new Separator(fileNameQualifier+"collapse")); tbm.appendToGroup(fileNameQualifier+"collapse", collapseAll); if (!parentSite.isModal()) { 671 tbm.appendToGroup(fileNameQualifier+"collapse", compareModeAction); } 675 tbm.update(false); 676 } 677 678 menuMgr = new MenuManager(); 679 menuMgr.setRemoveAllWhenShown(true); 680 menuMgr.addMenuListener(new IMenuListener() { 681 public void menuAboutToShow(IMenuManager menuMgr) { 682 fillTextMenu(menuMgr); 683 } 684 }); 685 StyledText text = textViewer.getTextWidget(); 686 menu = menuMgr.createContextMenu(text); 687 text.setMenu(menu); 688 } 689 690 private String getFileNameQualifier() { 691 return Long.toString(System.currentTimeMillis()); 693 } 694 695 private boolean isLocalHistoryFilteredOut() { 696 return localFilteredOut; 697 } 698 699 private boolean isRemoteHistoryFilteredOut(){ 700 return remoteFilteredOut; 701 } 702 703 void fillTableMenu(IMenuManager manager) { 704 IHistoryPageSite parentSite = getHistoryPageSite(); 706 manager.add(new Separator(IWorkbenchActionConstants.GROUP_FILE)); 707 708 if (file != null && !parentSite.isModal()){ 709 manager.add(openAction); 710 manager.add(compareAction); 711 manager.add(new Separator("openCompare")); } 713 if (file != null && 714 !(file instanceof RemoteFile)) { 715 ISelection sel = treeViewer.getSelection(); 717 if (!sel.isEmpty()) { 718 if (sel instanceof IStructuredSelection) { 719 IStructuredSelection tempSelection = (IStructuredSelection) sel; 720 if (tempSelection.size() == 1) { 721 manager.add(getContentsAction); 722 if (!(tempSelection.getFirstElement() instanceof LocalFileRevision)) { 723 manager.add(getRevisionAction); 724 manager.add(new Separator()); 725 if (!parentSite.isModal()) 726 manager.add(tagWithExistingAction); 727 } 728 } 729 } 730 } 731 } 732 733 if (!parentSite.isModal()){ 734 manager.add(new Separator("additions")); manager.add(refreshAction); 736 manager.add(new Separator("additions-end")); } 738 } 739 740 private void fillTextMenu(IMenuManager manager) { 741 manager.add(copyAction); 742 manager.add(selectAllAction); 743 } 744 745 753 protected TreeViewer createTree(Composite parent) { 754 755 historyTableProvider = new CVSHistoryTableProvider(); 756 TreeViewer viewer = historyTableProvider.createTree(parent, cvsFileHistory == null ? true : cvsFileHistory.isIncludeLocal()); 757 758 viewer.setContentProvider(new ITreeContentProvider() { 759 public Object [] getElements(Object inputElement) { 760 761 if (entries != null) 763 return entries; 764 765 if (!(inputElement instanceof IFileHistory) && 766 !(inputElement instanceof AbstractHistoryCategory[])) 767 return new Object [0]; 768 769 if (inputElement instanceof AbstractHistoryCategory[]){ 770 return (AbstractHistoryCategory[]) inputElement; 771 } 772 773 final IFileHistory fileHistory = (IFileHistory) inputElement; 774 entries = fileHistory.getFileRevisions(); 775 776 return entries; 777 } 778 779 public void dispose() { 780 } 781 782 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 783 entries = null; 784 } 785 786 public Object [] getChildren(Object parentElement) { 787 if (parentElement instanceof AbstractHistoryCategory){ 788 return ((AbstractHistoryCategory) parentElement).getRevisions(); 789 } 790 791 return null; 792 } 793 794 public Object getParent(Object element) { 795 return null; 796 } 797 798 public boolean hasChildren(Object element) { 799 if (element instanceof AbstractHistoryCategory){ 800 IFileRevision[] revs = ((AbstractHistoryCategory) element).getRevisions(); 801 if (revs != null) 802 return revs.length > 0; 803 } 804 return false; 805 } 806 }); 807 808 viewer.addSelectionChangedListener(new ISelectionChangedListener() { 809 public void selectionChanged(SelectionChangedEvent event) { 810 ISelection selection = event.getSelection(); 811 if (selection == null || !(selection instanceof IStructuredSelection)) { 812 textViewer.setDocument(new Document("")); tagViewer.setInput(null); 814 setStatusLineMessage(null); 815 return; 816 } 817 IStructuredSelection ss = (IStructuredSelection)selection; 818 if (ss.size() != 1) { 819 textViewer.setDocument(new Document("")); tagViewer.setInput(null); 821 setStatusLineMessage(null); 822 return; 823 } 824 Object o = ss.getFirstElement(); 825 if (o instanceof AbstractHistoryCategory){ 826 textViewer.setDocument(new Document("")); tagViewer.setInput(null); 828 setStatusLineMessage(null); 829 return; 830 } 831 IFileRevision entry = (IFileRevision)o; 832 textViewer.setDocument(new Document(entry.getComment())); 833 tagViewer.setInput(entry.getTags()); 834 setStatusLineMessage(CVSHistoryTableProvider.getCommentAsSingleLine(entry)); 835 } 836 }); 837 838 return viewer; 839 } 840 841 private Action getContextMenuAction(String title, final boolean needsProgressDialog, final IWorkspaceRunnable action) { 842 return new Action(title) { 843 public void run() { 844 try { 845 if (file == null) return; 846 ISelection selection = treeViewer.getSelection(); 847 if (!(selection instanceof IStructuredSelection)) return; 848 IStructuredSelection ss = (IStructuredSelection)selection; 849 Object o = ss.getFirstElement(); 850 851 if (o instanceof AbstractHistoryCategory) 852 return; 853 854 currentSelection = (IFileRevision)o; 855 if(needsProgressDialog) { 856 PlatformUI.getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() { 857 public void run(IProgressMonitor monitor) throws InvocationTargetException , InterruptedException { 858 try { 859 action.run(monitor); 860 } catch (CoreException e) { 861 throw new InvocationTargetException (e); 862 } 863 } 864 }); 865 } else { 866 try { 867 action.run(null); 868 } catch (CoreException e) { 869 throw new InvocationTargetException (e); 870 } 871 } 872 } catch (InvocationTargetException e) { 873 IHistoryPageSite parentSite = getHistoryPageSite(); 874 CVSUIPlugin.openError(parentSite.getShell(), null, null, e, CVSUIPlugin.LOG_NONTEAM_EXCEPTIONS); 875 } catch (InterruptedException e) { 876 } 878 } 879 880 public boolean isEnabled() { 881 ISelection selection = treeViewer.getSelection(); 882 if (!(selection instanceof IStructuredSelection)) return false; 883 IStructuredSelection ss = (IStructuredSelection)selection; 884 if(ss.size() != 1) return false; 885 return true; 886 } 887 }; 888 } 889 890 private boolean confirmOverwrite() { 891 if (file!=null && file.getIResource().exists()) { 892 try { 893 if(file.isModified(null)) { 894 String title = CVSUIMessages.HistoryView_overwriteTitle; 895 String msg = CVSUIMessages.HistoryView_overwriteMsg; 896 IHistoryPageSite parentSite = getHistoryPageSite(); 897 final MessageDialog dialog = new MessageDialog(parentSite.getShell(), title, null, msg, MessageDialog.QUESTION, new String [] { IDialogConstants.YES_LABEL, IDialogConstants.CANCEL_LABEL }, 0); 898 final int[] result = new int[1]; 899 parentSite.getShell().getDisplay().syncExec(new Runnable () { 900 public void run() { 901 result[0] = dialog.open(); 902 }}); 903 if (result[0] != 0) { 904 return false; 906 } 907 } 908 } catch(CVSException e) { 909 CVSUIPlugin.log(e); 910 } 911 } 912 return true; 913 } 914 915 private boolean validateChange(){ 916 if (file!=null && file.getIResource().exists()) { 917 IResourceChangeDescriptionFactory factory = ResourceChangeValidator.getValidator().createDeltaFactory(); 918 factory.change((IFile) file.getIResource()); 919 return IDE.promptToConfirm(getHistoryPageSite().getShell(), CVSUIMessages.CVSHistoryPage_ValidateChangeTitle, NLS.bind(CVSUIMessages.CVSHistoryPage_ValidateChangeMessage, new String []{file.getName()}), factory.getDelta(), new String [0], true ); 920 } 921 922 return false; 923 } 924 925 928 public void refresh() { 929 refresh(CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE); 930 } 931 932 public void refresh(int refreshFlags) { 933 refreshHistory(true, false, refreshFlags); 936 } 937 938 private void refreshHistory(boolean refetch, boolean selectOnly, int refreshFlags) { 939 if (refreshCVSFileHistoryJob.getState() != Job.NONE){ 940 refreshCVSFileHistoryJob.cancel(); 941 } 942 refreshCVSFileHistoryJob.setFileHistory(cvsFileHistory); 943 IResource resource = previousFile.getIResource(); 944 if (resource != null){ 945 IResource workspaceFile = ResourcesPlugin.getWorkspace().getRoot().findMember(resource.getFullPath()); 946 refreshCVSFileHistoryJob.setWorkspaceFile((IFile) workspaceFile); 947 } 948 refreshCVSFileHistoryJob.setSelectOnly(selectOnly); 950 refreshCVSFileHistoryJob.setRefetchHistory(refetch); 951 refreshCVSFileHistoryJob.setIncludeLocals(!isLocalHistoryFilteredOut()); 952 refreshCVSFileHistoryJob.setIncludeRemote(!isRemoteHistoryFilteredOut()); 953 refreshCVSFileHistoryJob.setGrouping(groupingOn); 954 refreshCVSFileHistoryJob.setRefreshFlags(refreshFlags); 955 IHistoryPageSite parentSite = getHistoryPageSite(); 956 Utils.schedule(refreshCVSFileHistoryJob, getWorkbenchSite(parentSite)); 957 } 958 959 private IWorkbenchPartSite getWorkbenchSite(IHistoryPageSite parentSite) { 960 IWorkbenchPart part = parentSite.getPart(); 961 if (part != null) 962 return part.getSite(); 963 return null; 964 } 965 966 969 public void selectRevision(String revision) { 970 IFileRevision entry = null; 971 entry = getFileRevision(revision); 972 973 if (entry != null) { 974 IStructuredSelection selection = new StructuredSelection(entry); 975 treeViewer.getTree().setRedraw(false); 976 treeViewer.setSelection(selection, true); 977 treeViewer.getTree().setRedraw(true); 978 } else { 979 treeViewer.getTree().deselectAll(); 981 } 982 } 983 984 private IFileRevision getFileRevision(String revision) { 985 if (entries != null) { 986 for (int i = 0; i < entries.length; i++) { 987 if (entries[i].getContentIdentifier().equals(revision)) { 988 return entries[i]; 989 } 990 } 991 } else if (cvsFileHistory != null) { 992 return cvsFileHistory.getFileRevision(revision); 993 } 994 return null; 995 } 996 997 1001 public void selectLocalRevision(long timeStamp){ 1002 IFileRevision entry = null; 1003 if (entries != null) { 1004 for (int i = 0; i < entries.length; i++) { 1005 if (entries[i].getTimestamp() == timeStamp) { 1006 entry = entries[i]; 1007 break; 1008 } 1009 } 1010 }else if (cvsFileHistory != null) { 1011 IFileRevision[] tempEntries = cvsFileHistory.getFileRevisions(); 1012 for (int i = 0; i < tempEntries.length; i++) { 1013 if (tempEntries[i].getTimestamp() == timeStamp) { 1014 entry = tempEntries[i]; 1015 break; 1016 } 1017 } 1018 } 1019 1020 if (entry != null) { 1021 IStructuredSelection selection = new StructuredSelection(entry); 1022 treeViewer.getTree().setRedraw(false); 1023 treeViewer.setSelection(selection, true); 1024 treeViewer.getTree().setRedraw(true); 1025 } else { 1026 treeViewer.getTree().deselectAll(); 1028 } 1029 } 1030 1031 protected static ICVSFile getCVSFile(Object object) { 1032 IResource resource = (IResource)Utils.getAdapter(object, IResource.class); 1034 if (resource instanceof IFile) { 1035 RepositoryProvider provider = RepositoryProvider.getProvider(((IResource)resource).getProject()); 1036 if (provider instanceof CVSTeamProvider) 1037 return CVSWorkspaceRoot.getCVSFileFor((IFile) resource); 1038 return null; 1039 } 1040 ICVSFile remoteFile = (ICVSFile)Utils.getAdapter(object, ICVSFile.class); 1042 if (remoteFile != null) { 1043 return remoteFile; 1044 } 1045 ICVSResource remote = (ICVSResource)Utils.getAdapter(object, ICVSResource.class); 1047 if (remote instanceof RemoteFile) { 1048 return (ICVSFile)remote; 1049 } 1050 IResourceVariant variant = (IResourceVariant)Utils.getAdapter(object, IResourceVariant.class); 1052 if (variant instanceof RemoteFile) { 1053 return (ICVSFile)remote; 1054 } 1055 IFileRevision revision = (IFileRevision)Utils.getAdapter(object, IFileRevision.class); 1057 if (revision instanceof CVSFileRevision) { 1058 return ((CVSFileRevision)revision).getCVSRemoteFile(); 1059 } 1060 1061 return null; 1062 } 1063 1064 void setViewerVisibility() { 1065 boolean showText = toggleTextAction.isChecked(); 1066 boolean showList = toggleListAction.isChecked(); 1067 boolean showSearch = toggleSearchAction.isChecked(); 1068 1069 IHistoryPageSite parentSite = getHistoryPageSite(); 1072 if (parentSite.isModal()){ 1073 showText = false; 1074 showList = false; 1075 } 1076 1077 1078 if (showText && showList && showSearch) { 1079 sashForm.setWeights(new int[] {60, 25, 15}); 1081 sashForm.setMaximizedControl(null); 1082 innerSashForm.setMaximizedControl(null); 1083 searchSashForm.setMaximizedControl(null); 1084 } else if (showText && showSearch) { 1085 sashForm.setWeights(new int[] {60, 25, 15}); 1087 sashForm.setMaximizedControl(null); 1088 innerSashForm.setMaximizedControl(textViewer.getTextWidget()); 1089 searchSashForm.setMaximizedControl(searchField); 1090 } else if (showList && showSearch) { 1091 sashForm.setWeights(new int[] {60, 25, 15}); 1093 sashForm.setMaximizedControl(null); 1094 innerSashForm.setMaximizedControl(tagViewer.getTable()); 1095 searchSashForm.setMaximizedControl(searchField); 1096 } else if (showSearch){ 1097 sashForm.setWeights(new int[] {85, 0, 15}); 1099 sashForm.setMaximizedControl(null); 1100 innerSashForm.setMaximizedControl(null); 1101 searchSashForm.setMaximizedControl(searchField); 1102 } else if (showText && showList) { 1103 sashForm.setWeights(new int[] {70, 30, 0}); 1105 sashForm.setMaximizedControl(null); 1106 innerSashForm.setMaximizedControl(null); 1107 searchSashForm.setMaximizedControl(searchField); 1108 } else if (showText) { 1109 sashForm.setWeights(new int[] {70, 30, 0}); 1111 sashForm.setMaximizedControl(null); 1112 innerSashForm.setMaximizedControl(textViewer.getTextWidget()); 1113 } else if (showList) { 1114 sashForm.setWeights(new int[] {70, 30, 0}); 1116 sashForm.setMaximizedControl(null); 1117 innerSashForm.setMaximizedControl(tagViewer.getTable()); 1118 } else { 1119 sashForm.setMaximizedControl(treeViewer.getControl()); 1121 } 1122 1123 boolean wrapText = toggleTextWrapAction.isChecked(); 1124 textViewer.getTextWidget().setWordWrap(wrapText); 1125 } 1126 1127 private void initializeImages() { 1128 CVSUIPlugin plugin = CVSUIPlugin.getPlugin(); 1129 versionImage = plugin.getImageDescriptor(ICVSUIConstants.IMG_PROJECT_VERSION).createImage(); 1130 branchImage = plugin.getImageDescriptor(ICVSUIConstants.IMG_TAG).createImage(); 1131 } 1132 1133 public void dispose() { 1134 shutdown = true; 1135 1136 if (resourceListener != null){ 1137 ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceListener); 1138 resourceListener = null; 1139 } 1140 1141 if (branchImage != null) { 1142 branchImage.dispose(); 1143 branchImage = null; 1144 } 1145 if (versionImage != null) { 1146 versionImage.dispose(); 1147 versionImage = null; 1148 } 1149 if (rulerSelectionListener != null) { 1150 rulerSelectionListener.dispose(); 1151 rulerSelectionListener= null; 1152 } 1153 1154 if (refreshCVSFileHistoryJob != null) { 1156 if (refreshCVSFileHistoryJob.getState() != Job.NONE) { 1157 refreshCVSFileHistoryJob.cancel(); 1158 } 1159 } 1160 } 1161 1162 public IFileRevision getCurrentFileRevision() { 1163 if (currentFileRevision != null) 1164 return currentFileRevision; 1165 1166 if (file != null) { 1167 try { 1168 if (file instanceof RemoteFile) { 1170 RemoteFile remote = (RemoteFile) file; 1171 currentFileRevision = cvsFileHistory.getFileRevision(remote.getContentIdentifier()); 1172 return currentFileRevision; 1175 } 1176 IFile localFile = (IFile) file.getIResource(); 1180 if (localFile != null) { 1181 currentFileRevision = new LocalFileRevision(localFile); 1183 } else { 1184 if (file.getSyncInfo() != null) { 1186 currentFileRevision = cvsFileHistory.getFileRevision(file.getSyncInfo().getRevision()); 1187 } 1188 } 1189 return currentFileRevision; 1190 } catch (CVSException e) { 1191 } 1192 } 1193 1194 return null; 1195 } 1196 1197 private final class CVSRevisionAnnotationController extends 1198 RevisionAnnotationController { 1199 public CVSRevisionAnnotationController(IWorkbenchPage page, IFile file) { 1200 super(page, file, treeViewer); 1201 } 1202 1203 public CVSRevisionAnnotationController(IWorkbenchPage page, IStorageEditorInput editorInput) { 1204 super(page, editorInput, treeViewer); 1205 } 1206 1207 protected Object getHistoryEntry(Revision selected) { 1208 return CVSHistoryPage.this.getFileRevision(selected.getId()); 1209 } 1210 } 1211 1212 1213 private final class SearchHistoryTable implements Runnable { 1214 public void run() { 1215 String searchString = searchField.getText(); 1216 if (searchString.equals("") || searchString.equals(CVSUIMessages.CVSHistoryPage_EnterSearchTerm)) { 1218 if (searchFilter != null) 1219 treeViewer.removeFilter(searchFilter); 1220 return; 1221 } 1222 1223 1224 if (searchFilter != null) 1225 treeViewer.removeFilter(searchFilter); 1226 1227 searchFilter = new CVSHistorySearchFilter(searchString); 1228 1229 if (historyFilter != null) 1230 treeViewer.removeFilter(historyFilter); 1231 1232 treeViewer.addFilter(searchFilter); 1233 } 1234 } 1235 1236 1237 private class RefreshCVSFileHistory extends Job { 1238 private final static int NUMBER_OF_CATEGORIES = 4; 1239 1240 private CVSFileHistory fileHistory; 1241 private AbstractHistoryCategory[] categories; 1242 private boolean grouping; 1243 private Object [] elementsToExpand; 1244 private boolean revisionsFound; 1245 private IFile workspaceFile; 1246 private CVSHistoryPage page; 1247 private boolean selectOnly; 1248 private boolean useLocalSelect; 1249 1250 private CVSLocalFileRevision localFileRevision; 1251 1252 private int refreshFlags = CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE; 1253 1254 public RefreshCVSFileHistory(CVSHistoryPage page) { 1255 super(CVSUIMessages.HistoryView_fetchHistoryJob); 1256 this.page = page; 1257 } 1258 1259 public void setWorkspaceFile(IFile workspaceFile) { 1260 this.workspaceFile = workspaceFile; 1261 } 1262 1263 public void setIncludeLocals(boolean flag) { 1264 if (fileHistory != null) 1265 fileHistory.includeLocalRevisions(flag); 1266 } 1267 1268 public void setIncludeRemote(boolean flag){ 1269 if (fileHistory != null) 1270 fileHistory.includeRemoteRevisions(flag); 1271 } 1272 1273 public void setRefetchHistory(boolean refetch) { 1274 if (fileHistory != null) 1275 fileHistory.setRefetchRevisions(refetch); 1276 } 1277 1278 public void setFileHistory(CVSFileHistory fileHistory) { 1279 this.fileHistory = fileHistory; 1280 } 1281 1282 public void setGrouping (boolean value){ 1283 this.grouping = value; 1284 } 1285 1286 public void setSelectOnly(boolean select) { 1287 this.selectOnly = select; 1288 } 1289 1290 public void setSelectLocal(boolean localSelect) { 1291 this.useLocalSelect = localSelect; 1292 } 1293 1294 public void setLocalFileRevision(CVSLocalFileRevision localRev){ 1295 this.localFileRevision = localRev; 1296 } 1297 1298 public IStatus run(IProgressMonitor monitor) { 1299 1300 IStatus status = Status.OK_STATUS; 1301 1302 if (fileHistory != null && !shutdown) { 1303 boolean localFetched = false; 1306 boolean needsUpdate = true; 1307 if (!fileHistory.isInitialized() && fileHistory.isIncludeLocal() && (refreshFlags & CVSFileHistory.REFRESH_REMOTE) > 0) { 1308 try { 1310 fileHistory.refresh(CVSFileHistory.REFRESH_LOCAL, monitor); 1311 updateTable(); 1312 localFetched = true; 1313 needsUpdate = false; 1314 } catch (TeamException e) { 1315 } 1317 } 1318 try { 1319 fileHistory.refresh(refreshFlags , monitor); 1320 needsUpdate = true; 1321 } catch (TeamException ex) { 1322 if (!localFetched) { 1323 try { 1324 fileHistory.refresh(CVSFileHistory.REFRESH_LOCAL, monitor); 1325 needsUpdate = true; 1326 } catch (TeamException e) { 1327 } 1329 } 1330 status = new CVSStatus(ex.getStatus().getSeverity(), ex.getStatus().getCode(), ex.getMessage(), ex); 1331 } 1332 if (needsUpdate) 1333 updateTable(); 1334 } 1335 1336 if (status != Status.OK_STATUS ) { 1337 this.setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE); 1338 this.setProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY, Boolean.TRUE); 1339 } 1340 1341 return status; 1342 } 1343 1344 private void updateTable() { 1345 if (grouping) 1346 revisionsFound = sortRevisions(); 1347 1348 Utils.asyncExec(new Runnable () { 1349 public void run() { 1350 historyTableProvider.setLocalRevisionsDisplayed(fileHistory.isIncludeLocal()); 1351 historyTableProvider.setFile(fileHistory, workspaceFile); 1352 if (!selectOnly){ 1354 if (grouping) { 1355 mapExpandedElements(treeViewer.getExpandedElements()); 1356 treeViewer.getTree().setLinesVisible(revisionsFound); 1357 treeViewer.getTree().setRedraw(false); 1358 treeViewer.setInput(categories); 1359 if (elementsToExpand.length > 0) 1362 treeViewer.setExpandedElements(elementsToExpand); 1363 else { 1364 treeViewer.expandAll(); 1365 Object [] el = treeViewer.getExpandedElements(); 1366 if (el != null && el.length > 0) { 1367 treeViewer.setSelection(new StructuredSelection(el[0])); 1368 treeViewer.getTree().deselectAll(); 1369 } 1370 } 1371 treeViewer.getTree().setRedraw(true); 1372 } else { 1373 if (fileHistory.getFileRevisions().length > 0) { 1374 treeViewer.getTree().setLinesVisible(true); 1375 treeViewer.setInput(fileHistory); 1376 } else { 1377 categories = new AbstractHistoryCategory[] {getErrorMessage()}; 1378 treeViewer.getTree().setLinesVisible(false); 1379 treeViewer.setInput(categories); 1380 } 1381 } 1382 } 1383 if (historyFilter != null){ 1386 CVSHistoryFilter tempFilter = new CVSHistoryFilter(historyFilter.author, historyFilter.comment, historyFilter.fromDate, historyFilter.toDate, historyFilter.isOr); 1387 showFilter(tempFilter); 1388 } 1389 1390 if (file != null){ 1392 try { 1393 if (useLocalSelect){ 1394 page.selectLocalRevision(localFileRevision.getTimestamp()); 1395 } else { 1396 byte[] syncBytes = file.getSyncBytes(); 1397 if (syncBytes != null) { 1398 String workspaceRevision = ResourceSyncInfo.getRevision(syncBytes); 1399 page.selectRevision(workspaceRevision); 1400 } 1401 } 1402 } catch (CVSException e){ 1403 } 1404 } 1405 } 1406 }, treeViewer); 1407 } 1408 1409 private void mapExpandedElements(Object [] expandedElements) { 1410 HashMap elementMap = new HashMap(); 1412 for (int i=0; i<expandedElements.length; i++){ 1413 elementMap.put(((DateHistoryCategory)expandedElements[i]).getName(), null); 1414 } 1415 1416 ArrayList expandable = new ArrayList(); 1418 for (int i = 0; i<categories.length; i++){ 1419 if (elementMap.containsKey(categories[i].getName())){ 1421 expandable.add(categories[i]); 1422 } 1423 } 1424 1425 elementsToExpand = new Object [expandable.size()]; 1426 elementsToExpand = (Object []) expandable.toArray(new Object [expandable.size()]); 1427 } 1428 1429 private boolean sortRevisions() { 1430 IFileRevision[] fileRevision = fileHistory.getFileRevisions(); 1431 1432 DateHistoryCategory[] tempCategories = new DateHistoryCategory[NUMBER_OF_CATEGORIES]; 1434 Calendar currentCal = Calendar.getInstance(); 1436 tempCategories[0] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_Today, currentCal, null); 1437 Calendar yesterdayCal = Calendar.getInstance(); 1439 yesterdayCal.roll(Calendar.DAY_OF_YEAR, -1); 1440 tempCategories[1] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_Yesterday, yesterdayCal, null); 1441 Calendar monthCal = Calendar.getInstance(); 1443 monthCal.set(Calendar.DAY_OF_MONTH, 1); 1444 tempCategories[2] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_ThisMonth, monthCal, yesterdayCal); 1445 tempCategories[3] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_Previous, null, monthCal); 1447 1448 ArrayList finalCategories = new ArrayList(); 1449 for (int i = 0; i<NUMBER_OF_CATEGORIES; i++){ 1450 tempCategories[i].collectFileRevisions(fileRevision, false); 1451 if (tempCategories[i].hasRevisions()) 1452 finalCategories.add(tempCategories[i]); 1453 } 1454 1455 boolean revisionsFound = true; 1457 1458 if (finalCategories.size() == 0){ 1459 finalCategories.add(getErrorMessage()); 1461 revisionsFound = false; 1462 } 1463 1464 categories = (AbstractHistoryCategory[])finalCategories.toArray(new AbstractHistoryCategory[finalCategories.size()]); 1465 return revisionsFound; 1466 } 1467 1468 private MessageHistoryCategory getErrorMessage(){ 1469 String message = ""; switch(currentFilerMode){ 1471 case LOCAL_MODE: 1472 message = CVSUIMessages.CVSHistoryPage_LocalModeTooltip; 1473 break; 1474 1475 case REMOTE_MODE: 1476 message = CVSUIMessages.CVSHistoryPage_RemoteModeTooltip; 1477 break; 1478 1479 case REMOTE_LOCAL_MODE: 1480 message = CVSUIMessages.CVSHistoryPage_NoRevisions; 1481 break; 1482 } 1483 1484 MessageHistoryCategory messageCategory = new MessageHistoryCategory(NLS.bind(CVSUIMessages.CVSHistoryPage_NoRevisionsForMode, new String [] { message })); 1485 return messageCategory; 1486 } 1487 1488 public int getRefreshFlags() { 1489 return refreshFlags; 1490 } 1491 1492 public void setRefreshFlags(int refreshFlags) { 1493 this.refreshFlags = refreshFlags; 1494 } 1495 1496 1497 1498 } 1499 1500 1501 1505 private class SimpleContentProvider implements IStructuredContentProvider { 1506 1507 1510 public SimpleContentProvider() { 1511 super(); 1512 } 1513 1514 1517 public void dispose() { 1518 } 1519 1520 1523 public Object [] getElements(Object element) { 1524 return new Object [0]; 1525 } 1526 1527 1530 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 1531 } 1532 } 1533 1534 private class HistoryResourceListener implements IResourceChangeListener { 1535 1538 public void resourceChanged(IResourceChangeEvent event) { 1539 IResourceDelta root = event.getDelta(); 1540 if (file == null || file.getIResource() == null) 1543 return; 1544 1545 IResourceDelta resourceDelta = root.findMember(((IFile)file.getIResource()).getFullPath()); 1546 if (resourceDelta != null){ 1547 String revision = getRevision(); 1548 final boolean hasRevision = cvsFileHistory.getFileRevision(revision) != null; 1549 Display.getDefault().asyncExec(new Runnable () { 1550 public void run() { 1551 if (treeViewer.getControl().isDisposed()) 1552 return; 1553 if (treeViewer.getControl().isVisible()) { 1554 if (hasRevision) 1555 refresh(CVSFileHistory.REFRESH_LOCAL); 1556 else 1557 refresh(); 1558 } else { 1559 refreshRequest = hasRevision ? CVSFileHistory.REFRESH_LOCAL : CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE; 1560 } 1561 } 1562 }); 1563 } 1564 } 1565 1566 private String getRevision() { 1567 try { 1568 byte[] syncBytes = file.getSyncBytes(); 1569 if (syncBytes != null && !ResourceSyncInfo.isAddition(syncBytes)) { 1570 return ResourceSyncInfo.getRevision(syncBytes); 1571 } 1572 } catch (CVSException e) { 1573 } 1575 return null; 1576 } 1577 } 1578 1579 public Control getControl() { 1580 return sashForm; 1581 } 1582 1583 public boolean isValidInput(Object object) { 1584 ICVSFile file = getCVSFile(object); 1585 return file != null; 1586 } 1587 1588 public String getName() { 1589 if (description != null) 1590 return description; 1591 if (file != null) 1592 return file.getName(); 1593 1594 return ""; } 1596 1597 1601 public IPath getFilePath() { 1602 if (file != null) 1603 return file.getIResource().getFullPath(); 1604 1605 return null; 1606 } 1607 1608 public Object getAdapter(Class adapter) { 1609 if(adapter == IHistoryCompareAdapter.class) { 1610 return this; 1611 } 1612 return null; 1613 } 1614 1615 public ICompareInput getCompareInput(Object object) { 1616 if (object instanceof IFileRevision){ 1617 IFileRevision selectedFileRevision = (IFileRevision)object; 1618 if (fileElement == null) 1619 fileElement = SaveableCompareEditorInput.createFileElement((IFile) file.getIResource()); 1620 FileRevisionTypedElement right = new FileRevisionTypedElement(selectedFileRevision, getLocalEncoding()); 1621 DiffNode node = new DiffNode(fileElement, right); 1622 return node; 1623 } 1624 return null; 1625 } 1626 1627 private String getLocalEncoding() { 1628 IResource resource = file.getIResource(); 1629 if (resource instanceof IFile) { 1630 IFile file = (IFile) resource; 1631 try { 1632 return file.getCharset(); 1633 } catch (CoreException e) { 1634 CVSUIPlugin.log(e); 1635 } 1636 } 1637 return null; 1638 } 1639 1640 public void setClickAction(boolean compare) { 1641 compareMode = !compare; 1644 compareModeAction.run(); 1645 } 1646 1647 public void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) { 1648 initLabels(input, configuration); 1649 } 1651 1652 private void initLabels(ICompareInput input, CompareConfiguration cc) { 1653 String leftLabel = getFileRevisionLabel(input.getLeft(), cc); 1654 cc.setLeftLabel(leftLabel); 1655 String rightLabel = getFileRevisionLabel(input.getRight(), cc); 1656 cc.setRightLabel(rightLabel); 1657 } 1658 1659 private String getFileRevisionLabel(ITypedElement element, CompareConfiguration cc) { 1660 String label = null; 1661 1662 if (element instanceof IEditableContent) { 1663 if (element instanceof IModificationDate) { 1665 IModificationDate md = (IModificationDate) element; 1666 Date dateFromLong = new Date(md.getModificationDate()); 1667 label = NLS.bind(TeamUIMessages.CompareFileRevisionEditorInput_workspace, new Object []{ element.getName(), getDateTimeFormat().format(dateFromLong)}); 1668 } else { 1669 label = element.getName(); 1670 } 1671 return label; 1672 1673 } else if (element instanceof FileRevisionTypedElement) { 1674 Object fileObject = ((FileRevisionTypedElement) element).getFileRevision(); 1675 1676 if (fileObject instanceof LocalFileRevision) { 1677 try { 1678 IStorage storage = ((LocalFileRevision) fileObject).getStorage(new NullProgressMonitor()); 1679 if (Utils.getAdapter(storage, IFileState.class) != null) { 1680 label = NLS.bind(TeamUIMessages.CompareFileRevisionEditorInput_localRevision, new Object []{element.getName(), ((FileRevisionTypedElement) element).getTimestamp()}); 1682 } 1683 } catch (CoreException e) { 1684 } 1685 } else { 1686 label = NLS.bind( 1687 TeamUIMessages.CompareFileRevisionEditorInput_repository, 1688 new Object []{ 1689 element.getName(), 1690 ((FileRevisionTypedElement) element).getContentIdentifier(), 1691 ((FileRevisionTypedElement) element).getAuthor() 1692 }); 1693 } 1694 } 1695 return label; 1696 } 1697 1698 private synchronized DateFormat getDateTimeFormat() { 1699 if (dateTimeFormat == null) 1700 dateTimeFormat = DateFormat.getDateTimeInstance(); 1701 return dateTimeFormat; 1702 } 1703 1704 public String getDescription() { 1705 try { 1706 if (file != null) 1707 return file.getRepositoryRelativePath(); 1708 } catch (CVSException e) { 1709 } 1711 return null; 1712 } 1713 1714 public boolean inputSet() { 1715 currentFileRevision = null; 1717 Object inputObj = getInput(); 1718 1719 ICVSFile cvsFile = getCVSFile(inputObj); 1720 if (cvsFile == null) 1721 return false; 1722 1723 1724 this.file = cvsFile; 1725 fileElement = null; 1726 1727 if (refreshCVSFileHistoryJob == null) 1728 refreshCVSFileHistoryJob = new RefreshCVSFileHistory(this); 1729 1730 boolean needRefresh = checkPreviousInput(); 1733 1734 if (inputObj instanceof CVSLocalFileRevision){ 1738 refreshCVSFileHistoryJob.setLocalFileRevision((CVSLocalFileRevision) inputObj); 1739 } else if (inputObj instanceof IFile) { 1740 refreshCVSFileHistoryJob.setLocalFileRevision(new CVSLocalFileRevision((IFile) inputObj)); 1741 } 1742 refreshCVSFileHistoryJob.setSelectLocal(inputObj instanceof CVSLocalFileRevision || inputObj instanceof IFile); 1745 1746 1747 if (needRefresh){ 1750 cvsFileHistory = new CVSFileHistory(cvsFile); 1751 cvsFileHistory.includeLocalRevisions(true); 1753 this.treeViewer.setInput(null); 1756 1757 linkWithEditor(); 1758 } 1759 1760 refreshHistory(needRefresh, !needRefresh, CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE); 1763 1764 if (toggleSearchAction!= null && toggleSearchAction.isChecked()){ 1765 searchField.selectAll(); 1766 } 1767 1768 return true; 1769 } 1770 1771 1772 1773 1778 public void linkWithEditor() { 1779 if (rulerSelectionListener != null) { 1780 rulerSelectionListener.dispose(); 1781 rulerSelectionListener= null; 1782 } 1783 1784 if (!getHistoryPageSite().isModal()) { 1785 IResource resource = file.getIResource(); 1786 if (resource instanceof IFile) { 1787 IFile file = (IFile) resource; 1788 rulerSelectionListener= new CVSRevisionAnnotationController(getHistoryPageSite().getWorkbenchPageSite().getPage(), file); 1789 } else { 1790 Object input = getInput(); 1791 if (input instanceof IStorageEditorInput) { 1792 IStorageEditorInput editorInput = (IStorageEditorInput) input; 1793 rulerSelectionListener= new CVSRevisionAnnotationController(getHistoryPageSite().getWorkbenchPageSite().getPage(), editorInput); 1794 } 1795 } 1796 } 1797 } 1798 1799 1803 private boolean checkPreviousInput() { 1804 1805 if (previousFile != null){ 1806 try { 1807 if (isSameRemote(file, previousFile) 1808 && (isSameLocalFile(file, previousFile) 1809 || (!isLocal(file) && isLocal(previousFile)))) { 1810 return false; 1811 } 1812 } catch (CVSException e) { 1813 } 1814 } 1815 1816 previousFile = file; 1818 return true; 1819 } 1820 1821 private boolean isLocal(ICVSFile file) { 1822 return file.getIResource() != null; 1823 } 1824 1825 private boolean isSameLocalFile(ICVSFile file, ICVSFile previousFile) { 1826 IResource r1 = file.getIResource(); 1827 IResource r2 = previousFile.getIResource(); 1828 return r1 != null && r2 != null && r1.equals(r2); 1829 } 1830 1831 private boolean isSameRemote(ICVSFile file, ICVSFile previousFile) throws CVSException { 1832 String path = file.getRepositoryRelativePath(); 1833 String previousPath = previousFile.getRepositoryRelativePath(); 1834 1835 if (path == null && previousPath == null) 1837 return true; 1838 1839 return (path != null && previousPath != null && path.equals(previousPath) && isSameRepository(file.getParent(), previousFile.getParent())); 1840 } 1841 1842 1843 private boolean isSameRepository(ICVSFolder parent1, ICVSFolder parent2) { 1844 try { 1845 FolderSyncInfo info1 = parent1.getFolderSyncInfo(); 1846 FolderSyncInfo info2 = parent2.getFolderSyncInfo(); 1847 return (info1 != null && info2 != null && info1.getRemoteLocation().equals(info2.getRemoteLocation())); 1848 } catch (CVSException e) { 1849 } 1851 return false; 1852 } 1853 1854 private void updateFilterMode(int mode) { 1855 currentFilerMode=mode; 1856 switch(mode){ 1857 case LOCAL_MODE: 1858 localFilteredOut = false; 1859 remoteFilteredOut = true; 1860 localMode.setChecked(true); 1861 remoteMode.setChecked(false); 1862 remoteLocalMode.setChecked(false); 1863 break; 1864 1865 case REMOTE_MODE: 1866 localFilteredOut = true; 1867 remoteFilteredOut = false; 1868 localMode.setChecked(false); 1869 remoteMode.setChecked(true); 1870 remoteLocalMode.setChecked(false); 1871 break; 1872 1873 case REMOTE_LOCAL_MODE: 1874 localFilteredOut = false; 1875 remoteFilteredOut = false; 1876 localMode.setChecked(false); 1877 remoteMode.setChecked(false); 1878 remoteLocalMode.setChecked(true); 1879 break; 1880 } 1881 1882 if (refreshCVSFileHistoryJob != null){ 1885 refreshHistory(false, false, CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE); 1888 } 1889 } 1890 1891 public TreeViewer getTreeViewer() { 1892 return treeViewer; 1893 } 1894 1895 public void showFilter(CVSHistoryFilter filter) { 1896 if (historyFilter != null) 1897 treeViewer.removeFilter(historyFilter); 1898 1899 historyFilter = filter; 1900 int before = cvsFileHistory.getFileRevisions().length; 1901 treeViewer.addFilter(historyFilter); 1902 IHistoryPageSite historyPageSite =getHistoryPageSite(); 1903 if (historyPageSite instanceof WorkbenchHistoryPageSite){ 1904 IWorkbenchPart part = ((WorkbenchHistoryPageSite) historyPageSite).getPart(); 1905 if (part instanceof GenericHistoryView){ 1906 String revisions = NLS.bind(CVSUIMessages.CVSHistoryPage_FilterOnMessage, new Object []{new Integer (historyFilter.getMatchCount()),new Integer (before)}); 1907 String old = getName(); 1908 description = NLS.bind(CVSUIMessages.CVSHistoryPage_FilterDescription, new Object []{file.getName(), revisions}); 1909 CVSHistoryPage.this.firePropertyChange(CVSHistoryPage.this, P_NAME, old, getName()); 1910 } 1911 } 1912 toggleFilterAction.setEnabled(true); 1913 } 1914 1915 1919 public void setMode(int flag){ 1920 switch(flag){ 1921 case LOCAL_MODE: 1922 localMode.setChecked(true); 1923 localMode.run(); 1924 break; 1925 1926 case REMOTE_MODE: 1927 remoteMode.setChecked(true); 1928 remoteMode.run(); 1929 break; 1930 1931 case REMOTE_LOCAL_MODE: 1932 remoteLocalMode.setChecked(true); 1933 remoteLocalMode.run(); 1934 break; 1935 } 1936 1937 refreshHistory(true, false, CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE); 1939 } 1940 1941 1946 public void saveChanges(IProgressMonitor monitor) throws CoreException { 1947 if (fileElement instanceof LocalResourceTypedElement) { 1948 LocalResourceTypedElement element = (LocalResourceTypedElement) fileElement; 1949 element.commit(monitor); 1950 } 1951 } 1952 1953 private void setStatusLineMessage(String message) { 1954 IPageSite workbenchPageSite = getHistoryPageSite().getWorkbenchPageSite(); 1955 if (workbenchPageSite != null) { 1956 workbenchPageSite.getActionBars().getStatusLineManager().setMessage(message); 1957 } 1958 } 1959} 1960 | Popular Tags |