KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > ui > CVSHistoryPage


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Eugene Kuleshov <eu@md.pp.ru> - Bug 153932 [History] Custom hyperlink detectors for comments in History view
11  * Brock Janiczak (brockj@tpg.com.au) - Bug 181899 CVS History wrongly ordered
12  *******************************************************************************/

13
14 package org.eclipse.team.internal.ccvs.ui;
15
16 import java.io.InputStream JavaDoc;
17 import java.lang.reflect.InvocationTargetException JavaDoc;
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     /* private */ ICVSFile file;
85     /* private */ ICVSFile previousFile;
86     /* private */ IFileRevision currentFileRevision;
87     private ITypedElement fileElement;
88     
89     // cached for efficiency
90
/* private */ CVSFileHistory cvsFileHistory;
91     /* private */IFileRevision[] entries;
92
93     /* private */CVSHistoryTableProvider historyTableProvider;
94
95     /* private */TreeViewer treeViewer;
96     /* private */TextViewer textViewer;
97     /* private */TableViewer tagViewer;
98
99     /* private */CompareRevisionAction compareAction;
100     /* private */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     /* private */RefreshCVSFileHistory refreshCVSFileHistoryJob;
132
133     /* private */boolean shutdown = false;
134
135     /* private */boolean localFilteredOut = false;
136     /* private */boolean remoteFilteredOut = false;
137     
138     private HistoryResourceListener resourceListener;
139     
140     //toggle constants for default click action
141
private boolean compareMode = false;
142     
143     //filter constants
144
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     //current filter mode
149
private int currentFilerMode = 0;
150     
151     //text field used for search
152
private Text searchField;
153     
154     //grouping on
155
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 JavaDoc description;
163     
164     public CVSHistoryPage(Object JavaDoc 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         //Find field
181
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", //$NON-NLS-1$
213
new IAdaptable() {
214               public Object JavaDoc getAdapter(Class JavaDoc 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 JavaDoc[] getElements(Object JavaDoc inputElement) {
246                 if (inputElement == null)
247                     return new Object JavaDoc[0];
248                 ITag[] tags = (ITag[]) inputElement;
249                 return tags;
250             }
251         });
252         result.setLabelProvider(new LabelProvider() {
253             public Image getImage(Object JavaDoc 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 JavaDoc getText(Object JavaDoc element) {
271                 return ((ITag) element).getName();
272             }
273         });
274         result.setComparator(new ViewerComparator() {
275             public int compare(Viewer viewer, Object JavaDoc e1, Object JavaDoc 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         //Refresh
303
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         //Local Mode
313
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         //Remote Mode
328
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         //Remote + Local Mode
342
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         //set the inital filter to both remote and local
356
updateFilterMode(store.getInt(ICVSUIConstants.PREF_REVISION_MODE));
357         
358         //Group by Date
359
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         //Collapse All
373
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         //Compare Mode Action
383
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         // Click Compare action
395
compareAction = new CompareRevisionAction(CVSUIMessages.CVSHistoryPage_CompareRevisionAction);
396         treeViewer.getTree().addSelectionListener(new SelectionAdapter(){
397             public void widgetSelected(SelectionEvent e) {
398                 //update the current
399
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 JavaDoc[] {getCurrentFileRevision(), tableStructuredSelection.getFirstElement()});
420                         compareAction.selectionChanged(sel);
421                         compareAction.run();
422                     } else {
423                         //Pass in the entire structured selection to allow for multiple editor openings
424
StructuredSelection sel = tableStructuredSelection;
425                         openAction.selectionChanged(sel);
426                         openAction.run();
427                     }
428                 }
429             }
430         });
431
432         getContentsAction = getContextMenuAction(CVSUIMessages.HistoryView_getContentsAction, true /* needs progress */, 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 JavaDoc 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 /* needs progress */, 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 JavaDoc() {
466                                 public void run() {
467                                     refresh();
468                                 }
469                             });
470                         }
471                     }
472                 } catch (InvocationTargetException JavaDoc e) {
473                     CVSException.wrapException(e);
474                 } catch (InterruptedException JavaDoc e) {
475                     // Cancelled by user
476
}
477             }
478         });
479         PlatformUI.getWorkbench().getHelpSystem().setHelp(getRevisionAction, IHelpContextIds.GET_FILE_REVISION_ACTION);
480
481         // Override MoveRemoteTagAction to work for log entries
482
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 JavaDoc 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 JavaDoc 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             /*
514              * Override the creation of the tag operation in order to support
515              * the refresh of the view after the tag operation completes
516              */

