KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > ui > PageSaveablePart


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  *******************************************************************************/

11 package org.eclipse.team.ui;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Iterator JavaDoc;
16
17 import org.eclipse.compare.*;
18 import org.eclipse.compare.contentmergeviewer.IFlushable;
19 import org.eclipse.compare.internal.CompareEditor;
20 import org.eclipse.compare.internal.CompareEditorInputNavigator;
21 import org.eclipse.compare.structuremergeviewer.ICompareInput;
22 import org.eclipse.core.runtime.Assert;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.jface.action.ToolBarManager;
25 import org.eclipse.jface.operation.IRunnableWithProgress;
26 import org.eclipse.jface.util.IPropertyChangeListener;
27 import org.eclipse.jface.util.PropertyChangeEvent;
28 import org.eclipse.jface.viewers.*;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.events.DisposeEvent;
31 import org.eclipse.swt.events.DisposeListener;
32 import org.eclipse.swt.layout.GridData;
33 import org.eclipse.swt.layout.GridLayout;
34 import org.eclipse.swt.widgets.*;
35 import org.eclipse.team.internal.ui.TeamUIMessages;
36 import org.eclipse.team.internal.ui.Utils;
37 import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement;
38 import org.eclipse.team.internal.ui.synchronize.SynchronizePageConfiguration;
39 import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
40 import org.eclipse.ui.PlatformUI;
41 import org.eclipse.ui.progress.IProgressService;
42
43 /**
44  * Abstract class for hosting a page based structure input view for the purposes
45  * of feeding compare viewers.
46  * <p>
47  * This class is not intended to be subclassed by clients outside of the Team framework.
48  *
49  * @since 3.2
50  * @deprecated Clients should use a subclass of {@link CompareEditorInput}
51  * and {@link CompareUI#openCompareDialog(org.eclipse.compare.CompareEditorInput)}
52  */

