diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java
index 3895aed0df5..19c8ab9ed26 100644
--- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java
+++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/AbstractReconciler.java
@@ -15,7 +15,6 @@
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
@@ -56,31 +55,27 @@ abstract public class AbstractReconciler implements IReconciler {
/**
* Background thread for the reconciling activity.
*/
- private class BackgroundThread extends Job {
+ class BackgroundWorker implements Runnable {
/** Has the reconciler been canceled. */
- private boolean fCanceled= false;
+ private boolean fCanceled;
/** Has the reconciler been reset. */
- private boolean fReset= false;
+ private boolean fReset;
/** Some changes need to be processed. */
- private boolean fIsDirty= false;
+ private boolean fIsDirty;
/** Is a reconciling strategy active. */
- private boolean fIsActive= false;
+ private boolean fIsActive;
- private volatile boolean fIsAlive;
+ private boolean fStarted;
- private boolean started;
+ private String fName;
- /**
- * Creates a new background thread. The thread
- * runs with minimal priority.
- *
- * @param name the thread's name
- */
- public BackgroundThread(String name) {
- super(name);
- setPriority(Job.DECORATE);
- setSystem(true);
+ private boolean fIsAlive;
+
+ private volatile Thread fThread;
+
+ public BackgroundWorker(String name) {
+ fName= name;
}
/**
@@ -105,7 +100,7 @@ public synchronized boolean isDirty() {
/**
* Cancels the background thread.
*/
- public void doCancel() {
+ public void cancel() {
fCanceled= true;
IProgressMonitor pm= fProgressMonitor;
if (pm != null)
@@ -160,9 +155,7 @@ public void reset() {
fDirtyRegionQueue.notifyAll();
}
}
- synchronized (this) {
- started= false;
- }
+
informNotFinished();
reconcilerReset();
}
@@ -171,79 +164,91 @@ public void reset() {
* The background activity. Waits until there is something in the
* queue managing the changes that have been applied to the text viewer.
* Removes the first change from the queue and process it.
- *
- * Calls {@link AbstractReconciler#initialProcess()} on entrance.
- *
*/
@Override
- public IStatus run(IProgressMonitor monitor) {
- fIsAlive= true;
- delay();
-
- if (fCanceled)
- return Status.CANCEL_STATUS;
-
- initialProcess();
-
- while (!fCanceled) {
-
- delay();
+ public void run() {
+ try {
+ while (!fCanceled) {
- if (fCanceled)
- break;
+ delay();
- if (!isDirty()) {
- waitFinish= false; //signalWaitForFinish() was called but nothing todo
- continue;
- }
+ if (fCanceled)
+ break;
- synchronized (this) {
- if (fReset) {
- fReset= false;
+ if (!isDirty()) {
+ waitFinish= false; //signalWaitForFinish() was called but nothing todo
continue;
}
- }
- DirtyRegion r= null;
- synchronized (fDirtyRegionQueue) {
- r= fDirtyRegionQueue.removeNextDirtyRegion();
- }
+ synchronized (this) {
+ if (fReset) {
+ fReset= false;
+ continue;
+ }
+ }
- fIsActive= true;
+ DirtyRegion r= null;
+ synchronized (fDirtyRegionQueue) {
+ r= fDirtyRegionQueue.removeNextDirtyRegion();
+ }
- fProgressMonitor.setCanceled(false);
+ fIsActive= true;
- process(r);
+ fProgressMonitor.setCanceled(false);
- synchronized (fDirtyRegionQueue) {
- if (0 == fDirtyRegionQueue.getSize()) {
- synchronized (this) {
- fIsDirty= fProgressMonitor.isCanceled();
+ process(r);
+
+ synchronized (fDirtyRegionQueue) {
+ if (fDirtyRegionQueue.isEmpty()) {
+ synchronized (this) {
+ fIsDirty= fProgressMonitor.isCanceled();
+ }
+ fDirtyRegionQueue.notifyAll();
}
- fDirtyRegionQueue.notifyAll();
}
+ fIsActive= false;
}
-
- fIsActive= false;
+ } finally {
+ fIsAlive= false;
}
- fIsAlive= false;
- return Status.OK_STATUS;
}
- public boolean isAlive() {
+ boolean isAlive() {
return fIsAlive;
}
- public synchronized void start() {
- if (!started) {
- started= true;
- schedule();
+ /**
+ * Star the reconciling if not running (and calls
+ * {@link AbstractReconciler#initialProcess()}) or {@link #reset()} otherwise.
+ */
+ public void startReconciling() {
+ if (!fStarted) {
+ fIsAlive= true;
+ fStarted= true;
+ Job.createSystem("Delayed Reconciler startup for " + fName, m -> { //$NON-NLS-1$
+ //Until we process some code from the job, the reconciler thread is the current thread
+ fThread= Thread.currentThread();
+ delay();
+ if (fCanceled) {
+ return Status.CANCEL_STATUS;
+ }
+ initialProcess();
+ if (fCanceled) {
+ return Status.CANCEL_STATUS;
+ }
+ Thread thread= new Thread(this);
+ thread.setName(fName);
+ thread.setPriority(Thread.MIN_PRIORITY);
+ thread.setDaemon(true);
+ //we will no longer process any code here, so hand over to the worker thread.
+ fThread= thread;
+ thread.start();
+ return Status.OK_STATUS;
+ }).schedule();
+ } else {
+ reset();
}
- }
- @Override
- public boolean belongsTo(Object family) {
- return family == fViewer || AbstractReconciler.class == family;
}
}
@@ -259,7 +264,7 @@ public void documentAboutToBeChanged(DocumentEvent e) {
@Override
public void documentChanged(DocumentEvent e) {
- if (fThread.isActive() || !fThread.isDirty() && fThread.isAlive()) {
+ if (fWorker.isActive() || !fWorker.isDirty() && fWorker.isAlive()) {
if (!fIsAllowedToModifyDocument && isRunningInReconcilerThread())
throw new UnsupportedOperationException("The reconciler thread is not allowed to modify the document"); //$NON-NLS-1$
aboutToBeReconciledInternal();
@@ -269,13 +274,13 @@ public void documentChanged(DocumentEvent e) {
* The second OR condition handles the case when the document
* gets changed while still inside initialProcess().
*/
- if (fThread.isActive() || fThread.isDirty() && fThread.isAlive())
+ if (fWorker.isActive() || fWorker.isDirty() && fWorker.isAlive())
fProgressMonitor.setCanceled(true);
if (fIsIncrementalReconciler)
createDirtyRegion(e);
- fThread.reset();
+ fWorker.reset();
}
@@ -291,11 +296,11 @@ public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput
synchronized (fDirtyRegionQueue) {
fDirtyRegionQueue.purgeQueue();
}
- if (fDocument != null && fDocument.getLength() > 0 && fThread.isDirty() && fThread.isAlive()) {
+ if (fDocument != null && fDocument.getLength() > 0 && fWorker.isDirty() && fWorker.isAlive()) {
DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), ""); //$NON-NLS-1$
createDirtyRegion(e);
- fThread.reset();
- fThread.suspendCallerWhileDirty();
+ fWorker.reset();
+ fWorker.suspendCallerWhileDirty();
}
}
@@ -315,7 +320,7 @@ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
fDocument.addDocumentListener(this);
- if (!fThread.isDirty())
+ if (!fWorker.isDirty())
aboutToBeReconciledInternal();
startReconciling();
@@ -325,7 +330,7 @@ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
/** Queue to manage the changes applied to the text viewer. */
private DirtyRegionQueue fDirtyRegionQueue;
/** The background thread. */
- private BackgroundThread fThread;
+ private BackgroundWorker fWorker;
/** Internal document and text input listener. */
private Listener fListener;
/** The background thread delay. */
@@ -474,9 +479,9 @@ public void install(ITextViewer textViewer) {
fViewer= textViewer;
synchronized (this) {
- if (fThread != null)
+ if (fWorker != null)
return;
- fThread= new BackgroundThread(getClass().getName());
+ fWorker= new BackgroundWorker(getClass().getName());
}
fDirtyRegionQueue= new DirtyRegionQueue();
@@ -510,9 +515,9 @@ public void uninstall() {
synchronized (this) {
// http://dev.eclipse.org/bugs/show_bug.cgi?id=19135
- BackgroundThread bt= fThread;
- fThread= null;
- bt.doCancel();
+ BackgroundWorker bt= fWorker;
+ fWorker= null;
+ bt.cancel();
}
}
}
@@ -617,10 +622,10 @@ protected void forceReconciling() {
if (fDocument != null) {
- if (!fThread.isDirty()&& fThread.isAlive())
+ if (!fWorker.isDirty()&& fWorker.isAlive())
aboutToBeReconciledInternal();
- if (fThread.isActive())
+ if (fWorker.isActive())
fProgressMonitor.setCanceled(true);
if (fIsIncrementalReconciler) {
@@ -637,14 +642,10 @@ protected void forceReconciling() {
* Clients may extend this method.
*/
protected synchronized void startReconciling() {
- if (fThread == null)
+ if (fWorker == null)
return;
- if (!fThread.isAlive()) {
- fThread.start();
- } else {
- fThread.reset();
- }
+ fWorker.startReconciling();
}
/**
@@ -661,9 +662,8 @@ protected void reconcilerReset() {
* @since 3.4
*/
protected synchronized boolean isRunningInReconcilerThread() {
- if (fThread == null) {
+ if (fWorker == null)
return false;
- }
- return Job.getJobManager().currentJob() == fThread;
+ return Thread.currentThread() == fWorker.fThread;
}
-}
\ No newline at end of file
+}
diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/DirtyRegionQueue.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/DirtyRegionQueue.java
index c342fc77627..e8a53dfd266 100644
--- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/DirtyRegionQueue.java
+++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/DirtyRegionQueue.java
@@ -85,6 +85,10 @@ public int getSize() {
return fDirtyRegions.size();
}
+ public boolean isEmpty() {
+ return fDirtyRegions.isEmpty();
+ }
+
/**
* Throws away all entries in the queue.
*/
diff --git a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF
index d3502adcfbc..13debb7c1bc 100644
--- a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jface;singleton:=true
-Bundle-Version: 3.37.100.qualifier
+Bundle-Version: 3.38.0.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.jface,
@@ -18,7 +18,7 @@ Export-Package: org.eclipse.jface,
org.eclipse.jface.fieldassist,
org.eclipse.jface.fieldassist.images,
org.eclipse.jface.images,
- org.eclipse.jface.internal;x-friends:="org.eclipse.ui.workbench,org.eclipse.e4.ui.workbench.renderers.swt",
+ org.eclipse.jface.internal;x-friends:="org.eclipse.ui.workbench,org.eclipse.e4.ui.workbench.renderers.swt,org.eclipse.jface.tests",
org.eclipse.jface.internal.provisional.action;x-friends:="org.eclipse.ui.workbench,org.eclipse.ui.ide",
org.eclipse.jface.layout,
org.eclipse.jface.menus,
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/IScopeChangeProvider.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/IScopeChangeProvider.java
new file mode 100644
index 00000000000..cfd615ca36c
--- /dev/null
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/IScopeChangeProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.dialogs;
+
+/**
+ * @since 3.38
+ *
+ */
+public interface IScopeChangeProvider {
+
+ /**
+ * Adds a listener for scope changes in this scope change provider. Has no
+ * effect if an identical listener is already registered.
+ *
+ * @param listener a scope changed listener
+ */
+ void addScopeChangedListener(IScopeChangedListener listener);
+
+ /**
+ * Removes the given scope change listener from this page change provider. Has
+ * no effect if an identical listener is not registered.
+ *
+ * @param listener a scope changed listener
+ */
+ void removeScopeChangedListener(IScopeChangedListener listener);
+
+}
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/IScopeChangedListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/IScopeChangedListener.java
new file mode 100644
index 00000000000..d6748a32ca9
--- /dev/null
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/IScopeChangedListener.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.dialogs;
+
+/**
+ * A listener which is notified when the scope for the search page is changed.
+ *
+ * @see IScopeChangeProvider
+ * @see ScopeChangedEvent
+ *
+ * @since 3.38
+ */
+public interface IScopeChangedListener {
+ /**
+ * Notifies that the selected scope has changed.
+ *
+ * @param event event object describing the change
+ */
+ void scopeChanged(ScopeChangedEvent event);
+}
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/ScopeChangedEvent.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/ScopeChangedEvent.java
new file mode 100644
index 00000000000..c4326c18cdd
--- /dev/null
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/dialogs/ScopeChangedEvent.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Red Hat Inc. - copied and modified from PageChangedEvent.java
+ *******************************************************************************/
+package org.eclipse.jface.dialogs;
+
+import java.util.EventObject;
+
+/**
+ * Event object describing a page selection change. The source of these events
+ * is a page change provider.
+ *
+ * @see IPageChangeProvider
+ * @see IPageChangedListener
+ *
+ * @since 3.38
+ */
+public class ScopeChangedEvent extends EventObject {
+
+ private static final long serialVersionUID = -2652600407410991930L;
+
+ /**
+ * The changed scope.
+ */
+ private final int scope;
+
+ /**
+ * Creates a new event for the given source and new scope.
+ *
+ * @param source the page change provider
+ * @param scope the new scope. In the JFace provided dialogs this will be an
+ * ISearchPageContainer constant.
+ */
+ public ScopeChangedEvent(IPageChangeProvider source,
+ int scope) {
+ super(source);
+ this.scope = scope;
+ }
+
+ /**
+ * Returns the new scope.
+ *
+ * @return the new scope. In dialogs implemented by JFace, this will be an
+ * ISearchPageContainer constant.
+ */
+ public int getScope() {
+ return scope;
+ }
+
+ /**
+ * Returns the scope change provider that is the source of this event.
+ *
+ * @return the originating scope change provider
+ */
+ public IScopeChangeProvider getPageChangeProvider() {
+ return (IScopeChangeProvider) getSource();
+ }
+}
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java
index 5b0368be105..646ca5cb90f 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java
@@ -19,12 +19,11 @@
import java.io.BufferedInputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -246,24 +245,16 @@ private static String getxPath(String name, int zoom) {
*
* @return {@link String} or null if the file cannot be found
*/
- private static String getFilePath(URL url, boolean logIOException) {
+ private static String getFilePath(URL url, boolean logException) {
try {
if (!InternalPolicy.OSGI_AVAILABLE) {
- if (FILE_PROTOCOL.equalsIgnoreCase(url.getProtocol()))
- return IPath.fromOSString(url.getFile()).toOSString();
- return null;
+ return getFilePath(url);
}
url = resolvePathVariables(url);
URL locatedURL = FileLocator.toFileURL(url);
- if (FILE_PROTOCOL.equalsIgnoreCase(locatedURL.getProtocol())) {
- String filePath = IPath.fromOSString(locatedURL.getPath()).toOSString();
- if (Files.exists(Path.of(filePath))) {
- return filePath;
- }
- }
- return null;
+ return getFilePath(locatedURL);
} catch (IOException e) {
- if (logIOException) {
+ if (logException) {
Policy.logException(e);
} else if (InternalPolicy.DEBUG_LOG_URL_IMAGE_DESCRIPTOR_MISSING_2x) {
String path = url.getPath();
@@ -275,6 +266,16 @@ private static String getFilePath(URL url, boolean logIOException) {
}
}
+ private static String getFilePath(URL url) {
+ if (FILE_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
+ File file = IPath.fromOSString(url.getPath()).toFile();
+ if (file.exists()) {
+ return file.getPath();
+ }
+ }
+ return null;
+ }
+
private static URL resolvePathVariables(URL url) {
URL platformURL = FileLocator.find(url); // Resolve variables within URL's path
if (platformURL != null) {
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/util/Util.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/util/Util.java
index 86f6c008c25..55d49b689e9 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/util/Util.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/util/Util.java
@@ -560,7 +560,7 @@ public static boolean isWindows() {
*/
public static boolean isMac() {
final String ws = SWT.getPlatform();
- return WS_CARBON.equals(ws) || WS_COCOA.equals(ws);
+ return WS_COCOA.equals(ws);
}
/**
diff --git a/bundles/org.eclipse.search/META-INF/MANIFEST.MF b/bundles/org.eclipse.search/META-INF/MANIFEST.MF
index fcfd9d845d8..001a2b22bfb 100644
--- a/bundles/org.eclipse.search/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.search/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.search; singleton:=true
-Bundle-Version: 3.17.200.qualifier
+Bundle-Version: 3.17.300.qualifier
Bundle-Activator: org.eclipse.search.internal.ui.SearchPlugin
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %providerName
diff --git a/bundles/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDialog.java b/bundles/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDialog.java
index f00afb61d4b..3d2b82912dd 100644
--- a/bundles/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDialog.java
+++ b/bundles/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDialog.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -60,7 +60,10 @@
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.IPageChangeProvider;
import org.eclipse.jface.dialogs.IPageChangedListener;
+import org.eclipse.jface.dialogs.IScopeChangeProvider;
+import org.eclipse.jface.dialogs.IScopeChangedListener;
import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.jface.dialogs.ScopeChangedEvent;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.SafeRunnable;
@@ -91,7 +94,8 @@
import org.eclipse.search.ui.ISearchPageScoreComputer;
-public class SearchDialog extends ExtendedDialogWindow implements ISearchPageContainer, IPageChangeProvider {
+public class SearchDialog extends ExtendedDialogWindow
+ implements ISearchPageContainer, IPageChangeProvider, IScopeChangeProvider {
// Dialog store id constants
private static final String DIALOG_NAME= "SearchDialog"; //$NON-NLS-1$
@@ -150,6 +154,7 @@ protected void layout(Composite composite, boolean flushCache) {
private Button fCustomizeButton;
private Button fReplaceButton;
private ListenerList fPageChangeListeners;
+ private ListenerList fScopeChangeListeners;
private final IWorkbenchWindow fWorkbenchWindow;
private final ISelection fCurrentSelection;
@@ -706,6 +711,13 @@ public void setPerformActionEnabled(boolean state) {
*/
public void notifyScopeSelectionChanged() {
setPerformActionEnabled(fLastEnableState);
+ if (fScopeChangeListeners != null && !fScopeChangeListeners.isEmpty()) {
+ // Fires the scope change event
+ final ScopeChangedEvent event = new ScopeChangedEvent(this, getSelectedScope());
+ for (IScopeChangedListener l : fScopeChangeListeners) {
+ SafeRunner.run(() -> l.scopeChanged(event));
+ }
+ }
}
private Control createPageControl(Composite parent, final SearchPageDescriptor descriptor) {
@@ -828,4 +840,19 @@ public void run() {
}
}
}
+
+ @Override
+ public void addScopeChangedListener(IScopeChangedListener listener) {
+ if (fScopeChangeListeners == null) {
+ fScopeChangeListeners = new ListenerList<>();
+ }
+ fScopeChangeListeners.add(listener);
+ }
+
+ @Override
+ public void removeScopeChangedListener(IScopeChangedListener listener) {
+ if (fScopeChangeListeners != null) {
+ fScopeChangeListeners.remove(listener);
+ }
+ }
}
diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControl.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControl.java
index ce44dfc2504..5d0d04beb2a 100644
--- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControl.java
+++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControl.java
@@ -236,7 +236,8 @@ private void styleStickyLines() {
List stickyLinesStyleRanges= new ArrayList<>();
int stickyLineTextOffset= 0;
- for (int i= 0; i < getNumberStickyLines(); i++) {
+ int stickyLinesCount = getNumberStickyLines();
+ for (int i = 0; i < stickyLinesCount; i++) {
IStickyLine stickyLine= stickyLines.get(i);
StyleRange[] ranges= stickyLine.getStyleRanges();
if (ranges != null) {
diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/StickyLine.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/StickyLine.java
index 6d0ebdbf4e7..fa00944998b 100644
--- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/StickyLine.java
+++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/StickyLine.java
@@ -47,7 +47,11 @@ public int getLineNumber() {
public String getText() {
if (text == null) {
StyledText textWidget = sourceViewer.getTextWidget();
- text = textWidget.getLine(getWidgetLineNumber());
+ int widgetLineNumber = getWidgetLineNumber();
+ if (widgetLineNumber < 0 || widgetLineNumber >= textWidget.getLineCount()) {
+ return ""; // return empty string if line number is invalid //$NON-NLS-1$
+ }
+ text = textWidget.getLine(widgetLineNumber);
}
return text;
}
@@ -57,16 +61,19 @@ public StyleRange[] getStyleRanges() {
StyledText textWidget = sourceViewer.getTextWidget();
int widgetLineNumber = getWidgetLineNumber();
- if (widgetLineNumber >= textWidget.getLineCount()) {
+ if (widgetLineNumber < 0 || widgetLineNumber >= textWidget.getLineCount()) {
return null;
}
-
- int offsetAtLine = textWidget.getOffsetAtLine(getWidgetLineNumber());
- StyleRange[] styleRanges = textWidget.getStyleRanges(offsetAtLine, getText().length());
- for (StyleRange styleRange : styleRanges) {
- styleRange.start = styleRange.start - offsetAtLine;
+ try {
+ int offsetAtLine = textWidget.getOffsetAtLine(widgetLineNumber);
+ StyleRange[] styleRanges = textWidget.getStyleRanges(offsetAtLine, getText().length());
+ for (StyleRange styleRange : styleRanges) {
+ styleRange.start = styleRange.start - offsetAtLine;
+ }
+ return styleRanges;
+ } catch (IllegalArgumentException e) {
+ return null; // in case of an invalid line number, return null
}
- return styleRanges;
}
private int getWidgetLineNumber() {
diff --git a/bundles/org.eclipse.ui.forms/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.forms/META-INF/MANIFEST.MF
index 0f0fa404973..49b3629e275 100644
--- a/bundles/org.eclipse.ui.forms/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.ui.forms/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %name
Bundle-SymbolicName: org.eclipse.ui.forms;singleton:=true
-Bundle-Version: 3.13.500.qualifier
+Bundle-Version: 3.13.600.qualifier
Bundle-Vendor: %provider-name
Bundle-Localization: plugin
Export-Package: org.eclipse.ui.forms,
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/FormText.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/FormText.java
index 154344d859b..0e2bde803f5 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/FormText.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/FormText.java
@@ -1554,7 +1554,15 @@ private void paint(PaintEvent e) {
ensureBoldFontPresent(getFont());
gc.setForeground(getForeground());
gc.setBackground(getBackground());
- repaint(gc, e.x, e.y, e.width, e.height);
+ Point size = getSize();
+ Rectangle paintBounds;
+ if (size.x == 0 && size.y == 0) {
+ // avoids crash on image creation with (0,0) image size
+ paintBounds = new Rectangle(e.x, e.y, e.width, e.height);
+ } else {
+ paintBounds = new Rectangle(0, 0, size.x, size.y);
+ }
+ repaint(gc, paintBounds.x, paintBounds.y, paintBounds.width, paintBounds.height);
}
private void repaint(GC gc, int x, int y, int width, int height) {
diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/e4/compatibility/CompatibilityEditor.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/e4/compatibility/CompatibilityEditor.java
index b46d072e9b4..bc22035b669 100644
--- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/e4/compatibility/CompatibilityEditor.java
+++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/e4/compatibility/CompatibilityEditor.java
@@ -59,9 +59,11 @@ public class CompatibilityEditor extends CompatibilityPart {
@Override
IWorkbenchPart createPart(WorkbenchPartReference reference) throws PartInitException {
IWorkbenchPart part = super.createPart(reference);
- IEditorInput input = ((EditorReference) reference).getEditorInput();
- if (input instanceof MultiEditorInput && part instanceof MultiEditor) {
- createMultiEditorChildren(part, input);
+ if (part instanceof MultiEditor) {
+ IEditorInput input = ((EditorReference) reference).getEditorInput();
+ if (input instanceof MultiEditorInput) {
+ createMultiEditorChildren(part, input);
+ }
}
return part;
}
diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/keys/BindingPersistence.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/keys/BindingPersistence.java
index f7afca45bcb..55675dcbbd1 100644
--- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/keys/BindingPersistence.java
+++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/keys/BindingPersistence.java
@@ -519,7 +519,7 @@ private static final void readBindingsFromPreferences(final IMemento preferences
* @param commandService The command service for the workbench; must
* not be null.
*/
- @SuppressWarnings("removal")
+ // @SuppressWarnings("removal")
private static final void readBindingsFromRegistry(final IConfigurationElement[] configurationElements,
final int configurationElementCount, final BindingManager bindingManager,
final CommandManager commandService) {
@@ -608,12 +608,6 @@ private static final void readBindingsFromRegistry(final IConfigurationElement[]
if (Util.WS_COCOA.equals(platform)) {
cocoaTempList.add(binding);
- } else if (Util.WS_CARBON.equals(platform)) {
- bindings.add(binding);
- // temp work around ... simply honour the carbon
- // bindings for cocoa.
- cocoaTempList.add(new KeyBinding(keySequence, parameterizedCommand, schemeId, contextId, locale,
- Util.WS_COCOA, null, Binding.SYSTEM));
} else {
bindings.add(binding);
}
diff --git a/releng/org.eclipse.ui.releng/platformUiTools.p2f b/releng/org.eclipse.ui.releng/platformUiTools.p2f
index c64d35de192..1a637cd75f0 100644
--- a/releng/org.eclipse.ui.releng/platformUiTools.p2f
+++ b/releng/org.eclipse.ui.releng/platformUiTools.p2f
@@ -129,7 +129,7 @@
-
+
diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/jface/tests/internal/databinding/swt/Screenshots.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/jface/tests/internal/databinding/swt/Screenshots.java
index d08947505a9..90ebb6b7f48 100644
--- a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/jface/tests/internal/databinding/swt/Screenshots.java
+++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/jface/tests/internal/databinding/swt/Screenshots.java
@@ -89,7 +89,7 @@ public static String takeScreenshot(Class> testClass, String name, PrintStream
GC gc = new GC(display);
Rectangle displayBounds= display.getBounds();
out.println("Display @ " + displayBounds);
- final Image image = new Image(display, displayBounds.width, displayBounds.height);
+ final Image image = new Image(display, (iGc, width, height) -> {}, displayBounds.width, displayBounds.height);
gc.copyArea(image, 0, 0);
gc.dispose();
diff --git a/tests/org.eclipse.jface.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.jface.tests/META-INF/MANIFEST.MF
index 15d33aa01f3..fffe968e1e8 100644
--- a/tests/org.eclipse.jface.tests/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.jface.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.jface.tests
-Bundle-Version: 1.4.900.qualifier
+Bundle-Version: 1.4.1000.qualifier
Automatic-Module-Name: org.eclipse.jface.tests
Bundle-RequiredExecutionEnvironment: JavaSE-17
Require-Bundle: org.junit;bundle-version="4.12.0",
diff --git a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/images/UrlImageDescriptorTest.java b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/images/UrlImageDescriptorTest.java
index c86db5d3a34..ead4939cca0 100644
--- a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/images/UrlImageDescriptorTest.java
+++ b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/images/UrlImageDescriptorTest.java
@@ -21,11 +21,13 @@
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
+import java.io.File;
import java.io.IOException;
import java.net.URL;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.internal.InternalPolicy;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
@@ -122,20 +124,52 @@ public void testImageFileNameProviderGetxName() {
@Test
public void testImageFileNameProviderGetxName_forFileURL() throws IOException {
- URL imageFileURL = tempFolder.newFile("image.png").toURI().toURL();
- tempFolder.newFile("image@2x.png");
+ testImageFileNameProviderGetxName_forFileURL(true);
+ }
+
+ @Test
+ public void testImageFileNameProviderGetxName_forFileURL_noOSGi() throws IOException {
+ testImageFileNameProviderGetxName_forFileURL(false);
+ }
+
+ private void testImageFileNameProviderGetxName_forFileURL(boolean osgiAvailable) throws IOException {
+ boolean oldOsgiAvailable = InternalPolicy.OSGI_AVAILABLE;
+ InternalPolicy.OSGI_AVAILABLE = osgiAvailable;
+ try {
+ URL imageFileURL = tempFolder.newFile("image.png").toURI().toURL();
+ tempFolder.newFile("image@2x.png");
+ ImageDescriptor descriptor = ImageDescriptor.createFromURL(imageFileURL);
+
+ ImageFileNameProvider fileNameProvider = Adapters.adapt(descriptor, ImageFileNameProvider.class);
+ assertNotNull("URLImageDescriptor does not adapt to ImageFileNameProvider", fileNameProvider);
+ String imagePath100 = fileNameProvider.getImagePath(100);
+ assertNotNull("URLImageDescriptor ImageFileNameProvider does not return the 100% path", imagePath100);
+ assertEquals(IPath.fromOSString(imagePath100).lastSegment(), "image.png");
+ String imagePath200 = fileNameProvider.getImagePath(200);
+ assertNotNull("URLImageDescriptor ImageFileNameProvider does not return the @2x path", imagePath200);
+ assertEquals(IPath.fromOSString(imagePath200).lastSegment(), "image@2x.png");
+ String imagePath150 = fileNameProvider.getImagePath(150);
+ assertNull("URLImageDescriptor's ImageFileNameProvider does return a @1.5x path", imagePath150);
+ } finally {
+ InternalPolicy.OSGI_AVAILABLE = oldOsgiAvailable;
+ }
+ }
+
+ @Test
+ public void testImageFileNameProviderGetxName_forFileURL_WhiteSpace() throws IOException {
+ File imageFolder = tempFolder.newFolder("folder with spaces");
+ File imageFile = new File(imageFolder, "image with spaces.png");
+ imageFile.createNewFile();
+
+ // This is an invalid URL because the whitespace characters are not properly encoded
+ URL imageFileURL = new URL("file", null, imageFile.getPath());
ImageDescriptor descriptor = ImageDescriptor.createFromURL(imageFileURL);
ImageFileNameProvider fileNameProvider = Adapters.adapt(descriptor, ImageFileNameProvider.class);
assertNotNull("URLImageDescriptor does not adapt to ImageFileNameProvider", fileNameProvider);
+
String imagePath100 = fileNameProvider.getImagePath(100);
assertNotNull("URLImageDescriptor ImageFileNameProvider does not return the 100% path", imagePath100);
- assertEquals(IPath.fromOSString(imagePath100).lastSegment(), "image.png");
- String imagePath200 = fileNameProvider.getImagePath(200);
- assertNotNull("URLImageDescriptor ImageFileNameProvider does not return the @2x path", imagePath200);
- assertEquals(IPath.fromOSString(imagePath200).lastSegment(), "image@2x.png");
- String imagePath150 = fileNameProvider.getImagePath(150);
- assertNull("URLImageDescriptor's ImageFileNameProvider does return a @1.5x path", imagePath150);
}
@Test
diff --git a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/labelProviders/LabelProviderTest.java b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/labelProviders/LabelProviderTest.java
index dc2e74db1e1..49b6ce965b9 100644
--- a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/labelProviders/LabelProviderTest.java
+++ b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/labelProviders/LabelProviderTest.java
@@ -15,8 +15,8 @@ public class LabelProviderTest {
private static final Car HORCH = new Car("Horch");
- private static Image horchImage = new Image(Display.getDefault(), 50, 10);
- private static Image defaultImage = new Image(Display.getDefault(), 1, 1);
+ private static Image horchImage = new Image(Display.getDefault(), (gc, width, height) -> {}, 50, 10);
+ private static Image defaultImage = new Image(Display.getDefault(), (gc, width, height) -> {}, 1, 1);
private final Function