517             protected ITagOperation createTagOperation() {
518                 return new TagInRepositoryOperation(getTargetPart(), getSelectedRemoteResources()) {
519                     public void execute(IProgressMonitor monitor) throws CVSException, InterruptedException JavaDoc {
520                         super.execute(monitor);
521                         Display.getDefault().asyncExec(new Runnable JavaDoc() {
522                             public void run() {
523                                 if( ! wasCancelled()) {
524                                     refresh();
525                                 }
526                             }
527                         });
528                     };
529                 };
530             }
531         };
532         tagWithExistingAction = getContextMenuAction(CVSUIMessages.HistoryView_tagWithExistingAction, false /* no progress */, 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         // Toggle text visible action
541
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         //PlatformUI.getWorkbench().getHelpSystem().setHelp(toggleTextAction, IHelpContextIds.SHOW_COMMENT_IN_HISTORY_ACTION);
549

550         // Toggle wrap comments action
551
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         //PlatformUI.getWorkbench().getHelpSystem().setHelp(toggleTextWrapAction, IHelpContextIds.SHOW_TAGS_IN_HISTORY_ACTION);
559

560         // Toggle list visible action
561
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         //PlatformUI.getWorkbench().getHelpSystem().setHelp(toggleListAction, IHelpContextIds.SHOW_TAGS_IN_HISTORY_ACTION);
569

570         //Toggle search field
571
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         //PlatformUI.getWorkbench().getHelpSystem().setHelp(toggleListAction, IHelpContextIds.SHOW_TAGS_IN_HISTORY_ACTION);
587

588         toggleFilterAction = new Action(CVSUIMessages.CVSHistoryPage_NoFilter){
589             public void run(){
590                 if (historyFilter != null)
591                     treeViewer.removeFilter(historyFilter);
592                     historyFilter = null;
593                     String JavaDoc 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         //Create the filter action
602
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         //Contribute actions to popup menu
609
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         //Don't add the object contribution menu items if this page is hosted in a dialog
619
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                 // Contribute toggle text visible to the toolbar drop-down
630
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                 // Create actions for the text editor
643
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         //Create the local tool bar
658
IToolBarManager tbm = parentSite.getToolBarManager();
659         if (tbm != null) {
660             String JavaDoc fileNameQualifier = getFileNameQualifier();
661             //Add groups
662
tbm.add(new Separator(fileNameQualifier + "grouping")); //$NON-NLS-1$
663
tbm.appendToGroup(fileNameQualifier+"grouping", groupByDateMode); //$NON-NLS-1$
664
tbm.add(new Separator(fileNameQualifier+"modes")); //$NON-NLS-1$
665
tbm.appendToGroup(fileNameQualifier+"modes", remoteLocalMode); //$NON-NLS-1$
666
tbm.appendToGroup(fileNameQualifier+"modes", localMode); //$NON-NLS-1$
667
tbm.appendToGroup(fileNameQualifier+"modes", remoteMode); //$NON-NLS-1$
668
tbm.add(new Separator(fileNameQualifier+"collapse")); //$NON-NLS-1$
669
tbm.appendToGroup(fileNameQualifier+"collapse", collapseAll); //$NON-NLS-1$
670
if (!parentSite.isModal()) {
671                 //don't bother adding the compare mode toolbar button if in
672
//a dialog; you can only compare from dialogs
673
tbm.appendToGroup(fileNameQualifier+"collapse", compareModeAction); //$NON-NLS-1$
674
}
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 JavaDoc getFileNameQualifier() {
691         //Just append the current system time to generate a unique group name
692
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     /* private */ void fillTableMenu(IMenuManager manager) {
704         // file actions go first (view file)
705
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")); //$NON-NLS-1$
712
}
713         if (file != null &&
714           !(file instanceof RemoteFile)) {
715             // Add the "Add to Workspace" action if 1 revision is selected.
716
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")); //$NON-NLS-1$
735
manager.add(refreshAction);
736             manager.add(new Separator("additions-end")); //$NON-NLS-1$
737
}
738     }
739
740     private void fillTextMenu(IMenuManager manager) {
741         manager.add(copyAction);
742         manager.add(selectAllAction);
743     }
744     
745     /**
746      * Creates the group that displays lists of the available repositories and
747      * team streams.
748      *
749      * @param the
750      * parent composite to contain the group
751      * @return the group control
752      */

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 JavaDoc[] getElements(Object JavaDoc inputElement) {
760
761                 // The entries of already been fetch so return them
762
if (entries != null)
763                     return entries;
764                 
765                 if (!(inputElement instanceof IFileHistory) &&
766                     !(inputElement instanceof AbstractHistoryCategory[]))
767                     return new Object JavaDoc[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 JavaDoc oldInput, Object JavaDoc newInput) {
783                 entries = null;
784             }
785
786             public Object JavaDoc[] getChildren(Object JavaDoc parentElement) {
787                 if (parentElement instanceof AbstractHistoryCategory){
788                     return ((AbstractHistoryCategory) parentElement).getRevisions();
789                 }
790                 
791                 return null;
792             }
793
794             public Object JavaDoc getParent(Object JavaDoc element) {
795                 return null;
796             }
797
798             public boolean hasChildren(Object JavaDoc 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("")); //$NON-NLS-1$
813
tagViewer.setInput(null);
814                     setStatusLineMessage(null);
815                     return;
816                 }
817                 IStructuredSelection ss = (IStructuredSelection)selection;
818                 if (ss.size() != 1) {
819                     textViewer.setDocument(new Document("")); //$NON-NLS-1$
820
tagViewer.setInput(null);
821                     setStatusLineMessage(null);
822                     return;
823                 }
824                 Object JavaDoc o = ss.getFirstElement();
825                 if (o instanceof AbstractHistoryCategory){
826                     textViewer.setDocument(new Document("")); //$NON-NLS-1$
827
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 JavaDoc 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 JavaDoc 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 JavaDoc, InterruptedException JavaDoc {
858                                 try {
859                                     action.run(monitor);
860                                 } catch (CoreException e) {
861                                     throw new InvocationTargetException JavaDoc(e);
862                                 }
863                             }
864                         });
865                     } else {
866                         try {
867                             action.run(null);
868                         } catch (CoreException e) {
869                             throw new InvocationTargetException JavaDoc(e);
870                         }
871                     }
872                 } catch (InvocationTargetException JavaDoc e) {
873                     IHistoryPageSite parentSite = getHistoryPageSite();
874                     CVSUIPlugin.openError(parentSite.getShell(), null, null, e, CVSUIPlugin.LOG_NONTEAM_EXCEPTIONS);
875                 } catch (InterruptedException JavaDoc e) {
876                     // Do nothing
877
}
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 JavaDoc title = CVSUIMessages.HistoryView_overwriteTitle;
895                     String JavaDoc msg = CVSUIMessages.HistoryView_overwriteMsg;
896                     IHistoryPageSite parentSite = getHistoryPageSite();
897                     final MessageDialog dialog = new MessageDialog(parentSite.getShell(), title, null, msg, MessageDialog.QUESTION, new String JavaDoc[] { IDialogConstants.YES_LABEL, IDialogConstants.CANCEL_LABEL }, 0);
898                     final int[] result = new int[1];
899                     parentSite.getShell().getDisplay().syncExec(new Runnable JavaDoc() {
900                     public void run() {
901                         result[0] = dialog.open();
902                     }});
903                     if (result[0] != 0) {
904                         // cancel
905
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 JavaDoc[]{file.getName()}), factory.getDelta(), new String JavaDoc[0], true /* syncExec */);
920         }
921         
922         return false;
923     }
924
925     /*
926      * Refresh the view by refetching the log entries for the remote file
927      */