53 public abstract class PageSaveablePart extends SaveablePartAdapter implements IContentChangeListener{
54     
55     private CompareConfiguration cc;
56     Shell shell;
57     
58     // Tracking of dirty state
59
private boolean fDirty= false;
60     private ArrayList JavaDoc fDirtyViewers= new ArrayList JavaDoc();
61     private IPropertyChangeListener fDirtyStateListener;
62     
63     // SWT controls
64
private CompareViewerSwitchingPane fContentPane;
65     private CompareViewerPane fEditionPane;
66     private CompareViewerSwitchingPane fStructuredComparePane;
67     private Control control;
68     
69     // Configuration options
70
private boolean showContentPanes = true;
71     
72     /**
73      * Create a saveable part.
74      * @param shell the shell for the part
75      * @param compareConfiguration the compare configuration
76      */

77     protected PageSaveablePart(Shell shell, CompareConfiguration compareConfiguration){
78         this.shell = shell;
79         this.cc = compareConfiguration;
80         
81         fDirtyStateListener= new IPropertyChangeListener() {
82             public void propertyChange(PropertyChangeEvent e) {
83                 String JavaDoc propertyName= e.getProperty();
84                 if (CompareEditorInput.DIRTY_STATE.equals(propertyName)) {
85                     boolean changed= false;
86                     Object JavaDoc newValue= e.getNewValue();
87                     if (newValue instanceof Boolean JavaDoc)
88                         changed= ((Boolean JavaDoc)newValue).booleanValue();
89                     setDirty(e.getSource(), changed);
90                 }
91             }
92         };
93     }
94
95     /* (non-Javadoc)
96      * @see org.eclipse.ui.ISaveablePart#isDirty()
97      */

98     public boolean isDirty() {
99         return fDirty || fDirtyViewers.size() > 0;
100     }
101
102     /* (non-Javadoc)
103      * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
104      */

105     public void createPartControl(Composite parent) {
106         Composite composite = new Composite(parent, SWT.NULL);
107         GridLayout layout = new GridLayout();
108         layout.marginHeight = 0;
109         layout.marginWidth = 0;
110         layout.verticalSpacing = 0;
111         GridData data = new GridData(GridData.FILL_BOTH);
112         data.grabExcessHorizontalSpace = true;
113         composite.setLayout(layout);
114         composite.setLayoutData(data);
115         
116         shell = parent.getShell();
117         
118         Splitter vsplitter = new Splitter(composite, SWT.VERTICAL);
119         vsplitter.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
120         // we need two panes: the left for the elements, the right one for the structured diff
121
Splitter hsplitter = new Splitter(vsplitter, SWT.HORIZONTAL);
122         fEditionPane = new CompareViewerPane(hsplitter, SWT.BORDER | SWT.FLAT);
123         fStructuredComparePane = new CompareViewerSwitchingPane(hsplitter, SWT.BORDER | SWT.FLAT, true) {
124             protected Viewer getViewer(Viewer oldViewer, Object JavaDoc input) {
125                 if (input instanceof ICompareInput)
126                     return findStructureViewer(this, oldViewer, (ICompareInput)input);
127                 return null;
128             }
129         };
130         fStructuredComparePane.addSelectionChangedListener(new ISelectionChangedListener() {
131             public void selectionChanged(SelectionChangedEvent e) {
132                 feedInput2(e.getSelection());
133             }
134         });
135         fEditionPane.setText(TeamUIMessages.ParticipantPageSaveablePart_0);
136         fContentPane = new CompareViewerSwitchingPane(vsplitter, SWT.BORDER | SWT.FLAT) {
137             protected Viewer getViewer(Viewer oldViewer, Object JavaDoc input) {
138                 if (!(input instanceof ICompareInput))
139                     return null;
140                 Viewer newViewer= findContentViewer(this, oldViewer, (ICompareInput)input);
141                 boolean isNewViewer= newViewer != oldViewer;
142                 if (isNewViewer && newViewer instanceof IPropertyChangeNotifier) {
143                     final IPropertyChangeNotifier dsp= (IPropertyChangeNotifier) newViewer;
144                     dsp.addPropertyChangeListener(fDirtyStateListener);
145                     Control c= newViewer.getControl();
146                     c.addDisposeListener(
147                         new DisposeListener() {
148                             public void widgetDisposed(DisposeEvent e) {
149                                 dsp.removePropertyChangeListener(fDirtyStateListener);
150                             }
151                         }
152                     );
153                     hookContentChangeListener((ICompareInput)input);
154                 }
155                 return newViewer;
156             }
157         };
158         vsplitter.setWeights(new int[]{30, 70});
159         
160         control = composite;
161         
162         ToolBarManager toolBarManager = CompareViewerPane.getToolBarManager(fEditionPane);
163         Control c = createPage(fEditionPane, toolBarManager);
164         fEditionPane.setContent(c);
165
166         if(! showContentPanes) {
167             hsplitter.setMaximizedControl(fEditionPane);
168         }
169         
170         getSelectionProvider().addSelectionChangedListener(new ISelectionChangedListener() {
171             public void selectionChanged(SelectionChangedEvent event) {
172                 ICompareInput input = getCompareInput(event.getSelection());
173                 if (input != null)
174                     prepareCompareInput(input);
175                 setInput(input);
176             }
177         });
178     }
179     
180     /**
181      * Return the selection provider for the page. This method is
182      * called after the page is created in order to register a
183      * selection listener on the page.
184      * @return the selection provider for the page
185      */

186     protected abstract ISelectionProvider getSelectionProvider();
187
188     /**
189      * Create the page for this part and return the top level control
190      * for the page.
191      * @param parent the parent composite
192      * @param toolBarManager the toolbar manager for the page
193      * @return the top-level control for the page
194      */

195     protected abstract Control createPage(Composite parent, ToolBarManager toolBarManager);
196     
197     /**
198      * Set the title of the page's page to the given text. The title
199      * will appear in the header of the pane containing the page.
200      * @param title the page's title
201      */

202     protected void setPageDescription(String JavaDoc title) {
203         fEditionPane.setText(title);
204     }
205     
206     /**
207      * Set the saveable part's dirty state to the given state.
208      * @param dirty the dirty state
209      */

210     protected void setDirty(boolean dirty) {
211         boolean confirmSave= true;
212         Object JavaDoc o= cc.getProperty(CompareEditor.CONFIRM_SAVE_PROPERTY);
213         if (o instanceof Boolean JavaDoc)
214             confirmSave= ((Boolean JavaDoc)o).booleanValue();
215
216         if (!confirmSave) {
217             fDirty= dirty;
218             if (!fDirty)
219                 fDirtyViewers.clear();
220         }
221     }
222     
223     private void setDirty(Object JavaDoc source, boolean dirty) {
224         Assert.isNotNull(source);
225         if (dirty)
226             fDirtyViewers.add(source);
227         else
228             fDirtyViewers.remove(source);
229     }
230     
231     /**
232      * Feeds input from the page into the content and structured viewers.
233      * @param input the input
234      */

235     private void setInput(Object JavaDoc input) {
236         CompareViewerPane pane = fContentPane;
237         if (pane != null && !pane.isDisposed())
238             fContentPane.setInput(input);
239         if (fStructuredComparePane != null && !fStructuredComparePane.isDisposed())
240             fStructuredComparePane.setInput(input);
241     }
242     
243     /*
244      * Feeds selection from structure viewer to content viewer.
245      */

246     private void feedInput2(ISelection sel) {
247         ICompareInput input = getCompareInput(sel);
248         prepareCompareInput(input);
249         if (input != null)
250             fContentPane.setInput(input);
251     }
252     
253     /**
254      * Convenience method that calls {@link #prepareInput(ICompareInput, CompareConfiguration, IProgressMonitor)}
255      * with a progress monitor.
256      * @param input the compare input to be prepared
257      */

258     protected void prepareCompareInput(final ICompareInput input) {
259         if (input == null)
260             return;
261         // Don't allow the use of shared documents with PageSaveableParts
262
Object JavaDoc left = input.getLeft();
263         if (left instanceof LocalResourceTypedElement) {
264             LocalResourceTypedElement lrte = (LocalResourceTypedElement) left;
265             lrte.enableSharedDocument(false);
266         }
267         IProgressService manager = PlatformUI.getWorkbench().getProgressService();
268         try {
269             // TODO: we need a better progress story here (i.e. support for cancellation) bug 127075
270
manager.busyCursorWhile(new IRunnableWithProgress() {
271                 public void run(IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
272                     prepareInput(input, getCompareConfiguration(), monitor);
273                     hookContentChangeListener(input);
274                 }
275             });
276         } catch (InvocationTargetException JavaDoc e) {
277             Utils.handle(e);
278         } catch (InterruptedException JavaDoc e) {
279             // Ignore
280
}
281     }
282     
283     /**
284      * Prepare the compare input for display in a content viewer. This method is
285      * called from {@link #prepareCompareInput(ICompareInput)} and may be called
286      * from a non-UI thread. This method should not be called by others.
287      * @param input the input
288      * @param configuration the compare configuration
289      * @param monitor a progress monitor
290      * @throws InvocationTargetException
291      */

292     protected abstract void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) throws InvocationTargetException JavaDoc;
293
294     private void hookContentChangeListener(ICompareInput node) {
295         // TODO: there is no unhook which may lead to a leak
296
ITypedElement left = node.getLeft();
297         if(left instanceof IContentChangeNotifier) {
298             ((IContentChangeNotifier)left).addContentChangeListener(this);
299         }
300         ITypedElement right = node.getRight();
301         if(right instanceof IContentChangeNotifier) {
302             ((IContentChangeNotifier)right).addContentChangeListener(this);
303         }
304     }
305     
306     /**
307      * Return the parent shell of this part.
308      * @return the parent shell of this part
309      */

