Logo Search packages:      
Sourcecode: eclipse-cdt version File versions  Download package

ModulesView.java

/*******************************************************************************
 * Copyright (c) 2004, 2005 QNX Software Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * QNX Software Systems - Initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.modules; 

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.debug.core.model.ICDebugElement;
import org.eclipse.cdt.debug.core.model.ICDebugTarget;
import org.eclipse.cdt.debug.core.model.ICModule;
import org.eclipse.cdt.debug.internal.ui.CDebugModelPresentation;
import org.eclipse.cdt.debug.internal.ui.ICDebugHelpContextIds;
import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants;
import org.eclipse.cdt.debug.internal.ui.actions.ToggleDetailPaneAction;
import org.eclipse.cdt.debug.internal.ui.preferences.ICDebugPreferenceConstants;
import org.eclipse.cdt.debug.internal.ui.views.AbstractDebugEventHandler;
import org.eclipse.cdt.debug.internal.ui.views.AbstractDebugEventHandlerView;
import org.eclipse.cdt.debug.internal.ui.views.AbstractViewerState;
import org.eclipse.cdt.debug.internal.ui.views.IDebugExceptionHandler;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.cdt.debug.ui.ICDebugUIConstants;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IValueDetailListener;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.ListenerList;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.INullSelectionListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.console.actions.TextViewerAction;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
 
/**
 * Displays the modules currently loaded by the process being debugged.
 */