928     public void refresh() {
929         refresh(CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE);
930     }
931     
932     public void refresh(int refreshFlags) {
933         //refetch revisions, not a select only job
934
// TODO
935
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         //if we need to refetch it's not a select only job and vice versa
949
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     /**
967      * Select the revision in the receiver.
968      */

969     public void selectRevision(String JavaDoc 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             //nothing to select so clear selection
980
treeViewer.getTree().deselectAll();
981         }
982     }
983     
984     private IFileRevision getFileRevision(String JavaDoc 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     /**
998      * Select the local revision in the receiver. Local revisions are differentiated by their
999      * timestamps.
1000     */

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            //nothing to select so clear selection
1027
treeViewer.getTree().deselectAll();
1028        }
1029    }
1030    
1031    protected static ICVSFile getCVSFile(Object JavaDoc object) {
1032        // First, adapt to IResource and ensure mapped to CVS
1033
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        // Second, try ICVSFile
1041
ICVSFile remoteFile = (ICVSFile)Utils.getAdapter(object, ICVSFile.class);
1042        if (remoteFile != null) {
1043            return remoteFile;
1044        }
1045        // Next, try ICVSResource
1046
ICVSResource remote = (ICVSResource)Utils.getAdapter(object, ICVSResource.class);
1047        if (remote instanceof RemoteFile) {
1048            return (ICVSFile)remote;
1049        }
1050        // Next, try IResourceVariant
1051
IResourceVariant variant = (IResourceVariant)Utils.getAdapter(object, IResourceVariant.class);
1052        if (variant instanceof RemoteFile) {
1053            return (ICVSFile)remote;
1054        }
1055        // Finally, try IFileRevision
1056
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    /* private */void setViewerVisibility() {
1065        boolean showText = toggleTextAction.isChecked();
1066        boolean showList = toggleListAction.isChecked();
1067        boolean showSearch = toggleSearchAction.isChecked();
1068        
1069        //check to see if this page is being shown in a dialog, in which case
1070
//don't show the text and list panes
1071
IHistoryPageSite parentSite = getHistoryPageSite();
1072        if (parentSite.isModal()){
1073            showText = false;
1074            showList = false;
1075        }
1076
1077        
1078        if (showText && showList && showSearch) {
1079            //tree + 1 + 2 + search
1080
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            //tree + 1 + search
1086
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            //tree + 2 + search
1092
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            //tree + search
1098
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            //tree + 1 + 2
1104
sashForm.setWeights(new int[] {70, 30, 0});
1105            sashForm.setMaximizedControl(null);
1106            innerSashForm.setMaximizedControl(null);
1107            searchSashForm.setMaximizedControl(searchField);
1108        } else if (showText) {
1109            //tree + 1
1110
sashForm.setWeights(new int[] {70, 30, 0});
1111            sashForm.setMaximizedControl(null);
1112            innerSashForm.setMaximizedControl(textViewer.getTextWidget());
1113        } else if (showList) {
1114            //tree + 2
1115
sashForm.setWeights(new int[] {70, 30, 0});
1116            sashForm.setMaximizedControl(null);
1117            innerSashForm.setMaximizedControl(tagViewer.getTable());
1118        } else {
1119            //tree
1120
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        //Cancel any incoming
1155
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                //Case 1 : file is remote
1169
if (file instanceof RemoteFile) {
1170                    RemoteFile remote = (RemoteFile) file;
1171                    currentFileRevision = cvsFileHistory.getFileRevision(remote.getContentIdentifier());
1172                    //remote.getContents(monitor);
1173
//currentFileRevision = new CVSFileRevision(remote.getLogEntry(monitor));
1174
return currentFileRevision;
1175                }
1176                //Case 2 : file is local
1177
//if (file.isModified(monitor)) {
1178
//file has been modified locally
1179
IFile localFile = (IFile) file.getIResource();
1180                if (localFile != null) {
1181                    //make sure that there's actually a resource associated with the file
1182
currentFileRevision = new LocalFileRevision(localFile);
1183                } else {
1184                    //no local version exists
1185
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 JavaDoc getHistoryEntry(Revision selected) {
1208            return CVSHistoryPage.this.getFileRevision(selected.getId());
1209        }
1210    }
1211
1212
1213    private final class SearchHistoryTable implements Runnable JavaDoc {
1214        public void run() {
1215            String JavaDoc searchString = searchField.getText();
1216            if (searchString.equals("") || //$NON-NLS-1$
1217
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 JavaDoc[] 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                //If fileHistory terminates in a bad way, try to fetch the local
1304
//revisions only
1305
boolean localFetched = false;
1306                boolean needsUpdate = true;
1307                if (!fileHistory.isInitialized() && fileHistory.isIncludeLocal() && (refreshFlags & CVSFileHistory.REFRESH_REMOTE) > 0) {
1308                    // If this is the first refresh, show the local history before hitting the server
1309
try {
1310                        fileHistory.refresh(CVSFileHistory.REFRESH_LOCAL, monitor);
1311                        updateTable();
1312                        localFetched = true;
1313                        needsUpdate = false;
1314                    } catch (TeamException e) {
1315                        // Ignore and try the full refresh
1316
}
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                            // Ignore and allow the original exception to go through
1328
}
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 JavaDoc() {
1349                public void run() {
1350                    historyTableProvider.setLocalRevisionsDisplayed(fileHistory.isIncludeLocal());
1351                    historyTableProvider.setFile(fileHistory, workspaceFile);
1352                    //historyTableProvider.setWorkspaceFile(workspaceFile);
1353
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 user is switching modes and already has expanded elements
1360
//selected try to expand those, else expand all
1361
if (elementsToExpand.length > 0)
1362                                treeViewer.setExpandedElements(elementsToExpand);
1363                            else {
1364                                treeViewer.expandAll();
1365                                Object JavaDoc[] 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                    //Update the history (if it exists) to reflect the new
1384
//counts
1385
if (historyFilter != null){
1386                        CVSHistoryFilter tempFilter = new CVSHistoryFilter(historyFilter.author, historyFilter.comment, historyFilter.fromDate, historyFilter.toDate, historyFilter.isOr);
1387                        showFilter(tempFilter);
1388                    }
1389                    
1390                    //Select the current file if we didn't have to refetch the history
1391
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 JavaDoc 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 JavaDoc[] expandedElements) {
1410            //store the names of the currently expanded categories in a map
1411
HashMap elementMap = new HashMap();
1412            for (int i=0; i<expandedElements.length; i++){
1413                elementMap.put(((DateHistoryCategory)expandedElements[i]).getName(), null);
1414            }
1415            
1416            //Go through the new categories and keep track of the previously expanded ones
1417
ArrayList expandable = new ArrayList();
1418            for (int i = 0; i<categories.length; i++){
1419                //check to see if this category is currently expanded
1420
if (elementMap.containsKey(categories[i].getName())){
1421                    expandable.add(categories[i]);
1422                }
1423            }
1424            
1425            elementsToExpand = new Object JavaDoc[expandable.size()];
1426            elementsToExpand = (Object JavaDoc[]) expandable.toArray(new Object JavaDoc[expandable.size()]);
1427        }
1428
1429        private boolean sortRevisions() {
1430            IFileRevision[] fileRevision = fileHistory.getFileRevisions();
1431            
1432            //Create the 4 categories
1433
DateHistoryCategory[] tempCategories = new DateHistoryCategory[NUMBER_OF_CATEGORIES];
1434            //Get a calendar instance initialized to the current time
1435
Calendar currentCal = Calendar.getInstance();
1436            tempCategories[0] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_Today, currentCal, null);
1437            //Get yesterday
1438
Calendar yesterdayCal = Calendar.getInstance();
1439            yesterdayCal.roll(Calendar.DAY_OF_YEAR, -1);
1440            tempCategories[1] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_Yesterday, yesterdayCal, null);
1441            //Get this month
1442
Calendar monthCal = Calendar.getInstance();
1443            monthCal.set(Calendar.DAY_OF_MONTH, 1);
1444            tempCategories[2] = new DateHistoryCategory(CVSUIMessages.CVSHistoryPage_ThisMonth, monthCal, yesterdayCal);
1445            //Everything before this month is previous
1446
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            //Assume that some revisions have been found
1456
boolean revisionsFound = true;
1457            
1458            if (finalCategories.size() == 0){
1459                //no revisions found for the current mode, so add a message category
1460
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 JavaDoc message = ""; //$NON-NLS-1$
1470
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 JavaDoc[] { 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    /**
1502     * A default content provider to prevent subclasses from
1503     * having to implement methods they don't need.
1504     */

1505    private class SimpleContentProvider implements IStructuredContentProvider {
1506
1507        /**
1508         * SimpleContentProvider constructor.
1509         */

1510        public SimpleContentProvider() {
1511            super();
1512        }
1513
1514        /*
1515         * @see SimpleContentProvider#dispose()
1516         */

1517        public void dispose() {
1518        }
1519
1520        /*
1521         * @see SimpleContentProvider#getElements()
1522         */

1523        public Object JavaDoc[] getElements(Object JavaDoc element) {
1524            return new Object JavaDoc[0];
1525        }
1526
1527        /*
1528         * @see SimpleContentProvider#inputChanged()
1529         */

1530        public void inputChanged(Viewer viewer, Object JavaDoc oldInput, Object JavaDoc newInput) {
1531        }
1532    }
1533
1534    private class HistoryResourceListener implements IResourceChangeListener {
1535        /**
1536         * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent)
1537         */

1538        public void resourceChanged(IResourceChangeEvent event) {
1539            IResourceDelta root = event.getDelta();
1540            //Safety check for non-managed files that are added with the CVSHistoryPage
1541
//in view
1542
if (file == null || file.getIResource() == null)
1543                 return;
1544            
1545            IResourceDelta resourceDelta = root.findMember(((IFile)file.getIResource()).getFullPath());
1546            if (resourceDelta != null){
1547                String JavaDoc revision = getRevision();
1548                final boolean hasRevision = cvsFileHistory.getFileRevision(revision) != null;
1549                Display.getDefault().asyncExec(new Runnable JavaDoc() {
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 JavaDoc 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                // Ignore the errors
1574
}
1575            return null;
1576        }
1577    }
1578        
1579    public Control getControl() {
1580        return sashForm;
1581    }
1582
1583    public boolean isValidInput(Object JavaDoc object) {
1584        ICVSFile file = getCVSFile(object);
1585        return file != null;
1586    }
1587
1588    public String JavaDoc getName() {
1589        if (description != null)
1590            return description;
1591        if (file != null)
1592            return file.getName();
1593        
1594        return ""; //$NON-NLS-1$
1595
}
1596    
1597    /**
1598     * Returns the path of the file currently being shown in the CVS History Page.
1599     * @return an IPath or <code>null</code> if the file is null
1600     */

1601    public IPath getFilePath() {
1602        if (file != null)
1603            return file.getIResource().getFullPath();
1604        
1605        return null;
1606    }
1607
1608    public Object JavaDoc getAdapter(Class JavaDoc adapter) {
1609        if(adapter == IHistoryCompareAdapter.class) {
1610            return this;
1611        }
1612        return null;
1613    }
1614
1615    public ICompareInput getCompareInput(Object JavaDoc 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 JavaDoc 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        //toggleCompareAction is going to switch the mode
1642
//so make sure that we're in the appropriate mode before
1643
compareMode = !compare;
1644        compareModeAction.run();
1645    }
1646
1647    public void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) {
1648        initLabels(input, configuration);
1649        // TODO: pre-fetch contents
1650
}
1651    
1652    private void initLabels(ICompareInput input, CompareConfiguration cc) {
1653        String JavaDoc leftLabel = getFileRevisionLabel(input.getLeft(), cc);
1654        cc.setLeftLabel(leftLabel);
1655        String JavaDoc rightLabel = getFileRevisionLabel(input.getRight(), cc);
1656        cc.setRightLabel(rightLabel);
1657    }
1658
1659    private String JavaDoc getFileRevisionLabel(ITypedElement element, CompareConfiguration cc) {
1660        String JavaDoc label = null;
1661
1662        if (element instanceof IEditableContent) {
1663            //current revision
1664
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 JavaDoc[]{ element.getName(), getDateTimeFormat().format(dateFromLong)});
1668            } else {
1669                label = element.getName();
1670            }
1671            return label;
1672
1673        } else if (element instanceof FileRevisionTypedElement) {
1674            Object JavaDoc 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                        //local revision
1681
label = NLS.bind(TeamUIMessages.CompareFileRevisionEditorInput_localRevision, new Object JavaDoc[]{element.getName(), ((FileRevisionTypedElement) element).getTimestamp()});
1682                    }
1683                } catch (CoreException e) {
1684                }
1685            } else {
1686                label = NLS.bind(
1687                        TeamUIMessages.CompareFileRevisionEditorInput_repository,
1688                        new Object JavaDoc[]{
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 JavaDoc getDescription() {
1705        try {
1706            if (file != null)
1707                return file.getRepositoryRelativePath();
1708        } catch (CVSException e) {
1709            // Ignore
1710
}
1711        return null;
1712    }
1713
1714    public boolean inputSet() {
1715        //reset currentFileRevision
1716
currentFileRevision = null;
1717        Object JavaDoc 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        //if this input is the same as the last, don't refetch the history
1731
//just update the selection
1732
boolean needRefresh = checkPreviousInput();
1733        
1734        //if the input is a local file revision, pass it to the refresh job to
1735
//allow the refresh job to use it to match the time stamp of the local
1736
//files displayed in the history page
1737
if (inputObj instanceof CVSLocalFileRevision){
1738            refreshCVSFileHistoryJob.setLocalFileRevision((CVSLocalFileRevision) inputObj);
1739        } else if (inputObj instanceof IFile) {
1740            refreshCVSFileHistoryJob.setLocalFileRevision(new CVSLocalFileRevision((IFile) inputObj));
1741        }
1742        //let the refresh job know which flavour of select to use (ie. select CVSFileRevisions
1743
//or CVSLocalFileRevision)
1744
refreshCVSFileHistoryJob.setSelectLocal(inputObj instanceof CVSLocalFileRevision || inputObj instanceof IFile);
1745        
1746        
1747        //If the file history doesn't need to be refreshed, we can just
1748
//use the previous input file history
1749
if (needRefresh){
1750            cvsFileHistory = new CVSFileHistory(cvsFile);
1751            //fetch both local and remote revisions the first time around
1752
cvsFileHistory.includeLocalRevisions(true);
1753            //blank current input only after we're sure that we have a file
1754
//to fetch history for
1755
this.treeViewer.setInput(null);
1756            
1757            linkWithEditor();
1758        }
1759        
1760        //always refresh the history if the input gets set - in which
1761
//case set the selectOnly to false
1762
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    /**
1774     * @param page the workbench page that view and editor are contained in
1775     * @param editor the editor to link to the history view
1776     * @param historyView the history view to link to the editor
1777     */

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 JavaDoc 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    /*
1800     * Check to see if we need to refresh the input; if the previous file
1801     * that was being shown
1802     */

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        //set previous file to current file
1817
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 JavaDoc path = file.getRepositoryRelativePath();
1833        String JavaDoc previousPath = previousFile.getRepositoryRelativePath();
1834        
1835        //Could be comparing two local files with no remotes
1836
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            // Ignore
1850
}
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        //the refresh job gets created once the input is set
1883
//don't bother trying to refresh any history until the input has been set
1884
if (refreshCVSFileHistoryJob != null){
1885            //don't refetch, but not a select only job (ie. have to get the
1886
//existing revisions corresponding to the mode change)
1887
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 JavaDoc revisions = NLS.bind(CVSUIMessages.CVSHistoryPage_FilterOnMessage, new Object JavaDoc[]{new Integer JavaDoc(historyFilter.getMatchCount()),new Integer JavaDoc(before)});
1907                String JavaDoc old = getName();
1908                description = NLS.bind(CVSUIMessages.CVSHistoryPage_FilterDescription, new Object JavaDoc[]{file.getName(), revisions});
1909                CVSHistoryPage.this.firePropertyChange(CVSHistoryPage.this, P_NAME, old, getName());
1910            }
1911        }
1912        toggleFilterAction.setEnabled(true);
1913    }
1914    
1915    /*
1916     * Sets the filter mode for the page.
1917     * param flag LOCAL_MODE, REMOTE_MODE, REMOTE_LOCAL_MODE
1918     */

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        //refetch revisions, not a select only job
1938
refreshHistory(true, false, CVSFileHistory.REFRESH_LOCAL | CVSFileHistory.REFRESH_REMOTE);
1939    }
1940
1941    /**
1942     * Save any changes that are buffered in the pages typed element.
1943     * @param monitor a progress monitor.
1944     * @throws CoreException
1945     */

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 JavaDoc message) {
1954        IPageSite workbenchPageSite = getHistoryPageSite().getWorkbenchPageSite();
1955        if (workbenchPageSite != null) {
1956            workbenchPageSite.getActionBars().getStatusLineManager().setMessage(message);
1957        }
1958    }
1959}
1960
Popular Tags