diff options
author | Samantha Chan | 2006-03-02 16:21:43 +0000 |
---|---|---|
committer | Samantha Chan | 2006-03-02 16:21:43 +0000 |
commit | 5f913897226a682f532d5e4539b50842543e0815 (patch) | |
tree | a1dc2d229ce85e658ba149aa92495b2383dd4550 | |
parent | 0865474f11b53dbc761ff8be74469eb0be18e003 (diff) | |
download | eclipse.platform.debug-5f913897226a682f532d5e4539b50842543e0815.tar.gz eclipse.platform.debug-5f913897226a682f532d5e4539b50842543e0815.tar.xz eclipse.platform.debug-5f913897226a682f532d5e4539b50842543e0815.zip |
Bug 121624 - [flex-hierarchy] Enhancements needed AsynchronousTableViewer
23 files changed, 965 insertions, 2426 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousRequestMonitor.java deleted file mode 100644 index 74c91d92b..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousRequestMonitor.java +++ /dev/null @@ -1,196 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor; -import org.eclipse.swt.widgets.Widget; -import org.eclipse.ui.progress.WorkbenchJob; - -/** - * Base implementation of an asynchronous request monitor. - * <p> - * Not intended to be subclassed or instantiated by clients. For internal use - * with the <code>AsynchronousTreeViewer</code> implementation. - * </p> - * @since 3.2 - */ -abstract class AsynchronousRequestMonitor implements IAsynchronousRequestMonitor { - - /** - * Widget the upadte is rooted at - */ - private Widget fWidget; - - /** - * Viewer the update is being performed for - */ - private AsynchronousViewer fViewer; - - /** - * Whether this request has been canelled - */ - private boolean fCanceled = false; - - /** - * Update request status or <code>null</code> - */ - private IStatus fStatus = null; - - protected WorkbenchJob fViewerUpdateJob = new WorkbenchJob("AsynchronousRequestMonitor.fViewerUpdateJob") { //$NON-NLS-1$ - public IStatus runInUIThread(IProgressMonitor monitor) { - // necessary to check if widget is disposed. The item may - // have been removed from the tree when another children update - // occured. - getViewer().updateComplete(AsynchronousRequestMonitor.this); - if (!isCanceled() && !getWidget().isDisposed()) { - if (fStatus != null && !fStatus.isOK()) { - getViewer().handlePresentationFailure(AsynchronousRequestMonitor.this, fStatus); - } - performUpdate(); - } - return Status.OK_STATUS; - } - }; - - /** - * Constructs an udpate rooted at the given item. - * - * @param item - */ - AsynchronousRequestMonitor(Widget item, AsynchronousViewer viewer) { - fWidget = item; - fViewer = viewer; - fViewerUpdateJob.setSystem(true); - } - - /** - * Returns the viewer this update is being peformed for - * - * @return the viewer this update is being peformed for - */ - protected AsynchronousViewer getViewer() { - return fViewer; - } - - /** - * Returns the widget this update is rooted at - * - * @return the widget this update is rooted at - */ - protected Widget getWidget() { - return fWidget; - } - - /** - * Returns whether this update contains the given widget. - * That is, whether this update is for the same widget or a child of - * the given widget. - * - * @param widget widget to test containment on - * @return whether this update contains the given widget - */ - protected boolean contains(Widget widget) { - if (widget == getWidget()) { - return true; - } - Widget parent = getViewer().getParent(widget); - while (parent != null) { - if (parent.equals(getWidget())) { - return true; - } - parent = getViewer().getParent(parent); - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.viewers.IAsynchronousRequestMonitor#setStatus(org.eclipse.core.runtime.IStatus) - */ - public void setStatus(IStatus status) { - fStatus = status; - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IProgressMonitor#beginTask(java.lang.String, int) - */ - public void beginTask(String name, int totalWork) { - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IProgressMonitor#internalWorked(double) - */ - public void internalWorked(double work) { - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IProgressMonitor#isCanceled() - */ - public boolean isCanceled() { - return fCanceled; - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IProgressMonitor#setCanceled(boolean) - */ - public void setCanceled(boolean value) { - fCanceled = true; - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IProgressMonitor#setTaskName(java.lang.String) - */ - public void setTaskName(String name) { - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IProgressMonitor#subTask(java.lang.String) - */ - public void subTask(String name) { - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IProgressMonitor#worked(int) - */ - public void worked(int work) { - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IProgressMonitor#done() - */ - public final void done() { - if (!isCanceled()) { - fViewerUpdateJob.schedule(); - } - } - - protected void scheduleViewerUpdate(long ms) { - if(!isCanceled()) - fViewerUpdateJob.schedule(ms); - } - - /** - * Notification this update has been completed and should now be applied to - * this update's viewer. This method is called in the UI thread. - */ - protected abstract void performUpdate(); - - /** - * Returns whether this update effectively contains the given update. - * That is, whether this update will also perform the given update. - * - * @param update update to compare to - * @return whether this update will also perform the given update - */ - protected abstract boolean contains(AsynchronousRequestMonitor update); -} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableModel.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableModel.java new file mode 100644 index 000000000..7b6c0ef99 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableModel.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModel; +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer; +import org.eclipse.debug.internal.ui.model.viewers.ModelNode; + +/** + * @since 3.2 + * + */ +public class AsynchronousTableModel extends AsynchronousModel { + + /** + * Constructs a new table model. + * + * @param viewer + */ + public AsynchronousTableModel(AsynchronousModelViewer viewer) { + super(viewer); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModel#add(org.eclipse.debug.internal.ui.model.viewers.ModelNode, java.lang.Object) + */ + protected void add(ModelNode parent, Object element) { + // TODO Auto-generated method stub + + } + + /** + * Adds the given elements to the table. + * + * @param elements + */ + public void add(Object[] elements) { + TableAddRequestMonitor update = new TableAddRequestMonitor(getRootNode(), elements, this); + requestScheduled(update); + update.done(); + } + + /** + * Notification add request is complete. + * + * @param elements elements to add + */ + protected void added(Object[] elements) { + List kids = null; + boolean changed = false; + synchronized (this) { + ModelNode[] childrenNodes = getRootNode().getChildrenNodes(); + if (childrenNodes == null) { + kids = new ArrayList(elements.length); + } else { + kids = new ArrayList(elements.length + childrenNodes.length); + for (int i = 0; i < childrenNodes.length; i++) { + kids.add(childrenNodes[i].getElement()); + } + } + for (int i = 0; i < elements.length; i++) { + if (!kids.contains(elements[i])) { + kids.add(elements[i]); + changed = true; + } + } + } + if (changed) { + setChildren(getRootNode(), kids); + } + } + + /** + * Inserts the given elements to the table. + * + * @param elements + * @param index + */ + public void insert(Object[] elements, int index) { + TableAddRequestMonitor update = new TableInsertRequestMonitor(getRootNode(), elements, index, this); + requestScheduled(update); + update.done(); + } + + /** + * Notification insert request is complete. + * + * @param elements elements to add + * @param index index to insert at + */ + protected void inserted(Object[] elements, int index) { + List kids = null; + boolean changed = false; + synchronized (this) { + ModelNode[] childrenNodes = getRootNode().getChildrenNodes(); + if (childrenNodes == null) { + kids = new ArrayList(elements.length); + } else { + kids = new ArrayList(elements.length + childrenNodes.length); + for (int i = 0; i < childrenNodes.length; i++) { + kids.add(childrenNodes[i].getElement()); + } + } + for (int i = 0; i < elements.length; i++) { + if (!kids.contains(elements[i])) { + kids.add(index, elements[i]); + index++; + changed = true; + } + } + } + if (changed) { + setChildren(getRootNode(), kids); + } + } + + /** + * Removes the given elements from the table. + * + * @param elements + */ + public void remove(Object[] elements) { + TableRemoveRequestMonitor update = new TableRemoveRequestMonitor(getRootNode(), elements, this); + requestScheduled(update); + update.done(); + } + + /** + * Notification remove request is complete. + * + * @param elements elements to remove + */ + protected void removed(Object[] elements) { + List kids = null; + boolean changed = false; + synchronized (this) { + ModelNode[] childrenNodes = getRootNode().getChildrenNodes(); + if (childrenNodes != null) { + kids = new ArrayList(childrenNodes.length); + for (int i = 0; i < childrenNodes.length; i++) { + kids.add(childrenNodes[i].getElement()); + } + } + for (int i = 0; i < elements.length; i++) { + if (kids.remove(elements[i])) { + changed = true; + } + } + } + if (changed) { + setChildren(getRootNode(), kids); + } + } + + /** + * Adds the given elements to the table. + * + * @param elements + */ + public void replace(Object element, Object replacement) { + TableReplaceRequestMonitor update = new TableReplaceRequestMonitor(getRootNode(), element, replacement, this); + requestScheduled(update); + update.done(); + } + + /** + * Notification add request is complete. + * + * @param elements elements to add + */ + protected void replaced(Object element, Object replacement) { + Object[] filtered = filter(getRootNode().getElement(), new Object[] { replacement }); + if (filtered.length == 0) { + remove(new Object[]{element}); + return; + } + List list = new ArrayList(); + synchronized (this) { + ModelNode[] nodes = getNodes(element); + for (int i = 0; i < nodes.length; i++) { + ModelNode node = nodes[i]; + node.remap(replacement); + list.add(node); + } + } + if (!list.isEmpty()) { + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + ModelNode node = (ModelNode) iterator.next(); + getViewer().nodeChanged(node); + } + } + } +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java index 2d736e249..563f84f7e 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewer.java @@ -3,16 +3,14 @@ package org.eclipse.debug.internal.ui.viewers; import java.util.ArrayList; import java.util.List; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IChildrenRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.update.DefaultTableUpdatePolicy; +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModel; +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer; +import org.eclipse.debug.internal.ui.model.viewers.IModelUpdatePolicy; +import org.eclipse.debug.internal.ui.model.viewers.ModelNode; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.util.Assert; import org.eclipse.jface.viewers.CellEditor; @@ -36,22 +34,21 @@ import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.progress.WorkbenchJob; /** - * TODO non virtual table support - * TODO sorting by column + * @since 3.2 */ -public class AsynchronousTableViewer extends AsynchronousViewer { +public class AsynchronousTableViewer extends AsynchronousModelViewer implements Listener { private Table fTable; - private AsynchronousTableViewerContentManager fContentManager; - private TableEditor fTableEditor; private TableEditorImpl fTableEditorImpl; @@ -74,7 +71,6 @@ public class AsynchronousTableViewer extends AsynchronousViewer { public AsynchronousTableViewer(Table table) { Assert.isTrue((table.getStyle() & SWT.VIRTUAL) != 0); fTable = table; - fContentManager = createContentManager(); hookControl(fTable); fTableEditor = new TableEditor(fTable); fTableEditorImpl = createTableEditorImpl(); @@ -86,23 +82,14 @@ public class AsynchronousTableViewer extends AsynchronousViewer { public void mouseDown(MouseEvent e) { fTableEditorImpl.handleMouseDown(e); } - }); - } - - public IUpdatePolicy createUpdatePolicy() { - return new DefaultTableUpdatePolicy(); + }); } public synchronized void dispose() { - fContentManager.dispose(); fTable.dispose(); fTableEditor.dispose(); super.dispose(); - } - - protected AsynchronousTableViewerContentManager createContentManager() { - return new AsynchronousTableViewerContentManager(this); - } + } protected ISelection doAttemptSelectionToWidget(ISelection selection, boolean reveal) { if (acceptsSelection(selection)) { @@ -113,22 +100,24 @@ public class AsynchronousTableViewer extends AsynchronousViewer { } int[] indices = new int[list.size()]; - Object[] elements = fContentManager.getElements(); - int index = 0; - - // I'm not sure if it would be faster to check TableItems first... - for (int i = 0; i < elements.length; i++) { - Object element = elements[i]; - if (list.contains(element)) { - indices[index] = i; - index++; - } - } - - fTable.setSelection(indices); - if (reveal && indices.length > 0) { - TableItem item = fTable.getItem(indices[0]); - fTable.showItem(item); + ModelNode[] nodes = getModel().getRootNode().getChildrenNodes(); + if (nodes != null) { + int index = 0; + + // I'm not sure if it would be faster to check TableItems first... + for (int i = 0; i < nodes.length; i++) { + Object element = nodes[i].getElement(); + if (list.contains(element)) { + indices[index] = i; + index++; + } + } + + fTable.setSelection(indices); + if (reveal && indices.length > 0) { + TableItem item = fTable.getItem(indices[0]); + fTable.showItem(item); + } } } return StructuredSelection.EMPTY; @@ -149,25 +138,6 @@ public class AsynchronousTableViewer extends AsynchronousViewer { return null; } - /*this is wrong... should look in content manager - * as the data may not be set on the widget yet. - * (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#doFindInputItem(java.lang.Object) - */ - protected Widget doFindInputItem(Object element) { - if (element.equals(getInput())) { - return fTable; - } - TableItem[] items = fTable.getItems(); - for (int i = 0; i < items.length; i++) { - Object data = items[i].getData(); - if (data != null && equals(data, element)) { - return items[i]; - } - } - return null; - } - protected List getSelectionFromWidget() { TableItem[] selection = fTable.getSelection(); List datas = new ArrayList(selection.length); @@ -185,60 +155,15 @@ public class AsynchronousTableViewer extends AsynchronousViewer { return (Table) getControl(); } - protected void setChildren(Widget widget, List children) { - Object[] elements = filter(children.toArray()); - if (elements.length > 0) { - ViewerSorter sorter = getSorter(); - if (sorter != null) - sorter.sort(this, elements); - - fContentManager.setElements(elements); - } - } - - protected void doUpdateItem(Widget item, Object element, boolean fullMap) { - super.doUpdateItem(item, element, fullMap); - } - - protected void updateLabel(Object element, Widget item) { - if (item instanceof Item) { - IAsynchronousLabelAdapter adapter = getLabelAdapter(element); - if (adapter != null) { - ILabelRequestMonitor labelUpdate = new LabelRequestMonitor(item, this); - schedule(labelUpdate); - adapter.retrieveLabel(element, getPresentationContext(), labelUpdate); - } - } - } - - protected void inputChanged(Object input, Object oldInput) { - super.inputChanged(input, oldInput); - map(input, fTable); - refresh(); - } - - protected void internalRefresh(Object element, Widget widget) { - super.internalRefresh(element, widget); - if (element.equals(getRoot())) { - IAsynchronousContentAdapter adapter = getTableContentAdapter(element); - if (adapter != null) { - IChildrenRequestMonitor update = new ChildrenRequestMonitor(widget, this); - schedule(update); - adapter.retrieveChildren(element, getPresentationContext(), update); - } + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer#internalRefresh(org.eclipse.debug.internal.ui.model.viewers.ModelNode) + */ + protected void internalRefresh(ModelNode node) { + super.internalRefresh(node); + if (node.getElement().equals(getInput())) { + updateChildren(node); } - } - - private IAsynchronousContentAdapter getTableContentAdapter(Object element) { - IAsynchronousContentAdapter adapter = null; - if (element instanceof IAsynchronousContentAdapter) { - adapter = (IAsynchronousContentAdapter) element; - } else if (element instanceof IAdaptable) { - IAdaptable adaptable = (IAdaptable) element; - adapter = (IAsynchronousContentAdapter) adaptable.getAdapter(IAsynchronousContentAdapter.class); - } - return adapter; - } + } public void setLabels(Widget widget, String[] labels, ImageDescriptor[] imageDescriptors) { TableItem item = (TableItem) widget; @@ -396,20 +321,6 @@ public class AsynchronousTableViewer extends AsynchronousViewer { } /** - * FIXME: currently requires UI Thread - * - * @param index - */ - void clear(int index) { - TableItem item = fTable.getItem(index); - Object data = item.getData(); - if (item.getData() != null) { - unmap(data, item); - } - fTable.clear(index); - } - - /** * This is not asynchronous. This method must be called in the UI Thread. */ public void cancelEditing() { @@ -458,11 +369,6 @@ public class AsynchronousTableViewer extends AsynchronousViewer { return min; } - - protected void add(Widget parent, Object element) { - add(element); - } - public void add(Object element) { if (element != null) add(new Object[] { element }); @@ -471,27 +377,7 @@ public class AsynchronousTableViewer extends AsynchronousViewer { public void add(Object[] elements) { if (elements == null || elements.length == 0) return; // done - - ViewerSorter sorter = getSorter(); - if (sorter != null) { - insert(elements, 0); - return; - } - - final Object[] filteredElements = filter(elements); - if (filteredElements.length == 0) - return; - - WorkbenchJob job = new WorkbenchJob("AsychronousTableViewer.add") { //$NON-NLS-1$ - public IStatus runInUIThread(IProgressMonitor monitor) { - if (!monitor.isCanceled()) - fContentManager.add(filteredElements); - return Status.OK_STATUS; - } - }; - job.setSystem(true); - job.setPriority(Job.INTERACTIVE); - job.schedule(); + ((AsynchronousTableModel)getModel()).add(elements); } public void remove(Object element) { @@ -502,17 +388,7 @@ public class AsynchronousTableViewer extends AsynchronousViewer { public void remove(final Object[] elements) { if (elements == null || elements.length == 0) return; // done - - WorkbenchJob job = new WorkbenchJob("AsychronousTableViewer.remove") { //$NON-NLS-1$ - public IStatus runInUIThread(IProgressMonitor monitor) { - if (!monitor.isCanceled()) - fContentManager.remove(elements); - return Status.OK_STATUS; - } - }; - job.setSystem(true); - job.setPriority(Job.INTERACTIVE); - job.schedule(); + ((AsynchronousTableModel)getModel()).remove(elements); } public void insert(Object element, int position) { @@ -520,67 +396,85 @@ public class AsynchronousTableViewer extends AsynchronousViewer { insert(new Object[] { element }, position); } - public void insert(Object[] elements, final int position) { + public void insert(Object[] elements, int position) { if (elements == null || elements.length == 0) return; - - final Object[] filteredElements = filter(elements); - WorkbenchJob job = new WorkbenchJob("AsychronousTableViewer.insert") { //$NON-NLS-1$ - public IStatus runInUIThread(IProgressMonitor monitor) { - if (monitor.isCanceled()) - return Status.OK_STATUS; - - ViewerSorter sorter = getSorter(); - if (sorter == null) { - fContentManager.insert(filteredElements, position); - } else { - for (int i = 0; i < filteredElements.length; i++) { - Object element = filteredElements[i]; - int index = indexForElement(element); - fContentManager.insert(new Object[] { element }, index); - } - } - return Status.OK_STATUS; - } - }; - job.setSystem(true); - job.setPriority(Job.INTERACTIVE); - job.schedule(); + ((AsynchronousTableModel)getModel()).insert(elements, position); } - public void replace(final Object element, final Object replacement) { + public void replace(Object element, Object replacement) { if (element == null || replacement == null) throw new IllegalArgumentException("unexpected null parameter"); //$NON-NLS-1$ + ((AsynchronousTableModel)getModel()).replace(element, replacement); + } - Object[] filtered = filter(new Object[] { replacement }); - if (filtered.length == 0) { - remove(element); - return; - } + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer#createModel() + */ + protected AsynchronousModel createModel() { + return new AsynchronousTableModel(this); + } - WorkbenchJob job = new WorkbenchJob("AsychronousTableViewer.replace") { //$NON-NLS-1$ - public IStatus runInUIThread(IProgressMonitor monitor) { - if (monitor.isCanceled()) - return Status.OK_STATUS; - - ViewerSorter sorter = getSorter(); - if (sorter == null) { - fContentManager.replace(element, replacement); - } else { - fContentManager.remove(new Object[] { element }); - int position = indexForElement(replacement); - fContentManager.insert(new Object[] { replacement }, position); - } - return Status.OK_STATUS; - } - }; - job.setSystem(true); - job.setPriority(Job.INTERACTIVE); - job.schedule(); + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer#setItemCount(org.eclipse.swt.widgets.Widget, int) + */ + protected void setItemCount(Widget parent, int itemCount) { + fTable.setItemCount(itemCount); + } + + protected int getVisibleItemCount(int top) { + int itemCount = fTable.getItemCount(); + return Math.min((fTable.getBounds().height / fTable.getItemHeight()) + 2, itemCount - top); } - public AsynchronousTableViewerContentManager getContentManager() - { - return fContentManager; - } + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer#createUpdatePolicy() + */ + public IModelUpdatePolicy createUpdatePolicy() { + return new DefaultTableUpdatePolicy(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer#getParentWidget(org.eclipse.swt.widgets.Widget) + */ + protected Widget getParentWidget(Widget widget) { + if (widget instanceof TableItem) { + return ((TableItem)widget).getParent(); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer#getChildIndex(org.eclipse.swt.widgets.Widget, org.eclipse.swt.widgets.Event) + */ + protected int getChildIndex(Widget parent, Event event) { + if (parent instanceof Table) { + return ((Table)parent).indexOf((TableItem)event.item); + } + return -1; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer#getChildWidget(org.eclipse.swt.widgets.Widget, int) + */ + protected Widget getChildWidget(Widget parent, int index) { + if (index < fTable.getItemCount()) { + return fTable.getItem(index); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer#clear(org.eclipse.swt.widgets.Widget) + */ + protected void clear(Widget item) { + if (item instanceof TableItem) { + int i = fTable.indexOf((TableItem)item); + if (i >= 0) { + fTable.clear(i); + } + } + } + + } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewerContentManager.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewerContentManager.java deleted file mode 100644 index b5b0d646a..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTableViewerContentManager.java +++ /dev/null @@ -1,240 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableItem; - -public class AsynchronousTableViewerContentManager implements Listener { - - private Table fTable; - - private int fItemCount = 0; - - private Object[] fElements = new Object[50]; - - private AsynchronousTableViewer fViewer; - - public AsynchronousTableViewerContentManager(AsynchronousTableViewer viewer) { - fViewer = viewer; - fTable = viewer.getTable(); - fTable.addListener(SWT.SetData, this); - } - - public void handleEvent(Event event) { - TableItem item = (TableItem) event.item; - int index = fTable.indexOf(item); - Object element = fElements[index]; - fViewer.map(element, item); - fViewer.updateLabel(element, item); - } - - public void setElements(Object[] newElements) { - growElementArray(newElements.length); - int oldItemCount = fItemCount; - - setItemCount(newElements.length); - - int topIndex = fTable.getTopIndex(); - int visibleItems = getVisibleItemCount(topIndex); - int bottomIndex = topIndex + visibleItems; - - int index = 0; - for (int i = 0; i < newElements.length; i++) { - Object element = newElements[i]; - fElements[index] = element; - TableItem item = fTable.getItem(index); - if (index >= topIndex && index <= bottomIndex) { - if (item.getData() != null) { - fViewer.remap(fElements[index], item); - } else { - // item is visible, but data is null?? - fViewer.map(fElements[index], item); - } - fViewer.updateLabel(fElements[index], item); - } else { - fViewer.unmap(fElements[i], item); - fTable.clear(index); - } - index++; - } - - while (index < oldItemCount && fTable.getItemCount() > index) { - TableItem item = fTable.getItem(index); - fViewer.unmap(fElements[index], item); - fElements[index] = null; - index++; - } - } - - private void setItemCount(int itemCount) { - fItemCount = itemCount; - fTable.setItemCount(fItemCount); - fTable.redraw(); - } - - private void growElementArray(int size) { - if (size > fElements.length) { - Object[] elements = new Object[size]; - System.arraycopy(fElements, 0, elements, 0, fElements.length); - fElements = elements; - } - } - - public int getVisibleItemCount(int top) { - int itemCount = fTable.getItemCount(); - return Math.min((fTable.getBounds().height / fTable.getItemHeight()) + 2, itemCount - top); - } - - public void dispose() { - fElements = null; - fViewer = null; - } - - public Object[] getElements() { - Object[] elements = new Object[fItemCount]; - System.arraycopy(fElements, 0, elements, 0, fItemCount); - return elements; - } - - public void add(Object[] elements) { - growElementArray(fItemCount + elements.length); - for (int index = fItemCount; index < fItemCount + elements.length; index++) { - fElements[index] = elements[index - fItemCount]; - } - setItemCount(fItemCount + elements.length); - } - - public void remove(Object[] elements) { - for (int i = 0; i < elements.length; i++) { - Object element = elements[i]; - remove(element); - } - } - - private void remove(Object element) { - for (int i = 0; i < fItemCount; i++) { - Object obj = fElements[i]; - if (element.equals(obj)) { - System.arraycopy(fElements, i + 1, fElements, i, fItemCount - 1); - TableItem item = fTable.getItem(i); - fViewer.unmap(element, item); - item.dispose(); - fItemCount --; - } - } - } - - public void insert(Object[] elements, int index) { - growElementArray(fItemCount + elements.length); - System.arraycopy(fElements, index, fElements, index + elements.length, fItemCount - index); - - int topIndex = fTable.getTopIndex(); - int visibleItems = getVisibleItemCount(topIndex); - int bottomIndex = topIndex + visibleItems; - - for (int i = 0; i < elements.length; i++) { - Object element = elements[i]; - fElements[index + i] = element; - } - - setItemCount(fItemCount + elements.length); - - for (int i = index; i < fItemCount; i++) { - Object element = fElements[i]; - - TableItem item = fTable.getItem(i); - Object data = item != null ? item.getData() : null; - - if (i >= topIndex && i <= bottomIndex) { - if (data != null) { - fViewer.remap(element, item); - } else { - fViewer.map(element, item); - } - fViewer.updateLabel(element, item); - } else { - if (data != null) { - fViewer.unmap(element, item); - } - fTable.clear(i); - } - } - } - - public void replace(Object element, Object replacement) { - for (int i = 0; i < fItemCount; i++) { - Object obj = fElements[i]; - if (obj.equals(element)) { - TableItem item = fTable.getItem(i); - Object data = item.getData(); - - int topIndex = fTable.getTopIndex(); - int visibleItems = getVisibleItemCount(topIndex); - int bottomIndex = topIndex + visibleItems; - - if (i >= topIndex && i <= bottomIndex) { - if (data != null) { - fViewer.remap(replacement, item); - } else { - fViewer.map(replacement, item); - } - fViewer.updateLabel(replacement, item); - } else { - if (data != null) { - fViewer.unmap(element, item); - } - fTable.clear(i); - } - - fElements[i] = replacement; - return; - } - } - } - - public Object getElement(int index) - { - if (index >= 0 && index < fElements.length) - return fElements[index]; - - return null; - } - - public Object getElement(TableItem item) - { - int i = fTable.indexOf(item); - if (i > 0 && i<fElements.length) - return fElements[i]; - - return null; - } - - public int indexOfElement(Object element) - { - for (int i=0; i<fElements.length; i++) - { - if (fElements[i] == element) - return i; - } - return -1; - } - - protected AsynchronousTableViewer getTableViewer() - { - return fViewer; - } - - -} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewerContentManager.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewerContentManager.java deleted file mode 100644 index fda668fe3..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousTreeViewerContentManager.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ - -package org.eclipse.debug.internal.ui.viewers; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.swt.widgets.TreeItem; -import org.eclipse.swt.widgets.Widget; - -public class AsynchronousTreeViewerContentManager { - - private static final Object[] EMPTY = new Object[0]; - private Map fWidgetToChildElements = new HashMap(); - - public void clearAll() { - fWidgetToChildElements.clear(); - } - - public Object[] getChildElements(Widget parentWidget) { - Object[] childElements = (Object[]) fWidgetToChildElements.get(parentWidget); - if (childElements == null) - childElements = EMPTY; - return childElements; - } - - public void addChildElement(Widget parentWidget, Object child) { - Object[] originalChildren = getChildElements(parentWidget); - Object[] newChildren = new Object[originalChildren.length + 1]; - System.arraycopy(originalChildren, 0, newChildren, 0, originalChildren.length); - newChildren[originalChildren.length] = child; - fWidgetToChildElements.put(parentWidget, newChildren); - } - - public int getChildCount(Widget parentWidget) { - return getChildElements(parentWidget).length; - } - - public void setChildElements(Widget parentWidget, Object[] children) { - fWidgetToChildElements.put(parentWidget, children); - } - - public Object getChildElement(Widget parentWidget, int index) { - Object[] childElements = getChildElements(parentWidget); - if (index < childElements.length) - return childElements[index]; - else - return null; - } - - public void remove(Widget widget) { - if (widget instanceof TreeItem) { - TreeItem treeItem = (TreeItem) widget; - removeChildren(treeItem); - - Object data = treeItem.getData(); - if (data != null) { - Widget parentWidget = treeItem.getParentItem(); - if (parentWidget == null) - parentWidget = treeItem.getParent(); - - removeFromParent(parentWidget, data); - } - } else { - fWidgetToChildElements.clear(); - } - } - - private void removeFromParent(Widget parentWidget, Object data) { - Object[] childElements = getChildElements(parentWidget); - for (int i = 0; i < childElements.length; i++) { - Object object = childElements[i]; - if (data.equals(object)) { - Object[] newChildren = new Object[childElements.length - 1]; - System.arraycopy(childElements, 0, newChildren, 0, i); - System.arraycopy(childElements, i + 1, newChildren, i, newChildren.length - i); - fWidgetToChildElements.put(parentWidget, newChildren); - return; - } - } - } - - private void removeChildren(TreeItem item) { - TreeItem[] items = item.getItems(); - for (int i = 0; i < items.length; i++) { - removeChildren(items[i]); - } - - fWidgetToChildElements.remove(item); - } -} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java deleted file mode 100644 index 22720b0d2..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/AsynchronousViewer.java +++ /dev/null @@ -1,1014 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.debug.internal.ui.elements.adapters.AsynchronousDebugLabelAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxyFactoryAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IModelSelectionPolicyAdapter; -import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredContentProvider; -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.Viewer; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.Widget; -import org.eclipse.ui.progress.WorkbenchJob; - -/** - * A viewer that retrieves labels and content asynchronously via adapters and supports - * duplicate elements in the viewer. Retrieving conetnt and labels asynchrnously allows - * for arbitrary latency without blocking the UI thread. - * <p> - * This viewer uses adapters to retreive labels and content rather than - * a label provider and content provider. As such, the label provider for this viewer - * is <code>null</code> by default. The content provider returned by this viewer is - * non-<code>null</code> to conform to the viewer specification, but performs no - * useful function. - * </p> - * <p> - * The selection in this viewer is also set asynchronously. When the selection is set, - * the viewer attempts to perform the selection. If the elements in the specified selection - * are not yet in the viewer, the portion of the selection that could not be honored - * becomes a pending selection. As more elements are added to viewer, the pending selection - * is attempted to be set. - * </p> - * @since 3.2 - */ -public abstract class AsynchronousViewer extends StructuredViewer { - - public static boolean DEBUG_CACHE; - - /** - * A map of elements to associated tree items or tree - */ - private Map fElementsToWidgets = new HashMap(); - - /** - * Map of widgets to their data elements used to avoid requirement to access - * data in UI thread. - */ - private Map fWidgetsToElements = new HashMap(); - - /** - * List of updates currently being performed. - */ - private List fPendingUpdates = new ArrayList(); - - /** - * Cache of images used for elements in this tree viewer. Label updates - * use the method <code>getImage(...)</code> to cache images for - * image descriptors. The images are disposed when this viewer is disposed. - */ - private Map fImageCache = new HashMap(); - - /** - * Cache of the fonts used for elements in this tree viewer. Label updates - * use the method <code>getFont(...)</code> to cache fonts for - * FontData objects. The fonts are disposed with the viewer. - */ - private Map fFontCache = new HashMap(); - - /** - * Cache of the colors used for elements in this tree viewer. Label updates - * use the method <code>getColor(...)</code> to cache colors for - * RGB values. The colors are disposed with the viewer. - */ - private Map fColorCache = new HashMap(); - - /** - * The context in which this viewer is being used - i.e. what part it is contained - * in any any preference settings associated with it. - */ - private IPresentationContext fContext; - - private ISelection fPendingSelection; - - private ISelection fCurrentSelection; - - /** - * The update policy for this viewer. - */ - private IUpdatePolicy fUpdatePolicy; - - /** - * Cache of update policies keyed by element - */ - private Map fModelProxies = new HashMap(); - - /** - * Creates a presentation adapter viewer - */ - protected AsynchronousViewer() { - setContentProvider(new NullContentProvider()); - } - - /** - * Clients must call this methods when this viewer is no longer needed - * so it can perform cleanup. - */ - public synchronized void dispose() { - Iterator images = fImageCache.values().iterator(); - while (images.hasNext()) { - Image image = (Image) images.next(); - image.dispose(); - } - fImageCache.clear(); - - Iterator fonts = fFontCache.values().iterator(); - while (fonts.hasNext()) { - Font font = (Font) fonts.next(); - font.dispose(); - } - fFontCache.clear(); - - Iterator colors = fColorCache.values().iterator(); - while (colors.hasNext()) { - Color color = (Color) colors.next(); - color.dispose(); - } - fColorCache.clear(); - - disposeAllModelProxies(); - if (fUpdatePolicy != null) { - fUpdatePolicy.dispose(); - } - - unmapAllElements(); - fPendingUpdates.clear(); - } - - /** - * Unintalls all update policies installed in this viewer - */ - private void disposeAllModelProxies() { - synchronized(fModelProxies) { - Iterator updatePolicies = fModelProxies.values().iterator(); - while (updatePolicies.hasNext()) { - IModelProxy proxy = (IModelProxy)updatePolicies.next(); - if (fUpdatePolicy instanceof IModelChangedListener) { - proxy.removeModelChangedListener((IModelChangedListener)fUpdatePolicy); - } - proxy.dispose(); - } - - fModelProxies.clear(); - } - } - - /** - * Updates all occurrences of the given element in this viewer. - * - * @param element element to update - */ - public void update(Object element) { - if (element == getInput()) { - return; // the input is not displayed - } - Widget[] items = getWidgets(element); - if (items != null) { - for (int i = 0; i < items.length; i++) { - updateLabel(element, items[i]); - } - } - } - - /** - * Updates the label for a specific element and item. - * - * @param element element to update - * @param item its associated item - */ - protected void updateLabel(Object element, Widget item) { - if (item instanceof Item) { - IAsynchronousLabelAdapter adapter = getLabelAdapter(element); - if (adapter != null) { - ILabelRequestMonitor labelUpdate = new LabelRequestMonitor(item, this); - schedule(labelUpdate); - adapter.retrieveLabel(element, getPresentationContext(), labelUpdate); - } - } - } - - /** - * Returns the presentation context to be used in update requests. - * Clients may override this method if required to provide special - * implementations of contexts. - * - * @return presentation contenxt - */ - public IPresentationContext getPresentationContext() { - return fContext; - } - -// /** -// * Refreshes all occurrences of the given element in this tree, and visible -// * children. -// * -// * @param element element to refresh -// */ -// public void refresh(final Object element) { -// // TODO: preserving selection currently has to be UI thread -//// preservingSelection(new Runnable() { -//// public void run() { -// internalRefresh(element); -//// } -//// }); -// } - - /** - * Returns the label adapter for the given element or <code>null</code> if none. - * - * @param element element to retrieve adapter for - * @return presentation adapter or <code>null</code> - */ - protected IAsynchronousLabelAdapter getLabelAdapter(Object element) { - IAsynchronousLabelAdapter adapter = null; - if (element instanceof IAsynchronousLabelAdapter) { - adapter = (IAsynchronousLabelAdapter) element; - } else if (element instanceof IAdaptable) { - IAdaptable adaptable = (IAdaptable) element; - adapter = (IAsynchronousLabelAdapter) adaptable.getAdapter(IAsynchronousLabelAdapter.class); - } - // if no adapter, use default (i.e. model presentation) - if (adapter == null) { - return new AsynchronousDebugLabelAdapter(); - } - return adapter; - } - - /** - * Returns the model proxy factory for the given element of <code>null</code> if none. - * - * @param element element to retrieve adapters for - * @return model proxy factory adapter or <code>null</code> - */ - protected IModelProxyFactoryAdapter getModelProxyFactoryAdapter(Object element) { - IModelProxyFactoryAdapter adapter = null; - if (element instanceof IModelProxyFactoryAdapter) { - adapter = (IModelProxyFactoryAdapter) element; - } else if (element instanceof IAdaptable) { - IAdaptable adaptable = (IAdaptable) element; - adapter = (IModelProxyFactoryAdapter) adaptable.getAdapter(IModelProxyFactoryAdapter.class); - } - return adapter; - } - /** - * Cancels any conflicting updates for children of the given item, and - * schedules the new update. - * - * @param update the update to schedule - */ - protected void schedule(IAsynchronousRequestMonitor update) { - AsynchronousRequestMonitor absUpdate = (AsynchronousRequestMonitor) update; - synchronized (fPendingUpdates) { - Iterator updates = fPendingUpdates.listIterator(); - while (updates.hasNext()) { - AsynchronousRequestMonitor pendingUpdate = (AsynchronousRequestMonitor) updates.next(); - if (absUpdate.contains(pendingUpdate)) { - pendingUpdate.setCanceled(true); - updates.remove(); - } - } - fPendingUpdates.add(update); - } - } - - /** - * Returns the widgets associated with the given element or - * <code>null</code>. - * - * @param element element to retrieve widgets for - * @return widgets or <code>null</code> if none - */ - protected synchronized Widget[] getWidgets(Object element) { - if (element == null) { - return null; - } - return (Widget[]) fElementsToWidgets.get(element); - } - - /** - * Returns the element associated with the given widget or - * <code>null</code>. - * - * @param widget widget to retrieve element for - * @return element or <code>null</code> if none - */ - protected synchronized Object getElement(Widget widget) { - return fWidgetsToElements.get(widget); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#unmapAllElements() - */ - protected synchronized void unmapAllElements() { - Iterator iterator = fElementsToWidgets.keySet().iterator(); - while (iterator.hasNext()) { - Object element = iterator.next(); - Widget[] widgets = getWidgets(element); - if (widgets != null) { - for (int i = 0; i < widgets.length; i++) { - Widget widget = widgets[i]; - if (widget instanceof Item) { - Item item = (Item) widget; - item.dispose(); - } - } - } - } - fElementsToWidgets.clear(); - fWidgetsToElements.clear(); - disposeAllModelProxies(); - if (DEBUG_CACHE) { - System.out.println("unmapped all elements"); //$NON-NLS-1$ - System.out.println("\tfWidgetsToElements.size() " + fWidgetsToElements.size()); //$NON-NLS-1$ - System.out.println("\tfElementsToWidgets.size() " + fElementsToWidgets.size()); //$NON-NLS-1$ - } - } - - /** - * Cancels all pending update requests. - */ - protected synchronized void cancelPendingUpdates() { - Iterator updates = fPendingUpdates.iterator(); - while (updates.hasNext()) { - IAsynchronousRequestMonitor update = (IAsynchronousRequestMonitor) updates.next(); - update.setCanceled(true); - } - fPendingUpdates.clear(); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object) - */ - protected void inputChanged(Object input, Object oldInput) { - if (fUpdatePolicy == null) { - fUpdatePolicy = createUpdatePolicy(); - fUpdatePolicy.init(this); - } - cancelPendingUpdates(); - } - - /** - * Maps the given element to the given item. Installs the elememt's - * update policy if not already installed. - * - * @param element model element - * @param item TreeItem or Tree - */ - protected void map(Object element, Widget item) { - item.setData(element); - Widget[] widgets = getWidgets(element); - fWidgetsToElements.put(item, element); - if (widgets == null) { - fElementsToWidgets.put(element, new Widget[] { item }); - } else { - Widget[] old = widgets; - Widget[] items = new Widget[old.length + 1]; - System.arraycopy(old, 0, items, 0, old.length); - items[old.length] = item; - fElementsToWidgets.put(element, items); - } - installModelProxy(element); - - if (DEBUG_CACHE) { - System.out.println("mapped " + element + " to " + item + "(hashcode: " + item.hashCode()+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - System.out.println("\tfWidgetsToElements.size() " + fWidgetsToElements.size()); //$NON-NLS-1$ - System.out.println("\tfElementsToWidgets.size() " + fElementsToWidgets.size()); //$NON-NLS-1$ - } - } - - /** - * Updates the cached information that maps the given element to the - * specified widget. This can be useful when an element is being remapped - * to an equal (but not identical) object. - * - * @param element - * @param item - */ - protected void remap(Object element, Widget item) { - item.setData(element); - installModelProxy(element); - fWidgetsToElements.put(item, element); - Widget[] widgets = (Widget[]) fElementsToWidgets.remove(element); - if (widgets == null) { - fElementsToWidgets.put(element, new Widget[] {item}); - } else { - Widget[] newArray = new Widget[widgets.length + 1]; - System.arraycopy(widgets, 0, newArray, 0, widgets.length); - newArray[widgets.length] = item; - fElementsToWidgets.put(element, newArray); - } - - if (DEBUG_CACHE) { - System.out.println("remapped " + element + " to " + item + "(hashcode: " + item.hashCode()+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - System.out.println("\tfWidgetsToElements.size() " + fWidgetsToElements.size()); //$NON-NLS-1$ - System.out.println("\tfElementsToWidgets.size() " + fElementsToWidgets.size()); //$NON-NLS-1$ - } - } - - public abstract IUpdatePolicy createUpdatePolicy(); - - /** - * Installs the model proxy for the given element into this viewer - * if not already installed. - * - * @param element element to install an update policy for - */ - public void installModelProxy(Object element) { - synchronized (fModelProxies) { - if (!fModelProxies.containsKey(element)) { - IModelProxyFactoryAdapter modelProxyFactory = getModelProxyFactoryAdapter(element); - if (modelProxyFactory != null) { - IModelProxy proxy = modelProxyFactory.createModelProxy(element, getPresentationContext()); - if (proxy != null) { - proxy.init(getPresentationContext()); - fModelProxies.put(element, proxy); - - if (fUpdatePolicy instanceof IModelChangedListener) { - proxy.addModelChangedListener((IModelChangedListener)fUpdatePolicy); - } - proxy.installed(); - } - } - } - } - } - - - /** - * Uninstalls the model proxy installed for the given element, if any. - * - * @param element - */ - protected void disposeModelProxy(Object element) { - synchronized (fModelProxies) { - IModelProxy proxy = (IModelProxy) fModelProxies.remove(element); - if (proxy != null) { - if (fUpdatePolicy instanceof IModelChangedListener) { - proxy.removeModelChangedListener((IModelChangedListener)fUpdatePolicy); - } - proxy.dispose(); - } - } - } - - /** - * Removes the update from the pending updates list. - * - * @param update - */ - protected void updateComplete(IAsynchronousRequestMonitor update) { - synchronized (fPendingUpdates) { - fPendingUpdates.remove(update); - } - } - - /** - * Unmaps the given item. Does not dispose of the given item, - * such that it can be reused. - * - * @param kid - * @param widget - */ - protected synchronized void unmap(Object kid, Widget widget) { - if (kid == null) { - // when unmapping a dummy item - return; - } - Widget[] widgets = getWidgets(kid); - if (widgets != null) { - for (int i = 0; i < widgets.length; i++) { - Widget item = widgets[i]; - if (item == widget) { - if (widgets.length == 1) { - fElementsToWidgets.remove(kid); - // uninstall its update policy, if element no longer in viewer - disposeModelProxy(kid); - } else { - Widget[] newItems = new Widget[widgets.length - 1]; - System.arraycopy(widgets, 0, newItems, 0, i); - if (i < newItems.length) { - System.arraycopy(widgets, i + 1, newItems, i, newItems.length - i); - } - fElementsToWidgets.put(kid, newItems); - } - } - } - } - - fWidgetsToElements.remove(widget); - - if (DEBUG_CACHE) { - System.out.println("unmapped " + kid + " to " + widget + "(hashcode: " + widget.hashCode()+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - System.out.println("\tfWidgetsToElements.size() " + fWidgetsToElements.size()); //$NON-NLS-1$ - System.out.println("\tfElementsToWidgets.size() " + fElementsToWidgets.size()); //$NON-NLS-1$ - } - } - - Image[] getImages(ImageDescriptor[] descriptors) { - if (descriptors == null || descriptors.length == 0) { - return new Image[0]; - } - Image[] images = new Image[descriptors.length]; - for (int i = 0; i < images.length; i++) { - images[i] = getImage(descriptors[i]); - } - return images; - } - - /** - * Returns an image for the given image descriptor or <code>null</code>. Adds the image - * to a cache of images if it does not already exist. The cache is cleared when this viewer - * is disposed. - * - * @param descriptor image descriptor or <code>null</code> - * @return image or <code>null</code> - */ - Image getImage(ImageDescriptor descriptor) { - if (descriptor == null) { - return null; - } - Image image = (Image) fImageCache.get(descriptor); - if (image == null) { - image = new Image(getControl().getDisplay(), descriptor.getImageData()); - fImageCache.put(descriptor, image); - } - return image; - } - - Font[] getFonts(FontData[] fontDatas) { - if (fontDatas == null) { - return new Font[0]; - } - - Font[] fonts = new Font[fontDatas.length]; - for (int i = 0; i < fonts.length; i++) { - fonts[i] = getFont(fontDatas[i]); - } - return fonts; - } - - /** - * Returns a font for the given font data or <code>null</code>. Adds the font to this viewer's font - * cache which is disposed when this viewer is disposed. - * - * @param fontData font data or <code>null</code> - * @return font font or <code>null</code> - */ - Font getFont(FontData fontData) { - if (fontData == null) { - return null; - } - Font font = (Font) fFontCache.get(fontData); - if (font == null) { - font = new Font(getControl().getDisplay(), fontData); - fFontCache.put(fontData, font); - } - return font; - } - - Color[] getColor(RGB[] rgb) { - if (rgb == null) { - return new Color[0]; - } - Color[] colors = new Color[rgb.length]; - for (int i = 0; i < colors.length; i++) { - colors[i] = getColor(rgb[i]); - } - return colors; - } - /** - * Returns a color for the given RGB or <code>null</code>. Adds the color to this viewer's color - * cache which is disposed when this viewer is disposed. - * - * @param rgb RGB or <code>null</code> - * @return color or <code>null</code> - */ - Color getColor(RGB rgb) { - if (rgb == null) { - return null; - } - Color color = (Color) fColorCache.get(rgb); - if (color == null) { - color = new Color(getControl().getDisplay(), rgb); - fColorCache.put(rgb, color); - } - return color; - } - - /** - * Sets the context for this viewer. - * - * @param context - */ - public void setContext(IPresentationContext context) { - fContext = context; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#doFindItem(java.lang.Object) - */ - protected Widget doFindItem(Object element) { - Widget[] widgets = getWidgets(element); - if (widgets != null && widgets.length > 0) { - return widgets[0]; - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#doUpdateItem(org.eclipse.swt.widgets.Widget, java.lang.Object, boolean) - */ - protected void doUpdateItem(Widget item, Object element, boolean fullMap) { - updateLabel(element, item); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#internalRefresh(java.lang.Object) - */ - protected void internalRefresh(Object element) { - Widget[] items = getWidgets(element); - if (items == null) { - return; - } - for (int i = 0; i < items.length; i++) { - internalRefresh(element, items[i]); - } - } - - /** - * Refreshes a specific occurrence of an element. - * - * @param element element to update - * @param item item to update - */ - protected void internalRefresh(Object element, Widget item) { - updateLabel(element, item); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean) - */ - public synchronized void setSelection(ISelection selection, boolean reveal) { - setSelection(selection, reveal, false); - } - - /** - * Sets the selection in this viewer. - * - * @param selection new selection - * @param reveal whether to reveal the selection - * @param force whether to force the selection change without consulting the model - * selection policy - */ - public synchronized void setSelection(ISelection selection, final boolean reveal, boolean force) { - Control control = getControl(); - if (control == null || control.isDisposed()) { - return; - } - if (!acceptsSelection(selection)) { - selection = getEmptySelection(); - } - if (!force && !overrideSelection(fCurrentSelection, selection)) { - return; - } - - fPendingSelection = selection; - - if (getControl().getDisplay().getThread() == Thread.currentThread()) { - attemptSelection(reveal); - } else { - WorkbenchJob job = new WorkbenchJob("attemptSelection") { //$NON-NLS-1$ - public IStatus runInUIThread(IProgressMonitor monitor) { - attemptSelection(reveal); - return Status.OK_STATUS; - } - - }; - job.setSystem(true); - job.schedule(); - } - } - - - /** - * Returns whether the candidate selection should override the current - * selection. - * - * @param current - * @param curr - * @return - */ - protected boolean overrideSelection(ISelection current, ISelection candidate) { - IModelSelectionPolicyAdapter selectionPolicy = getSelectionPolicy(current); - if (selectionPolicy == null) { - return true; - } - if (selectionPolicy.contains(candidate, getPresentationContext())) { - return selectionPolicy.overrides(current, candidate, getPresentationContext()); - } - return !selectionPolicy.isSticky(current, getPresentationContext()); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#getSelection() - */ - public ISelection getSelection() { - Control control = getControl(); - if (control == null || control.isDisposed() || fCurrentSelection == null) { - return StructuredSelection.EMPTY; - } - return fCurrentSelection; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#handleSelect(org.eclipse.swt.events.SelectionEvent) - */ - protected void handleSelect(SelectionEvent event) { - // handle case where an earlier selection listener disposed the control. - Control control = getControl(); - if (control != null && !control.isDisposed()) { - updateSelection(newSelectionFromWidget()); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#handlePostSelect(org.eclipse.swt.events.SelectionEvent) - */ - protected void handlePostSelect(SelectionEvent e) { - SelectionChangedEvent event = new SelectionChangedEvent(this, newSelectionFromWidget()); - firePostSelectionChanged(event); - } - - /** - * Creates and returns a new seletion from this viewer, based on the selected - * elements in the widget. - * - * @return a new selection - */ - protected abstract ISelection newSelectionFromWidget(); - - /** - * Returns the selection policy associated with the given selection - * or <code>null</code> if none. - * - * @param selection or <code>null</code> - * @return selection policy or <code>null</code> - */ - protected IModelSelectionPolicyAdapter getSelectionPolicy(ISelection selection) { - if (selection instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection) selection; - Object element = ss.getFirstElement(); - if (element instanceof IAdaptable) { - IAdaptable adaptable = (IAdaptable) element; - return (IModelSelectionPolicyAdapter) adaptable.getAdapter(IModelSelectionPolicyAdapter.class); - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#setSelectionToWidget(org.eclipse.jface.viewers.ISelection, boolean) - */ - final protected void setSelectionToWidget(ISelection selection, final boolean reveal) { - // NOT USED - throw new IllegalArgumentException("This method should not be called"); //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#setSelectionToWidget(java.util.List, boolean) - */ - final protected void setSelectionToWidget(List l, boolean reveal) { - // NOT USED - throw new IllegalArgumentException("This method should not be called"); //$NON-NLS-1$ - } - - /** - * Attempts to update any pending selection. - * - * @param reveal whether to reveal the selection - */ - protected void attemptSelection(boolean reveal) { - if (fPendingSelection != null && !fPendingSelection.isEmpty()) { - ISelection currentSelection = null; - - synchronized (this) { - ISelection remaining = doAttemptSelectionToWidget(fPendingSelection, reveal); - - if (!fPendingSelection.equals(remaining) || (fPendingSelection.isEmpty() && fPendingSelection.equals(remaining))) { - fPendingSelection = remaining; - currentSelection = newSelectionFromWidget(); - if (isSuppressEqualSelections() && currentSelection.equals(fCurrentSelection)) { - return; - } - } - } - - if (currentSelection != null) { - updateSelection(currentSelection); - } - } - } - - /** - * Controls whether selection change notification is sent even when - * successive selections are equal. - * - * TODO: what we really want is to fire selection change on ACTIVATE model - * change, even when selection is the same. - * - * @return whether to suppress change notification for equal successive - * selections - */ - protected boolean isSuppressEqualSelections() { - return true; - } - - /** - * Attempts to selection the specified selection and returns a selection - * representing the portion of the selection that could not be honored - * and still needs to be selected. - * - * @param selection selection to attempt - * @param reveal whether to reveal the selection - * @return remaining selection - */ - protected abstract ISelection doAttemptSelectionToWidget(ISelection selection, boolean reveal); - - /** - * Returns whether this viewer supports the given selection. - * - * @param selection a selection - * @return whether this viewer supports the given selection - */ - protected abstract boolean acceptsSelection(ISelection selection); - - /** - * Returns an empty selection supported by this viewer. - * - * @return an empty selection supported by this viewer - */ - protected abstract ISelection getEmptySelection(); - - /** - * A content provider that does nothing. - */ - private class NullContentProvider implements IStructuredContentProvider { - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - public Object[] getElements(Object inputElement) { - return null; - } - } - - /** - * Notification that a presentation update has failed. - * Subclasses may override as required. The default implementation - * does nothing. - * - * @param monitor monitor for the presentation request that failed - * @param status status of update - */ - protected void handlePresentationFailure(IAsynchronousRequestMonitor monitor, IStatus status) { - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#preservingSelection(java.lang.Runnable) - */ - protected synchronized void preservingSelection(Runnable updateCode) { - if (fPendingSelection == null || fPendingSelection.isEmpty()) { - ISelection oldSelection = null; - try { - // preserve selection - oldSelection = fCurrentSelection; - // perform the update - updateCode.run(); - } finally { - // restore selection - if (oldSelection == null) { - oldSelection = new StructuredSelection(); - } - if (getControl().getDisplay().getThread() == Thread.currentThread()) { - restoreSelection(oldSelection); - } else { - final ISelection tempSelection = oldSelection; - WorkbenchJob job = new WorkbenchJob("attemptSelection") { //$NON-NLS-1$ - public IStatus runInUIThread(IProgressMonitor monitor) { - if (!getControl().isDisposed()) { - restoreSelection(tempSelection); - } - return Status.OK_STATUS; - } - - }; - job.setSystem(true); - job.schedule(); - } - } - } else { - updateCode.run(); - } - } - - protected synchronized void restoreSelection(ISelection oldSelection) { - doAttemptSelectionToWidget(oldSelection, false); - // send out notification if old and new differ - fCurrentSelection = newSelectionFromWidget(); - if (!fCurrentSelection.equals(oldSelection)) - handleInvalidSelection(oldSelection, fCurrentSelection); - } - - /** - * Sets the color attributes of the given widget. - * - * @param widget the widget to update - * @param foreground foreground color of the widget or <code>null</code> if default - * @param background background color of the widget or <code>null</code> if default - */ - abstract void setColors(Widget widget, RGB foreground[], RGB background[]); - - /** - * Sets the label attributes of the given widget. - * - * @param widget the widget to update - * @param text label text - * @param image label image or <code>null</code> - */ - abstract void setLabels(Widget widget, String[] text, ImageDescriptor[] image); - - /** - * Sets the font attributes of the given widget. - * - * @param widget widget to update - * @param font font of the widget or <code>null</code> if default. - */ - abstract void setFonts(Widget widget, FontData[] font); - - /** - * Returns the parent widget of the give widget or <code>null</code> - * if none. This method can be called in a non-UI thread. - * - * @param widget widget - * @return parent widget or <code>null</code> - */ - protected abstract Widget getParent(Widget widget); - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.StructuredViewer#updateSelection(org.eclipse.jface.viewers.ISelection) - */ - protected synchronized void updateSelection(ISelection selection) { - fCurrentSelection = selection; - super.updateSelection(selection); - } - - protected abstract void setChildren(Widget widget, List children); - protected abstract void add(Widget parent, Object element); - - - /** - * @return if there are any more pending updates in the viewer - */ - protected boolean hasPendingUpdates() - { - return !fPendingUpdates.isEmpty(); - } -} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/ChildrenRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/ChildrenRequestMonitor.java deleted file mode 100644 index e2eba935b..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/ChildrenRequestMonitor.java +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.debug.internal.ui.viewers.provisional.IChildrenRequestMonitor; -import org.eclipse.swt.widgets.Widget; - -/** - * Implementation for <code>IChildrenRequestMonitor</code>. Collects - * children from an asynchronous tree content adapter. - * <p> - * Not intended to be subclassed or instantiated by clients. For use - * speficially with <code>AsynchronousTreeViewer</code>. - * </p> - * @since 3.2 - */ -class ChildrenRequestMonitor extends AsynchronousRequestMonitor implements IChildrenRequestMonitor { - - private boolean fFirstUpdate = true; - - /** - * Collection of children retrieved - */ - private List fChildren = new ArrayList(); - - /** - * Constucts a monitor to retrieve and update the children of the given - * widget. - * - * @param widget widget to retrieve children for - */ - ChildrenRequestMonitor(Widget widget, AsynchronousViewer viewer) { - super(widget, viewer); - } - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.viewers.IChildrenRequestMonitor#addChild(java.lang.Object) - */ - public void addChild(Object child) { - synchronized (fChildren) { - fChildren.add(child); - } - - scheduleViewerUpdate(250); - } - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.viewers.IChildrenRequestMonitor#addChildren(java.lang.Object[]) - */ - public void addChildren(Object[] children) { - synchronized (fChildren) { - for (int i = 0; i < children.length; i++) { - fChildren.add(children[i]); - } - } - - scheduleViewerUpdate(0); - } - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.viewers.AsynchronousRequestMonitor#contains(org.eclipse.debug.ui.viewers.AsynchronousRequestMonitor) - */ - protected boolean contains(AsynchronousRequestMonitor update) { - return update instanceof ChildrenRequestMonitor && contains(update.getWidget()); - } - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.viewers.AsynchronousRequestMonitor#performUpdate() - */ - protected void performUpdate() { - synchronized (fChildren) { - if (fFirstUpdate) { - getViewer().setChildren(getWidget(), fChildren); - fFirstUpdate = false; - } else { - for (Iterator iter = fChildren.iterator(); iter.hasNext();) { - Object child = iter.next(); - getViewer().add(getWidget(), child); - } - } - - fChildren.clear(); - } - } - -} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/DefaultElementComparer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/DefaultElementComparer.java deleted file mode 100644 index 46593e6be..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/DefaultElementComparer.java +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers; - -import org.eclipse.jface.viewers.IElementComparer; - -/** - * Default comparator used to compare individual elements in a tree path. - * - * @since 3.2 - * @see org.eclipse.debug.internal.ui.treeviewer.TreePath - */ -public class DefaultElementComparer implements IElementComparer { - - public static final DefaultElementComparer INSTANCE= new DefaultElementComparer(); - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IElementComparer#equals(java.lang.Object, java.lang.Object) - */ - public boolean equals(Object a, Object b) { - return a.equals(b); - } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IElementComparer#hashCode(java.lang.Object) - */ - public int hashCode(Object element) { - return element.hashCode(); - } -} - diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultTableUpdatePolicy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/DefaultTableUpdatePolicy.java index b35fc36a8..a0b61c02d 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/DefaultTableUpdatePolicy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/DefaultTableUpdatePolicy.java @@ -8,10 +8,9 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.update; +package org.eclipse.debug.internal.ui.viewers; -import org.eclipse.debug.internal.ui.viewers.AsynchronousTableViewer; -import org.eclipse.debug.internal.ui.viewers.AsynchronousViewer; +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer; import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; import org.eclipse.jface.viewers.StructuredSelection; @@ -21,14 +20,14 @@ import org.eclipse.jface.viewers.StructuredSelection; * * @since 3.2 */ -public class DefaultTableUpdatePolicy extends AbstractUpdatePolicy implements IModelChangedListener { +public class DefaultTableUpdatePolicy extends org.eclipse.debug.internal.ui.model.viewers.AbstractUpdatePolicy implements IModelChangedListener { public void modelChanged(IModelDelta delta) { updateNodes(new IModelDelta[] {delta}); } private void handleState(IModelDelta node) { - AsynchronousViewer viewer = getViewer(); + AsynchronousModelViewer viewer = getViewer(); if (viewer != null) { Object element = node.getElement(); viewer.update(element); @@ -36,7 +35,7 @@ public class DefaultTableUpdatePolicy extends AbstractUpdatePolicy implements IM } } private void handleContent(IModelDelta node) { - AsynchronousViewer viewer = getViewer(); + AsynchronousModelViewer viewer = getViewer(); if (viewer != null) { Object element = node.getElement(); viewer.refresh(element); @@ -45,10 +44,10 @@ public class DefaultTableUpdatePolicy extends AbstractUpdatePolicy implements IM } private void updateSelection(Object element, int flags) { - AsynchronousViewer viewer = getViewer(); + AsynchronousModelViewer viewer = getViewer(); if (viewer != null) { if ((flags & IModelDelta.SELECT) != 0) { - ((AsynchronousTableViewer) getViewer()).setSelection(new StructuredSelection(element)); + getViewer().setSelection(new StructuredSelection(element)); } } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/IUpdatePolicy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/IUpdatePolicy.java deleted file mode 100644 index 0930535db..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/IUpdatePolicy.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers; - - - -/** - * An update policy updates elements from an instance of a model - * in a viewer. - * - * @since 3.2 - */ -public interface IUpdatePolicy { - - /** - * Installs this update policy on the given viewer. - * - * @param viewer viewer to update - */ - public void init(AsynchronousViewer viewer); - - /** - * Disposes this update policy. - */ - public void dispose(); - -} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/LabelRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/LabelRequestMonitor.java deleted file mode 100644 index 3eb7c4de5..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/LabelRequestMonitor.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers; - -import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Widget; - -/** - * Implementation of an <code>ILabelRequestMonitor</code>. Collects label - * attributes from an asynchronous label adapter. - * <p> - * Not intended to be subclassed or instantiated by clients. For use speficially - * with <code>AsynchronousViewer</code>. - * </p> - * - * @since 3.2 - */ -class LabelRequestMonitor extends AsynchronousRequestMonitor implements ILabelRequestMonitor { - - /** - * Retrieved label text. Only <code>null</code> if cancelled or failed. - */ - private String[] fLabels; - - /** - * Retrieved image descriptor or <code>null</code> - */ - private ImageDescriptor[] fImageDescriptors; - - /** - * Retrieved font data or <code>null</code> - */ - private FontData[] fFontDatas; - - /** - * Retieved colors or <code>null</code> - */ - private RGB[] fForegrounds; - private RGB[] fBackgrounds; - - /** - * Cosntructs a request to upate the label of the given widget in the give - * viewer. - * - * @param widget widget to update - * @param viewer viewer containing the widget - */ - LabelRequestMonitor(Widget widget, AsynchronousViewer viewer) { - super(widget, viewer); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.debug.ui.viewers.AsynchronousRequestMonitor#performUpdate() - */ - protected void performUpdate() { - AsynchronousViewer viewer = getViewer(); - Widget widget = getWidget(); - viewer.setLabels(widget, fLabels, fImageDescriptors); - viewer.setColors(widget, fForegrounds, fBackgrounds); - viewer.setFonts(widget, fFontDatas); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.debug.ui.viewers.AsynchronousRequestMonitor#contains(org.eclipse.debug.ui.viewers.AsynchronousRequestMonitor) - */ - protected boolean contains(AsynchronousRequestMonitor update) { - return update instanceof LabelRequestMonitor && update.getWidget() == getWidget(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.debug.ui.viewers.ILabelRequestMonitor#setLabel(java.lang.String) - */ - public void setLabels(String[] text) { - fLabels = text; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.debug.ui.viewers.ILabelRequestMonitor#setFontData(org.eclipse.swt.graphics.FontData) - */ - public void setFontDatas(FontData[] fontData) { - fFontDatas = fontData; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.debug.ui.viewers.ILabelRequestMonitor#setImageDescriptor(org.eclipse.jface.resource.ImageDescriptor) - */ - public void setImageDescriptors(ImageDescriptor[] image) { - fImageDescriptors = image; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.debug.ui.viewers.ILabelRequestMonitor#setForeground(org.eclipse.swt.graphics.RGB) - */ - public void setForegrounds(RGB[] foreground) { - fForegrounds = foreground; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.debug.ui.viewers.ILabelRequestMonitor#setBackground(org.eclipse.swt.graphics.RGB) - */ - public void setBackgrounds(RGB[] background) { - fBackgrounds = background; - } - -} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableAddRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableAddRequestMonitor.java new file mode 100644 index 000000000..ab38a2d2e --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableAddRequestMonitor.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers; + +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModel; +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelRequestMonitor; +import org.eclipse.debug.internal.ui.model.viewers.ModelNode; + +/** + * @since 3.2 + * + */ +public class TableAddRequestMonitor extends AsynchronousModelRequestMonitor { + + protected Object[] fElements; + + /** + * @param node + * @param model + */ + TableAddRequestMonitor(ModelNode parent, Object elements[], AsynchronousModel model) { + super(parent, model); + fElements = elements; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelRequestMonitor#performUpdate() + */ + protected void performUpdate() { + ((AsynchronousTableModel)getModel()).added(fElements); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelRequestMonitor#contains(org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelRequestMonitor) + */ + protected boolean contains(AsynchronousModelRequestMonitor update) { + return false; + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableInsertRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableInsertRequestMonitor.java new file mode 100644 index 000000000..eeb2a6d87 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableInsertRequestMonitor.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers; + +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModel; +import org.eclipse.debug.internal.ui.model.viewers.ModelNode; + +/** + * @since 3.2 + * + */ +public class TableInsertRequestMonitor extends TableAddRequestMonitor { + + private int fIndex; + + /** + * @param node + * @param model + */ + TableInsertRequestMonitor(ModelNode parent, Object elements[], int index, AsynchronousModel model) { + super(parent, elements, model); + fIndex = index; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelRequestMonitor#performUpdate() + */ + protected void performUpdate() { + ((AsynchronousTableModel)getModel()).inserted(fElements, fIndex); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableRemoveRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableRemoveRequestMonitor.java new file mode 100644 index 000000000..9149993ee --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableRemoveRequestMonitor.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers; + +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModel; +import org.eclipse.debug.internal.ui.model.viewers.ModelNode; + +/** + * @since 3.2 + * + */ +public class TableRemoveRequestMonitor extends TableAddRequestMonitor { + + /** + * @param parent + * @param elements + * @param model + */ + TableRemoveRequestMonitor(ModelNode parent, Object[] elements, AsynchronousModel model) { + super(parent, elements, model); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelRequestMonitor#performUpdate() + */ + protected void performUpdate() { + ((AsynchronousTableModel)getModel()).removed(fElements); + } +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableReplaceRequestMonitor.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableReplaceRequestMonitor.java new file mode 100644 index 000000000..671b3e3a7 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/TableReplaceRequestMonitor.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.viewers; + +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModel; +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelRequestMonitor; +import org.eclipse.debug.internal.ui.model.viewers.ModelNode; + +/** + * @since 3.2 + * + */ +public class TableReplaceRequestMonitor extends AsynchronousModelRequestMonitor { + + private Object fOriginal; + private Object fReplacement; + + /** + * @param node + * @param model + */ + TableReplaceRequestMonitor(ModelNode node, Object element, Object replacement, AsynchronousModel model) { + super(node, model); + fReplacement = replacement; + fOriginal = element; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelRequestMonitor#performUpdate() + */ + protected void performUpdate() { + ((AsynchronousTableModel)getModel()).replaced(fOriginal, fReplacement); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelRequestMonitor#contains(org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelRequestMonitor) + */ + protected boolean contains(AsynchronousModelRequestMonitor update) { + return false; + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/AbstractUpdatePolicy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/AbstractUpdatePolicy.java deleted file mode 100644 index 8ead85266..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/update/AbstractUpdatePolicy.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.debug.internal.ui.viewers.update; - -import org.eclipse.debug.internal.ui.viewers.AsynchronousViewer; -import org.eclipse.debug.internal.ui.viewers.IUpdatePolicy; - -/** - * @since 3.2 - * - */ -public abstract class AbstractUpdatePolicy implements IUpdatePolicy { - - private AsynchronousViewer fViewer = null; - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.viewers.IUpdatePolicy#init(org.eclipse.debug.ui.viewers.update.IPresentation) - */ - public void init(AsynchronousViewer viewer) { - fViewer = viewer; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.ui.viewers.IUpdatePolicy#dispose() - */ - public synchronized void dispose() { - fViewer = null; - } - - /** - * Returns the viewer this policy is installed on or <code>null</code> - * if disposed. - * - * @return presentation to update - */ - public AsynchronousViewer getViewer() { - return fViewer; - } - - protected synchronized boolean isDisposed() { - return fViewer == null; - } - -} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AbstractAsyncTableRendering.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AbstractAsyncTableRendering.java index c1e7b5d9a..ca23eec05 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AbstractAsyncTableRendering.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AbstractAsyncTableRendering.java @@ -67,6 +67,8 @@ import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.custom.TableCursor; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseTrackAdapter; import org.eclipse.swt.events.SelectionAdapter; @@ -114,7 +116,14 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende */ public void run() { fIsShowAddressColumn = !fIsShowAddressColumn; - resizeColumnsToPreferredSize(); + if (!fIsShowAddressColumn) + { + fTableViewer.getTable().getColumn(0).setWidth(0); + } + else + { + fTableViewer.getTable().getColumn(0).pack(); + } updateActionLabel(); } @@ -265,8 +274,8 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende public void resetRendering() throws DebugException { BigInteger baseAddress = fContentDescriptor.getContentBaseAddress(); goToAddress(baseAddress); - fTableViewer.setTopIndex(baseAddress); fTableViewer.setSelection(baseAddress); + fTableViewer.setTopIndex(baseAddress); } public Control createControl(Composite parent) { @@ -778,8 +787,6 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende { reloadTable(address); } - Object selection = fTableViewer.getSelectionKey(); - fTableViewer.setSelection(selection); } private boolean isAtBottomBuffer(BigInteger address) @@ -788,8 +795,8 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende if (idx < 0) return true; - int bottomIdx = idx + fTableViewer.getContentManager().getVisibleItemCount(idx); - int elementsCnt = fTableViewer.getContentManager().getElements().length; + int bottomIdx = idx + getNumberOfVisibleLines(); + int elementsCnt = fTableViewer.getVirtualContentModel().getElements().length; int numLinesLeft = elementsCnt - bottomIdx; if (numLinesLeft <= 3) @@ -832,13 +839,12 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende public void run() { // call this to make the table viewer to reload when needed - fTableViewer.setSelection(address); - int i = fTableViewer.indexOf(address); if (i < 0) { topVisibleAddressChanged(address); } + fTableViewer.setSelection(address); } }; @@ -1251,10 +1257,11 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende { BigInteger startAddress = fContentDescriptor.getStartAddress(); startAddress = MemoryViewUtil.alignDoubleWordBoundary(startAddress); - if (fTableViewer.getContentManager() instanceof IVirtualContentManager) + AbstractVirtualContentTableModel model = fTableViewer.getVirtualContentModel(); + + if (model != null) { - IVirtualContentManager vcMgr = (IVirtualContentManager)fTableViewer.getContentManager(); - Object key = vcMgr.getKey(0); + Object key = model.getKey(0); if (key instanceof BigInteger) { BigInteger startBufferAddress = (BigInteger)key; @@ -1272,12 +1279,11 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende BigInteger endAddress = fContentDescriptor.getEndAddress(); endAddress = MemoryViewUtil.alignDoubleWordBoundary(endAddress); - int numElements = fTableViewer.getContentManager().getElements().length; - - if (fTableViewer.getContentManager() instanceof IVirtualContentManager) + AbstractVirtualContentTableModel model = fTableViewer.getVirtualContentModel(); + if (model != null) { - IVirtualContentManager vcMgr = (IVirtualContentManager)fTableViewer.getContentManager(); - Object key = vcMgr.getKey(numElements-1); + int numElements = model.getElements().length; + Object key = model.getKey(numElements-1); if (key instanceof BigInteger) { BigInteger endBufferAddress = (BigInteger)key; @@ -1644,7 +1650,10 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende public void goToAddress(BigInteger address) throws DebugException { - int i = fTableViewer.getVirtualContentManager().indexOf(address); + if (fTableViewer.getVirtualContentModel() == null) + return; + + int i = fTableViewer.getVirtualContentModel().indexOfKey(address); if (i >= 0) { @@ -1680,11 +1689,11 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende DebugException e = new DebugException(stat); throw e; } - + // load at the address - reloadTable(address); fTableViewer.setSelection(address); - + reloadTable(address); + updateSyncSelectedAddress(address); if (!isDynamicLoad()) @@ -1702,10 +1711,18 @@ public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRende public void resizeColumnsToPreferredSize() { fTableViewer.resizeColumnsToPreferredSize(); - if (!fIsShowAddressColumn) { - fTableViewer.getTable().getColumn(0).setWidth(0); + final TableColumn column = fTableViewer.getTable().getColumn(0); + column.addControlListener(new ControlListener() { + + public void controlMoved(ControlEvent e) { + } + + public void controlResized(ControlEvent e) { + column.removeControlListener(this); + column.setWidth(0); + }}); } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AbstractVirtualContentTableModel.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AbstractVirtualContentTableModel.java new file mode 100644 index 000000000..bf9193c92 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AbstractVirtualContentTableModel.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.views.memory.renderings; + +import java.util.ArrayList; + +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer; +import org.eclipse.debug.internal.ui.model.viewers.ModelNode; +import org.eclipse.debug.internal.ui.viewers.AsynchronousTableModel; + +abstract public class AbstractVirtualContentTableModel extends AsynchronousTableModel{ + + public AbstractVirtualContentTableModel(AsynchronousModelViewer viewer) { + super(viewer); + } + + public Object[] getElements() + { + ModelNode[] nodes = getNodes(getRootNode().getElement()); + ArrayList result = new ArrayList(); + if (nodes != null) + { + for (int i=0; i<nodes.length; i++) + { + ModelNode[] children = nodes[i].getChildrenNodes(); + if (children != null) + { + for (int j=0; j<children.length; j++) + { + result.add(children[j].getElement()); + } + } + } + + return result.toArray(); + } + return new Object[0]; + } + + public Object getElement(int idx) + { + Object[] elements = getElements(); + if (idx >=0 && idx < elements.length) + return elements[idx]; + + return null; + } + + + public int indexOfElement(Object element) + { + Object[] elements = getElements(); + + for (int i=0; i<elements.length; i++) + { + if (elements[i] == element) + return i; + } + return -1; + } + + abstract public int indexOfKey(Object key); + + abstract public int columnOf(Object element, Object key); + + abstract public Object getKey(int idx); + + abstract public Object getKey(Object element); + + abstract public Object getKey(int idx, int col); + + public void handleViewerChanged() + { + + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncTableRenderingUpdatePolicy.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncTableRenderingUpdatePolicy.java index ee77dba96..6b0fec436 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncTableRenderingUpdatePolicy.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncTableRenderingUpdatePolicy.java @@ -18,10 +18,9 @@ import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlockExtension; -import org.eclipse.debug.internal.ui.viewers.AsynchronousTableViewerContentManager; +import org.eclipse.debug.internal.ui.viewers.DefaultTableUpdatePolicy; import org.eclipse.debug.internal.ui.viewers.provisional.IModelChangedListener; import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.update.DefaultTableUpdatePolicy; import org.eclipse.ui.progress.UIJob; /** @@ -35,40 +34,44 @@ class AsyncTableRenderingUpdatePolicy extends DefaultTableUpdatePolicy public void modelChanged(IModelDelta node) { // clear current cache as it becomes invalid when the memory block is changed - AsynchronousTableViewerContentManager contentManager = getTableViewer().getContentManager(); - IContentChangeComputer computer = null; - if (contentManager instanceof IContentChangeComputer) - computer = (IContentChangeComputer)contentManager; + AbstractVirtualContentTableModel model = getTableViewer().getVirtualContentModel(); - clearCache(computer); - - if (!shouldHandleEvent(node)) + if (model != null) { - return; - } - - if (node.getElement() instanceof IMemoryBlock && (node.getFlags() & IModelDelta.CONTENT) != 0) - { - if (computer != null && getTableViewer() != null) + IContentChangeComputer computer = null; + if (model instanceof IContentChangeComputer) + computer = (IContentChangeComputer)model; + + clearCache(computer); + + if (!containsEvent(node)) { - // only cache if the rendering is not currently displaying error - if (!getTableViewer().getRendering().isDisplayingError()) - { - // cache visible elelements - computer.cache(getTableViewer().getContentManager().getElements()); - } + return; } - // override handling of content node - // let the super class deals with the rest of the changes - if (node.getElement() instanceof IMemoryBlock) + if (node.getElement() instanceof IMemoryBlock && (node.getFlags() & IModelDelta.CONTENT) != 0) { - // update policy figured out what's changed in the memory block - // and will tell rendering to update accordinly. - // Updating the rendering indirectly update the table viewer - notifyRendering(node); - handleMemoryBlockChanged((IMemoryBlock)node.getElement(), node); - return; + if (computer != null && getTableViewer() != null) + { + // only cache if the rendering is not currently displaying error + if (!getTableViewer().getRendering().isDisplayingError()) + { + // cache visible elelements + computer.cache(model.getElements()); + } + } + + // override handling of content node + // let the super class deals with the rest of the changes + if (node.getElement() instanceof IMemoryBlock) + { + // update policy figured out what's changed in the memory block + // and will tell rendering to update accordinly. + // Updating the rendering indirectly update the table viewer + notifyRendering(node); + handleMemoryBlockChanged((IMemoryBlock)node.getElement(), node); + return; + } } } @@ -149,7 +152,7 @@ class AsyncTableRenderingUpdatePolicy extends DefaultTableUpdatePolicy return null; } - private boolean shouldHandleEvent(IModelDelta delta) + private boolean containsEvent(IModelDelta delta) { if (getViewer().getPresentationContext() instanceof TableRenderingPresentationContext) { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncTableRenderingViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncTableRenderingViewer.java index 1370c9880..a30d9936d 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncTableRenderingViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncTableRenderingViewer.java @@ -12,24 +12,17 @@ package org.eclipse.debug.internal.ui.views.memory.renderings; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.debug.core.model.IMemoryBlock; -import org.eclipse.debug.core.model.IMemoryBlockExtension; import org.eclipse.debug.internal.ui.DebugUIMessages; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; -import org.eclipse.debug.internal.ui.viewers.AsynchronousTableViewerContentManager; -import org.eclipse.debug.internal.ui.viewers.IUpdatePolicy; +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModel; +import org.eclipse.debug.internal.ui.model.viewers.IModelUpdatePolicy; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor; import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil; -import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.ICellModifier; @@ -60,11 +53,10 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.progress.UIJob; public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { - + private AbstractAsyncTableRendering fRendering; // selection keys @@ -83,34 +75,10 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { private FocusAdapter fEditorFocusListener; private KeyAdapter fEditorKeyListener; - private boolean fMBSupportsChangeManagement; - - class SupportsChangeMgmtJob extends Job { - - SupportsChangeMgmtJob() - { - super("Support Change Management"); //$NON-NLS-1$ - setSystem(true); - } - - protected IStatus run(IProgressMonitor monitor) { - IMemoryBlock mb = fRendering.getMemoryBlock(); - if (mb instanceof IMemoryBlockExtension) - { - IMemoryBlockExtension mbExt = (IMemoryBlockExtension)mb; - fMBSupportsChangeManagement = mbExt.supportsChangeManagement(); - } - return Status.OK_STATUS; - } - - } - public AsyncTableRenderingViewer(AbstractAsyncTableRendering rendering, Composite parent, int style) { super(parent, style); fRendering = rendering; - new SupportsChangeMgmtJob().schedule(); - getTable().addMouseListener(new MouseAdapter() { public void mouseDown(MouseEvent e) { handleTableMouseEvent(e); @@ -119,66 +87,10 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { createCursor(getTable()); } - public IUpdatePolicy createUpdatePolicy() { - // TODO: need pluggble update policy + public IModelUpdatePolicy createUpdatePolicy() { return new AsyncTableRenderingUpdatePolicy(); } - // TODO: Need pluggable content manager to allow models to provide own content - // manager to translate model data to a key and vice versa - protected AsynchronousTableViewerContentManager createContentManager() { - return new TableRenderingContentManager(this); - } - - protected void setChildren(Widget widget, List children) { - - if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING) - { - System.out.println("Set Children in AsyncTableRenderingViewer"); //$NON-NLS-1$ - Iterator iter = children.iterator(); - int i=0; - while(iter.hasNext()) - { - System.out.println(i + " " + ((MemorySegment)iter.next()).getAddress().toString(16)); //$NON-NLS-1$ - i++; - } - } - - Object[] newContent = compare(children); - ArrayList newList = new ArrayList(); - for (int i=0; i<newContent.length; i++) - { - newList.add(newContent[i]); - } - - super.setChildren(widget, newList); - - if (widget == getTable()) - attemptSetKeySelection(); - } - - private Object[] compare(List newContent) - { - IContentChangeComputer computer = null; - - if (getContentManager() instanceof IContentChangeComputer) - computer = (IContentChangeComputer)getContentManager(); - - if (computer == null) - return newContent.toArray(); - - if (computer.isEmpty()) - return newContent.toArray(); - - if (isChangesManagedByMemoryBlock()) - { - return newContent.toArray(); - } - - Object[] content = computer.compare(newContent.toArray()); - return content; - } - public AbstractAsyncTableRendering getRendering() { return fRendering; @@ -202,6 +114,7 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { handleCursorKeyPressed(e); } }; + fTableCursor.addKeyListener(fCursorKeyAdapter); fCursorTraverseListener = new TraverseListener() { @@ -268,7 +181,6 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { } private void handleCursorTraverseEvt(TraverseEvent e){ - if (fTableCursor.getRow() == null) return; @@ -298,14 +210,14 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { fTableCursor.setSelection(row, col); } -// handleCursorMoved(); + handleCursorMoved(); } /** * Update selected address. * Load more memory if required. */ - private synchronized void handleCursorMoved() + private void handleCursorMoved() { fSelectionKey = getSelectionKeyFromCursor(); @@ -331,7 +243,6 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { */ public void setSelection(Object key) { - fSelectionKey = key; fPendingSelection = key; attemptSetKeySelection(); } @@ -341,19 +252,15 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { return fSelectionKey; } - synchronized private void attemptSetKeySelection() + private synchronized void attemptSetKeySelection() { if (fPendingSelection != null) { - Object remaining = doAttemptSetKeySelection(fPendingSelection); - if (remaining == null) - { - fPendingSelection = remaining; - } + doAttemptSetKeySelection(fPendingSelection); } } - synchronized Object doAttemptSetKeySelection(Object key) + synchronized private Object doAttemptSetKeySelection(final Object key) { if (getBufferTopKey() == null || getBufferEndKey() == null) return key; @@ -367,7 +274,7 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { return key; } - Object element = getContentManager().getElement(row); + Object element = getVirtualContentModel().getElement(row); final int col = columnOf(element, key); if (col == -1) @@ -380,17 +287,38 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { public IStatus runInUIThread(IProgressMonitor monitor) { try { + if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING) + System.out.println(getRendering() + " set cursor selection " + ((BigInteger)key).toString(16)); //$NON-NLS-1$ + + if (fPendingSelection != null && fPendingSelection != key) + return Status.OK_STATUS; + + fSelectionKey = key; + fPendingSelection = null; + + if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING) + { + System.out.println(getRendering() + " set cursor selection, row is " + getTable().getItem(row).getData()); //$NON-NLS-1$ + System.out.println(getRendering() + " set cursor selection, model is " + getVirtualContentModel().getElement(row)); //$NON-NLS-1$ + } + fTableCursor.setSelection(row, col); showTableCursor(true); + int topIndex = getTable().getTopIndex(); - Object topKey = getVirtualContentManager().getKey(topIndex); + Object topKey = getVirtualContentModel().getKey(topIndex); setTopIndexKey(topKey); } catch (RuntimeException e) { - // by the time this is called, the selection may no longer - // be valid, catch all exception and just hide cursor. + // hide cursor and retry selection showTableCursor(false); + + // by the time this is called, the selection may no longer + // get the latest selection and try to set selection again + Object selectionKey = getSelectionKey(); + fPendingSelection = selectionKey; + doAttemptSetKeySelection(selectionKey); } return Status.OK_STATUS; }}; @@ -402,11 +330,11 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { } private Object getSelectionKeyFromCursor() - { - int row = getContentManager().indexOfElement((getElement(fTableCursor.getRow()))); + { + int idx = getTable().indexOf(fTableCursor.getRow()); int col = fTableCursor.getColumn(); - return getVirtualContentManager().getKey(row, col); + return getVirtualContentModel().getKey(idx, col); } private Object getBufferTopKey() @@ -416,39 +344,39 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { private Object getBufferEndKey() { - AsynchronousTableViewerContentManager mgr = getContentManager(); + AbstractVirtualContentTableModel model = getVirtualContentModel(); - return getKey(mgr.getElements().length-1); + if (model != null) + return getKey(model.getElements().length-1); + return null; } public int indexOf(Object key) { int idx = -1; - AsynchronousTableViewerContentManager mgr = getContentManager(); - if (mgr instanceof IVirtualContentManager) - { - idx = ((IVirtualContentManager)mgr).indexOf(key); - } + AbstractVirtualContentTableModel model = getVirtualContentModel(); + if (model != null) + idx = model.indexOfKey(key); return idx; } private int columnOf(Object element, Object key) { int idx = -1; - AsynchronousTableViewerContentManager mgr = getContentManager(); - if (mgr instanceof IVirtualContentManager) + AbstractVirtualContentTableModel model = getVirtualContentModel(); + if (model != null) { - idx = ((IVirtualContentManager)mgr).columnOf(element, key); + idx = model.columnOf(element, key); } return idx; } public Object getKey(int index) { - AsynchronousTableViewerContentManager mgr = getContentManager(); - if (mgr instanceof IVirtualContentManager) + AbstractVirtualContentTableModel model = getVirtualContentModel(); + if (model != null) { - Object key = ((IVirtualContentManager)mgr).getKey(index); + Object key = model.getKey(index); return key; } return null; @@ -456,7 +384,10 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { public Object getKey(int row, int col) { - return getVirtualContentManager().getKey(row, col); + AbstractVirtualContentTableModel model = getVirtualContentModel(); + if (model != null) + return model.getKey(row, col); + return null; } @@ -471,7 +402,6 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { { oldTopIndexKey = getPendingSetTopIndexKey(); } - Object oldSelectionKey = null; try { if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING) @@ -482,13 +412,28 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { System.out.println("top index key is null, nothing to preserve"); //$NON-NLS-1$ } - oldSelectionKey = getSelectionKey(); + if (fPendingSelection != null) + oldSelectionKey = fPendingSelection; + else + oldSelectionKey = getSelectionKey(); + + if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING) + { + if (oldTopIndexKey != null) + System.out.println(getRendering() + " preserve selection: " + ((BigInteger)oldSelectionKey).toString(16)); //$NON-NLS-1$ + else + System.out.println("selection key is null, nothing to preserve"); //$NON-NLS-1$ + } + // perform the update updateCode.run(); } finally { + if (oldSelectionKey != null) { + if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING) + System.out.println(getRendering() + " preserved selection " + ((BigInteger)oldSelectionKey).toString(16)); //$NON-NLS-1$ setSelection(oldSelectionKey); } @@ -523,11 +468,15 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { public void showTableCursor(final boolean show) { + Display display = DebugUIPlugin.getDefault().getWorkbench().getDisplay(); if (Thread.currentThread() == display.getThread()) { if (!fTableCursor.isDisposed()) - fTableCursor.setVisible(show); + { + if (fTableCursor.isVisible() != show) + fTableCursor.setVisible(show); + } } else { @@ -535,7 +484,10 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { public IStatus runInUIThread(IProgressMonitor monitor) { if (!fTableCursor.isDisposed()) - fTableCursor.setVisible(show); + { + if (fTableCursor.isVisible() != show) + fTableCursor.setVisible(show); + } return Status.OK_STATUS; }}; @@ -543,24 +495,6 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { job.schedule(); } } - - public void setLabels(Widget widget, String[] labels, ImageDescriptor[] imageDescriptors) { - super.setLabels(widget, labels, imageDescriptors); - - // when the cursor selection is set, the table viewer may not have been populated - // hence the table cursor may not have been drawn properly - if (widget == fTableCursor.getRow()) - { - fTableCursor.redraw(); - } - - // HACK: hack to get cursor to be selected properly during reload - if (!hasPendingUpdates()) - { - fPendingSelection = getSelectionKey(); - attemptSetKeySelection(); - } - } private void handleTableMouseEvent(MouseEvent e) { // figure out new cursor position based on here the mouse is pointing @@ -927,10 +861,13 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { return; } - TableItem tableItem = getTable().getItem(row); - - Object property = getColumnProperties()[col]; - getCellModifier().modify(tableItem, (String)property, newValue); + if (row >= 0 && row < getTable().getItemCount()) + { + TableItem tableItem = getTable().getItem(row); + + Object property = getColumnProperties()[col]; + getCellModifier().modify(tableItem, (String)property, newValue); + } } public TableCursor getCursor() @@ -952,7 +889,7 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { } public String getColumnText(Object element, int columnIndex) { - int idx = getContentManager().indexOfElement(element); + int idx = getVirtualContentModel().indexOfElement(element); if (idx >= 0 ) { TableItem item = getTable().getItem(idx); @@ -982,10 +919,10 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { public void run() { // causes the content of the table viewer to be replaced // without asking content adapter for content - AsynchronousTableViewerContentManager mgr = getContentManager(); - if (mgr instanceof IVirtualContentManager) + AbstractVirtualContentTableModel model = getVirtualContentModel(); + if (model != null) { - ((IVirtualContentManager)mgr).handleViewerChanged(); + model.handleViewerChanged(); } }}); } @@ -1003,11 +940,6 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { super.handlePresentationFailure(monitor, status); } - private boolean isChangesManagedByMemoryBlock() - { - return fMBSupportsChangeManagement; - } - public void refresh(boolean getContent) { if (getContent) @@ -1017,11 +949,36 @@ public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer { preservingSelection(new Runnable() { public void run() { - AsynchronousTableViewerContentManager mgr = getContentManager(); - Object[] elements = mgr.getElements(); - mgr.remove(elements); - mgr.add(elements); + AbstractVirtualContentTableModel model = getVirtualContentModel(); + if (model != null) + { + Object[] elements = model.getElements(); + model.remove(elements); + model.add(elements); + } }}); } } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.model.viewers.AsynchronousModelViewer#getModel() + */ + public AsynchronousModel getModel() { + return super.getModel(); + } + + // TODO: need pluggable model to be truly flexible + protected AbstractVirtualContentTableModel createVirtualContentTableModel() { + return new TableRenderingModel(this); + } + + protected void updateComplete(IAsynchronousRequestMonitor monitor) { + super.updateComplete(monitor); + + if (!hasPendingUpdates()) + { + attemptSetKeySelection(); + fTableCursor.redraw(); + } + } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncVirtualContentTableViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncVirtualContentTableViewer.java index c77978691..0365f73f9 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncVirtualContentTableViewer.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/AsyncVirtualContentTableViewer.java @@ -13,7 +13,6 @@ package org.eclipse.debug.internal.ui.views.memory.renderings; import java.math.BigInteger; import java.util.ArrayList; -import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.ISafeRunnable; @@ -22,10 +21,11 @@ import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.model.viewers.AsynchronousModel; import org.eclipse.debug.internal.ui.viewers.AsynchronousTableViewer; -import org.eclipse.debug.internal.ui.viewers.AsynchronousTableViewerContentManager; import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor; -import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.debug.internal.ui.viewers.provisional.ILabelRequestMonitor; +import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; @@ -34,10 +34,10 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.ScrollBar; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.Widget; +import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.progress.UIJob; -public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { +abstract public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { private Object fPendingTopIndexKey; private ArrayList fTopIndexQueue = new ArrayList(); @@ -47,7 +47,7 @@ public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { private SelectionListener fScrollSelectionListener; private ListenerList fPresentationErrorListeners; private Object fTopIndexKey; - private IVirtualContentManager fVirtualContentManager; + public static boolean DEBUG_DYNAMIC_LOADING = false; public AsyncVirtualContentTableViewer(Composite parent, int style) { @@ -66,12 +66,6 @@ public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { }}; scroll.addSelectionListener(fScrollSelectionListener); } - - - public void setLabels(Widget widget, String[] labels, ImageDescriptor[] imageDescriptors) { - super.setLabels(widget, labels, imageDescriptors); - fPendingResizeColumns = attemptResizeColumnsToPreferredSize(); - } public void setTopIndex(Object key) { @@ -126,29 +120,27 @@ public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { if (fPendingResizeColumns) { if(!hasPendingUpdates()) { - Table table = getTable(); - TableColumn[] columns = table.getColumns(); + UIJob job = new UIJob("packcolumns"){ //$NON-NLS-1$ + + public IStatus runInUIThread(IProgressMonitor monitor) { + Table table = getTable(); + TableColumn[] columns = table.getColumns(); + + for (int i=0 ;i<columns.length-1; i++) + { + columns[i].pack(); + } + return Status.OK_STATUS; + }}; + job.setSystem(true); + job.schedule(); - for (int i=0 ;i<columns.length-1; i++) - { - columns[i].pack(); - } return false; } } return fPendingResizeColumns; } - protected IVirtualContentManager getVirtualContentManager() - { - if (fVirtualContentManager == null) - { - if (getContentManager() instanceof IVirtualContentManager) - fVirtualContentManager = (IVirtualContentManager)getContentManager(); - } - return fVirtualContentManager; - } - /** * Attempts to update any pending setTopIndex * @@ -166,7 +158,7 @@ public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { private synchronized Object doAttemptSetTopIndex(final Object topIndexKey) { - final int i = getVirtualContentManager().indexOf(topIndexKey); + final int i = getVirtualContentModel().indexOfKey(topIndexKey); if (i >= 0) { UIJob job = new UIJob("set top index"){ //$NON-NLS-1$ @@ -177,7 +169,7 @@ public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { // remove the top index key from queue when it is processed removeKeyFromQueue(topIndexKey); - int idx = getVirtualContentManager().indexOf(topIndexKey); + int idx = getVirtualContentModel().indexOfKey(topIndexKey); if (idx >= 0) { if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING) @@ -205,20 +197,6 @@ public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { } return topIndexKey; } - - protected void setChildren(final Widget widget, final List children) - { - preservingSelection(new Runnable() { - - public void run() { - if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING) - System.out.println(Thread.currentThread().getName() + " Set children"); //$NON-NLS-1$ - AsyncVirtualContentTableViewer.super.setChildren(widget, children); - }}); - - if (widget == getTable()) - attemptSetTopIndex(); - } public void addVirtualContentListener(IVirtualContentListener listener) { @@ -255,8 +233,8 @@ public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { { Object[] listeners = fVirtualContentListeners.getListeners(); int topIdx = getTable().getTopIndex(); - int bottomIdx = topIdx + getContentManager().getVisibleItemCount(topIdx); - int elementsCnt = getContentManager().getElements().length; + int bottomIdx = topIdx + getNumberOfVisibleLines(); + int elementsCnt = getVirtualContentModel().getElements().length; int numLinesLeft = elementsCnt - bottomIdx; for (int i = 0; i < listeners.length; i++) { @@ -291,7 +269,7 @@ public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { System.out.println(Thread.currentThread().getName() + " handle scroll bar moved: top index: " + a.getAddress().toString(16)); //$NON-NLS-1$ } - setTopIndexKey(getVirtualContentManager().getKey(getTable().getTopIndex())); + setTopIndexKey(getVirtualContentModel().getKey(getTable().getTopIndex())); notifyListenersAtBufferStart(); notifyListenersAtBufferEnd(); @@ -362,16 +340,17 @@ public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { } } - // TODO: viewer needs to create a content manager that implements IVirtualContentManager - protected AsynchronousTableViewerContentManager createContentManager() { - return super.createContentManager(); + protected AsynchronousModel createModel() { + return createVirtualContentTableModel(); } + abstract protected AbstractVirtualContentTableModel createVirtualContentTableModel(); + private void addKeyToQueue(Object topIndexKey) { synchronized(fTopIndexQueue){ if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING) - System.out.println(" >>> add to queue: " + ((BigInteger)topIndexKey).toString(16)); //$NON-NLS-1$ + System.out.println(" >>> add to top index queue: " + ((BigInteger)topIndexKey).toString(16)); //$NON-NLS-1$ fTopIndexQueue.add(topIndexKey); } } @@ -380,9 +359,83 @@ public class AsyncVirtualContentTableViewer extends AsynchronousTableViewer { { synchronized(fTopIndexQueue){ if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING) - System.out.println(" >>> remove frome queue: " + ((BigInteger)topIndexKey).toString(16)); //$NON-NLS-1$ + System.out.println(" >>> remove frome top index queue: " + ((BigInteger)topIndexKey).toString(16)); //$NON-NLS-1$ fTopIndexQueue.remove(topIndexKey); } } + + public AbstractVirtualContentTableModel getVirtualContentModel() + { + if (getModel() instanceof AbstractVirtualContentTableModel) + return (AbstractVirtualContentTableModel) getModel(); + return null; + } + + private int getNumberOfVisibleLines() + { + Table table = getTable(); + int height = table.getSize().y; + + // when table is not yet created, height is zero + if (height == 0) + { + // make use of the table viewer to estimate table size + height = table.getParent().getSize().y; + } + + // height of border + int border = table.getHeaderHeight(); + + // height of scroll bar + int scroll = table.getHorizontalBar().getSize().y; + + // height of table is table's area minus border and scroll bar height + height = height-border-scroll; + + // calculate number of visible lines + int lineHeight = getMinTableItemHeight(table); + + int numberOfLines = height/lineHeight; + + if (numberOfLines <= 0) + return 20; + + return numberOfLines; + } + + private int getMinTableItemHeight(Table table){ + + // Hack to get around Linux GTK problem. + // On Linux GTK, table items have variable item height as + // carriage returns are actually shown in a cell. Some rows will be + // taller than others. When calculating number of visible lines, we + // need to find the smallest table item height. Otherwise, the rendering + // underestimates the number of visible lines. As a result the rendering + // will not be able to get more memory as needed. + if (MemoryViewUtil.isLinuxGTK()) + { + // check each of the items and find the minimum + TableItem[] items = table.getItems(); + int minHeight = table.getItemHeight(); + for (int i=0; i<items.length; i++) + { + minHeight = Math.min(items[i].getBounds(0).height, minHeight); + } + + return minHeight; + + } + return table.getItemHeight(); + } + + protected void updateComplete(IAsynchronousRequestMonitor monitor) { + super.updateComplete(monitor); + attemptSetTopIndex(); + if (monitor instanceof ILabelRequestMonitor) + { + fPendingResizeColumns = attemptResizeColumnsToPreferredSize(); + } + } + } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/IVirtualContentManager.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/IVirtualContentManager.java deleted file mode 100644 index d9819721d..000000000 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/IVirtualContentManager.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation 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: - * IBM Corporation - initial API and implementation - *******************************************************************************/ - -package org.eclipse.debug.internal.ui.views.memory.renderings; - -public interface IVirtualContentManager { - - public int indexOf(Object key); - - public int columnOf(Object element, Object key); - - public Object getKey(int idx); - - public Object getKey(Object element); - - public Object getKey(int idx, int col); - - public void handleViewerChanged(); -} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingContentManager.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingModel.java index a0bdf3988..1189928cc 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingContentManager.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingModel.java @@ -15,25 +15,58 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; +import java.util.List; import java.util.Vector; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockExtension; import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.debug.internal.ui.model.viewers.ModelNode; import org.eclipse.debug.internal.ui.viewers.AsynchronousTableViewer; -import org.eclipse.debug.internal.ui.viewers.AsynchronousTableViewerContentManager; -public class TableRenderingContentManager extends - AsynchronousTableViewerContentManager implements IVirtualContentManager, IContentChangeComputer { + +public class TableRenderingModel extends AbstractVirtualContentTableModel + implements IContentChangeComputer { + private Hashtable fCache; private Vector fOrderedCache; // needed to re-organize cache - public TableRenderingContentManager(AsynchronousTableViewer viewer) { + private boolean fMBSupportsChangeManagement; + private IMemoryBlock fMemoryBlock; + + class SupportsChangeMgmtJob extends Job { + + SupportsChangeMgmtJob() + { + super("Support Change Management"); //$NON-NLS-1$ + setSystem(true); + } + + protected IStatus run(IProgressMonitor monitor) { + IMemoryBlock mb = getMemoryBlock(); + if (mb instanceof IMemoryBlockExtension) + { + IMemoryBlockExtension mbExt = (IMemoryBlockExtension)mb; + fMBSupportsChangeManagement = mbExt.supportsChangeManagement(); + } + return Status.OK_STATUS; + } + + } + + + public TableRenderingModel(AsynchronousTableViewer viewer) { super(viewer); fCache = new Hashtable(); fOrderedCache = new Vector(); } - public int indexOf(Object key) + public int indexOfKey(Object key) { if (key instanceof BigInteger) { @@ -327,6 +360,53 @@ public class TableRenderingContentManager extends // } // System.out.println(buf.toString()); // } + + private AsynchronousTableViewer getTableViewer() + { + return (AsynchronousTableViewer)getViewer(); + } + protected void setChildren(ModelNode parentNode, List kids) { + + if (computeChanges()) + { + Object[] newContent = compare(kids.toArray()); + ArrayList newList = new ArrayList(); + for (int i=0; i<newContent.length; i++) + { + newList.add(newContent[i]); + } + super.setChildren(parentNode, newList); + } + else + super.setChildren(parentNode, kids); + } + + private boolean computeChanges() + { + if (isEmpty()) + return false; + + if (fMBSupportsChangeManagement) + { + return false; + } + + return true; + } + + private IMemoryBlock getMemoryBlock() + { + return fMemoryBlock; + } + + public void init(Object root) { + if (root instanceof IMemoryBlock) + { + fMemoryBlock = (IMemoryBlock)root; + new SupportsChangeMgmtJob().schedule(); + } + super.init(root); + } } |