310     protected Shell getShell() {
311         return shell;
312     }
313     
314     /**
315      * This method is internal to the framework and should not be called by clients
316      * outside of the framework.
317      */

318     protected void setNavigator(ISynchronizePageConfiguration configuration) {
319             configuration.setProperty(SynchronizePageConfiguration.P_NAVIGATOR, new CompareEditorInputNavigator(
320                 new Object JavaDoc[] {
321                     configuration.getProperty(SynchronizePageConfiguration.P_ADVISOR),
322                     fStructuredComparePane,
323                     fContentPane
324                 }
325             ));
326     }
327     
328     /*
329      * Find a viewer that can provide a structure view for the given compare input.
330      * Return <code>null</code> if a suitable viewer could not be found.
331      * @param parent the parent composite for the viewer
332      * @param oldViewer the viewer that is currently a child of the parent
333      * @param input the compare input to be viewed
334      * @return a viewer capable of displaying a structure view of the input or
335      * <code>null</code> if such a viewer is not available.
336      */

337     private Viewer findStructureViewer(Composite parent, Viewer oldViewer, ICompareInput input) {
338         return CompareUI.findStructureViewer(oldViewer, input, parent, cc);
339     }
340     
341     /*
342      * Find a viewer that can provide a content compare view for the given compare input.
343      * Return <code>null</code> if a suitable viewer could not be found.
344      * @param parent the parent composite for the viewer
345      * @param oldViewer the viewer that is currently a child of the parent
346      * @param input the compare input to be viewed
347      * @return a viewer capable of displaying a content compare view of the input or
348      * <code>null</code> if such a viewer is not available.
349      */

