KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > ui > memory > AbstractMemoryRendering


1 /*******************************************************************************
2  * Copyright (c) 2004, 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.debug.ui.memory;
12
13 import org.eclipse.core.runtime.IProgressMonitor;
14 import org.eclipse.core.runtime.IStatus;
15 import org.eclipse.core.runtime.ListenerList;
16 import org.eclipse.core.runtime.PlatformObject;
17 import org.eclipse.core.runtime.SafeRunner;
18 import org.eclipse.core.runtime.Status;
19 import org.eclipse.core.runtime.jobs.Job;
20 import org.eclipse.debug.core.DebugException;
21 import org.eclipse.debug.core.model.IMemoryBlock;
22 import org.eclipse.debug.core.model.IMemoryBlockExtension;
23 import org.eclipse.debug.internal.ui.views.memory.PropertyChangeNotifier;
24 import org.eclipse.debug.ui.DebugUITools;
25 import org.eclipse.jface.action.IMenuListener;
26 import org.eclipse.jface.action.IMenuManager;
27 import org.eclipse.jface.action.MenuManager;
28 import org.eclipse.jface.action.Separator;
29 import org.eclipse.jface.util.IPropertyChangeListener;
30 import org.eclipse.jface.util.PropertyChangeEvent;
31 import org.eclipse.jface.viewers.ILabelDecorator;
32 import org.eclipse.jface.viewers.ISelectionProvider;
33 import org.eclipse.swt.graphics.Image;
34 import org.eclipse.swt.widgets.Control;
35 import org.eclipse.swt.widgets.Menu;
36 import org.eclipse.ui.IWorkbenchActionConstants;
37
38 /**
39  * Abstract implementation of a memory rendering.
40  * <p>
41  * To contribute an action to a rendering, an <code>objectContribution</code> can
42  * be used on a rendering implementation class itself using a
43  * <code>popupMenus</code> extension. Additionally, the context menu created
44  * by <code>createPopupMenu()</code> is registered with an identifier of this
45  * rendering's container identifier. Actions may also be contributed to the
46  * container's context menu specifically by using a <code>viewerContribution</code>
47  * on a <code>popupMenus</code> extension that has a <code>targetID</code> referring
48  * to this rendering container's identifier.
49  * </p>
50  * <p>
51  * Clients implementing memory renderings must subclass this class.
52  * </p>
53  * @since 3.1
54  */

