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 59465 Details for
Bug 173678
[StatusHandling] Workbench ILogDialog swallows dialog title if StatusManager is installed
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]
Fix
173678.txt (text/plain), 22.37 KB, created by
Szymon Brandys
on 2007-02-21 07:58:46 EST
(
hide
)
Description:
Fix
Filename:
MIME Type:
Creator:
Szymon Brandys
Created:
2007-02-21 07:58:46 EST
Size:
22.37 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.ui.workbench >Index: Eclipse UI/org/eclipse/ui/statushandlers/StatusDialog.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/statushandlers/StatusDialog.java,v >retrieving revision 1.2 >diff -u -r1.2 StatusDialog.java >--- Eclipse UI/org/eclipse/ui/statushandlers/StatusDialog.java 6 Feb 2007 17:49:49 -0000 1.2 >+++ Eclipse UI/org/eclipse/ui/statushandlers/StatusDialog.java 21 Feb 2007 12:55:19 -0000 >@@ -10,18 +10,15 @@ > *******************************************************************************/ > package org.eclipse.ui.statushandlers; > >-import java.net.URL; > import java.util.HashMap; > import java.util.Iterator; > import java.util.Map; > >-import org.eclipse.core.runtime.jobs.Job; > import org.eclipse.jface.action.IAction; > import org.eclipse.jface.dialogs.ErrorDialog; > import org.eclipse.jface.dialogs.IDialogConstants; > import org.eclipse.jface.dialogs.MessageDialogWithToggle; > import org.eclipse.jface.preference.IPreferenceStore; >-import org.eclipse.jface.resource.ImageDescriptor; > import org.eclipse.jface.viewers.IContentProvider; > import org.eclipse.jface.viewers.ILabelProviderListener; > import org.eclipse.jface.viewers.ISelection; >@@ -43,14 +40,11 @@ > import org.eclipse.swt.widgets.Button; > import org.eclipse.swt.widgets.Composite; > import org.eclipse.swt.widgets.Control; >-import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Shell; > import org.eclipse.ui.internal.WorkbenchPlugin; >-import org.eclipse.ui.internal.progress.ProgressManager; > import org.eclipse.ui.internal.progress.ProgressManagerUtil; > import org.eclipse.ui.internal.progress.ProgressMessages; >-import org.eclipse.ui.progress.IProgressConstants; >-import org.eclipse.ui.statushandlers.StatusNotificationManager.StatusInfo; >+import org.eclipse.ui.statushandlers.StatusNotificationManager.StatusAdapterInfo; > > /** > * A dialog for displaying >@@ -71,7 +65,7 @@ > > private TableViewer statusListViewer; > >- private StatusInfo selectedStatus; >+ private StatusAdapterInfo selectedStatus; > > /** > * Create a new instance of the receiver. >@@ -83,9 +77,10 @@ > * @param displayMask > */ > public StatusDialog(Shell parentShell, String title, String msg, >- StatusInfo statusInfo, int displayMask) { >- super(parentShell, (title == null ? statusInfo.getStatus().getMessage() >- : title), msg, statusInfo.getStatus(), displayMask); >+ StatusAdapterInfo statusInfo, int displayMask) { >+ super(parentShell, (title == null ? statusInfo.getStatusAdapter() >+ .getTitle() : title), msg, statusInfo.getStatusAdapter() >+ .getStatus(), displayMask); > setShellStyle(SWT.RESIZE | SWT.MIN | getShellStyle()); > this.selectedStatus = statusInfo; > setBlockOnOpen(false); >@@ -146,7 +141,8 @@ > private void updateEnablements() { > Button details = getButton(IDialogConstants.DETAILS_ID); > if (details != null) { >- details.setEnabled(selectedStatus.getStatus().isMultiStatus() >+ details.setEnabled(selectedStatus.getStatusAdapter().getStatus() >+ .isMultiStatus() > || isMultipleStatusDialog()); > } > Button gotoButton = getButton(GOTO_ACTION_ID); >@@ -212,17 +208,17 @@ > > private IAction getGotoAction() { > >- Object extension = selectedStatus.getExtension(); >- Object property = null; >- >- if (extension != null && extension instanceof Job) { >- property = ((Job) extension) >- .getProperty(IProgressConstants.ACTION_PROPERTY); >- } >- >- if (property instanceof IAction) { >- return (IAction) property; >- } >+// Object extension = selectedStatus.getExtension(); >+// Object property = null; >+// >+// if (extension != null && extension instanceof Job) { >+// property = ((Job) extension) >+// .getProperty(IProgressConstants.ACTION_PROPERTY); >+// } >+// >+// if (property instanceof IAction) { >+// return (IAction) property; >+// } > return null; > } > >@@ -288,7 +284,7 @@ > * > * @return ErrorInfo > */ >- public StatusInfo getSelectedError() { >+ public StatusAdapterInfo getSelectedError() { > return selectedStatus; > } > >@@ -362,7 +358,7 @@ > Point newSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT); > getShell().setSize(newSize); > } >- setStatus(selectedStatus.getStatus()); >+ setStatus(selectedStatus.getStatusAdapter().getStatus()); > } > > private void initLabelProvider() { >@@ -400,47 +396,47 @@ > * int) > */ > public Image getColumnImage(Object element, int columnIndex) { >- if (element != null) { >- Object extension = ((StatusInfo) element).getExtension(); >- if (extension != null && extension instanceof Job) { >- return getIcon((Job) extension); >- } >- } >+// if (element != null) { >+// Object extension = ((StatusInfo) element).getExtension(); >+// if (extension != null && extension instanceof Job) { >+// return getIcon((Job) extension); >+// } >+// } > return null; > } > > /* > * Get the icon for the job. Code copied from NewProgressViewer > */ >- private Image getIcon(Job job) { >- if (job != null) { >- >- Object property = job >- .getProperty(IProgressConstants.ICON_PROPERTY); >- >- // If we already have an image cached, return it >- Image im = (Image) imageTable.get(property); >- if (im != null) { >- return im; >- } >- >- // Create an image from the job's icon property or family >- Display display = getShell().getDisplay(); >- if (property instanceof ImageDescriptor) { >- im = ((ImageDescriptor) property).createImage(display); >- imageTable.put(property, im); // Cache for disposal >- } else if (property instanceof URL) { >- im = ImageDescriptor.createFromURL((URL) property) >- .createImage(display); >- imageTable.put(property, im); // Cache for disposal >- } else { >- im = ProgressManager.getInstance().getIconFor(job); >- // No need to cache since the progress manager will >- } >- return im; >- } >- return null; >- } >+// private Image getIcon(Job job) { >+// if (job != null) { >+// >+// Object property = job >+// .getProperty(IProgressConstants.ICON_PROPERTY); >+// >+// // If we already have an image cached, return it >+// Image im = (Image) imageTable.get(property); >+// if (im != null) { >+// return im; >+// } >+// >+// // Create an image from the job's icon property or family >+// Display display = getShell().getDisplay(); >+// if (property instanceof ImageDescriptor) { >+// im = ((ImageDescriptor) property).createImage(display); >+// imageTable.put(property, im); // Cache for disposal >+// } else if (property instanceof URL) { >+// im = ImageDescriptor.createFromURL((URL) property) >+// .createImage(display); >+// imageTable.put(property, im); // Cache for disposal >+// } else { >+// im = ProgressManager.getInstance().getIconFor(job); >+// // No need to cache since the progress manager will >+// } >+// return im; >+// } >+// return null; >+// } > > /* > * (non-Javadoc) >@@ -449,7 +445,7 @@ > * int) > */ > public String getColumnText(Object element, int columnIndex) { >- return ((StatusInfo) element).getDisplayString(); >+ return ((StatusAdapterInfo) element).getDisplayString(); > } > > /* >@@ -480,13 +476,13 @@ > * > * @return ErrorInfo or <code>null</code>. > */ >- private StatusInfo getSingleSelection() { >+ private StatusAdapterInfo getSingleSelection() { > ISelection rawSelection = statusListViewer.getSelection(); > if (rawSelection != null > && rawSelection instanceof IStructuredSelection) { > IStructuredSelection selection = (IStructuredSelection) rawSelection; > if (selection.size() == 1) { >- return (StatusInfo) selection.getFirstElement(); >+ return (StatusAdapterInfo) selection.getFirstElement(); > } > } > return null; >@@ -519,10 +515,10 @@ > * enablements and repopulate the list. > */ > void handleSelectionChange() { >- StatusInfo newSelection = getSingleSelection(); >+ StatusAdapterInfo newSelection = getSingleSelection(); > if (newSelection != null && newSelection != selectedStatus) { > selectedStatus = newSelection; >- setStatus(selectedStatus.getStatus()); >+ setStatus(selectedStatus.getStatusAdapter().getStatus()); > updateEnablements(); > showDetailsArea(); > } >Index: Eclipse UI/org/eclipse/ui/statushandlers/StatusNotificationManager.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/statushandlers/StatusNotificationManager.java,v >retrieving revision 1.2 >diff -u -r1.2 StatusNotificationManager.java >--- Eclipse UI/org/eclipse/ui/statushandlers/StatusNotificationManager.java 6 Feb 2007 17:49:48 -0000 1.2 >+++ Eclipse UI/org/eclipse/ui/statushandlers/StatusNotificationManager.java 21 Feb 2007 12:55:19 -0000 >@@ -23,7 +23,6 @@ > import org.eclipse.core.runtime.IStatus; > import org.eclipse.core.runtime.Platform; > import org.eclipse.core.runtime.Status; >-import org.eclipse.core.runtime.jobs.Job; > import org.eclipse.jface.resource.ImageDescriptor; > import org.eclipse.jface.resource.JFaceResources; > import org.eclipse.osgi.util.NLS; >@@ -33,7 +32,6 @@ > import org.eclipse.ui.internal.WorkbenchPlugin; > import org.eclipse.ui.internal.progress.ProgressManagerUtil; > import org.eclipse.ui.internal.progress.ProgressMessages; >-import org.eclipse.ui.progress.IProgressConstants; > import org.eclipse.ui.progress.WorkbenchJob; > > import com.ibm.icu.text.DateFormat; >@@ -89,30 +87,12 @@ > /** > * Add a new error to the list for the supplied job. > * >- * @param status >+ * @param statusAdapter > */ >- void addError(IStatus status, Object extension) { >- >- // Handle out of memory errors via the workbench >- final Throwable exception = status.getException(); >- if (exception != null && exception instanceof OutOfMemoryError) { >- PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { >- //TODO change !!! possible invocation loops >- /* >- * (non-Javadoc) >- * >- * @see java.lang.Runnable#run() >- */ >- public void run() { >- // is it really needed >- //ExceptionHandler.getInstance().handleException(exception); >- } >- }); >- >- return; >- } >- StatusInfo errorInfo = new StatusInfo(status, extension); >- showError(errorInfo); >+ public void addStatusAdapter(StatusAdapter statusAdapter) { >+ StatusAdapterInfo statusAdapterInfo = new StatusAdapterInfo( >+ statusAdapter); >+ showError(statusAdapterInfo); > } > > /** >@@ -122,11 +102,12 @@ > * @param statusInfo > * the error to be displayed > */ >- private void showError(final StatusInfo statusInfo) { >+ private void showError(final StatusAdapterInfo statusAdapterInfo) { > > if (!PlatformUI.isWorkbenchRunning()) { > // we are shuttting down, so just log >- WorkbenchPlugin.log(statusInfo.getStatus()); >+ WorkbenchPlugin.log(statusAdapterInfo.getStatusAdapter() >+ .getStatus()); > return; > } > >@@ -138,18 +119,18 @@ > > // Add the error in the UI thread to ensure thread safety in the > // dialog >- errors.add(statusInfo); >+ errors.add(statusAdapterInfo); > if (dialog != null) { > dialog.refresh(); > } else if (Platform.isRunning()) { > // Delay prompting if the job property is set > Object noPromptProperty = null; >- Object extension = statusInfo.getExtension(); >+// Object extension = statusAdapterInfo.getExtension(); > >- if (extension != null && extension instanceof Job) { >- noPromptProperty = ((Job) extension) >- .getProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY); >- } >+// if (extension != null && extension instanceof Job) { >+// noPromptProperty = ((Job) extension) >+// .getProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY); >+// } > > boolean prompt = true; > if (noPromptProperty instanceof Boolean) { >@@ -158,7 +139,7 @@ > > if (prompt) { > return openErrorDialog(null /* use default title */, >- null /* use default message */, statusInfo); >+ null /* use default message */, statusAdapterInfo); > } > } > return Status.OK_STATUS; >@@ -190,7 +171,7 @@ > * @return IStatus > */ > private IStatus openErrorDialog(String title, String msg, >- final StatusInfo statusInfo) { >+ final StatusAdapterInfo statusAdapterInfo) { > IWorkbench workbench = PlatformUI.getWorkbench(); > > // Abort on shutdown >@@ -199,7 +180,7 @@ > return Status.CANCEL_STATUS; > } > dialog = new StatusDialog(ProgressManagerUtil.getDefaultParent(), >- title, msg, statusInfo, IStatus.OK | IStatus.INFO >+ title, msg, statusAdapterInfo, IStatus.OK | IStatus.INFO > | IStatus.WARNING | IStatus.ERROR); > > dialog.open(); >@@ -229,8 +210,8 @@ > Iterator errorIterator = errorsToRemove.iterator(); > Set errorStatuses = new HashSet(); > while (errorIterator.hasNext()) { >- StatusInfo next = (StatusInfo) errorIterator.next(); >- errorStatuses.add(next.getStatus()); >+ StatusAdapterInfo next = (StatusAdapterInfo) errorIterator.next(); >+ errorStatuses.add(next.getStatusAdapter().getStatus()); > } > > // TODO those classes have default access modifier :/ >@@ -258,67 +239,6 @@ > } > > /** >- * Display the error for the given job and any other errors that have been >- * accumulated. This method must be invoked from the UI thread. >- * >- * @param job >- * the job whose error should be displayed >- * @param title >- * The title for the dialog >- * @param msg >- * The message for the dialog. >- * @return <code>true</code> if the info for the job was found and the >- * error displayed and <code>false</code> otherwise. >- */ >- public boolean showErrorFor(Job job, String title, String msg) { >- if (dialog != null) { >- // The dialog is already open so the error is being displayed >- return true; >- } >- StatusInfo info = null; >- if (job == null) { >- info = getMostRecentJobError(); >- } else { >- info = getErrorInfo(job); >- } >- if (info != null) { >- openErrorDialog(title, msg, info); >- return true; >- } >- return false; >- } >- >- /* >- * Return the most recent error. >- */ >- private StatusInfo getMostRecentJobError() { >- StatusInfo mostRecentInfo = null; >- for (Iterator iter = errors.iterator(); iter.hasNext();) { >- StatusInfo info = (StatusInfo) iter.next(); >- if ((mostRecentInfo == null || info.getTimestamp() > mostRecentInfo >- .getTimestamp()) >- && info.getExtension() != null >- && info.getExtension() instanceof Job) { >- mostRecentInfo = info; >- } >- } >- return mostRecentInfo; >- } >- >- /* >- * Return the error info for the given job >- */ >- private StatusInfo getErrorInfo(Job job) { >- for (Iterator iter = errors.iterator(); iter.hasNext();) { >- StatusInfo info = (StatusInfo) iter.next(); >- if (info.getExtension() == job) { >- return info; >- } >- } >- return null; >- } >- >- /** > * Return whether the manager has errors to report. > * > * @return whether the manager has errors to report >@@ -340,45 +260,30 @@ > * A wrapper class for statuses displayed in the dialog. > * > */ >- protected static class StatusInfo implements Comparable { >+ protected static class StatusAdapterInfo implements Comparable { > >- private final IStatus status; >+ private final StatusAdapter statusAdapter; > > private final long timestamp; > >- private final Object extension; >- >- /** >- * Constructs a simple <code>StatusInfo</code>, without any >- * extensions. >- * >- * @param status >- * the root status for this status info >- */ >- public StatusInfo(IStatus status) { >- this(status, null); >- } >- > /** > * Constructs a <code>StatusInfo</code> with a extension (used to > * retrieve extra properties). > * >- * @param status >- * the root status for this status info >- * @param extension >- * the extension >+ * @param statusAdapter >+ * the root status adapter for this info > */ >- public StatusInfo(IStatus status, Object extension) { >- this.status = status; >+ public StatusAdapterInfo(StatusAdapter statusAdapter) { >+ this.statusAdapter = statusAdapter; > timestamp = System.currentTimeMillis(); >- this.extension = extension; > } > > String getDisplayString() { >- String text = status.getMessage(); >- if (this.extension != null && this.extension instanceof Job) { >- text = ((Job) extension).getName(); >- } >+ String text = statusAdapter.getStatus().getMessage(); >+ >+// if (this.extension != null && this.extension instanceof Job) { >+// text = ((Job) extension).getName(); >+// } > > return NLS.bind(ProgressMessages.JobInfo_Error, (new Object[] { > text, >@@ -401,34 +306,26 @@ > * @see java.lang.Comparable#compareTo(T) > */ > public int compareTo(Object arg0) { >- if (arg0 instanceof StatusInfo) { >- // Order ErrorInfo by time received >- long otherTimestamp = ((StatusInfo) arg0).timestamp; >+ if (arg0 instanceof StatusAdapterInfo) { >+ // Order StatusAdapterInfo by time received >+ long otherTimestamp = ((StatusAdapterInfo) arg0).timestamp; > if (timestamp < otherTimestamp) { > return -1; > } else if (timestamp > otherTimestamp) { > return 1; > } else { > return getDisplayString().compareTo( >- ((StatusInfo) arg0).getDisplayString()); >+ ((StatusAdapterInfo) arg0).getDisplayString()); > } > } > return 0; > } > > /** >- * @return Returns the status. >+ * @return Returns the status adapter. > */ >- public IStatus getStatus() { >- return status; >+ public StatusAdapter getStatusAdapter() { >+ return statusAdapter; > } >- >- /** >- * @return Returns the extension. >- */ >- public Object getExtension() { >- return extension; >- } >- > } > } >Index: Eclipse UI/org/eclipse/ui/statushandlers/StatusAdapter.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/statushandlers/StatusAdapter.java,v >retrieving revision 1.1 >diff -u -r1.1 StatusAdapter.java >--- Eclipse UI/org/eclipse/ui/statushandlers/StatusAdapter.java 5 Feb 2007 14:59:17 -0000 1.1 >+++ Eclipse UI/org/eclipse/ui/statushandlers/StatusAdapter.java 21 Feb 2007 12:55:19 -0000 >@@ -38,6 +38,8 @@ > > private IStatus status; > >+ private String title; >+ > private HashMap adapters; > > private int handlingHint; >@@ -46,11 +48,10 @@ > * Creates an instance of this class. > * > * @param status >- * the status set in the adapter >+ * the status set in the adapter, not null > */ > public StatusAdapter(IStatus status) { > this.status = status; >- adapters = new HashMap(); > } > > /** >@@ -62,6 +63,9 @@ > * the adapter instance > */ > public void addAdapter(Class adapter, Object object) { >+ if (adapters == null) { >+ adapters = new HashMap(); >+ } > adapters.put(adapter, object); > } > >@@ -71,6 +75,9 @@ > * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) > */ > public Object getAdapter(Class adapter) { >+ if (adapters == null) { >+ return null; >+ } > return adapters.get(adapter); > } > >@@ -104,4 +111,20 @@ > public void setHandlingHint(int handlingHint) { > this.handlingHint = handlingHint; > } >+ >+ /** >+ * @return Returns the title. It is the information which can be used in >+ * dialogs' title bars. >+ */ >+ public String getTitle() { >+ return title; >+ } >+ >+ /** >+ * @param title >+ * The title to set. >+ */ >+ public void setTitle(String title) { >+ this.title = title; >+ } > } >Index: Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchErrorHandler.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchErrorHandler.java,v >retrieving revision 1.3 >diff -u -r1.3 WorkbenchErrorHandler.java >--- Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchErrorHandler.java 5 Feb 2007 14:59:17 -0000 1.3 >+++ Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchErrorHandler.java 21 Feb 2007 12:55:19 -0000 >@@ -34,8 +34,8 @@ > */ > public boolean handle(final StatusAdapter statusAdapter) { > if ((statusAdapter.getHandlingHint() & StatusManager.SHOW) == StatusManager.SHOW) { >- StatusNotificationManager.getInstance().addError( >- statusAdapter.getStatus(), null); >+ StatusNotificationManager.getInstance().addStatusAdapter( >+ statusAdapter); > } > > if ((statusAdapter.getHandlingHint() & StatusManager.LOG) == StatusManager.LOG) { >Index: Eclipse UI/org/eclipse/ui/internal/JFaceUtil.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/JFaceUtil.java,v >retrieving revision 1.14 >diff -u -r1.14 JFaceUtil.java >--- Eclipse UI/org/eclipse/ui/internal/JFaceUtil.java 6 Feb 2007 17:47:54 -0000 1.14 >+++ Eclipse UI/org/eclipse/ui/internal/JFaceUtil.java 21 Feb 2007 12:55:19 -0000 >@@ -29,6 +29,7 @@ > import org.eclipse.jface.util.SafeRunnable; > import org.eclipse.jface.window.Window; > import org.eclipse.swt.widgets.Shell; >+import org.eclipse.ui.statushandlers.StatusAdapter; > import org.eclipse.ui.statushandlers.StatusManager; > > /** >@@ -89,7 +90,12 @@ > status = new Status(IStatus.ERROR, > WorkbenchPlugin.PI_WORKBENCH, message); > } >- StatusManager.getManager().handle(status, StatusManager.SHOW); >+ >+ StatusAdapter statusAdapter = new StatusAdapter(status); >+ statusAdapter.setTitle(title); >+ statusAdapter.setHandlingHint(StatusManager.SHOW); >+ >+ StatusManager.getManager().handle(statusAdapter); > return Window.OK; > } > >@@ -125,8 +131,12 @@ > if (severity == IStatus.ERROR || severity == IStatus.WARNING) { > IStatus status = new Status(severity, > WorkbenchPlugin.PI_WORKBENCH, message); >- StatusManager.getManager().handle(status, >- StatusManager.SHOW); >+ >+ StatusAdapter statusAdapter = new StatusAdapter(status); >+ statusAdapter.setTitle(title); >+ statusAdapter.setHandlingHint(StatusManager.SHOW); >+ >+ StatusManager.getManager().handle(statusAdapter); > return Window.OK; > } >
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 173678
:
58681
| 59465