350     private Viewer findContentViewer(Composite parent, Viewer oldViewer, ICompareInput input) {
351         return CompareUI.findContentViewer(oldViewer, input, parent, cc);
352     }
353     
354     /**
355      * Return a compare input that represents the selection.
356      * This input is used to feed the structure and content
357      * viewers. By default, a compare input is returned if the selection is
358      * of size 1 and the selected element implements <code>ICompareInput</code>.
359      * Subclasses may override.
360      * @param selection the selection
361      * @return a compare input representing the selection
362      */

363     protected ICompareInput getCompareInput(ISelection selection) {
364         if (selection != null && selection instanceof IStructuredSelection) {
365             IStructuredSelection ss= (IStructuredSelection) selection;
366             if (ss.size() == 1) {
367                 Object JavaDoc o = ss.getFirstElement();
368                 if(o instanceof ICompareInput) {
369                     return (ICompareInput)o;
370                 }
371             }
372         }
373         return null;
374     }
375
376     /**
377      * Set whether the file contents panes should be shown. If they are not,
378      * only the page will be shown.
379      *
380      * @param showContentPanes whether to show contents pane
381      */

382     public void setShowContentPanes(boolean showContentPanes) {
383         this.showContentPanes = showContentPanes;
384     }
385
386     /**
387      * Returns the primary control for this part.
388      *
389      * @return the primary control for this part.
390      */

391     public Control getControl() {
392         return control;
393     }
394
395     /**
396      * Return the compare configuration.
397      * @return the compare configuration
398      */

399     private CompareConfiguration getCompareConfiguration() {
400         return cc;
401     }
402
403     /**
404      * This method flushes the content in any viewers. Subclasses should
405      * override if they need to perform additional processing when a save is
406      * performed.
407      *
408      * @param monitor
409      * a progress monitor
410      */

411     public void doSave(IProgressMonitor monitor) {
412         flushViewers(monitor);
413     }
414     
415     private void flushViewers(IProgressMonitor monitor) {
416         Iterator JavaDoc iter = fDirtyViewers.iterator();
417         
418         for (int i=0; i<fDirtyViewers.size(); i++){
419             Object JavaDoc element = iter.next();
420             IFlushable flushable = (IFlushable)Utils.getAdapter(element, IFlushable.class);
421             if (flushable != null)
422                 flushable.flush(monitor);
423         }
424     }
425
426 }
427
Popular Tags