55 public abstract class AbstractMemoryRendering extends PlatformObject implements IMemoryRendering{
56
57     private IMemoryBlock fMemoryBlock;
58     private IMemoryRenderingContainer fContainer;
59     private ListenerList fPropertyListeners;
60     private boolean fVisible = true;
61     private MenuManager fPopupMenuMgr;
62     private String JavaDoc fRenderingId;
63     
64     private class ConnectionJob extends Job
65     {
66         Runnable JavaDoc fRunnable;
67         ConnectionJob(Runnable JavaDoc runnable)
68         {
69             super("Connect/Disconnect MemoryBlock"); //$NON-NLS-1$
70
fRunnable = runnable;
71             setSystem(true);
72         }
73
74         protected IStatus run(IProgressMonitor monitor) {
75             fRunnable.run();
76             return Status.OK_STATUS;
77         }
78     }
79     
80     /**
81      * Client may provide a label decorator adapter from its memory block
82      * to decorate the label of a rendering.
83      * @since 3.2
84      */

85     private ILabelDecorator fLabelDecorator;
86     private IMenuListener fMenuListener;
87     
88     /**
89      * Constructs a new rendering of the given type.
90      *
91      * @param renderingId memory rendering type identifier
92      */

93     public AbstractMemoryRendering(String JavaDoc renderingId)
94     {
95         fRenderingId = renderingId;
96     }
97     
98     /* (non-Javadoc)
99      * @see org.eclipse.debug.ui.memory.IMemoryRendering#init(org.eclipse.debug.ui.memory.IMemoryRenderingSite, org.eclipse.debug.core.model.IMemoryBlock)
100      */

101     public void init(IMemoryRenderingContainer container, IMemoryBlock block) {
102         fContainer = container;
103         fMemoryBlock = block;
104         
105         fLabelDecorator = (ILabelDecorator)fMemoryBlock.getAdapter(ILabelDecorator.class);
106     }
107
108     /* (non-Javadoc)
109      * @see org.eclipse.debug.ui.memory.IMemoryRendering#dispose()
110      */

111     public void dispose()
112     {
113         // disconnect from memory block when rendering is disposed
114
if (fMemoryBlock instanceof IMemoryBlockExtension)
115         {
116             Runnable JavaDoc runnable = new Runnable JavaDoc(){
117                 public void run() {
118                         ((IMemoryBlockExtension)fMemoryBlock).disconnect(this);
119                 }};
120             new ConnectionJob(runnable).schedule();
121         }
122         
123         if (fPopupMenuMgr != null)
124         {
125             fPopupMenuMgr.removeMenuListener(fMenuListener);
126             fPopupMenuMgr.removeAll();
127             fPopupMenuMgr.dispose();
128             fPopupMenuMgr = null;
129         }
130         
131         if (fPropertyListeners != null)
132             fPropertyListeners = null;
133     }
134
135     /* (non-Javadoc)
136      * @see org.eclipse.debug.ui.memory.IMemoryRendering#activated()
137      */

138     public void activated() {
139         if (fContainer.getMemoryRenderingSite().getSynchronizationService() != null)
140             fContainer.getMemoryRenderingSite().getSynchronizationService().setSynchronizationProvider(this);
141     }
142
143     /* (non-Javadoc)
144      * @see org.eclipse.debug.ui.memory.IMemoryRendering#deactivated()
145      */

146     public void deactivated() {
147         // do nothing when deactivated
148
// we do not want to set the sync provider from rendering site
149
// to null because Linux GTK unexpectedly fires deactivated event.
150
// If we reset the sync provider upon a deactivated event, it screws
151
// up synchronization on Linux GTK.
152
}
153
154     /* (non-Javadoc)
155      * @see org.eclipse.debug.ui.memory.IMemoryRendering#becomesVisible()
156      */

157     public void becomesVisible() {
158         fVisible = true;
159         
160         if (fMemoryBlock instanceof IMemoryBlockExtension)
161         {
162             Runnable JavaDoc runnable = new Runnable JavaDoc(){
163                 public void run() {
164                     ((IMemoryBlockExtension)fMemoryBlock).connect(this);
165                 }};
166             new ConnectionJob(runnable).schedule();
167         }
168     }
169
170     /* (non-Javadoc)
171      * @see org.eclipse.debug.ui.memory.IMemoryRendering#becomesHidden()
172      */

173     public void becomesHidden() {
174         fVisible = false;
175         if (fMemoryBlock instanceof IMemoryBlockExtension)
176         {
177             Runnable JavaDoc runnable = new Runnable JavaDoc(){
178                 public void run() {
179                         ((IMemoryBlockExtension)fMemoryBlock).disconnect(this);
180                 }};
181             new ConnectionJob(runnable).schedule();
182         }
183     }
184
185     /* (non-Javadoc)
186      * @see org.eclipse.debug.ui.memory.IMemoryRendering#getMemoryBlock()
187      */

188     public IMemoryBlock getMemoryBlock() {
189         return fMemoryBlock;
190     }
191
192     /* (non-Javadoc)
193      * @see org.eclipse.debug.ui.memory.IMemoryRendering#getRenderingId()
194      */

195     public String JavaDoc getRenderingId()
196     {
197         return fRenderingId;
198     }
199
200     /* (non-Javadoc)
201      * @see org.eclipse.debug.ui.memory.IMemoryRendering#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
202      */

203     public void addPropertyChangeListener(IPropertyChangeListener listener) {
204                 
205         if (fPropertyListeners == null)
206             fPropertyListeners = new ListenerList();
207         
208         fPropertyListeners.add(listener);
209     }
210
211     /* (non-Javadoc)
212      * @see org.eclipse.debug.ui.memory.IMemoryRendering#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
213      */

214     public void removePropertyChangeListener(IPropertyChangeListener listener) {
215         
216         if (fPropertyListeners == null)
217             return;
218         fPropertyListeners.remove(listener);
219     }
220
221     /* (non-Javadoc)
222      * @see org.eclipse.debug.ui.memory.IMemoryRendering#getImage()
223      */

224     public Image getImage() {
225         return decorateImage(null);
226     }
227     
228     /**
229      * Decorates and returns this rendering's image.
230      *
231      * @param image base image
232      * @return decorated image
233      * @since 3.2
234      */

235     protected Image decorateImage(Image image) {
236         if (fLabelDecorator != null)
237             return fLabelDecorator.decorateImage(image, this);
238         return image;
239     }
240
241     /* (non-Javadoc)
242      * @see org.eclipse.debug.ui.memory.IMemoryRendering#getLabel()
243      */

244     public String JavaDoc getLabel()
245     {
246         if (fMemoryBlock == null)
247             return ""; //$NON-NLS-1$
248

249         StringBuffer JavaDoc label = new StringBuffer JavaDoc(""); //$NON-NLS-1$
250

251         if (fMemoryBlock instanceof IMemoryBlockExtension)
252         {
253             String JavaDoc expression = ((IMemoryBlockExtension)fMemoryBlock).getExpression();
254             
255             if (expression == null)
256                 expression = ""; //$NON-NLS-1$
257

258             label.append(expression);
259             
260             if (expression.startsWith("&")) //$NON-NLS-1$
261
label.insert(0, "&"); //$NON-NLS-1$
262

263             // show full address if the rendering is visible
264
// hide address if the rendering is invisible
265
try {
266                 if (fVisible && ((IMemoryBlockExtension)fMemoryBlock).getBigBaseAddress() != null)
267                 {
268                     label.append(" : 0x"); //$NON-NLS-1$
269
label.append(((IMemoryBlockExtension)fMemoryBlock).getBigBaseAddress().toString(16).toUpperCase());
270                 }
271             } catch (DebugException e) {
272                 // do nothing... the label will not show memory block's address
273
}
274         }
275         else
276         {
277             long address = fMemoryBlock.getStartAddress();
278             label.append(Long.toHexString(address).toUpperCase());
279         }
280         
281         IMemoryRenderingType type = DebugUITools.getMemoryRenderingManager().getRenderingType(getRenderingId());
282         
283         if (type != null)
284         {
285             String JavaDoc preName = type.getLabel();
286             
287             if (preName != null)
288             {
289                 label.append(" <"); //$NON-NLS-1$
290
label.append(preName);
291                 label.append(">"); //$NON-NLS-1$
292
}
293         }
294         
295         return decorateLabel(label.toString());
296     }
297     
298     /**
299      * Decorates and returns this rendering's label.
300      *
301      * @param label base label
302      * @return decorated label
303      * @since 3.2
304      */

305     protected String JavaDoc decorateLabel(String JavaDoc label) {
306         if (fLabelDecorator != null)
307             return fLabelDecorator.decorateText(label.toString(), this);
308         return label.toString();
309     }
310     
311     /**
312      * Helper method for creating a pop up menu in the rendering for a control.
313      * Call this method when a context menu is required for a control
314      * in a rendering.
315      * <p>
316      * To contribute an action to a rendering, an <code>objectContribution</code> can
317      * be used on a rendering implementation class itself using a
318      * <code>popupMenus</code> extension. Additionally, the context menu created
319      * by this method is registered with an identifier of this rendering's container.
320      * Actions may also be contributed to the context menu specifically by using a
321      * <code>viewerContribution</code> on a <code>popupMenus</code> extension
322      * that has a <code>targetID</code> referring to this rendering container's identifier.
323      * </p>
324      * <p>
325      * Clients are expected to become a menu listener for their pop up
326      * menu if they require to fill the context menu for the rendering.
327      * </p>
328      * @param control - control to create the pop up menu for
329      */

330     protected void createPopupMenu(Control control)
331     {
332         if (fPopupMenuMgr == null)
333         {
334             fPopupMenuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
335
fPopupMenuMgr.setRemoveAllWhenShown(true);
336             IMemoryRenderingSite site = fContainer.getMemoryRenderingSite();
337             String JavaDoc menuId = fContainer.getId();
338                         
339             ISelectionProvider selProvider = site.getSite().getSelectionProvider();
340             
341             fMenuListener = new IMenuListener() {
342                             public void menuAboutToShow(IMenuManager manager) {
343                                 manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
344                             }};
345             fPopupMenuMgr.addMenuListener(fMenuListener);
346             
347             site.getSite().registerContextMenu(menuId, fPopupMenuMgr, selProvider);
348         }
349         
350         Menu popupMenu = fPopupMenuMgr.createContextMenu(control);
351         control.setMenu(popupMenu);
352     }
353     
354     /**
355      * Returns the pop up menu manager for this rendering, or <code>null</code>
356      * if none.
357      *
358      * @return the pop up menu manager for this rendering, or <code>null</code>
359      */

360     protected MenuManager getPopupMenuManager()
361     {
362         return fPopupMenuMgr;
363     }
364     
365     /**
366      * Fires the given event to all registered listeners.
367      *
368      * @param event the event to fire
369      */

370     protected void firePropertyChangedEvent(PropertyChangeEvent event)
371     {
372         if (fPropertyListeners == null)
373             return;
374         
375         Object JavaDoc[] listeners = fPropertyListeners.getListeners();
376         
377         for (int i=0; i<listeners.length; i++)
378         {
379             PropertyChangeNotifier notifier = new PropertyChangeNotifier((IPropertyChangeListener)listeners[i], event);
380             SafeRunner.run(notifier);
381         }
382     }
383     
384     /**
385      * Returns the container hosting this memory rendering.
386      *
387      * @return the container hosting this memory rendering
388      */

389     public IMemoryRenderingContainer getMemoryRenderingContainer()
390     {
391         return fContainer;
392     }
393
394     /**
395      * Returns whether this rendering is currently visible.
396      *
397      * @return whether this rendering is currently visible
398      */

399     public boolean isVisible() {
400         return fVisible;
401     }
402 }
403
Popular Tags