Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 55916 Details for
Bug 167325
[Viewers]ViewerCell and ViewerRow should provide API to find neighbors
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Addressing Boris requestes
167325.patch (text/plain), 19.08 KB, created by
Thomas Schindl
on 2006-12-19 13:35:32 EST
(
hide
)
Description:
Addressing Boris requestes
Filename:
MIME Type:
Creator:
Thomas Schindl
Created:
2006-12-19 13:35:32 EST
Size:
19.08 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jface.snippets >Index: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet026TreeViewerTabEditing.java >=================================================================== >RCS file: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet026TreeViewerTabEditing.java >diff -N Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet026TreeViewerTabEditing.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet026TreeViewerTabEditing.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,222 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 Tom Schindl 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: >+ * Tom Schindl - initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.jface.snippets.viewers; >+ >+import java.util.ArrayList; >+ >+import org.eclipse.jface.resource.FontRegistry; >+import org.eclipse.jface.viewers.CellEditor; >+import org.eclipse.jface.viewers.EditingSupport; >+import org.eclipse.jface.viewers.ICellModifier; >+import org.eclipse.jface.viewers.ITableLabelProvider; >+import org.eclipse.jface.viewers.ITreeContentProvider; >+import org.eclipse.jface.viewers.LabelProvider; >+import org.eclipse.jface.viewers.TextCellEditor; >+import org.eclipse.jface.viewers.TreeViewer; >+import org.eclipse.jface.viewers.Viewer; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.layout.FillLayout; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.TreeColumn; >+import org.eclipse.swt.widgets.TreeItem; >+ >+/** >+ * A simple TreeViewer to demonstrate usage >+ * >+ * @author Tom Schindl <tom.schindl@bestsolution.at> >+ * >+ */ >+public class Snippet026TreeViewerTabEditing { >+ private class MyContentProvider implements ITreeContentProvider { >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) >+ */ >+ public Object[] getElements(Object inputElement) { >+ return ((MyModel) inputElement).child.toArray(); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.jface.viewers.IContentProvider#dispose() >+ */ >+ public void dispose() { >+ >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, >+ * java.lang.Object, java.lang.Object) >+ */ >+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { >+ >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) >+ */ >+ public Object[] getChildren(Object parentElement) { >+ return getElements(parentElement); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) >+ */ >+ public Object getParent(Object element) { >+ if (element == null) { >+ return null; >+ } >+ >+ return ((MyModel) element).parent; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) >+ */ >+ public boolean hasChildren(Object element) { >+ return ((MyModel) element).child.size() > 0; >+ } >+ >+ } >+ >+ public class MyModel { >+ public MyModel parent; >+ >+ public ArrayList child = new ArrayList(); >+ >+ public int counter; >+ >+ public MyModel(int counter, MyModel parent) { >+ this.parent = parent; >+ this.counter = counter; >+ } >+ >+ public String toString() { >+ String rv = "Item "; >+ if (parent != null) { >+ rv = parent.toString() + "."; >+ } >+ >+ rv += counter; >+ >+ return rv; >+ } >+ } >+ >+ public class MyLabelProvider extends LabelProvider implements >+ ITableLabelProvider { >+ FontRegistry registry = new FontRegistry(); >+ >+ public Image getColumnImage(Object element, int columnIndex) { >+ return null; >+ } >+ >+ public String getColumnText(Object element, int columnIndex) { >+ return "Column " + columnIndex + " => " + element.toString(); >+ } >+ } >+ >+ public Snippet026TreeViewerTabEditing(Shell shell) { >+ final TreeViewer v = new TreeViewer(shell,SWT.BORDER|SWT.FULL_SELECTION); >+ >+ TreeColumn column = new TreeColumn(v.getTree(),SWT.NONE); >+ column.setWidth(200); >+ column.setText("Column 1"); >+ >+ column = new TreeColumn(v.getTree(),SWT.NONE); >+ column.setWidth(200); >+ column.setText("Column 2"); >+ >+ v.setLabelProvider(new MyLabelProvider()); >+ v.setContentProvider(new MyContentProvider()); >+ v.setCellModifier(new ICellModifier() { >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, java.lang.String) >+ */ >+ public boolean canModify(Object element, String property) { >+ return true; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, java.lang.String) >+ */ >+ public Object getValue(Object element, String property) { >+ return ((MyModel)element).counter + ""; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object, java.lang.String, java.lang.Object) >+ */ >+ public void modify(Object element, String property, Object value) { >+ TreeItem item = (TreeItem)element; >+ ((MyModel)item.getData()).counter = Integer.parseInt(value.toString()); >+ v.update(item.getData(), null); >+ } >+ >+ }); >+ >+ v.setColumnProperties(new String[] { "column1", "column2" }); >+ v.setCellEditors(new CellEditor[] { new TextCellEditor(v.getTree()), new TextCellEditor(v.getTree()) }); >+ v.setTabEditingStyle(EditingSupport.TABING_HORIZONTAL|EditingSupport.TABING_MOVE_TO_ROW_NEIGHBOR|EditingSupport.TABING_VERTICAL); >+ >+ v.setInput(createModel()); >+ } >+ >+ private MyModel createModel() { >+ >+ MyModel root = new MyModel(0, null); >+ root.counter = 0; >+ >+ MyModel tmp; >+ MyModel subItem; >+ for (int i = 1; i < 10; i++) { >+ tmp = new MyModel(i, root); >+ root.child.add(tmp); >+ for (int j = 1; j < i; j++) { >+ subItem = new MyModel(j, tmp); >+ subItem.child.add(new MyModel(j*100,subItem)); >+ tmp.child.add(subItem); >+ } >+ } >+ >+ return root; >+ } >+ >+ public static void main(String[] args) { >+ Display display = new Display(); >+ Shell shell = new Shell(display); >+ shell.setLayout(new FillLayout()); >+ new Snippet026TreeViewerTabEditing(shell); >+ shell.open(); >+ >+ while (!shell.isDisposed()) { >+ if (!display.readAndDispatch()) >+ display.sleep(); >+ } >+ >+ display.dispose(); >+ } >+} >#P org.eclipse.jface >Index: src/org/eclipse/jface/viewers/TableViewerRow.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/TableViewerRow.java,v >retrieving revision 1.3 >diff -u -r1.3 TableViewerRow.java >--- src/org/eclipse/jface/viewers/TableViewerRow.java 5 Sep 2006 20:51:25 -0000 1.3 >+++ src/org/eclipse/jface/viewers/TableViewerRow.java 19 Dec 2006 18:28:09 -0000 >@@ -146,4 +146,39 @@ > return item.getParent(); > } > >+ public ViewerRow getNeighbor(int direction, boolean sameLevel) { >+ if( direction == ViewerRow.ABOVE ) { >+ return getRowAbove(sameLevel); >+ } else if( direction == ViewerRow.BELOW ) { >+ return getRowBelow(sameLevel); >+ } else { >+ throw new IllegalArgumentException("The given direction argument is not known!"); //$NON-NLS-1$ >+ } >+ } >+ >+ >+ private ViewerRow getRowAbove(boolean sameLevel) { >+ int index = item.getParent().indexOf(item) - 1; >+ >+ if( index >= 0 ) { >+ return (ViewerRow)item.getParent().getItem(index).getData(ViewerRow.ROWPART_KEY); >+ } >+ >+ return null; >+ } >+ >+ private ViewerRow getRowBelow(boolean sameLevel) { >+ int index = item.getParent().indexOf(item) + 1; >+ >+ if( index < item.getParent().getItemCount() ) { >+ TableItem tmp = item.getParent().getItem(index); >+ //TODO NULL can happen in case of VIRTUAL => How do we deal with that >+ if( tmp != null ) { >+ return (ViewerRow)tmp.getData(ViewerRow.ROWPART_KEY); >+ } >+ } >+ >+ return null; >+ } >+ > } >Index: src/org/eclipse/jface/viewers/EditingSupport.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/EditingSupport.java,v >retrieving revision 1.4 >diff -u -r1.4 EditingSupport.java >--- src/org/eclipse/jface/viewers/EditingSupport.java 30 Nov 2006 18:53:06 -0000 1.4 >+++ src/org/eclipse/jface/viewers/EditingSupport.java 19 Dec 2006 18:28:09 -0000 >@@ -16,8 +16,6 @@ > import org.eclipse.core.runtime.Assert; > import org.eclipse.swt.SWT; > import org.eclipse.swt.events.TraverseEvent; >-import org.eclipse.swt.graphics.Point; >-import org.eclipse.swt.graphics.Rectangle; > > /** > * EditingSupport is the abstract superclass of the support for cell editing. >@@ -184,9 +182,9 @@ > ViewerRow newRow = null; > > if (above) { >- newRow = getRowAbove(row, viewer); >+ newRow = row.getNeighbor(ViewerRow.ABOVE, false); > } else { >- newRow = getRowBelow(row, viewer); >+ newRow = row.getNeighbor(ViewerRow.BELOW,false); > } > > if (newRow != null) { >@@ -228,7 +226,7 @@ > startIndex); > } > } else if ((getTabingStyle() & TABING_MOVE_TO_ROW_NEIGHBOR) == TABING_MOVE_TO_ROW_NEIGHBOR) { >- ViewerRow rowAbove = getRowAbove(row, viewer); >+ ViewerRow rowAbove = row.getNeighbor(ViewerRow.ABOVE,false); > if (rowAbove != null) { > rv = searchPreviousCell(rowAbove, viewer, rowAbove > .getColumnCount(), startIndex); >@@ -261,7 +259,7 @@ > rv = searchNextCell(row, viewer, -1, startIndex); > } > } else if ((getTabingStyle() & TABING_MOVE_TO_ROW_NEIGHBOR) == TABING_MOVE_TO_ROW_NEIGHBOR) { >- ViewerRow rowBelow = getRowBelow(row, viewer); >+ ViewerRow rowBelow = row.getNeighbor(ViewerRow.BELOW,false); > if (rowBelow != null) { > rv = searchNextCell(rowBelow, viewer, -1, startIndex); > } >@@ -270,23 +268,6 @@ > > return rv; > } >- >- private ViewerRow getRowAbove(ViewerRow row, ColumnViewer viewer) { >- // TODO maybe there's a better solution maybe we should provide an >- // API in ViewerColumn >- // to find row above/below itself? >- Rectangle r = row.getBounds(); >- return viewer.getViewerRow(new Point(r.x, r.y - 2)); >- } >- >- private ViewerRow getRowBelow(ViewerRow row, ColumnViewer viewer) { >- // TODO maybe there's a better solution maybe we should provide an >- // API in ViewerColumn >- // to find row above/below itself? >- Rectangle r = row.getBounds(); >- return viewer.getViewerRow(new Point(r.x, >- r.y + r.height + 2)); >- } > > /** > * @return the viewer this editing support works for >Index: src/org/eclipse/jface/viewers/TreeViewerRow.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/TreeViewerRow.java,v >retrieving revision 1.3 >diff -u -r1.3 TreeViewerRow.java >--- src/org/eclipse/jface/viewers/TreeViewerRow.java 5 Sep 2006 20:51:25 -0000 1.3 >+++ src/org/eclipse/jface/viewers/TreeViewerRow.java 19 Dec 2006 18:28:09 -0000 >@@ -18,6 +18,7 @@ > import org.eclipse.swt.graphics.Rectangle; > import org.eclipse.swt.widgets.Control; > import org.eclipse.swt.widgets.Item; >+import org.eclipse.swt.widgets.Tree; > import org.eclipse.swt.widgets.TreeItem; > > /** >@@ -144,4 +145,154 @@ > public Control getControl() { > return item.getParent(); > } >+ >+ >+ public ViewerRow getNeighbor(int direction, boolean sameLevel) { >+ if( direction == ViewerRow.ABOVE ) { >+ return getRowAbove(sameLevel); >+ } else if( direction == ViewerRow.BELOW ) { >+ return getRowBelow(sameLevel); >+ } else { >+ throw new IllegalArgumentException("The given direction argument is not known!"); //$NON-NLS-1$ >+ } >+ } >+ >+ private ViewerRow getRowBelow(boolean sameLevel) { >+ Tree tree = item.getParent(); >+ >+ // This means we have top-level item >+ if( item.getParentItem() == null ) { >+ if( sameLevel || ! item.getExpanded() ) { >+ int index = tree.indexOf(item) + 1; >+ >+ if( index < tree.getItemCount() ) { >+ return (ViewerRow)tree.getItem(index).getData(ViewerRow.ROWPART_KEY); >+ } >+ } else if( item.getExpanded() && item.getItemCount() > 0 ) { >+ return (ViewerRow)item.getItem(0).getData(ViewerRow.ROWPART_KEY); >+ } >+ } else { >+ if( sameLevel || ! item.getExpanded() ) { >+ TreeItem parentItem = item.getParentItem(); >+ >+ int nextIndex = parentItem.indexOf(item) + 1; >+ int totalIndex = parentItem.getItemCount(); >+ >+ TreeItem itemAfter; >+ >+ // This would mean that it was the last item >+ if( nextIndex == totalIndex ) { >+ itemAfter = findNextItem( parentItem ); >+ } else { >+ itemAfter = parentItem.getItem(nextIndex); >+ } >+ >+ if( itemAfter != null ) { >+ return (ViewerRow) itemAfter.getData(ViewerRow.ROWPART_KEY); >+ } >+ >+ } else if( item.getExpanded() && item.getItemCount() > 0 ) { >+ return (ViewerRow)item.getItem(0).getData(ViewerRow.ROWPART_KEY); >+ } >+ } >+ >+ return null; >+ } >+ >+ private ViewerRow getRowAbove(boolean sameLevel) { >+ Tree tree = item.getParent(); >+ >+ // This means we have top-level item >+ if( item.getParentItem() == null ) { >+ int index = tree.indexOf(item) - 1; >+ TreeItem nextTopItem = null; >+ >+ if( index >= 0 ) { >+ nextTopItem = tree.getItem(index); >+ } >+ >+ if( nextTopItem != null ) { >+ if( sameLevel ) { >+ return (ViewerRow)nextTopItem.getData(ViewerRow.ROWPART_KEY); >+ } >+ >+ return (ViewerRow) findLastVisibleItem(nextTopItem).getData(ViewerRow.ROWPART_KEY); >+ } >+ } else { >+ TreeItem parentItem = item.getParentItem(); >+ int previousIndex = parentItem.indexOf(item) - 1; >+ >+ TreeItem itemBefore; >+ if( previousIndex >= 0 ) { >+ if( sameLevel ) { >+ itemBefore = parentItem.getItem(previousIndex); >+ } else { >+ itemBefore = findLowestLeave(parentItem.getItem(previousIndex)); >+ } >+ } else { >+ itemBefore = parentItem; >+ } >+ >+ if( itemBefore != null ) { >+ return (ViewerRow) itemBefore.getData(ViewerRow.ROWPART_KEY); >+ } >+ } >+ >+ return null; >+ } >+ >+ private TreeItem findLastVisibleItem(TreeItem parentItem) { >+ TreeItem rv = parentItem; >+ >+ if( rv.getExpanded() && rv.getItemCount() > 0 ) { >+ rv = findLastVisibleItem(rv.getItem(rv.getItemCount()-1)); >+ } >+ >+ return rv; >+ } >+ >+ private TreeItem findLowestLeave(TreeItem item) { >+ TreeItem rv = item; >+ >+ if( rv.getExpanded() && rv.getItemCount() > 0 ) { >+ rv = findLowestLeave(rv.getItem(rv.getItemCount()-1)); >+ } >+ >+ return rv; >+ } >+ >+ private TreeItem findNextItem(TreeItem item) { >+ TreeItem rv = null; >+ Tree tree = item.getParent(); >+ TreeItem parentItem = item.getParentItem(); >+ >+ int nextIndex; >+ int totalItems; >+ >+ if( parentItem == null ) { >+ nextIndex = tree.indexOf(item) + 1; >+ totalItems = tree.getItemCount(); >+ } else { >+ nextIndex = parentItem.indexOf(item) + 1; >+ totalItems = parentItem.getItemCount(); >+ } >+ >+ // This is once more the last item in the tree >+ // Search on >+ if( nextIndex == totalItems ) { >+ if( item.getParentItem() != null ) { >+ rv = findNextItem(item.getParentItem()); >+ } >+ } else { >+ if( parentItem == null ) { >+ rv = tree.getItem(nextIndex); >+ } else { >+ rv = parentItem.getItem(nextIndex); >+ } >+ } >+ >+ return rv; >+ } >+ >+ > } >Index: src/org/eclipse/jface/viewers/ViewerRow.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/ViewerRow.java,v >retrieving revision 1.5 >diff -u -r1.5 ViewerRow.java >--- src/org/eclipse/jface/viewers/ViewerRow.java 6 Dec 2006 15:57:04 -0000 1.5 >+++ src/org/eclipse/jface/viewers/ViewerRow.java 19 Dec 2006 18:28:09 -0000 >@@ -41,6 +41,16 @@ > public static final String ROWPART_KEY = Policy.JFACE + ".ROWPART"; //$NON-NLS-1$ > > /** >+ * the cell above the current one >+ */ >+ public static final int ABOVE = 1; >+ >+ /** >+ * the cell below the current one; >+ */ >+ public static final int BELOW = 2; >+ >+ /** > * Create a new instance of the receiver. > * > * @param item >@@ -190,12 +200,12 @@ > */ > public int getColumnIndex(Point point) { > int count = getColumnCount(); >- >+ > // If there are no columns the column-index is 0 >- if( count == 0 ) { >+ if (count == 0) { > return 0; > } >- >+ > for (int i = 0; i < count; i++) { > if (getBounds(i).contains(point)) { > return i; >@@ -226,4 +236,15 @@ > */ > public abstract Control getControl(); > >+ /** >+ * Get the neighbor of the row >+ * >+ * @param direction the direction {@link #BELOW} or {@link #ABOVE} >+ * >+ * @param sameLevel >+ * search at the samelevel >+ * @return the row above or <code>null</code> >+ */ >+ public abstract ViewerRow getNeighbor(int direction, boolean sameLevel); >+ > } >Index: src/org/eclipse/jface/viewers/ViewerCell.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/ViewerCell.java,v >retrieving revision 1.4 >diff -u -r1.4 ViewerCell.java >--- src/org/eclipse/jface/viewers/ViewerCell.java 6 Sep 2006 19:16:09 -0000 1.4 >+++ src/org/eclipse/jface/viewers/ViewerCell.java 19 Dec 2006 18:28:09 -0000 >@@ -34,6 +34,26 @@ > private ViewerRow row; > > /** >+ * The direction pointing to the row above the current cell >+ */ >+ public int ABOVE = 1; >+ >+ /** >+ * The direction pointing to the row below the current cell >+ */ >+ public int BELOW = 1 << 1; >+ >+ /** >+ * The direction pointing to the left of the current cell >+ */ >+ public int LEFT = 1 << 2; >+ >+ /** >+ * The direction pointing to the right of the current cell >+ */ >+ public int RIGHT = 1 << 3; >+ >+ /** > * Create a new instance of the receiver on the row. > * > * @param row >@@ -177,4 +197,46 @@ > public Control getControl() { > return row.getControl(); > } >+ >+ /** >+ * This method provides access to all cells who are neighbors of the >+ * current-cell by passing the appropriate coordinadate constant. You can >+ * even access cell e.g. to the upper-left of the current cell by passing a >+ * bitmask like {@link #ABOVE} | {@link #LEFT} >+ * >+ * @param directionMask >+ * the direction mask used to identify the requested cell >+ * @param sameLevel >+ * should we stay at the samelevel (this only has an effect for >+ * viewers organized as trees) >+ * @return the cell or <code>null</code> >+ */ >+ public ViewerCell getNeighbor(int directionMask, boolean sameLevel) { >+ ViewerRow row; >+ int columnIndex; >+ >+ if ((directionMask & ABOVE) == ABOVE) { >+ row = this.row.getNeighbor(ViewerRow.ABOVE, sameLevel); >+ } else if ((directionMask & BELOW) == BELOW) { >+ row = this.row.getNeighbor(ViewerRow.BELOW, sameLevel); >+ } else { >+ row = this.row; >+ } >+ >+ if (row != null) { >+ if ((directionMask & LEFT) == LEFT) { >+ columnIndex = getColumnIndex() - 1; >+ } else if ((directionMask & RIGHT) == RIGHT) { >+ columnIndex = getColumnIndex() + 1; >+ } else { >+ columnIndex = getColumnIndex(); >+ } >+ >+ if (columnIndex >= 0 && columnIndex < row.getColumnCount()) { >+ return row.getCell(columnIndex); >+ } >+ } >+ >+ return null; >+ } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 167325
:
55449
|
55916
|
56191
|
57078