00103 public class ModulesView extends AbstractDebugEventHandlerView implements IDebugExceptionHandler, IPropertyChangeListener, ISelectionListener, INullSelectionListener {


      class ModulesViewModelPresentation implements IDebugModelPresentation {

            private CDebugModelPresentation fDelegate;

            /* (non-Javadoc)
             * @see org.eclipse.debug.ui.IDebugModelPresentation#setAttribute(java.lang.String, java.lang.Object)
             */
            public void setAttribute( String attribute, Object value ) {
                  getModelPresentation().setAttribute( attribute, value );
            }

            /* (non-Javadoc)
             * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
             */
            public Image getImage( Object element ) {
                  Image image = getModelPresentation().getImage( element );
                  if ( image == null ) {
                        if ( element instanceof IAdaptable ) {
                              IWorkbenchAdapter de = (IWorkbenchAdapter)((IAdaptable)element).getAdapter( IWorkbenchAdapter.class );
                              if ( de != null ) {
                                    ImageDescriptor descriptor = de.getImageDescriptor( element );
                                    if ( descriptor != null ) {
                                          image = ModulesView.this.getImage( descriptor );
                                    }
                              }
                        }
                  }
                  return image;
            }

            /* (non-Javadoc)
             * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
             */
            public String getText( Object element ) {
                  String text = getModelPresentation().getText( element );
                  if ( text == null ) {
                        if ( element instanceof IAdaptable ) {
                              IWorkbenchAdapter de = (IWorkbenchAdapter)((IAdaptable)element).getAdapter( IWorkbenchAdapter.class );
                              if ( de != null ) {
                                    text = de.getLabel( element );
                              }
                              else {
                                    text = element.toString();
                              }
                        }
                  }
                  if ( element instanceof ICModule ) {
                        ICModule module = (ICModule)element;
                        text += ( module.areSymbolsLoaded() ) ? ModulesMessages.getString( "ModulesView.11" ) : ModulesMessages.getString( "ModulesView.12" ); //$NON-NLS-1$ //$NON-NLS-2$
                  }
                  return text;
            }

            /* (non-Javadoc)
             * @see org.eclipse.debug.ui.IDebugModelPresentation#computeDetail(org.eclipse.debug.core.model.IValue, org.eclipse.debug.ui.IValueDetailListener)
             */
            public void computeDetail( IValue value, IValueDetailListener listener ) {
            }

            /* (non-Javadoc)
             * @see org.eclipse.debug.ui.ISourcePresentation#getEditorInput(java.lang.Object)
             */
            public IEditorInput getEditorInput( Object element ) {
                  return null;
            }

            /* (non-Javadoc)
             * @see org.eclipse.debug.ui.ISourcePresentation#getEditorId(org.eclipse.ui.IEditorInput, java.lang.Object)
             */
            public String getEditorId( IEditorInput input, Object element ) {
                  return null;
            }

            /* (non-Javadoc)
             * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
             */
            public void addListener( ILabelProviderListener listener ) {
            }

            /* (non-Javadoc)
             * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
             */
            public void dispose() {
            }

            /* (non-Javadoc)
             * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
             */
            public boolean isLabelProperty( Object element, String property ) {
                  return false;
            }

            /* (non-Javadoc)
             * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
             */
            public void removeListener( ILabelProviderListener listener ) {
            }

            private CDebugModelPresentation getModelPresentation() {
                  if ( fDelegate == null ) {
                        fDelegate = CDebugModelPresentation.getDefault();
                  }
                  return fDelegate;
            }
      }

      /**
       * Internal interface for a cursor listener. I.e. aggregation 
       * of mouse and key listener.
       */
00216       interface ICursorListener extends MouseListener, KeyListener {
      }

      /**
       * The selection provider for the modules view changes depending on whether
       * the variables viewer or detail pane source viewer have focus. This "super" 
       * provider ensures the correct selection is sent to all listeners.
       */
00224       public class ModulesViewSelectionProvider implements ISelectionProvider {

            private ListenerList fListeners= new ListenerList();
            
            private ISelectionProvider fUnderlyingSelectionProvider;

            /* (non-Javadoc)
             * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
             */
            public void addSelectionChangedListener( ISelectionChangedListener listener ) {
                  fListeners.add( listener );
            }

            /* (non-Javadoc)
             * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
             */
            public ISelection getSelection() {
                  return getUnderlyingSelectionProvider().getSelection();
            }

            /* (non-Javadoc)
             * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
             */
            public void removeSelectionChangedListener( ISelectionChangedListener listener ) {
                  fListeners.remove( listener );
            }

            /* (non-Javadoc)
             * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
             */
            public void setSelection( ISelection selection ) {
                  getUnderlyingSelectionProvider().setSelection( selection );
            }

            protected ISelectionProvider getUnderlyingSelectionProvider() {
                  return fUnderlyingSelectionProvider;
            }

            protected void setUnderlyingSelectionProvider( ISelectionProvider underlyingSelectionProvider ) {
                  fUnderlyingSelectionProvider = underlyingSelectionProvider;
            }

            protected void fireSelectionChanged( SelectionChangedEvent event ) {
                  Object[] listeners = fListeners.getListeners();
                  for( int i = 0; i < listeners.length; i++ ) {
                        ISelectionChangedListener listener = (ISelectionChangedListener)listeners[i];
                        listener.selectionChanged( event );
                  }
            }
      }

      /**
       * The UI construct that provides a sliding sash between the modules tree
       * and the detail pane.
       */
00279       private SashForm fSashForm;
      
      /**
       * The detail pane viewer.
       */
00284       private ISourceViewer fDetailViewer;

      /**
       * The document associated with the detail pane viewer.
       */
00289       private IDocument fDetailDocument;
      
      /**
       * Selection provider for this view.
       */
00294       private ModulesViewSelectionProvider fSelectionProvider = new ModulesViewSelectionProvider();

      /**
       * The model presentation used as the label provider for the tree viewer,
       * and also as the detail information provider for the detail pane.
       */
00300       private IDebugModelPresentation fModelPresentation;

      /**
       * Remembers which viewer (tree viewer or details viewer) had focus, so we
       * can reset the focus properly when re-activated.
       */
00306       private Viewer fFocusViewer = null;

      /**
       * Various listeners used to update the enabled state of actions and also to
       * populate the detail pane.
       */
00312       private ISelectionChangedListener fTreeSelectionChangedListener;
      private ISelectionChangedListener fDetailSelectionChangedListener;
      private IDocumentListener fDetailDocumentListener;

      /**
       * These are used to initialize and persist the position of the sash that
       * separates the tree viewer from the detail pane.
       */
00320       private static final int[] DEFAULT_SASH_WEIGHTS = { 13, 6 };
      private int[] fLastSashWeights;
      private boolean fToggledDetailOnce;
      private ToggleDetailPaneAction[] fToggleDetailPaneActions;
      private String fCurrentDetailPaneOrientation = ICDebugPreferenceConstants.MODULES_DETAIL_PANE_HIDDEN;
      protected static final String SASH_WEIGHTS = CDebugUIPlugin.getUniqueIdentifier() + ".modulesView.SASH_WEIGHTS"; //$NON-NLS-1$
      
      private ICursorListener fCursorListener;

      private HashMap fSelectionStates = new HashMap( 10 );

      private AbstractViewerState fLastState = null;
      
      private HashMap fImageCache = new HashMap( 10 );

      /* (non-Javadoc)
       * @see org.eclipse.debug.ui.AbstractDebugView#createViewer(org.eclipse.swt.widgets.Composite)
       */
      protected Viewer createViewer( Composite parent ) {
            TreeViewer viewer = createTreeViewer( parent );
            createDetailsViewer();
            getSashForm().setMaximizedControl( viewer.getControl() );

            createOrientationActions();
            IPreferenceStore prefStore = CDebugUIPlugin.getDefault().getPreferenceStore();
            String orientation = prefStore.getString( getDetailPanePreferenceKey() );
            for( int i = 0; i < fToggleDetailPaneActions.length; i++ ) {
                  fToggleDetailPaneActions[i].setChecked( fToggleDetailPaneActions[i].getOrientation().equals( orientation ) );
            }
            setDetailPaneOrientation( orientation );

            return viewer;
      }

      /* (non-Javadoc)
       * @see org.eclipse.debug.ui.AbstractDebugView#createActions()
       */
      protected void createActions() {
            TextViewerAction textAction = new TextViewerAction( getDetailViewer(), ITextOperationTarget.SELECT_ALL );
            textAction.configureAction( ModulesMessages.getString( "ModulesView.13" ), "", "" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            textAction.setActionDefinitionId( IWorkbenchActionDefinitionIds.SELECT_ALL );
            setAction( ActionFactory.SELECT_ALL.getId(), textAction );
            textAction = new TextViewerAction( getDetailViewer(), ITextOperationTarget.COPY );
            textAction.configureAction( ModulesMessages.getString( "ModulesView.16" ), "", "" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            textAction.setActionDefinitionId( IWorkbenchActionDefinitionIds.COPY );
            setAction( ActionFactory.COPY.getId(), textAction );
      }

      /* (non-Javadoc)
       * @see org.eclipse.debug.ui.AbstractDebugView#getHelpContextId()
       */
      protected String getHelpContextId() {
            return ICDebugHelpContextIds.MODULES_VIEW;
      }

      /* (non-Javadoc)
       * @see org.eclipse.debug.ui.AbstractDebugView#fillContextMenu(org.eclipse.jface.action.IMenuManager)
       */
      protected void fillContextMenu( IMenuManager menu ) {
            menu.add( new Separator( ICDebugUIConstants.EMPTY_MODULES_GROUP ) );
            menu.add( new Separator( ICDebugUIConstants.MODULES_GROUP ) );
            menu.add( new Separator( ICDebugUIConstants.EMPTY_REFRESH_GROUP ) );
            menu.add( new Separator( ICDebugUIConstants.REFRESH_GROUP ) );
            menu.add( new Separator( IWorkbenchActionConstants.MB_ADDITIONS ) );
            updateObjects();
      }

      /* (non-Javadoc)
       * @see org.eclipse.debug.ui.AbstractDebugView#configureToolBar(org.eclipse.jface.action.IToolBarManager)
       */
      protected void configureToolBar( IToolBarManager tbm ) {
            tbm.add( new Separator( ICDebugUIConstants.MODULES_GROUP ) );
            tbm.add( new Separator( ICDebugUIConstants.REFRESH_GROUP ) );
      }

      /* (non-Javadoc)
       * @see org.eclipse.cdt.debug.internal.ui.views.IDebugExceptionHandler#handleException(org.eclipse.debug.core.DebugException)
       */
00398       public void handleException( DebugException e ) {
            showMessage( e.getMessage() );
      }

      /* (non-Javadoc)
       * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
       */
      public void propertyChange( PropertyChangeEvent event ) {
            String propertyName = event.getProperty();
            if ( propertyName.equals( IInternalCDebugUIConstants.DETAIL_PANE_FONT ) ) {
                  getDetailViewer().getTextWidget().setFont( JFaceResources.getFont( IInternalCDebugUIConstants.DETAIL_PANE_FONT ) );
            }
      }

      /* (non-Javadoc)
       * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
       */
      public void selectionChanged( IWorkbenchPart part, ISelection selection ) {
            if ( !isAvailable() || !isVisible() )
                  return;
            if ( selection == null )
                  setViewerInput( new StructuredSelection() );
            else if ( selection instanceof IStructuredSelection )
                  setViewerInput( (IStructuredSelection)selection );
      }

      protected void setViewerInput( IStructuredSelection ssel ) {
            ICDebugTarget target = null;
            if ( ssel.size() == 1 ) {
                  Object input = ssel.getFirstElement();
                  if ( input instanceof ICDebugElement ) {
                        target = (ICDebugTarget)((ICDebugElement)input).getDebugTarget();
                  }
            }

            Object current = getViewer().getInput();
            if ( current == null && target == null ) {
                  return;
            }
            if ( current != null && current.equals( target ) ) {
                  return;
            }

            if ( current != null ) {
                  // save state
                  fLastState = getViewerState();
                  fSelectionStates.put( current, fLastState );
            }           

            showViewer();
            getViewer().setInput( target );

            // restore state
            if ( target != null ) {
                  AbstractViewerState state = (AbstractViewerState)fSelectionStates.get( target );
                  if ( state == null ) {
                        // attempt to restore selection/expansion based on last target
                        state = fLastState;
                  }
                  if ( state != null ) {
                        state.restoreState( getModulesViewer() );
                  }
            }
      }

      protected TreeViewer createTreeViewer( Composite parent ) {
            CDebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener( this );
            JFaceResources.getFontRegistry().addListener( this );
            // create the sash form that will contain the tree viewer & text viewer
            setSashForm( new SashForm( parent, SWT.NONE ) );
            // add tree viewer
            final TreeViewer modulesViewer = new ModulesViewer( getSashForm(), SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL );
            modulesViewer.setContentProvider( createContentProvider() );
            modulesViewer.setLabelProvider( createLabelProvider( modulesViewer ) );
            modulesViewer.setUseHashlookup( true );
            modulesViewer.getControl().addFocusListener( new FocusAdapter() {

                  /* (non-Javadoc)
                   * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
                   */
                  public void focusGained( FocusEvent e ) {
                        getModulesViewSelectionProvider().setUnderlyingSelectionProvider( modulesViewer );
                        setFocusViewer( getModulesViewer() );
                  }
            } );
            modulesViewer.addPostSelectionChangedListener( getTreeSelectionChangedListener() );
            getModulesViewSelectionProvider().setUnderlyingSelectionProvider( modulesViewer );
            getSite().setSelectionProvider( getModulesViewSelectionProvider() );
            // listen to selection in debug view
            getSite().getPage().addSelectionListener( IDebugUIConstants.ID_DEBUG_VIEW, this );
            setEventHandler( createEventHandler() );
            return modulesViewer;
      }

      /**
       * Create the widgetry for the details viewer.
       */
00495       protected void createDetailsViewer() {
            // Create & configure a SourceViewer
            SourceViewer detailsViewer = new SourceViewer( getSashForm(), null, SWT.V_SCROLL | SWT.H_SCROLL );
            setDetailViewer( detailsViewer );
            detailsViewer.setDocument( getDetailDocument() );
            detailsViewer.getTextWidget().setFont( JFaceResources.getFont( IInternalCDebugUIConstants.DETAIL_PANE_FONT ) );
            getDetailDocument().addDocumentListener( getDetailDocumentListener() );
            detailsViewer.configure( new SourceViewerConfiguration() );
            detailsViewer.setEditable( false );
            Control control = detailsViewer.getControl();
            GridData gd = new GridData( GridData.FILL_BOTH );
            control.setLayoutData( gd );
            detailsViewer.getSelectionProvider().addSelectionChangedListener( getDetailSelectionChangedListener() );
            detailsViewer.getControl().addFocusListener( new FocusAdapter() {

                  /* (non-Javadoc)
                   * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
                   */
                  public void focusGained( FocusEvent e ) {
                        getModulesViewSelectionProvider().setUnderlyingSelectionProvider( getDetailViewer().getSelectionProvider() );
                        setFocusViewer( (Viewer)getDetailViewer() );
                  }
            } );
            // add a context menu to the detail area
            createDetailContextMenu( detailsViewer.getTextWidget() );
            detailsViewer.getTextWidget().addMouseListener( getCursorListener() );
            detailsViewer.getTextWidget().addKeyListener( getCursorListener() );
      }

      private void setDetailViewer( ISourceViewer viewer ) {
            fDetailViewer = viewer;
      }

      protected ISourceViewer getDetailViewer() {
            return fDetailViewer;
      }

      protected SashForm getSashForm() {
            return fSashForm;
      }

      private void setSashForm( SashForm sashForm ) {
            fSashForm = sashForm;
      }

      protected IContentProvider createContentProvider() {
            ModulesViewContentProvider cp = new ModulesViewContentProvider();
            cp.setExceptionHandler( this );
            return cp;
      }

      protected IBaseLabelProvider createLabelProvider( StructuredViewer viewer ) {
//          return new DebugViewDecoratingLabelProvider( viewer, new DebugViewInterimLabelProvider( getModelPresentation() ), new DebugViewLabelDecorator( getModelPresentation() ) );
            return getModelPresentation();
      }

      protected IDebugModelPresentation getModelPresentation() {
            if ( fModelPresentation == null ) {
                  fModelPresentation = new ModulesViewModelPresentation();
            }
            return fModelPresentation;
      }

      protected ModulesViewSelectionProvider getModulesViewSelectionProvider() {
            return fSelectionProvider;
      }

      protected ModulesViewer getModulesViewer() {
            return (ModulesViewer)getViewer();
      }

      protected void setFocusViewer( Viewer viewer ) {
            fFocusViewer = viewer;
      }

      protected Viewer getFocusViewer() {
            return fFocusViewer;
      }

      /**
       * Lazily instantiate and return a selection listener that populates the detail pane,
       * but only if the detail is currently visible. 
       */
00578       protected ISelectionChangedListener getTreeSelectionChangedListener() {
            if ( fTreeSelectionChangedListener == null ) {
                  fTreeSelectionChangedListener = new ISelectionChangedListener() {

                        public void selectionChanged( SelectionChangedEvent event ) {
                              if ( event.getSelectionProvider().equals( getModulesViewer() ) ) {
                                    getModulesViewSelectionProvider().fireSelectionChanged( event );
                                    // if the detail pane is not visible, don't waste time retrieving details
                                    if ( getSashForm().getMaximizedControl() == getViewer().getControl() ) {
                                          return;
                                    }
                                    IStructuredSelection selection = (IStructuredSelection)event.getSelection();
                                    populateDetailPaneFromSelection( selection );
                                    treeSelectionChanged( event );
                              }
                        }
                  };
            }
            return fTreeSelectionChangedListener;
      }

      protected void treeSelectionChanged( SelectionChangedEvent event ) {
      }

      /**
       * Ask the modules tree for its current selection, and use this to populate
       * the detail pane.
       */
00606       public void populateDetailPane() {
            if ( isDetailPaneVisible() ) {
                  Viewer viewer = getViewer();
                  if ( viewer != null ) {
                        IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
                        populateDetailPaneFromSelection( selection );
                  }
            }
      }

      /**
       * Show the details associated with the first of the selected elements in the 
       * detail pane.
       */
00620       protected void populateDetailPaneFromSelection( IStructuredSelection selection ) {
            getDetailDocument().set( "" ); //$NON-NLS-1$
            if ( !selection.isEmpty() ) {
                  computeDetail( selection.getFirstElement() );
            }
      }

      /**
       * Lazily instantiate and return a selection listener that updates the enabled
       * state of the selection oriented actions in this view.
       */
00631       protected ISelectionChangedListener getDetailSelectionChangedListener() {
            if ( fDetailSelectionChangedListener == null ) {
                  fDetailSelectionChangedListener = new ISelectionChangedListener() {

                        public void selectionChanged( SelectionChangedEvent event ) {
                              if ( event.getSelectionProvider().equals( getModulesViewSelectionProvider().getUnderlyingSelectionProvider() ) ) {
                                    getModulesViewSelectionProvider().fireSelectionChanged( event );
                                    updateSelectionDependentActions();
                              }
                        }
                  };
            }
            return fDetailSelectionChangedListener;
      }

      /**
       * Lazily instantiate and return a document listener that updates the enabled state
       * of the 'Find/Replace' action.
       */
00650       protected IDocumentListener getDetailDocumentListener() {
            if ( fDetailDocumentListener == null ) {
                  fDetailDocumentListener = new IDocumentListener() {

                        public void documentAboutToBeChanged( DocumentEvent event ) {
                        }

                        public void documentChanged( DocumentEvent event ) {
                        }
                  };
            }
            return fDetailDocumentListener;
      }

      /**
       * Lazily instantiate and return a Document for the detail pane text viewer.
       */
00667       protected IDocument getDetailDocument() {
            if ( fDetailDocument == null ) {
                  fDetailDocument = new Document();
            }
            return fDetailDocument;
      }

      protected AbstractDebugEventHandler createEventHandler() {
            return new ModulesViewEventHandler( this );
      }

      protected void updateSelectionDependentActions() {
      }

      protected void updateAction( String actionId ) {
            IAction action = getAction( actionId );
            if ( action instanceof IUpdate ) {
                  ((IUpdate)action).update();
            }
      }

      protected void createDetailContextMenu( Control menuControl ) {
            MenuManager menuMgr = new MenuManager(); //$NON-NLS-1$
            menuMgr.setRemoveAllWhenShown( true );
            menuMgr.addMenuListener( new IMenuListener() {

                  public void menuAboutToShow( IMenuManager mgr ) {
                        fillDetailContextMenu( mgr );
                  }
            } );
            Menu menu = menuMgr.createContextMenu( menuControl );
            menuControl.setMenu( menu );
            // register the context menu such that other plugins may contribute to it
            getSite().registerContextMenu( ICDebugUIConstants.MODULES_VIEW_DETAIL_ID, menuMgr, getDetailViewer().getSelectionProvider() );
            addContextMenuManager( menuMgr );
      }

      protected void fillDetailContextMenu( IMenuManager menu ) {
            menu.add( new Separator( ICDebugUIConstants.MODULES_GROUP ) );
            menu.add( new Separator() );
            menu.add( getAction( ActionFactory.COPY.getId() ) );
            menu.add( getAction( ActionFactory.SELECT_ALL.getId() ) );
            menu.add( new Separator( IWorkbenchActionConstants.MB_ADDITIONS ) );
            updateObjects();
      }

      private ICursorListener getCursorListener() {
            if ( fCursorListener == null ) {
                  fCursorListener = new ICursorListener() {

                        public void keyPressed( KeyEvent e ) {
                        }

                        public void keyReleased( KeyEvent e ) {
                        }

                        public void mouseDoubleClick( MouseEvent e ) {
                        }

                        public void mouseDown( MouseEvent e ) {
                        }

                        public void mouseUp( MouseEvent e ) {
                        }
                  };
            }
            return fCursorListener;
      }

      public void setDetailPaneOrientation( String orientation ) {
            if ( orientation.equals( fCurrentDetailPaneOrientation ) ) {
                  return;
            }
            if ( orientation.equals( ICDebugPreferenceConstants.MODULES_DETAIL_PANE_HIDDEN ) ) {
                  hideDetailPane();
            }
            else {
                  int vertOrHoriz = orientation.equals( ICDebugPreferenceConstants.MODULES_DETAIL_PANE_UNDERNEATH ) ? SWT.VERTICAL : SWT.HORIZONTAL;
                  getSashForm().setOrientation( vertOrHoriz );
                  if ( ICDebugPreferenceConstants.MODULES_DETAIL_PANE_HIDDEN.equals( fCurrentDetailPaneOrientation ) ) {
                        showDetailPane();
                  }
            }
            fCurrentDetailPaneOrientation = orientation;
            CDebugUIPlugin.getDefault().getPreferenceStore().setValue( getDetailPanePreferenceKey(), orientation );
      }
      
      private void hideDetailPane() {
            if ( fToggledDetailOnce ) {
                  setLastSashWeights( getSashForm().getWeights() );
            }
            getSashForm().setMaximizedControl( getViewer().getControl() );          
      }
      
      private void showDetailPane() {
            getSashForm().setMaximizedControl( null );
            getSashForm().setWeights( getLastSashWeights() );
            populateDetailPane();
            revealTreeSelection();
            fToggledDetailOnce = true;          
      }

      protected String getDetailPanePreferenceKey() {
            return ICDebugPreferenceConstants.MODULES_DETAIL_PANE_ORIENTATION;
      }

      protected int[] getLastSashWeights() {
            if ( fLastSashWeights == null ) {
                  fLastSashWeights = DEFAULT_SASH_WEIGHTS;
            }
            return fLastSashWeights;
      }

      protected void setLastSashWeights( int[] weights ) {
            fLastSashWeights = weights;
      }

      private void createOrientationActions() {
            IActionBars actionBars = getViewSite().getActionBars();
            IMenuManager viewMenu = actionBars.getMenuManager();
            fToggleDetailPaneActions = new ToggleDetailPaneAction[3];
            fToggleDetailPaneActions[0] = new ToggleDetailPaneAction( this, ICDebugPreferenceConstants.MODULES_DETAIL_PANE_UNDERNEATH, null );
            fToggleDetailPaneActions[1] = new ToggleDetailPaneAction( this, ICDebugPreferenceConstants.MODULES_DETAIL_PANE_RIGHT, null );
            fToggleDetailPaneActions[2] = new ToggleDetailPaneAction( this, ICDebugPreferenceConstants.MODULES_DETAIL_PANE_HIDDEN, getToggleActionLabel() );
            viewMenu.add( new Separator() );
            viewMenu.add( fToggleDetailPaneActions[0] );
            viewMenu.add( fToggleDetailPaneActions[1] );
            viewMenu.add( fToggleDetailPaneActions[2] );
            viewMenu.add( new Separator() );          
      }

      protected String getToggleActionLabel() {
            return ModulesMessages.getString( "ModulesView.0" ); //$NON-NLS-1$
      }

      protected boolean isDetailPaneVisible() {
            return !fToggleDetailPaneActions[2].isChecked();
      }

      /**
       * Make sure the currently selected item in the tree is visible.
       */
00809       protected void revealTreeSelection() {
            ModulesViewer viewer = getModulesViewer();
            if ( viewer != null ) {
                  ISelection selection = viewer.getSelection();
                  if ( selection instanceof IStructuredSelection ) {
                        Object selected = ((IStructuredSelection)selection).getFirstElement();
                        if ( selected != null ) {
                              viewer.reveal( selected );
                        }
                  }
            }
      }

      /**
       * Set on or off the word wrap flag for the detail pane.
       */
00825       public void toggleDetailPaneWordWrap( boolean on ) {
            fDetailViewer.getTextWidget().setWordWrap( on );
      }

      /* (non-Javadoc)
       * @see org.eclipse.ui.IViewPart#saveState(org.eclipse.ui.IMemento)
       */
      public void saveState( IMemento memento ) {
            super.saveState( memento );
            SashForm sashForm = getSashForm();
            if ( sashForm != null ) {
                  int[] weights = sashForm.getWeights();
                  memento.putInteger( SASH_WEIGHTS + "-Length", weights.length ); //$NON-NLS-1$
                  for( int i = 0; i < weights.length; i++ ) {
                        memento.putInteger( SASH_WEIGHTS + "-" + i, weights[i] ); //$NON-NLS-1$
                  }
            }
      }

      /* (non-Javadoc)
       * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento)
       */
      public void init( IViewSite site, IMemento memento ) throws PartInitException {
            super.init( site, memento );
            if ( memento != null ) {
                  Integer bigI = memento.getInteger( SASH_WEIGHTS + "-Length" ); //$NON-NLS-1$
                  if ( bigI == null ) {
                        return;
                  }
                  int numWeights = bigI.intValue();
                  int[] weights = new int[numWeights];
                  for( int i = 0; i < numWeights; i++ ) {
                        bigI = memento.getInteger( SASH_WEIGHTS + "-" + i ); //$NON-NLS-1$
                        if ( bigI == null ) {
                              return;
                        }
                        weights[i] = bigI.intValue();
                  }
                  if ( weights.length > 0 ) {
                        setLastSashWeights( weights );
                  }
            }
      }

      /* (non-Javadoc)
       * @see org.eclipse.debug.ui.AbstractDebugView#getDefaultControl()
       */
      protected Control getDefaultControl() {
            return getSashForm();
      }

      /* (non-Javadoc)
       * @see org.eclipse.debug.ui.AbstractDebugView#becomesHidden()
       */
00879       protected void becomesHidden() {
            setViewerInput( new StructuredSelection() );
            super.becomesHidden();
      }

      /* (non-Javadoc)
       * @see org.eclipse.debug.ui.AbstractDebugView#becomesVisible()
       */
00887       protected void becomesVisible() {
            super.becomesVisible();
            IViewPart part = getSite().getPage().findView( IDebugUIConstants.ID_DEBUG_VIEW );
            if ( part != null ) {
                  ISelection selection = getSite().getPage().getSelection( IDebugUIConstants.ID_DEBUG_VIEW );
                  selectionChanged( part, selection );
            }
      }

      private void computeDetail( final Object element ) {
            if ( element != null ) {
                  DebugPlugin.getDefault().asyncExec( new Runnable() {

                        public void run() {
                              detailComputed( element, doComputeDetail( element ) );
                        }
                  } );
            }
      }

      protected String doComputeDetail( Object element ) {
            if ( element instanceof ICModule ) {
                  return getModuleDetail( ((ICModule)element) );
            }
            if ( element instanceof ICElement ) {
                  return element.toString();
            }
            return ""; //$NON-NLS-1$
      }

      private String getModuleDetail( ICModule module ) {
            StringBuffer sb = new StringBuffer();
            
            // Type
            String type = null;
            switch( module.getType() ) {
                  case ICModule.EXECUTABLE:
                        type = ModulesMessages.getString( "ModulesView.1" ); //$NON-NLS-1$
                        break;
                  case ICModule.SHARED_LIBRARY:
                        type = ModulesMessages.getString( "ModulesView.2" ); //$NON-NLS-1$
                        break;
            }
            if ( type != null ) {
                  sb.append( ModulesMessages.getString( "ModulesView.3" ) ); //$NON-NLS-1$
                  sb.append( type );
                  sb.append( '\n' );
            }
            
            // Symbols flag
            sb.append( ModulesMessages.getString( "ModulesView.4" ) ); //$NON-NLS-1$
            sb.append( ( module.areSymbolsLoaded() ) ? ModulesMessages.getString( "ModulesView.5" ) : ModulesMessages.getString( "ModulesView.6" ) ); //$NON-NLS-1$ //$NON-NLS-2$
            sb.append( '\n' );

            // Symbols file
            sb.append( ModulesMessages.getString( "ModulesView.7" ) ); //$NON-NLS-1$
            sb.append( module.getSymbolsFileName().toOSString() );
            sb.append( '\n' );

            // CPU
            String cpu = module.getCPU();
            if ( cpu != null ) {
                  sb.append( ModulesMessages.getString( "ModulesView.8" ) ); //$NON-NLS-1$
                  sb.append( cpu );
                  sb.append( '\n' );
            }

            // Base address
            IAddress baseAddress = module.getBaseAddress();
            if ( !baseAddress.isZero() ) {
                  sb.append( ModulesMessages.getString( "ModulesView.9" ) ); //$NON-NLS-1$
                  sb.append( baseAddress.toHexAddressString() );
                  sb.append( '\n' );
            }
            
            // Size
            long size = module.getSize();
            if ( size > 0 ) { 
                  sb.append( ModulesMessages.getString( "ModulesView.10" ) ); //$NON-NLS-1$
                  sb.append( size );
                  sb.append( '\n' );
            }

            return sb.toString();
      }

      protected void detailComputed( Object element, final String result ) {
            Runnable runnable = new Runnable() {

                  public void run() {
                        if ( isAvailable() ) {
                              getDetailDocument().set( result );  
                        }
                  }
            };
            asyncExec( runnable );        
      }

      /* (non-Javadoc)
       * @see org.eclipse.ui.IWorkbenchPart#dispose()
       */
00988       public void dispose() {
            getSite().getPage().removeSelectionListener( IDebugUIConstants.ID_DEBUG_VIEW, this );
            CDebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener( this );
            JFaceResources.getFontRegistry().removeListener( this );
            Viewer viewer = getViewer();
            if ( viewer != null ) {
                  getDetailDocument().removeDocumentListener( getDetailDocumentListener() );
            }
            disposeImageCache();
            super.dispose();
      }

      private AbstractViewerState getViewerState() {
            return new ModulesViewerState( getModulesViewer() );
      }
      
      protected Image getImage( ImageDescriptor desc ) {
            Image image = (Image)fImageCache.get( desc );
            if ( image == null ) {
                  image = desc.createImage();
                  fImageCache.put( desc, image );
            }
            return image;
      }

      private void disposeImageCache() {
            Iterator it = fImageCache.values().iterator();
            while( it.hasNext() ) {
                  Map.Entry entry = (Map.Entry)it.next();
                  ((Image)entry.getValue()).dispose();
            }
            fImageCache.clear();
      }
}

Generated by  Doxygen 1.6.0   Back to index