From cd55cc57610fff353bb0dfc5f83309f04db739ef Mon Sep 17 00:00:00 2001 From: Mikhail Khodjaiants Date: Tue, 8 Feb 2005 21:10:18 +0000 Subject: [PATCH] Bug 82264: Enhance the Shared Libraries view. Improved detail information. Save the viewer state. --- debug/org.eclipse.cdt.debug.ui/ChangeLog | 10 ++ debug/org.eclipse.cdt.debug.ui/plugin.xml | 16 +- .../ui/views/AbstractViewerState.java | 145 ++++++++++++++++++ .../views/modules/ModulesMessages.properties | 3 + .../ui/views/modules/ModulesView.java | 52 +++++++ .../ui/views/modules/ModulesViewerState.java | 97 ++++++++++++ 6 files changed, 318 insertions(+), 5 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/AbstractViewerState.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesViewerState.java diff --git a/debug/org.eclipse.cdt.debug.ui/ChangeLog b/debug/org.eclipse.cdt.debug.ui/ChangeLog index 32daceb58fb..b7b83602b87 100644 --- a/debug/org.eclipse.cdt.debug.ui/ChangeLog +++ b/debug/org.eclipse.cdt.debug.ui/ChangeLog @@ -1,3 +1,13 @@ +2005-02-08 Mikhail Khodjaiants + Bug 82264: Enhance the Shared Libraries view. + Improved detail information. + Save the viewer state. + * AbstractViewerState.java: new + * ModulesMessages.properties + * ModulesView.java + * ModulesViewerState.java: new + * plugin.xml + 2005-02-07 Mikhail Khodjaiants Bug 82264: Enhance the Shared Libraries view. Added the definition of detail pane font. diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index 84b1ba8c178..1617ed64fef 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -105,15 +105,18 @@ - - - + id="org.eclipse.cdt.debug.ui.ModulesView"> + + + + + + diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/AbstractViewerState.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/AbstractViewerState.java new file mode 100644 index 00000000000..b0a245a86a4 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/AbstractViewerState.java @@ -0,0 +1,145 @@ +/********************************************************************** + * Copyright (c) 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.debug.internal.ui.views; +import java.util.ArrayList; +import java.util.List; +import org.eclipse.core.runtime.IPath; +import org.eclipse.debug.core.DebugException; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.TreeItem; + +/** + * The abstract superclass for mementos of the expanded and + * selected items in a tree viewer. + */ +public abstract class AbstractViewerState { + + // paths to expanded elements + private List fExpandedElements = null; + // paths to selected elements + private IPath[] fSelection = null; + + /** + * Constructs a memento for the given viewer. + */ + public AbstractViewerState( TreeViewer viewer ) { + saveState( viewer ); + } + + /** + * Saves the current state of the given viewer into + * this memento. + * + * @param viewer viewer of which to save the state + */ + public void saveState( TreeViewer viewer ) { + List expanded = new ArrayList(); + fExpandedElements = null; + TreeItem[] items = viewer.getTree().getItems(); + try { + for( int i = 0; i < items.length; i++ ) { + collectExandedItems( items[i], expanded ); + } + if ( expanded.size() > 0 ) { + fExpandedElements = expanded; + } + } + catch( DebugException e ) { + fExpandedElements = null; + } + TreeItem[] selection = viewer.getTree().getSelection(); + fSelection = new IPath[selection.length]; + try { + for( int i = 0; i < selection.length; i++ ) { + fSelection[i] = encodeElement( selection[i] ); + } + } + catch( DebugException e ) { + fSelection = null; + } + } + + protected void collectExandedItems( TreeItem item, List expanded ) throws DebugException { + if ( item.getExpanded() ) { + expanded.add( encodeElement( item ) ); + TreeItem[] items = item.getItems(); + for( int i = 0; i < items.length; i++ ) { + collectExandedItems( items[i], expanded ); + } + } + } + + /** + * Constructs a path representing the given tree item. The segments in the + * path denote parent items, and the last segment is the name of + * the given item. + * + * @param item tree item to encode + * @return path encoding the given item + * @throws DebugException if unable to generate a path + */ + protected abstract IPath encodeElement( TreeItem item ) throws DebugException; + + /** + * Restores the state of the given viewer to this memento's + * saved state. + * + * @param viewer viewer to which state is restored + */ + public void restoreState( TreeViewer viewer ) { + if ( fExpandedElements != null ) { + List expansion = new ArrayList( fExpandedElements.size() ); + for( int i = 0; i < fExpandedElements.size(); i++ ) { + IPath path = (IPath)fExpandedElements.get( i ); + if ( path != null ) { + Object obj; + try { + obj = decodePath( path, viewer ); + if ( obj != null ) { + expansion.add( obj ); + } + } + catch( DebugException e ) { + } + } + } + viewer.setExpandedElements( expansion.toArray() ); + } + if ( fSelection != null ) { + List selection = new ArrayList( fSelection.length ); + for( int i = 0; i < fSelection.length; i++ ) { + IPath path = fSelection[i]; + Object obj; + try { + obj = decodePath( path, viewer ); + if ( obj != null ) { + selection.add( obj ); + } + } + catch( DebugException e ) { + } + } + viewer.setSelection( new StructuredSelection( selection ) ); + } + } + + /** + * Returns an element in the given viewer that corresponds to the given + * path, or null if none. + * + * @param path encoded element path + * @param viewer viewer to search for the element in + * @return element represented by the path, or null if none + * @throws DebugException if unable to locate a variable + */ + protected abstract Object decodePath( IPath path, TreeViewer viewer ) throws DebugException; +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesMessages.properties index b545cd96d43..7afa1adbe0d 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesMessages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesMessages.properties @@ -1,8 +1,11 @@ ModulesView.0=Modules View Only ModulesView.1=executable +ModulesView.10=Size: ModulesView.2=shared library ModulesView.3=Type: ModulesView.4=Symbols: ModulesView.5=loaded ModulesView.6=not loaded ModulesView.7=Symbols file: +ModulesView.8=CPU: +ModulesView.9=Base address: diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesView.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesView.java index 47e7ae7b82b..fed283c8d99 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesView.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesView.java @@ -10,6 +10,10 @@ ***********************************************************************/ package org.eclipse.cdt.debug.internal.ui.views.modules; +import java.util.HashMap; +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.core.model.IBinary; +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; @@ -28,6 +32,7 @@ import org.eclipse.cdt.debug.ui.CDebugUIPlugin; import org.eclipse.cdt.debug.ui.ICDebugUIConstants; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.cdt.debug.internal.ui.views.AbstractViewerState; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.action.IAction; @@ -205,6 +210,10 @@ public class ModulesView extends AbstractDebugEventHandlerView implements IDebug private ICursorListener fCursorListener; + private HashMap fSelectionStates = new HashMap( 10 ); + + private AbstractViewerState fLastState = null; + /* (non-Javadoc) * @see org.eclipse.debug.ui.AbstractDebugView#createViewer(org.eclipse.swt.widgets.Composite) */ @@ -304,8 +313,26 @@ public class ModulesView extends AbstractDebugEventHandlerView implements IDebug 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 ) { @@ -757,6 +784,9 @@ public class ModulesView extends AbstractDebugEventHandlerView implements IDebug if ( element instanceof ICModule ) { return getModuleDetail( ((ICModule)element) ); } + if ( element instanceof ICElement ) { + return element.toString(); + } return ""; //$NON-NLS-1$ } @@ -784,6 +814,24 @@ public class ModulesView extends AbstractDebugEventHandlerView implements IDebug sb.append( module.getSymbolsFileName().toOSString() ); sb.append( '\n' ); } + IBinary binary = (IBinary)module.getAdapter( IBinary.class ); + if ( binary != null ) { + sb.append( ModulesMessages.getString( "ModulesView.8" ) ); //$NON-NLS-1$ + sb.append( binary.getCPU() ); + sb.append( '\n' ); + } + IAddress baseAddress = module.getBaseAddress(); + if ( !baseAddress.isZero() ) { + sb.append( ModulesMessages.getString( "ModulesView.9" ) ); //$NON-NLS-1$ + sb.append( baseAddress.toHexAddressString() ); + sb.append( '\n' ); + } + 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(); } @@ -812,4 +860,8 @@ public class ModulesView extends AbstractDebugEventHandlerView implements IDebug } super.dispose(); } + + private AbstractViewerState getViewerState() { + return new ModulesViewerState( getModulesViewer() ); + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesViewerState.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesViewerState.java new file mode 100644 index 00000000000..10ff1c6c584 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/modules/ModulesViewerState.java @@ -0,0 +1,97 @@ +/********************************************************************** + * Copyright (c) 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.debug.internal.ui.views.modules; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.debug.core.model.ICModule; +import org.eclipse.cdt.debug.internal.ui.views.AbstractViewerState; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.debug.core.DebugException; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.TreeItem; + +/** + * Memento of the expanded and selected items in a modules viewer. + */ +public class ModulesViewerState extends AbstractViewerState { + + /** + * Constructor for ModulesViewerState. + */ + public ModulesViewerState( TreeViewer viewer ) { + super( viewer ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.views.AbstractViewerState#encodeElement(org.eclipse.swt.widgets.TreeItem) + */ + protected IPath encodeElement( TreeItem item ) throws DebugException { + String name = getTreeItemName( item ); + IPath path = new Path( name ); + TreeItem parent = item.getParentItem(); + while( parent != null ) { + name = getTreeItemName( parent ); + path = new Path( name ).append( path ); + parent = parent.getParentItem(); + } + return path; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.views.AbstractViewerState#decodePath(org.eclipse.core.runtime.IPath, org.eclipse.jface.viewers.TreeViewer) + */ + protected Object decodePath( IPath path, TreeViewer viewer ) throws DebugException { + ITreeContentProvider contentProvider = (ITreeContentProvider)viewer.getContentProvider(); + String[] names = path.segments(); + Object parent = viewer.getInput(); + Object element = null; + for( int i = 0; i < names.length; i++ ) { + element = null; + Object[] children = contentProvider.getChildren( parent ); + for( int j = 0; j < children.length; j++ ) { + String name = getElementName( children[j] ); + if ( names[i].equals( name ) ) { + element = children[j]; + break; + } + } + if ( element == null ) { + return null; + } + parent = element; + } + return element; + } + + private String getTreeItemName( TreeItem item ) { + Object data = item.getData(); + String name = null; + if ( data instanceof ICModule ) { + name = ((ICModule)data).getName(); + } + else if ( data instanceof ICElement ) { + name = ((ICElement)data).getElementName(); + } + return name; + } + + private String getElementName( Object element ) { + if ( element instanceof ICModule ) { + return ((ICModule)element).getName(); + } + if ( element instanceof ICElement ) { + return ((ICElement)element).getElementName(); + } + return null; + } +}