# HG changeset patch
# User Frank Benoit
+ * See also ParameterizedCommand.escape(String)
+ *
+ * Note: This supports bridging actions to the command framework,
+ * and should not be used outside the framework.
+ *
+ * Note: This supports bridging actions to the command framework,
+ * and should not be used outside the framework.
+ *
+ * Note: This supports bridging actions to the command framework,
+ * and should not be used outside the framework.
+ *
+ * Note: This supports bridging actions to the command framework,
+ * and should not be used outside the framework.
+ *
+ * Note: This supports bridging actions to the command framework,
+ * and should not be used outside the framework.
+ * true
+ * @see #setEnabled(Object)
+ * @see #setBaseEnabled(bool)
*/
public bool isEnabled() {
- return true;
+ return baseEnabled;
+ }
+
+ /**
+ * Allow the default {@link #isEnabled()} to answer our enabled state. It
+ * will fire a HandlerEvent if necessary. If clients use this method they
+ * should also consider overriding {@link #setEnabled(Object)} so they can
+ * be notified about framework execution contexts.
+ *
+ * @param state
+ * the enabled state
+ * @since 3.4
+ */
+ protected void setBaseEnabled(bool state) {
+ if (baseEnabled is state) {
+ return;
+ }
+ baseEnabled = state;
+ fireHandlerChanged(new HandlerEvent(this, true, false));
+ }
+
+ /**
+ * Called by the framework to allow the handler to update its enabled state
+ * by extracting the same information available at execution time. Clients
+ * may override if they need to extract information from the application
+ * context.
+ *
+ * @param evaluationContext
+ * the application context. May be null
+ * @since 3.4
+ * @see #setBaseEnabled(bool)
+ */
+ public void setEnabled(Object evaluationContext) {
}
/**
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/commands/Command.d
--- a/dwtx/core/commands/Command.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/commands/Command.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * Copyright (c) 2004, 2008 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
@@ -499,6 +499,7 @@
// Perform the execution, if there is a handler.
if ((handler !is null) && (handler.isHandled())) {
+ setEnabled(event.getApplicationContext());
if (!isEnabled()) {
NotEnabledException exception = new NotEnabledException(
"Trying to execute the disabled command " ~ getId()); //$NON-NLS-1$
@@ -735,7 +736,7 @@
/**
* Returns the help context identifier associated with this command. This
* method should not be called by clients. Clients should use
- * {@link CommandManager#getHelpContextId(String)} instead.
+ * {@link CommandManager#getHelpContextId(Command)} instead.
*
* @return The help context identifier for this command; may be
* null
if there is none.
@@ -862,6 +863,21 @@
return handler.isEnabled();
}
+
+ /**
+ * Called be the framework to allow the handler to update its enabled state.
+ *
+ * @param evaluationContext
+ * the state to evaluate against. May be null
+ * which indicates that the handler can query whatever model that
+ * is necessary. This context must not be cached.
+ * @since 3.4
+ */
+ public void setEnabled(Object evaluationContext) {
+ if (handler instanceof IHandler2) {
+ ((IHandler2) handler).setEnabled(evaluationContext);
+ }
+ }
/**
* Returns whether this command has a handler, and whether this handler is
@@ -1004,7 +1020,7 @@
}
/**
- * @return
+ * @return the handler listener
*/
private IHandlerListener getHandlerListener() {
if (handlerListener is null) {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/commands/CommandManager.d
--- a/dwtx/core/commands/CommandManager.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/commands/CommandManager.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 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
@@ -206,11 +206,14 @@
/**
* Unescapes special characters in the command id, parameter ids and
- * parameter values for {@link #deserialize()}. The special characters
+ * parameter values for {@link #deserialize(String)}. The special characters
* {@link #PARAMETER_START_CHAR}, {@link #PARAMETER_END_CHAR},
* {@link #ID_VALUE_CHAR}, {@link #PARAMETER_SEPARATOR_CHAR} and
* {@link #ESCAPE_CHAR} are escaped by prepending an {@link #ESCAPE_CHAR}
* character.
+ * String
that may contain escaped special
@@ -220,7 +223,6 @@
* @throws SerializationException
* if escapedText
contains an invalid escape
* sequence
- * @see ParameterizedCommand#escape(String)
* @since 3.2
*/
private static final String unescape(String escapedText) {
@@ -296,7 +298,7 @@
* events from commands controlled by this manager to listeners on this
* manager.
*/
- private IExecutionListener executionListener = null;
+ private IExecutionListenerWithChecks executionListener = null;
/**
* The collection of execution listeners. This collection is
@@ -729,8 +731,6 @@
* array of parameters of the command being deserialized; may be
* null
.
* @return an array of parameterizations; may be null
.
- * @throws NotDefinedException
- * if the command is not defined
* @throws SerializationException
* if there is an error deserializing the parameters
* @since 3.2
@@ -987,4 +987,109 @@
return pos;
}
+ /**
+ * Fires the notEnabled
event for
+ * executionListeners
.
+ * null
.
+ * @param exception
+ * The exception, never null
.
+ * @since 3.4
+ */
+ public void fireNotEnabled(String commandId, NotEnabledException exception) {
+ if (executionListener !is null) {
+ executionListener.notEnabled(commandId, exception);
+ }
+ }
+
+ /**
+ * Fires the notDefined
event for
+ * executionListeners
.
+ * null
.
+ * @param exception
+ * The exception, never null
.
+ * @since 3.4
+ */
+ public void fireNotDefined(String commandId, NotDefinedException exception) {
+ if (executionListener !is null) {
+ executionListener.notDefined(commandId, exception);
+ }
+ }
+
+ /**
+ * Fires the preExecute
event for
+ * executionListeners
.
+ * null
.
+ * @param event
+ * The event that triggered the command, may be null
.
+ * @since 3.4
+ */
+ public void firePreExecute(String commandId, ExecutionEvent event) {
+ if (executionListener !is null) {
+ executionListener.preExecute(commandId, event);
+ }
+ }
+
+ /**
+ * Fires the postExecuteSuccess
event for
+ * executionListeners
.
+ * null
.
+ * @param returnValue
+ * The value returned from the command, may be null
.
+ * @since 3.4
+ */
+ public void firePostExecuteSuccess(String commandId, Object returnValue) {
+ if (executionListener !is null) {
+ executionListener.postExecuteSuccess(commandId, returnValue);
+ }
+ }
+
+ /**
+ * Fires the postExecuteFailure
event for
+ * executionListeners
.
+ * null
.
+ * @param exception
+ * The exception, never null
.
+ * @since 3.4
+ */
+ public void firePostExecuteFailure(String commandId,
+ ExecutionException exception) {
+ if (executionListener !is null) {
+ executionListener.postExecuteFailure(commandId, exception);
+ }
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/commands/IHandler.d
--- a/dwtx/core/commands/IHandler.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/commands/IHandler.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * Copyright (c) 2004, 2008 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
@@ -15,7 +15,6 @@
import dwtx.core.commands.IHandlerListener;
import dwtx.core.commands.ExecutionEvent;
-
/**
* A handler is the pluggable piece of a command that handles execution. Each
* command can have zero or more handlers associated with it (in general), of
@@ -61,10 +60,13 @@
/**
* Returns whether this handler is capable of executing at this moment in
- * time.
+ * time. If the enabled state is other than true clients should also
+ * consider implementing IHandler2 so they can be notified about framework
+ * execution contexts.
*
* @return true
if the command is enabled; false
* otherwise.
+ * @see IHandler2#setEnabled(Object)
*/
public bool isEnabled();
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/commands/IHandler2.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/core/commands/IHandler2.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * Port to the D programming language:
+ * Frank Benoit null
+ * which indicates that the handler can query whatever model that
+ * is necessary. This context must not be cached.
+ */
+ public void setEnabled(Object evaluationContext);
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/commands/ParameterizedCommand.d
--- a/dwtx/core/commands/ParameterizedCommand.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/commands/ParameterizedCommand.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Benjamin Muskalla - bug 222861 [Commands] ParameterizedCommand#equals broken
* Port to the D programming language:
* Frank Benoit String
representing rawText
with
* special serialization characters escaped
- * @see CommandManager#unescape(String)
* @since 3.2
*/
private static final String escape(String rawText) {
@@ -318,6 +318,69 @@
}
/**
+ * Take a command and a map of parameter IDs to values, and generate the
+ * appropriate parameterized command.
+ *
+ * @param command
+ * The command object. Must not be null
.
+ * @param parameters
+ * A map of String parameter ids to objects. May be
+ * null
.
+ * @return the parameterized command, or null
if it could not
+ * be generated
+ * @since 3.4
+ */
+ public static final ParameterizedCommand generateCommand(Command command,
+ Map parameters) {
+ // no parameters
+ if (parameters is null || parameters.isEmpty()) {
+ return new ParameterizedCommand(command, null);
+ }
+
+ try {
+ ArrayList parms = new ArrayList();
+ Iterator i = parameters.keySet().iterator();
+
+ // iterate over given parameters
+ while (i.hasNext()) {
+ String key = (String) i.next();
+ IParameter parameter = null;
+ // get the parameter from the command
+ parameter = command.getParameter(key);
+
+ // if the parameter is defined add it to the parameter list
+ if (parameter is null) {
+ return null;
+ }
+ ParameterType parameterType = command.getParameterType(key);
+ if (parameterType is null) {
+ parms.add(new Parameterization(parameter,
+ (String) parameters.get(key)));
+ } else {
+ AbstractParameterValueConverter valueConverter = parameterType
+ .getValueConverter();
+ if (valueConverter !is null) {
+ String val = valueConverter.convertToString(parameters
+ .get(key));
+ parms.add(new Parameterization(parameter, val));
+ } else {
+ parms.add(new Parameterization(parameter,
+ (String) parameters.get(key)));
+ }
+ }
+ }
+
+ // convert the parameters to an Parameterization array and create
+ // the command
+ return new ParameterizedCommand(command, (Parameterization[]) parms
+ .toArray(new Parameterization[parms.size()]));
+ } catch (NotDefinedException e) {
+ } catch (ParameterValueConversionException e) {
+ }
+ return null;
+ }
+
+ /**
* The base command which is being parameterized. This value is never
* null
.
*/
@@ -346,10 +409,7 @@
* null
.
* @param parameterizations
* An array of parameterizations binding parameters to values for
- * the command. This value may be null
. This
- * argument is not copied; if you need to make changes to it
- * after constructing this parameterized command, then make a
- * copy yourself.
+ * the command. This value may be null
.
*/
public this(Command command,
Parameterization[] parameterizations) {
@@ -359,8 +419,27 @@
}
this.command = command;
- this.parameterizations = (parameterizations is null || parameterizations.length is 0) ? null
- : parameterizations;
+ IParameter[] parms = null;
+ try {
+ parms = command.getParameters();
+ } catch (NotDefinedException e) {
+ // This should not happen.
+ }
+ if (parameterizations !is null && parameterizations.length>0 && parms !is null) {
+ int parmIndex = 0;
+ Parameterization[] params = new Parameterization[parameterizations.length];
+ for (int j = 0; j < parms.length; j++) {
+ for (int i = 0; i < parameterizations.length; i++) {
+ Parameterization pm = parameterizations[i];
+ if (parms[j].equals(pm.getParameter())) {
+ params[parmIndex++] = pm;
+ }
+ }
+ }
+ this.parameterizations = params;
+ } else {
+ this.parameterizations = null;
+ }
}
/*
@@ -548,7 +627,9 @@
return parameterMap;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see java.lang.Object#hashCode()
*/
public override final hash_t toHash() {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/commands/common/CommandException.d
--- a/dwtx/core/commands/common/CommandException.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/commands/common/CommandException.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 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
@@ -21,10 +21,18 @@
*
null
.
*/
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/commands/common/IIdentifiable.d
--- a/dwtx/core/commands/common/IIdentifiable.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/commands/common/IIdentifiable.d Thu May 22 01:36:46 2008 +0200
@@ -1,1 +1,32 @@
-/*******************************************************************************
* 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
* Port to the D programming language:
* Frank Benoit * An object that is unique identifiable based on the combination of its class * and its identifier. *
* * @see HandleObject * @since 3.2 */ public interface IIdentifiable { /** * Returns the identifier for this object. * * @return The identifier; nevernull
.
*/
String getId();
}
\ No newline at end of file
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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
+ * Port to the D programming language:
+ * Frank Benoit + * An object that is unique identifiable based on the combination of its class + * and its identifier. + *
+ * + * @see HandleObject + * @since 3.2 + */ +public interface IIdentifiable { + + /** + * Returns the identifier for this object. + * + * @return The identifier; nevernull
.
+ */
+ String getId();
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/commands/common/NamedHandleObjectComparator.d
--- a/dwtx/core/commands/common/NamedHandleObjectComparator.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/commands/common/NamedHandleObjectComparator.d Thu May 22 01:36:46 2008 +0200
@@ -1,1 +1,61 @@
-/*******************************************************************************
* 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
* Port to the D programming language:
* Frank Benoit NamedHandleObject
for display to
* an end user. The comparison is based on the name of the instances.
*
* @since 3.2
*/
public class NamedHandleObjectComparator /+: Comparator+/ {
/**
* Compares to instances of NamedHandleObject based on their names. This is
* useful is they are display to an end user.
*
* @param left
* The first obect to compare; may be null
.
* @param right
* The second object to compare; may be null
.
* @return -1
if left
is null
* and right
is not null
;
* 0
if they are both null
;
* 1
if left
is not null
* and right
is null
. Otherwise, the
* result of left.compareTo(right)
.
*/
public final int compare(Object left, Object right) {
NamedHandleObject a = cast(NamedHandleObject) left;
NamedHandleObject b = cast(NamedHandleObject) right;
String aName = null;
try {
aName = a.getName();
} catch (NotDefinedException e) {
// Leave aName as null.
}
String bName = null;
try {
bName = b.getName();
} catch (NotDefinedException e) {
// Leave bName as null.
}
return Util.compare(aName, bName);
}
}
\ No newline at end of file
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ * Port to the D programming language:
+ * Frank Benoit NamedHandleObject
for display to
+ * an end user. The comparison is based on the name of the instances.
+ *
+ * @since 3.2
+ */
+public class NamedHandleObjectComparator /+: Comparator+/ {
+
+ /**
+ * Compares to instances of NamedHandleObject based on their names. This is
+ * useful is they are display to an end user.
+ *
+ * @param left
+ * The first obect to compare; may be null
.
+ * @param right
+ * The second object to compare; may be null
.
+ * @return -1
if left
is null
+ * and right
is not null
;
+ * 0
if they are both null
;
+ * 1
if left
is not null
+ * and right
is null
. Otherwise, the
+ * result of left.compareTo(right)
.
+ */
+ public final int compare(Object left, Object right) {
+ NamedHandleObject a = cast(NamedHandleObject) left;
+ NamedHandleObject b = cast(NamedHandleObject) right;
+
+ String aName = null;
+ try {
+ aName = a.getName();
+ } catch (NotDefinedException e) {
+ // Leave aName as null.
+ }
+ String bName = null;
+ try {
+ bName = b.getName();
+ } catch (NotDefinedException e) {
+ // Leave bName as null.
+ }
+
+ return Util.compare(aName, bName);
+ }
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/commands/operations/AbstractOperation.d
--- a/dwtx/core/commands/operations/AbstractOperation.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/commands/operations/AbstractOperation.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -51,9 +51,11 @@
* Construct an operation that has the specified label.
*
* @param label
- * the label to be used for the operation.
+ * the label to be used for the operation. Should never be
+ * null
.
*/
public this(String label) {
+ Assert.isNotNull(label);
this.label = label;
contexts = new ArraySeq!(IUndoContext);
}
@@ -143,7 +145,8 @@
* Set the label of the operation to the specified name.
*
* @param name
- * the string to be used for the label.
+ * the string to be used for the label. Should never be
+ * null
.
*/
public void setLabel(String name) {
label = name;
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/commands/operations/IUndoableOperation.d
--- a/dwtx/core/commands/operations/IUndoableOperation.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/commands/operations/IUndoableOperation.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -158,9 +158,9 @@
/**
* Return the label that should be used to show the name of the operation to
* the user. This label is typically combined with the command strings shown
- * to the user in "Undo" and "Redo" user interfaces.
+ * to the user in "Undo" and "Redo" user interfaces.
*
- * @return the label
+ * @return the String label. Should never be null
.
*/
String getLabel();
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/internal/runtime/LocalizationUtils.d
--- a/dwtx/core/internal/runtime/LocalizationUtils.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/internal/runtime/LocalizationUtils.d Thu May 22 01:36:46 2008 +0200
@@ -25,9 +25,9 @@
* use the NLS-based translation routine. If it falls, the method returns the original
* non-translated key.
*
- * @param key case-sensetive name of the filed in the translation file representing
+ * @param key case-sensitive name of the filed in the translation file representing
* the string to be translated
- * @return
+ * @return The localized message or the non-translated key
*/
static public String safeLocalize(String key) {
//TODO: LocalizationUtils tries to load module CommonMessages. How to handle this?
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/internal/runtime/PrintStackUtil.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/core/internal/runtime/PrintStackUtil.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * Port to the D programming language:
+ * Frank Benoit @@ -23,8 +22,6 @@ *
* Clients may implement this interface. *
- * @see ILog#addLogListener(ILogListener) - * @see Platform#addLogListener(ILogListener) */ public interface ILogListener : EventListener { /** diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/runtime/IPath.d --- a/dwtx/core/runtime/IPath.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/core/runtime/IPath.d Thu May 22 01:36:46 2008 +0200 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2006 IBM Corporation and others. + * Copyright (c) 2000, 2008 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 @@ -40,6 +40,8 @@ * This interface is not intended to be implemented by clients. * * @see Path + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. */ public interface IPath : Cloneable { @@ -248,7 +250,7 @@ * When the platform location is a file system with no meaningful device * separator, the entire string is treated as the path proper. * The device id is not checked for validity; the path proper is correct - * if each of the segments in its canonicalized form is valid. + * if each of the segments in its canonicalized form is valid. * * @param path the path to check * @returntrue
if the given string is a valid path,
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/runtime/IProgressMonitorWithBlocking.d
--- a/dwtx/core/runtime/IProgressMonitorWithBlocking.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/runtime/IProgressMonitorWithBlocking.d Thu May 22 01:36:46 2008 +0200
@@ -53,7 +53,6 @@
* reason why this operation is blocked, or null
if this
* information is not available.
* @see #clearBlocked()
- * @see dwtx.core.runtime.jobs.IJobStatus
*/
public void setBlocked(IStatus reason);
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/runtime/ISafeRunnable.d
--- a/dwtx/core/runtime/ISafeRunnable.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/runtime/ISafeRunnable.d Thu May 22 01:36:46 2008 +0200
@@ -14,7 +14,6 @@
// import dwt.internal.Platform;
import dwt.dwthelper.utils;
-
/**
* Safe runnables represent blocks of code and associated exception
* handlers. They are typically used when a plug-in needs to call some
@@ -25,7 +24,7 @@
* * Clients may implement this interface. *
- * @see Platform#run(ISafeRunnable) + * @see SafeRunner#run(ISafeRunnable) */ public interface ISafeRunnable { /** @@ -37,7 +36,7 @@ * * @param exception an exception which occurred during processing * the body of this runnable (i.e., inrun()
)
- * @see Platform#run(ISafeRunnable)
+ * @see SafeRunner#run(ISafeRunnable)
*/
public void handleException(Exception exception);
@@ -48,7 +47,7 @@
*
* @exception Exception if a problem occurred while running this method.
* The exception will be processed by handleException
- * @see Platform#run(ISafeRunnable)
+ * @see SafeRunner#run(ISafeRunnable)
*/
public void run();
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/runtime/OperationCanceledException.d
--- a/dwtx/core/runtime/OperationCanceledException.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/runtime/OperationCanceledException.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -23,6 +23,7 @@
* This class is not intended to be subclassed by clients but
* may be instantiated.
*
+ * @noextend This class is not intended to be subclassed by clients.
*/
public final class OperationCanceledException : RuntimeException {
/**
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/runtime/Path.d
--- a/dwtx/core/runtime/Path.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/runtime/Path.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -38,6 +38,7 @@
* may be instantiated.
*
* @see IPath
+ * @noextend This class is not intended to be subclassed by clients.
*/
public class Path : IPath, Cloneable {
/** masks for separator values */
@@ -59,7 +60,6 @@
/** Mask for all bits that are involved in the hash code */
private static const int HASH_MASK = ~HAS_TRAILING;
-
/** Constant root path string ("/"
). */
private static const String ROOT_STRING = "/"; //$NON-NLS-1$
@@ -120,7 +120,7 @@
* @since 3.1
*/
public static IPath fromPortableString(String pathString) {
- int firstMatch = pathString.indexOf(DEVICE_SEPARATOR) +1;
+ int firstMatch = pathString.indexOf(DEVICE_SEPARATOR) + 1;
//no extra work required if no device characters
if (firstMatch <= 0)
return (new Path()).initialize(null, pathString);
@@ -507,6 +507,7 @@
}
return newSegments;
}
+
/**
* Returns the platform-neutral encoding of the given segment onto
* the given string buffer. This escapes literal colon characters with double colons.
@@ -947,7 +948,7 @@
encodeSegment(segments_[i], result);
else
result.append(segments_[i]);
- if (i < len-1 || (separators & HAS_TRAILING) !is 0)
+ if (i < len - 1 || (separators & HAS_TRAILING) !is 0)
result.append(SEPARATOR);
}
return result.toString();
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/runtime/QualifiedName.d
--- a/dwtx/core/runtime/QualifiedName.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/core/runtime/QualifiedName.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -27,6 +27,7 @@
* * This class is not intended to be subclassed by clients. *
+ * @noextend This class is not intended to be subclassed by clients. */ public final class QualifiedName { diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/core/runtime/SubMonitor.d --- a/dwtx/core/runtime/SubMonitor.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/core/runtime/SubMonitor.d Thu May 22 01:36:46 2008 +0200 @@ -9,6 +9,7 @@ * Stefan Xenos - initial API and implementation * Stefan Xenos - bug 174539 - add a 1-argument convert(...) method * Stefan Xenos - bug 174040 - SubMonitor#convert doesn't always set task name + * Stefan Xenos - bug 206942 - updated javadoc to recommend better constants for infinite progress * Port to the D programming language: * Frank Benoit* void doSomething(IProgressMonitor monitor, LinkedListNode node) { - * SubMonitor progress = SubMonitor.convert(monitor, 100); + * SubMonitor progress = SubMonitor.convert(monitor); * * while (node !is null) { * // Regardless of the amount of progress reported so far, - * // use 5% of the space remaining in the monitor to process the next node. - * progress.setWorkRemaining(100); + * // use 0.01% of the space remaining in the monitor to process the next node. + * progress.setWorkRemaining(10000); * - * doWorkOnElement(node, progress.newChild(5)); + * doWorkOnElement(node, progress.newChild(1)); * * node = node.next; * } @@ -570,6 +571,8 @@ * @see dwtx.core.runtime.IProgressMonitor#internalWorked(double) */ public void internalWorked(double work) { + cleanupActiveChild(); + int delta = consume((work > 0.0) ? work : 0.0); if (delta !is 0) root.worked(delta); diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/Action.d --- a/dwtx/jface/action/Action.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/jface/action/Action.d Thu May 22 01:36:46 2008 +0200 @@ -272,7 +272,7 @@ /** * Holds the action's menu creator (an IMenuCreator) or checked state (a - * bool for toggle button, or an Integer for radio button), or + * Boolean for toggle button, or an Integer for radio button), or *null
if neither have been set. ** The value of this field affects the value of
getStyle()
. @@ -495,9 +495,9 @@ * @since 3.0 */ public final void notifyResult(bool success) { - // avoid bool.valueOf(bool) to allow compilation against JCL + // avoid Boolean.valueOf(bool) to allow compilation against JCL // Foundation (bug 80059) - firePropertyChange(RESULT, null, new ValueWrapperBool(success)); + firePropertyChange(RESULT, null, success ? Boolean.TRUE : Boolean.FALSE); } /** @@ -559,9 +559,9 @@ if (newValue !is value) { value = newValue; if (checked) { - firePropertyChange(CHECKED, new ValueWrapperBool(false), new ValueWrapperBool(true)); + firePropertyChange(CHECKED, Boolean.FALSE, Boolean.TRUE); } else { - firePropertyChange(CHECKED, new ValueWrapperBool(true), new ValueWrapperBool(false)); + firePropertyChange(CHECKED, Boolean.TRUE, Boolean.FALSE); } } } @@ -597,8 +597,10 @@ */ public void setEnabled(bool enabled) { if (enabled !is this.enabled) { + Boolean oldVal = this.enabled ? Boolean.TRUE : Boolean.FALSE; + Boolean newVal = enabled ? Boolean.TRUE : Boolean.FALSE; this.enabled = enabled; - firePropertyChange(ENABLED, new ValueWrapperBool(this.enabled), new ValueWrapperBool(enabled)); + firePropertyChange(ENABLED, oldVal, newVal); } } diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/ActionContributionItem.d --- a/dwtx/jface/action/ActionContributionItem.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/jface/action/ActionContributionItem.d Thu May 22 01:36:46 2008 +0200 @@ -22,7 +22,6 @@ import dwt.DWT; import dwt.graphics.GC; import dwt.graphics.Point; -import dwt.graphics.Rectangle; import dwt.widgets.Button; import dwt.widgets.Composite; import dwt.widgets.Display; @@ -35,6 +34,8 @@ import dwt.widgets.ToolItem; import dwt.widgets.Widget; import dwtx.jface.action.ExternalActionManager; +import dwtx.core.commands.ExecutionException; +import dwtx.core.commands.NotEnabledException; import dwtx.jface.bindings.Trigger; import dwtx.jface.bindings.TriggerSequence; import dwtx.jface.bindings.keys.IKeyLookup; @@ -61,11 +62,11 @@ */ public class ActionContributionItem : ContributionItem { alias ContributionItem.fill fill; - + /** - * Mode bit: Show text on tool items, even if an image is present. If this - * mode bit is not set, text is only shown on tool items if there is no - * image present. + * Mode bit: Show text on tool items or buttons, even if an image is + * present. If this mode bit is not set, text is only shown on tool items if + * there is no image present. * * @since 3.0 */ @@ -74,6 +75,11 @@ /** a string inserted in the middle of text that has been shortened */ private static const String ellipsis = "..."; //$NON-NLS-1$ + /** + * Stores the result of the action. False when the action returned failure. + */ + private Boolean result = null; + private static bool USE_COLOR_ICONS = true; /** @@ -144,6 +150,8 @@ */ private Widget widget = null; + private Listener menuCreatorListener; + /** * Creates a new contribution item from the given action. The id of the * action is used as the id of the item. @@ -262,7 +270,6 @@ */ public override void fill(Menu parent, int index) { if (widget is null && parent !is null) { - Menu subMenu = null; int flags = DWT.PUSH; if (action !is null) { int style = action.getStyle(); @@ -271,11 +278,7 @@ } else if (style is IAction.AS_RADIO_BUTTON) { flags = DWT.RADIO; } else if (style is IAction.AS_DROP_DOWN_MENU) { - IMenuCreator mc = action.getMenuCreator(); - if (mc !is null) { - subMenu = mc.getMenu(parent); - flags = DWT.CASCADE; - } + flags = DWT.CASCADE; } } @@ -294,7 +297,12 @@ mi.addHelpListener(action.getHelpListener()); } - if (subMenu !is null) { + if (flags is DWT.CASCADE) { + // just create a proxy for now, if the user shows it then + // fill it in + Menu subMenu = new Menu(parent); + subMenu.addListener(DWT.Show, getMenuCreatorListener()); + subMenu.addListener(DWT.Hide, getMenuCreatorListener()); mi.setMenu(subMenu); } @@ -477,7 +485,8 @@ // Check if our widget is the one being disposed. if (e.widget is widget) { // Dispose of the menu creator. - if (action.getStyle() is IAction.AS_DROP_DOWN_MENU) { + if (action.getStyle() is IAction.AS_DROP_DOWN_MENU + && menuCreatorCalled) { IMenuCreator mc = action.getMenuCreator(); if (mc !is null) { mc.dispose(); @@ -525,6 +534,7 @@ if (e.detail is 4) { // on drop-down button if (action.getStyle() is IAction.AS_DROP_DOWN_MENU) { IMenuCreator mc = action.getMenuCreator(); + menuCreatorCalled = true; ToolItem ti = cast(ToolItem) item; // we create the menu as a sub-menu of "dummy" so that // we can use @@ -538,11 +548,11 @@ Menu m = mc.getMenu(ti.getParent()); if (m !is null) { // position the menu below the drop down item - Rectangle b = ti.getBounds(); - Point p = ti.getParent().toDisplay( - new Point(b.x, b.y + b.height)); - m.setLocation(p.x, p.y); // waiting for DWT - // 0.42 + Point point = ti.getParent().toDisplay( + new Point(e.x, e.y)); + m.setLocation(point.x, point.y); // waiting + // for DWT + // 0.42 m.setVisible(true); return; // we don't fire the action } @@ -551,6 +561,16 @@ } } + ExternalActionManager.IExecuteCallback callback = null; + String actionDefinitionId = action.getActionDefinitionId(); + if (actionDefinitionId !is null) { + Object obj = ExternalActionManager.getInstance() + .getCallback(); + if (obj instanceof ExternalActionManager.IExecuteCallback) { + callback = (ExternalActionManager.IExecuteCallback) obj; + } + } + // Ensure action is enabled first. // See 1GAN3M6: ITPUI:WINNT - Any IAction in the workbench can be // executed while disabled. @@ -561,13 +581,49 @@ if (trace) { ms = System.currentTimeMillis(); Stdout.formatln("Running action: {}", action.getText()); //$NON-NLS-1$ + } + + IPropertyChangeListener resultListener = null; + if (callback !is null) { + resultListener = new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + // Check on result + if (event.getProperty().equals(IAction.RESULT)) { + if (event.getNewValue() instanceof Boolean) { + result = (Boolean) event.getNewValue(); + } + } + } + }; + action.addPropertyChangeListener(resultListener); + callback.preExecute(action, e); } action.runWithEvent(e); + if (callback !is null) { + if (result is null || result.equals(Boolean.TRUE)) { + callback.postExecuteSuccess(action, Boolean.TRUE); + } else { + callback.postExecuteFailure(action, + new ExecutionException(action.getText() + + " returned failure.")); //$NON-NLS-1$ + } + } + + if (resultListener!isnull) { + result = null; + action.removePropertyChangeListener(resultListener); + } if (trace) { Stdout.formatln("{} ms to run action: {}",(System.currentTimeMillis() - ms), action.getText()); //$NON-NLS-1$ } + } else { + if (callback !is null) { + callback.notEnabled(action, new NotEnabledException(action + .getText() + + " is not enabled.")); //$NON-NLS-1$ + } } } } @@ -753,9 +809,12 @@ ExternalActionManager.ICallback callback = ExternalActionManager .getInstance().getCallback(); String commandId = action.getActionDefinitionId(); - if ((callback !is null) && (commandId !is null) && (toolTip !is null)) { - String acceleratorText = callback.getAcceleratorText(commandId); - if (acceleratorText !is null && acceleratorText.length !is 0) { + if ((callback !is null) && (commandId !is null) + && (toolTip !is null)) { + String acceleratorText = callback + .getAcceleratorText(commandId); + if (acceleratorText !is null + && acceleratorText.length !is 0) { toolTip = JFaceResources.format( "Toolbar_Tooltip_Accelerator", //$NON-NLS-1$ [ toolTip, acceleratorText ]); @@ -872,10 +931,14 @@ } if (text !is null && acceleratorText is null) { - // use extracted accelerator text in case accelerator cannot be fully represented in one int (e.g. multi-stroke keys) - acceleratorText = LegacyActionTools.extractAcceleratorText(text); + // use extracted accelerator text in case accelerator + // cannot be fully represented in one int (e.g. + // multi-stroke keys) + acceleratorText = LegacyActionTools + .extractAcceleratorText(text); if (acceleratorText is null && accelerator !is 0) { - acceleratorText= Action.convertAccelerator(accelerator); + acceleratorText = Action + .convertAccelerator(accelerator); } } @@ -919,19 +982,19 @@ if (cast(Button)widget ) { Button button = cast(Button) widget; - if (imageChanged && updateImages(false)) { - textChanged = false; // don't update text if it has an - // image + if (imageChanged) { + updateImages(false); } if (textChanged) { String text = action.getText(); - if (text is null) { - text = ""; //$NON-NLS-1$ - } else { + bool showText = text !is null && ((getMode() & MODE_FORCE_TEXT) !is 0 || !hasImages(action)); + // only do the trimming if the text will be used + if (showText) { text = Action.removeAcceleratorText(text); } - button.setText(text); + String textToSet = showText ? text : ""; //$NON-NLS-1$ + button.setText(textToSet); } if (tooltipTextChanged) { @@ -1134,4 +1197,187 @@ // If for some reason we fall through abort return textValue; } + + /* + * (non-Javadoc) + * + * @see dwtx.jface.action.ContributionItem#dispose() + */ + public void dispose() { + if (widget !is null) { + widget.dispose(); + widget = null; + } + holdMenu = null; + } + + /** + * Handle show and hide on the proxy menu for IAction.AS_DROP_DOWN_MENU + * actions. + * + * @return the appropriate listener + * @since 3.4 + */ + private Listener getMenuCreatorListener() { + if (menuCreatorListener is null) { + menuCreatorListener = new Listener() { + public void handleEvent(Event event) { + switch (event.type) { + case DWT.Show: + handleShowProxy((Menu) event.widget); + break; + case DWT.Hide: + handleHideProxy((Menu) event.widget); + break; + } + } + }; + } + return menuCreatorListener; + } + + /** + * This is the easiest way to hold the menu until we can swap it in to the + * proxy. + */ + private Menu holdMenu = null; + + private bool menuCreatorCalled = false; + + /** + * The proxy menu is being shown, we better get the real menu. + * + * @param proxy + * the proxy menu + * @since 3.4 + */ + private void handleShowProxy(Menu proxy) { + proxy.removeListener(DWT.Show, getMenuCreatorListener()); + IMenuCreator mc = action.getMenuCreator(); + menuCreatorCalled = true; + if (mc is null) { + return; + } + holdMenu = mc.getMenu(proxy.getParentMenu()); + if (holdMenu is null) { + return; + } + copyMenu(holdMenu, proxy); + } + + /** + * Create MenuItems in the proxy menu that can execute the real menu items + * if selected. Create proxy menus for any real item submenus. + * + * @param realMenu + * the real menu to copy from + * @param proxy + * the proxy menu to populate + * @since 3.4 + */ + private void copyMenu(Menu realMenu, Menu proxy) { + if (realMenu.isDisposed() || proxy.isDisposed()) { + return; + } + + // we notify the real menu so it can populate itself if it was + // listening for DWT.Show + realMenu.notifyListeners(DWT.Show, null); + + final Listener passThrough = new Listener() { + public void handleEvent(Event event) { + if (!event.widget.isDisposed()) { + Widget realItem = (Widget) event.widget.getData(); + if (!realItem.isDisposed()) { + int style = event.widget.getStyle(); + if (event.type is DWT.Selection + && ((style & (DWT.TOGGLE | DWT.CHECK)) !is 0) + && realItem instanceof MenuItem) { + ((MenuItem) realItem) + .setSelection(((MenuItem) event.widget) + .getSelection()); + } + event.widget = realItem; + realItem.notifyListeners(event.type, event); + } + } + } + }; + + MenuItem[] items = realMenu.getItems(); + for (int i = 0; i < items.length; i++) { + final MenuItem realItem = items[i]; + final MenuItem proxyItem = new MenuItem(proxy, realItem.getStyle()); + proxyItem.setData(realItem); + proxyItem.setAccelerator(realItem.getAccelerator()); + proxyItem.setEnabled(realItem.getEnabled()); + proxyItem.setImage(realItem.getImage()); + proxyItem.setSelection(realItem.getSelection()); + proxyItem.setText(realItem.getText()); + + // pass through any events + proxyItem.addListener(DWT.Selection, passThrough); + proxyItem.addListener(DWT.Arm, passThrough); + proxyItem.addListener(DWT.Help, passThrough); + + final Menu itemMenu = realItem.getMenu(); + if (itemMenu !is null) { + // create a proxy for any sub menu items + final Menu subMenu = new Menu(proxy); + subMenu.setData(itemMenu); + proxyItem.setMenu(subMenu); + subMenu.addListener(DWT.Show, new Listener() { + public void handleEvent(Event event) { + event.widget.removeListener(DWT.Show, this); + if (event.type is DWT.Show) { + copyMenu(itemMenu, subMenu); + } + } + }); + subMenu.addListener(DWT.Help, passThrough); + subMenu.addListener(DWT.Hide, passThrough); + } + } + } + + /** + * The proxy menu is being hidden, so we need to make it go away. + * + * @param proxy + * the proxy menu + * @since 3.4 + */ + private void handleHideProxy(final Menu proxy) { + proxy.removeListener(DWT.Hide, getMenuCreatorListener()); + proxy.getDisplay().asyncExec(new Runnable() { + public void run() { + if (!proxy.isDisposed()) { + MenuItem parentItem = proxy.getParentItem(); + proxy.dispose(); + parentItem.setMenu(holdMenu); + } + if (holdMenu !is null && !holdMenu.isDisposed()) { + holdMenu.notifyListeners(DWT.Hide, null); + } + holdMenu = null; + } + }); + } + + /** + * Return the widget associated with this contribution item. It should not + * be cached, as it can be disposed and re-created by its containing + * ContributionManager, which controls all of the widgets lifecycle methods. + *+ * This can be used to set layout data on the widget if appropriate. The + * actual type of the widget can be any valid control for this + * ContributionItem's current ContributionManager. + *
+ * + * @return the widget, ornull
depending on the lifecycle. + * @since 3.4 + */ + public Widget getWidget() { + return widget; + } } diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/ContributionItem.d --- a/dwtx/jface/action/ContributionItem.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/jface/action/ContributionItem.d Thu May 22 01:36:46 2008 +0200 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2005 IBM Corporation and others. + * Copyright (c) 2000, 2008 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 @@ -215,4 +215,16 @@ */ public void update(String id) { } + + /** + * The ID for this contribution item. It should be set once either in the + * constructor or using this method. + * + * @param itemId + * @since 3.4 + * @see #getId() + */ + public void setId(String itemId) { + id = itemId; + } } diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/ContributionManager.d --- a/dwtx/jface/action/ContributionManager.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/jface/action/ContributionManager.d Thu May 22 01:36:46 2008 +0200 @@ -22,6 +22,7 @@ import tango.util.collection.ArraySeq; import tango.util.collection.model.Seq; +import dwtx.core.runtime.Assert; import dwtx.jface.util.Policy; import dwt.dwthelper.utils; @@ -85,6 +86,7 @@ * (non-Javadoc) Method declared on IContributionManager. */ public void add(IAction action) { + Assert.isNotNull(action, "Action must not be null"); //$NON-NLS-1$ add(new ActionContributionItem(action)); } @@ -92,6 +94,7 @@ * (non-Javadoc) Method declared on IContributionManager. */ public void add(IContributionItem item) { + Assert.isNotNull(item, "Item must not be null"); //$NON-NLS-1$ if (allowItem(item)) { contributions.append(item); itemAdded(item); @@ -240,7 +243,7 @@ public IContributionManagerOverrides getOverrides() { if (overrides is null) { overrides = new class IContributionManagerOverrides { - public ValueWrapperBool getEnabled(IContributionItem item) { + public Boolean getEnabled(IContributionItem item) { return null; } diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/CoolBarManager.d --- a/dwtx/jface/action/CoolBarManager.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/jface/action/CoolBarManager.d Thu May 22 01:36:46 2008 +0200 @@ -308,17 +308,17 @@ */ public void dispose() { if (coolBarExist()) { - IContributionItem[] items = getItems(); - for (int i = 0; i < items.length; i++) { - // Disposes of the contribution item. - // If Contribution Item is a toolbar then it will dispose of - // all the nested - // contribution items. - items[i].dispose(); - } coolBar.dispose(); coolBar = null; } + IContributionItem[] items = getItems(); + for (int i = 0; i < items.length; i++) { + // Disposes of the contribution item. + // If Contribution Item is a toolbar then it will dispose of + // all the nested + // contribution items. + items[i].dispose(); + } // If a context menu existed then dispose of it. if (contextMenuManager !is null) { contextMenuManager.dispose(); diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/ExternalActionManager.d --- a/dwtx/jface/action/ExternalActionManager.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/jface/action/ExternalActionManager.d Thu May 22 01:36:46 2008 +0200 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2006 IBM Corporation and others. + * Copyright (c) 2000, 2007 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 @@ -20,12 +20,18 @@ import tango.util.collection.model.Map; import tango.util.collection.model.Set; +import dwt.widgets.Event; import dwtx.core.commands.Command; import dwtx.core.commands.CommandEvent; import dwtx.core.commands.CommandManager; +import dwtx.core.commands.ExecutionEvent; +import dwtx.core.commands.ExecutionException; import dwtx.core.commands.ICommandListener; +import dwtx.core.commands.NotEnabledException; import dwtx.core.commands.ParameterizedCommand; +import dwtx.core.commands.common.NotDefinedException; import dwtx.core.runtime.IStatus; +import dwtx.core.runtime.ListenerList; import dwtx.core.runtime.Status; import dwtx.jface.bindings.BindingManager; import dwtx.jface.bindings.BindingManagerEvent; @@ -71,11 +77,14 @@ * A simple implementation of theICallback
mechanism that * simply takes aBindingManager
and a *CommandManager
. + *+ * Note: this class is not intended to be subclassed by clients. + *
* * @since 3.1 */ - public static final class CommandCallback : - IBindingManagerListener, IBindingManagerCallback { + public static class CommandCallback : + IBindingManagerListener, IBindingManagerCallback, IExecuteCallback { /** * The internationalization bundle for text produced by this class. @@ -86,6 +95,11 @@ * The callback capable of responding to whether a command is active. */ private const IActiveChecker activeChecker; + + /** + * Check the applicability of firing an execution event for an action. + */ + private final IExecuteApplicable applicabilityChecker; /** * The binding manager for your application. Must not be @@ -116,7 +130,8 @@ /** * The list of listeners that have registered for property change * notification. This is a map of command identifiers (String
) - * to listeners (IPropertyChangeListener
). + * to listeners (IPropertyChangeListener
or + *ListenerList
ofIPropertyChangeListener
). */ private const Map!(String,IPropertyChangeListener) registeredListeners; @@ -144,9 +159,12 @@ return true; } + }, new IExecuteApplicable() { + public bool isApplicable(IAction action) { + return true; + } }); } - /** * Constructs a new instance ofCommandCallback
with the * workbench it should be using. @@ -166,6 +184,36 @@ public this(BindingManager bindingManager, CommandManager commandManager, IActiveChecker activeChecker) { + this(bindingManager, commandManager, activeChecker, + new IExecuteApplicable() { + public bool isApplicable(IAction action) { + return true; + } + }); + } + /** + * Constructs a new instance ofCommandCallback
with the + * workbench it should be using. + * + * @param bindingManager + * The binding manager which will provide the callback; must + * not benull
. + * @param commandManager + * The command manager which will provide the callback; must + * not benull
. + * @param activeChecker + * The callback mechanism for checking whether a command is + * active; must not benull
. + * @param checker + * The callback to check if an IAction should fire execution + * events. + * + * @since 3.4 + */ + public CommandCallback(final BindingManager bindingManager, + final CommandManager commandManager, + final IActiveChecker activeChecker, + final IExecuteApplicable checker) { loggedCommandIds = new HashSet!(String); registeredListeners = new HashMap!(String,IPropertyChangeListener); if (bindingManager is null) { @@ -182,10 +230,15 @@ throw new NullPointerException( "The callback needs an active callback"); //$NON-NLS-1$ } + if (checker is null) { + throw new NullPointerException( + "The callback needs an applicable callback"); //$NON-NLS-1$ + } this.activeChecker = activeChecker; this.bindingManager = bindingManager; this.commandManager = commandManager; + this.applicabilityChecker = checker; } /** @@ -194,7 +247,16 @@ */ public final void addPropertyChangeListener(String commandId, IPropertyChangeListener listener) { - registeredListeners.add(commandId, listener); + Object existing = registeredListeners.get(commandId); + if (existing instanceof ListenerList) { + ((ListenerList) existing).add(listener); + } else if (existing !is null) { + ListenerList listeners = new ListenerList(ListenerList.IDENTITY); + listeners.add(existing); + listeners.add(listener); + } else { + registeredListeners.put(commandId, listener); + } if (!bindingManagerListenerAttached) { bindingManager.addBindingManagerListener(this); bindingManagerListenerAttached = true; @@ -213,9 +275,19 @@ ParameterizedCommand parameterizedCommand = new ParameterizedCommand( command, null); if (event.isActiveBindingsChangedFor(parameterizedCommand)) { - IPropertyChangeListener listener = cast(IPropertyChangeListener) v; - listener.propertyChange(new PropertyChangeEvent(event - .getManager(), IAction.TEXT, null, null)); + Object value = entry.getValue(); + PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(event + .getManager(), IAction.TEXT, null, null); + if (value instanceof ListenerList) { + Object[] listeners= ((ListenerList) value).getListeners(); + for (int i = 0; i < listeners.length; i++) { + final IPropertyChangeListener listener = (IPropertyChangeListener) listeners[i]; + listener.propertyChange(propertyChangeEvent); + } + } else { + final IPropertyChangeListener listener = (IPropertyChangeListener) value; + listener.propertyChange(propertyChangeEvent); + } } } } @@ -343,16 +415,71 @@ */ public final void removePropertyChangeListener(String commandId, IPropertyChangeListener listener) { - IPropertyChangeListener existingListener = cast(IPropertyChangeListener) registeredListeners - .get(commandId); - if (existingListener is listener) { + Object existing= registeredListeners.get(commandId); + if (existing is listener) { registeredListeners.removeKey(commandId); if (registeredListeners.drained()) { bindingManager.removeBindingManagerListener(this); bindingManagerListenerAttached = false; } + } else if (existing instanceof ListenerList) { + ListenerList existingList = (ListenerList) existing; + existingList.remove(listener); + if (existingList.size() is 1) { + registeredListeners.put(commandId, existingList.getListeners()[0]); + } } } + + public void preExecute(IAction action, Event event) { + String actionDefinitionId = action.getActionDefinitionId(); + if (actionDefinitionIdisnull + || !applicabilityChecker.isApplicable(action)) { + return; + } + Command command = commandManager.getCommand(actionDefinitionId); + ExecutionEvent executionEvent = new ExecutionEvent(command, + Collections.EMPTY_MAP, event, null); + + commandManager.firePreExecute(actionDefinitionId, executionEvent); + } + + public void postExecuteSuccess(IAction action, Object returnValue) { + String actionDefinitionId = action.getActionDefinitionId(); + if (actionDefinitionIdisnull + || !applicabilityChecker.isApplicable(action)) { + return; + } + commandManager.firePostExecuteSuccess(actionDefinitionId, returnValue); + } + + public void postExecuteFailure(IAction action, + ExecutionException exception) { + String actionDefinitionId = action.getActionDefinitionId(); + if (actionDefinitionIdisnull + || !applicabilityChecker.isApplicable(action)) { + return; + } + commandManager.firePostExecuteFailure(actionDefinitionId, exception); + } + + public void notDefined(IAction action, NotDefinedException exception) { + String actionDefinitionId = action.getActionDefinitionId(); + if (actionDefinitionIdisnull + || !applicabilityChecker.isApplicable(action)) { + return; + } + commandManager.fireNotDefined(actionDefinitionId, exception); + } + + public void notEnabled(IAction action, NotEnabledException exception) { + String actionDefinitionId = action.getActionDefinitionId(); + if (actionDefinitionIdisnull + || !applicabilityChecker.isApplicable(action)) { + return; + } + commandManager.fireNotEnabled(actionDefinitionId, exception); + } } /** @@ -406,6 +533,102 @@ */ public TriggerSequence[] getActiveBindingsFor(String commandId); } + + /** + * An overridable mechanism to filter certain IActions from the execution + * bridge. + * + * @since 3.4 + */ + public static interface IExecuteApplicable { + /** + * Allow the callback to filter out actions that should not fire + * execution events. + * + * @param action + * The action with an actionDefinitionId + * @return true if this action should be considered. + */ + public bool isApplicable(IAction action); + } + + /** + *+ * A callback for executing execution events. Allows + *
+ *ActionContributionItems
to fire useful events. + *+ * Clients must not implement this interface and must not extend. + *
+ * + * @since 3.4 + * + */ + public static interface IExecuteCallback { + + /** + * Fires aNotEnabledException
because the action was not + * enabled. + * + * @param action + * The action contribution that caused the exception, + * nevernull
. + * @param exception + * TheNotEnabledException
, nevernull
. + */ + public void notEnabled(IAction action, NotEnabledException exception); + + /** + * Fires aNotDefinedException
because the action was not + * defined. + * + * @param action + * The action contribution that caused the exception, + * nevernull
. + * @param exception + * TheNotDefinedException
, nevernull
. + */ + public void notDefined(IAction action, NotDefinedException exception); + + /** + * Fires an execution event before an action is run. + * + * @param action + * The action contribution that requires an + * execution event to be fired. Cannot benull
. + * @param e + * The DWT Event, may benull
. + * + */ + public void preExecute(IAction action, + Event e); + + /** + * Fires an execution event when the action returned a success. + * + * @param action + * The action contribution that requires an + * execution event to be fired. Cannot benull
. + * @param returnValue + * The command's result, may benull
. + * + */ + public void postExecuteSuccess(IAction action, + Object returnValue); + + /** + * Creates anExecutionException
when the action returned + * a failure. + * + * @param action + * The action contribution that caused the exception, + * nevernull
. + * @param exception + * TheExecutionException
, nevernull
. + */ + public void postExecuteFailure(IAction action, + ExecutionException exception); + } /** * A callback mechanism for some external tool to communicate extra @@ -423,9 +646,8 @@ * case of the Eclipse workbench, this is the command identifier. * *- * A single instance of the listener may only ever be associated with - * one identifier. Attempts to add the listener twice (without a removal - * in between) has undefined behaviour. + * Has no effect if an identical listener has already been added for + * the
* * @param identifier @@ -505,6 +727,7 @@ */ public void removePropertyChangeListener(String identifier, IPropertyChangeListener listener); + } /** diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/ExternalActionManager.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/action/ExternalActionManager.properties Thu May 22 01:36:46 2008 +0200 @@ -0,0 +1,12 @@ +############################################################################### +# 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 +############################################################################### + +undefinedCommand.WarningMessage = The command ("{0}") is undefined diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/IAction.d --- a/dwtx/jface/action/IAction.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/jface/action/IAction.d Thu May 22 01:36:46 2008 +0200 @@ -122,8 +122,8 @@ /** * Property name of an action's success/fail result * (valueidentifier
. *"result"
). The values are - *bool.TRUE
if running the action succeeded and - *bool.FALSE
if running the action failed or did not + *Boolean.TRUE
if running the action succeeded and + *Boolean.FALSE
if running the action failed or did not * complete. ** Not all actions report whether they succeed or fail. This property diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/IContributionManager.d --- a/dwtx/jface/action/IContributionManager.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/jface/action/IContributionManager.d Thu May 22 01:36:46 2008 +0200 @@ -47,14 +47,14 @@ * Adds an action as a contribution item to this manager. * Equivalent to
add(new ActionContributionItem(action))
. * - * @param action the action + * @param action the action, this cannot benull
*/ public void add(IAction action); /** * Adds a contribution item to this manager. * - * @param item the contribution item + * @param item the contribution item, this cannot benull
*/ public void add(IContributionItem item); diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/IContributionManagerOverrides.d --- a/dwtx/jface/action/IContributionManagerOverrides.d Mon May 19 13:41:06 2008 +0200 +++ b/dwtx/jface/action/IContributionManagerOverrides.d Thu May 22 01:36:46 2008 +0200 @@ -40,13 +40,13 @@ * @param item the contribution item for which the enable override value is * determined * @return
bool.TRUE
if the given contribution item should be enabledbool.FALSE
if the item should be disabledBoolean.TRUE
if the given contribution item should be enabledBoolean.FALSE
if the item should be disablednull
if the item may determine its own enablementnull
.
* Typically used for creating a context menu, where it doesn't need to be referred to by id.
*/
public this() {
- this(null, null);
+ this(null, null, null);
}
/**
@@ -121,7 +143,7 @@
* @param text the text for the menu, or null
if none
*/
public this(String text) {
- this(text, null);
+ this(text, null, null);
}
/**
@@ -132,8 +154,22 @@
* @param id the menu id, or null
if it is to have no id
*/
public this(String text, String id) {
+ this(text, null, id);
+ }
+
+ /**
+ * Creates a menu manager with the given text, image, and id.
+ * Typically used for creating a sub-menu, where it needs to be referred to by id.
+ *
+ * @param text the text for the menu, or null
if none
+ * @param image the image for the menu, or null
if none
+ * @param id the menu id, or null
if it is to have no id
+ * @since 3.4
+ */
+ public MenuManager(String text, ImageDescriptor image, String id) {
listeners = new ListenerList();
this.menuText = text;
+ this.image = image;
this.id = id;
}
@@ -211,10 +247,14 @@
menuItem = null;
}
+ disposeOldImages();
+
IContributionItem[] items = getItems();
for (int i = 0; i < items.length; i++) {
items[i].dispose();
}
+
+ markDirty();
}
/* (non-Javadoc)
@@ -242,6 +282,14 @@
menuItem.setText(getMenuText());
+ if (image !is null) {
+ LocalResourceManager localManager = new LocalResourceManager(
+ JFaceResources.getResources());
+ menuItem.setImage(localManager.createImage(image));
+ disposeOldImages();
+ imageManager = localManager;
+ }
+
if (!menuExist()) {
menu = new Menu(parent);
}
@@ -250,9 +298,7 @@
initializeMenu();
- // populate the submenu, in order to enable accelerators
- // and to set enabled state on the menuItem properly
- update(true);
+ setDirty(true);
}
}
@@ -346,13 +392,36 @@
}
/**
- * Returns the text shown in the menu.
+ * Returns the text shown in the menu, potentially with a shortcut
+ * appended.
*
* @return the menu text
*/
public String getMenuText() {
+ if (definitionId is null) {
+ return menuText;
+ }
+ ExternalActionManager.ICallback callback = ExternalActionManager
+ .getInstance().getCallback();
+ if (callback !is null) {
+ String shortCut = callback.getAcceleratorText(definitionId);
+ if (shortCut is null) {
+ return menuText;
+ }
+ return menuText + "\t" + shortCut; //$NON-NLS-1$
+ }
return menuText;
}
+
+ /**
+ * Returns the image for this menu as an image descriptor.
+ *
+ * @return the image, or null
if this menu has no image
+ * @since 3.4
+ */
+ public ImageDescriptor getImageDescriptor() {
+ return image;
+ }
/* (non-Javadoc)
* @see dwtx.jface.action.IContributionManager#getOverrides()
@@ -369,7 +438,7 @@
return null;
}
- public ValueWrapperBool getEnabled(IContributionItem item) {
+ public Boolean getEnabled(IContributionItem item) {
return null;
}
@@ -410,7 +479,7 @@
removeAll();
}
fireAboutToShow(this);
- update(false, true);
+ update(false, false);
}
/**
@@ -491,10 +560,15 @@
*/
public bool isVisible() {
if (!visible) {
- return false; // short circut calculations in this case
+ return false; // short circuit calculations in this case
}
- // menus arent visible if all of its children are invisible (or only contains visible separators).
+ if (removeAllWhenShown) {
+ // we have no way of knowing if the menu has children
+ return true;
+ }
+
+ // menus aren't visible if all of its children are invisible (or only contains visible separators).
IContributionItem[] childItems = getItems();
bool visibleChildren = false;
for (int j = 0; j < childItems.length; j++) {
@@ -536,7 +610,7 @@
* @return true
if the control is created
* and not disposed, false
otherwise
*/
- private bool menuExist() {
+ protected bool menuExist() {
return menu !is null && !menu.isDisposed();
}
@@ -584,6 +658,19 @@
public void setVisible(bool visible) {
this.visible = visible;
}
+
+ /**
+ * Sets the action definition id of this action. This simply allows the menu
+ * item text to include a short cut if available. It can be used to
+ * notify a user of a key combination that will open a quick menu.
+ *
+ * @param definitionId
+ * the command definition id
+ * @since 3.4
+ */
+ public void setActionDefinitionId(String definitionId) {
+ this.definitionId = definitionId;
+ }
/* (non-Javadoc)
* @see dwtx.jface.action.IContributionItem#update()
@@ -603,6 +690,65 @@
}
/**
+ * Get all the items from the implementation's widget.
+ *
+ * @return the menu items
+ * @since 3.4
+ */
+ protected Item[] getMenuItems() {
+ if (menu !is null) {
+ return menu.getItems();
+ }
+ return null;
+ }
+
+ /**
+ * Get an item from the implementation's widget.
+ *
+ * @param index
+ * of the item
+ * @return the menu item
+ * @since 3.4
+ */
+ protected Item getMenuItem(int index) {
+ if (menu !isnull) {
+ return menu.getItem(index);
+ }
+ return null;
+ }
+
+ /**
+ * Get the menu item count for the implementation's widget.
+ *
+ * @return the number of items
+ * @since 3.4
+ */
+ protected int getMenuItemCount() {
+ if (menu !is null) {
+ return menu.getItemCount();
+ }
+ return 0;
+ }
+
+ /**
+ * Call an IContributionItem
's fill method with the
+ * implementation's widget. The default is to use the Menu
+ * widget.fill(Menu menu, int index)
+ *
+ * @param ci
+ * An IContributionItem
whose fill()
+ * method should be called.
+ * @param index
+ * The position the fill()
method should start
+ * inserting at.
+ * @since 3.4
+ */
+ protected void doItemFill(IContributionItem ci, int index) {
+ ci.fill(menu, index);
+ }
+
+ /**
* Incrementally builds the menu from the contribution items.
* This method leaves out double separators and separators in the first
* or last position.
@@ -641,7 +787,7 @@
}
// remove obsolete (removed or non active)
- MenuItem[] mi = menu.getItems();
+ Item[] mi = getMenuItems();
for (int i = 0; i < mi.length; i++) {
Object data = mi[i].getData();
@@ -660,7 +806,7 @@
}
// add new
- mi = menu.getItems();
+ mi = getMenuItems();
int srcIx = 0;
int destIx = 0;
@@ -683,11 +829,11 @@
srcIx++;
destIx++;
} else {
- int start = menu.getItemCount();
- src.fill(menu, destIx);
- int newItems = menu.getItemCount() - start;
+ int start = getMenuItemCount();
+ doItemFill(src, destIx);
+ int newItems = getMenuItemCount() - start;
for (int i = 0; i < newItems; i++) {
- MenuItem item = menu.getItem(destIx++);
+ Item item = getMenuItem(destIx++);
item.setData(cast(Object)src);
}
}
@@ -743,42 +889,59 @@
for (int i = 0; i < items.length; i++) {
items[i].update(property);
}
-
- if (menu !is null && !menu.isDisposed() && menu.getParentItem() !is null
- && IAction.TEXT.equals(property)) {
- String text = getOverrides().getText(this);
+
+ if (menu !is null && !menu.isDisposed() && menu.getParentItem() !is null) {
+ if (IAction.TEXT.equals(property)) {
+ String text = getOverrides().getText(this);
- if (text is null) {
- text = getMenuText();
- }
+ if (text is null) {
+ text = getMenuText();
+ }
- if (text !is null) {
- ExternalActionManager.ICallback callback = ExternalActionManager
- .getInstance().getCallback();
+ if (text !is null) {
+ ExternalActionManager.ICallback callback = ExternalActionManager
+ .getInstance().getCallback();
- if (callback !is null) {
- int index = dwt.dwthelper.utils.indexOf( text, '&' );
+ if (callback !is null) {
+ int index = dwt.dwthelper.utils.indexOf( text, '&' );
- if (index >= 0 && index < text.length - 1) {
- char character = CharacterToUpper(text
- .charAt(index + 1));
+ if (index >= 0 && index < text.length - 1) {
+ char character = CharacterToUpper(text
+ .charAt(index + 1));
- if (callback.isAcceleratorInUse(DWT.ALT | character)) {
- if (index is 0) {
- text = text.substring(1);
- } else {
- text = text.substring(0, index)
+ if (callback.isAcceleratorInUse(DWT.ALT | character)) {
+ if (index is 0) {
+ text = text.substring(1);
+ } else {
+ text = text.substring(0, index)
~ text.substring(index + 1);
+ }
}
}
}
- }
- menu.getParentItem().setText(text);
+ menu.getParentItem().setText(text);
+ }
+ } else if (IAction.IMAGE.equals(property) && image !is null) {
+ LocalResourceManager localManager = new LocalResourceManager(JFaceResources
+ .getResources());
+ menu.getParentItem().setImage(localManager.createImage(image));
+ disposeOldImages();
+ imageManager = localManager;
}
}
}
+ /**
+ * Dispose any images allocated for this menu
+ */
+ private void disposeOldImages() {
+ if (imageManager !is null) {
+ imageManager.dispose();
+ imageManager = null;
+ }
+ }
+
/* (non-Javadoc)
* @see dwtx.jface.action.IMenuManager#updateAll(bool)
*/
@@ -813,7 +976,7 @@
// Partial fix for bug #34969 - diable the menu item if no
// items in sub-menu (for context menus).
if (menuItem !is null && !menuItem.isDisposed() && menuExist()) {
- bool enabled = menu.getItemCount() > 0;
+ bool enabled = removeAllWhenShown || menu.getItemCount() > 0;
// Workaround for 1GDDCN2: DWT:Linux - MenuItem.setEnabled() always causes a redraw
if (menuItem.getEnabled() !is enabled) {
// We only do this for context menus (for bug #34969)
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/StatusLine.d
--- a/dwtx/jface/action/StatusLine.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/action/StatusLine.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -39,20 +39,22 @@
import dwtx.jface.resource.ImageDescriptor;
import dwtx.jface.resource.JFaceColors;
import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.util.Util;
import dwt.dwthelper.utils;
import dwt.dwthelper.Runnable;
/**
* A StatusLine control is a DWT Composite with a horizontal layout which hosts
- * a number of status indication controls.
- * Typically it is situated below the content area of the window.
+ * a number of status indication controls. Typically it is situated below the
+ * content area of the window.
* - * By default a StatusLine has two predefined status controls: a MessageLine and a - * ProgressIndicator and it provides API for easy access. + * By default a StatusLine has two predefined status controls: a MessageLine and + * a ProgressIndicator and it provides API for easy access. *
*- * This is an internal class, not intended to be used outside the JFace framework. + * This is an internal class, not intended to be used outside the JFace + * framework. *
*/ /* package */class StatusLine : Composite, IProgressMonitor { @@ -183,7 +185,8 @@ // in its update method. There is thus a dependency // between the layout of the standard widgets and the update method. - // Make sure cancel button and progress bar are before contributions. + // Make sure cancel button and progress bar are before + // contributions. fMessageLabel.moveAbove(null); fToolBar.moveBelow(fMessageLabel); fProgressBarComposite.moveBelow(fToolBar); @@ -238,14 +241,12 @@ for (int i = 0; i < count; i++) { Control w = children[i]; /* - * Workaround for Linux Motif: - * Even if the progress bar and cancel button are - * not set to be visible ad of width 0, they still - * draw over the first pixel of the editor - * contributions. + * Workaround for Linux Motif: Even if the progress bar and + * cancel button are not set to be visible ad of width 0, they + * still draw over the first pixel of the editor contributions. * - * The fix here is to draw the progress bar and - * cancel button off screen if they are not visible. + * The fix here is to draw the progress bar and cancel button + * off screen if they are not visible. */ if (w is fProgressBarComposite && !fProgressIsVisible || w is fToolBar && !fCancelButtonIsVisible) { @@ -263,8 +264,10 @@ /** * Create a new StatusLine as a child of the given parent. * - * @param parent the parent for this Composite - * @param style the style used to create this widget + * @param parent + * the parent for this Composite + * @param style + * the style used to create this widget */ public this(Composite parent, int style) { super(parent, style); @@ -282,12 +285,13 @@ setLayout(new StatusLineLayout()); - fMessageLabel = new CLabel(this, DWT.NONE);//DWT.SHADOW_IN); - // Color[] colors = new Color[2]; - // colors[0] = parent.getDisplay().getSystemColor(DWT.COLOR_WIDGET_LIGHT_SHADOW); - // colors[1] = fMessageLabel.getBackground(); - // int[] gradient = new int[] {JFaceColors.STATUS_PERCENT}; - // fMessageLabel.setBackground(colors, gradient); + fMessageLabel = new CLabel(this, DWT.NONE);// DWT.SHADOW_IN); + // Color[] colors = new Color[2]; + // colors[0] = + // parent.getDisplay().getSystemColor(DWT.COLOR_WIDGET_LIGHT_SHADOW); + // colors[1] = fMessageLabel.getBackground(); + // int[] gradient = new int[] {JFaceColors.STATUS_PERCENT}; + // fMessageLabel.setBackground(colors, gradient); fProgressIsVisible = false; fCancelEnabled = false; @@ -330,13 +334,15 @@ /** * Notifies that the main task is beginning. * - * @param name the name (or description) of the main task - * @param totalWork the total number of work units into which - * the main task is been subdivided. If the value is 0 or UNKNOWN the - * implemenation is free to indicate progress in a way which doesn't - * require the total number of work units in advance. In general users - * should use the UNKNOWN value if they don't know the total amount of - * work units. + * @param name + * the name (or description) of the main task + * @param totalWork + * the total number of work units into which the main task is + * been subdivided. If the value is 0 or UNKNOWN the + * implemenation is free to indicate progress in a way which + * doesn't require the total number of work units in advance. In + * general users should use the UNKNOWN value if they don't know + * the total amount of work units. */ public void beginTask(String name, int totalWork) { long timestamp = System.currentTimeMillis(); @@ -364,7 +370,7 @@ fProgressBar.beginTask(totalWork); } if (name is null) { - fTaskName = "";//$NON-NLS-1$ + fTaskName = Util.ZERO_LENGTH_STRING; } else { fTaskName = name; } @@ -372,10 +378,9 @@ } /** - * Notifies that the work is done; that is, either the main task is completed or the - * user cancelled it. - * Done() can be called more than once; an implementation should be prepared to handle - * this case. + * Notifies that the work is done; that is, either the main task is + * completed or the user cancelled it. Done() can be called more than once; + * an implementation should be prepared to handle this case. */ public void done() { @@ -392,6 +397,7 @@ /** * Returns the status line's progress monitor + * * @return {@link IProgressMonitor} the progress monitor */ public IProgressMonitor getProgressMonitor() { @@ -414,7 +420,7 @@ /** * Hides the Cancel button and ProgressIndicator. - * @private + * */ protected void hideProgress() { @@ -450,15 +456,16 @@ /** * Returns true if the user does some UI action to cancel this operation. - * (like hitting the Cancel button on the progress dialog). - * The long running operation typically polls isCanceled(). + * (like hitting the Cancel button on the progress dialog). The long running + * operation typically polls isCanceled(). */ public bool isCanceled() { return fIsCanceled; } /** - * Returnstrue if the ProgressIndication provides UI for canceling
+ * Returns
+ * true if the ProgressIndication provides UI for canceling
* a long running operation.
* @return true if the ProgressIndication provides UI for canceling
*/
@@ -467,8 +474,8 @@
}
/**
- * Sets the cancel status. This method is usually called with the
- * argument false if a client wants to abort a cancel action.
+ * Sets the cancel status. This method is usually called with the argument
+ * false if a client wants to abort a cancel action.
*/
public void setCanceled(bool b) {
fIsCanceled = b;
@@ -478,12 +485,13 @@
}
/**
- * Controls whether the ProgressIndication provides UI for canceling
- * a long running operation.
- * If the ProgressIndication is currently visible calling this method may have
- * a direct effect on the layout because it will make a cancel button visible.
- *
- * @param enabled true if cancel should be enabled
+ * Controls whether the ProgressIndication provides UI for canceling a long
+ * running operation. If the ProgressIndication is currently visible calling
+ * this method may have a direct effect on the layout because it will make a
+ * cancel button visible.
+ *
+ * @param enabled
+ * true if cancel should be enabled
*/
public void setCancelEnabled(bool enabled) {
fCancelEnabled = enabled;
@@ -497,10 +505,11 @@
}
/**
- * Sets the error message text to be displayed on the status line.
- * The image on the status line is cleared.
+ * Sets the error message text to be displayed on the status line. The image
+ * on the status line is cleared.
*
- * @param message the error message, or null
for no error message
+ * @param message
+ * the error message, or null
for no error message
*/
public void setErrorMessage(String message) {
setErrorMessage(null, message);
@@ -509,8 +518,10 @@
/**
* Sets an image and error message text to be displayed on the status line.
*
- * @param image the image to use, or null
for no image
- * @param message the error message, or null
for no error message
+ * @param image
+ * the image to use, or null
for no image
+ * @param message
+ * the error message, or null
for no error message
*/
public void setErrorMessage(Image image, String message) {
fErrorText = trim(message);
@@ -530,10 +541,11 @@
}
/**
- * Sets the message text to be displayed on the status line.
- * The image on the status line is cleared.
+ * Sets the message text to be displayed on the status line. The image on
+ * the status line is cleared.
*
- * @param message the error message, or null
for no error message
+ * @param message
+ * the error message, or null
for no error message
*/
public void setMessage(String message) {
setMessage(null, message);
@@ -542,8 +554,10 @@
/**
* Sets an image and a message text to be displayed on the status line.
*
- * @param image the image to use, or null
for no image
- * @param message the message, or null
for no message
+ * @param image
+ * the image to use, or null
for no image
+ * @param message
+ * the message, or null
for no message
*/
public void setMessage(Image image, String message) {
fMessageText = trim(message);
@@ -555,12 +569,15 @@
* @see IProgressMonitor#setTaskName(java.lang.String)
*/
public void setTaskName(String name) {
- fTaskName = name;
+ if (name is null)
+ fTaskName = Util.ZERO_LENGTH_STRING;
+ else
+ fTaskName = name;
}
/**
* Makes the Cancel button visible.
- * @private
+ *
*/
protected void showButton() {
if (fToolBar !is null && !fToolBar.isDisposed()) {
@@ -573,7 +590,7 @@
/**
* Shows the Cancel button and ProgressIndicator.
- * @private
+ *
*/
protected void showProgress() {
if (!fProgressIsVisible && !isDisposed()) {
@@ -604,31 +621,40 @@
}
/**
- * Notifies that a subtask of the main task is beginning.
- * Subtasks are optional; the main task might not have subtasks.
- * @param name the name (or description) of the subtask
+ * Notifies that a subtask of the main task is beginning. Subtasks are
+ * optional; the main task might not have subtasks.
+ *
+ * @param name
+ * the name (or description) of the subtask
* @see IProgressMonitor#subTask(String)
*/
public void subTask(String name) {
+
+ String newName;
+ if (name is null)
+ newName = Util.ZERO_LENGTH_STRING;
+ else
+ newName = name;
+
String text;
if (fTaskName.length is 0) {
- text = name;
+ text = newName;
} else {
text = JFaceResources.format(
- "Set_SubTask", [ fTaskName, name ]);//$NON-NLS-1$
+ "Set_SubTask", [ fTaskName, newName ]);//$NON-NLS-1$
}
setMessage(text);
}
/**
- * Trims the message to be displayable in the status line.
- * This just pulls out the first line of the message.
- * Allows null.
+ * Trims the message to be displayable in the status line. This just pulls
+ * out the first line of the message. Allows null.
*/
String trim(String message) {
if (message is null) {
return null;
}
+ message = Util.replaceAll(message, "&", "&&"); //$NON-NLS-1$//$NON-NLS-2$
int cr = message.indexOf('\r');
int lf = message.indexOf('\n');
if (cr is -1 && lf is -1) {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/StatusLineContributionItem.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/action/StatusLineContributionItem.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ * Port to the D programming language:
+ * Frank Benoit
+ *******************************************************************************/
+
+module dwtx.jface.action.StatusLineContributionItem;
+
+
+import dwt.DWT;
+import dwt.custom.CLabel;
+import dwt.graphics.FontMetrics;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.widgets.Composite;
+import dwt.widgets.Label;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.util.Util;
+
+/**
+ * A contribution item to be used with status line managers.
+ *
+ * This class may be instantiated; it is not intended to be subclassed.
+ *
+ *
+ * @since 3.4
+ */
+public class StatusLineContributionItem extends ContributionItem {
+
+ private final static int DEFAULT_CHAR_WIDTH = 40;
+
+ private int charWidth;
+
+ private CLabel label;
+
+ /**
+ * The composite into which this contribution item has been placed. This
+ * will be null
if this instance has not yet been
+ * initialized.
+ */
+ private Composite statusLine = null;
+
+ private String text = Util.ZERO_LENGTH_STRING;
+
+ private int widthHint = -1;
+
+ private int heightHint = -1;
+
+ /**
+ * Creates a status line contribution item with the given id.
+ *
+ * @param id
+ * the contribution item's id, or null
if it is to
+ * have no id
+ */
+ public StatusLineContributionItem(String id) {
+ this(id, DEFAULT_CHAR_WIDTH);
+ }
+
+ /**
+ * Creates a status line contribution item with the given id that displays
+ * the given number of characters.
+ *
+ * @param id
+ * the contribution item's id, or null
if it is to
+ * have no id
+ * @param charWidth
+ * the number of characters to display
+ */
+ public StatusLineContributionItem(String id, int charWidth) {
+ super(id);
+ this.charWidth = charWidth;
+ setVisible(false); // no text to start with
+ }
+
+ public void fill(Composite parent) {
+ statusLine = parent;
+
+ Label sep = new Label(parent, DWT.SEPARATOR);
+ label = new CLabel(statusLine, DWT.SHADOW_NONE);
+
+ if (widthHint < 0) {
+ GC gc = new GC(statusLine);
+ gc.setFont(statusLine.getFont());
+ FontMetrics fm = gc.getFontMetrics();
+ widthHint = fm.getAverageCharWidth() * charWidth;
+ heightHint = fm.getHeight();
+ gc.dispose();
+ }
+
+ StatusLineLayoutData data = new StatusLineLayoutData();
+ data.widthHint = widthHint;
+ label.setLayoutData(data);
+ label.setText(text);
+
+ data = new StatusLineLayoutData();
+ data.heightHint = heightHint;
+ sep.setLayoutData(data);
+ }
+
+ /**
+ * An accessor for the current location of this status line contribution
+ * item -- relative to the display.
+ *
+ * @return The current location of this status line; null
if
+ * not yet initialized.
+ */
+ public Point getDisplayLocation() {
+ if ((label !is null) && (statusLine !is null)) {
+ return statusLine.toDisplay(label.getLocation());
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieves the text that is being displayed in the status line.
+ *
+ * @return the text that is currently being displayed
+ */
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * Sets the text to be displayed in the status line.
+ *
+ * @param text
+ * the text to be displayed, must not be null
+ */
+ public void setText(String text) {
+ Assert.isNotNull(text);
+
+ this.text = escape(text);
+
+ if (label !is null && !label.isDisposed()) {
+ label.setText(this.text);
+ }
+
+ if (this.text.length() is 0) {
+ if (isVisible()) {
+ setVisible(false);
+ IContributionManager contributionManager = getParent();
+
+ if (contributionManager !is null) {
+ contributionManager.update(true);
+ }
+ }
+ } else {
+ if (!isVisible()) {
+ setVisible(true);
+ IContributionManager contributionManager = getParent();
+
+ if (contributionManager !is null) {
+ contributionManager.update(true);
+ }
+ }
+ }
+ }
+
+ private String escape(String text) {
+ return Util.replaceAll(text, "&", "&&"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/SubMenuManager.d
--- a/dwtx/jface/action/SubMenuManager.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/action/SubMenuManager.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -114,7 +114,7 @@
if (menuListener !is null) {
getParentMenuManager().removeMenuListener(menuListener);
menuListener = null;
- clearListenerList(menuListeners);
+ menuListeners.clear();
}
// Dispose wrapped menus in addition to removing them.
// See bugs 64024 and 73715 for details.
@@ -132,20 +132,6 @@
super.disposeManager();
}
- /**
- * Clears all of the listeners in a listener list. TODO Bug 117519 Remove
- * this method when fixed.
- *
- * @param list
- * The list to be clear; must not be null
.
- */
- private final void clearListenerList(ListenerList list) {
- Object[] listeners = list.getListeners();
- for (int i = 0; i < listeners.length; i++) {
- list.remove(cast(Object)listeners[i]);
- }
- }
-
/* (non-Javadoc)
* @see dwtx.jface.action.IContributionItem#fill(dwt.widgets.Composite)
*/
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/ToolBarManager.d
--- a/dwtx/jface/action/ToolBarManager.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/action/ToolBarManager.d Thu May 22 01:36:46 2008 +0200
@@ -25,8 +25,11 @@
import dwt.accessibility.AccessibleAdapter;
import dwt.accessibility.AccessibleEvent;
import dwt.accessibility.AccessibleListener;
+import dwt.graphics.Point;
import dwt.widgets.Composite;
import dwt.widgets.Control;
+import dwt.widgets.CoolBar;
+import dwt.widgets.CoolItem;
import dwt.widgets.Menu;
import dwt.widgets.ToolBar;
import dwt.widgets.ToolItem;
@@ -184,8 +187,7 @@
* Re-lays out the tool bar.
*
* The default implementation of this framework method re-lays out the
- * parent when the number of items crosses the zero threshold. Subclasses
- * should override this method to implement their own re-layout strategy
+ * parent when the number of items are different and the new count !is 0
*
* @param layoutBar
* the tool bar control
@@ -195,8 +197,31 @@
* the new number of items
*/
protected void relayout(ToolBar layoutBar, int oldCount, int newCount) {
- if ((oldCount is 0) !is (newCount is 0)) {
+ if ((oldCount !is newCount) && (newCount!is0)) {
+ Point beforePack = layoutBar.getSize();
+ layoutBar.pack(true);
+ Point afterPack = layoutBar.getSize();
+
+ // If the TB didn't change size then we're done
+ if (beforePack.equals(afterPack))
+ return;
+
+ // OK, we need to re-layout the TB
layoutBar.getParent().layout();
+
+ // Now, if we're in a CoolBar then change the CoolItem size as well
+ if (layoutBar.getParent() instanceof CoolBar) {
+ CoolBar cb = (CoolBar) layoutBar.getParent();
+ CoolItem[] items = cb.getItems();
+ for (int i = 0; i < items.length; i++) {
+ if (items[i].getControl() is layoutBar) {
+ Point curSize = items[i].getSize();
+ items[i].setSize(curSize.x+ (afterPack.x - beforePack.x),
+ curSize.y+ (afterPack.y - beforePack.y));
+ return;
+ }
+ }
+ }
}
}
@@ -362,6 +387,11 @@
}
int newCount = toolBar.getItemCount();
+
+ // If we're forcing a change then ensure that we re-layout everything
+ if (force)
+ oldCount = newCount+1;
+
relayout(toolBar, oldCount, newCount);
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/action/images/stop.gif
Binary file dwtx/jface/action/images/stop.gif has changed
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/bindings/Binding.d
--- a/dwtx/jface/bindings/Binding.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/bindings/Binding.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * Copyright (c) 2004, 2008 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
@@ -270,7 +270,7 @@
if (!Util.opEquals(getSchemeId(), binding.getSchemeId())) {
return false;
}
- return (getType() !is binding.getType());
+ return (getType() is binding.getType());
}
/**
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/bindings/BindingManager.d
--- a/dwtx/jface/bindings/BindingManager.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/bindings/BindingManager.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * Copyright (c) 2004, 2008 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
@@ -1204,13 +1204,7 @@
public final TriggerSequence[] getActiveBindingsFor(String commandId) {
ParameterizedCommand parameterizedCommand = new ParameterizedCommand(
commandManager.getCommand(commandId), null);
- Object object = getActiveBindingsByParameterizedCommand().get(
- parameterizedCommand);
- if ( auto collection = cast(Seq!(Object))object ) {
- return arraycast!(TriggerSequence)(collection.toArray());
- }
-
- return EMPTY_TRIGGER_SEQUENCE;
+ return getActiveBindingsFor(parameterizedCommand);
}
/**
@@ -1225,8 +1219,8 @@
* null
if there are no active bindings.
* @since 3.2
*/
- private final Binding[] getActiveBindingsFor1(String commandId) {
- TriggerSequence[] triggers = getActiveBindingsFor(commandId);
+ private final Binding[] getActiveBindingsFor1(final ParameterizedCommand command) {
+ TriggerSequence[] triggers = getActiveBindingsFor(command);
if (triggers.length is 0) {
return null;
}
@@ -1281,7 +1275,16 @@
* @since 3.2
*/
public final TriggerSequence getBestActiveBindingFor(String commandId) {
- Binding[] bindings = getActiveBindingsFor1(commandId);
+ return getBestActiveBindingFor(new ParameterizedCommand(commandManager.getCommand(commandId), null));
+ }
+
+ /**
+ * @param command
+ * @return
+ * blah
+ */
+ public final TriggerSequence getBestActiveBindingFor(final ParameterizedCommand command) {
+ final Binding[] bindings = getActiveBindingsFor1(command);
if ((bindings is null) || (bindings.length is 0)) {
return null;
}
@@ -1397,7 +1400,6 @@
return null;
}
-
/**
*
* Returns the set of all bindings managed by this class.
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/bindings/keys/KeySequenceText.d
--- a/dwtx/jface/bindings/keys/KeySequenceText.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/bindings/keys/KeySequenceText.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * Copyright (c) 2004, 2008 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
@@ -84,6 +84,8 @@
* The key strokes from which to delete. This list must not
* be null
, and must represent a valid key
* sequence.
+ * @return An array of keystrokes minus the keystrokes that were
+ * deleted.
*/
private final KeyStroke[] deleteKeyStroke(KeyStroke[] keyStrokes) {
clearInsertionIndex();
@@ -152,7 +154,7 @@
*/
private KeyStroke[] handleKeyDown(Event event, KeyStroke[] keyStrokes) {
// Is it an unmodified backspace character?
- if ((event.character is DWT.BS) && (event.stateMask is 0)) {
+ if ((event.character is DWT.BS || event.character is DWT.DEL) && (event.stateMask is 0)) {
return deleteKeyStroke(keyStrokes);
}
@@ -638,6 +640,10 @@
* @param allowIncomplete
* Whether incomplete strokes should be allowed to exist in the
* list after the deletion.
+ * @param deletedKeyStrokes
+ * The list of keystrokes that were deleted by this operation.
+ * Declared as final since it will hold a reference to the new
+ * keyStroke array that has deleted the selected keystrokes.
* @return The index at which a subsequent insert should occur. This index
* only has meaning to the insertStrokeAt
method.
*/
@@ -684,6 +690,8 @@
*/
int endStrokeIndex;
if (start is end) {
+ // return the current keystrokes, nothing has to be deleted
+ deletedKeyStrokes[0] = keyStrokes;
return startStrokeIndex;
}
@@ -700,10 +708,15 @@
* Remove the strokes that are touched by the selection. Keep track of
* the first stroke removed.
*/
- int newLength = endStrokeIndex - startStrokeIndex + 1;
+ int newLength = keyStrokesLength
+ - (endStrokeIndex - startStrokeIndex + 1);
deletedKeyStrokes[0] = new KeyStroke[newLength];
KeyStroke startStroke = keyStrokes[startStrokeIndex];
- System.arraycopy(keyStrokes, 0, keyStrokes, 0, newLength);
+ KeyStroke keyStrokeResult[] = new KeyStroke[newLength];
+ System.arraycopy(keyStrokes, 0, keyStrokeResult, 0, startStrokeIndex);
+ System.arraycopy(keyStrokes, endStrokeIndex + 1, keyStrokeResult,
+ startStrokeIndex, keyStrokesLength - endStrokeIndex - 1);
+ System.arraycopy(keyStrokeResult, 0, deletedKeyStrokes[0], 0, newLength);
/*
* Allow the first stroke removed to be replaced by an incomplete
@@ -720,7 +733,7 @@
startStrokeIndex);
added[startStrokeIndex] = incompleteStroke;
System.arraycopy(deletedKeyStrokes[0], startStrokeIndex, added,
- startStrokeIndex + 1, newLength);
+ startStrokeIndex + 1, newLength - startStrokeIndex);
deletedKeyStrokes[0] = added;
}
}
@@ -904,8 +917,13 @@
*/
public void setKeySequence(KeySequence newKeySequence) {
KeySequence oldKeySequence = keySequence;
- keySequence = newKeySequence;
+ if (newKeySequence is null) {
+ text.setText(""); //$NON-NLS-1$
+ } else {
+ keySequence = newKeySequence;
+ }
+
// Trim any extra strokes.
if (maxStrokes !is INFINITE) {
KeyStroke[] oldKeyStrokes = keySequence.getKeyStrokes();
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/commands/RadioState.d
--- a/dwtx/jface/commands/RadioState.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/commands/RadioState.d Thu May 22 01:36:46 2008 +0200
@@ -29,8 +29,8 @@
/**
*
* A piece of bool state grouped with other bool states. Of these states,
- * only one may have a value of {@link bool#TRUE} at any given point in time.
- * The values of all other states must be {@link bool#FALSE}.
+ * only one may have a value of {@link Boolean#TRUE} at any given point in time.
+ * The values of all other states must be {@link Boolean#FALSE}.
*
*
* If this state is registered using {@link IMenuStateIds#STYLE}, then it will
@@ -79,7 +79,7 @@
*/
private final void activateMember(RadioState state) {
if (active !is null && active !is state) {
- active.setValue( new ValueWrapperBool( false ));
+ active.setValue(Boolean.FALSE);
}
active = state;
}
@@ -101,8 +101,8 @@
state.addListener(this);
Object value = state.getValue();
- if ( auto v = cast(ValueWrapperBool)value ) {
- if (v.value) {
+ if ( auto v = cast(Boolean)value ) {
+ if (v.booleanValue()) {
activateMember(state);
}
}
@@ -111,8 +111,8 @@
public final void handleStateChange(State state,
Object oldValue) {
Object newValue = state.getValue();
- if ( auto v = cast(ValueWrapperBool)newValue) {
- if (v.value) {
+ if ( auto v = cast(Boolean)newValue) {
+ if (v.booleanValue()) {
activateMember(cast(RadioState) state);
}
}
@@ -254,15 +254,15 @@
* the change.
*
* @param value
- * The new value; should be a bool
.
+ * The new value; should be a Boolean
.
*/
public override void setValue(Object value) {
- if (!( cast(ValueWrapperBool)value )) {
+ if (!( cast(Boolean)value )) {
throw new IllegalArgumentException(
- "RadioState takes a bool as a value"); //$NON-NLS-1$
+ "RadioState takes a Boolean as a value"); //$NON-NLS-1$
}
- if (( cast(ValueWrapperBool)value ).value && (radioGroupIdentifier !is null)) {
+ if (( cast(Boolean)value ).booleanValue() && (radioGroupIdentifier !is null)) {
RadioStateManager.activateGroup(radioGroupIdentifier, this);
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/commands/ToggleState.d
--- a/dwtx/jface/commands/ToggleState.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/commands/ToggleState.d Thu May 22 01:36:46 2008 +0200
@@ -22,7 +22,7 @@
/**
*
- * A piece of state storing a {@link bool}.
+ * A piece of state storing a {@link Boolean}.
*
*
* If this state is registered using {@link IMenuStateIds#STYLE}, then it will
@@ -42,16 +42,16 @@
* off (e.g., false
).
*/
public this() {
- setValue(new ValueWrapperBool(false));
+ setValue(Boolean.FALSE);
}
public override final void load(IPreferenceStore store,
String preferenceKey) {
- bool currentValue = (cast(ValueWrapperBool) getValue()).value;
+ bool currentValue = (cast(Boolean) getValue()).booleanValue();
store.setDefault(preferenceKey, currentValue);
if (shouldPersist() && (store.contains(preferenceKey))) {
bool value = store.getBoolean(preferenceKey);
- setValue( new ValueWrapperBool( value ));
+ setValue(value ? Boolean.TRUE : Boolean.FALSE);
}
}
@@ -59,16 +59,16 @@
String preferenceKey) {
if (shouldPersist()) {
Object value = getValue();
- if ( auto v = cast(ValueWrapperBool)value ) {
- store.setValue(preferenceKey, v.value);
+ if ( auto v = cast(Boolean)value ) {
+ store.setValue(preferenceKey, v.booleanValue());
}
}
}
public override void setValue(Object value) {
- if (!(cast(ValueWrapperBool)value)) {
+ if (!(cast(Boolean)value)) {
throw new IllegalArgumentException(
- "ToggleState takes a bool as a value"); //$NON-NLS-1$
+ "ToggleState takes a Boolean as a value"); //$NON-NLS-1$
}
super.setValue(value);
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/dialogs/Dialog.d
--- a/dwtx/jface/dialogs/Dialog.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/dialogs/Dialog.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Remy Chi Jian Suen - Bug 218553 [JFace] mis-spelling of their in applyDialogFont(...)
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -450,8 +451,13 @@
*/
protected this(IShellProvider parentShell) {
super(parentShell);
- setShellStyle(DWT.DIALOG_TRIM | DWT.APPLICATION_MODAL
- | getDefaultOrientation());
+ if (isResizable()) {
+ setShellStyle(DWT.DIALOG_TRIM | DWT.APPLICATION_MODAL | DWT.MAX | DWT.RESIZE
+ | getDefaultOrientation());
+ } else {
+ setShellStyle(DWT.DIALOG_TRIM | DWT.APPLICATION_MODAL
+ | getDefaultOrientation());
+ }
setBlockOnOpen(true);
}
@@ -1009,7 +1015,7 @@
}
/**
- * Sets the dialog font on the control and any of its children if thier font
+ * Sets the dialog font on the control and any of its children if their font
* is not otherwise set.
*
* @param control
@@ -1283,5 +1289,31 @@
// constraining behavior in Window will be used.
return result;
}
-
+
+ /**
+ * Returns a bool indicating whether the dialog should be
+ * considered resizable when the shell style is initially
+ * set.
+ *
+ * This method is used to ensure that all style
+ * bits appropriate for resizable dialogs are added to the
+ * shell style. Individual dialogs may always set the shell
+ * style to ensure that a dialog is resizable, but using this
+ * method ensures that resizable dialogs will be created with
+ * the same set of style bits.
+ *
+ * Style bits will never be removed based on the return value
+ * of this method. For example, if a dialog returns
+ * false
, but also sets a style bit for a
+ * DWT.RESIZE border, the style bit will be honored.
+ *
+ * @return a bool indicating whether the dialog is
+ * resizable and should have the default style bits for
+ * resizable dialogs
+ *
+ * @since 3.4
+ */
+ protected bool isResizable() {
+ return false;
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/dialogs/ErrorDialog.d
--- a/dwtx/jface/dialogs/ErrorDialog.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/dialogs/ErrorDialog.d Thu May 22 01:36:46 2008 +0200
@@ -146,7 +146,6 @@
"Reason", [ message, status.getMessage() ]); //$NON-NLS-1$
this.status = status;
this.displayMask = displayMask;
- setShellStyle(getShellStyle() | DWT.RESIZE);
}
/*
@@ -201,7 +200,7 @@
provider.createSupportArea(supportArea, status);
GridData supportData = new GridData(DWT.FILL, DWT.FILL, true, true);
- supportData.verticalSpan = 3;
+ supportData.verticalSpan = 4;
supportArea.setLayoutData(supportData);
if (supportArea.getLayout() is null){
GridLayout layout = new GridLayout();
@@ -232,6 +231,11 @@
* and lays out a composite. Subclasses that require a different dialog area
* may either override this method, or call the super
* implementation and add controls to the created composite.
+ *
+ * Note: Since 3.4, the created composite no longer grabs excess vertical space.
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=72489.
+ * If the old behavior is desired by subclasses, get the returned composite's
+ * layout data and set grabExcessVerticalSpace to true.
*/
protected override Control createDialogArea(Composite parent) {
createMessageArea(parent);
@@ -247,6 +251,7 @@
composite.setLayout(layout);
GridData childData = new GridData(GridData.FILL_BOTH);
childData.horizontalSpan = 2;
+ childData.grabExcessVerticalSpace = false;
composite.setLayoutData(childData);
composite.setFont(parent.getFont());
@@ -535,6 +540,7 @@
} else {
list = createDropDownList(cast(Composite) getContents());
detailsButton.setText(IDialogConstants.HIDE_DETAILS_LABEL);
+ getContents().getShell().layout();
}
Point newSize = getShell().computeSize(DWT.DEFAULT, DWT.DEFAULT);
getShell()
@@ -681,4 +687,13 @@
return 2;
return 3;
}
+
+ /*
+ * (non-Javadoc)
+ * @see dwtx.jface.dialogs.Dialog#isResizable()
+ */
+ protected bool isResizable() {
+ return true;
+ }
+
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/dialogs/IconAndMessageDialog.d
--- a/dwtx/jface/dialogs/IconAndMessageDialog.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/dialogs/IconAndMessageDialog.d Thu May 22 01:36:46 2008 +0200
@@ -74,6 +74,7 @@
* since the parent is typically the composite created in
* {@link Dialog#createDialogArea}.
*
+ *
* @param composite
* The composite to parent from.
* @return Control
@@ -165,11 +166,11 @@
protected override Control createButtonBar(Composite parent) {
Composite composite = new Composite(parent, DWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(0) // this is incremented
- // by createButton
+ // by createButton
.equalWidth(true).applyTo(composite);
- GridDataFactory.fillDefaults().align_(DWT.END, DWT.CENTER).span(
- 2, 1).applyTo(composite);
+ GridDataFactory.fillDefaults().align_(DWT.END, DWT.CENTER).span(2, 1)
+ .applyTo(composite);
composite.setFont(parent.getFont());
// Add the buttons to the button bar.
createButtonsForButtonBar(composite);
@@ -193,12 +194,10 @@
protected override Control createContents(Composite parent) {
// initialize the dialog units
initializeDialogUnits(parent);
- Point defaultMargins = LayoutConstants.getMargins();
Point defaultSpacing = LayoutConstants.getSpacing();
- GridLayoutFactory.fillDefaults().margins(defaultMargins.x,
- defaultMargins.y * 3 / 2).spacing(defaultSpacing.x * 2,
- defaultSpacing.y).numColumns(getColumnCount()).applyTo(
- parent);
+ GridLayoutFactory.fillDefaults().margins(LayoutConstants.getMargins())
+ .spacing(defaultSpacing.x * 2,
+ defaultSpacing.y).numColumns(getColumnCount()).applyTo(parent);
GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
createDialogAndButtonArea(parent);
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/dialogs/InputDialog.d
--- a/dwtx/jface/dialogs/InputDialog.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/dialogs/InputDialog.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -172,7 +172,7 @@
label.setLayoutData(data);
label.setFont(parent.getFont());
}
- text = new Text(composite, DWT.SINGLE | DWT.BORDER);
+ text = new Text(composite, getInputTextStyle());
text.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
| GridData.HORIZONTAL_ALIGN_FILL));
text.addModifyListener(new class ModifyListener {
@@ -286,4 +286,17 @@
}
}
}
+
+ /**
+ * Returns the style bits that should be used for the input text field.
+ * Defaults to a single line entry. Subclasses may override.
+ *
+ * @return the integer style bits that should be used when creating the
+ * input text
+ *
+ * @since 3.4
+ */
+ protected int getInputTextStyle() {
+ return DWT.SINGLE | DWT.BORDER;
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/dialogs/MessageDialogWithToggle.d
--- a/dwtx/jface/dialogs/MessageDialogWithToggle.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/dialogs/MessageDialogWithToggle.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -701,9 +701,16 @@
return IDialogConstants.NO_TO_ALL_ID;
}
+ if (IDialogConstants.SHOW_DETAILS_LABEL.equals(buttonLabel)) {
+ return IDialogConstants.DETAILS_ID;
+ }
+
+ if (IDialogConstants.HIDE_DETAILS_LABEL.equals(buttonLabel)) {
+ return IDialogConstants.DETAILS_ID;
+ }
+
// No XXX_LABEL in IDialogConstants for these. Unlikely
// they would be used in a message dialog though.
- // public int DETAILS_ID = 13;
// public int SELECT_ALL_ID = 18;
// public int DESELECT_ALL_ID = 19;
// public int SELECT_TYPES_ID = 20;
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/dialogs/PopupDialog.d
--- a/dwtx/jface/dialogs/PopupDialog.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/dialogs/PopupDialog.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -31,12 +31,10 @@
import dwt.graphics.Color;
import dwt.graphics.Font;
import dwt.graphics.FontData;
-import dwt.graphics.Image;
import dwt.graphics.Point;
import dwt.graphics.Rectangle;
import dwt.widgets.Composite;
import dwt.widgets.Control;
-import dwt.widgets.Display;
import dwt.widgets.Event;
import dwt.widgets.Label;
import dwt.widgets.Listener;
@@ -53,7 +51,6 @@
import dwtx.jface.action.Separator;
import dwtx.jface.layout.GridDataFactory;
import dwtx.jface.layout.GridLayoutFactory;
-import dwtx.jface.resource.ImageDescriptor;
import dwtx.jface.resource.JFaceResources;
import dwtx.jface.window.Window;
@@ -109,8 +106,32 @@
/**
* The dialog settings key name for remembering if the persisted bounds
* should be accessed.
+ *
+ * @deprecated Since 3.4, this is retained only for backward compatibility.
*/
- private static const String DIALOG_USE_PERSISTED_BOUNDS = "DIALOG_USE_PERSISTED_BOUNDS"; //$NON-NLS-1$
+ private static final String DIALOG_USE_PERSISTED_BOUNDS = "DIALOG_USE_PERSISTED_BOUNDS"; //$NON-NLS-1$
+
+ /**
+ * The dialog settings key name for remembering if the bounds persisted
+ * prior to 3.4 have been migrated to the 3.4 settings.
+ *
+ * @since 3.4
+ * @deprecated This is marked deprecated at its introduction to discourage
+ * future dependency
+ */
+ private static final String DIALOG_VALUE_MIGRATED_TO_34 = "hasBeenMigratedTo34"; //$NON-NLS-1$
+
+ /**
+ * The dialog settings key name for remembering if the persisted size should
+ * be accessed.
+ */
+ private static final String DIALOG_USE_PERSISTED_SIZE = "DIALOG_USE_PERSISTED_SIZE"; //$NON-NLS-1$
+
+ /**
+ * The dialog settings key name for remembering if the persisted location
+ * should be accessed.
+ */
+ private static final String DIALOG_USE_PERSISTED_LOCATION = "DIALOG_USE_PERSISTED_LOCATION"; //$NON-NLS-1$
/**
* Move action for the dialog.
@@ -160,7 +181,7 @@
this() {
super(JFaceResources.getString("PopupDialog.persistBounds"), //$NON-NLS-1$
IAction.AS_CHECK_BOX);
- setChecked(persistBounds);
+ setChecked(persistLocation && persistSize);
}
/*
@@ -169,20 +190,66 @@
* @see dwtx.jface.action.IAction#run()
*/
public override void run() {
- persistBounds = isChecked();
+ persistSize = isChecked();
+ persistLocation = persistSize;
+ }
+ }
+
+ /**
+ *
+ * Remember bounds action for the dialog.
+ */
+ private class PersistSizeAction extends Action {
+
+ PersistSizeAction() {
+ super(JFaceResources.getString("PopupDialog.persistSize"), //$NON-NLS-1$
+ IAction.AS_CHECK_BOX);
+ setChecked(persistSize);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.action.IAction#run()
+ */
+ public void run() {
+ persistSize = isChecked();
+ }
+ }
+
+ /**
+ *
+ * Remember location action for the dialog.
+ */
+ private class PersistLocationAction extends Action {
+
+ PersistLocationAction() {
+ super(JFaceResources.getString("PopupDialog.persistLocation"), //$NON-NLS-1$
+ IAction.AS_CHECK_BOX);
+ setChecked(persistLocation);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.action.IAction#run()
+ */
+ public void run() {
+ persistLocation = isChecked();
}
}
/**
* Shell style appropriate for a simple hover popup that cannot get focus.
+ *
*/
public const static int HOVER_SHELLSTYLE = DWT.NO_FOCUS | DWT.ON_TOP
- | DWT.NO_TRIM;
+ | DWT.TOOL;
/**
* Shell style appropriate for an info popup that can get focus.
*/
- public const static int INFOPOPUP_SHELLSTYLE = DWT.NO_TRIM;
+ public const static int INFOPOPUP_SHELLSTYLE = DWT.TOOL;
/**
* Shell style appropriate for a resizable info popup that can get focus.
@@ -214,9 +281,23 @@
public const static int POPUP_HORIZONTALSPACING = 1;
/**
- *
+ * Image registry key for menu image.
+ *
+ * @since 3.3
*/
- private static const GridLayoutFactory POPUP_LAYOUT_FACTORY;
+ public static final String POPUP_IMG_MENU = "popup_menu_image"; //$NON-NLS-1$
+
+ /**
+ * Image registry key for disabled menu image.
+ *
+ * @since 3.3
+ */
+ public static final String POPUP_IMG_MENU_DISABLED = "popup_menu_image_diabled"; //$NON-NLS-1$
+
+ /**
+ *
+ */
+ private static final GridLayoutFactory POPUP_LAYOUT_FACTORY;
static this(){
LAYOUTDATA_GRAB_BOTH = GridDataFactory.fillDefaults().grab(true,true);
@@ -224,10 +305,6 @@
.fillDefaults().margins(POPUP_MARGINWIDTH, POPUP_MARGINHEIGHT)
.spacing(POPUP_HORIZONTALSPACING, POPUP_VERTICALSPACING);
}
- /**
- * Border thickness in pixels.
- */
- private static const int BORDER_THICKNESS = 1;
/**
* The dialog's toolbar for the move and resize capabilities.
@@ -256,11 +333,6 @@
private Control titleSeparator, infoSeparator;
/**
- * The images for the dialog menu.
- */
- private Image menuImage, disabledMenuImage = null;
-
- /**
* Font to be used for the info area text. Computed based on the dialog's
* font.
*/
@@ -295,16 +367,29 @@
private bool showDialogMenu_ = false;
/**
- * Flag specifying whether a menu action allowing the user to choose whether
- * the dialog bounds should be persisted is to be shown.
+ * Flag specifying whether menu actions allowing the user to choose whether
+ * the dialog bounds and location should be persisted are to be shown.
*/
- private bool showPersistAction = false;
+ private bool showPersistActions = false;
+
+ /**
+ * Flag specifying whether the size of the popup should be persisted. This
+ * flag is used as initial default and updated by the menu if it is shown.
+ */
+ private bool persistSize = false;
/**
- * Flag specifying whether the bounds of the popup should be persisted. This
- * flag is updated by a menu if the menu is shown.
+ * Flag specifying whether the location of the popup should be persisted.
+ * This flag is used as initial default and updated by the menu if it is
+ * shown.
*/
- private bool persistBounds = false;
+ private bool persistLocation = false;
+ /**
+ * Flag specifying whether to use new 3.4 API instead of the old one.
+ *
+ * @since 3.4
+ */
+ private bool isUsing34API = true;
/**
* Text to be shown in an optional title area (on top).
@@ -327,19 +412,20 @@
* A bool indicating whether focus should be taken by this
* popup when it opens.
* @param persistBounds
- * A bool indicating whether the bounds should be persisted
- * upon close of the dialog. The bounds can only be persisted if
- * the dialog settings for persisting the bounds are also
- * specified. If a menu action will be provided that allows the
- * user to control this feature, then the last known value of the
- * user's setting will be used instead of this flag.
+ * A bool indicating whether the bounds (size and location) of
+ * the dialog should be persisted upon close of the dialog. The
+ * bounds can only be persisted if the dialog settings for
+ * persisting the bounds are also specified. If a menu action
+ * will be provided that allows the user to control this feature,
+ * then the last known value of the user's setting will be used
+ * instead of this flag.
* @param showDialogMenu
* A bool indicating whether a menu for moving and resizing
* the popup should be provided.
- * @param showPersistAction
- * A bool indicating whether an action allowing the user to
- * control the persisting of the dialog bounds should be shown in
- * the dialog menu. This parameter has no effect if
+ * @param showPersistActions
+ * A bool indicating whether actions allowing the user to
+ * control the persisting of the dialog size and location should
+ * be shown in the dialog menu. This parameter has no effect if
* showDialogMenu
is false
.
* @param titleText
* Text to be shown in an upper title area, or null
@@ -347,23 +433,149 @@
* @param infoText
* Text to be shown in a lower info area, or null
* if there is no info area.
- *
+ *
* @see PopupDialog#getDialogSettings()
+ * @deprecated As of 3.4, replaced by
+ * {@link #PopupDialog(Shell, int, bool, bool, bool, bool, bool, String, String)}
+ */
+ public PopupDialog(Shell parent, int shellStyle, bool takeFocusOnOpen,
+ bool persistBounds, bool showDialogMenu,
+ bool showPersistActions, String titleText, String infoText) {
+ this(parent, shellStyle, takeFocusOnOpen, persistBounds, persistBounds,
+ showDialogMenu, showPersistActions, titleText, infoText, false);
+ }
+
+ /**
+ * Constructs a new instance of PopupDialog
.
+ *
+ * @param parent
+ * The parent shell.
+ * @param shellStyle
+ * The shell style.
+ * @param takeFocusOnOpen
+ * A bool indicating whether focus should be taken by this
+ * popup when it opens.
+ * @param persistSize
+ * A bool indicating whether the size should be persisted upon
+ * close of the dialog. The size can only be persisted if the
+ * dialog settings for persisting the bounds are also specified.
+ * If a menu action will be provided that allows the user to
+ * control this feature and the user hasn't changed that setting,
+ * then this flag is used as initial default for the menu.
+ * @param persistLocation
+ * A bool indicating whether the location should be persisted
+ * upon close of the dialog. The location can only be persisted
+ * if the dialog settings for persisting the bounds are also
+ * specified. If a menu action will be provided that allows the
+ * user to control this feature and the user hasn't changed that
+ * setting, then this flag is used as initial default for the
+ * menu. default for the menu until the user changed it.
+ * @param showDialogMenu
+ * A bool indicating whether a menu for moving and resizing
+ * the popup should be provided.
+ * @param showPersistActions
+ * A bool indicating whether actions allowing the user to
+ * control the persisting of the dialog bounds and location
+ * should be shown in the dialog menu. This parameter has no
+ * effect if showDialogMenu
is false
.
+ * @param titleText
+ * Text to be shown in an upper title area, or null
+ * if there is no title.
+ * @param infoText
+ * Text to be shown in a lower info area, or null
+ * if there is no info area.
+ *
+ * @see PopupDialog#getDialogSettings()
+ *
+ * @since 3.4
*/
- public this(Shell parent, int shellStyle, bool takeFocusOnOpen,
- bool persistBounds, bool showDialogMenu_,
- bool showPersistAction, String titleText, String infoText) {
+ public PopupDialog(Shell parent, int shellStyle, bool takeFocusOnOpen,
+ bool persistSize, bool persistLocation,
+ bool showDialogMenu, bool showPersistActions,
+ String titleText, String infoText) {
+ this(parent, shellStyle, takeFocusOnOpen, persistSize, persistLocation,
+ showDialogMenu, showPersistActions, titleText, infoText, true);
+
+ }
+
+ /**
+ * Constructs a new instance of PopupDialog
.
+ *
+ * @param parent
+ * The parent shell.
+ * @param shellStyle
+ * The shell style.
+ * @param takeFocusOnOpen
+ * A bool indicating whether focus should be taken by this
+ * popup when it opens.
+ * @param persistSize
+ * A bool indicating whether the size should be persisted upon
+ * close of the dialog. The size can only be persisted if the
+ * dialog settings for persisting the bounds are also specified.
+ * If a menu action will be provided that allows the user to
+ * control this feature and the user hasn't changed that setting,
+ * then this flag is used as initial default for the menu.
+ * @param persistLocation
+ * A bool indicating whether the location should be persisted
+ * upon close of the dialog. The location can only be persisted
+ * if the dialog settings for persisting the bounds are also
+ * specified. If a menu action will be provided that allows the
+ * user to control this feature and the user hasn't changed that
+ * setting, then this flag is used as initial default for the
+ * menu. default for the menu until the user changed it.
+ * @param showDialogMenu
+ * A bool indicating whether a menu for moving and resizing
+ * the popup should be provided.
+ * @param showPersistActions
+ * A bool indicating whether actions allowing the user to
+ * control the persisting of the dialog bounds and location
+ * should be shown in the dialog menu. This parameter has no
+ * effect if showDialogMenu
is false
.
+ * @param titleText
+ * Text to be shown in an upper title area, or null
+ * if there is no title.
+ * @param infoText
+ * Text to be shown in a lower info area, or null
+ * if there is no info area.
+ * @param use34API
+ * true
if 3.4 API should be used
+ *
+ * @see PopupDialog#getDialogSettings()
+ *
+ * @since 3.4
+ */
+ private PopupDialog(Shell parent, int shellStyle, bool takeFocusOnOpen,
+ bool persistSize, bool persistLocation,
+ bool showDialogMenu, bool showPersistActions,
+ String titleText, String infoText, bool use34API) {
super(parent);
+ // Prior to 3.4, we encouraged use of DWT.NO_TRIM and provided a
+ // border using a black composite background and margin. Now we
+ // use DWT.TOOL to get the border for some cases and this conflicts
+ // with DWT.NO_TRIM. Clients who previously have used DWT.NO_TRIM
+ // and still had a border drawn for them would find their border go
+ // away unless we do the following:
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=219743
+ if ((shellStyle & DWT.NO_TRIM) !is 0) {
+ shellStyle &= ~(DWT.NO_TRIM | DWT.SHELL_TRIM);
+ }
+
setShellStyle(shellStyle);
this.takeFocusOnOpen = takeFocusOnOpen;
this.showDialogMenu_ = showDialogMenu_;
- this.showPersistAction = showPersistAction;
+ this.showPersistActions = showPersistActions;
this.titleText = titleText;
this.infoText = infoText;
setBlockOnOpen(false);
- this.persistBounds = persistBounds;
+ this.isUsing34API = use34API;
+
+ this.persistSize = persistSize;
+ this.persistLocation = persistLocation;
+
+ migrateBoundsSetting();
+
initializeWidgetState();
}
@@ -373,12 +585,8 @@
* @see dwtx.jface.window.Window#configureShell(Shell)
*/
protected override void configureShell(Shell shell) {
- Display display = shell.getDisplay();
- shell.setBackground(display.getSystemColor(DWT.COLOR_BLACK));
-
- int border = ((getShellStyle() & DWT.NO_TRIM) is 0) ? 0
- : BORDER_THICKNESS;
- GridLayoutFactory.fillDefaults().margins(border, border).spacing(5,5).applyTo(shell);
+ GridLayoutFactory.fillDefaults().margins(0, 0).spacing(5, 5).applyTo(
+ shell);
shell.addListener(DWT.Deactivate, new class Listener {
public void handleEvent(Event event) {
@@ -391,11 +599,13 @@
*/
if (listenToDeactivate && event.widget is getShell()
&& getShell().getShells().length is 0) {
- close();
+ asyncClose();
} else {
- /* We typically ignore deactivates to work around platform-specific
- * event ordering. Now that we've ignored whatever we were supposed to,
- * start listening to deactivates. Example issues can be found in
+ /*
+ * We typically ignore deactivates to work around
+ * platform-specific event ordering. Now that we've ignored
+ * whatever we were supposed to, start listening to
+ * deactivates. Example issues can be found in
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=123392
*/
listenToDeactivate = true;
@@ -420,17 +630,18 @@
});
if ((getShellStyle() & DWT.ON_TOP) !is 0 && shell.getParent() !is null) {
- parentDeactivateListener= new class Listener {
+ parentDeactivateListener = new class Listener {
public void handleEvent(Event event) {
if (listenToParentDeactivate) {
- close();
+ asyncClose();
} else {
// Our first deactivate, now start listening on the Mac.
listenToParentDeactivate = listenToDeactivate;
}
}
};
- shell.getParent().addListener(DWT.Deactivate, parentDeactivateListener);
+ shell.getParent().addListener(DWT.Deactivate,
+ parentDeactivateListener);
}
shell.addDisposeListener(new class DisposeListener {
@@ -440,6 +651,15 @@
});
}
+ private void asyncClose() {
+ // workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=152010
+ getShell().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ close();
+ }
+ });
+ }
+
/**
* The PopupDialog
implementation of this Window
* method creates and lays out the top level composite for the dialog. It
@@ -585,9 +805,8 @@
Composite titleAreaComposite = new Composite(parent, DWT.NONE);
POPUP_LAYOUT_FACTORY.copy().numColumns(2).applyTo(titleAreaComposite);
- GridDataFactory.fillDefaults()
- .align_(DWT.FILL, DWT.CENTER).grab(true, false)
- .applyTo(titleAreaComposite);
+ GridDataFactory.fillDefaults().align_(DWT.FILL, DWT.CENTER).grab(true,
+ false).applyTo(titleAreaComposite);
createTitleControl(titleAreaComposite);
@@ -615,19 +834,8 @@
protected Control createTitleControl(Composite parent) {
titleLabel = new Label(parent, DWT.NONE);
- GridDataFactory.fillDefaults()
- .align_(DWT.FILL, DWT.CENTER)
- .grab(true, false)
- .span(showDialogMenu_ ? 1 : 2, 1)
- .applyTo(titleLabel);
-
- Font font = titleLabel.getFont();
- FontData[] fontDatas = font.getFontData();
- for (int i = 0; i < fontDatas.length; i++) {
- fontDatas[i].setStyle(DWT.BOLD);
- }
- titleFont = new Font(titleLabel.getDisplay(), fontDatas);
- titleLabel.setFont(titleFont);
+ GridDataFactory.fillDefaults().align_(DWT.FILL, DWT.CENTER).grab(true,
+ false).span(showDialogMenu ? 1 : 2, 1).applyTo(titleLabel);
if (titleText !is null) {
titleLabel.setText(titleText);
@@ -657,15 +865,9 @@
// Status label
infoLabel = new Label(parent, DWT.RIGHT);
infoLabel.setText(infoText);
- Font font = infoLabel.getFont();
- FontData[] fontDatas = font.getFontData();
- for (int i = 0; i < fontDatas.length; i++) {
- fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
- }
- infoFont = new Font(infoLabel.getDisplay(), fontDatas);
- infoLabel.setFont(infoFont);
- GridDataFactory.fillDefaults().grab(true, false).align_(DWT.FILL, DWT.BEGINNING)
- .applyTo(infoLabel);
+
+ GridDataFactory.fillDefaults().grab(true, false).align(DWT.FILL,
+ DWT.BEGINNING).applyTo(infoLabel);
infoLabel.setForeground(parent.getDisplay().getSystemColor(
DWT.COLOR_WIDGET_DARK_SHADOW));
return infoLabel;
@@ -681,7 +883,8 @@
private Control createHorizontalSeparator(Composite parent) {
Label separator = new Label(parent, DWT.SEPARATOR | DWT.HORIZONTAL
| DWT.LINE_DOT);
- GridDataFactory.fillDefaults().align_(DWT.FILL, DWT.CENTER).grab(true, false).applyTo(separator);
+ GridDataFactory.fillDefaults().align_(DWT.FILL, DWT.CENTER).grab(true,
+ false).applyTo(separator);
return separator;
}
@@ -696,14 +899,11 @@
toolBar = new ToolBar(parent, DWT.FLAT);
ToolItem viewMenuButton = new ToolItem(toolBar, DWT.PUSH, 0);
- GridDataFactory.fillDefaults().align_(DWT.END, DWT.CENTER).applyTo(toolBar);
-
- menuImage = ImageDescriptor.createFromFile(
- getImportData!("dwtx.jface.dialogs.images.popup_menu.gif")).createImage();//$NON-NLS-1$
- disabledMenuImage = ImageDescriptor.createFromFile(
- getImportData!("dwtx.jface.dialogs.images.popup_menu_disabled.gif")).createImage();//$NON-NLS-1$
- viewMenuButton.setImage(menuImage);
- viewMenuButton.setDisabledImage(disabledMenuImage);
+ GridDataFactory.fillDefaults().align_(DWT.END, DWT.CENTER).applyTo(
+ toolBar);
+ viewMenuButton.setImage(JFaceResources.getImage(POPUP_IMG_MENU));
+ viewMenuButton.setDisabledImage(JFaceResources
+ .getImage(POPUP_IMG_MENU_DISABLED));
viewMenuButton.setToolTipText(JFaceResources
.getString("PopupDialog.menuTooltip")); //$NON-NLS-1$
viewMenuButton.addSelectionListener(new class SelectionAdapter {
@@ -711,14 +911,6 @@
showDialogMenu();
}
});
- viewMenuButton.addDisposeListener(new class DisposeListener {
- public void widgetDisposed(DisposeEvent e) {
- menuImage.dispose();
- menuImage = null;
- disabledMenuImage.dispose();
- disabledMenuImage = null;
- }
- });
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=177183
toolBar.addMouseListener(new class MouseAdapter {
public void mouseDown(MouseEvent e) {
@@ -737,8 +929,13 @@
dialogMenu.add(new GroupMarker("SystemMenuStart")); //$NON-NLS-1$
dialogMenu.add(new MoveAction());
dialogMenu.add(new ResizeAction());
- if (showPersistAction) {
- dialogMenu.add(new PersistBoundsAction());
+ if (showPersistActions) {
+ if (isUsing34API) {
+ dialogMenu.add(new PersistLocationAction());
+ dialogMenu.add(new PersistSizeAction());
+ } else {
+ dialogMenu.add(new PersistBoundsAction());
+ }
}
dialogMenu.add(new Separator("SystemMenuEnd")); //$NON-NLS-1$
}
@@ -837,11 +1034,47 @@
* modified if the persist bounds action is shown on the menu and the user
* has changed its value. Subclasses may override this method.
*
- * @return if the dialogs bounds will be persisted, false if it will
- * not.
+ * @return true
if the dialog's bounds will be persisted,
+ * false
if it will not.
+ *
+ * @deprecated As of 3.4, please use {@link #getPersistLocation()} or
+ * {@link #getPersistSize()} to determine separately whether
+ * size or location should be persisted.
*/
protected bool getPersistBounds() {
- return persistBounds;
+ return persistLocation && persistSize;
+ }
+
+ /**
+ * Return a bool indicating whether this dialog will persist its
+ * location. This value is initially set in the dialog's constructor, but
+ * can be modified if the persist location action is shown on the menu and
+ * the user has changed its value. Subclasses may override this method.
+ *
+ * @return true
if the dialog's location will be persisted,
+ * false
if it will not.
+ *
+ * @see #getPersistSize()
+ * @since 3.4
+ */
+ protected bool getPersistLocation() {
+ return persistLocation;
+ }
+
+ /**
+ * Return a bool indicating whether this dialog will persist its size.
+ * This value is initially set in the dialog's constructor, but can be
+ * modified if the persist size action is shown on the menu and the user has
+ * changed its value. Subclasses may override this method.
+ *
+ * @return true
if the dialog's size will be persisted,
+ * false
if it will not.
+ *
+ * @see #getPersistLocation()
+ * @since 3.4
+ */
+ protected bool getPersistSize() {
+ return persistSize;
}
/**
@@ -922,7 +1155,8 @@
initializeWidgetState();
if (parentDeactivateListener !is null) {
- getShell().getParent().removeListener(DWT.Deactivate, parentDeactivateListener);
+ getShell().getParent().removeListener(DWT.Deactivate,
+ parentDeactivateListener);
parentDeactivateListener = null;
}
@@ -965,17 +1199,21 @@
shellLocation.x -= parentLocation.x;
shellLocation.y -= parentLocation.y;
}
- if (persistBounds) {
- String prefix = this.classinfo.name;
- settings.put(prefix ~ DIALOG_ORIGIN_X, shellLocation.x);
- settings.put(prefix ~ DIALOG_ORIGIN_Y, shellLocation.y);
+ String prefix = this.classinfo.name;
+ if (persistSize) {
settings.put(prefix ~ DIALOG_WIDTH, shellSize.x);
settings.put(prefix ~ DIALOG_HEIGHT, shellSize.y);
}
- if (showPersistAction && showDialogMenu_) {
- settings.put(
- this.classinfo.name ~ DIALOG_USE_PERSISTED_BOUNDS,
- persistBounds);
+ if (persistLocation) {
+ settings.put(prefix ~ DIALOG_ORIGIN_X, shellLocation.x);
+ settings.put(prefix ~ DIALOG_ORIGIN_Y, shellLocation.y);
+ }
+ if (showPersistActions && showDialogMenu) {
+ settings.put(getClass().getName() + DIALOG_USE_PERSISTED_SIZE,
+ persistSize);
+ settings.put(getClass().getName()
+ + DIALOG_USE_PERSISTED_LOCATION, persistLocation);
+
}
}
}
@@ -986,8 +1224,8 @@
* @see dwtx.jface.window.Window#getInitialSize()
*/
protected override Point getInitialSize() {
- Point result = super.getInitialSize();
- if (persistBounds) {
+ Point result = getDefaultSize();
+ if (persistSize) {
IDialogSettings settings = getDialogSettings();
if (settings !is null) {
try {
@@ -1007,6 +1245,42 @@
}
/**
+ * Return the default size to use for the shell. This default size is used
+ * if the dialog does not have any persisted size to restore. The default
+ * implementation returns the preferred size of the shell. Subclasses should
+ * override this method when an alternate default size is desired, rather
+ * than overriding {@link #getInitialSize()}.
+ *
+ * @return the initial size of the shell
+ *
+ * @see #getPersistSize()
+ * @since 3.4
+ */
+ protected Point getDefaultSize() {
+ return super.getInitialSize();
+ }
+
+ /**
+ * Returns the default location to use for the shell. This default location
+ * is used if the dialog does not have any persisted location to restore.
+ * The default implementation uses the location computed by
+ * {@link dwtx.jface.window.Window#getInitialLocation(Point)}.
+ * Subclasses should override this method when an alternate default location
+ * is desired, rather than overriding {@link #getInitialLocation(Point)}.
+ *
+ * @param initialSize
+ * the initial size of the shell, as returned by
+ * getInitialSize
.
+ * @return the initial location of the shell
+ *
+ * @see #getPersistLocation()
+ * @since 3.4
+ */
+ protected Point getDefaultLocation(Point initialSize) {
+ return super.getInitialLocation(initialSize);
+ }
+
+ /**
* Adjust the bounds of the popup as necessary prior to opening the dialog.
* Default is to do nothing, which honors any bounds set directly by clients
* or those that have been saved in the dialog settings. Subclasses should
@@ -1022,8 +1296,8 @@
* @see dwtx.jface.window.Window#getInitialLocation(dwt.graphics.Point)
*/
protected override Point getInitialLocation(Point initialSize) {
- Point result = super.getInitialLocation(initialSize);
- if (persistBounds) {
+ Point result = getDefaultLocation(initialSize);
+ if (persistLocation) {
IDialogSettings settings = getDialogSettings();
if (settings !is null) {
try {
@@ -1056,12 +1330,66 @@
* the contents composite
*/
private void applyColors(Composite composite) {
- applyForegroundColor(getShell().getDisplay().getSystemColor(
- DWT.COLOR_INFO_FOREGROUND), composite,
- getForegroundColorExclusions());
- applyBackgroundColor(getShell().getDisplay().getSystemColor(
- DWT.COLOR_INFO_BACKGROUND), composite,
- getBackgroundColorExclusions());
+ // The getForeground() and getBackground() methods
+ // should not answer null, but IColorProvider clients
+ // are accustomed to null meaning use the default, so we guard
+ // against this assumption.
+ Color color = getForeground();
+ if (color is null)
+ color = getDefaultForeground();
+ applyForegroundColor(color, composite, getForegroundColorExclusions());
+ color = getBackground();
+ if (color is null)
+ color = getDefaultBackground();
+ applyBackgroundColor(color, composite, getBackgroundColorExclusions());
+ }
+
+ /**
+ * Get the foreground color that should be used for this popup. Subclasses
+ * may override.
+ *
+ * @return the foreground color to be used. Should not be null
.
+ *
+ * @since 3.4
+ *
+ * @see #getForegroundColorExclusions()
+ */
+ protected Color getForeground() {
+ return getDefaultForeground();
+ }
+
+ /**
+ * Get the background color that should be used for this popup. Subclasses
+ * may override.
+ *
+ * @return the background color to be used. Should not be null
.
+ *
+ * @since 3.4
+ *
+ * @see #getBackgroundColorExclusions()
+ */
+ protected Color getBackground() {
+ return getDefaultBackground();
+ }
+
+ /**
+ * Return the default foreground color used for popup dialogs.
+ *
+ * @return the default foreground color.
+ */
+ private Color getDefaultForeground() {
+ return getShell().getDisplay()
+ .getSystemColor(DWT.COLOR_INFO_FOREGROUND);
+ }
+
+ /**
+ * Return the default background color used for popup dialogs.
+ *
+ * @return the default background color
+ */
+ private Color getDefaultBackground() {
+ return getShell().getDisplay()
+ .getSystemColor(DWT.COLOR_INFO_BACKGROUND);
}
/**
@@ -1073,6 +1401,25 @@
private void applyFonts(Composite composite) {
Dialog.applyDialogFont(composite);
+ if (titleLabel !is null) {
+ Font font = titleLabel.getFont();
+ FontData[] fontDatas = font.getFontData();
+ for (int i = 0; i < fontDatas.length; i++) {
+ fontDatas[i].setStyle(DWT.BOLD);
+ }
+ titleFont = new Font(titleLabel.getDisplay(), fontDatas);
+ titleLabel.setFont(titleFont);
+ }
+
+ if (infoLabel !is null) {
+ Font font = infoLabel.getFont();
+ FontData[] fontDatas = font.getFontData();
+ for (int i = 0; i < fontDatas.length; i++) {
+ fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
+ }
+ infoFont = new Font(infoLabel.getDisplay(), fontDatas);
+ infoLabel.setFont(infoFont);
+ }
}
/**
@@ -1102,7 +1449,7 @@
/**
* Set the specified background color for the specified control and all of
- * its children.
+ * its children, except for those specified in the list of exclusions.
*
* @param color
* the color to use as the background color
@@ -1130,13 +1477,13 @@
* its children. Subclasses may override this method, but typically do not.
* If a subclass wishes to exclude a particular control in its contents from
* getting the specified foreground color, it may instead override
- * PopupDialog.getForegroundColorExclusions
.
+ * {@link #getForegroundColorExclusions()}.
*
* @param color
- * the color to use as the background color
+ * the color to use as the foreground color
* @param control
* the control whose color is to be changed
- * @see PopupDialog#getBackgroundColorExclusions()
+ * @see PopupDialog#getForegroundColorExclusions()
*/
protected void applyForegroundColor(Color color, Control control) {
applyForegroundColor(color, control, getForegroundColorExclusions());
@@ -1147,7 +1494,7 @@
* its children. Subclasses may override this method, but typically do not.
* If a subclass wishes to exclude a particular control in its contents from
* getting the specified background color, it may instead override
- * PopupDialog.getBackgroundColorExclusions
.
+ * {@link #getBackgroundColorExclusions()}
*
* @param color
* the color to use as the background color
@@ -1161,7 +1508,7 @@
/**
* Return a list of controls which should never have their foreground color
- * reset. Subclasses may extend this method (should always call
+ * reset. Subclasses may extend this method, but should always call
* super.getForegroundColorExclusions
to aggregate the list.
*
*
@@ -1184,7 +1531,7 @@
/**
* Return a list of controls which should never have their background color
- * reset. Subclasses may extend this method (should always call
+ * reset. Subclasses may extend this method, but should always call
* super.getBackgroundColorExclusions
to aggregate the list.
*
* @return the List of controls
@@ -1217,19 +1564,40 @@
// If the menu item for persisting bounds is displayed, use the stored
// value to determine whether any persisted bounds should be honored at
// all.
- if (showDialogMenu_ && showPersistAction) {
+ if (showDialogMenu_ && showPersistActions) {
IDialogSettings settings = getDialogSettings();
if (settings !is null) {
- persistBounds = settings.getBoolean(this.classinfo.name
- ~ DIALOG_USE_PERSISTED_BOUNDS);
+ String key = this.classinfo.name ~ DIALOG_USE_PERSISTED_SIZE;
+ if (settings.get(key) !is null || !isUsing34API)
+ persistSize = settings.getBoolean(key);
+ key = this.classinfo.name ~ DIALOG_USE_PERSISTED_LOCATION;
+ if (settings.get(key) !is null || !isUsing34API)
+ persistLocation = settings.getBoolean(key);
}
}
+ }
+ private void migrateBoundsSetting() {
+ IDialogSettings settings = getDialogSettings();
+ if (settings is null)
+ return;
+
+ final String className = getClass().getName();
+
+ String key = className + DIALOG_USE_PERSISTED_BOUNDS;
+ String value = settings.get(key);
+ if (value is null || DIALOG_VALUE_MIGRATED_TO_34.equals(value))
+ return;
+
+ bool storeBounds = settings.getBoolean(key);
+ settings.put(className + DIALOG_USE_PERSISTED_LOCATION, storeBounds);
+ settings.put(className + DIALOG_USE_PERSISTED_SIZE, storeBounds);
+ settings.put(key, DIALOG_VALUE_MIGRATED_TO_34);
}
/**
- * The dialog is being disposed. Dispose of any resources allocated.
- *
+ * The dialog is being disposed. Dispose of any resources allocated.
+ *
*/
private void handleDispose() {
if (infoFont !is null && !infoFont.isDisposed()) {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/dialogs/ProgressIndicator.d
--- a/dwtx/jface/dialogs/ProgressIndicator.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/dialogs/ProgressIndicator.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Mark Siegel - Fix for Bug 184533
+ * [Progress] ProgressIndicator uses hardcoded style for ProgressBar
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -50,9 +52,27 @@
* The widgets parent
*/
public this(Composite parent) {
+ this(parent, DWT.NONE);
+ }
+
+ /**
+ * Create a ProgressIndicator as a child under the given parent.
+ *
+ * @param parent
+ * The widgets parent
+ * @param style the DWT style constants for progress monitors created
+ * by the receiver.
+ * @since 3.4
+ */
+ public ProgressIndicator(Composite parent, int style) {
super(parent, DWT.NULL);
- determinateProgressBar = new ProgressBar(this, DWT.HORIZONTAL);
- indeterminateProgressBar = new ProgressBar(this, DWT.HORIZONTAL
+
+ // Enforce horizontal only if vertical isn't set
+ if ((style & DWT.VERTICAL) is 0)
+ style |= DWT.HORIZONTAL;
+
+ determinateProgressBar = new ProgressBar(this, style);
+ indeterminateProgressBar = new ProgressBar(this, style
| DWT.INDETERMINATE);
layout_ = new StackLayout();
setLayout(layout_);
@@ -126,4 +146,32 @@
determinateProgressBar.setSelection(value);
}
}
+
+ /**
+ * Show the receiver as showing an error.
+ * @since 3.4
+ */
+ public void showError() {
+ determinateProgressBar.setState(DWT.ERROR);
+ indeterminateProgressBar.setState(DWT.ERROR);
+ }
+
+ /**
+ * Show the receiver as being paused.
+ * @since 3.4
+ */
+ public void showPaused() {
+ determinateProgressBar.setState(DWT.PAUSED);
+ indeterminateProgressBar.setState(DWT.PAUSED);
+ }
+
+ /**
+ * Reset the progress bar to it's normal style.
+ * @since 3.4
+ */
+ public void showNormal() {
+ determinateProgressBar.setState(DWT.NORMAL);
+ indeterminateProgressBar.setState(DWT.NORMAL);
+
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/dialogs/ProgressMonitorDialog.d
--- a/dwtx/jface/dialogs/ProgressMonitorDialog.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/dialogs/ProgressMonitorDialog.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -265,6 +265,8 @@
* @see dwtx.core.runtime.IProgressMonitorWithBlocking#clearBlocked()
*/
public void clearBlocked() {
+ if (getShell().isDisposed())
+ return;
locked = false;
updateForClearBlocked();
}
@@ -275,6 +277,8 @@
* @see dwtx.core.runtime.IProgressMonitorWithBlocking#setBlocked(dwtx.core.runtime.IStatus)
*/
public void setBlocked(IStatus reason) {
+ if (getShell().isDisposed())
+ return;
locked = true;
updateForSetBlocked(reason);
}
@@ -284,8 +288,10 @@
* Clear blocked state from the receiver.
*/
protected void updateForClearBlocked() {
+ progressIndicator.showNormal();
setMessage(task, true);
imageLabel.setImage(getImage());
+
}
/**
@@ -295,8 +301,10 @@
* IStatus that gives the details
*/
protected void updateForSetBlocked(IStatus reason) {
+ progressIndicator.showPaused();
setMessage(reason.getMessage(), true);
imageLabel.setImage(getImage());
+
}
/**
@@ -310,10 +318,14 @@
public this(Shell parent) {
progressMonitor = new ProgressMonitor();
super(parent);
- setShellStyle(getDefaultOrientation() | DWT.BORDER | DWT.TITLE
- | DWT.APPLICATION_MODAL); // no
- // close
- // button
+ // no close button on the shell style
+ if (isResizable()) {
+ setShellStyle(getDefaultOrientation() | DWT.BORDER | DWT.TITLE
+ | DWT.APPLICATION_MODAL | DWT.RESIZE | DWT.MAX);
+ } else {
+ setShellStyle(getDefaultOrientation() | DWT.BORDER | DWT.TITLE
+ | DWT.APPLICATION_MODAL);
+ }
setBlockOnOpen(false);
}
@@ -678,7 +690,8 @@
}
}
int result = super.open();
- // update message label just in case beginTask() has been invoked already
+ // update message label just in case beginTask() has been invoked
+ // already
if (task is null || task.length is 0)
setMessage(DEFAULT_TASKNAME, true);
else
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/dialogs/TrayDialog.d
--- a/dwtx/jface/dialogs/TrayDialog.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/dialogs/TrayDialog.d Thu May 22 01:36:46 2008 +0200
@@ -254,7 +254,7 @@
GridLayout grid = cast(GridLayout)layout;
return !grid.makeColumnsEqualWidth && (grid.horizontalSpacing is 0) &&
(grid.marginWidth is 0) && (grid.marginHeight is 0) &&
- (grid.horizontalSpacing is 0) && (grid.numColumns is 5);
+ (grid.numColumns is 5);
}
return false;
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/fieldassist/ComboContentAdapter.d
--- a/dwtx/jface/fieldassist/ComboContentAdapter.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/fieldassist/ComboContentAdapter.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2007 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
@@ -12,6 +12,7 @@
*******************************************************************************/
module dwtx.jface.fieldassist.ComboContentAdapter;
+import dwt.DWT;
import dwtx.jface.fieldassist.IControlContentAdapter;
import dwt.graphics.GC;
@@ -30,7 +31,18 @@
*
* @since 3.2
*/
-public class ComboContentAdapter : IControlContentAdapter {
+public class ComboContentAdapter : IControlContentAdapter,
+ IControlContentAdapter2 {
+
+ /*
+ * Set to true
if we should compute the text
+ * vertical bounds rather than just use the field size.
+ * Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=164748
+ * The corresponding DWT bug is
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44072
+ */
+ private static final bool COMPUTE_TEXT_USING_CLIENTAREA = !"carbon".equals(DWT.getPlatform()); //$NON-NLS-1$
+
/*
* (non-Javadoc)
@@ -92,6 +104,8 @@
* @see dwtx.jface.fieldassist.IControlContentAdapter#getInsertionBounds(dwt.widgets.Control)
*/
public Rectangle getInsertionBounds(Control control) {
+ // This doesn't take horizontal scrolling into affect.
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=204599
Combo combo = cast(Combo) control;
int position = combo.getSelection().y;
String contents = combo.getText();
@@ -100,8 +114,11 @@
Point extent = gc.textExtent(contents.substring(0, Math.min(position,
contents.length)));
gc.dispose();
- return new Rectangle(combo.getClientArea().x + extent.x, combo
+ if (COMPUTE_TEXT_USING_CLIENTAREA) {
+ return new Rectangle(combo.getClientArea().x + extent.x, combo
.getClientArea().y, 1, combo.getClientArea().height);
+ }
+ return new Rectangle(extent.x, 0, 1, combo.getSize().y);
}
/*
@@ -114,4 +131,27 @@
(cast(Combo) control).setSelection(new Point(index, index));
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.fieldassist.IControlContentAdapter2#getSelection(dwt.widgets.Control)
+ *
+ * @since 3.4
+ */
+ public Point getSelection(Control control) {
+ return ((Combo) control).getSelection();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.fieldassist.IControlContentAdapter2#setSelection(dwt.widgets.Control,
+ * dwt.graphics.Point)
+ *
+ * @since 3.4
+ */
+ public void setSelection(Control control, Point range) {
+ ((Combo) control).setSelection(range);
+ }
+
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/fieldassist/ContentProposalAdapter.d
--- a/dwtx/jface/fieldassist/ContentProposalAdapter.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/fieldassist/ContentProposalAdapter.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -27,6 +27,7 @@
import dwt.events.FocusEvent;
import dwt.events.SelectionEvent;
import dwt.events.SelectionListener;
+import dwt.graphics.Color;
import dwt.graphics.Image;
import dwt.graphics.Point;
import dwt.graphics.Rectangle;
@@ -44,6 +45,8 @@
import dwtx.core.runtime.ListenerList;
import dwtx.jface.bindings.keys.KeyStroke;
import dwtx.jface.dialogs.PopupDialog;
+import dwtx.jface.preference.JFacePreferences;
+import dwtx.jface.resource.JFaceResources;
import dwtx.jface.viewers.ILabelProvider;
import dwt.dwthelper.utils;
@@ -104,10 +107,7 @@
this(Event e__){ e_=e__; }
public void run() {
if (isValid()) {
- if (scrollbarClicked
- || hasFocus()
- || (infoPopup !is null && infoPopup
- .hasFocus())) {
+ if (scrollbarClicked || hasFocus()) {
return;
}
// Workaround a problem on X and Mac, whereby at
@@ -318,10 +318,9 @@
String contents = getControlContentAdapter()
.getControlContents(getControl());
// If there are no contents, changes in cursor
- // position
- // have no effect. Note also that we do not affect
- // the filter
- // text on ARROW_LEFT as we would with BS.
+ // position have no effect. Note also that we do
+ // not affect the filter text on ARROW_LEFT as
+ // we would with BS.
if (contents.length > 0) {
asyncRecomputeProposals(filterText);
}
@@ -512,6 +511,24 @@
}
getShell().setBounds(proposedBounds);
}
+
+ /*
+ * (non-Javadoc)
+ * @see dwtx.jface.dialogs.PopupDialog#getForeground()
+ */
+ protected Color getForeground() {
+ return control.getDisplay().
+ getSystemColor(DWT.COLOR_INFO_FOREGROUND);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see dwtx.jface.dialogs.PopupDialog#getBackground()
+ */
+ protected Color getBackground() {
+ return control.getDisplay().
+ getSystemColor(DWT.COLOR_INFO_BACKGROUND);
+ }
/*
* Set the text contents of the popup.
@@ -598,25 +615,21 @@
}
/*
- * Overridden to force change of colors. See
- * https://bugs.eclipse.org/bugs/show_bug.cgi?id=136244 (non-Javadoc)
- *
- * @see dwtx.jface.dialogs.PopupDialog#createContents(dwt.widgets.Composite)
+ * (non-Javadoc)
+ * @see dwtx.jface.dialogs.PopupDialog#getForeground()
*/
- protected override Control createContents(Composite parent) {
- Control contents = super.createContents(parent);
- changeDefaultColors(parent);
- return contents;
+ protected Color getForeground() {
+ return JFaceResources.getColorRegistry().get(
+ JFacePreferences.CONTENT_ASSIST_FOREGROUND_COLOR);
}
-
+
/*
- * Set the colors of the popup. The contents have already been created.
+ * (non-Javadoc)
+ * @see dwtx.jface.dialogs.PopupDialog#getBackground()
*/
- private void changeDefaultColors(Control control) {
- applyForegroundColor(getShell().getDisplay().getSystemColor(
- DWT.COLOR_LIST_FOREGROUND), control);
- applyBackgroundColor(getShell().getDisplay().getSystemColor(
- DWT.COLOR_LIST_BACKGROUND), control);
+ protected Color getBackground() {
+ return JFaceResources.getColorRegistry().get(
+ JFacePreferences.CONTENT_ASSIST_BACKGROUND_COLOR);
}
/*
@@ -821,14 +834,20 @@
}
/*
- * Return whether the receiver has focus.
+ * Return whether the receiver has focus. Since 3.4, this includes a
+ * check for whether the info popup has focus.
*/
private bool hasFocus() {
if (!isValid()) {
return false;
}
- return getShell().isFocusControl()
- || proposalTable.isFocusControl();
+ if (getShell().isFocusControl() || proposalTable.isFocusControl()) {
+ return true;
+ }
+ if (infoPopup !is null && infoPopup.hasFocus()) {
+ return true;
+ }
+ return false;
}
/*
@@ -968,10 +987,9 @@
* Accept the current proposal.
*/
private void acceptCurrentProposal() {
- // Close before accepting the proposal.
- // This is important so that the cursor position can be
- // properly restored at acceptance, which does not work without
- // focus on some controls.
+ // Close before accepting the proposal. This is important
+ // so that the cursor position can be properly restored at
+ // acceptance, which does not work without focus on some controls.
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=127108
IContentProposal proposal = getSelectedProposal();
close();
@@ -1090,6 +1108,11 @@
/**
* Indicates that a cumulative filter applies as keys are typed in the
* popup. That is, each character typed will be added to the filter.
+ *
+ * @deprecated As of 3.4, filtering that is sensitive to changes in the
+ * control content should be performed by the supplied
+ * {@link IContentProposalProvider}, such as that performed by
+ * {@link SimpleContentProposalProvider}
*/
public static const int FILTER_CUMULATIVE = 3;
@@ -1230,10 +1253,16 @@
private int insertionPos = -1;
/*
- * A flag that indicates that a pending modify event was caused by
- * the adapter rather than the user.
+ * The remembered selection range. Not all controls will restore the
+ * selection position if the proposal popup gets focus, so we need to
+ * remember it.
*/
- private bool modifyingControlContent = false;
+ private Point selectionRange = new Point(-1, -1);
+
+ /*
+ * A flag that indicates that we are watching modify events
+ */
+ private bool watchModify = false;
/**
* Construct a content proposal adapter that can assist the user with
@@ -1453,12 +1482,13 @@
* @return a constant indicating how keystrokes in the proposal popup affect
* filtering of the proposals shown. FILTER_NONE
* specifies that no filtering will occur in the content proposal
- * list as keys are typed. FILTER_CUMULATIVE
- * specifies that the content of the popup will be filtered by a
- * string containing all the characters typed since the popup has
- * been open. FILTER_CHARACTER
specifies the content
- * of the popup will be filtered by the most recently typed
- * character. The default is FILTER_NONE
.
+ * list as keys are typed. FILTER_CHARACTER
specifies
+ * the content of the popup will be filtered by the most recently
+ * typed character. FILTER_CUMULATIVE
is deprecated
+ * and no longer recommended. It specifies that the content of the
+ * popup will be filtered by a string containing all the characters
+ * typed since the popup has been open. The default is
+ * FILTER_NONE
.
*/
public int getFilterStyle() {
return filterStyle;
@@ -1479,12 +1509,12 @@
* popup affect filtering of the proposals shown.
* FILTER_NONE
specifies that no automatic
* filtering of the content proposal list will occur as keys are
- * typed in the popup. FILTER_CUMULATIVE
specifies
- * that the content of the popup will be filtered by a string
- * containing all the characters typed since the popup has been
- * open. FILTER_CHARACTER
specifies that the
- * content of the popup will be filtered by the most recently
- * typed character.
+ * typed in the popup. FILTER_CHARACTER
specifies
+ * that the content of the popup will be filtered by the most
+ * recently typed character. FILTER_CUMULATIVE
is
+ * deprecated and no longer recommended. It specifies that the
+ * content of the popup will be filtered by a string containing
+ * all the characters typed since the popup has been open.
*/
public void setFilterStyle(int filterStyle) {
this.filterStyle = filterStyle;
@@ -1719,45 +1749,52 @@
}
}
/*
- * The triggering keystroke was not invoked. Check for
- * autoactivation characters.
+ * The triggering keystroke was not invoked. If a character
+ * was typed, compare it to the autoactivation characters.
*/
if (e.character !is 0) {
- // Auto-activation characters were specified. Check
- // them.
if (autoActivateString !is null) {
if (autoActivateString.indexOf(e.character) >= 0) {
- e.doit = propagateKeys;
autoActivate();
+ } else {
+ // No autoactivation occurred, so record the key
+ // down as a means to interrupt any
+ // autoactivation
+ // that is pending due to autoactivation delay.
+ receivedKeyDown = true;
}
} else {
- // No autoactivation occurred, so record the key
- // down
- // as a means to interrupt any autoactivation that
- // is
- // pending.
- receivedKeyDown = true;
+ // The autoactivate string is null. If the trigger
+ // is also null, we want to act on any modification
+ // to the content. Set a flag so we'll catch this
+ // in the modify event.
+ if (triggerKeyStroke is null) {
+ watchModify = true;
+ }
}
}
break;
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=147377
// Given that we will close the popup when there are no valid
- // proposals, we must reopen it when there are. Normally, the
- // keydown event handling will catch all the cases where it
- // should reopen. But when autoactivation should occur on all
- // content changes, we check it here after keys have been
- // processed.
+ // proposals, we must reopen it when there are. This means
+ // we should check modifications in those cases.
// See also https://bugs.eclipse.org/bugs/show_bug.cgi?id=183650
- // We should not autoactivate if the content change was caused
- // by the popup itself.
+ // The watchModify flag ensures that we don't autoactivate if
+ // the content change was caused by something other than typing.
case DWT.Modify:
if (triggerKeyStroke is null && autoActivateString is null
- && !modifyingControlContent) {
+ && watchModify) {
if (DEBUG) {
dump("Modify event triggers autoactivation", e); //$NON-NLS-1$
}
- autoActivate();
+ watchModify = false;
+ // We don't autoactivate if the net change is no
+ // content. In other words, backspacing to empty
+ // should never cause a popup to open.
+ if (!isControlContentEmpty()) {
+ autoActivate();
+ }
}
break;
default:
@@ -1892,13 +1929,10 @@
*/
private void setControlContent(String text, int cursorPosition) {
if (isValid()) {
- // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=183650
- modifyingControlContent = true;
-
+ // should already be false, but just in case.
+ watchModify = false;
controlContentAdapter.setControlContents(control, text,
cursorPosition);
-
- modifyingControlContent = false;
}
}
@@ -1908,18 +1942,22 @@
*/
private void insertControlContent(String text, int cursorPosition) {
if (isValid()) {
- // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=183650
- modifyingControlContent = true;
+ // should already be false, but just in case.
+ watchModify = false;
// Not all controls preserve their selection index when they lose
// focus, so we must set it explicitly here to what it was before
// the popup opened.
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=127108
- if (insertionPos !is -1) {
+ // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=139063
+ if (controlContentAdapter instanceof IControlContentAdapter2
+ && selectionRange.x !is -1) {
+ ((IControlContentAdapter2) controlContentAdapter).setSelection(
+ control, selectionRange);
+ } else if (insertionPos !is -1) {
controlContentAdapter.setCursorPosition(control, insertionPos);
}
controlContentAdapter.insertControlContents(control, text,
cursorPosition);
- modifyingControlContent = false;
}
}
@@ -1936,8 +1974,13 @@
*/
private void recordCursorPosition() {
if (isValid()) {
- insertionPos = getControlContentAdapter()
- .getCursorPosition(control);
+ IControlContentAdapter adapter = getControlContentAdapter();
+ insertionPos = adapter.getCursorPosition(control);
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=139063
+ if (adapter instanceof IControlContentAdapter2) {
+ selectionRange = ((IControlContentAdapter2) adapter)
+ .getSelection(control);
+ }
}
}
@@ -2048,4 +2091,24 @@
.proposalPopupClosed(this);
}
}
+
+ /**
+ * Returns whether the content proposal popup has the focus. This includes
+ * both the primary popup and any secondary info popup that may have focus.
+ *
+ * @return true
if the proposal popup or its secondary info
+ * popup has the focus
+ * @since 3.4
+ */
+ public bool hasProposalPopupFocus() {
+ return popup !is null && popup.hasFocus();
+ }
+
+ /*
+ * Return whether the control content is empty
+ */
+ private bool isControlContentEmpty() {
+ return getControlContentAdapter().getControlContents(getControl())
+ .length() is 0;
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/fieldassist/ControlDecoration.d
--- a/dwtx/jface/fieldassist/ControlDecoration.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/fieldassist/ControlDecoration.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -121,13 +121,13 @@
private bool visible = true;
/**
- * bool indicating whether the decoration should only be shown when the
+ * Boolean indicating whether the decoration should only be shown when the
* control has focus
*/
private bool showOnlyOnFocus = false;
/**
- * bool indicating whether the decoration should show its description
+ * Boolean indicating whether the decoration should show its description
* text in a hover when the user hovers over the decoration.
*/
private bool showHover = true;
@@ -249,7 +249,7 @@
Region region;
/**
- * bool indicating whether the last computed polygon location had an
+ * Boolean indicating whether the last computed polygon location had an
* arrow on left. (true if left, false if right).
*/
bool arrowOnLeft = true;
@@ -260,7 +260,7 @@
this(Shell parent) {
Display display = parent.getDisplay();
hoverShell = new Shell(parent, DWT.NO_TRIM | DWT.ON_TOP
- | DWT.NO_FOCUS);
+ | DWT.NO_FOCUS | DWT.TOOL);
hoverShell.setBackground(display
.getSystemColor(DWT.COLOR_INFO_BACKGROUND));
hoverShell.setForeground(display
@@ -824,7 +824,8 @@
* an info hover over the field's control whenever the mouse hovers over the
* decoration. This method can be used to show a decoration's description
* text at other times (such as when the control receives focus), or to show
- * other text associated with the field.
+ * other text associated with the field. The hover will not be shown if the
+ * decoration is hidden.
*
* @param text
* the text to be shown in the info hover, or null
@@ -870,12 +871,13 @@
}
/**
- * Hide the control decoration. This message has no effect if the decoration
- * is already hidden.
+ * Hide the control decoration and any associated hovers. This message has
+ * no effect if the decoration is already hidden.
*/
public void hide() {
if (visible) {
visible = false;
+ hideHover();
update();
}
}
@@ -919,7 +921,8 @@
* decoration.
*
* @param image
- * the image to be shown adjacent to the control
+ * the image to be shown adjacent to the control. Should never be
+ * null
.
*/
public void setImage(Image image) {
this.image = image;
@@ -1045,6 +1048,11 @@
if (!showHover) {
return;
}
+
+ // If we are not visible, don't show the hover.
+ if (!visible) {
+ return;
+ }
// If there is no text, don't do anything.
if (text is null) {
hideHover();
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/fieldassist/DecoratedField.d
--- a/dwtx/jface/fieldassist/DecoratedField.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/fieldassist/DecoratedField.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -202,7 +202,7 @@
Region region;
/**
- * bool indicating whether the last computed polygon location had an
+ * Boolean indicating whether the last computed polygon location had an
* arrow on left. (true if left, false if right).
*/
bool arrowOnLeft = true;
@@ -213,7 +213,7 @@
this(Shell parent) {
final Display display = parent.getDisplay();
hoverShell = new Shell(parent, DWT.NO_TRIM | DWT.ON_TOP
- | DWT.NO_FOCUS);
+ | DWT.NO_FOCUS | DWT.TOOL);
hoverShell.setBackground(display
.getSystemColor(DWT.COLOR_INFO_BACKGROUND));
hoverShell.setForeground(display
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/fieldassist/IControlContentAdapter2.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/fieldassist/IControlContentAdapter2.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ * Port to the D programming language:
+ * Frank Benoit
+ *******************************************************************************/
+module dwtx.jface.fieldassist.IControlContentAdapter2;
+
+import dwt.graphics.Point;
+import dwt.widgets.Control;
+
+/**
+ * This interface is used by a {@link ContentProposalAdapter} in order to
+ * retrieve and set the selection range in a control.
+ *
+ * @since 3.4
+ */
+public interface IControlContentAdapter2 {
+ /**
+ * Get the current selection range in the control. The x coordinate of the
+ * returned point is the position of the first selected character and the y
+ * coordinate of the returned point is the position of the last selected
+ * character. The positions are specified as a zero-based index into the
+ * string. Valid ranges are from 0 to N, where N is the size of the contents
+ * string. A value of N indicates that the last character is in the
+ * selection.
+ *
+ * @param control
+ * the control whose position is to be retrieved.
+ * @return a point representing the selection start and end
+ */
+ public Point getSelection(Control control);
+
+ /**
+ * Set the current selection range in the control. The x coordinate of the
+ * provided point is the position of the first selected character and the y
+ * coordinate of the point is the position of the last selected character.
+ * The positions are specified as a zero-based index into the string. Valid
+ * ranges are from 0 to N, where N is the size of the contents string. A
+ * value of N indicates that the last character is in the selection. If the
+ * x and y coordinates are the same, then there is no selection.
+ *
+ * @param control
+ * the control whose position is to be retrieved.
+ * @param range
+ * a point representing the selection start and end
+ */
+ public void setSelection(Control control, Point range);
+
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/fieldassist/SimpleContentProposalProvider.d
--- a/dwtx/jface/fieldassist/SimpleContentProposalProvider.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/fieldassist/SimpleContentProposalProvider.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2007 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Amir Kouchekinia - bug 200762
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -41,7 +42,7 @@
private IContentProposal[] contentProposals;
/*
- * bool that tracks whether filtering is used.
+ * Boolean that tracks whether filtering is used.
*/
private bool filterProposals = false;
@@ -60,7 +61,7 @@
/**
* Return an array of Objects representing the valid content proposals for a
- * field. Ignore the current contents of the field.
+ * field.
*
* @param contents
* the current contents of the field (only consulted if filtering
@@ -74,7 +75,7 @@
if (filterProposals) {
auto list = new ArraySeq!(IContentProposal);
for (int i = 0; i < proposals.length; i++) {
- if (proposals[i].length > contents.length
+ if (proposals[i].length >= contents.length
&& proposals[i].substring(0, contents.length)
.equalsIgnoreCase(contents)) {
list.append(makeContentProposal(proposals[i]));
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/fieldassist/TextContentAdapter.d
--- a/dwtx/jface/fieldassist/TextContentAdapter.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/fieldassist/TextContentAdapter.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2007 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
@@ -28,7 +28,8 @@
*
* @since 3.2
*/
-public class TextContentAdapter : IControlContentAdapter {
+public class TextContentAdapter : IControlContentAdapter,
+ IControlContentAdapter2 {
/*
* (non-Javadoc)
@@ -86,8 +87,10 @@
public Rectangle getInsertionBounds(Control control) {
Text text = cast(Text) control;
Point caretOrigin = text.getCaretLocation();
- return new Rectangle(caretOrigin.x, caretOrigin.y, 1, text
- .getLineHeight());
+ // We fudge the y pixels due to problems with getCaretLocation
+ // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=52520
+ return new Rectangle(caretOrigin.x + text.getClientArea().x,
+ caretOrigin.y + text.getClientArea().y + 3, 1, text.getLineHeight());
}
/*
@@ -99,4 +102,27 @@
public void setCursorPosition(Control control, int position) {
(cast(Text) control).setSelection(new Point(position, position));
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.fieldassist.IControlContentAdapter2#getSelection(dwt.widgets.Control)
+ *
+ * @since 3.4
+ */
+ public Point getSelection(Control control) {
+ return ((Text) control).getSelection();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.fieldassist.IControlContentAdapter2#setSelection(dwt.widgets.Control,
+ * dwt.graphics.Point)
+ *
+ * @since 3.4
+ */
+ public void setSelection(Control control, Point range) {
+ ((Text) control).setSelection(range);
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/internal/ConfigureColumnsDialog.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/ConfigureColumnsDialog.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * Port to the D programming language:
+ * Frank Benoit
+ ******************************************************************************/
+
+module dwtx.jface.internal.ConfigureColumnsDialog;
+
+
+import dwt.DWT;
+import dwt.graphics.Image;
+import dwt.widgets.Button;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Event;
+import dwt.widgets.Item;
+import dwt.widgets.Label;
+import dwt.widgets.Listener;
+import dwt.widgets.Table;
+import dwt.widgets.TableColumn;
+import dwt.widgets.TableItem;
+import dwt.widgets.Text;
+import dwt.widgets.Tree;
+import dwt.widgets.TreeColumn;
+import dwtx.jface.dialogs.Dialog;
+import dwtx.jface.layout.GridDataFactory;
+import dwtx.jface.layout.GridLayoutFactory;
+import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.window.IShellProvider;
+
+/**
+ * NON-API - This class is internal and will be moved to another package in 3.5.
+ *
+ */
+public class ConfigureColumnsDialog extends Dialog {
+
+ private Control targetControl;
+ private ColumnObject[] columnObjects;
+ private Table table;
+ private Button upButton;
+ private Button downButton;
+ private Text text;
+ private bool moveableColumnsFound;
+
+ class ColumnObject {
+ Item column;
+ int index;
+ String name;
+ Image image;
+ bool visible;
+ int width;
+ bool moveable;
+ bool resizable;
+
+ ColumnObject(Item column, int index, String text, Image image,
+ int width, bool moveable, bool resizable, bool visible) {
+ this.column = column;
+ this.index = index;
+ this.name = text;
+ this.image = image;
+ this.width = width;
+ this.moveable = moveable;
+ this.resizable = resizable;
+ this.visible = visible;
+ }
+ }
+
+ /**
+ * NON-API - This class is internal and will be moved to another package in
+ * 3.5. Creates a new dialog for configuring columns of the given column
+ * viewer. The column viewer must have an underlying {@link Tree} or {@link
+ * Table}, other controls are not supported.
+ *
+ * @param shellProvider
+ * @param table
+ */
+ public ConfigureColumnsDialog(IShellProvider shellProvider, Table table) {
+ this(shellProvider, (Control) table);
+ }
+
+ /**
+ * NON-API - This class is internal and will be moved to another package in
+ * 3.5. Creates a new dialog for configuring columns of the given column
+ * viewer. The column viewer must have an underlying {@link Tree} or {@link
+ * Table}, other controls are not supported.
+ *
+ * @param shellProvider
+ * @param tree
+ */
+ public ConfigureColumnsDialog(IShellProvider shellProvider, Tree tree) {
+ this(shellProvider, (Control) tree);
+ }
+
+ /**
+ * @param shellProvider
+ * @param control
+ */
+ private ConfigureColumnsDialog(IShellProvider shellProvider, Control control) {
+ super(shellProvider);
+ this.targetControl = control;
+ this.moveableColumnsFound = createColumnObjects();
+ }
+
+ protected bool isResizable() {
+ return true;
+ }
+
+ public void create() {
+ super.create();
+ getShell().setText(
+ JFaceResources.getString("ConfigureColumnsDialog_Title")); //$NON-NLS-1$
+ }
+
+ protected void initializeBounds() {
+ super.initializeBounds();
+ table.setSelection(0);
+ handleSelectionChanged(0);
+ }
+
+ /**
+ * Returns true if any of the columns is moveable (can be reordered).
+ */
+ private bool createColumnObjects() {
+ bool result = true;
+ Item[] columns = getViewerColumns();
+ ColumnObject[] cObjects = new ColumnObject[columns.length];
+ for (int i = 0; i < columns.length; i++) {
+ Item c = columns[i];
+ bool moveable = getMoveable(c);
+ result = result && moveable;
+ cObjects[i] = new ColumnObject(c, i, getColumnName(c),
+ getColumnImage(c), getColumnWidth(c), moveable,
+ getResizable(c), true);
+ }
+ int[] columnOrder = getColumnOrder();
+ columnObjects = new ColumnObject[columns.length];
+ for (int i = 0; i < columnOrder.length; i++) {
+ columnObjects[i] = cObjects[columnOrder[i]];
+ }
+ return result;
+ }
+
+ /**
+ * @param c
+ * @return
+ */
+ private Image getColumnImage(Item item) {
+ if (item instanceof TableColumn) {
+ return ((TableColumn) item).getImage();
+ } else if (item instanceof TreeColumn) {
+ return ((TreeColumn) item).getImage();
+ }
+ return null;
+ }
+
+ /**
+ * @return
+ */
+ private int[] getColumnOrder() {
+ if (targetControl instanceof Table) {
+ return ((Table) targetControl).getColumnOrder();
+ } else if (targetControl instanceof Tree) {
+ return ((Tree) targetControl).getColumnOrder();
+ }
+ return new int[0];
+ }
+
+ /**
+ * @param c
+ * @return
+ */
+ private bool getMoveable(Item item) {
+ if (item instanceof TableColumn) {
+ return ((TableColumn) item).getMoveable();
+ } else if (item instanceof TreeColumn) {
+ return ((TreeColumn) item).getMoveable();
+ }
+ return false;
+ }
+
+ /**
+ * @param c
+ * @return
+ */
+ private bool getResizable(Item item) {
+ if (item instanceof TableColumn) {
+ return ((TableColumn) item).getResizable();
+ } else if (item instanceof TreeColumn) {
+ return ((TreeColumn) item).getResizable();
+ }
+ return false;
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite) super.createDialogArea(parent);
+
+ table = new Table(composite, DWT.BORDER | DWT.SINGLE | DWT.V_SCROLL
+ | DWT.H_SCROLL | DWT.FULL_SELECTION /*
+ * | DWT.CHECK
+ */);
+ for (int i = 0; i < columnObjects.length; i++) {
+ TableItem tableItem = new TableItem(table, DWT.NONE);
+ tableItem.setText(columnObjects[i].name);
+ tableItem.setImage(columnObjects[i].image);
+ tableItem.setData(columnObjects[i]);
+ }
+
+ GridDataFactory.defaultsFor(table)
+ .span(1, moveableColumnsFound ? 3 : 1).applyTo(table);
+
+ if (moveableColumnsFound) {
+ upButton = new Button(composite, DWT.PUSH);
+ upButton.setText(JFaceResources
+ .getString("ConfigureColumnsDialog_up")); //$NON-NLS-1$
+ upButton.addListener(DWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ handleMove(table, true);
+ }
+ });
+ setButtonLayoutData(upButton);
+ downButton = new Button(composite, DWT.PUSH);
+ downButton.setText(JFaceResources
+ .getString("ConfigureColumnsDialog_down")); //$NON-NLS-1$
+ downButton.addListener(DWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ handleMove(table, false);
+ }
+ });
+ setButtonLayoutData(downButton);
+
+ // filler label
+ createLabel(composite, ""); //$NON-NLS-1$
+ }
+
+ Composite widthComposite = new Composite(composite, DWT.NONE);
+ createLabel(widthComposite, JFaceResources
+ .getString("ConfigureColumnsDialog_WidthOfSelectedColumn")); //$NON-NLS-1$
+
+ text = new Text(widthComposite, DWT.SINGLE | DWT.BORDER);
+ // see #initializeBounds
+ text.setText(Integer.toString(1000));
+
+ GridLayoutFactory.fillDefaults().numColumns(2).applyTo(widthComposite);
+
+ int numColumns = moveableColumnsFound ? 2 : 1;
+
+ GridDataFactory.defaultsFor(widthComposite).grab(false, false).span(
+ numColumns, 1).applyTo(widthComposite);
+
+ GridLayoutFactory.swtDefaults().numColumns(numColumns).applyTo(
+ composite);
+
+ table.addListener(DWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ handleSelectionChanged(table.indexOf((TableItem) event.item));
+ }
+ });
+ text.addListener(DWT.Modify, new Listener() {
+ public void handleEvent(Event event) {
+ ColumnObject columnObject = columnObjects[table
+ .getSelectionIndex()];
+ if (!columnObject.resizable) {
+ return;
+ }
+ try {
+ int width = Integer.parseInt(text.getText());
+ columnObject.width = width;
+ } catch (NumberFormatException ex) {
+ // ignore for now
+ }
+ }
+ });
+
+ return composite;
+ }
+
+ /**
+ * @param table
+ * @param up
+ */
+ protected void handleMove(Table table, bool up) {
+ int index = table.getSelectionIndex();
+ int newIndex = index + (up ? -1 : 1);
+ if (index < 0 || index >= table.getItemCount()) {
+ return;
+ }
+ ColumnObject columnObject = columnObjects[index];
+ columnObjects[index] = columnObjects[newIndex];
+ columnObjects[newIndex] = columnObject;
+ table.getItem(index).dispose();
+ TableItem newItem = new TableItem(table, DWT.NONE, newIndex);
+ newItem.setText(columnObject.name);
+ newItem.setImage(columnObject.image);
+ newItem.setData(columnObject);
+ table.setSelection(newIndex);
+ handleSelectionChanged(newIndex);
+ }
+
+ private void createLabel(final Composite composite, String string) {
+ Label label = new Label(composite, DWT.NONE);
+ label.setText(string);
+ }
+
+ /**
+ * @param item
+ * @return
+ */
+ private String getColumnName(Item item) {
+ String result = ""; //$NON-NLS-1$
+ if (item instanceof TableColumn) {
+ result = ((TableColumn) item).getText();
+ if (result.trim().equals("")) { //$NON-NLS-1$
+ result = ((TableColumn) item).getToolTipText();
+ }
+ } else if (item instanceof TreeColumn) {
+ result = ((TreeColumn) item).getText();
+ if (result.trim().equals("")) { //$NON-NLS-1$
+ result = ((TreeColumn) item).getToolTipText();
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @param item
+ * @return
+ */
+ private int getColumnWidth(Item item) {
+ if (item instanceof TableColumn) {
+ return ((TableColumn) item).getWidth();
+ } else if (item instanceof TreeColumn) {
+ return ((TreeColumn) item).getWidth();
+ }
+ return 0;
+ }
+
+ /**
+ * @return
+ */
+ private Item[] getViewerColumns() {
+ if (targetControl instanceof Table) {
+ return ((Table) targetControl).getColumns();
+ } else if (targetControl instanceof Tree) {
+ return ((Tree) targetControl).getColumns();
+ }
+ return new Item[0];
+ }
+
+ private void handleSelectionChanged(int index) {
+ ColumnObject c = columnObjects[index];
+ text.setText(Integer.toString(c.width));
+ text.setEnabled(c.resizable);
+ if (moveableColumnsFound) {
+ upButton.setEnabled(c.moveable && index > 0);
+ downButton.setEnabled(c.moveable
+ && index + 1 < table.getItemCount());
+ }
+ }
+
+ protected void okPressed() {
+ int[] columnOrder = new int[columnObjects.length];
+ for (int i = 0; i < columnObjects.length; i++) {
+ ColumnObject columnObject = columnObjects[i];
+ columnOrder[i] = columnObject.index;
+ setColumnWidth(columnObject.column, columnObject.width);
+ }
+ setColumnOrder(columnOrder);
+ super.okPressed();
+ }
+
+ /**
+ * @param column
+ * @param width
+ */
+ private void setColumnWidth(Item item, int width) {
+ if (item instanceof TableColumn) {
+ ((TableColumn) item).setWidth(width);
+ } else if (item instanceof TreeColumn) {
+ ((TreeColumn) item).setWidth(width);
+ }
+ }
+
+ /**
+ * @param columnOrder
+ */
+ private void setColumnOrder(int[] order) {
+ if (targetControl instanceof Table) {
+ ((Table) targetControl).setColumnOrder(order);
+ } else if (targetControl instanceof Tree) {
+ ((Tree) targetControl).setColumnOrder(order);
+ }
+ }
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/layout/AbstractColumnLayout.d
--- a/dwtx/jface/layout/AbstractColumnLayout.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/layout/AbstractColumnLayout.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -8,14 +8,14 @@
* Contributors:
* IBM Corporation - initial API and implementation (original file dwtx.ui.texteditor.templates.ColumnLayout)
* Tom Schindl - refactored to be widget independent (bug 171824)
- * - fix for bug 178280, 184342, 184045
+ * - fix for bug 178280, 184342, 184045, 208014, 214532
+ * Micah Hainline - fix in bug: 208335
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
module dwtx.jface.layout.AbstractColumnLayout;
-
import dwt.DWT;
import dwt.graphics.Point;
import dwt.graphics.Rectangle;
@@ -39,21 +39,24 @@
* in a consistent way even during a resize unlike a {@link TableLayout} which
* only sets initial sizes.
*
- * You can only add the layout to a container whose
- * only child is the table/tree control you want the layouts applied to.
+ *
+ * You can only add the layout to a container whose only child is the
+ * table/tree control you want the layouts applied to.
*
*
- * @since 3.3
+ * @since 3.4
*/
-abstract class AbstractColumnLayout : Layout {
- /**
- * The number of extra pixels taken as horizontal trim by the table column.
- * To ensure there are N pixels available for the content of the column,
- * assign N+COLUMN_TRIM for the column width.
- *
- * @since 3.1
- */
+public abstract class AbstractColumnLayout : Layout {
private static int COLUMN_TRIM;
+ static {
+ if ("win32".equals(DWT.getPlatform())) { //$NON-NLS-1$
+ COLUMN_TRIM = 4;
+ } else if ("carbon".equals(DWT.getPlatform())) { //$NON-NLS-1$
+ COLUMN_TRIM = 24;
+ } else {
+ COLUMN_TRIM = 3;
+ }
+ }
static const bool IS_GTK;
@@ -96,7 +99,7 @@
*/
public void setColumnData(Widget column, ColumnLayoutData data) {
- if( column.getData(LAYOUT_DATA) is null ) {
+ if (column.getData(LAYOUT_DATA) is null) {
column.addListener(DWT.Resize, resizeListener);
}
@@ -122,11 +125,11 @@
int width = 0;
int size = getColumnCount(scrollable);
for (int i = 0; i < size; ++i) {
- ColumnLayoutData layoutData = getLayoutData(scrollable,i);
+ ColumnLayoutData layoutData = getLayoutData(scrollable, i);
if ( auto col = cast(ColumnPixelData)layoutData) {
width += col.width;
if (col.addTrim) {
- width += COLUMN_TRIM;
+ width += getColumnTrim();
}
} else if ( auto col = cast(ColumnWeightData)layoutData ) {
width += col.minimumWidth;
@@ -151,70 +154,62 @@
*/
private void layoutTableTree(Scrollable scrollable, int width,
Rectangle area, bool increase) {
- int size = getColumnCount(scrollable);
- int[] widths = new int[size];
+ int numberOfColumns = getColumnCount(scrollable);
+ int[] widths = new int[numberOfColumns];
- int[] weightIteration = new int[size];
+ int[] weightColumnIndices = new int[numberOfColumns];
int numberOfWeightColumns = 0;
int fixedWidth = 0;
- int minWeightWidth = 0;
int totalWeight = 0;
// First calc space occupied by fixed columns
- for (int i = 0; i < size; i++) {
- ColumnLayoutData col = getLayoutData(scrollable,i);
+ for (int i = 0; i < numberOfColumns; i++) {
+ ColumnLayoutData col = getLayoutData(scrollable, i);
if ( auto cpd = cast(ColumnPixelData)col ) {
int pixels = cpd.width;
if (cpd.addTrim) {
- pixels += COLUMN_TRIM;
+ pixels += getColumnTrim();
}
widths[i] = pixels;
fixedWidth += pixels;
} else if ( auto cw = cast(ColumnWeightData) col ) {
- weightIteration[numberOfWeightColumns] = i;
+ weightColumnIndices[numberOfWeightColumns] = i;
numberOfWeightColumns++;
totalWeight += cw.weight;
- minWeightWidth += cw.minimumWidth;
- widths[i] = cw.minimumWidth;
} else {
Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
}
}
- // Do we have columns that have a weight?
- int restIncludingMinWidths = width - fixedWidth;
- int rest = restIncludingMinWidths - minWeightWidth;
- if (numberOfWeightColumns > 0 && rest > 0) {
-
- // Modify the weights to reflect what each column already
- // has due to its minimum. Otherwise, columns with low
- // minimums get discriminated.
- int totalWantedPixels = 0;
- int[] wantedPixels = new int[numberOfWeightColumns];
+ bool recalculate;
+ do {
+ recalculate = false;
for (int i = 0; i < numberOfWeightColumns; i++) {
- ColumnWeightData cw = cast(ColumnWeightData) getLayoutData(scrollable,weightIteration[i]);
- wantedPixels[i] = totalWeight is 0 ? 0 : cw.weight
- * restIncludingMinWidths / totalWeight;
- totalWantedPixels += wantedPixels[i];
+ int colIndex = weightColumnIndices[i];
+ ColumnWeightData cw = (ColumnWeightData) getLayoutData(
+ scrollable, colIndex);
+ final int minWidth = cw.minimumWidth;
+ final int allowedWidth = (width - fixedWidth) * cw.weight
+ / totalWeight;
+ if (allowedWidth < minWidth) {
+ /*
+ * if the width assigned by weight is less than the minimum,
+ * then treat this column as fixed, remove it from weight
+ * calculations, and recalculate other weights.
+ */
+ numberOfWeightColumns--;
+ totalWeight -= cw.weight;
+ fixedWidth += minWidth;
+ widths[colIndex] = minWidth;
+ System.arraycopy(weightColumnIndices, i + 1,
+ weightColumnIndices, i, numberOfWeightColumns - i);
+ recalculate = true;
+ break;
+ }
+ widths[colIndex] = allowedWidth;
}
-
- // Now distribute the rest to the columns with weight.
- int totalDistributed = 0;
- for (int i = 0; i < numberOfWeightColumns; ++i) {
- int pixels = totalWantedPixels is 0 ? 0 : wantedPixels[i]
- * rest / totalWantedPixels;
- totalDistributed += pixels;
- widths[weightIteration[i]] += pixels;
- }
-
- // Distribute any remaining pixels to columns with weight.
- int diff = rest - totalDistributed;
- for (int i = 0; diff > 0; i = ((i + 1) % numberOfWeightColumns)) {
- ++widths[weightIteration[i]];
- --diff;
- }
- }
+ } while (recalculate);
if (increase) {
scrollable.setSize(area.width, area.height);
@@ -314,7 +309,20 @@
*/
abstract void setColumnWidths(Scrollable tableTree, int[] widths);
- abstract ColumnLayoutData getLayoutData(Scrollable tableTree, int columnIndex);
+ abstract ColumnLayoutData getLayoutData(Scrollable tableTree,
+ int columnIndex);
abstract void updateColumnData(Widget column);
+
+ /**
+ * The number of extra pixels taken as horizontal trim by the table column.
+ * To ensure there are N pixels available for the content of the column,
+ * assign N+COLUMN_TRIM for the column width.
+ *
+ * @return the trim used by the columns
+ * @since 3.4
+ */
+ protected int getColumnTrim() {
+ return COLUMN_TRIM;
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/operation/AccumulatingProgressMonitor.d
--- a/dwtx/jface/operation/AccumulatingProgressMonitor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/operation/AccumulatingProgressMonitor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -126,7 +126,7 @@
synchronized (this) {
collector = null;
}
- display.syncExec(new class(name,totalWork) Runnable {
+ display.asyncExec(new class(name,totalWork) Runnable {
String name_;
int totalWork_;
this(String a, int b){
@@ -170,7 +170,7 @@
synchronized (this) {
collector = null;
}
- display.syncExec(new class Runnable {
+ display.asyncExec(new class Runnable {
public void run() {
getWrappedProgressMonitor().done();
}
@@ -195,7 +195,7 @@
synchronized (this) {
collector = null;
}
- display.syncExec(new class(name) Runnable {
+ display.asyncExec(new class(name) Runnable {
String name_;
this(String a){
name_=a;
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/operation/ModalContext.d
--- a/dwtx/jface/operation/ModalContext.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/operation/ModalContext.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -15,8 +15,11 @@
import dwt.widgets.Display;
import dwtx.core.runtime.Assert;
import dwtx.core.runtime.IProgressMonitor;
+import dwtx.core.runtime.IStatus;
import dwtx.core.runtime.OperationCanceledException;
import dwtx.core.runtime.ProgressMonitorWrapper;
+import dwtx.core.runtime.Status;
+import dwtx.jface.util.Policy;
import dwtx.jface.operation.IThreadListener;
import dwtx.jface.operation.IRunnableWithProgress;
@@ -28,12 +31,12 @@
import tango.io.Stdout;
/**
- * Utility class for supporting modal operations.
- * The runnable passed to the run
method is executed in a
- * separate thread, depending on the value of the passed fork argument.
- * If the runnable is executed in a separate thread then the current thread
- * either waits until the new thread ends or, if the current thread is the
- * UI thread, it polls the DWT event queue and dispatches each event.
+ * Utility class for supporting modal operations. The runnable passed to the
+ * run
method is executed in a separate thread, depending on the
+ * value of the passed fork argument. If the runnable is executed in a separate
+ * thread then the current thread either waits until the new thread ends or, if
+ * the current thread is the UI thread, it polls the DWT event queue and
+ * dispatches each event.
*
* This class is not intended to be subclassed.
*
@@ -41,21 +44,21 @@
public class ModalContext {
/**
- * Indicated whether ModalContext is in debug mode;
- * false
by default.
+ * Indicated whether ModalContext is in debug mode; false
by
+ * default.
*/
private static bool debug_ = true;
/**
- * The number of nested modal runs, or 0 if not inside a modal run.
- * This is global state.
+ * The number of nested modal runs, or 0 if not inside a modal run. This is
+ * global state.
*/
private static int modalLevel = 0;
/**
- * Indicates whether operations should be run in a separate thread.
- * Defaults to true.
- * For internal debugging use, set to false to run operations in the calling thread.
+ * Indicates whether operations should be run in a separate thread. Defaults
+ * to true. For internal debugging use, set to false to run operations in
+ * the calling thread.
*/
private static bool runInSeparateThread = true;
@@ -98,10 +101,13 @@
/**
* Creates a new modal context.
*
- * @param operation the runnable to run
- * @param monitor the progress monitor to use to display progress and receive
- * requests for cancelation
- * @param display the display to be used to read and dispatch events
+ * @param operation
+ * the runnable to run
+ * @param monitor
+ * the progress monitor to use to display progress and
+ * receive requests for cancelation
+ * @param display
+ * the display to be used to read and dispatch events
*/
private this(IRunnableWithProgress operation,
IProgressMonitor monitor, Display display) {
@@ -113,8 +119,8 @@
this.callingThread = Thread.getThis();
}
- /* (non-Javadoc)
- * Method declared on Thread.
+ /*
+ * (non-Javadoc) Method declared on Thread.
*/
public /+override+/ void run2() {
try {
@@ -129,15 +135,21 @@
} catch (RuntimeException e) {
throwable = e;
} catch (ThreadDeath e) {
- // Make sure to propagate ThreadDeath, or threads will never fully terminate
+ // Make sure to propagate ThreadDeath, or threads will never
+ // fully terminate
throw e;
+/
} catch (/+Error+/Exception e) {
throwable = e;
} finally {
- //notify the operation of change of thread of control
+ // notify the operation of change of thread of control
if ( auto tl = cast(IThreadListener)runnable ) {
- tl.threadChange(callingThread);
+ auto exception =
+ invokeThreadListener(tl, callingThread);
+
+ //Forward it if we don't already have one
+ if(exception !is null && throwable is null)
+ throwable = exception;
}
// Make sure that all events in the asynchronous event queue
@@ -163,7 +175,7 @@
public void block() {
if (display is Display.getCurrent()) {
while (continueEventDispatching) {
- // Run the event loop. Handle any uncaught exceptions caused
+ // Run the event loop. Handle any uncaught exceptions caused
// by UI events.
try {
if (!display.readAndDispatch()) {
@@ -171,7 +183,8 @@
}
}
/+
- // ThreadDeath is a normal error when the thread is dying. We must
+ // ThreadDeath is a normal error when the thread is dying.
+ // We must
// propagate it in order for it to properly terminate.
catch (ThreadDeath e) {
throw (e);
@@ -179,8 +192,14 @@
+/
// For all other exceptions, log the problem.
catch (Exception e) {
- Stderr.formatln("Unhandled event loop exception during blocked modal context."); //$NON-NLS-1$
- ExceptionPrintStackTrace(e);
+ Policy
+ .getLog()
+ .log(
+ new Status(
+ IStatus.ERROR,
+ Policy.JFACE,
+ "Unhandled event loop exception during blocked modal context.",//$NON-NLS-1$
+ e));
}
}
} else {
@@ -194,13 +213,15 @@
}
/**
- * Returns whether the first progress monitor is the same as, or
- * a wrapper around, the second progress monitor.
- *
- * @param monitor1 the first progress monitor
- * @param monitor2 the second progress monitor
- * @return true
if the first is the same as, or
- * a wrapper around, the second
+ * Returns whether the first progress monitor is the same as, or a wrapper
+ * around, the second progress monitor.
+ *
+ * @param monitor1
+ * the first progress monitor
+ * @param monitor2
+ * the second progress monitor
+ * @return true
if the first is the same as, or a wrapper
+ * around, the second
* @see ProgressMonitorWrapper
*/
public static bool canProgressMonitorBeUsed(IProgressMonitor monitor1,
@@ -223,19 +244,23 @@
* Checks with the given progress monitor and throws
* InterruptedException
if it has been canceled.
*
- * Code in a long-running operation should call this method
- * regularly so that a request to cancel will be honored.
+ * Code in a long-running operation should call this method regularly so
+ * that a request to cancel will be honored.
*
*
* Convenience for:
+ *
*
* if (monitor.isCanceled())
- * throw new InterruptedException();
+ * throw new InterruptedException();
*
+ *
*
- *
- * @param monitor the progress monitor
- * @exception InterruptedException if cancelling the operation has been requested
+ *
+ * @param monitor
+ * the progress monitor
+ * @exception InterruptedException
+ * if cancelling the operation has been requested
* @see IProgressMonitor#isCanceled()
*/
public static void checkCanceled(IProgressMonitor monitor) {
@@ -245,7 +270,8 @@
}
/**
- * Returns the currently active modal context thread, or null if no modal context is active.
+ * Returns the currently active modal context thread, or null if no modal
+ * context is active.
*/
private static ModalContextThread getCurrentModalContextThread() {
Thread t = Thread.getThis();
@@ -259,13 +285,13 @@
* Returns the modal nesting level.
*
* The modal nesting level increases by one each time the
- * ModalContext.run
method is called within the
- * dynamic scope of another call to ModalContext.run
.
+ * ModalContext.run
method is called within the dynamic scope
+ * of another call to ModalContext.run
.
*
- *
- * @return the modal nesting level, or 0
if
- * this method is called outside the dynamic scope of any
- * invocation of ModalContext.run
+ *
+ * @return the modal nesting level, or 0
if this method is
+ * called outside the dynamic scope of any invocation of
+ * ModalContext.run
*/
public static int getModalLevel() {
return modalLevel;
@@ -274,41 +300,54 @@
/**
* Returns whether the given thread is running a modal context.
*
- * @param thread The thread to be checked
- * @return true
if the given thread is running a modal context, false
if not
+ * @param thread
+ * The thread to be checked
+ * @return true
if the given thread is running a modal
+ * context, false
if not
*/
public static bool isModalContextThread(Thread thread) {
return (cast(ModalContextThread)thread) !is null;
}
/**
- * Runs the given runnable in a modal context, passing it a progress monitor.
+ * Runs the given runnable in a modal context, passing it a progress
+ * monitor.
*
- * The modal nesting level is increased by one from the perspective
- * of the given runnable.
+ * The modal nesting level is increased by one from the perspective of the
+ * given runnable.
*
- *
+ *
* If the supplied operation implements IThreadListener
, it
* will be notified of any thread changes required to execute the operation.
- * Specifically, the operation will be notified of the thread that will call its
- * run
method before it is called, and will be notified of the
- * change of control back to the thread calling this method when the operation
- * completes. These thread change notifications give the operation an
- * opportunity to transfer any thread-local state to the execution thread before
- * control is transferred to the new thread.
- *
- * @param operation the runnable to run
- * @param fork true
if the runnable should run in a separate thread,
- * and false
if in the same thread
- * @param monitor the progress monitor to use to display progress and receive
- * requests for cancelation
- * @param display the display to be used to read and dispatch events
- * @exception InvocationTargetException if the run method must propagate a checked exception,
- * it should wrap it inside an InvocationTargetException
; runtime exceptions and errors are automatically
- * wrapped in an InvocationTargetException
by this method
- * @exception InterruptedException if the operation detects a request to cancel,
- * using IProgressMonitor.isCanceled()
, it should exit by throwing
- * InterruptedException
; this method propagates the exception
+ * Specifically, the operation will be notified of the thread that will call
+ * its run
method before it is called, and will be notified
+ * of the change of control back to the thread calling this method when the
+ * operation completes. These thread change notifications give the operation
+ * an opportunity to transfer any thread-local state to the execution thread
+ * before control is transferred to the new thread.
+ *
+ *
+ * @param operation
+ * the runnable to run
+ * @param fork
+ * true
if the runnable should run in a separate
+ * thread, and false
if in the same thread
+ * @param monitor
+ * the progress monitor to use to display progress and receive
+ * requests for cancelation
+ * @param display
+ * the display to be used to read and dispatch events
+ * @exception InvocationTargetException
+ * if the run method must propagate a checked exception, it
+ * should wrap it inside an
+ * InvocationTargetException
; runtime
+ * exceptions and errors are automatically wrapped in an
+ * InvocationTargetException
by this method
+ * @exception InterruptedException
+ * if the operation detects a request to cancel, using
+ * IProgressMonitor.isCanceled()
, it should
+ * exit by throwing InterruptedException
;
+ * this method propagates the exception
*/
public static void run(IRunnableWithProgress operation, bool fork,
IProgressMonitor monitor, Display display) {
@@ -330,11 +369,19 @@
runInCurrentThread(operation, monitor);
} else {
t = new ModalContextThread(operation, monitor, display);
+ Exception listenerException = null;
if ( auto tl = cast(IThreadListener)operation ) {
- tl.threadChange(t);
+ listenerException = invokeThreadListener(tl, t);
}
- t.start();
- t.block();
+
+ if(listenerException is null){
+ t.start();
+ t.block();
+ }
+ else {
+ if(t.throwable is null)
+ t.throwable = listenerException;
+ }
Exception throwable = t.throwable;
if (throwable !is null) {
if (debug_
@@ -343,8 +390,10 @@
Stderr.formatln("Exception in modal context operation:"); //$NON-NLS-1$
ExceptionPrintStackTrace(throwable);
Stderr.formatln("Called from:"); //$NON-NLS-1$
- // Don't create the InvocationTargetException on the throwable,
- // otherwise it will print its stack trace (from the other thread).
+ // Don't create the InvocationTargetException on the
+ // throwable,
+ // otherwise it will print its stack trace (from the
+ // other thread).
ExceptionPrintStackTrace( new InvocationTargetException(null));
}
if (cast(InvocationTargetException)throwable ) {
@@ -352,7 +401,9 @@
} else if (cast(InterruptedException)throwable ) {
throw cast(InterruptedException) throwable;
} else if (cast(OperationCanceledException)throwable ) {
- // See 1GAN3L5: ITPUI:WIN2000 - ModalContext converts OperationCancelException into InvocationTargetException
+ // See 1GAN3L5: ITPUI:WIN2000 - ModalContext
+ // converts OperationCancelException into
+ // InvocationTargetException
throw new InterruptedException(throwable
.msg);
} else {
@@ -367,8 +418,32 @@
}
/**
- * Run a runnable. Convert all thrown exceptions to
- * either InterruptedException or InvocationTargetException
+ * Invoke the ThreadListener if there are any errors or RuntimeExceptions
+ * return them.
+ *
+ * @param listener
+ * @param switchingThread
+ * the {@link Thread} being switched to
+ */
+ static Throwable invokeThreadListener(IThreadListener listener,
+ Thread switchingThread) {
+ try {
+ listener.threadChange(switchingThread);
+ } catch (ThreadDeath e) {
+ // Make sure to propagate ThreadDeath, or threads will never
+ // fully terminate
+ throw e;
+ } catch (Error e) {
+ return e;
+ }catch (RuntimeException e) {
+ return e;
+ }
+ return null;
+ }
+
+ /**
+ * Run a runnable. Convert all thrown exceptions to either
+ * InterruptedException or InvocationTargetException
*/
private static void runInCurrentThread(IRunnableWithProgress runnable,
IProgressMonitor progressMonitor) {
@@ -384,7 +459,8 @@
throw new InterruptedException();
/+
} catch (ThreadDeath e) {
- // Make sure to propagate ThreadDeath, or threads will never fully terminate
+ // Make sure to propagate ThreadDeath, or threads will never fully
+ // terminate
throw e;
+/
} catch (RuntimeException e) {
@@ -396,21 +472,26 @@
/**
* Sets whether ModalContext is running in debug mode.
- *
- * @param debugMode true
for debug mode,
- * and false
for normal mode (the default)
+ *
+ * @param debugMode
+ * true
for debug mode, and false
+ * for normal mode (the default)
*/
public static void setDebugMode(bool debugMode) {
debug_ = debugMode;
}
/**
- * Sets whether ModalContext may process events (by calling Display.readAndDispatch()
)
- * while running operations. By default, ModalContext will process events while running operations.
- * Use this method to disallow event processing temporarily.
- * @param allowReadAndDispatch true
(the default) if events may be processed while
- * running an operation, false
if Display.readAndDispatch() should not be called
- * from ModalContext.
+ * Sets whether ModalContext may process events (by calling
+ * Display.readAndDispatch()
) while running operations. By
+ * default, ModalContext will process events while running operations. Use
+ * this method to disallow event processing temporarily.
+ *
+ * @param allowReadAndDispatch
+ * true
(the default) if events may be processed
+ * while running an operation, false
if
+ * Display.readAndDispatch() should not be called from
+ * ModalContext.
* @since 3.2
*/
public static void setAllowReadAndDispatch(bool allowReadAndDispatch) {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/preference/ComboFieldEditor.d
--- a/dwtx/jface/preference/ComboFieldEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/preference/ComboFieldEditor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Remy Chi Jian Suen - Bug 214392 missing implementation of ComboFieldEditor.setEnabled
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -210,4 +211,15 @@
fCombo.setText(fEntryNamesAndValues[0][0]);
}
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.preference.FieldEditor#setEnabled(bool,
+ * dwt.widgets.Composite)
+ */
+ public void setEnabled(bool enabled, Composite parent) {
+ super.setEnabled(enabled, parent);
+ getComboBoxControl(parent).setEnabled(enabled);
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/preference/FieldEditorPreferencePage.d
--- a/dwtx/jface/preference/FieldEditorPreferencePage.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/preference/FieldEditorPreferencePage.d Thu May 22 01:36:46 2008 +0200
@@ -358,7 +358,7 @@
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(FieldEditor.IS_VALID)) {
- bool newValue = (cast(ValueWrapperBool) event.getNewValue()).value;
+ bool newValue = (cast(Boolean) event.getNewValue()).booleanValue();
// If the new value is true then we must check all field editors.
// If it is false, then the page is invalid in any case.
if (newValue) {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/preference/FileFieldEditor.d
--- a/dwtx/jface/preference/FileFieldEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/preference/FileFieldEditor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -58,7 +58,7 @@
public this(String name, String labelText, Composite parent) {
this(name, labelText, false, parent);
}
-
+
/**
* Creates a file field editor.
*
@@ -68,14 +68,32 @@
* must be absolute, and false
otherwise
* @param parent the parent of the field editor's control
*/
+ public this(String name, String labelText, bool enforceAbsolute, Composite parent) {
+ this(name, labelText, enforceAbsolute, VALIDATE_ON_FOCUS_LOST, parent);
+ }
+ /**
+ * Creates a file field editor.
+ *
+ * @param name the name of the preference this field editor works on
+ * @param labelText the label text of the field editor
+ * @param enforceAbsolute true
if the file path
+ * must be absolute, and false
otherwise
+ * @param validationStrategy either {@link StringButtonFieldEditor#VALIDATE_ON_KEY_STROKE}
+ * to perform on the fly checking, or {@link StringButtonFieldEditor#VALIDATE_ON_FOCUS_LOST}
+ * (the default) to perform validation only after the text has been typed in
+ * @param parent the parent of the field editor's control.
+ * @since 3.4
+ * @see StringButtonFieldEditor#VALIDATE_ON_KEY_STROKE
+ * @see StringButtonFieldEditor#VALIDATE_ON_FOCUS_LOST
+ */
public this(String name, String labelText,
- bool enforceAbsolute, Composite parent) {
+ bool enforceAbsolute, int validationStrategy, Composite parent) {
init(name, labelText);
this.enforceAbsolute = enforceAbsolute;
setErrorMessage(JFaceResources
.getString("FileFieldEditor.errorMessage"));//$NON-NLS-1$
setChangeButtonText(JFaceResources.getString("openBrowse"));//$NON-NLS-1$
- setValidateStrategy(VALIDATE_ON_FOCUS_LOST);
+ setValidateStrategy(validationStrategy);
createControl(parent);
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/preference/IntegerFieldEditor.d
--- a/dwtx/jface/preference/IntegerFieldEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/preference/IntegerFieldEditor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * - Fix for bug 109389 - IntegerFieldEditor
+ * does not fire property change all the time
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -117,6 +119,7 @@
if (text !is null) {
int value = getPreferenceStore().getInt(getPreferenceName());
text.setText( tango.text.convert.Integer.toString(value));//$NON-NLS-1$
+ oldValue = "" + value; //$NON-NLS-1$
}
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/preference/JFacePreferences.d
--- a/dwtx/jface/preference/JFacePreferences.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/preference/JFacePreferences.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -18,8 +18,8 @@
/**
*
- * JFacePreferences is a class used to administer the preferences
- * used by JFace objects.
+ * JFacePreferences is a class used to administer the preferences used by JFace
+ * objects.
*/
public final class JFacePreferences {
@@ -38,6 +38,50 @@
*/
public static const String ACTIVE_HYPERLINK_COLOR = "ACTIVE_HYPERLINK_COLOR"; //$NON-NLS-1$
+ /**
+ * Identifier for the color used to show extra informations in labels, as a
+ * qualified name. For example in 'Foo.txt - myproject/bar', the qualifier
+ * is '- myproject/bar'.
+ *
+ * @since 3.4
+ */
+ public static final String QUALIFIER_COLOR = "QUALIFIER_COLOR"; //$NON-NLS-1$
+
+ /**
+ * Identifier for the color used to show label decorations For example in
+ * 'Foo.txt [1.16]', the decoration is '[1.16]'.
+ *
+ * @since 3.4
+ */
+ public static final String DECORATIONS_COLOR = "DECORATIONS_COLOR"; //$NON-NLS-1$
+
+ /**
+ * Identifier for the color used to counter informations For example in
+ * 'Foo.txt (2 matches)', the counter information is '(2 matches)'.
+ *
+ * @since 3.4
+ */
+ public static final String COUNTER_COLOR = "COUNTER_COLOR"; //$NON-NLS-1$
+
+
+ /**
+ * Identifier for the color used for the background of content assist
+ * popup dialogs.
+ *
+ * @since 3.4
+ */
+ public static final String CONTENT_ASSIST_BACKGROUND_COLOR = "CONTENT_ASSIST_BACKGROUND_COLOR"; //$NON-NLS-1$
+
+ /**
+ * Identifier for the color used for the foreground of content assist
+ * popup dialogs.
+ *
+ * @since 3.4
+ */
+ public static final String CONTENT_ASSIST_FOREGROUND_COLOR = "CONTENT_ASSIST_FOREGROUND_COLOR"; //$NON-NLS-1$
+
+
+
private static IPreferenceStore preferenceStore;
/**
@@ -48,6 +92,7 @@
/**
* Return the preference store for the receiver.
+ *
* @return IPreferenceStore or null
*/
public static IPreferenceStore getPreferenceStore() {
@@ -56,7 +101,9 @@
/**
* Set the preference store for the receiver.
- * @param store IPreferenceStore
+ *
+ * @param store
+ * IPreferenceStore
*/
public static void setPreferenceStore(IPreferenceStore store) {
preferenceStore = store;
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/preference/PreferenceDialog.d
--- a/dwtx/jface/preference/PreferenceDialog.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/preference/PreferenceDialog.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -80,6 +80,7 @@
import dwtx.jface.viewers.SelectionChangedEvent;
import dwtx.jface.viewers.StructuredSelection;
import dwtx.jface.viewers.TreeViewer;
+import dwtx.jface.viewers.ViewerComparator;
import dwtx.jface.viewers.ViewerFilter;
import dwt.dwthelper.utils;
@@ -231,7 +232,6 @@
minimumPageSize = new Point(400, 400);
pageChangedListeners = new ListenerList();
super(parentShell);
- setShellStyle(getShellStyle() | DWT.RESIZE | DWT.MAX);
preferenceManager = manager;
}
@@ -876,13 +876,12 @@
try {
(cast(IPersistentPreferenceStore) store).save();
} catch (IOException e) {
- MessageDialog
- .openError(
- getShell(),
- JFaceResources.getString("PreferenceDialog.saveErrorTitle"), //$NON-NLS-1$
- JFaceResources
- .format(
- "PreferenceDialog.saveErrorMessage", [ page.getTitle(), e.msg ])); //$NON-NLS-1$
+ String message =JFaceResources.format(
+ "PreferenceDialog.saveErrorMessage", new Object[] { page.getTitle(), e.getMessage() }); //$NON-NLS-1$
+ Policy.getStatusHandler().show(
+ new Status(IStatus.ERROR, Policy.JFACE, message, e),
+ JFaceResources.getString("PreferenceDialog.saveErrorTitle")); //$NON-NLS-1$
+
}
}
}
@@ -1007,7 +1006,10 @@
clearSelectedNode();
String message = JFaceResources.getString("SafeRunnable.errorMessage"); //$NON-NLS-1$
- MessageDialog.openError(getShell(), JFaceResources.getString("Error"), message); //$NON-NLS-1$
+
+ Policy.getStatusHandler().show(
+ new Status(IStatus.ERROR, Policy.JFACE, message, e),
+ JFaceResources.getString("Error")); //$NON-NLS-1$
}
});
@@ -1033,6 +1035,10 @@
IPreferenceNode node = findNodeMatching(getSelectedNodePreference());
if (node is null) {
IPreferenceNode[] nodes = preferenceManager.getRootSubNodes();
+ ViewerComparator comparator = getTreeViewer().getComparator();
+ if (comparator !is null) {
+ comparator.sort(null, nodes);
+ }
ViewerFilter[] filters = getTreeViewer().getFilters();
for (int i = 0; i < nodes.length; i++) {
IPreferenceNode selectedNode = nodes[i];
@@ -1565,4 +1571,13 @@
});
}
}
+
+ /*
+ * (non-Javadoc)
+ * @see dwtx.jface.dialogs.Dialog#isResizable()
+ */
+ protected bool isResizable() {
+ return true;
+ }
+
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/preference/PreferenceManager.d
--- a/dwtx/jface/preference/PreferenceManager.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/preference/PreferenceManager.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Jan-Hendrik Diederich, Bredex GmbH - bug 201052
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -40,6 +41,11 @@
* Post-order means visit the children, and then the root.
*/
public static const int POST_ORDER = 1;
+
+ /**
+ * The id of the root node.
+ */
+ private final static String ROOT_NODE_ID = ""; //$NON-NLS-1$
/**
* The root node.
@@ -58,18 +64,31 @@
* Creates a new preference manager.
*/
public this() {
- this('.');
+ this('.', new PreferenceNode(ROOT_NODE_ID));
+ }
+
+ /**
+ * Creates a new preference manager with the given
+ * path separator.
+ *
+ * @param separatorChar
+ */
+ public PreferenceManager(final char separatorChar) {
+ this(separatorChar, new PreferenceNode(ROOT_NODE_ID));
}
/**
* Creates a new preference manager with the given
- * the path separator.
+ * path separator and root node.
*
* @param separatorChar the separator character
+ * @param rootNode the root node.
+ *
+ * @since 3.4
*/
- public this(char separatorChar) {
- root = new PreferenceNode("");//$NON-NLS-1$
+ public this(final char separatorChar, PreferenceNode rootNode) {
separator = [ separatorChar ];
+ this.root = rootNode;
}
/**
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/preference/PreferencePage.d
--- a/dwtx/jface/preference/PreferencePage.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/preference/PreferencePage.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -35,6 +35,7 @@
import dwtx.jface.dialogs.Dialog;
import dwtx.jface.dialogs.DialogPage;
import dwtx.jface.dialogs.IDialogConstants;
+import dwtx.jface.dialogs.IDialogPage;
import dwtx.jface.resource.ImageDescriptor;
import dwtx.jface.resource.JFaceResources;
import dwtx.jface.util.IPropertyChangeListener;
@@ -217,6 +218,7 @@
* If a subclass that overrides this method creates a Composite
* that has a layout with default margins (for example, a GridLayout
)
* it is expected to set the margins of this Layout
to 0 pixels.
+ * @see IDialogPage#createControl(Composite)
*/
public void createControl(Composite parent){
@@ -398,6 +400,7 @@
* method returns whether this preference page is valid. Preference
* pages are considered valid by default; call setValid(false)
* to make a page invalid.
+ * @see IPreferencePage#isValid()
*/
public bool isValid() {
return isValid_;
@@ -407,7 +410,7 @@
* Suppresses creation of the standard Default and Apply buttons
* for this page.
*
- * Subclasses wishing a preference page wihthout these buttons
+ * Subclasses wishing a preference page without these buttons
* should call this framework method before the page's control
* has been created.
*
@@ -420,6 +423,7 @@
* The PreferencePage
implementation of this
* IPreferencePage
method returns true
* if the page is valid.
+ * @see IPreferencePage#okToLeave()
*/
public bool okToLeave() {
return isValid();
@@ -445,9 +449,10 @@
* method performs special processing when this page's Cancel button has
* been pressed.
*
- * This is a framework hook method for sublcasses to do special things when
+ * This is a framework hook method for subclasses to do special things when
* the Cancel button has been pressed. The default implementation of this
* framework method does nothing and returns true
.
+ * @see IPreferencePage#performCancel()
*/
public bool performCancel() {
return true;
@@ -465,16 +470,17 @@
updateApplyButton();
}
- /**
- * Method declared on IPreferencePage.
- * Subclasses should override
+
+ /* (non-Javadoc)
+ * @see dwtx.jface.preference.IPreferencePage#performOk()
*/
public bool performOk() {
return true;
}
- /** (non-Javadoc)
- * Method declared on IPreferencePage.
+
+ /* (non-Javadoc)
+ * @see dwtx.jface.preference.IPreferencePage#setContainer(dwtx.jface.preference.IPreferencePageContainer)
*/
public void setContainer(IPreferencePageContainer container) {
this.container = container;
@@ -494,8 +500,9 @@
preferenceStore = store;
}
+
/* (non-Javadoc)
- * Method declared on IPreferencePage.
+ * @see dwtx.jface.preference.IPreferencePage#setSize(dwt.graphics.Point)
*/
public void setSize(Point uiSize) {
Control control = getControl();
@@ -509,6 +516,7 @@
* The PreferencePage
implementation of this IDialogPage
* method extends the DialogPage
implementation to update
* the preference page container title. Subclasses may extend.
+ * @see IDialogPage#setTitle(String)
*/
public override void setTitle(String title) {
super.setTitle(title);
@@ -539,8 +547,9 @@
}
}
- /**
- * Returns a string suitable for debugging purpose only.
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
*/
public override String toString() {
return getTitle();
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/preference/StringFieldEditor.d
--- a/dwtx/jface/preference/StringFieldEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/preference/StringFieldEditor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -70,8 +70,9 @@
/**
* Old text value.
+ * @since 3.4 this field is protected.
*/
- private String oldValue;
+ protected String oldValue;
/**
* The text field, or null
if none.
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/resource/ColorRegistry.d
--- a/dwtx/jface/resource/ColorRegistry.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/resource/ColorRegistry.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2006 IBM Corporation and others.
+ * Copyright (c) 2003, 2007 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
@@ -54,6 +54,12 @@
public class ColorRegistry : ResourceRegistry {
/**
+ * Default color value. This is cyan (very unappetizing).
+ * @since 3.4
+ */
+ private static final ColorDescriptor DEFAULT_COLOR = new RGBColorDescriptor(new RGB(0, 255, 255));
+
+ /**
* This registries Display
. All colors will be allocated using
* it.
*/
@@ -199,7 +205,8 @@
* Returns the color data associated with the given symbolic color name.
*
* @param symbolicName symbolic color name.
- * @return the RGB
data.
+ * @return the RGB
data, or null
if the symbolic name
+ * is not valid.
*/
public RGB getRGB(String symbolicName) {
Assert.isNotNull(symbolicName);
@@ -207,17 +214,43 @@
}
/**
- * Returns the color descriptor associated with the given symbolic color name.
+ * Returns the color descriptor associated with the given symbolic color
+ * name. As of 3.4 if this color is not defined then an unspecified color
+ * is returned. Users that wish to ensure a reasonable default value should
+ * use {@link #getColorDescriptor(String, ColorDescriptor)} instead.
+ *
* @since 3.1
- *
+ *
* @param symbolicName
- * @return the color descriptor associated with the given symbolic color name.
+ * @return the color descriptor associated with the given symbolic color
+ * name or an unspecified sentinel.
*/
public ColorDescriptor getColorDescriptor(String symbolicName) {
- return ColorDescriptor.createFrom(getRGB(symbolicName));
+ return getColorDescriptor(symbolicName, DEFAULT_COLOR);
+ }
+
+ /**
+ * Returns the color descriptor associated with the given symbolic color
+ * name. If this name does not exist within the registry the supplied
+ * default value will be used.
+ *
+ * @param symbolicName
+ * @param defaultValue
+ * @return the color descriptor associated with the given symbolic color
+ * name or the default
+ * @since 3.4
+ */
+ public ColorDescriptor getColorDescriptor(String symbolicName,
+ ColorDescriptor defaultValue) {
+ RGB rgb = getRGB(symbolicName);
+ if (rgb is null)
+ return defaultValue;
+ return ColorDescriptor.createFrom(rgb);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.resource.ResourceRegistry#clearCaches()
*/
protected override void clearCaches() {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/resource/FileImageDescriptor.d
--- a/dwtx/jface/resource/FileImageDescriptor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/resource/FileImageDescriptor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -22,7 +22,10 @@
import dwt.DWT;
import dwt.DWTException;
+import dwt.graphics.Device;
+import dwt.graphics.Image;
import dwt.graphics.ImageData;
+import dwtx.core.runtime.Path;
import dwt.dwthelper.utils;
import dwt.dwthelper.InputStream;
@@ -31,16 +34,16 @@
import dwt.dwthelper.ByteArrayInputStream;
import tango.util.log.Trace;
+import tango.text.convert.Format;
/**
- * An image descriptor that loads its image information
- * from a file.
+ * An image descriptor that loads its image information from a file.
*/
class FileImageDescriptor : ImageDescriptor {
/**
- * The class whose resource directory contain the file,
- * or null
if none.
+ * The class whose resource directory contain the file, or null
+ * if none.
*/
// private ClassInfo location;
@@ -51,18 +54,18 @@
private void[] importdata;
/**
- * Creates a new file image descriptor.
- * The file has the given file name and is located
- * in the given class's resource directory. If the given
- * class is null
, the file name must be absolute.
+ * Creates a new file image descriptor. The file has the given file name and
+ * is located in the given class's resource directory. If the given class is
+ * null
, the file name must be absolute.
*
- * Note that the file is not accessed until its
- * getImageDate
method is called.
+ * Note that the file is not accessed until its getImageDate
+ * method is called.
*
- *
- * @param clazz class for resource directory, or
- * null
- * @param filename the name of the file
+ *
+ * @param clazz
+ * class for resource directory, or null
+ * @param filename
+ * the name of the file
*/
this(ImportData importdata) {
// this.location = clazz;
@@ -70,8 +73,8 @@
this.importdata = importdata.data;
}
- /* (non-Javadoc)
- * Method declared on Object.
+ /*
+ * (non-Javadoc) Method declared on Object.
*/
public override int opEquals(Object o) {
if (!( cast(FileImageDescriptor)o )) {
@@ -90,9 +93,11 @@
return importdata == other.importdata;
}
- /* (non-Javadoc)
- * Method declared on ImageDesciptor.
- * Returns null if the image data cannot be read.
+ /**
+ * @see dwtx.jface.resource.ImageDescriptor#getImageData() The
+ * FileImageDescriptor implementation of this method is not used by
+ * {@link ImageDescriptor#createImage(bool, Device)} as of version
+ * 3.4 so that the DWT OS optimised loading can be used.
*/
public override ImageData getImageData() {
InputStream in_ = getStream();
@@ -104,7 +109,7 @@
if (e.code !is DWT.ERROR_INVALID_IMAGE /+&& e.code !is DWT.ERROR_UNSUPPORTED_FORMAT+/) {
Trace.formatln( "FileImageDescriptor getImageData DWTException for name={}", name );
throw e;
- // fall through otherwise
+ // fall through otherwise
}
} finally {
in_.close();
@@ -114,11 +119,11 @@
}
/**
- * Returns a stream on the image contents. Returns
- * null if a stream could not be opened.
+ * Returns a stream on the image contents. Returns null if a stream could
+ * not be opened.
*
- * @return the buffered stream on the file or null
- * if the file cannot be found
+ * @return the buffered stream on the file or null
if the
+ * file cannot be found
*/
private InputStream getStream() {
InputStream is_ = null;
@@ -137,13 +142,13 @@
// }
if (is_ is null) {
return null;
- } else {
- return new BufferedInputStream(is_);
}
+ return new BufferedInputStream(is);
+
}
- /* (non-Javadoc)
- * Method declared on Object.
+ /*
+ * (non-Javadoc) Method declared on Object.
*/
public override hash_t toHash() {
int code = dwt.dwthelper.utils.toHash(cast(char[])importdata/+name+/);
@@ -153,15 +158,77 @@
return code;
}
- /* (non-Javadoc)
- * Method declared on Object.
+ /*
+ * (non-Javadoc) Method declared on Object.
*/
/**
- * The FileImageDescriptor
implementation of this Object
method
- * returns a string representation of this object which is suitable only for debugging.
+ * The FileImageDescriptor
implementation of this
+ * Object
method returns a string representation of this
+ * object which is suitable only for debugging.
*/
public override String toString() {
-// return "FileImageDescriptor(location=" ~ location.toString() ~ ", name=" ~ name ~ ")";//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
- return "FileImageDescriptor()";//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+ return Format("FileImageDescriptor(location={}, name={})", location, name );//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.resource.ImageDescriptor#createImage(bool,
+ * dwt.graphics.Device)
+ */
+ public Image createImage(bool returnMissingImageOnError, Device device) {
+ String path = getFilePath();
+ if (path is null)
+ return createDefaultImage(returnMissingImageOnError, device);
+ try {
+ return new Image(device, path);
+ } catch (DWTException exception) {
+ //if we fail try the default way using a stream
+ }
+ return super.createImage(returnMissingImageOnError, device);
+ }
+
+ /**
+ * Return default image if returnMissingImageOnError is true.
+ *
+ * @param device
+ * @return Image or null
+ */
+ private Image createDefaultImage(bool returnMissingImageOnError,
+ Device device) {
+ try {
+ if (returnMissingImageOnError)
+ return new Image(device, DEFAULT_IMAGE_DATA);
+ } catch (DWTException nextException) {
+ return null;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the filename for the ImageData.
+ *
+ * @return {@link String} or null
if the file cannot be found
+ */
+ private String getFilePath() {
+
+ if (location is null)
+ return new Path(name).toOSString();
+
+ URL resource = location.getResource(name);
+
+ if (resource is null)
+ return null;
+// try {
+// if (JFaceActivator.getBundleContext() is null) {// Stand-alone case
+//
+// return new Path(resource.getFile()).toOSString();
+// }
+// return new Path(FileLocator.toFileURL(resource).getPath()).toOSString();
+ return null;
+// } catch (IOException e) {
+// Policy.logException(e);
+// return null;
+// }
}
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/resource/ImageRegistry.d
--- a/dwtx/jface/resource/ImageRegistry.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/resource/ImageRegistry.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -300,9 +300,10 @@
"ImageRegistry key already in use: " ~ key); //$NON-NLS-1$
}
- // Should be checking for a null image here.
- // Current behavior is that a null image won't be caught until dispose.
+ // Check for a null image here, otherwise the problem won't appear
+ // until dispose.
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=130315
+ Assert.isNotNull(image, "Cannot register a null image."); //$NON-NLS-1$
entry.image = image;
entry.descriptor = new OriginalImageDescriptor(image, manager.getDevice());
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/resource/JFaceResources.d
--- a/dwtx/jface/resource/JFaceResources.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/resource/JFaceResources.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -28,6 +28,7 @@
import dwt.widgets.Display;
import dwtx.core.runtime.Assert;
import dwtx.jface.dialogs.Dialog;
+import dwtx.jface.dialogs.PopupDialog;
import dwtx.jface.dialogs.TitleAreaDialog;
import dwtx.jface.preference.PreferenceDialog;
import dwtx.jface.wizard.Wizard;
@@ -200,6 +201,7 @@
public static ColorRegistry getColorRegistry() {
if (colorRegistry is null) {
colorRegistry = new ColorRegistry();
+ initializeDefaultColors();
}
return colorRegistry;
}
@@ -451,12 +453,18 @@
~ "message_warning.gif", getImportData!( "dwtx.jface.dialogs.images.message_warning.gif")); //$NON-NLS-1$
declareImage(bundle, Dialog.DLG_IMG_MESSAGE_ERROR, ICONS_PATH
~ "message_error.gif", getImportData!( "dwtx.jface.dialogs.images.message_error.gif"));//$NON-NLS-1$ //$NON-NLS-2$
- declareImage(bundle, Dialog.DLG_IMG_HELP, ICONS_PATH
- ~ "help.gif", getImportData!( "dwtx.jface.dialogs.images.help.gif"));//$NON-NLS-1$ //$NON-NLS-2$
+ declareImage(bundle, Dialog.DLG_IMG_HELP,
+ ICONS_PATH ~ "help.gif", getImportData!( "dwtx.jface.dialogs.images.help.gif"));//$NON-NLS-1$ //$NON-NLS-2$
declareImage(bundle, TitleAreaDialog.DLG_IMG_TITLE_BANNER, ICONS_PATH
~ "title_banner.png", getImportData!( "dwtx.jface.dialogs.images.title_banner.gif"));//$NON-NLS-1$ //$NON-NLS-2$
declareImage(bundle, PreferenceDialog.PREF_DLG_TITLE_IMG, ICONS_PATH
~ "pref_dialog_title.gif", getImportData!( "dwtx.jface.preference.images.pref_dialog_title.gif"));//$NON-NLS-1$ //$NON-NLS-2$
+ declareImage(bundle, PopupDialog.POPUP_IMG_MENU, ICONS_PATH
+ ~ "popup_menu.gif", getImportData!( "images/popup_menu.gif"));//$NON-NLS-1$ //$NON-NLS-2$
+ declareImage(
+ bundle,
+ PopupDialog.POPUP_IMG_MENU_DISABLED,
+ ICONS_PATH ~ "popup_menu_disabled.gif", getImportData!( "images/popup_menu_disabled.gif"));//$NON-NLS-1$ //$NON-NLS-2$
}
/**
@@ -482,14 +490,14 @@
private static final void declareImage(Object bundle, String key,
String path, ImportData importdata/+ClassInfo fallback, String fallbackPath+/) {
-
ImageDescriptor descriptor = null;
if (bundle !is null) {
-//FIXME
-// URL url = FileLocator.find((Bundle) bundle, new Path(path), null);
-// if (url !is null)
-// descriptor = ImageDescriptor.createFromURL(url);
+ /*
+ URL url = FileLocator.find((Bundle) bundle, new Path(path), null);
+ if (url !is null)
+ descriptor = ImageDescriptor.createFromURL(url);
+ */
}
// If we failed then load from the backup file
@@ -599,4 +607,12 @@
private this() {
// no-op
}
+
+ /*
+ * Initialize any JFace colors that may not be initialized via a client.
+ */
+ private static void initializeDefaultColors() {
+ // JFace Colors that may not be defined in a workbench theme should be
+ // defined here.
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/resource/StringConverter.d
--- a/dwtx/jface/resource/StringConverter.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/resource/StringConverter.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -556,9 +556,9 @@
if( stok.length < 3 ){
throw new DataFormatException( "not enough values" );
}
- String red = stok[0];
- String green = stok[1];
- String blue = stok[2];
+ String red = stok[0].trim();
+ String green = stok[1].trim();
+ String blue = stok[2].trim();
int rval = 0, gval = 0, bval = 0;
try {
rval = tango.text.convert.Integer.toInt(red);
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/resource/URLImageDescriptor.d
--- a/dwtx/jface/resource/URLImageDescriptor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/resource/URLImageDescriptor.d Thu May 22 01:36:46 2008 +0200
@@ -21,30 +21,41 @@
import dwt.DWT;
import dwt.DWTException;
+import dwt.graphics.Device;
+import dwt.graphics.Image;
import dwt.graphics.ImageData;
+import dwtx.core.runtime.IStatus;
+import dwtx.core.runtime.Status;
+import dwtx.jface.util.Policy;
import dwt.dwthelper.utils;
import dwt.dwthelper.BufferedInputStream;
import dwt.dwthelper.InputStream;
/**
- * An ImageDescriptor that gets its information from a URL.
- * This class is not public API. Use ImageDescriptor#createFromURL
- * to create a descriptor that uses a URL.
+ * An ImageDescriptor that gets its information from a URL. This class is not
+ * public API. Use ImageDescriptor#createFromURL to create a descriptor that
+ * uses a URL.
*/
class URLImageDescriptor : ImageDescriptor {
+ /**
+ * Constant for the file protocol for optimized loading
+ */
+ private static final String FILE_PROTOCOL = "file"; //$NON-NLS-1$
private Uri url;
/**
* Creates a new URLImageDescriptor.
- * @param url The URL to load the image from. Must be non-null.
+ *
+ * @param url
+ * The URL to load the image from. Must be non-null.
*/
this(Uri url) {
this.url = url;
}
- /* (non-Javadoc)
- * Method declared on Object.
+ /*
+ * (non-Javadoc) Method declared on Object.
*/
public override int opEquals(Object o) {
if (!(cast(URLImageDescriptor)o )) {
@@ -53,9 +64,9 @@
return (cast(URLImageDescriptor) o).url.opEquals(this.url) !is 0;
}
- /* (non-Javadoc)
- * Method declared on ImageDesciptor.
- * Returns null if the image data cannot be read.
+ /*
+ * (non-Javadoc) Method declared on ImageDesciptor. Returns null if the
+ * image data cannot be read.
*/
public override ImageData getImageData() {
ImageData result = null;
@@ -68,7 +79,7 @@
} catch (DWTException e) {
if (e.code !is DWT.ERROR_INVALID_IMAGE) {
throw e;
- // fall through otherwise
+ // fall through otherwise
}
}
}
@@ -76,8 +87,9 @@
}
/**
- * Returns a stream on the image contents. Returns
- * null if a stream could not be opened.
+ * Returns a stream on the image contents. Returns null if a stream could
+ * not be opened.
+ *
* @return the stream for loading the data
*/
protected InputStream getStream() {
@@ -93,21 +105,70 @@
+/
}
- /* (non-Javadoc)
- * Method declared on Object.
+ /*
+ * (non-Javadoc) Method declared on Object.
*/
public override hash_t toHash() {
return url.toHash();
}
- /* (non-Javadoc)
- * Method declared on Object.
+ /*
+ * (non-Javadoc) Method declared on Object.
*/
/**
- * The URLImageDescriptor
implementation of this Object
method
- * returns a string representation of this object which is suitable only for debugging.
+ * The URLImageDescriptor
implementation of this
+ * Object
method returns a string representation of this
+ * object which is suitable only for debugging.
*/
public override String toString() {
return "URLImageDescriptor(" ~ url.toString ~ ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
+
+ /**
+ * Returns the filename for the ImageData.
+ *
+ * @return {@link String} or null
if the file cannot be found
+ */
+ private String getFilePath() {
+
+ return null;
+// try {
+// if (JFaceActivator.getBundleContext() is null) {
+// if (FILE_PROTOCOL.equalsIgnoreCase(url.getProtocol()))
+// return new Path(url.getFile()).toOSString();
+// return null;
+// }
+//
+// URL locatedURL = FileLocator.toFileURL(url);
+// if (FILE_PROTOCOL.equalsIgnoreCase(locatedURL.getProtocol()))
+// return new Path(locatedURL.getPath()).toOSString();
+// return null;
+//
+// } catch (IOException e) {
+// Policy.logException(e);
+// return null;
+// }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.resource.ImageDescriptor#createImage(bool,
+ * dwt.graphics.Device)
+ */
+ public Image createImage(bool returnMissingImageOnError, Device device) {
+
+ // Try to see if we can optimize using SWTs file based image support.
+ String path = getFilePath();
+ if (path is null)
+ return super.createImage(returnMissingImageOnError, device);
+
+ try {
+ return new Image(device, path);
+ } catch (DWTException exception) {
+ // If we fail fall back to the slower input stream method.
+ }
+ return super.createImage(returnMissingImageOnError, device);
+ }
+
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/util/Geometry.d
--- a/dwtx/jface/util/Geometry.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/util/Geometry.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 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
@@ -745,13 +745,13 @@
* be the upper-left corner of the rectangle.
*
* @param rectangle rectangle to modify
- * @param newSize new size of the rectangle
+ * @param newLocation new location of the rectangle
*
* @since 3.0
*/
- public static void setLocation(Rectangle rectangle, Point newSize) {
- rectangle.width = newSize.x;
- rectangle.height = newSize.y;
+ public static void setLocation(Rectangle rectangle, Point newLocation) {
+ rectangle.x = newLocation.x;
+ rectangle.y = newLocation.y;
}
/**
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/util/Policy.d
--- a/dwtx/jface/util/Policy.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/util/Policy.d Thu May 22 01:36:46 2008 +0200
@@ -1,10 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * Copyright (c) 2004, 2008 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
* Chris Gross (schtoo@schtoo.com) - support for ILogger added
@@ -15,7 +15,11 @@
module dwtx.jface.util.Policy;
static import dwtx.core.runtime.Assert;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.widgets.Display;
import dwtx.core.runtime.IStatus;
+import dwtx.core.runtime.Status;
import dwtx.jface.dialogs.AnimatorFactory;
import dwtx.jface.dialogs.ErrorSupportProvider;
@@ -40,7 +44,7 @@
/**
* The unique identifier of the JFace plug-in.
*/
- public static const String JFACE = "dwtx.jface";//$NON-NLS-1$
+ public static const String JFACE = "dwtx.jface"; //$NON-NLS-1$
private static ILogger log;
@@ -66,6 +70,8 @@
private static ErrorSupportProvider errorSupportProvider;
+ private static StatusHandler statusHandler;
+
/**
* Returns the dummy log to use if none has been set
*/
@@ -114,6 +120,64 @@
}
/**
+ * Sets the status handler used by JFace to handle statuses.
+ *
+ * @param status
+ * the handler to use, or null
to use the default
+ * one
+ * @since 3.4
+ */
+ public static void setStatusHandler(StatusHandler status) {
+ statusHandler = status;
+ }
+
+ /**
+ * Returns the status handler used by JFace to handle statuses.
+ *
+ * @return the status handler
+ * @since 3.4
+ */
+ public static StatusHandler getStatusHandler() {
+ if (statusHandler is null) {
+ statusHandler = getDummyStatusHandler();
+ }
+ return statusHandler;
+ }
+
+ private static StatusHandler getDummyStatusHandler() {
+ return new StatusHandler() {
+ private SafeRunnableDialog dialog;
+
+ public void show(final IStatus status, String title) {
+ Runnable runnable = new Runnable() {
+ public void run() {
+ if (dialog is null || dialog.getShell().isDisposed()) {
+ dialog = new SafeRunnableDialog(status);
+ dialog.create();
+ dialog.getShell().addDisposeListener(
+ new DisposeListener() {
+ public void widgetDisposed(
+ DisposeEvent e) {
+ dialog = null;
+ }
+ });
+ dialog.open();
+ } else {
+ dialog.addStatus(status);
+ dialog.refresh();
+ }
+ }
+ };
+ if (Display.getCurrent() !is null) {
+ runnable.run();
+ } else {
+ Display.getDefault().asyncExec(runnable);
+ }
+ }
+ };
+ }
+
+ /**
* Return the default comparator used by JFace to sort strings.
*
* @return a default comparator used by JFace to sort strings
@@ -207,11 +271,24 @@
/**
* Return the ErrorSupportProvider for the receiver.
*
- * @return ErrorSupportProvider or null
if this has not been set
+ * @return ErrorSupportProvider or null
if this has not been
+ * set
* @since 3.3
*/
public static ErrorSupportProvider getErrorSupportProvider() {
return errorSupportProvider;
}
+ /**
+ * Log the Exception to the logger.
+ *
+ * @param exception
+ */
+ public static void logException(Exception exception) {
+ getLog().log(
+ new Status(IStatus.ERROR, JFACE, exception
+ .getLocalizedMessage(), exception));
+
+ }
+
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/util/SafeRunnable.d
--- a/dwtx/jface/util/SafeRunnable.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/util/SafeRunnable.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -17,10 +17,6 @@
import dwtx.jface.util.ISafeRunnableRunner;
import dwtx.jface.util.SafeRunnableDialog;
import dwtx.jface.util.Policy;
-
-import dwt.events.DisposeEvent;
-import dwt.events.DisposeListener;
-import dwt.widgets.Display;
import dwtx.core.runtime.ISafeRunnable;
import dwtx.core.runtime.IStatus;
import dwtx.core.runtime.OperationCanceledException;
@@ -32,11 +28,10 @@
/**
* Implements a default implementation of ISafeRunnable. The default
- * implementation of handleException
opens a message dialog.
+ * implementation of handleException
opens a dialog to show any
+ * errors as they accumulate.
*
- * Note: This class can open an error dialog and should not be used
- * outside of the UI Thread.
- *
+ * This may be executed on any thread.
*/
public abstract class SafeRunnable : ISafeRunnable {
@@ -46,8 +41,6 @@
private String message;
- private static SafeRunnableDialog dialog;
-
/**
* Creates a new instance of SafeRunnable with a default error message.
*/
@@ -65,45 +58,23 @@
this.message = message;
}
-
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
*/
public void handleException(Exception e) {
- // Workaround to avoid interactive error dialogs during automated
- // testing
- if (!ignoreErrors) {
- if (message is null)
- message = JFaceResources.getString("SafeRunnable.errorMessage"); //$NON-NLS-1$
+ // Workaround to avoid interactive error dialogs during
+ // automated testing
+ if (ignoreErrors)
+ return;
- Runnable runnable = new class(new Status(IStatus.ERROR, Policy.JFACE, message,e)) Runnable {
- IStatus status;
- this(IStatus a){
- status = a;
- }
- public void run() {
- if (dialog is null || dialog.getShell().isDisposed()) {
- dialog = new SafeRunnableDialog(status);
- dialog.create();
- dialog.getShell().addDisposeListener(
- new class DisposeListener {
- public void widgetDisposed(DisposeEvent e) {
- dialog = null;
- }
- });
- dialog.open();
- } else {
- dialog.addStatus(status);
- dialog.refresh();
- }
- }
- };
- if (Display.getCurrent() !is null) {
- runnable.run();
- } else {
- Display.getDefault().asyncExec(runnable);
- }
- }
+ if (message is null)
+ message = JFaceResources.getString("SafeRunnable.errorMessage"); //$NON-NLS-1$
+
+ Policy.getStatusHandler().show(
+ new Status(IStatus.ERROR, Policy.JFACE, message, e),
+ JFaceResources.getString("SafeRunnable.errorMessage")); //$NON-NLS-1$
}
/**
@@ -173,9 +144,11 @@
private void handleException(ISafeRunnable code, Exception e) {
if (!(cast(OperationCanceledException)e )) {
try {
- Policy.getLog().log(
- new Status(IStatus.ERROR, Policy.JFACE,
- IStatus.ERROR, "Exception occurred", e)); //$NON-NLS-1$
+ Policy.getLog()
+ .log(
+ new Status(IStatus.ERROR, Policy.JFACE,
+ IStatus.ERROR,
+ "Exception occurred", e)); //$NON-NLS-1$
} catch (Exception ex) {
ExceptionPrintStackTrace(e);
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/util/SafeRunnableDialog.d
--- a/dwtx/jface/util/SafeRunnableDialog.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/util/SafeRunnableDialog.d Thu May 22 01:36:46 2008 +0200
@@ -41,7 +41,7 @@
/**
* SafeRunnableDialog is a dialog that can show the results of multiple safe
- * runnable errors
+ * runnable errors.
*
*/
class SafeRunnableDialog : ErrorDialog {
@@ -61,7 +61,7 @@
super(null, JFaceResources.getString("error"), status.getMessage(), //$NON-NLS-1$
status, IStatus.ERROR);
statuses = new ArraySeq!(IStatus);
- setShellStyle(DWT.DIALOG_TRIM | DWT.MODELESS | DWT.RESIZE | DWT.MIN
+ setShellStyle(DWT.DIALOG_TRIM | DWT.MODELESS | DWT.RESIZE | DWT.MIN | DWT.MAX
| getDefaultOrientation());
setStatus(status);
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/util/StatusHandler.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/util/StatusHandler.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * Port to the D programming language:
+ * Frank Benoit
+ ******************************************************************************/
+
+module dwtx.jface.util.StatusHandler;
+
+import dwtx.core.runtime.IStatus;
+
+/**
+ * A mechanism to handle statuses throughout JFace.
+ *
+ * Clients may provide their own implementation to change how statuses are
+ * handled from within JFace.
+ *
+ *
+ * @see dwtx.jface.util.Policy#getStatusHandler()
+ * @see dwtx.jface.util.Policy#setStatusHandler(StatusHandler)
+ *
+ * @since 3.4
+ */
+abstract public class StatusHandler {
+
+ /**
+ * Show the given status.
+ *
+ * @param status
+ * status to handle
+ * @param title
+ * title for the status
+ */
+ abstract public void show(IStatus status, String title);
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/util/Util.d
--- a/dwtx/jface/util/Util.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/util/Util.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -498,6 +498,43 @@
return defaultString;
}
+
+ /**
+ * Foundation replacement for String.replaceAll(*).
+ *
+ * @param src the starting string.
+ * @param find the string to find.
+ * @param replacement the string to replace.
+ * @return The new string.
+ * @since 3.4
+ */
+ public static final String replaceAll(String src, String find, String replacement) {
+ final int len = src.length();
+ final int findLen = find.length();
+
+ int idx = src.indexOf(find);
+ if (idx < 0) {
+ return src;
+ }
+
+ StringBuffer buf = new StringBuffer();
+ int beginIndex = 0;
+ while (idx !is -1 && idx < len) {
+ buf.append(src.substring(beginIndex, idx));
+ buf.append(replacement);
+
+ beginIndex = idx + findLen;
+ if (beginIndex < len) {
+ idx = src.indexOf(find, beginIndex);
+ } else {
+ idx = -1;
+ }
+ }
+ if (beginIndex - initial API and implementation (bug 174739)
+ * Port to the D programming language:
+ * Frank Benoit
+ ******************************************************************************/
+
+module dwtx.jface.viewers.AbstractComboBoxCellEditor;
+
+import dwt.DWT;
+import dwt.custom.CCombo;
+import dwt.widgets.Composite;
+
+/**
+ * Abstract base class for Cell-Editors presented as combo boxes
+ *
+ * @since 3.4
+ *
+ */
+abstract class AbstractComboBoxCellEditor extends CellEditor {
+ /**
+ * The list is dropped down when the activation is done through the mouse
+ */
+ public static final int DROP_DOWN_ON_MOUSE_ACTIVATION = 1;
+
+ /**
+ * The list is dropped down when the activation is done through the keyboard
+ */
+ public static final int DROP_DOWN_ON_KEY_ACTIVATION = 1 << 1;
+
+ /**
+ * The list is dropped down when the activation is done without
+ * ui-interaction
+ */
+ public static final int DROP_DOWN_ON_PROGRAMMATIC_ACTIVATION = 1 << 2;
+
+ /**
+ * The list is dropped down when the activation is done by traversing from
+ * cell to cell
+ */
+ public static final int DROP_DOWN_ON_TRAVERSE_ACTIVATION = 1 << 3;
+
+ private int activationStyle = DWT.NONE;
+
+ /**
+ * Create a new cell-editor
+ *
+ * @param parent
+ * the parent of the combo
+ * @param style
+ * the style used to create the combo
+ */
+ AbstractComboBoxCellEditor(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ /**
+ * Creates a new cell editor with no control and no st of choices.
+ * Initially, the cell editor has no cell validator.
+ *
+ */
+ AbstractComboBoxCellEditor() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.CellEditor#activate(dwtx.jface.viewers.ColumnViewerEditorActivationEvent)
+ */
+ public void activate(ColumnViewerEditorActivationEvent activationEvent) {
+ super.activate(activationEvent);
+ if (activationStyle !is DWT.NONE) {
+ bool dropDown = false;
+ if ((activationEvent.eventType is ColumnViewerEditorActivationEvent.MOUSE_CLICK_SELECTION || activationEvent.eventType is ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION)
+ && (activationStyle & DROP_DOWN_ON_MOUSE_ACTIVATION) !is 0 ) {
+ dropDown = true;
+ } else if (activationEvent.eventType is ColumnViewerEditorActivationEvent.KEY_PRESSED
+ && (activationStyle & DROP_DOWN_ON_KEY_ACTIVATION) !is 0 ) {
+ dropDown = true;
+ } else if (activationEvent.eventType is ColumnViewerEditorActivationEvent.PROGRAMMATIC
+ && (activationStyle & DROP_DOWN_ON_PROGRAMMATIC_ACTIVATION) !is 0) {
+ dropDown = true;
+ } else if (activationEvent.eventType is ColumnViewerEditorActivationEvent.TRAVERSAL
+ && (activationStyle & DROP_DOWN_ON_TRAVERSE_ACTIVATION) !is 0) {
+ dropDown = true;
+ }
+
+ if (dropDown) {
+ getControl().getDisplay().asyncExec(new Runnable() {
+
+ public void run() {
+ ((CCombo) getControl()).setListVisible(true);
+ }
+
+ });
+
+ }
+ }
+ }
+
+ /**
+ * This method allows to control how the combo reacts when activated
+ *
+ * @param activationStyle
+ * the style used
+ */
+ public void setActivationStyle(int activationStyle) {
+ this.activationStyle = activationStyle;
+ }
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/AbstractListViewer.d
--- a/dwtx/jface/viewers/AbstractListViewer.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/AbstractListViewer.d Thu May 22 01:36:46 2008 +0200
@@ -264,11 +264,6 @@
}
}
- /* (non-Javadoc)
- * Method declared on Viewer.
- */
- public override abstract Control getControl();
-
/**
* Returns the element with the given index from this list viewer.
* Returns null
if the index is out of range.
@@ -385,24 +380,28 @@
topIndex = listGetTopIndex();
}
+ Object[] children = null;
list.setRedraw(false);
- listRemoveAll();
-
- Object[] children = getSortedChildren(getRoot());
- String[] items = new String[children.length];
-
- ILabelProvider labelProvider = cast(ILabelProvider) getLabelProvider();
-
- for (int i = 0; i < items.length; i++) {
- Object el = children[i];
- items[i] = getLabelProviderText(labelProvider, el);
- listMap.append(el);
- mapElement(el, list); // must map it, since findItem only looks in map, if enabled
+ try {
+ listRemoveAll();
+
+ children = getSortedChildren(getRoot());
+ String[] items = new String[children.length];
+
+ ILabelProvider labelProvider = cast(ILabelProvider) getLabelProvider();
+
+ for (int i = 0; i < items.length; i++) {
+ Object el = children[i];
+ items[i] = getLabelProviderText(labelProvider, el);
+ listMap.append(el);
+ mapElement(el, list); // must map it, since findItem only looks in map, if enabled
+ }
+
+ listSetItems(items);
+ } finally {
+ list.setRedraw(true);
}
- listSetItems(items);
- list.setRedraw(true);
-
if (topIndex is -1) {
setSelectionToWidget(selection, false);
} else {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/AbstractTableViewer.d
--- a/dwtx/jface/viewers/AbstractTableViewer.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/AbstractTableViewer.d Thu May 22 01:36:46 2008 +0200
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - initial API and implementation bug 154329
- * - fixes in bug 170381, 198665
+ * - fixes in bug 170381, 198665, 200731
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -257,7 +257,7 @@
*/
public void add(Object[] elements) {
assertElementsNotNull(elements);
- if (isBusy())
+ if (checkBusy())
return;
Object[] filtered = filter(elements);
@@ -357,8 +357,8 @@
* java.lang.Object, bool)
*/
protected override void doUpdateItem(Widget widget, Object element, bool fullMap) {
- bool oldBusy = busy;
- busy = true;
+ bool oldBusy = isBusy();
+ setBusy(true);
try {
if ( auto item = cast(Item)widget ) {
@@ -415,7 +415,7 @@
}
} finally {
- busy = oldBusy;
+ setBusy(oldBusy);
}
}
@@ -622,7 +622,7 @@
if (position is -1) {
position = doGetItemCount();
}
- if (isBusy())
+ if (checkBusy())
return;
createItem(element, position);
}
@@ -768,12 +768,12 @@
Object input = getInput();
for (int i = 0; i < elements.length; ++i) {
if (opEquals(elements[i], input)) {
- bool oldBusy = busy;
- busy = false;
+ bool oldBusy = isBusy();
+ setBusy(false);
try {
setInput(null);
} finally {
- busy = oldBusy;
+ setBusy(oldBusy);
}
return;
}
@@ -823,7 +823,7 @@
*/
public void remove( Object[] elements) {
assertElementsNotNull(elements);
- if (isBusy())
+ if (checkBusy())
return;
if (elements.length is 0) {
return;
@@ -1000,7 +1000,8 @@
if (count < size) {
System.arraycopy(indices, 0, indices = new int[count], 0, count);
}
- doSetSelection(indices);
+ doDeselectAll();
+ doSelect(indices);
if (reveal && firstItem !is null) {
doShowItem(firstItem);
@@ -1016,7 +1017,7 @@
* @since 3.1
*/
public void setItemCount(int count) {
- if (isBusy())
+ if (checkBusy())
return;
int oldCount = doGetItemCount();
if (count < oldCount) {
@@ -1048,7 +1049,7 @@
* @since 3.1
*/
public void replace(Object element, int index) {
- if (isBusy())
+ if (checkBusy())
return;
Item item = doGetItem(index);
refreshItem(item, element);
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/AbstractTreeViewer.d
--- a/dwtx/jface/viewers/AbstractTreeViewer.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/AbstractTreeViewer.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -8,6 +8,11 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - bug 153993, bug 167323, bug 175192
+ * Lasse Knudsen, bug 205700
+ * Micah Hainline, bug 210448
+ * Michael Schneider, bug 210747
+ * Bruce Sutton, bug 221768
+ * Matthew Hall, bug 221988
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -160,7 +165,7 @@
public void add(Object parentElementOrTreePath, Object[] childElements) {
Assert.isNotNull(parentElementOrTreePath);
assertElementsNotNull(childElements);
- if (isBusy())
+ if (checkBusy())
return;
Widget[] widgets = internalFindItems(parentElementOrTreePath);
// If parent hasn't been realized yet, just ignore the add.
@@ -346,10 +351,6 @@
TreePath parentPath = internalGetSorterParentPath(widget, comparator);
Item[] items = getChildren(widget);
- // As the items are sorted already we optimize for a
- // start position
- int lastInsertion = 0;
-
// Optimize for the empty case
if (items.length is 0) {
for (int i = 0; i < elements.length; i++) {
@@ -358,49 +359,69 @@
return;
}
- for (int i = 0; i < elements.length; i++) {
- bool newItem = true;
- Object element = elements[i];
- int index;
- if (comparator is null) {
+ // Optimize for no comparator
+ if (comparator is null) {
+ for (int i = 0; i < elements.length; i++) {
+ Object element = elements[i];
if (itemExists(items, element)) {
internalRefresh(element);
- newItem = false;
- }
- index = -1;
- } else {
- lastInsertion = insertionPosition(items, comparator,
- lastInsertion, element, parentPath);
- // As we are only searching the original array we keep track of
- // those positions only
- if (lastInsertion is items.length) {
- index = -1;
- } else {// See if we should just refresh
- while (lastInsertion < items.length
- && internalCompare(comparator, parentPath, element,
- items[lastInsertion].getData()) is 0) {
- // As we cannot assume the sorter is consistent with
- // equals() - therefore we can
- // just check against the item prior to this index (if
- // any)
- if (items[lastInsertion].getData().opEquals(element)) {
- // refresh the element in case it has new children
- internalRefresh(element);
- newItem = false;
- }
- lastInsertion++;// We had an insertion so increment
- }
- // Did we get to the end?
- if (lastInsertion is items.length) {
- index = -1;
- } else {
- index = lastInsertion + i; // Add the index as the
- // array is growing
- }
+ } else {
+ createTreeItem(widget, element, -1);
}
}
- if (newItem) {
- createTreeItem(widget, element, index);
+ return;
+ }
+ // As the items are sorted already we optimize for a
+ // start position. This is the insertion position relative to the
+ // original item array.
+ int indexInItems = 0;
+
+ // Count of elements we have added. See bug 205700 for why this is needed.
+ int newItems = 0;
+
+ elementloop: for (int i = 0; i < elements.length; i++) {
+ Object element = elements[i];
+ // update the index relative to the original item array
+ indexInItems = insertionPosition(items, comparator,
+ indexInItems, element, parentPath);
+ if (indexInItems is items.length) {
+ createTreeItem(widget, element, -1);
+ newItems++;
+ } else {
+ // Search for an item for the element. The comparator might
+ // regard elements as equal when they are not.
+
+ // Use a separate index variable to search within the existing
+ // elements that compare equally, see
+ // TreeViewerTestBug205700.testAddEquallySortedElements.
+ int insertionIndexInItems = indexInItems;
+ while( insertionIndexInItems < items.length
+ && internalCompare(comparator, parentPath, element,
+ items[insertionIndexInItems].getData()) is 0) {
+ // As we cannot assume the sorter is consistent with
+ // equals() - therefore we can
+ // just check against the item prior to this index (if
+ // any)
+ if (items[insertionIndexInItems].getData().opEquals(element)) {
+ // Found the item for the element.
+ // Refresh the element in case it has new children.
+ internalRefresh(element);
+ // Do not create a new item - continue with the next element.
+ continue elementloop;
+ }
+ insertionIndexInItems++;
+ }
+ // Did we get to the end?
+ if (insertionIndexInItems is items.length) {
+ createTreeItem(widget, element, -1);
+ newItems++;
+ } else {
+ // InsertionIndexInItems is the index in the original array. We
+ // need to correct by the number of new items we have
+ // created. See bug 205700.
+ createTreeItem(widget, element, insertionIndexInItems + newItems);
+ newItems++;
+ }
}
}
}
@@ -769,8 +790,8 @@
* the widget
*/
protected void createChildren(Widget widget) {
- bool oldBusy = busy;
- busy = true;
+ bool oldBusy = isBusy();
+ setBusy(true);
try {
Item[] tis = getChildren(widget);
if (tis !is null && tis.length > 0) {
@@ -819,7 +840,7 @@
});
} finally {
- busy = oldBusy;
+ setBusy(oldBusy);
}
}
@@ -1002,8 +1023,8 @@
/* (non-Javadoc) Method declared on StructuredViewer. */
protected override void doUpdateItem(Widget widget, Object element, bool fullMap) {
- bool oldBusy = busy;
- busy = true;
+ bool oldBusy = isBusy();
+ setBusy(true);
try {
if ( auto item = cast(Item)widget ) {
@@ -1023,7 +1044,7 @@
SafeRunnable.run(new UpdateItemSafeRunnable(item, element));
}
} finally {
- busy = oldBusy;
+ setBusy(oldBusy);
}
}
@@ -1058,7 +1079,7 @@
* levels of the tree
*/
public void expandToLevel(Object elementOrTreePath, int level) {
- if (isBusy())
+ if (checkBusy())
return;
Widget w = internalExpand(elementOrTreePath, true);
if (w !is null) {
@@ -1076,18 +1097,24 @@
*/
protected void fireTreeCollapsed(TreeExpansionEvent event) {
Object[] listeners = treeListeners.getListeners();
- for (int i = 0; i < listeners.length; ++i) {
- SafeRunnable.run(new class(event,cast(ITreeViewerListener) listeners[i]) SafeRunnable {
- TreeExpansionEvent event_;
- ITreeViewerListener l;
- this(TreeExpansionEvent a,ITreeViewerListener b){
- event_=a;
- l = b;
- }
- public void run() {
- l.treeCollapsed(event_);
- }
- });
+ bool oldBusy = isBusy();
+ setBusy(true);
+ try {
+ for (int i = 0; i < listeners.length; ++i) {
+ SafeRunnable.run(new class(event,cast(ITreeViewerListener) listeners[i]) SafeRunnable {
+ TreeExpansionEvent event_;
+ ITreeViewerListener l;
+ this(TreeExpansionEvent a,ITreeViewerListener b){
+ event_=a;
+ l = b;
+ }
+ public void run() {
+ l.treeCollapsed(event_);
+ }
+ });
+ }
+ } finally {
+ setBusy(oldBusy);
}
}
@@ -1101,20 +1128,25 @@
*/
protected void fireTreeExpanded(TreeExpansionEvent event) {
Object[] listeners = treeListeners.getListeners();
- for (int i = 0; i < listeners.length; ++i) {
- SafeRunnable.run(new class( event, cast(ITreeViewerListener) listeners[i]) SafeRunnable {
- TreeExpansionEvent event_;
- ITreeViewerListener l;
- this(TreeExpansionEvent a,ITreeViewerListener b){
- event_=a;
- l = b;
- }
- public void run() {
- l.treeExpanded(event_);
- }
- });
+ bool oldBusy = isBusy();
+ setBusy(true);
+ try {
+ for (int i = 0; i < listeners.length; ++i) {
+ SafeRunnable.run(new class( event, cast(ITreeViewerListener) listeners[i]) SafeRunnable {
+ TreeExpansionEvent event_;
+ ITreeViewerListener l;
+ this(TreeExpansionEvent a,ITreeViewerListener b){
+ event_=a;
+ l = b;
+ }
+ public void run() {
+ l.treeExpanded(event_);
+ }
+ });
+ }
+ } finally {
+ setBusy(oldBusy);
}
-
}
/**
@@ -1323,8 +1355,8 @@
/* (non-Javadoc) Method declared on StructuredViewer. */
protected override Object[] getRawChildren(Object parentElementOrTreePath) {
- bool oldBusy = busy;
- busy = true;
+ bool oldBusy = isBusy();
+ setBusy(true);
try {
Object parent;
TreePath path;
@@ -1364,7 +1396,7 @@
}
return null;
} finally {
- busy = oldBusy;
+ setBusy(oldBusy);
}
}
@@ -1475,20 +1507,15 @@
preservingSelection(new class Runnable {
public void run() {
Control tree = getControl();
- bool useRedraw = true;
- // (size > REDRAW_THRESHOLD) || (table.getItemCount() >
- // REDRAW_THRESHOLD);
- if (useRedraw) {
- tree.setRedraw(false);
- }
- removeAll(tree);
- tree.setData(getRoot());
- internalInitializeTree(tree);
- if (useRedraw) {
+ tree.setRedraw(false);
+ try {
+ removeAll(tree);
+ tree.setData(getRoot());
+ internalInitializeTree(tree);
+ } finally {
tree.setRedraw(true);
}
}
-
});
}
@@ -1645,7 +1672,7 @@
TreePath[] paths = tpcp.getParents(elementOrTreePath);
if (paths.length > 0) {
if (paths[0].getSegmentCount() is 0) {
- return getInput();
+ return getRoot();
}
return paths[0].getLastSegment();
}
@@ -1896,11 +1923,28 @@
return;
}
Widget[] childItems = internalFindItems(element);
- for (int j = 0; j < childItems.length; j++) {
- Widget childItem = childItems[j];
- if ( auto it = cast(Item)childItem ) {
- disassociate(it);
- childItem.dispose();
+ if (childItems.length > 0) {
+ for (int j = 0; j < childItems.length; j++) {
+ Widget childItem = childItems[j];
+ if ( auto it = cast(Item)childItem ) {
+ disassociate(it);
+ childItem.dispose();
+ }
+ }
+ } else {
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=210747
+ Object parent = getParentElement(element);
+ if (parent !is null
+ && !equals(parent, getRoot())
+ && !(parent instanceof TreePath && ((TreePath) parent)
+ .getSegmentCount() is 0)) {
+ Widget[] parentItems = internalFindItems(parent);
+ for (int j = 0; j < parentItems.length; j++) {
+ Widget parentItem = parentItems[j];
+ if (parentItem instanceof Item) {
+ updatePlus((Item) parentItem, parent);
+ }
+ }
}
}
}
@@ -1927,16 +1971,27 @@
for (int i = 0; i < parentItemArray.length; i++) {
Widget parentItem = parentItemArray[i];
+ // May happen if parent element is a descendent of of a previously
+ // removed element
+ if (parentItem.isDisposed())
+ continue;
+
// Iterate over the child items and remove each one
Item[] children = getChildren(parentItem);
- for (int j = 0; j < children.length; j++) {
- Item child = children[j];
+ if (children.length is 1 && children[0].getData() is null &&
+ parentItem instanceof Item) { // dummy node
+ // Remove plus if parent element has no children
+ updatePlus((Item) parentItem, parent);
+ } else {
+ for (int j = 0; j < children.length; j++) {
+ Item child = children[j];
- Object data = child.getData();
- if (data !is null && toRemove.containsKey(data)) {
- disassociate(child);
- child.dispose();
+ Object data = child.getData();
+ if (data !is null && toRemove.containsKey(data)) {
+ disassociate(child);
+ child.dispose();
+ }
}
}
}
@@ -2119,7 +2174,7 @@
if (elementsOrTreePaths.length is 0) {
return;
}
- if (isBusy())
+ if (checkBusy())
return;
preservingSelection(new class(elementsOrTreePaths) Runnable {
Object[] elementsOrTreePaths_;
@@ -2155,7 +2210,7 @@
if (elements.length is 0) {
return;
}
- if (isBusy())
+ if (checkBusy())
return;
preservingSelection(new class(parent,elements) Runnable {
Object parent_;
@@ -2258,14 +2313,22 @@
}
/**
- * Sets the auto-expand level. The value 0 means that there is no
- * auto-expand; 1 means that top-level elements are expanded, but not their
- * children; 2 means that top-level elements are expanded, and their
- * children, but not grandchildren; and so on.
+ * Sets the auto-expand level to be used when the input of the viewer is set
+ * using {@link #setInput(Object)}. The value 0 means that there is no
+ * auto-expand; 1 means that the invisible root element is expanded (since
+ * most concrete subclasses do not show the root element, there is usually
+ * no practical difference between using the values 0 and 1); 2 means that
+ * top-level elements are expanded, but not their children; 3 means that
+ * top-level elements are expanded, and their children, but not
+ * grandchildren; and so on.
*
* The value ALL_LEVELS
means that all subtrees should be
* expanded.
*
+ *
+ * Note that in previous releases, the Javadoc for this method had an off-by
+ * one error. See bug 177669 for details.
+ *
*
* @param level
* non-negative level, or ALL_LEVELS
to expand all
@@ -2315,7 +2378,7 @@
*/
public void setExpandedElements(Object[] elements) {
assertElementsNotNull(elements);
- if (isBusy()) {
+ if (checkBusy()) {
return;
}
CustomHashtable expandedElements = newHashtable(elements.length * 2 + 1);
@@ -2352,7 +2415,7 @@
*/
public void setExpandedTreePaths(TreePath[] treePaths) {
assertElementsNotNull(treePaths);
- if (isBusy())
+ if (checkBusy())
return;
IElementComparer treePathComparer = new class(getComparer()) IElementComparer {
IElementComparer comparer;
@@ -2398,7 +2461,7 @@
*/
public void setExpandedState(Object elementOrTreePath, bool expanded) {
Assert.isNotNull(elementOrTreePath);
- if (isBusy())
+ if (checkBusy())
return;
Widget item = internalExpand(elementOrTreePath, false);
if ( cast(Item)item ) {
@@ -2452,10 +2515,14 @@
// Although setting the selection in the control should reveal it,
// setSelection may be a no-op if the selection is unchanged,
- // so explicitly reveal the first item in the selection here.
+ // so explicitly reveal items in the selection here.
// See bug 100565 for more details.
if (reveal && newSelection.size() > 0) {
- showItem(cast(Item) newSelection.get(0));
+ // Iterate backwards so the first item in the list
+ // is the one guaranteed to be visible
+ for (int i = (newSelection.size()-1); i >= 0; i--) {
+ showItem(cast(Item) newSelection.get(i));
+ }
}
}
@@ -2552,8 +2619,8 @@
oldCnt = getItemCount(tree);
}
- Item[] items = getChildren(widget);
-
+ Item[] items = getChildren(widget,elementChildren);
+
// save the expanded elements
CustomHashtable expanded = newHashtable(CustomHashtable.DEFAULT_CAPACITY); // assume
// num
@@ -2700,6 +2767,20 @@
}
/**
+ * Return the items to be refreshed as part of an update. elementChildren are the
+ * new elements.
+ * @param widget
+ * @param elementChildren
+ * @since 3.4
+ * @return Item[]
+ * NOTE: This API is experimental and may be deleted
+ * before 3.4 is released.
+ */
+ public Item[] getChildren(Widget widget, Object[] elementChildren) {
+ return getChildren(widget);
+ }
+
+ /**
* Updates the "+"/"-" icon of the tree node from the given element. It
* calls isExpandable
to determine whether an element is
* expandable.
@@ -2891,7 +2972,7 @@
int position) {
Assert.isNotNull(parentElementOrTreePath);
Assert.isNotNull(element);
- if (isBusy())
+ if (checkBusy())
return;
if (getComparator() !is null || hasFilters()) {
add(parentElementOrTreePath, [ element ]);
@@ -2918,6 +2999,11 @@
}
createTreeItem(item, element, insertionPosition);
+ } else {
+ Object parentElement = parentElementOrTreePath;
+ if (element instanceof TreePath)
+ parentElement = ((TreePath) parentElement).getLastSegment();
+ updatePlus(item, parentElement);
}
} else {
int insertionPosition = position;
@@ -3010,7 +3096,7 @@
* @since 3.3
*/
final protected bool internalIsInputOrEmptyPath(Object elementOrTreePath) {
- if (elementOrTreePath.opEquals(getInput()))
+ if (elementOrTreePath.opEquals(getRoot()))
return true;
if (!(cast(TreePath)elementOrTreePath ))
return false;
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/CellEditor.d
--- a/dwtx/jface/viewers/CellEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/CellEditor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Tom Schindl - bugfix in: 187963, 218336
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -21,6 +22,7 @@
import dwt.events.KeyEvent;
import dwt.widgets.Composite;
import dwt.widgets.Control;
+import dwt.widgets.Display;
import dwtx.core.runtime.Assert;
import dwtx.core.runtime.ListenerList;
import dwtx.jface.util.IPropertyChangeListener;
@@ -30,8 +32,8 @@
import dwt.dwthelper.utils;
/**
- * Struct-like layout data for cell editors, with reasonable defaults
- * for all fields.
+ * Struct-like layout data for cell editors, with reasonable defaults for
+ * all fields.
*/
public static class LayoutData {
/**
@@ -40,7 +42,8 @@
public int horizontalAlignment = DWT.LEFT;
/**
- * Indicates control grabs additional space; true
by default.
+ * Indicates control grabs additional space; true
by
+ * default.
*/
public bool grabHorizontal = true;
@@ -48,32 +51,45 @@
* Minimum width in pixels; 50
pixels by default.
*/
public int minimumWidth = 50;
+
+ /**
+ * Minimum height in pixels; by default the height is aligned to the
+ * row-height
+ */
+ public int minimumHeight = DWT.DEFAULT;
+
+ /**
+ * The vertical alignment; DWT.CENTER
by default.
+ */
+ public int verticalAlignment = DWT.CENTER;
}
/**
- * Abstract base class for cell editors. Implements property change listener handling,
- * and DWT window management.
+ * Abstract base class for cell editors. Implements property change listener
+ * handling, and DWT window management.
*
- * Subclasses implement particular kinds of cell editors. This package contains various
- * specialized cell editors:
+ * Subclasses implement particular kinds of cell editors. This package contains
+ * various specialized cell editors:
*
- * TextCellEditor
- for simple text strings
- * ColorCellEditor
- for colors
- * ComboBoxCellEditor
- value selected from drop-down combo box
- * CheckboxCellEditor
- bool valued checkbox
- * DialogCellEditor
- value from arbitrary dialog
+ * TextCellEditor
- for simple text strings
+ * ColorCellEditor
- for colors
+ * ComboBoxCellEditor
- value selected from drop-down combo
+ * box
+ * CheckboxCellEditor
- bool valued checkbox
+ * DialogCellEditor
- value from arbitrary dialog
*
*
*/
public abstract class CellEditor {
/**
- * List of cell editor listeners (element type: ICellEditorListener
).
+ * List of cell editor listeners (element type:
+ * ICellEditorListener
).
*/
private ListenerList listeners;
/**
- * List of cell editor property change listeners
- * (element type: IPropertyChangeListener
).
+ * List of cell editor property change listeners (element type:
+ * IPropertyChangeListener
).
*/
private ListenerList propertyChangeListeners;
@@ -88,8 +104,8 @@
private ICellEditorValidator validator = null;
/**
- * The error message string to display for invalid values;
- * null
if none (that is, the value is valid).
+ * The error message string to display for invalid values; null
+ * if none (that is, the value is valid).
*/
private String errorMessage = null;
@@ -99,8 +115,7 @@
private bool dirty = false;
/**
- * This cell editor's control, or null
- * if not created yet.
+ * This cell editor's control, or null
if not created yet.
*/
private Control control = null;
@@ -156,8 +171,9 @@
public static const String UNDO = "undo"; //$NON-NLS-1$
/**
- * Creates a new cell editor with no control
- * The cell editor has no cell validator.
+ * Creates a new cell editor with no control The cell editor has no cell
+ * validator.
+ *
* @since 2.1
*/
protected this() {
@@ -166,21 +182,24 @@
}
/**
- * Creates a new cell editor under the given parent control.
- * The cell editor has no cell validator.
+ * Creates a new cell editor under the given parent control. The cell editor
+ * has no cell validator.
*
- * @param parent the parent control
+ * @param parent
+ * the parent control
*/
protected this(Composite parent) {
this(parent, defaultStyle);
}
/**
- * Creates a new cell editor under the given parent control.
- * The cell editor has no cell validator.
+ * Creates a new cell editor under the given parent control. The cell editor
+ * has no cell validator.
*
- * @param parent the parent control
- * @param style the style bits
+ * @param parent
+ * the parent control
+ * @param style
+ * the style bits
* @since 2.1
*/
protected this(Composite parent, int style) {
@@ -193,29 +212,30 @@
/**
* Activates this cell editor.
*
- * The default implementation of this framework method
- * does nothing. Subclasses may reimplement.
+ * The default implementation of this framework method does nothing.
+ * Subclasses may reimplement.
*
*/
public void activate() {
}
/**
- * Adds a listener to this cell editor.
- * Has no effect if an identical listener is already registered.
+ * Adds a listener to this cell editor. Has no effect if an identical
+ * listener is already registered.
*
- * @param listener a cell editor listener
+ * @param listener
+ * a cell editor listener
*/
public void addListener(ICellEditorListener listener) {
listeners.add(cast(Object)listener);
}
/**
- * Adds a property change listener to this cell editor.
- * Has no effect if an identical property change listener
- * is already registered.
+ * Adds a property change listener to this cell editor. Has no effect if an
+ * identical property change listener is already registered.
*
- * @param listener a property change listener
+ * @param listener
+ * a property change listener
*/
public void addPropertyChangeListener(IPropertyChangeListener listener) {
propertyChangeListeners.add(cast(Object)listener);
@@ -224,19 +244,21 @@
/**
* Creates the control for this cell editor under the given parent control.
*
- * This framework method must be implemented by concrete
- * subclasses.
+ * This framework method must be implemented by concrete subclasses.
*
*
- * @param parent the parent control
- * @return the new control, or null
if this cell editor has no control
+ * @param parent
+ * the parent control
+ * @return the new control, or null
if this cell editor has
+ * no control
*/
protected abstract Control createControl(Composite parent);
/**
* Creates the control for this cell editor under the given parent control.
*
- * @param parent the parent control
+ * @param parent
+ * the parent control
* @since 2.1
*/
public void create(Composite parent) {
@@ -245,14 +267,15 @@
// See 1GD5CA6: ITPUI:ALL - TaskView.setSelection does not work
// Control is created with getVisible()istrue by default.
// This causes composite.setFocus() to work incorrectly.
- // The cell editor's control grabs focus instead, even if it is not active.
+ // The cell editor's control grabs focus instead, even if it is not
+ // active.
// Make the control invisible here by default.
deactivate();
}
/**
- * Hides this cell editor's control. Does nothing if this
- * cell editor is not visible.
+ * Hides this cell editor's control. Does nothing if this cell editor is not
+ * visible.
*/
public void deactivate() {
if (control !is null && !control.isDisposed()) {
@@ -297,14 +320,15 @@
* This framework method must be implemented by concrete subclasses.
*
*
- * @param value the value of this cell editor
+ * @param value
+ * the value of this cell editor
* @see #setValue
*/
protected abstract void doSetValue(Object value);
/**
- * Notifies all registered cell editor listeners of an apply event.
- * Only listeners registered at the time this method is called are notified.
+ * Notifies all registered cell editor listeners of an apply event. Only
+ * listeners registered at the time this method is called are notified.
*
* @see ICellEditorListener#applyEditorValue
*/
@@ -347,8 +371,10 @@
/**
* Notifies all registered cell editor listeners of a value change.
*
- * @param oldValidState the valid state before the end user changed the value
- * @param newValidState the current valid state
+ * @param oldValidState
+ * the valid state before the end user changed the value
+ * @param newValidState
+ * the current valid state
* @see ICellEditorListener#editorValueChanged
*/
protected void fireEditorValueChanged(bool oldValidState,
@@ -372,10 +398,10 @@
}
/**
- * Notifies all registered property listeners
- * of an enablement change.
+ * Notifies all registered property listeners of an enablement change.
*
- * @param actionId the id indicating what action's enablement has changed.
+ * @param actionId
+ * the id indicating what action's enablement has changed.
*/
protected void fireEnablementChanged(String actionId) {
Object[] array = propertyChangeListeners.getListeners();
@@ -398,7 +424,8 @@
/**
* Sets the style bits for this cell editor.
*
- * @param style the DWT style bits for this cell editor
+ * @param style
+ * the DWT style bits for this cell editor
* @since 2.1
*/
public void setStyle(int style) {
@@ -418,7 +445,8 @@
/**
* Returns the control used to implement this cell editor.
*
- * @return the control, or null
if this cell editor has no control
+ * @return the control, or null
if this cell editor has no
+ * control
*/
public Control getControl() {
return control;
@@ -427,21 +455,20 @@
/**
* Returns the current error message for this cell editor.
*
- * @return the error message if the cell editor is in an invalid state,
- * and null
if the cell editor is valid
+ * @return the error message if the cell editor is in an invalid state, and
+ * null
if the cell editor is valid
*/
public String getErrorMessage() {
return errorMessage;
}
/**
- * Returns a layout data object for this cell editor.
- * This is called each time the cell editor is activated
- * and controls the layout of the DWT table editor.
+ * Returns a layout data object for this cell editor. This is called each
+ * time the cell editor is activated and controls the layout of the DWT
+ * table editor.
*
- * The default implementation of this method sets the
- * minimum width to the control's preferred width.
- * Subclasses may extend or reimplement.
+ * The default implementation of this method sets the minimum width to the
+ * control's preferred width. Subclasses may extend or reimplement.
*
*
* @return the layout data object
@@ -468,8 +495,8 @@
/**
* Returns this cell editor's value provided that it has a valid one.
*
- * @return the value of this cell editor, or null
- * if the cell editor does not contain a valid value
+ * @return the value of this cell editor, or null
if the cell
+ * editor does not contain a valid value
*/
public final Object getValue() {
if (!valid) {
@@ -482,8 +509,8 @@
/**
* Returns whether this cell editor is activated.
*
- * @return true
if this cell editor's control is
- * currently activated, and false
if not activated
+ * @return true
if this cell editor's control is currently
+ * activated, and false
if not activated
*/
public bool isActivated() {
// Use the state of the visible style bit (getVisible()) rather than the
@@ -493,29 +520,31 @@
}
/**
- * Returns true
if this cell editor is
- * able to perform the copy action.
+ * Returns true
if this cell editor is able to perform the
+ * copy action.
*
- * This default implementation always returns
- * false
.
+ * This default implementation always returns false
.
*
*
* Subclasses may override
*
- * @return true
if copy is possible,
- * false
otherwise
+ *
+ * @return true
if copy is possible, false
+ * otherwise
*/
public bool isCopyEnabled() {
return false;
}
/**
- * Returns whether the given value is valid for this cell editor.
- * This cell editor's validator (if any) makes the actual determination.
- * @param value the value to check for
+ * Returns whether the given value is valid for this cell editor. This cell
+ * editor's validator (if any) makes the actual determination.
+ *
+ * @param value
+ * the value to check for
*
* @return true
if the value is valid, and false
- * if invalid
+ * if invalid
*/
protected bool isCorrect(Object value) {
errorMessage = null;
@@ -528,45 +557,45 @@
}
/**
- * Returns true
if this cell editor is
- * able to perform the cut action.
+ * Returns true
if this cell editor is able to perform the
+ * cut action.
*
- * This default implementation always returns
- * false
.
+ * This default implementation always returns false
.
*
*
* Subclasses may override
*
- * @return true
if cut is possible,
- * false
otherwise
+ *
+ * @return true
if cut is possible, false
+ * otherwise
*/
public bool isCutEnabled() {
return false;
}
/**
- * Returns true
if this cell editor is
- * able to perform the delete action.
+ * Returns true
if this cell editor is able to perform the
+ * delete action.
*
- * This default implementation always returns
- * false
.
+ * This default implementation always returns false
.
*
*
* Subclasses may override
*
- * @return true
if delete is possible,
- * false
otherwise
+ *
+ * @return true
if delete is possible, false
+ * otherwise
*/
public bool isDeleteEnabled() {
return false;
}
/**
- * Returns whether the value of this cell editor has changed since the
- * last call to setValue
.
+ * Returns whether the value of this cell editor has changed since the last
+ * call to setValue
.
*
- * @return true
if the value has changed, and false
- * if unchanged
+ * @return true
if the value has changed, and
+ * false
if unchanged
*/
public bool isDirty() {
return dirty;
@@ -574,6 +603,7 @@
/**
* Marks this cell editor as dirty.
+ *
* @since 2.1
*/
protected void markDirty() {
@@ -581,96 +611,96 @@
}
/**
- * Returns true
if this cell editor is
- * able to perform the find action.
+ * Returns true
if this cell editor is able to perform the
+ * find action.
*
- * This default implementation always returns
- * false
.
+ * This default implementation always returns false
.
*
*
* Subclasses may override
*
- * @return true
if find is possible,
- * false
otherwise
+ *
+ * @return true
if find is possible, false
+ * otherwise
*/
public bool isFindEnabled() {
return false;
}
/**
- * Returns true
if this cell editor is
- * able to perform the paste action.
+ * Returns true
if this cell editor is able to perform the
+ * paste action.
*
- * This default implementation always returns
- * false
.
+ * This default implementation always returns false
.
*
*
* Subclasses may override
*
- * @return true
if paste is possible,
- * false
otherwise
+ *
+ * @return true
if paste is possible, false
+ * otherwise
*/
public bool isPasteEnabled() {
return false;
}
/**
- * Returns true
if this cell editor is
- * able to perform the redo action.
+ * Returns true
if this cell editor is able to perform the
+ * redo action.
*
- * This default implementation always returns
- * false
.
+ * This default implementation always returns false
.
*
*
* Subclasses may override
*
- * @return true
if redo is possible,
- * false
otherwise
+ *
+ * @return true
if redo is possible, false
+ * otherwise
*/
public bool isRedoEnabled() {
return false;
}
/**
- * Returns true
if this cell editor is
- * able to perform the select all action.
+ * Returns true
if this cell editor is able to perform the
+ * select all action.
*
- * This default implementation always returns
- * false
.
+ * This default implementation always returns false
.
*
*
* Subclasses may override
*
- * @return true
if select all is possible,
- * false
otherwise
+ *
+ * @return true
if select all is possible, false
+ * otherwise
*/
public bool isSelectAllEnabled() {
return false;
}
/**
- * Returns true
if this cell editor is
- * able to perform the undo action.
+ * Returns true
if this cell editor is able to perform the
+ * undo action.
*
- * This default implementation always returns
- * false
.
+ * This default implementation always returns false
.
*
*
* Subclasses may override
*
- * @return true
if undo is possible,
- * false
otherwise
+ *
+ * @return true
if undo is possible, false
+ * otherwise
*/
public bool isUndoEnabled() {
return false;
}
/**
- * Returns whether this cell editor has a valid value.
- * The default value is false.
+ * Returns whether this cell editor has a valid value. The default value is
+ * false.
*
* @return true
if the value is valid, and false
- * if invalid
+ * if invalid
*
* @see #setValueValid(bool)
*/
@@ -681,14 +711,14 @@
/**
* Processes a key release event that occurred in this cell editor.
*
- * The default implementation of this framework method cancels editing
- * when the ESC key is pressed. When the RETURN key is pressed the current
- * value is applied and the cell editor deactivates.
- * Subclasses should call this method at appropriate times.
- * Subclasses may also extend or reimplement.
+ * The default implementation of this framework method cancels editing when
+ * the ESC key is pressed. When the RETURN key is pressed the current value
+ * is applied and the cell editor deactivates. Subclasses should call this
+ * method at appropriate times. Subclasses may also extend or reimplement.
*
*
- * @param keyEvent the key event
+ * @param keyEvent
+ * the key event
*/
protected void keyReleaseOccured(KeyEvent keyEvent) {
if (keyEvent.character is '\u001b') { // Escape character
@@ -703,9 +733,8 @@
* Processes a focus lost event that occurred in this cell editor.
*
* The default implementation of this framework method applies the current
- * value and deactivates the cell editor.
- * Subclasses should call this method at appropriate times.
- * Subclasses may also extend or reimplement.
+ * value and deactivates the cell editor. Subclasses should call this method
+ * at appropriate times. Subclasses may also extend or reimplement.
*
*/
protected void focusLost() {
@@ -716,8 +745,7 @@
}
/**
- * Performs the copy action.
- * This default implementation does nothing.
+ * Performs the copy action. This default implementation does nothing.
*
* Subclasses may override
*
@@ -726,8 +754,7 @@
}
/**
- * Performs the cut action.
- * This default implementation does nothing.
+ * Performs the cut action. This default implementation does nothing.
*
* Subclasses may override
*
@@ -736,8 +763,7 @@
}
/**
- * Performs the delete action.
- * This default implementation does nothing.
+ * Performs the delete action. This default implementation does nothing.
*
* Subclasses may override
*
@@ -746,8 +772,7 @@
}
/**
- * Performs the find action.
- * This default implementation does nothing.
+ * Performs the find action. This default implementation does nothing.
*
* Subclasses may override
*
@@ -756,8 +781,7 @@
}
/**
- * Performs the paste action.
- * This default implementation does nothing.
+ * Performs the paste action. This default implementation does nothing.
*
* Subclasses may override
*
@@ -766,8 +790,7 @@
}
/**
- * Performs the redo action.
- * This default implementation does nothing.
+ * Performs the redo action. This default implementation does nothing.
*
* Subclasses may override
*
@@ -776,8 +799,7 @@
}
/**
- * Performs the select all action.
- * This default implementation does nothing.
+ * Performs the select all action. This default implementation does nothing.
*
* Subclasses may override
*
@@ -786,8 +808,7 @@
}
/**
- * Performs the undo action.
- * This default implementation does nothing.
+ * Performs the undo action. This default implementation does nothing.
*
* Subclasses may override
*
@@ -796,21 +817,22 @@
}
/**
- * Removes the given listener from this cell editor.
- * Has no affect if an identical listener is not registered.
+ * Removes the given listener from this cell editor. Has no affect if an
+ * identical listener is not registered.
*
- * @param listener a cell editor listener
+ * @param listener
+ * a cell editor listener
*/
public void removeListener(ICellEditorListener listener) {
listeners.remove(cast(Object)listener);
}
/**
- * Removes the given property change listener from this cell editor.
- * Has no affect if an identical property change listener is not
- * registered.
+ * Removes the given property change listener from this cell editor. Has no
+ * affect if an identical property change listener is not registered.
*
- * @param listener a property change listener
+ * @param listener
+ * a property change listener
*/
public void removePropertyChangeListener(IPropertyChangeListener listener) {
propertyChangeListeners.remove(cast(Object)listener);
@@ -819,10 +841,12 @@
/**
* Sets or clears the current error message for this cell editor.
*
- * No formatting is done here, the message to be set is expected to be fully formatted
- * before being passed in.
+ * No formatting is done here, the message to be set is expected to be fully
+ * formatted before being passed in.
*
- * @param message the error message, or null
to clear
+ *
+ * @param message
+ * the error message, or null
to clear
*/
protected void setErrorMessage(String message) {
errorMessage = message;
@@ -838,7 +862,8 @@
/**
* Sets the input validator for this cell editor.
*
- * @param validator the input validator, or null
if none
+ * @param validator
+ * the input validator, or null
if none
*/
public void setValidator(ICellEditorValidator validator) {
this.validator = validator;
@@ -847,7 +872,8 @@
/**
* Sets this cell editor's value.
*
- * @param value the value of this cell editor
+ * @param value
+ * the value of this cell editor
*/
public final void setValue(Object value) {
valid = isCorrect(value);
@@ -856,12 +882,12 @@
}
/**
- * Sets the valid state of this cell editor.
- * The default value is false.
+ * Sets the valid state of this cell editor. The default value is false.
* Subclasses should call this method on construction.
*
- * @param valid true
if the current value is valid,
- * and false
if invalid
+ * @param valid
+ * true
if the current value is valid, and
+ * false
if invalid
*
* @see #isValueValid
*/
@@ -870,12 +896,14 @@
}
/**
- * The value has changed.
- * Updates the valid state flag, marks this cell editor as dirty,
- * and notifies all registered cell editor listeners of a value change.
+ * The value has changed. Updates the valid state flag, marks this cell
+ * editor as dirty, and notifies all registered cell editor listeners of a
+ * value change.
*
- * @param oldValidState the valid state before the end user changed the value
- * @param newValidState the current valid state
+ * @param oldValidState
+ * the valid state before the end user changed the value
+ * @param newValidState
+ * the current valid state
* @see ICellEditorListener#editorValueChanged
*/
protected void valueChanged(bool oldValidState, bool newValidState) {
@@ -885,10 +913,12 @@
}
/**
- * Activate the editor but also inform the editor which event triggered its activation.
- * The default implementation simply calls {@link #activate()}
+ * Activate the editor but also inform the editor which event triggered its
+ * activation. The default implementation simply calls
+ * {@link #activate()}
*
- * @param activationEvent the editor activation event
+ * @param activationEvent
+ * the editor activation event
* @since 3.3
*/
public void activate(ColumnViewerEditorActivationEvent activationEvent) {
@@ -896,12 +926,38 @@
}
/**
- * This method is for interal use in {@link ColumnViewerEditor} to not break clients
- * who don't implement the {@link ICellEditorListener} appropiately
+ * The default implementation of this method returns true. Subclasses that
+ * hook their own focus listener should override this method and return
+ * false. See also bug 58777.
*
- * @return true
to indicate that a focus listener has to be attached
+ * @return true
to indicate that a focus listener has to be
+ * attached
+ * @since 3.4
*/
- bool dependsOnExternalFocusListener() {
+ protected bool dependsOnExternalFocusListener() {
return true;
}
+
+ /**
+ * @param event
+ * deactivation event
+ *
+ */
+ protected void deactivate(ColumnViewerEditorDeactivationEvent event) {
+ deactivate();
+ }
+
+ /**
+ * Returns the duration, in milliseconds, between the mouse button click
+ * that activates the cell editor and a subsequent mouse button click that
+ * will be considered a double click on the underlying control.
+ * Clients may override, in particular, clients can return 0 to denote that
+ * two subsequent mouse clicks in a cell should not be interpreted as a
+ * double click.
+ *
+ * @return the timeout or 0
+ */
+ protected int getDoubleClickTimeout() {
+ return Display.getCurrent().getDoubleClickTime();
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/CellLabelProvider.d
--- a/dwtx/jface/viewers/CellLabelProvider.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/CellLabelProvider.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -236,5 +236,39 @@
* {@link ViewerCell}
*/
public abstract void update(ViewerCell cell);
+
+ /**
+ * Initialize this label provider for use with the given column viewer for
+ * the given column. Subclasses may extend but should call the super
+ * implementation (which at this time is empty but may be changed in the
+ * future).
+ *
+ * @param viewer
+ * the viewer
+ * @param column
+ * the column, or null
if a column is not
+ * available.
+ *
+ * @since 3.4
+ */
+ protected void initialize(ColumnViewer viewer, ViewerColumn column) {
+ }
+ /**
+ * Dispose of this label provider which was used with the given column
+ * viewer and column. Subclasses may extend but should call the super
+ * implementation (which calls {@link #dispose()}).
+ *
+ * @param viewer
+ * the viewer
+ * @param column
+ * the column, or null
if a column is not
+ * available.
+ *
+ * @since 3.4
+ */
+ public void dispose(ColumnViewer viewer, ViewerColumn column) {
+ dispose();
+ }
+
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/CheckboxCellEditor.d
--- a/dwtx/jface/viewers/CheckboxCellEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/CheckboxCellEditor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 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
@@ -103,12 +103,12 @@
/**
* The CheckboxCellEditor
implementation of
* this CellEditor
framework method returns
- * the checkbox setting wrapped as a bool
.
+ * the checkbox setting wrapped as a Boolean
.
*
- * @return the bool checkbox value
+ * @return the Boolean checkbox value
*/
protected override Object doGetValue() {
- return new ValueWrapperBool( value );
+ return value ? Boolean.TRUE : Boolean.FALSE;
}
/* (non-Javadoc)
@@ -121,13 +121,13 @@
/**
* The CheckboxCellEditor
implementation of
* this CellEditor
framework method accepts
- * a value wrapped as a bool
.
+ * a value wrapped as a Boolean
.
*
- * @param value a bool value
+ * @param value a Boolean value
*/
protected override void doSetValue(Object value) {
- Assert.isTrue( null !is cast(ValueWrapperBool)value );
- this.value = (cast(ValueWrapperBool) value).value;
+ Assert.isTrue( null !is cast(Boolean)value );
+ this.value = (cast(Boolean) value).booleanValue();
}
public override void activate(ColumnViewerEditorActivationEvent activationEvent) {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/CheckboxTreeViewer.d
--- a/dwtx/jface/viewers/CheckboxTreeViewer.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/CheckboxTreeViewer.d Thu May 22 01:36:46 2008 +0200
@@ -576,9 +576,16 @@
/**
* Sets to the given value the checked state for all elements in this viewer.
* Does not fire events to check state listeners.
+ * Assumes that the element has been expanded before. To enforce
+ * that the item is expanded, call expandToLevel
+ * for the element.
*
* @param state true
if the element should be checked,
* and false
if it should be unchecked
+ * @deprecated as this method only checks or unchecks visible items
+ * is is recommended that {@link #setSubtreeChecked(Object, bool)}
+ * is used instead.
+ * @see #setSubtreeChecked(Object, bool)
*
* @since 3.2
*/
@@ -588,9 +595,11 @@
}
/**
- * Set the checked state of items and their children to state.
+ * Set the checked state of the visible items and their children to state.
* @param state
* @param items
+ * @deprecated
+ * @see #setAllChecked(bool)
*/
private void setAllChecked(bool state, TreeItem[] items) {
for (int i = 0; i < items.length; i++) {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ColumnViewer.d
--- a/dwtx/jface/viewers/ColumnViewer.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ColumnViewer.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - initial API and implementation; bug 153993
- * fix in bug 163317, 151295, 167323, 167858, 184346, 187826, 200558,201002
+ * fix in bug 163317, 151295, 167323, 167858, 184346, 187826, 201905
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -29,7 +29,6 @@
import dwtx.jface.viewers.ITableLabelProvider;
import dwtx.jface.viewers.ILabelProvider;
import dwtx.jface.viewers.StructuredSelection;
-
import dwt.events.MouseAdapter;
import dwt.events.MouseEvent;
import dwt.graphics.Point;
@@ -47,14 +46,14 @@
/**
* The ColumnViewer is the abstract superclass of viewers that have columns
* (e.g., AbstractTreeViewer and AbstractTableViewer). Concrete subclasses of
- * {@link ColumnViewer} should implement a matching concrete subclass of
- * {@link ViewerColumn}.
- *
+ * {@link ColumnViewer} should implement a matching concrete subclass of {@link
+ * ViewerColumn}.
+ *
* This class is not intended to be subclassed outside of the JFace
* viewers framework.
- *
+ *
* @since 3.3
- *
+ *
*/
public abstract class ColumnViewer : StructuredViewer {
alias StructuredViewer.getLabelProvider getLabelProvider;
@@ -74,8 +73,11 @@
private ColumnViewerEditor viewerEditor;
- /* package */ bool busy;
- /* package */ bool logWhenBusy = true; // initially true, set to false after logging for the first time
+ private bool busy;
+ private bool logWhenBusy = true; // initially true, set to false
+
+ // after logging for the first
+ // time
/**
* Create a new instance of the receiver.
@@ -84,27 +86,6 @@
cell = new ViewerCell(null, 0, null);
}
- /* package */ bool isBusy() {
- if (busy) {
- if (logWhenBusy) {
- String message = "Ignored reentrant call while viewer is busy."; //$NON-NLS-1$
- if (!InternalPolicy.DEBUG_LOG_REENTRANT_VIEWER_CALLS) {
- // stop logging after the first
- logWhenBusy = false;
- message ~= " This is only logged once per viewer instance," ~ //$NON-NLS-1$
- " but similar calls will still be ignored."; //$NON-NLS-1$
- }
- Policy.getLog().log(
- new Status(
- IStatus.WARNING,
- Policy.JFACE,
- message, new RuntimeException()));
- }
- return true;
- }
- return false;
- }
-
protected override void hookControl(Control control) {
super.hookControl(control);
viewerEditor = createViewerEditor();
@@ -113,9 +94,9 @@
/**
* Hook up the editing support. Subclasses may override.
- *
+ *
* @param control
- * the control you want to hook on
+ * the control you want to hook on
*/
protected void hookEditingSupport(Control control) {
// Needed for backwards comp with AbstractTreeViewer and TableTreeViewer
@@ -126,7 +107,7 @@
control.addMouseListener(new class MouseAdapter {
public void mouseDown(MouseEvent e) {
// Workaround for bug 185817
- if( e.count !is 2 ) {
+ if (e.count !is 2) {
handleMouseDown(e);
}
}
@@ -141,22 +122,24 @@
/**
* Creates the viewer editor used for editing cell contents. To be
* implemented by subclasses.
- *
- * @return the editor, or null
if this viewer does not
- * support editing cell contents.
+ *
+ * @return the editor, or null
if this viewer does not support
+ * editing cell contents.
*/
protected abstract ColumnViewerEditor createViewerEditor();
/**
* Returns the viewer cell at the given widget-relative coordinates, or
* null
if there is no cell at that location
- *
+ *
* @param point
- * the widget-relative coordinates
+ * the widget-relative coordinates
* @return the cell or null
if no cell is found at the given
- * point
+ * point
+ *
+ * @since 3.4
*/
- ViewerCell getCell(Point point) {
+ public ViewerCell getCell(Point point) {
ViewerRow row = getViewerRow(point);
if (row !is null) {
return row.getCell(point);
@@ -167,11 +150,11 @@
/**
* Returns the viewer row at the given widget-relative coordinates.
- *
+ *
* @param point
- * the widget-relative coordinates of the viewer row
- * @return ViewerRow the row or null
if no row is found at
- * the given coordinates
+ * the widget-relative coordinates of the viewer row
+ * @return ViewerRow the row or null
if no row is found at the
+ * given coordinates
*/
protected ViewerRow getViewerRow(Point point) {
Item item = getItemAt(point);
@@ -186,14 +169,14 @@
return getViewerRow(point);
}
-
-
/**
- * Returns a {@link ViewerRow} associated with the given row widget. Implementations
- * may re-use the same instance for different row widgets; callers can only use the viewer
- * row locally and until the next call to this method.
- *
- * @param item the row widget
+ * Returns a {@link ViewerRow} associated with the given row widget.
+ * Implementations may re-use the same instance for different row widgets;
+ * callers can only use the viewer row locally and until the next call to
+ * this method.
+ *
+ * @param item
+ * the row widget
* @return ViewerRow a viewer row object
*/
protected abstract ViewerRow getViewerRowFromItem(Widget item);
@@ -203,27 +186,27 @@
/**
* Returns the column widget at the given column index.
- *
+ *
* @param columnIndex
- * the column index
+ * the column index
* @return Widget the column widget
*/
protected abstract Widget getColumnViewerOwner(int columnIndex);
/**
* Returns the viewer column for the given column index.
- *
+ *
* @param columnIndex
- * the column index
+ * the column index
* @return the viewer column at the given index, or null
if
- * there is none for the given index
+ * there is none for the given index
*/
/* package */ViewerColumn getViewerColumn(int columnIndex) {
ViewerColumn viewer;
Widget columnOwner = getColumnViewerOwner(columnIndex);
- if (columnOwner is null) {
+ if (columnOwner is null || columnOwner.isDisposed()) {
return null;
}
@@ -245,7 +228,7 @@
/**
* Sets up editing support for the given column based on the "old" cell
* editor API.
- *
+ *
* @param columnIndex
* @param viewer
*/
@@ -259,13 +242,15 @@
}
/*
* (non-Javadoc)
- *
- * @see dwtx.jface.viewers.EditingSupport#canEdit(java.lang.Object)
+ *
+ * @see
+ * dwtx.jface.viewers.EditingSupport#canEdit(java.lang
+ * .Object)
*/
public bool canEdit(Object element) {
Object[] properties = getColumnProperties();
- if( columnIndex_ < properties.length ) {
+ if (columnIndex_ < properties.length ) {
return getCellModifier().canModify(element,
(cast(ArrayWrapperString) getColumnProperties()[columnIndex_]).array);
}
@@ -275,12 +260,14 @@
/*
* (non-Javadoc)
- *
- * @see dwtx.jface.viewers.EditingSupport#getCellEditor(java.lang.Object)
+ *
+ * @see
+ * dwtx.jface.viewers.EditingSupport#getCellEditor(java
+ * .lang.Object)
*/
public CellEditor getCellEditor(Object element) {
CellEditor[] editors = getCellEditors();
- if( columnIndex_ < editors.length ) {
+ if (columnIndex_ < editors.length ) {
return getCellEditors()[columnIndex_];
}
return null;
@@ -288,13 +275,15 @@
/*
* (non-Javadoc)
- *
- * @see dwtx.jface.viewers.EditingSupport#getValue(java.lang.Object)
+ *
+ * @see
+ * dwtx.jface.viewers.EditingSupport#getValue(java.lang
+ * .Object)
*/
public Object getValue(Object element) {
Object[] properties = getColumnProperties();
- if( columnIndex_ < properties.length ) {
+ if (columnIndex_ < properties.length) {
return getCellModifier().getValue(element,
(cast(ArrayWrapperString) getColumnProperties()[columnIndex_]).array);
}
@@ -304,16 +293,18 @@
/*
* (non-Javadoc)
- *
- * @see dwtx.jface.viewers.EditingSupport#setValue(java.lang.Object,
- * java.lang.Object)
+ *
+ * @see
+ * dwtx.jface.viewers.EditingSupport#setValue(java.lang
+ * .Object, java.lang.Object)
*/
public void setValue(Object element, Object value) {
Object[] properties = getColumnProperties();
- if( columnIndex_ < properties.length ) {
+ if (columnIndex_ < properties.length) {
getCellModifier().modify(findItem(element),
- (cast(ArrayWrapperString) getColumnProperties()[columnIndex_]).array, value);
+ (cast(ArrayWrapperString) getColumnProperties()[columnIndex_]).array,
+ value);
}
}
@@ -327,11 +318,11 @@
/**
* Creates a generic viewer column for the given column widget, based on the
* given label provider.
- *
+ *
* @param columnOwner
- * the column widget
+ * the column widget
* @param labelProvider
- * the label provider to use for the column
+ * the label provider to use for the column
* @return ViewerColumn the viewer column
*/
private ViewerColumn createViewerColumn(Widget columnOwner,
@@ -346,16 +337,14 @@
}
/**
- * Update the cached cell object with the given row and column. Be careful not
- * to hold on to element objects longer than required. It is good practice to
- * call updateCell(null, 0, null) to clear references immediately after using
- * the cached cell object. (See bug 201280 for an example case where this happened.)
- *
+ * Update the cached cell object with the given row and column.
+ *
* @param rowItem
* @param column
* @return ViewerCell
*/
- /* package */ViewerCell updateCell(ViewerRow rowItem, int column, Object element) {
+ /* package */ViewerCell updateCell(ViewerRow rowItem, int column,
+ Object element) {
cell.update(rowItem, column, element);
return cell;
}
@@ -363,17 +352,17 @@
/**
* Returns the {@link Item} at the given widget-relative coordinates, or
* null
if there is no item at the given coordinates.
- *
+ *
* @param point
- * the widget-relative coordinates
- * @return the {@link Item} at the coordinates or null
if
- * there is no item at the given coordinates
+ * the widget-relative coordinates
+ * @return the {@link Item} at the coordinates or null
if there
+ * is no item at the given coordinates
*/
protected abstract Item getItemAt(Point point);
/*
* (non-Javadoc)
- *
+ *
* @see dwtx.jface.viewers.StructuredViewer#getItem(int, int)
*/
protected override Item getItem(int x, int y) {
@@ -386,20 +375,20 @@
* ITableLabelProvider
, ILabelProvider
, or
* CellLabelProvider
.
*
- * If the label provider is an {@link ITableLabelProvider}, then it
+ * If the label provider is an {@link ITableLabelProvider} , then it
* provides a separate label text and image for each column. Implementers of
- * ITableLabelProvider
may also implement
- * {@link ITableColorProvider} and/or {@link ITableFontProvider} to provide
- * colors and/or fonts.
+ * ITableLabelProvider
may also implement {@link
+ * ITableColorProvider} and/or {@link ITableFontProvider} to provide colors
+ * and/or fonts.
*
*
- * If the label provider is an ILabelProvider
, then it
+ * If the label provider is an ILabelProvider
, then it
* provides only the label text and image for the first column, and any
* remaining columns are blank. Implementers of ILabelProvider
* may also implement {@link IColorProvider} and/or {@link IFontProvider} to
* provide colors and/or fonts.
*
- *
+ *
*/
public override void setLabelProvider(IBaseLabelProvider labelProvider) {
Assert.isTrue( null !is cast(ITableLabelProvider)labelProvider
@@ -408,6 +397,17 @@
updateColumnParts(labelProvider);// Reset the label providers in the
// columns
super.setLabelProvider(labelProvider);
+ if (labelProvider instanceof CellLabelProvider) {
+ ((CellLabelProvider) labelProvider).initialize(this, null);
+ }
+ }
+
+ void internalDisposeLabelProvider(IBaseLabelProvider oldProvider) {
+ if (oldProvider instanceof CellLabelProvider) {
+ ((CellLabelProvider) oldProvider).dispose(this, null);
+ } else {
+ super.internalDisposeLabelProvider(oldProvider);
+ }
}
/**
@@ -426,7 +426,7 @@
/**
* Cancels a currently active cell editor if one is active. All changes
* already done in the cell editor are lost.
- *
+ *
* @since 3.1 (in subclasses, added in 3.3 to abstract class)
*/
public void cancelEditing() {
@@ -437,7 +437,7 @@
/**
* Apply the value of the active cell editor if one is active.
- *
+ *
* @since 3.3
*/
protected void applyEditorValue() {
@@ -448,11 +448,11 @@
/**
* Starts editing the given element at the given column index.
- *
+ *
* @param element
- * the model element
+ * the model element
* @param column
- * the column index
+ * the column index
* @since 3.1 (in subclasses, added in 3.3 to abstract class)
*/
public void editElement(Object element, int column) {
@@ -461,7 +461,7 @@
getControl().setRedraw(false);
// Set the selection at first because in Tree's
// the element might not be materialized
- setSelection(new StructuredSelection(element),true);
+ setSelection(new StructuredSelection(element), true);
Widget item = findItem(element);
if (item !is null) {
@@ -481,14 +481,15 @@
}
/**
- * Return the CellEditors for the receiver, or null
if no
- * cell editors are set.
+ * Return the CellEditors for the receiver, or null
if no cell
+ * editors are set.
*
- * Since 3.3, an alternative API is available, see
- * {@link ViewerColumn#setEditingSupport(EditingSupport)} for a more
- * flexible way of editing values in a column viewer.
+ * Since 3.3, an alternative API is available, see {@link
+ * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
+ * of editing values in a column viewer.
*
- *
+ *
+ *
* @return CellEditor[]
* @since 3.1 (in subclasses, added in 3.3 to abstract class)
* @see ViewerColumn#setEditingSupport(EditingSupport)
@@ -501,13 +502,13 @@
/**
* Returns the cell modifier of this viewer, or null
if none
* has been set.
- *
+ *
*
- * Since 3.3, an alternative API is available, see
- * {@link ViewerColumn#setEditingSupport(EditingSupport)} for a more
- * flexible way of editing values in a column viewer.
+ * Since 3.3, an alternative API is available, see {@link
+ * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
+ * of editing values in a column viewer.
*
- *
+ *
* @return the cell modifier, or null
* @since 3.1 (in subclasses, added in 3.3 to abstract class)
* @see ViewerColumn#setEditingSupport(EditingSupport)
@@ -521,13 +522,13 @@
* Returns the column properties of this table viewer. The properties must
* correspond with the columns of the table control. They are used to
* identify the column in a cell modifier.
- *
+ *
*
- * Since 3.3, an alternative API is available, see
- * {@link ViewerColumn#setEditingSupport(EditingSupport)} for a more
- * flexible way of editing values in a column viewer.
+ * Since 3.3, an alternative API is available, see {@link
+ * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
+ * of editing values in a column viewer.
*
- *
+ *
* @return the list of column properties
* @since 3.1 (in subclasses, added in 3.3 to abstract class)
* @see ViewerColumn#setEditingSupport(EditingSupport)
@@ -543,15 +544,15 @@
/**
* Returns whether there is an active cell editor.
- *
+ *
*
- * Since 3.3, an alternative API is available, see
- * {@link ViewerColumn#setEditingSupport(EditingSupport)} for a more
- * flexible way of editing values in a column viewer.
+ * Since 3.3, an alternative API is available, see {@link
+ * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
+ * of editing values in a column viewer.
*
- *
+ *
* @return true
if there is an active cell editor, and
- * false
otherwise
+ * false
otherwise
* @since 3.1 (in subclasses, added in 3.3 to abstract class)
* @see ViewerColumn#setEditingSupport(EditingSupport)
* @see EditingSupport
@@ -564,10 +565,10 @@
}
public override void refresh(Object element) {
- if (isBusy())
+ if (checkBusy())
return;
- if( isCellEditorActive() ) {
+ if (isCellEditorActive()) {
cancelEditing();
}
@@ -575,10 +576,10 @@
}
public override void refresh(Object element, bool updateLabels) {
- if (isBusy())
+ if (checkBusy())
return;
- if( isCellEditorActive() ) {
+ if (isCellEditorActive()) {
cancelEditing();
}
@@ -586,7 +587,7 @@
}
public override void update(Object element, String[] properties) {
- if (isBusy())
+ if (checkBusy())
return;
super.update(element, properties);
}
@@ -594,15 +595,18 @@
/**
* Sets the cell editors of this column viewer. If editing is not supported
* by this viewer the call simply has no effect.
- *
+ *
*
- * Since 3.3, an alternative API is available, see
- * {@link ViewerColumn#setEditingSupport(EditingSupport)} for a more
- * flexible way of editing values in a column viewer.
+ * Since 3.3, an alternative API is available, see {@link
+ * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
+ * of editing values in a column viewer.
*
- *
+ *
+ * Users setting up an editable {@link TreeViewer} or {@link TableViewer} with more than 1 column have
+ * to pass the DWT.FULL_SELECTION style bit
+ *
* @param editors
- * the list of cell editors
+ * the list of cell editors
* @since 3.1 (in subclasses, added in 3.3 to abstract class)
* @see ViewerColumn#setEditingSupport(EditingSupport)
* @see EditingSupport
@@ -614,15 +618,18 @@
/**
* Sets the cell modifier for this column viewer. This method does nothing
* if editing is not supported by this viewer.
- *
+ *
*
- * Since 3.3, an alternative API is available, see
- * {@link ViewerColumn#setEditingSupport(EditingSupport)} for a more
- * flexible way of editing values in a column viewer.
+ * Since 3.3, an alternative API is available, see {@link
+ * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
+ * of editing values in a column viewer.
*
- *
+ *
+ * Users setting up an editable {@link TreeViewer} or {@link TableViewer} with more than 1 column have
+ * to pass the DWT.FULL_SELECTION style bit
+ *
* @param modifier
- * the cell modifier
+ * the cell modifier
* @since 3.1 (in subclasses, added in 3.3 to abstract class)
* @see ViewerColumn#setEditingSupport(EditingSupport)
* @see EditingSupport
@@ -636,15 +643,18 @@
* correspond with the columns of the control. They are used to identify the
* column in a cell modifier. If editing is not supported by this viewer the
* call simply has no effect.
- *
+ *
*
- * Since 3.3, an alternative API is available, see
- * {@link ViewerColumn#setEditingSupport(EditingSupport)} for a more
- * flexible way of editing values in a column viewer.
+ * Since 3.3, an alternative API is available, see {@link
+ * ViewerColumn#setEditingSupport(EditingSupport)} for a more flexible way
+ * of editing values in a column viewer.
*
- *
+ *
+ * Users setting up an editable {@link TreeViewer} or {@link TableViewer} with more than 1 column have
+ * to pass the DWT.FULL_SELECTION style bit
+ *
* @param columnProperties
- * the list of column properties
+ * the list of column properties
* @since 3.1 (in subclasses, added in 3.3 to abstract class)
* @see ViewerColumn#setEditingSupport(EditingSupport)
* @see EditingSupport
@@ -659,9 +669,9 @@
* visually, one column of items may be visible. This occurs when the
* programmer uses the column viewer like a list, adding elements but never
* creating a column.
- *
+ *
* @return the number of columns
- *
+ *
* @since 3.3
*/
protected abstract int doGetColumnCount();
@@ -672,12 +682,12 @@
/**
* Returns the label provider associated with the column at the given index
* or null
if no column with this index is known.
- *
+ *
* @param columnIndex
- * the column index
+ * the column index
* @return the label provider associated with the column or
- * null
if no column with this index is known
- *
+ * null
if no column with this index is known
+ *
* @since 3.3
*/
public CellLabelProvider getLabelProvider(int columnIndex) {
@@ -700,12 +710,12 @@
/**
* Invoking this method fires an editor activation event which tries to
- * enable the editor but before this event is passed to
- * {@link ColumnViewerEditorActivationStrategy} to see if this event should
- * really trigger editor activation
- *
+ * enable the editor but before this event is passed to {@link
+ * ColumnViewerEditorActivationStrategy} to see if this event should really
+ * trigger editor activation
+ *
* @param event
- * the activation event
+ * the activation event
*/
protected void triggerEditorActivationEvent(
ColumnViewerEditorActivationEvent event) {
@@ -718,7 +728,7 @@
/**
* @param columnViewerEditor
- * the new column viewer editor
+ * the new column viewer editor
*/
public void setColumnViewerEditor(ColumnViewerEditor columnViewerEditor) {
Assert.isNotNull(viewerEditor);
@@ -733,38 +743,123 @@
}
protected override Object[] getRawChildren(Object parent) {
- bool oldBusy = busy;
- busy = true;
+ bool oldBusy = isBusy();
+ setBusy(true);
try {
return super.getRawChildren(parent);
} finally {
- busy = oldBusy;
+ setBusy(oldBusy);
}
}
- /**
- * Clear all cell-editors setup for backwards compatibility in
- * {@link #setupEditingSupport(int, ViewerColumn)}. This has to be done
- * whenever a column is disposed because the index cached when the anonymous
- * class is created has to be readjusted
- */
void clearLegacyEditingSetup() {
- int count = doGetColumnCount();
+ if (!getControl().isDisposed() && getCellEditors() !is null) {
+ int count = doGetColumnCount();
- for( int i = 0; i < count || i is 0; i++ ) {
- Widget owner = getColumnViewerOwner(i);
-
- if( owner !is null && ! owner.isDisposed() ) {
- ViewerColumn column = cast(ViewerColumn) owner.getData(ViewerColumn.COLUMN_VIEWER_KEY);
- if( column !is null ) {
- EditingSupport e = column.getEditingSupport();
- // Ensure that only EditingSupports are wiped that are setup
- // for Legacy reasons
- if (e !is null && e.isLegacySupport()) {
- column.setEditingSupport(null);
+ for (int i = 0; i < count || i is 0; i++) {
+ Widget owner = getColumnViewerOwner(i);
+ if (owner !is null && !owner.isDisposed()) {
+ ViewerColumn column = cast(ViewerColumn) owner
+ .getData(ViewerColumn.COLUMN_VIEWER_KEY);
+ if (column !is null) {
+ EditingSupport e = column.getEditingSupport();
+ // Ensure that only EditingSupports are wiped that are
+ // setup
+ // for Legacy reasons
+ if (e !is null && e.isLegacySupport()) {
+ column.setEditingSupport(null);
+ }
}
}
}
}
}
+
+ /**
+ * Checks if this viewer is currently busy, logging a warning and returning
+ * true
if it is busy. A column viewer is busy when it is
+ * processing a refresh, add, remove, insert, replace, setItemCount,
+ * expandToLevel, update, setExpandedElements, or similar method that may
+ * make calls to client code. Column viewers are not designed to handle
+ * reentrant calls while they are busy. The method returns true
+ * if the viewer is busy. It is recommended that this method be used by
+ * subclasses to determine whether the viewer is busy to return early from
+ * state-changing methods.
+ *
+ *
+ * This method is not intended to be overridden by subclasses.
+ *
+ *
+ * @return true
if the viewer is busy.
+ *
+ * @since 3.4
+ */
+ protected bool checkBusy() {
+ if (isBusy()) {
+ if (logWhenBusy) {
+ String message = "Ignored reentrant call while viewer is busy."; //$NON-NLS-1$
+ if (!InternalPolicy.DEBUG_LOG_REENTRANT_VIEWER_CALLS) {
+ // stop logging after the first
+ logWhenBusy = false;
+ message += " This is only logged once per viewer instance," + //$NON-NLS-1$
+ " but similar calls will still be ignored."; //$NON-NLS-1$
+ }
+ Policy.getLog().log(
+ new Status(IStatus.WARNING, Policy.JFACE, message,
+ new RuntimeException()));
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Sets the busy state of this viewer. Subclasses MUST use try
+ * ...finally
as follows to ensure that the busy flag is reset
+ * to its original value:
+ *
+ *
+ * bool oldBusy = isBusy();
+ * setBusy(true);
+ * try {
+ * // do work
+ * } finally {
+ * setBusy(oldBusy);
+ * }
+ *
+ *
+ *
+ * This method is not intended to be overridden by subclasses.
+ *
+ *
+ * @param busy
+ * the new value of the busy flag
+ *
+ * @since 3.4
+ */
+ protected void setBusy(bool busy) {
+ this.busy = busy;
+ }
+
+ /**
+ * Returns true
if this viewer is currently busy processing a
+ * refresh, add, remove, insert, replace, setItemCount, expandToLevel,
+ * update, setExpandedElements, or similar method that may make calls to
+ * client code. Column viewers are not designed to handle reentrant calls
+ * while they are busy. It is recommended that clients avoid using this
+ * method if they can ensure by other means that they will not make
+ * reentrant calls to methods like the ones listed above. See bug 184991 for
+ * background discussion.
+ *
+ *
+ * This method is not intended to be overridden by subclasses.
+ *
+ *
+ * @return Returns whether this viewer is busy.
+ *
+ * @since 3.4
+ */
+ public bool isBusy() {
+ return busy;
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ColumnViewerEditor.d
--- a/dwtx/jface/viewers/ColumnViewerEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ColumnViewerEditor.d Thu May 22 01:36:46 2008 +0200
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - refactoring (bug 153993)
- * fix in bug 151295,166500,200337
+ * fix in bug: 151295,178946,166500,195908,201906,207676,180504,216706,218336
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -29,6 +29,8 @@
import dwtx.jface.viewers.OpenEvent;
import dwt.DWT;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
import dwt.events.FocusAdapter;
import dwt.events.FocusEvent;
import dwt.events.FocusListener;
@@ -38,7 +40,6 @@
import dwt.events.TraverseEvent;
import dwt.events.TraverseListener;
import dwt.widgets.Control;
-import dwt.widgets.Display;
import dwt.widgets.Item;
import dwtx.core.runtime.ListenerList;
@@ -46,7 +47,7 @@
/**
* This is the base for all editor implementations of Viewers. ColumnViewer
- * implementators have to subclass this class and implement the missing methods
+ * implementors have to subclass this class and implement the missing methods
*
* @since 3.3
* @see TableViewerEditor
@@ -65,16 +66,16 @@
private TraverseListener tabeditingListener;
- private int activationTime;
-
private ViewerCell cell;
- private ColumnViewerEditorActivationEvent activationEvent;
-
private ListenerList editorActivationListener;
private ColumnViewerEditorActivationStrategy editorActivationStrategy;
+ private bool inEditorDeactivation;
+
+ private DisposeListener disposeListener;
+
/**
* Tabbing from cell to cell is turned off
*/
@@ -107,6 +108,13 @@
*/
public static const int KEYBOARD_ACTIVATION = 1 << 5;
+ /**
+ * Style mask used to turn off the feature that an editor activation
+ * is canceled on double click. It is also possible to turn off this feature
+ * per cell-editor using {@link CellEditor#getDoubleClickTimeout()}
+ */
+ public static final int KEEP_EDITOR_ON_DOUBLE_CLICK = 1 << 6;
+
private int feature;
/**
@@ -134,6 +142,18 @@
.setEnableEditorActivationWithKeyboard(true);
}
this.feature = feature;
+ this.disposeListener = new class(viewer) DisposeListener {
+ ColumnViewer viewer_;
+ this(ColumnViewer a){
+ viewer_=a;
+ }
+ public void widgetDisposed(DisposeEvent e) {
+ if( viewer_.isCellEditorActive() ) {
+ cancelEditing();
+ }
+ }
+
+ };
initCellEditorListener();
}
@@ -154,29 +174,36 @@
};
}
- void activateCellEditor() {
+ private bool activateCellEditor(final ColumnViewerEditorActivationEvent activationEvent) {
ViewerColumn part = viewer.getViewerColumn(cell.getColumnIndex());
Object element = cell.getElement();
if (part !is null && part.getEditingSupport() !is null
&& part.getEditingSupport().canEdit_package(element)) {
-
cellEditor = part.getEditingSupport().getCellEditor_package(element);
if (cellEditor !is null) {
+ int timeout = cellEditor.getDoubleClickTimeout();
+
+ final int activationTime;
+
+ if (timeout !is 0) {
+ activationTime = activationEvent.time + timeout;
+ } else {
+ activationTime = 0;
+ }
+
if (editorActivationListener !is null
&& !editorActivationListener.isEmpty()) {
Object[] ls = editorActivationListener.getListeners();
for (int i = 0; i < ls.length; i++) {
-
- if (activationEvent.cancel) {
- // Avoid leaking
- this.cell = null;
- return;
- }
-
(cast(ColumnViewerEditorActivationListener) ls[i])
.beforeEditorActivated(activationEvent);
+
+ // Was the activation canceled ?
+ if (activationEvent.cancel) {
+ return false;
+ }
}
}
@@ -194,13 +221,13 @@
Control control = cellEditor.getControl();
cellEditor.activate(activationEvent);
if (control is null) {
- return;
+ return false;
}
setLayoutData(cellEditor.getLayoutData());
setEditor(control, cast(Item) cell.getItem(), cell.getColumnIndex());
cellEditor.setFocus();
- if( cellEditor.dependsOnExternalFocusListener() ) {
+ if (cellEditor.dependsOnExternalFocusListener()) {
if (focusListener is null) {
focusListener = new class FocusAdapter {
public void focusLost(FocusEvent e) {
@@ -219,7 +246,7 @@
public void mouseDown(MouseEvent e) {
// time wrap?
// check for expiration of doubleClickTime
- if (e.time <= activationTime) {
+ if (shouldFireDoubleClick(activationTime, e.time, activationEvent) && e.button is 1) {
control_.removeMouseListener(mouseListener);
cancelEditing();
handleDoubleClickEvent();
@@ -228,7 +255,11 @@
}
}
};
- control.addMouseListener(mouseListener);
+
+ if (activationTime !is 0
+ && (feature & KEEP_EDITOR_ON_DOUBLE_CLICK) is 0) {
+ control.addMouseListener(mouseListener);
+ }
if (tabeditingListener is null) {
tabeditingListener = new class TraverseListener {
@@ -253,11 +284,23 @@
.afterEditorActivated(activationEvent);
}
}
+
+ this.cell.getItem().addDisposeListener(disposeListener);
+
+ return true;
}
- } else {
- // Avoid leaking
- this.cell = null;
+
}
+
+ return false;
+ }
+
+ private bool shouldFireDoubleClick(int activationTime, int mouseTime,
+ ColumnViewerEditorActivationEvent activationEvent) {
+ return mouseTime <= activationTime
+ && activationEvent.eventType !is ColumnViewerEditorActivationEvent.KEY_PRESSED
+ && activationEvent.eventType !is ColumnViewerEditorActivationEvent.PROGRAMMATIC
+ && activationEvent.eventType !is ColumnViewerEditorActivationEvent.TRAVERSAL;
}
/**
@@ -265,62 +308,72 @@
* editor.
*/
void applyEditorValue() {
- CellEditor c = this.cellEditor;
- if (c !is null && this.cell !is null) {
- // null out cell editor before calling save
- // in case save results in applyEditorValue being re-entered
- // see 1GAHI8Z: ITPUI:ALL - How to code event notification when
- // using cell editor ?
- ColumnViewerEditorDeactivationEvent tmp = new ColumnViewerEditorDeactivationEvent(
- cell);
- if (editorActivationListener !is null
- && !editorActivationListener.isEmpty()) {
- Object[] ls = editorActivationListener.getListeners();
- for (int i = 0; i < ls.length; i++) {
+ // avoid re-entering
+ if (!inEditorDeactivation) {
+ try {
+ inEditorDeactivation = true;
+ CellEditor c = this.cellEditor;
+ if (c !is null && this.cell !is null) {
+ ColumnViewerEditorDeactivationEvent tmp = new ColumnViewerEditorDeactivationEvent(
+ cell);
+ tmp.eventType = ColumnViewerEditorDeactivationEvent.EDITOR_SAVED;
+ if (editorActivationListener !is null
+ && !editorActivationListener.isEmpty()) {
+ Object[] ls = editorActivationListener.getListeners();
+ for (int i = 0; i < ls.length; i++) {
- (cast(ColumnViewerEditorActivationListener) ls[i])
- .beforeEditorDeactivated(tmp);
- }
- }
+ (cast(ColumnViewerEditorActivationListener) ls[i])
+ .beforeEditorDeactivated(tmp);
+ }
+ }
+
+ Item t = cast(Item) this.cell.getItem();
+
+ // don't null out table item -- same item is still selected
+ if (t !is null && !t.isDisposed()) {
+ saveEditorValue(c);
+ }
+ if (!viewer.getControl().isDisposed()) {
+ setEditor(null, null, 0);
+ }
- this.cellEditor = null;
- this.activationEvent = null;
- Item t = cast(Item) this.cell.getItem();
-
- // don't null out table item -- same item is still selected
- if (t !is null && !t.isDisposed()) {
- saveEditorValue(c);
- }
+ c.removeListener(cellEditorListener);
+ Control control = c.getControl();
+ if (control !is null && !control.isDisposed()) {
+ if (mouseListener !is null) {
+ control.removeMouseListener(mouseListener);
+ // Clear the instance not needed any more
+ mouseListener = null;
+ }
+ if (focusListener !is null) {
+ control.removeFocusListener(focusListener);
+ }
- setEditor(null, null, 0);
- c.removeListener(cellEditorListener);
- Control control = c.getControl();
- if (control !is null) {
- if (mouseListener !is null) {
- control.removeMouseListener(mouseListener);
- // Clear the instance not needed any more
- mouseListener = null;
- }
- if (focusListener !is null) {
- control.removeFocusListener(focusListener);
+ if (tabeditingListener !is null) {
+ control.removeTraverseListener(tabeditingListener);
+ }
+ }
+ c.deactivate(tmp);
+
+ if (editorActivationListener !is null
+ && !editorActivationListener.isEmpty()) {
+ Object[] ls = editorActivationListener.getListeners();
+ for (int i = 0; i < ls.length; i++) {
+ (cast(ColumnViewerEditorActivationListener) ls[i])
+ .afterEditorDeactivated(tmp);
+ }
+ }
+
+ if( ! this.cell.getItem().isDisposed() ) {
+ this.cell.getItem().removeDisposeListener(disposeListener);
+ }
}
- if (tabeditingListener !is null) {
- control.removeTraverseListener(tabeditingListener);
- }
+ this.cellEditor = null;
+ this.cell = null;
+ } finally {
+ inEditorDeactivation = false;
}
- c.deactivate();
-
- if (editorActivationListener !is null
- && !editorActivationListener.isEmpty()) {
- Object[] ls = editorActivationListener.getListeners();
- for (int i = 0; i < ls.length; i++) {
- (cast(ColumnViewerEditorActivationListener) ls[i])
- .afterEditorDeactivated(tmp);
- }
- }
-
- this.cell = null;
}
}
@@ -328,53 +381,69 @@
* Cancel editing
*/
void cancelEditing() {
- if (cellEditor !is null) {
- ColumnViewerEditorDeactivationEvent tmp = new ColumnViewerEditorDeactivationEvent(
- cell);
- if (editorActivationListener !is null
- && !editorActivationListener.isEmpty()) {
- Object[] ls = editorActivationListener.getListeners();
- for (int i = 0; i < ls.length; i++) {
+ // avoid re-entering
+ if (!inEditorDeactivation) {
+ try {
+ inEditorDeactivation = true;
+ if (cellEditor !is null) {
+ ColumnViewerEditorDeactivationEvent tmp = new ColumnViewerEditorDeactivationEvent(
+ cell);
+ tmp.eventType = ColumnViewerEditorDeactivationEvent.EDITOR_CANCELED;
+ if (editorActivationListener !is null
+ && !editorActivationListener.isEmpty()) {
+ Object[] ls = editorActivationListener.getListeners();
+ for (int i = 0; i < ls.length; i++) {
+
+ (cast(ColumnViewerEditorActivationListener) ls[i])
+ .beforeEditorDeactivated(tmp);
+ }
+ }
+
+ if (!viewer.getControl().isDisposed()) {
+ setEditor(null, null, 0);
+ }
+
+ cellEditor.removeListener(cellEditorListener);
- (cast(ColumnViewerEditorActivationListener) ls[i])
- .beforeEditorDeactivated(tmp);
- }
- }
+ Control control = cellEditor.getControl();
+ if (control !is null && !viewer.getControl().isDisposed()) {
+ if (mouseListener !is null) {
+ control.removeMouseListener(mouseListener);
+ // Clear the instance not needed any more
+ mouseListener = null;
+ }
+ if (focusListener !is null) {
+ control.removeFocusListener(focusListener);
+ }
+
+ if (tabeditingListener !is null) {
+ control.removeTraverseListener(tabeditingListener);
+ }
+ }
- setEditor(null, null, 0);
- cellEditor.removeListener(cellEditorListener);
+ CellEditor oldEditor = cellEditor;
+ oldEditor.deactivate(tmp);
- Control control = cellEditor.getControl();
- if (control !is null) {
- if (mouseListener !is null) {
- control.removeMouseListener(mouseListener);
- // Clear the instance not needed any more
- mouseListener = null;
+ if (editorActivationListener !is null
+ && !editorActivationListener.isEmpty()) {
+ Object[] ls = editorActivationListener.getListeners();
+ for (int i = 0; i < ls.length; i++) {
+ (cast(ColumnViewerEditorActivationListener) ls[i])
+ .afterEditorDeactivated(tmp);
+ }
+ }
+
+ if( ! this.cell.getItem().isDisposed() ) {
+ this.cell.getItem().addDisposeListener(disposeListener);
+ }
+
+ this.cellEditor = null;
+ this.cell = null;
+
}
- if (focusListener !is null) {
- control.removeFocusListener(focusListener);
- }
-
- if (tabeditingListener !is null) {
- control.removeTraverseListener(tabeditingListener);
- }
+ } finally {
+ inEditorDeactivation = false;
}
-
- CellEditor oldEditor = cellEditor;
- oldEditor.deactivate();
-
- if (editorActivationListener !is null
- && !editorActivationListener.isEmpty()) {
- Object[] ls = editorActivationListener.getListeners();
- for (int i = 0; i < ls.length; i++) {
- (cast(ColumnViewerEditorActivationListener) ls[i])
- .afterEditorDeactivated(tmp);
- }
- }
-
- this.cellEditor = null;
- this.activationEvent = null;
- this.cell = null;
}
}
@@ -384,18 +453,20 @@
* @param event
*/
void handleEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
- if (editorActivationStrategy.isEditorActivationEvent_package(event)) {
+
+ // Only activate if the event isn't tagged as canceled
+ if (!event.cancel
+ && editorActivationStrategy.isEditorActivationEvent_package(event)) {
if (cellEditor !is null) {
applyEditorValue();
}
this.cell = cast(ViewerCell) event.getSource();
- activationEvent = event;
- activationTime = event.time
- + Display.getCurrent().getDoubleClickTime();
-
- activateCellEditor();
+ if( ! activateCellEditor(event) ) {
+ this.cell = null;
+ this.cellEditor = null;
+ }
}
}
@@ -487,8 +558,8 @@
&& (feature & TABBING_VERTICAL) is TABBING_VERTICAL) {
cell2edit = searchCellAboveBelow(row, viewer, columnIndex, true);
} else if ((feature & TABBING_HORIZONTAL) is TABBING_HORIZONTAL) {
- cell2edit = searchPreviousCell(row, viewer, columnIndex,
- columnIndex);
+ cell2edit = searchPreviousCell(row, row.getCell(columnIndex),
+ row.getCell(columnIndex), viewer);
}
} else if (event.detail is DWT.TRAVERSE_TAB_NEXT) {
event.doit = false;
@@ -498,8 +569,8 @@
cell2edit = searchCellAboveBelow(row, viewer, columnIndex,
false);
} else if ((feature & TABBING_HORIZONTAL) is TABBING_HORIZONTAL) {
- cell2edit = searchNextCell(row, viewer, columnIndex,
- columnIndex);
+ cell2edit = searchNextCell(row, row.getCell(columnIndex), row
+ .getCell(columnIndex), viewer);
}
}
@@ -540,36 +611,48 @@
return rv;
}
- private ViewerCell searchPreviousCell(ViewerRow row, ColumnViewer viewer,
- int columnIndex, int startIndex) {
+ private bool isCellEditable(ColumnViewer viewer, ViewerCell cell) {
+ ViewerColumn column = viewer.getViewerColumn(cell.getColumnIndex());
+ return column !is null && column.getEditingSupport() !is null
+ && column.getEditingSupport().canEdit(cell.getElement());
+ }
+
+ private ViewerCell searchPreviousCell(ViewerRow row,
+ ViewerCell currentCell, ViewerCell originalCell, ColumnViewer viewer) {
ViewerCell rv = null;
+ ViewerCell previousCell;
- if (columnIndex - 1 >= 0) {
- ViewerColumn column = viewer.getViewerColumn(columnIndex - 1);
- if (column !is null
- && column.getEditingSupport() !is null
- && column.getEditingSupport().canEdit_package(
- row.getItem().getData())) {
- rv = row.getCell(columnIndex - 1);
+ if (currentCell !is null) {
+ previousCell = currentCell.getNeighbor(ViewerCell.LEFT, true);
+ } else {
+ if (row.getColumnCount() !is 0) {
+ previousCell = row.getCell(row.getCreationIndex(row
+ .getColumnCount() - 1));
} else {
- rv = searchPreviousCell(row, viewer, columnIndex - 1,
- startIndex);
+ previousCell = row.getCell(0);
+ }
+
+ }
+
+ // No endless loop
+ if (originalCell.equals(previousCell)) {
+ return null;
+ }
+
+ if (previousCell !is null) {
+ if (isCellEditable(viewer, previousCell)) {
+ rv = previousCell;
+ } else {
+ rv = searchPreviousCell(row, previousCell, originalCell, viewer);
}
} else {
if ((feature & TABBING_CYCLE_IN_ROW) is TABBING_CYCLE_IN_ROW) {
- // Check that we don't get into endless loop
- if (columnIndex - 1 !is startIndex) {
- // Don't subtract -1 from getColumnCount() we need to
- // start in the virtual column
- // next to it
- rv = searchPreviousCell(row, viewer, row.getColumnCount(),
- startIndex);
- }
+ rv = searchPreviousCell(row, null, originalCell, viewer);
} else if ((feature & TABBING_MOVE_TO_ROW_NEIGHBOR) is TABBING_MOVE_TO_ROW_NEIGHBOR) {
ViewerRow rowAbove = row.getNeighbor(ViewerRow.ABOVE, false);
if (rowAbove !is null) {
- rv = searchPreviousCell(rowAbove, viewer, rowAbove
- .getColumnCount(), startIndex);
+ rv = searchPreviousCell(rowAbove, null, originalCell,
+ viewer);
}
}
}
@@ -577,32 +660,36 @@
return rv;
}
- private ViewerCell searchNextCell(ViewerRow row, ColumnViewer viewer,
- int columnIndex, int startIndex) {
+ private ViewerCell searchNextCell(ViewerRow row, ViewerCell currentCell,
+ ViewerCell originalCell, ColumnViewer viewer) {
ViewerCell rv = null;
- if (columnIndex + 1 < row.getColumnCount()) {
- ViewerColumn column = viewer.getViewerColumn(columnIndex + 1);
- if (column !is null
- && column.getEditingSupport() !is null
- && column.getEditingSupport().canEdit_package(
- row.getItem().getData())) {
- rv = row.getCell(columnIndex + 1);
+ ViewerCell nextCell;
+
+ if (currentCell !is null) {
+ nextCell = currentCell.getNeighbor(ViewerCell.RIGHT, true);
+ } else {
+ nextCell = row.getCell(row.getCreationIndex(0));
+ }
+
+ // No endless loop
+ if (originalCell.equals(nextCell)) {
+ return null;
+ }
+
+ if (nextCell !is null) {
+ if (isCellEditable(viewer, nextCell)) {
+ rv = nextCell;
} else {
- rv = searchNextCell(row, viewer, columnIndex + 1, startIndex);
+ rv = searchNextCell(row, nextCell, originalCell, viewer);
}
} else {
if ((feature & TABBING_CYCLE_IN_ROW) is TABBING_CYCLE_IN_ROW) {
- // Check that we don't get into endless loop
- if (columnIndex + 1 !is startIndex) {
- // Start from -1 from the virtual column before the
- // first one
- rv = searchNextCell(row, viewer, -1, startIndex);
- }
+ rv = searchNextCell(row, null, originalCell, viewer);
} else if ((feature & TABBING_MOVE_TO_ROW_NEIGHBOR) is TABBING_MOVE_TO_ROW_NEIGHBOR) {
ViewerRow rowBelow = row.getNeighbor(ViewerRow.BELOW, false);
if (rowBelow !is null) {
- rv = searchNextCell(rowBelow, viewer, -1, startIndex);
+ rv = searchNextCell(rowBelow, null, originalCell, viewer);
}
}
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ColumnViewerEditorActivationEvent.d
--- a/dwtx/jface/viewers/ColumnViewerEditorActivationEvent.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ColumnViewerEditorActivationEvent.d Thu May 22 01:36:46 2008 +0200
@@ -147,7 +147,7 @@
super(cell);
this.eventType = KEY_PRESSED;
this.sourceEvent = event;
- this.time = 0;
+ this.time = event.time;
this.keyCode = event.keyCode;
this.character = event.character;
this.stateMask = event.stateMask;
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ColumnViewerEditorDeactivationEvent.d
--- a/dwtx/jface/viewers/ColumnViewerEditorDeactivationEvent.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ColumnViewerEditorDeactivationEvent.d Thu May 22 01:36:46 2008 +0200
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Tom Schindl - initial API and implementation
+ * fixes in bug: 178946
* Port to the D programming language:
* Frank Benoit
******************************************************************************/
@@ -29,10 +31,24 @@
private static const long serialVersionUID = 1L;
/**
+ * The event type
+ */
+ public int eventType;
+
+ /**
+ * Event when editor is canceled
+ */
+ public static final int EDITOR_CANCELED = 1;
+
+ /**
+ * Event when editor is saved
+ */
+ public static final int EDITOR_SAVED = 2;
+
+ /**
* @param source
*/
public this(Object source) {
super(source);
}
-
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ColumnViewerToolTipSupport.d
--- a/dwtx/jface/viewers/ColumnViewerToolTipSupport.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ColumnViewerToolTipSupport.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - initial API and implementation
+ * bugfix in: 195137, 198089
* Fredy Dobler - bug 159600
* Brock Janiczak - bug 182443
* Port to the D programming language:
@@ -22,9 +23,9 @@
import dwtx.jface.viewers.CellLabelProvider;
import dwtx.jface.viewers.StructuredSelection;
-import dwt.DWT;
import dwt.graphics.Image;
import dwt.graphics.Point;
+import dwt.widgets.Composite;
import dwt.widgets.Event;
import dwtx.jface.util.Policy;
import dwtx.jface.window.DefaultToolTip;
@@ -33,7 +34,8 @@
import dwt.dwthelper.utils;
/**
- * The ColumnViewerTooltipSupport is the class that provides tool tips for ColumnViewers.
+ * The ColumnViewerTooltipSupport is the class that provides tool tips for
+ * ColumnViewers.
*
* @since 3.3
*
@@ -41,10 +43,8 @@
public class ColumnViewerToolTipSupport : DefaultToolTip {
private ColumnViewer viewer;
- private static const String LABEL_PROVIDER_KEY = Policy.JFACE
- ~ "_LABEL_PROVIDER"; //$NON-NLS-1$
-
- private static const String ELEMENT_KEY = Policy.JFACE ~ "_ELEMENT_KEY"; //$NON-NLS-1$
+ private static const String VIEWER_CELL_KEY = Policy.JFACE
+ ~ "_VIEWER_CELL_KEY"; //$NON-NLS-1$
private static const int DEFAULT_SHIFT_X = 10;
@@ -57,14 +57,16 @@
*
* @param viewer
* the viewer the support is attached to
- * @param style style passed to control tool tip behavior
+ * @param style
+ * style passed to control tool tip behavior
*
* @param manualActivation
* true
if the activation is done manually using
* {@link #show(Point)}
*/
- protected this(ColumnViewer viewer, int style, bool manualActivation ) {
- super(viewer.getControl(),style,manualActivation);
+ protected this(ColumnViewer viewer, int style,
+ bool manualActivation) {
+ super(viewer.getControl(), style, manualActivation);
this.viewer = viewer;
}
@@ -77,7 +79,7 @@
* the viewer the support is attached to
*/
public static void enableFor(ColumnViewer viewer) {
- new ColumnViewerToolTipSupport(viewer,ToolTip.NO_RECREATE,false);
+ new ColumnViewerToolTipSupport(viewer, ToolTip.NO_RECREATE, false);
}
/**
@@ -87,21 +89,57 @@
*
* @param viewer
* the viewer the support is attached to
- * @param style style passed to control tool tip behavior
+ * @param style
+ * style passed to control tool tip behavior
*
* @see ToolTip#RECREATE
* @see ToolTip#NO_RECREATE
*/
public static void enableFor(ColumnViewer viewer, int style) {
- new ColumnViewerToolTipSupport(viewer,style,false);
+ new ColumnViewerToolTipSupport(viewer, style, false);
}
protected override Object getToolTipArea(Event event) {
- return viewer.getCell(new Point(event.x,event.y));
+ return viewer.getCell(new Point(event.x, event.y));
+ }
+
+ /**
+ * Instead of overwriting this method subclasses should overwrite
+ * {@link #createViewerToolTipContentArea(Event, ViewerCell, Composite)}
+ */
+ protected Composite createToolTipContentArea(Event event, Composite parent) {
+ ViewerCell cell = (ViewerCell) getData(VIEWER_CELL_KEY);
+ setData(VIEWER_CELL_KEY, null);
+
+ return createViewerToolTipContentArea(event, cell, parent);
}
- protected override final bool shouldCreateToolTip(Event event) {
- if( ! super.shouldCreateToolTip(event) ) {
+ /**
+ * Creates the content area of the tool tip giving access to the cell the
+ * tip is shown for. Subclasses can overload this method to implement their
+ * own tool tip design.
+ *
+ *
+ * This method is called from
+ * {@link #createToolTipContentArea(Event, Composite)} and by default calls
+ * the {@link DefaultToolTip#createToolTipContentArea(Event, Composite)}.
+ *
+ *
+ * @param event
+ * the event that which
+ * @param cell
+ * the cell the tool tip is shown for
+ * @param parent
+ * the parent of the control to create
+ * @return the control to be displayed in the tool tip area
+ */
+ protected Composite createViewerToolTipContentArea(Event event,
+ ViewerCell cell, Composite parent) {
+ return super.createToolTipContentArea(event, parent);
+ }
+
+ protected override bool shouldCreateToolTip(Event event) {
+ if (!super.shouldCreateToolTip(event)) {
return false;
}
@@ -115,8 +153,9 @@
if (row !is null) {
Object element = row.getItem().getData();
- ViewerColumn viewPart = viewer.getViewerColumn(row
- .getColumnIndex(point));
+ ViewerCell cell = row.getCell(point);
+ ViewerColumn viewPart = viewer.getViewerColumn(cell
+ .getColumnIndex());
if (viewPart is null) {
return false;
@@ -128,11 +167,11 @@
String text = labelProvider.getToolTipText(element);
Image img = null;
- if( ! useNative ) {
+ if (!useNative) {
img = labelProvider.getToolTipImage(element);
}
- if( useNative || (text is null && img is null ) ) {
+ if (useNative || (text is null && img is null)) {
viewer.getControl().setToolTipText(text);
rv = false;
} else {
@@ -147,14 +186,15 @@
setShift(new Point(shift.x, shift.y));
}
- setData(LABEL_PROVIDER_KEY, labelProvider);
- setData(ELEMENT_KEY, element);
+ setData(VIEWER_CELL_KEY, cell);
setText(text);
setImage(img);
setStyle(labelProvider.getToolTipStyle(element));
- setForegroundColor(labelProvider.getToolTipForegroundColor(element));
- setBackgroundColor(labelProvider.getToolTipBackgroundColor(element));
+ setForegroundColor(labelProvider
+ .getToolTipForegroundColor(element));
+ setBackgroundColor(labelProvider
+ .getToolTipBackgroundColor(element));
setFont(labelProvider.getToolTipFont(element));
// Check if at least one of the values is set
@@ -166,12 +206,11 @@
}
protected override void afterHideToolTip(Event event) {
+ super.afterHideToolTip(event);
+ // Clear the restored value else this could be a source of a leak
+ setData(VIEWER_CELL_KEY, null);
if (event !is null && event.widget !is viewer.getControl()) {
- if (event.type is DWT.MouseDown) {
- viewer.setSelection(new StructuredSelection());
- } else {
- viewer.getControl().setFocus();
- }
+ viewer.getControl().setFocus();
}
}
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ComboBoxCellEditor.d
--- a/dwtx/jface/viewers/ComboBoxCellEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ComboBoxCellEditor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -7,7 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Tom Schindl - bugfix in 199775
+ * Tom Schindl - bugfix in 174739
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -35,14 +35,13 @@
import tango.text.convert.Format;
/**
- * A cell editor that presents a list of items in a combo box.
- * The cell editor's value is the zero-based index of the selected
- * item.
+ * A cell editor that presents a list of items in a combo box. The cell editor's
+ * value is the zero-based index of the selected item.
*
* This class may be instantiated; it is not intended to be subclassed.
*
*/
-public class ComboBoxCellEditor : CellEditor {
+public class ComboBoxCellEditor : AbstractComboBoxCellEditor {
/**
* The list of items to present in the combo box.
@@ -65,8 +64,8 @@
private static const int defaultStyle = DWT.NONE;
/**
- * Creates a new cell editor with no control and no st of choices. Initially,
- * the cell editor has no cell validator.
+ * Creates a new cell editor with no control and no st of choices.
+ * Initially, the cell editor has no cell validator.
*
* @since 2.1
* @see CellEditor#setStyle
@@ -79,29 +78,32 @@
}
/**
- * Creates a new cell editor with a combo containing the given
- * list of choices and parented under the given control. The cell
- * editor value is the zero-based index of the selected item.
- * Initially, the cell editor has no cell validator and
- * the first item in the list is selected.
+ * Creates a new cell editor with a combo containing the given list of
+ * choices and parented under the given control. The cell editor value is
+ * the zero-based index of the selected item. Initially, the cell editor has
+ * no cell validator and the first item in the list is selected.
*
- * @param parent the parent control
- * @param items the list of strings for the combo box
+ * @param parent
+ * the parent control
+ * @param items
+ * the list of strings for the combo box
*/
public this(Composite parent, String[] items) {
this(parent, items, defaultStyle);
}
/**
- * Creates a new cell editor with a combo containing the given
- * list of choices and parented under the given control. The cell
- * editor value is the zero-based index of the selected item.
- * Initially, the cell editor has no cell validator and
- * the first item in the list is selected.
+ * Creates a new cell editor with a combo containing the given list of
+ * choices and parented under the given control. The cell editor value is
+ * the zero-based index of the selected item. Initially, the cell editor has
+ * no cell validator and the first item in the list is selected.
*
- * @param parent the parent control
- * @param items the list of strings for the combo box
- * @param style the style bits
+ * @param parent
+ * the parent control
+ * @param items
+ * the list of strings for the combo box
+ * @param style
+ * the style bits
* @since 2.1
*/
public this(Composite parent, String[] items, int style) {
@@ -121,7 +123,8 @@
/**
* Sets the list of choices for the combo box
*
- * @param items the list of choices for the combo box
+ * @param items
+ * the list of choices for the combo box
*/
public void setItems(String[] items) {
// Assert.isNotNull(items);
@@ -129,8 +132,8 @@
populateComboBoxItems();
}
- /* (non-Javadoc)
- * Method declared on CellEditor.
+ /*
+ * (non-Javadoc) Method declared on CellEditor.
*/
protected override Control createControl(Composite parent) {
@@ -174,31 +177,31 @@
}
/**
- * The ComboBoxCellEditor
implementation of
- * this CellEditor
framework method returns
- * the zero-based index of the current selection.
+ * The ComboBoxCellEditor
implementation of this
+ * CellEditor
framework method returns the zero-based index
+ * of the current selection.
*
- * @return the zero-based index of the current selection wrapped
- * as an Integer
+ * @return the zero-based index of the current selection wrapped as an
+ * Integer
*/
protected override Object doGetValue() {
return new ValueWrapperInt(selection);
}
- /* (non-Javadoc)
- * Method declared on CellEditor.
+ /*
+ * (non-Javadoc) Method declared on CellEditor.
*/
protected override void doSetFocus() {
comboBox.setFocus();
}
/**
- * The ComboBoxCellEditor
implementation of
- * this CellEditor
framework method sets the
- * minimum width of the cell. The minimum width is 10 characters
- * if comboBox
is not null
or disposed
- * else it is 60 pixels to make sure the arrow button and some text is visible.
- * The list of CCombo will be wide enough to show its longest item.
+ * The ComboBoxCellEditor
implementation of this
+ * CellEditor
framework method sets the minimum width of the
+ * cell. The minimum width is 10 characters if comboBox
is
+ * not null
or disposed
else it is 60 pixels
+ * to make sure the arrow button and some text is visible. The list of
+ * CCombo will be wide enough to show its longest item.
*/
public override LayoutData getLayoutData() {
LayoutData layoutData = super.getLayoutData();
@@ -215,12 +218,13 @@
}
/**
- * The ComboBoxCellEditor
implementation of
- * this CellEditor
framework method
- * accepts a zero-based index of a selection.
+ * The ComboBoxCellEditor
implementation of this
+ * CellEditor
framework method accepts a zero-based index of
+ * a selection.
*
- * @param value the zero-based index of the selection wrapped
- * as an Integer
+ * @param value
+ * the zero-based index of the selection wrapped as an
+ * Integer
*/
protected override void doSetValue(Object value) {
Assert.isTrue(comboBox !is null && (cast(ValueWrapperInt)value ));
@@ -247,7 +251,7 @@
* Applies the currently selected value and deactivates the cell editor
*/
void applyEditorValueAndDeactivate() {
- // must set the selection before getting value
+ // must set the selection before getting value
selection = comboBox.getSelectionIndex();
Object newValue = doGetValue();
markDirty();
@@ -260,9 +264,9 @@
// try to insert the current value into the error message.
setErrorMessage(Format(getErrorMessage(),
[ items[selection] ]));
- }
- else {
- // Since we don't have a valid index, assume we're using an 'edit'
+ } else {
+ // Since we don't have a valid index, assume we're using an
+ // 'edit'
// combo so format using its text value
setErrorMessage(Format(getErrorMessage(),
[ comboBox.getText() ]));
@@ -274,7 +278,8 @@
}
/*
- * (non-Javadoc)
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.CellEditor#focusLost()
*/
protected override void focusLost() {
@@ -284,7 +289,8 @@
}
/*
- * (non-Javadoc)
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.CellEditor#keyReleaseOccured(dwt.events.KeyEvent)
*/
protected override void keyReleaseOccured(KeyEvent keyEvent) {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ComboBoxViewerCellEditor.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/viewers/ComboBoxViewerCellEditor.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,267 @@
+/*******************************************************************************
+ * 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
+ * bugfix in 174739
+ * Eric Rizzo - bug 213315
+ * Port to the D programming language:
+ * Frank Benoit
+ *******************************************************************************/
+
+module dwtx.jface.viewers.ComboBoxViewerCellEditor;
+
+import java.text.MessageFormat;
+
+import dwt.DWT;
+import dwt.custom.CCombo;
+import dwt.events.FocusAdapter;
+import dwt.events.FocusEvent;
+import dwt.events.KeyAdapter;
+import dwt.events.KeyEvent;
+import dwt.events.SelectionAdapter;
+import dwt.events.SelectionEvent;
+import dwt.events.TraverseEvent;
+import dwt.events.TraverseListener;
+import dwt.graphics.GC;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwtx.core.runtime.Assert;
+
+/**
+ * A cell editor that presents a list of items in a combo box. In contrast to
+ * {@link ComboBoxCellEditor} it wraps the underlying {@link CCombo} using a
+ * {@link ComboViewer}
+ */
+public class ComboBoxViewerCellEditor extends AbstractComboBoxCellEditor {
+
+ /**
+ * The custom combo box control.
+ */
+ ComboViewer viewer;
+
+ Object selectedValue;
+
+ /**
+ * Default ComboBoxCellEditor style
+ */
+ private static final int defaultStyle = DWT.NONE;
+
+ /**
+ * Creates a new cell editor with a combo viewer and a default style
+ *
+ * @param parent
+ * the parent control
+ */
+ public ComboBoxViewerCellEditor(Composite parent) {
+ this(parent, defaultStyle);
+ }
+
+ /**
+ * Creates a new cell editor with a combo viewer and the given style
+ *
+ * @param parent
+ * the parent control
+ * @param style
+ * the style bits
+ */
+ public ComboBoxViewerCellEditor(Composite parent, int style) {
+ super(parent, style);
+ setValueValid(true);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on CellEditor.
+ */
+ protected Control createControl(Composite parent) {
+
+ CCombo comboBox = new CCombo(parent, getStyle());
+ comboBox.setFont(parent.getFont());
+ viewer = new ComboViewer(comboBox);
+
+ comboBox.addKeyListener(new KeyAdapter() {
+ // hook key pressed - see PR 14201
+ public void keyPressed(KeyEvent e) {
+ keyReleaseOccured(e);
+ }
+ });
+
+ comboBox.addSelectionListener(new SelectionAdapter() {
+ public void widgetDefaultSelected(SelectionEvent event) {
+ applyEditorValueAndDeactivate();
+ }
+
+ public void widgetSelected(SelectionEvent event) {
+ ISelection selection = viewer.getSelection();
+ if (selection.isEmpty()) {
+ selectedValue = null;
+ } else {
+ selectedValue = ((IStructuredSelection) selection)
+ .getFirstElement();
+ }
+ }
+ });
+
+ comboBox.addTraverseListener(new TraverseListener() {
+ public void keyTraversed(TraverseEvent e) {
+ if (e.detail is DWT.TRAVERSE_ESCAPE
+ || e.detail is DWT.TRAVERSE_RETURN) {
+ e.doit = false;
+ }
+ }
+ });
+
+ comboBox.addFocusListener(new FocusAdapter() {
+ public void focusLost(FocusEvent e) {
+ ComboBoxViewerCellEditor.this.focusLost();
+ }
+ });
+ return comboBox;
+ }
+
+ /**
+ * The ComboBoxCellEditor
implementation of this
+ * CellEditor
framework method returns the zero-based index
+ * of the current selection.
+ *
+ * @return the zero-based index of the current selection wrapped as an
+ * Integer
+ */
+ protected Object doGetValue() {
+ return selectedValue;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on CellEditor.
+ */
+ protected void doSetFocus() {
+ viewer.getControl().setFocus();
+ }
+
+ /**
+ * The ComboBoxCellEditor
implementation of this
+ * CellEditor
framework method sets the minimum width of the
+ * cell. The minimum width is 10 characters if comboBox
is
+ * not null
or disposed
eles it is 60 pixels
+ * to make sure the arrow button and some text is visible. The list of
+ * CCombo will be wide enough to show its longest item.
+ */
+ public LayoutData getLayoutData() {
+ LayoutData layoutData = super.getLayoutData();
+ if ((viewer.getControl() is null) || viewer.getControl().isDisposed()) {
+ layoutData.minimumWidth = 60;
+ } else {
+ // make the comboBox 10 characters wide
+ GC gc = new GC(viewer.getControl());
+ layoutData.minimumWidth = (gc.getFontMetrics()
+ .getAverageCharWidth() * 10) + 10;
+ gc.dispose();
+ }
+ return layoutData;
+ }
+
+ /**
+ * Set a new value
+ *
+ * @param value
+ * the new value
+ */
+ protected void doSetValue(Object value) {
+ Assert.isTrue(viewer !is null);
+ selectedValue = value;
+ if (value is null) {
+ viewer.setSelection(StructuredSelection.EMPTY);
+ } else {
+ viewer.setSelection(new StructuredSelection(value));
+ }
+ }
+
+ /**
+ * @param labelProvider
+ * the label provider used
+ * @see StructuredViewer#setLabelProvider(IBaseLabelProvider)
+ */
+ public void setLabelProvider(IBaseLabelProvider labelProvider) {
+ viewer.setLabelProvider(labelProvider);
+ }
+
+ /**
+ * @param provider
+ * the content provider used
+ * @see StructuredViewer#setContentProvider(IContentProvider)
+ */
+ public void setContenProvider(IStructuredContentProvider provider) {
+ viewer.setContentProvider(provider);
+ }
+
+ /**
+ * @param input
+ * the input used
+ * @see StructuredViewer#setInput(Object)
+ */
+ public void setInput(Object input) {
+ viewer.setInput(input);
+ }
+
+ /**
+ * @return get the viewer
+ */
+ public ComboViewer getViewer() {
+ return viewer;
+ }
+
+ /**
+ * Applies the currently selected value and deactiavates the cell editor
+ */
+ void applyEditorValueAndDeactivate() {
+ // must set the selection before getting value
+ ISelection selection = viewer.getSelection();
+ if (selection.isEmpty()) {
+ selectedValue = null;
+ } else {
+ selectedValue = ((IStructuredSelection) selection)
+ .getFirstElement();
+ }
+
+ Object newValue = doGetValue();
+ markDirty();
+ bool isValid = isCorrect(newValue);
+ setValueValid(isValid);
+
+ if (!isValid) {
+ MessageFormat.format(getErrorMessage(),
+ new Object[] { selectedValue });
+ }
+
+ fireApplyEditorValue();
+ deactivate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.CellEditor#focusLost()
+ */
+ protected void focusLost() {
+ if (isActivated()) {
+ applyEditorValueAndDeactivate();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.CellEditor#keyReleaseOccured(dwt.events.KeyEvent)
+ */
+ protected void keyReleaseOccured(KeyEvent keyEvent) {
+ if (keyEvent.character is '\u001b') { // Escape character
+ fireCancelEditor();
+ } else if (keyEvent.character is '\t') { // tab key
+ applyEditorValueAndDeactivate();
+ }
+ }
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ComboViewer.d
--- a/dwtx/jface/viewers/ComboViewer.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ComboViewer.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004-2006 IBM Corporation and others.
+ * Copyright (c) 2004, 2008 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
@@ -37,9 +37,9 @@
*
*
* @see dwtx.jface.viewers.ListViewer
- * @since 3.0
+ * @since 3.0 (made non-final in 3.4)
*/
-public final class ComboViewer : AbstractListViewer {
+public class ComboViewer : AbstractListViewer {
/**
* This viewer's list control if this viewer is instantiated with a combo control; otherwise
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ContentViewer.d
--- a/dwtx/jface/viewers/ContentViewer.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ContentViewer.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -127,7 +127,7 @@
*
* The ContentViewer
implementation of this method returns the label
* provider recorded in an internal state variable; if none has been
- * set (with setLabelProvider
) a SimpleLabelProvider
+ * set (with setLabelProvider
) a default label provider
* will be created, remembered, and returned.
* Overriding this method is generally not required;
* however, if overriding in a subclass,
@@ -295,7 +295,16 @@
// Dispose old provider after refresh, so that items never refer to stale images.
if (oldProvider !is null) {
- oldProvider.dispose();
+ internalDisposeLabelProvider(oldProvider);
}
}
+
+ /**
+ * @param oldProvider
+ *
+ * @since 3.4
+ */
+ void internalDisposeLabelProvider(IBaseLabelProvider oldProvider) {
+ oldProvider.dispose();
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/DecoratingLabelProvider.d
--- a/dwtx/jface/viewers/DecoratingLabelProvider.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/DecoratingLabelProvider.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/DecoratingStyledCellLabelProvider.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/viewers/DecoratingStyledCellLabelProvider.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,318 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * Port to the D programming language:
+ * Frank Benoit
+ *******************************************************************************/
+module dwtx.jface.viewers.DecoratingStyledCellLabelProvider;
+
+
+import dwt.graphics.Color;
+import dwt.graphics.Font;
+import dwt.graphics.Image;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.viewers.StyledString.Styler;
+
+/**
+ * A {@link DecoratingStyledCellLabelProvider} is a
+ * {@link DelegatingStyledCellLabelProvider} that uses a nested
+ * {@link DelegatingStyledCellLabelProvider.IStyledLabelProvider} to compute
+ * styled text label and image and takes a {@link ILabelDecorator} to decorate
+ * the label.
+ *
+ *
+ * Use this label provider as a replacement for the
+ * {@link DecoratingLabelProvider} when decorating styled text labels.
+ *
+ *
+ *
+ * The {@link DecoratingStyledCellLabelProvider} will try to evaluate the text
+ * decoration added by the {@link ILabelDecorator} and will apply the style
+ * returned by {@link #getDecorationStyle(Object)}
+ *
+ *
+ * The {@link ILabelDecorator} can optionally implement {@link IColorDecorator}
+ * and {@link IFontDecorator} to provide foreground and background color and
+ * font decoration.
+ *
+ *
+ * @since 3.4
+ */
+public class DecoratingStyledCellLabelProvider extends
+ DelegatingStyledCellLabelProvider {
+
+ private ILabelDecorator decorator;
+ private IDecorationContext decorationContext= DecorationContext.DEFAULT_CONTEXT;
+ private ILabelProviderListener labelProviderListener;
+
+ /**
+ * Creates a {@link DecoratingStyledCellLabelProvider} that delegates the
+ * requests for styled labels and for images to a
+ * {@link DelegatingStyledCellLabelProvider.IStyledLabelProvider}.
+ *
+ * @param labelProvider
+ * the styled label provider
+ * @param decorator
+ * a label decorator or null
to not decorate the
+ * label
+ * @param decorationContext
+ * a decoration context or null
if the no
+ * decorator is configured or the default decorator should be
+ * used
+ */
+ public DecoratingStyledCellLabelProvider(
+ IStyledLabelProvider labelProvider, ILabelDecorator decorator,
+ IDecorationContext decorationContext) {
+ super(labelProvider);
+
+ this.decorator = decorator;
+ this.decorationContext = decorationContext !is null ? decorationContext
+ : DecorationContext.DEFAULT_CONTEXT;
+
+ this.labelProviderListener = new ILabelProviderListener() {
+ public void labelProviderChanged(LabelProviderChangedEvent event) {
+ fireLabelProviderChanged(event);
+ }
+ };
+ labelProvider.addListener(this.labelProviderListener);
+ if (decorator !is null)
+ decorator.addListener(this.labelProviderListener);
+ }
+
+ /**
+ * Returns the decoration context associated with this label provider. It
+ * will be passed to the decorator if the decorator is an instance of
+ * {@link LabelDecorator}.
+ *
+ * @return the decoration context associated with this label provider
+ */
+ public IDecorationContext getDecorationContext() {
+ return this.decorationContext;
+ }
+
+ /**
+ * Set the decoration context that will be based to the decorator for this
+ * label provider if that decorator implements {@link LabelDecorator}.
+ *
+ * @param decorationContext
+ * the decoration context.
+ */
+ public void setDecorationContext(IDecorationContext decorationContext) {
+ Assert.isNotNull(decorationContext);
+ this.decorationContext = decorationContext;
+ }
+
+ private bool waitForPendingDecoration(ViewerCell cell) {
+ if (this.decorator is null)
+ return false;
+
+ Object element = cell.getElement();
+ String oldText = cell.getText();
+
+ bool isDecorationPending = false;
+ if (this.decorator instanceof LabelDecorator) {
+ isDecorationPending = !((LabelDecorator) this.decorator)
+ .prepareDecoration(element, oldText, getDecorationContext());
+ } else if (this.decorator instanceof IDelayedLabelDecorator) {
+ isDecorationPending = !((IDelayedLabelDecorator) this.decorator)
+ .prepareDecoration(element, oldText);
+ }
+ if (isDecorationPending && oldText.length() is 0) {
+ // item is empty: is shown for the first time: don't wait
+ return false;
+ }
+ return isDecorationPending;
+ }
+
+ public void update(ViewerCell cell) {
+ if (waitForPendingDecoration(cell)) {
+ return; // wait until the decoration is ready
+ }
+ super.update(cell);
+ }
+
+ public Color getForeground(Object element) {
+ if (this.decorator instanceof IColorDecorator) {
+ Color foreground = ((IColorDecorator) this.decorator)
+ .decorateForeground(element);
+ if (foreground !is null)
+ return foreground;
+ }
+ return super.getForeground(element);
+ }
+
+ public Color getBackground(Object element) {
+ if (this.decorator instanceof IColorDecorator) {
+ Color color = ((IColorDecorator) this.decorator)
+ .decorateBackground(element);
+ if (color !is null)
+ return color;
+ }
+ return super.getBackground(element);
+ }
+
+ public Font getFont(Object element) {
+ if (this.decorator instanceof IFontDecorator) {
+ Font font = ((IFontDecorator) this.decorator).decorateFont(element);
+ if (font !is null)
+ return font;
+ }
+ return super.getFont(element);
+ }
+
+ public Image getImage(Object element) {
+ Image image = super.getImage(element);
+ if (this.decorator is null) {
+ return image;
+ }
+ Image decorated = null;
+ if (this.decorator instanceof LabelDecorator) {
+ decorated = ((LabelDecorator) this.decorator).decorateImage(image,
+ element, getDecorationContext());
+ } else {
+ decorated = this.decorator.decorateImage(image, element);
+ }
+ if (decorated !is null)
+ return decorated;
+
+ return image;
+ }
+
+ /**
+ * Returns the styled text for the label of the given element.
+ *
+ * @param element
+ * the element for which to provide the styled label text
+ * @return the styled text string used to label the element
+ */
+ protected StyledString getStyledText(Object element) {
+ StyledString styledString = super.getStyledText(element);
+ if (this.decorator is null) {
+ return styledString;
+ }
+
+ String label = styledString.getString();
+ String decorated;
+ if (this.decorator instanceof LabelDecorator) {
+ decorated = ((LabelDecorator) this.decorator).decorateText(label,
+ element, getDecorationContext());
+ } else {
+ decorated = this.decorator.decorateText(label, element);
+ }
+ if (decorated is null)
+ return styledString;
+
+ int originalStart = decorated.indexOf(label);
+ if (originalStart is -1) {
+ return new StyledString(decorated); // the decorator did
+ // something wild
+ }
+
+ if (decorated.length() is label.length())
+ return styledString;
+
+ Styler style = getDecorationStyle(element);
+ if (originalStart > 0) {
+ StyledString newString = new StyledString(decorated
+ .substring(0, originalStart), style);
+ newString.append(styledString);
+ styledString = newString;
+ }
+ if (decorated.length() > originalStart + label.length()) { // decorator
+ // appended
+ // something
+ return styledString.append(decorated.substring(originalStart
+ + label.length()), style);
+ }
+ return styledString;
+ }
+
+ /**
+ * Sets the {@link StyledString.Styler} to be used for string
+ * decorations. By default the
+ * {@link StyledString#DECORATIONS_STYLER decoration style}. Clients
+ * can override.
+ *
+ * Note that it is the client's responsibility to react on color changes of
+ * the decoration color by refreshing the view
+ *
+ * @param element
+ * the element that has been decorated
+ *
+ * @return return the decoration style
+ */
+ protected Styler getDecorationStyle(Object element) {
+ return StyledString.DECORATIONS_STYLER;
+ }
+
+ /**
+ * Returns the decorator or null
if no decorator is installed
+ *
+ * @return the decorator or null
if no decorator is installed
+ */
+ public ILabelDecorator getLabelDecorator() {
+ return this.decorator;
+ }
+
+ /**
+ * Sets the label decorator. Removes all known listeners from the old
+ * decorator, and adds all known listeners to the new decorator. The old
+ * decorator is not disposed. Fires a label provider changed event
+ * indicating that all labels should be updated. Has no effect if the given
+ * decorator is identical to the current one.
+ *
+ * @param newDecorator
+ * the label decorator, or null
if no decorations
+ * are to be applied
+ */
+ public void setLabelDecorator(ILabelDecorator newDecorator) {
+ ILabelDecorator oldDecorator = this.decorator;
+ if (oldDecorator !is newDecorator) {
+ if (oldDecorator !is null)
+ oldDecorator.removeListener(this.labelProviderListener);
+ this.decorator = newDecorator;
+ if (newDecorator !is null) {
+ newDecorator.addListener(this.labelProviderListener);
+ }
+ }
+ fireLabelProviderChanged(new LabelProviderChangedEvent(this));
+ }
+
+ public void addListener(ILabelProviderListener listener) {
+ super.addListener(listener);
+ if (this.decorator !is null) {
+ this.decorator.addListener(this.labelProviderListener);
+ }
+ }
+
+ public void removeListener(ILabelProviderListener listener) {
+ super.removeListener(listener);
+ if (this.decorator !is null) {
+ this.decorator.removeListener(this.labelProviderListener);
+ }
+ }
+
+ public bool isLabelProperty(Object element, String property) {
+ if (super.isLabelProperty(element, property)) {
+ return true;
+ }
+ return this.decorator !is null
+ && this.decorator.isLabelProperty(element, property);
+ }
+
+ public void dispose() {
+ super.dispose();
+ if (this.decorator !is null) {
+ this.decorator.removeListener(this.labelProviderListener);
+ this.decorator.dispose();
+ this.decorator = null;
+ }
+ }
+
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/DecorationContext.d
--- a/dwtx/jface/viewers/DecorationContext.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/DecorationContext.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/DecorationOverlayIcon.d
--- a/dwtx/jface/viewers/DecorationOverlayIcon.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/DecorationOverlayIcon.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -158,7 +158,7 @@
* @see java.lang.Object#hashCode()
*/
public override hash_t toHash() {
- int code = base.toHash();
+ int code = System.identityHashCode(base);
for (int i = 0; i < overlays.length; i++) {
if (overlays[i] !is null) {
code ^= overlays[i].toHash();
@@ -177,7 +177,11 @@
drawImage(underlay.getImageData(), 0, 0);
}
}
- drawImage(base.getImageData(), 0, 0);
+ if (overlays.length > IDecoration.REPLACE && overlays[IDecoration.REPLACE] !is null) {
+ drawImage(overlays[IDecoration.REPLACE].getImageData(), 0, 0);
+ } else {
+ drawImage(base.getImageData(), 0, 0);
+ }
drawOverlays(overlays);
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/DelegatingStyledCellLabelProvider.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/viewers/DelegatingStyledCellLabelProvider.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * Port to the D programming language:
+ * Frank Benoit
+ *******************************************************************************/
+module dwtx.jface.viewers.DelegatingStyledCellLabelProvider;
+
+import dwt.graphics.Color;
+import dwt.graphics.Font;
+import dwt.graphics.Image;
+
+/**
+ * A {@link DelegatingStyledCellLabelProvider} is a
+ * {@link StyledCellLabelProvider} that delegates requests for the styled string
+ * and the image to a
+ * {@link DelegatingStyledCellLabelProvider.IStyledLabelProvider}.
+ *
+ *
+ * Existing label providers can be enhanced by implementing
+ * {@link DelegatingStyledCellLabelProvider.IStyledLabelProvider} so they can be
+ * used in viewers with styled labels.
+ *
+ *
+ *
+ * The {@link DelegatingStyledCellLabelProvider.IStyledLabelProvider} can
+ * optionally implement {@link IColorProvider} and {@link IFontProvider} to
+ * provide foreground and background color and a default font.
+ *
+ *
+ * @since 3.4
+ */
+public class DelegatingStyledCellLabelProvider extends StyledCellLabelProvider {
+
+ /**
+ * Interface marking a label provider that provides styled text labels and
+ * images.
+ *
+ * The {@link DelegatingStyledCellLabelProvider.IStyledLabelProvider} can
+ * optionally implement {@link IColorProvider} and {@link IFontProvider} to
+ * provide foreground and background color and a default font.
+ *
+ */
+ public static interface IStyledLabelProvider extends IBaseLabelProvider {
+
+ /**
+ * Returns the styled text label for the given element
+ *
+ * @param element
+ * the element to evaluate the styled string for
+ *
+ * @return the styled string.
+ */
+ public StyledString getStyledText(Object element);
+
+ /**
+ * Returns the image for the label of the given element. The image is
+ * owned by the label provider and must not be disposed directly.
+ * Instead, dispose the label provider when no longer needed.
+ *
+ * @param element
+ * the element for which to provide the label image
+ * @return the image used to label the element, or null
+ * if there is no image for the given object
+ */
+ public Image getImage(Object element);
+ }
+
+ private IStyledLabelProvider styledLabelProvider;
+
+ /**
+ * Creates a {@link DelegatingStyledCellLabelProvider} that delegates the
+ * requests for the styled labels and the images to a
+ * {@link IStyledLabelProvider}.
+ *
+ * @param labelProvider
+ * the label provider that provides the styled labels and the
+ * images
+ */
+ public DelegatingStyledCellLabelProvider(IStyledLabelProvider labelProvider) {
+ if (labelProvider is null)
+ throw new IllegalArgumentException(
+ "Label provider must not be null"); //$NON-NLS-1$
+
+ this.styledLabelProvider = labelProvider;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.StyledCellLabelProvider#update(dwtx.jface.viewers.ViewerCell)
+ */
+ public void update(ViewerCell cell) {
+ Object element = cell.getElement();
+
+ StyledString styledString = getStyledText(element);
+ cell.setText(styledString.toString());
+ if (isOwnerDrawEnabled()) {
+ cell.setStyleRanges(styledString.getStyleRanges());
+ } else {
+ cell.setStyleRanges(null);
+ }
+
+ cell.setImage(getImage(element));
+ cell.setFont(getFont(element));
+ cell.setForeground(getForeground(element));
+ cell.setBackground(getBackground(element));
+
+ super.update(cell);
+ }
+
+ /**
+ * Provides a foreground color for the given element.
+ *
+ * @param element
+ * the element
+ * @return the foreground color for the element, or null
to
+ * use the default foreground color
+ */
+ public Color getForeground(Object element) {
+ if (this.styledLabelProvider instanceof IColorProvider) {
+ return ((IColorProvider) this.styledLabelProvider)
+ .getForeground(element);
+ }
+ return null;
+ }
+
+ /**
+ * Provides a background color for the given element.
+ *
+ * @param element
+ * the element
+ * @return the background color for the element, or null
to
+ * use the default background color
+ */
+ public Color getBackground(Object element) {
+ if (this.styledLabelProvider instanceof IColorProvider) {
+ return ((IColorProvider) this.styledLabelProvider)
+ .getBackground(element);
+ }
+ return null;
+ }
+
+ /**
+ * Provides a font for the given element.
+ *
+ * @param element
+ * the element
+ * @return the font for the element, or null
to use the
+ * default font
+ */
+ public Font getFont(Object element) {
+ if (this.styledLabelProvider instanceof IFontProvider) {
+ return ((IFontProvider) this.styledLabelProvider).getFont(element);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the image for the label of the given element. The image is owned
+ * by the label provider and must not be disposed directly. Instead, dispose
+ * the label provider when no longer needed.
+ *
+ * @param element
+ * the element for which to provide the label image
+ * @return the image used to label the element, or null
if
+ * there is no image for the given object
+ */
+ public Image getImage(Object element) {
+ return this.styledLabelProvider.getImage(element);
+ }
+
+ /**
+ * Returns the styled text for the label of the given element.
+ *
+ * @param element
+ * the element for which to provide the styled label text
+ * @return the styled text string used to label the element
+ */
+ protected StyledString getStyledText(Object element) {
+ return this.styledLabelProvider.getStyledText(element);
+ }
+
+ /**
+ * Returns the styled string provider.
+ *
+ * @return the wrapped label provider
+ */
+ public IStyledLabelProvider getStyledStringProvider() {
+ return this.styledLabelProvider;
+ }
+
+ public void addListener(ILabelProviderListener listener) {
+ super.addListener(listener);
+ this.styledLabelProvider.addListener(listener);
+ }
+
+ public void removeListener(ILabelProviderListener listener) {
+ super.removeListener(listener);
+ this.styledLabelProvider.removeListener(listener);
+ }
+
+ public bool isLabelProperty(Object element, String property) {
+ return this.styledLabelProvider.isLabelProperty(element, property);
+ }
+
+ public void dispose() {
+ super.dispose();
+ this.styledLabelProvider.dispose();
+ }
+
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/EditingSupport.d
--- a/dwtx/jface/viewers/EditingSupport.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/EditingSupport.d Thu May 22 01:36:46 2008 +0200
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - initial API and implementation
- * fix in bug 151295,167325,200558
+ * fix in bug 151295,167325,201905
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/FocusCellHighlighter.d
--- a/dwtx/jface/viewers/FocusCellHighlighter.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/FocusCellHighlighter.d Thu May 22 01:36:46 2008 +0200
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Tom Schindl - initial API and implementation
+ * bugfix in: 182800
* Port to the D programming language:
* Frank Benoit
******************************************************************************/
@@ -40,9 +42,12 @@
}
/**
- * Called by the framework when the focus cell has changed. Subclasses may extend.
+ * Called by the framework when the focus cell has changed. Subclasses may
+ * extend.
*
- * @param cell the new focus cell
+ * @param cell
+ * the new focus cell
+ * @deprecated use {@link #focusCellChanged(ViewerCell, ViewerCell)} instead
*/
protected void focusCellChanged(ViewerCell cell) {
}
@@ -51,6 +56,26 @@
}
/**
+ * Called by the framework when the focus cell has changed. Subclasses may
+ * extend.
+ *
+ * The default implementation for this method calls
+ * focusCellChanged(ViewerCell). Subclasses should override this method
+ * rather than {@link #focusCellChanged(ViewerCell)} .
+ *
+ * @param newCell
+ * the new focus cell or null
if no new cell
+ * receives the focus
+ * @param oldCell
+ * the old focus cell or null
if no cell has been
+ * focused before
+ * @since 3.4
+ */
+ protected void focusCellChanged(ViewerCell newCell, ViewerCell oldCell) {
+ focusCellChanged(newCell);
+ }
+
+ /**
* This method is called by the framework to initialize this cell
* highlighter object. Subclasses may extend.
*/
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/FocusCellOwnerDrawHighlighter.d
--- a/dwtx/jface/viewers/FocusCellOwnerDrawHighlighter.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/FocusCellOwnerDrawHighlighter.d Thu May 22 01:36:46 2008 +0200
@@ -1,17 +1,17 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2008 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
* Tom Schindl - initial API and implementation
- * - fix for bug 183850, 182652
- * IBM Corporation - initial API and implementation
+ * - fix for bug 183850, 182652, 182800, 215069
* Port to the D programming language:
* Frank Benoit
- ******************************************************************************/
+ *******************************************************************************/
module dwtx.jface.viewers.FocusCellOwnerDrawHighlighter;
@@ -31,21 +31,22 @@
import dwt.dwthelper.utils;
/**
+ * A concrete implementation of {@link FocusCellHighlighter} using by setting
+ * the control into owner draw mode and highlighting the currently selected
+ * cell. To make the use this class you should create the control with the
+ * {@link DWT#FULL_SELECTION} bit set
+ *
+ * This class can be subclassed to configure how the coloring of the selected
+ * cell.
+ *
* @since 3.3
*
*/
public class FocusCellOwnerDrawHighlighter : FocusCellHighlighter {
-
- private ViewerCell oldCell;
-
- // Needed to work-around problem in bug 183850
- private static const bool WIN_32;
-
- static this(){
- WIN_32 = "win32".equals(DWT.getPlatform()); //$NON-NLS-1$
- }
-
/**
+ * Create a new instance which can be passed to a
+ * {@link TreeViewerFocusCellManager}
+ *
* @param viewer
* the viewer
*/
@@ -55,10 +56,12 @@
}
private void markFocusedCell(Event event, ViewerCell cell) {
- Color background = getSelectedCellBackgroundColor(cell);
- Color foreground = getSelectedCellForegroundColor(cell);
+ Color background = (cell.getControl().isFocusControl()) ? getSelectedCellBackgroundColor(cell)
+ : getSelectedCellBackgroundColorNoFocus(cell);
+ Color foreground = (cell.getControl().isFocusControl()) ? getSelectedCellForegroundColor(cell)
+ : getSelectedCellForegroundColorNoFocus(cell);
- if ( WIN_32 || foreground !is null || background !is null) {
+ if (foreground !is null || background !is null || onlyTextHighlighting(cell)) {
GC gc = event.gc;
if (background is null) {
@@ -73,10 +76,18 @@
gc.setBackground(background);
gc.setForeground(foreground);
- gc.fillRectangle(event.getBounds());
-
- // This is a workaround for an DWT-Bug on WinXP bug 169517
- gc.drawText(" ", cell.getBounds().x, cell.getBounds().y, false); //$NON-NLS-1$
+
+ if (onlyTextHighlighting(cell)) {
+ Rectangle area = event.getBounds();
+ Rectangle rect = cell.getTextBounds();
+ if( rect !is null ) {
+ area.x = rect.x;
+ }
+ gc.fillRectangle(area);
+ } else {
+ gc.fillRectangle(event.getBounds());
+ }
+
event.detail &= ~DWT.SELECTED;
}
}
@@ -88,8 +99,6 @@
gc.setForeground(cell.getViewerRow().getForeground(
cell.getColumnIndex()));
gc.fillRectangle(cell.getBounds());
- // This is a workaround for an DWT-Bug on WinXP bug 169517
- gc.drawText(" ", cell.getBounds().x, cell.getBounds().y, false); //$NON-NLS-1$
event.detail &= ~DWT.SELECTED;
}
@@ -123,39 +132,81 @@
}
/**
+ * The color to use when rendering the background of the selected cell when
+ * the control has the input focus
+ *
* @param cell
* the cell which is colored
- * @return the color
+ * @return the color or null
to use the default
*/
protected Color getSelectedCellBackgroundColor(ViewerCell cell) {
return null;
}
/**
+ * The color to use when rendering the foreground (=text) of the selected
+ * cell when the control has the input focus
+ *
* @param cell
* the cell which is colored
- * @return the color
+ * @return the color or null
to use the default
*/
protected Color getSelectedCellForegroundColor(ViewerCell cell) {
return null;
}
- /*
- * (non-Javadoc)
- *
- * @see dwtx.jface.viewers.FocusCellHighlighter#focusCellChanged(dwtx.jface.viewers.ViewerCell)
+ /**
+ * The color to use when rendering the foreground (=text) of the selected
+ * cell when the control has no input focus
+ *
+ * @param cell
+ * the cell which is colored
+ * @return the color or null
to use the same used when
+ * control has focus
+ * @since 3.4
*/
- protected override void focusCellChanged(ViewerCell cell) {
- super.focusCellChanged(cell);
+ protected Color getSelectedCellForegroundColorNoFocus(ViewerCell cell) {
+ return null;
+ }
+
+ /**
+ * The color to use when rendering the background of the selected cell when
+ * the control has no input focus
+ *
+ * @param cell
+ * the cell which is colored
+ * @return the color or null
to use the same used when
+ * control has focus
+ * @since 3.4
+ */
+ protected Color getSelectedCellBackgroundColorNoFocus(ViewerCell cell) {
+ return null;
+ }
+
+ /**
+ * Controls whether the whole cell or only the text-area is highlighted
+ *
+ * @param cell
+ * the cell which is highlighted
+ * @return true
if only the text area should be highlighted
+ * @since 3.4
+ */
+ protected bool onlyTextHighlighting(ViewerCell cell) {
+ return false;
+ }
+
+ protected void focusCellChanged(ViewerCell newCell, ViewerCell oldCell) {
+ super.focusCellChanged(newCell, oldCell);
// Redraw new area
- if (cell !is null) {
- Rectangle rect = cell.getBounds();
- int x = cell.getColumnIndex() is 0 ? 0 : rect.x;
- int width = cell.getColumnIndex() is 0 ? rect.x + rect.width
+ if (newCell !is null) {
+ Rectangle rect = newCell.getBounds();
+ int x = newCell.getColumnIndex() is 0 ? 0 : rect.x;
+ int width = newCell.getColumnIndex() is 0 ? rect.x + rect.width
: rect.width;
// 1 is a fix for Linux-GTK
- cell.getControl().redraw(x, rect.y-1, width, rect.height+1, true);
+ newCell.getControl().redraw(x, rect.y - 1, width, rect.height + 1,
+ true);
}
if (oldCell !is null) {
@@ -164,9 +215,8 @@
int width = oldCell.getColumnIndex() is 0 ? rect.x + rect.width
: rect.width;
// 1 is a fix for Linux-GTK
- oldCell.getControl().redraw(x, rect.y-1, width, rect.height+1, true);
+ oldCell.getControl().redraw(x, rect.y - 1, width, rect.height + 1,
+ true);
}
-
- this.oldCell = cell;
}
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/IDecoration.d
--- a/dwtx/jface/viewers/IDecoration.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/IDecoration.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -54,6 +54,28 @@
public static const int UNDERLAY = 4;
/**
+ * Constant for replacing the original image. Note that for this to have an
+ * effect on the resulting decorated image, {@link #ENABLE_REPLACE} has to
+ * be set to {@link Boolean#TRUE} in the {@link IDecorationContext} (opt-in
+ * model). If replacement behavior is enabled, the resulting decorated image
+ * will be constructed by first painting the underlay, then the replacement
+ * image, and then the regular quadrant images.
+ *
+ * @since 3.4
+ */
+ public static final int REPLACE = 5;
+
+ /**
+ * Constant that is used as the property key on an
+ * {@link IDecorationContext}. To enable image replacement, set to
+ * {@link Boolean#TRUE}.
+ *
+ * @since 3.4
+ * @see IDecorationContext
+ */
+ public static final String ENABLE_REPLACE = "dwtx.jface.viewers.IDecoration.disableReplace"; //$NON-NLS-1$
+
+ /**
* Adds a prefix to the element's label.
*
* @param prefix
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/IStructuredContentProvider.d
--- a/dwtx/jface/viewers/IStructuredContentProvider.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/IStructuredContentProvider.d Thu May 22 01:36:46 2008 +0200
@@ -25,7 +25,12 @@
* when its input is set to the given element.
* These elements can be presented as rows in a table, items in a list, etc.
* The result is not modified by the viewer.
- *
+ *
+ * NOTE: For instances where the viewer is displaying a tree
+ * containing a single 'root' element it is still necessary that the
+ * 'input' does not return itself from this method. This leads
+ * to recursion issues (see bug 9262).
+ *
* @param inputElement the input element
* @return the array of elements to display in the viewer
*/
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/IStructuredSelection.d
--- a/dwtx/jface/viewers/IStructuredSelection.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/IStructuredSelection.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -52,6 +52,9 @@
/**
* Returns the elements in this selection as a List
.
+ * Note In the default implementation of {@link #toList()} in
+ * {@link StructuredSelection} the returned list is not a copy of the elements of the
+ * receiver and modifying it will modify the contents of the selection.
*
* @return the selected elements as a list
*/
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ITreeSelection.d
--- a/dwtx/jface/viewers/ITreeSelection.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ITreeSelection.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2007 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
@@ -19,6 +19,25 @@
/**
* A selection containing tree paths.
+ *
+ * It is recommended that clients do not implement this interface but instead
+ * use the standard implementation of this interface, {@link TreeSelection}.
+ * TreeSelection
adds API for getting the {@link IElementComparer}
+ * of a selection (if available). This is important for clients who want to
+ * create a slightly modified tree selection based on an existing tree selection.
+ * The recommended coding pattern in this case is as follows:
+ *
+ * ITreeSelection selection = (ITreeSelection)treeViewer.getSelection();
+ * TreePath[] paths = selection.getPaths();
+ * IElementComparer comparer = null;
+ * if (selection instanceof TreeSelection) {
+ * comparer = ((TreeSelection)selection).getElementComparer();
+ * }
+ * TreePath[] modifiedPaths = ... // modify as required
+ * TreeSelection modifiedSelection = new TreeSelection(modifiedPaths, comparer);
+ *
+ * See bugs 135818 and 133375 for details.
+ *
*
* @since 3.2
*
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/NamedHandleObjectLabelProvider.d
--- a/dwtx/jface/viewers/NamedHandleObjectLabelProvider.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/NamedHandleObjectLabelProvider.d Thu May 22 01:36:46 2008 +0200
@@ -1,55 +1,56 @@
-/*******************************************************************************
- * 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
- * Port to the D programming language:
- * Frank Benoit
- *******************************************************************************/
-
-module dwtx.jface.viewers.NamedHandleObjectLabelProvider;
-
-import dwtx.jface.viewers.DialogCellEditor;
-import dwtx.jface.viewers.LabelProvider;
-
-
-import dwtx.core.commands.common.NamedHandleObject;
-import dwtx.core.commands.common.NotDefinedException;
-
-import dwt.dwthelper.utils;
-
-/**
- * A label provider for instances of NamedHandlerObject
, which
- * exposes the name as the label.
- *
- * @since 3.2
- */
-public final class NamedHandleObjectLabelProvider : LabelProvider {
-
- /**
- * The text of the element is simply the name of the element if its a
- * defined instance of NamedHandleObject
. Otherwise, this
- * method just returns null
.
- *
- * @param element
- * The element for which the text should be retrieved; may be
- * null
.
- * @return the name of the handle object; null
if there is no
- * name or if the element is not a named handle object.
- */
- public override final String getText(Object element) {
- if ( cast(NamedHandleObject)element ) {
- try {
- return (cast(NamedHandleObject) element).getName();
- } catch (NotDefinedException e) {
- return null;
- }
- }
-
- return null;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ * Port to the D programming language:
+ * Frank Benoit
+ *******************************************************************************/
+
+module dwtx.jface.viewers.NamedHandleObjectLabelProvider;
+
+import dwtx.jface.viewers.DialogCellEditor;
+import dwtx.jface.viewers.LabelProvider;
+
+
+import dwtx.core.commands.common.NamedHandleObject;
+import dwtx.core.commands.common.NotDefinedException;
+
+import dwt.dwthelper.utils;
+
+/**
+ * A label provider for instances of NamedHandlerObject
, which
+ * exposes the name as the label.
+ *
+ * @since 3.2
+ */
+public final class NamedHandleObjectLabelProvider : LabelProvider {
+
+ /**
+ * The text of the element is simply the name of the element if its a
+ * defined instance of NamedHandleObject
. Otherwise, this
+ * method just returns null
.
+ *
+ * @param element
+ * The element for which the text should be retrieved; may be
+ * null
.
+ * @return the name of the handle object; null
if there is no
+ * name or if the element is not a named handle object.
+ */
+ public override final String getText(Object element) {
+ if ( cast(NamedHandleObject)element ) {
+ try {
+ return (cast(NamedHandleObject) element).getName();
+ } catch (NotDefinedException e) {
+ return null;
+ }
+ }
+
+ return null;
+ }
+}
+
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/SWTFocusCellManager.d
--- a/dwtx/jface/viewers/SWTFocusCellManager.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/SWTFocusCellManager.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2008 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
@@ -8,10 +8,10 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - initial API and implementation
- * - bug fix for bug 187189
+ * - bug fix for bug 187189, 182800, 215069
* Port to the D programming language:
* Frank Benoit
- ******************************************************************************/
+ *******************************************************************************/
module dwtx.jface.viewers.SWTFocusCellManager;
@@ -52,6 +52,7 @@
private DisposeListener itemDeletionListener;
+
/**
* @param viewer
* @param focusDrawingDelegate
@@ -114,8 +115,8 @@
}
private void handleSelection(Event event) {
- if (focusCell !is null && focusCell.getItem() !is event.item
- && event.item !is null) {
+ if ((event.detail & DWT.CHECK) is 0 && focusCell !is null && focusCell.getItem() !is event.item
+ && event.item !is null ) {
ViewerRow row = viewer.getViewerRowFromItem_package(event.item);
Assert
.isNotNull(row,
@@ -180,6 +181,8 @@
}
void setFocusCell(ViewerCell focusCell) {
+ ViewerCell oldCell = this.focusCell;
+
if( this.focusCell !is null && ! this.focusCell.getItem().isDisposed() ) {
this.focusCell.getItem().removeDisposeListener(itemDeletionListener);
}
@@ -190,7 +193,7 @@
this.focusCell.getItem().addDisposeListener(itemDeletionListener);
}
- this.cellHighlighter.focusCellChanged_package(focusCell);
+ this.cellHighlighter.focusCellChanged/*_package*/(focusCell,oldCell);
}
ColumnViewer getViewer() {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/StructuredSelection.d
--- a/dwtx/jface/viewers/StructuredSelection.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/StructuredSelection.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -41,6 +41,11 @@
private Object[] elements;
/**
+ * The element comparer, or null
+ */
+ private IElementComparer comparer;
+
+ /**
* The canonical empty selection. This selection should be used instead of
* null
.
*/
@@ -83,8 +88,24 @@
* @param elements list of selected elements
*/
public this(SeqView!(Object) elements) {
- Assert.isNotNull(cast(Object)elements);
+ this(elements, null);
+ }
+
+ /**
+ * Creates a structured selection from the given List
and
+ * element comparer. If an element comparer is provided, it will be used to
+ * determine equality between structured selection objects provided that
+ * they both are based on the same (identical) comparer. See bug
+ *
+ * @param elements
+ * list of selected elements
+ * @param comparer
+ * the comparer, or null
+ * @since 3.4
+ */
+ public StructuredSelection(List elements, IElementComparer comparer) {
this.elements = elements.toArray();
+ this.comparer = comparer;
}
/**
@@ -113,6 +134,8 @@
return false;
}
+ bool useComparer = comparer !is null && comparer is s2.comparer;
+
//size
int myLen = elements.length;
if (myLen !is s2.elements.length) {
@@ -120,8 +143,14 @@
}
//element comparison
for (int i = 0; i < myLen; i++) {
- if (!elements[i].opEquals(s2.elements[i])) {
- return false;
+ if (useComparer) {
+ if (!comparer.equals(elements[i], s2.elements[i])) {
+ return false;
+ }
+ } else {
+ if (!elements[i].equals(s2.elements[i])) {
+ return false;
+ }
}
}
return true;
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/StructuredViewer.d
--- a/dwtx/jface/viewers/StructuredViewer.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/StructuredViewer.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -334,7 +334,7 @@
}
/**
- * The ColorAndFontManager collects fonts and colors without a
+ * The ColorAndFontCollector collects fonts and colors without a
* a color or font provider.
*
*/
@@ -1025,7 +1025,7 @@
return StructuredSelection.EMPTY;
}
auto list = getSelectionFromWidget();
- return new StructuredSelection(list);
+ return new StructuredSelection(list, comparer);
}
/**
@@ -1382,9 +1382,7 @@
* setSelectionToWidget
* rediscovers the resulting selection (via getSelection
)
*
- * calls handleInvalidSelection
if the selection did not
- * take
- * calls postUpdateHook
+ * calls handleInvalidSelection
if the resulting selection is different from the old selection
*
*
*
@@ -1410,7 +1408,6 @@
*
* calls handleInvalidSelection
if the selection did not
* take
- * calls postUpdateHook
*
*
*
@@ -1539,7 +1536,7 @@
/**
*
- * Refreshes the given TableItem with the given element. Calls
+ * Refreshes the given item with the given element. Calls
* doUpdateItem(..., false)
.
*
* This method is internal to the framework; subclassers should not call
@@ -1947,6 +1944,9 @@
}
}
+ // flag to indicate that a full refresh took place. See bug 102440.
+ private bool refreshOccurred;
+
/**
* Updates the given elements' presentation when one or more of their
* properties change. Only the given elements are updated.
@@ -1987,8 +1987,17 @@
* indicate unknown
*/
public void update(Object[] elements, String[] properties) {
- for (int i = 0; i < elements.length; ++i) {
- update(elements[i], properties);
+ bool previousValue = refreshOccurred;
+ refreshOccurred = false;
+ try {
+ for (int i = 0; i < elements.length; ++i) {
+ update(elements[i], properties);
+ if (refreshOccurred) {
+ return;
+ }
+ }
+ } finally {
+ refreshOccurred = previousValue;
}
}
@@ -2035,8 +2044,13 @@
Assert.isNotNull(element);
Widget[] items = findItems(element);
+ bool mayExitEarly = !refreshOccurred;
for (int i = 0; i < items.length; i++) {
internalUpdate(items[i], element, properties);
+ if (mayExitEarly && refreshOccurred) {
+ // detected a change from refreshOccurredisfalse to refreshOccurredistrue
+ return;
+ }
}
}
@@ -2073,6 +2087,7 @@
preservingSelection(new class Runnable {
public void run() {
internalRefresh(getRoot());
+ refreshOccurred = true;
}
});
return;
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/StyledCellLabelProvider.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/viewers/StyledCellLabelProvider.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,384 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 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
+ * Michael Krkoska - initial API and implementation (bug 188333)
+ * Port to the D programming language:
+ * Frank Benoit
+ *******************************************************************************/
+module dwtx.jface.viewers.StyledCellLabelProvider;
+
+
+import dwt.DWT;
+import dwt.custom.StyleRange;
+import dwt.graphics.Color;
+import dwt.graphics.GC;
+import dwt.graphics.Image;
+import dwt.graphics.Rectangle;
+import dwt.graphics.TextLayout;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwtx.core.runtime.Assert;
+
+/**
+ * A {@link StyledCellLabelProvider} supports styled labels by using owner
+ * draw.
+ * Besides the styles in labels, the label provider preserves native viewer behavior:
+ *
+ * - similar image and label positioning
+ * - native drawing of focus and selection
+ *
+ *
+ * For providing the label's styles, create a subclass and overwrite
+ * {@link StyledCellLabelProvider#update(ViewerCell)} to
+ * return set all information needed to render a element. Use
+ * {@link ViewerCell#setStyleRanges(StyleRange[])} to set style ranges
+ * on the label.
+ *
+ *
+ * The current version of the {@link StyledCellLabelProvider} will ignore all font settings on
+ * {@link StyleRange}. Different fonts would make labels wider, and the native
+ * selection drawing could not be reused.
+ *
+ *
+ * NOTE: This API is experimental and may be deleted or
+ * changed before 3.4 is released.
+ *
+ * @since 3.4
+ */
+public abstract class StyledCellLabelProvider extends OwnerDrawLabelProvider {
+
+ /**
+ * Style constant for indicating that the styled colors are to be applied
+ * even it the viewer's item is selected. Default is not to apply colors.
+ */
+ public static final int COLORS_ON_SELECTION = 1 << 0;
+
+ /**
+ * Style constant for indicating to draw the focus if requested by the owner
+ * draw event. Default is to draw the focus.
+ */
+ public static final int NO_FOCUS = 1 << 1;
+
+ /**
+ * Private constant to indicate if owner draw is enabled for the
+ * label provider's column.
+ */
+ private static final int OWNER_DRAW_ENABLED = 1 << 4;
+
+ private int style;
+
+ // reused text layout
+ private TextLayout cachedTextLayout;
+
+ private ColumnViewer viewer;
+ private ViewerColumn column;
+
+ /**
+ * Creates a new StyledCellLabelProvider. By default, owner draw is enabled, focus is drawn and no
+ * colors are painted on selected elements.
+ */
+ public StyledCellLabelProvider() {
+ this(0);
+ }
+
+ /**
+ * Creates a new StyledCellLabelProvider. By default, owner draw is enabled.
+ *
+ * @param style
+ * the style bits
+ * @see StyledCellLabelProvider#COLORS_ON_SELECTION
+ * @see StyledCellLabelProvider#NO_FOCUS
+ */
+ public StyledCellLabelProvider(int style) {
+ this.style = style & (COLORS_ON_SELECTION | NO_FOCUS)
+ | OWNER_DRAW_ENABLED;
+ }
+
+ /**
+ * Returns true
is the owner draw rendering is enabled for this label provider.
+ * By default owner draw rendering is enabled. If owner draw rendering is disabled, rending is
+ * done by the viewer and no styled ranges (see {@link ViewerCell#getStyleRanges()})
+ * are drawn.
+ *
+ * @return true
is the rendering of styles is enabled.
+ */
+ public bool isOwnerDrawEnabled() {
+ return (this.style & OWNER_DRAW_ENABLED) !is 0;
+ }
+
+ /**
+ * Specifies whether owner draw rendering is enabled for this label
+ * provider. By default owner draw rendering is enabled. If owner draw
+ * rendering is disabled, rendering is done by the viewer and no styled
+ * ranges (see {@link ViewerCell#getStyleRanges()}) are drawn.
+ * It is the caller's responsibility to also call
+ * {@link StructuredViewer#refresh()} or similar methods to update the
+ * underlying widget.
+ *
+ * @param enabled
+ * specifies if owner draw rendering is enabled
+ */
+ public void setOwnerDrawEnabled(bool enabled) {
+ bool isEnabled= isOwnerDrawEnabled();
+ if (isEnabled !is enabled) {
+ if (enabled) {
+ this.style |= OWNER_DRAW_ENABLED;
+ } else {
+ this.style &= ~OWNER_DRAW_ENABLED;
+ }
+ if (this.viewer !is null) {
+ setOwnerDrawEnabled(this.viewer, this.column, enabled);
+ }
+ }
+ }
+
+ /**
+ * Returns the viewer on which this label provider is installed on or null
if the
+ * label provider is not installed.
+ *
+ * @return the viewer on which this label provider is installed on or null
if the
+ * label provider is not installed.
+ */
+ protected final ColumnViewer getViewer() {
+ return this.viewer;
+ }
+
+ /**
+ * Returns the column on which this label provider is installed on or null
if the
+ * label provider is not installed.
+ *
+ * @return the column on which this label provider is installed on or null
if the
+ * label provider is not installed.
+ */
+ protected final ViewerColumn getColumn() {
+ return this.column;
+ }
+
+ /* (non-Javadoc)
+ * @see dwtx.jface.viewers.OwnerDrawLabelProvider#initialize(dwtx.jface.viewers.ColumnViewer, dwtx.jface.viewers.ViewerColumn)
+ */
+ public void initialize(ColumnViewer viewer, ViewerColumn column) {
+ Assert.isTrue(this.viewer is null && this.column is null, "Label provider instance already in use"); //$NON-NLS-1$
+
+ this.viewer= viewer;
+ this.column= column;
+ super.initialize(viewer, column, isOwnerDrawEnabled());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.BaseLabelProvider#dispose()
+ */
+ public void dispose() {
+ if (this.cachedTextLayout !is null) {
+ cachedTextLayout.dispose();
+ cachedTextLayout = null;
+ }
+
+ this.viewer= null;
+ this.column= null;
+
+ super.dispose();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.OwnerDrawLabelProvider#update(dwtx.jface.viewers.ViewerCell)
+ */
+ public void update(ViewerCell cell) {
+ // clients must override and configure the cell and call super
+ super.update(cell); // calls 'repaint' to trigger the paint listener
+ }
+
+ private TextLayout getSharedTextLayout(Display display) {
+ if (cachedTextLayout is null) {
+ int orientation = viewer.getControl().getStyle() & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT);
+ cachedTextLayout = new TextLayout(display);
+ cachedTextLayout.setOrientation(orientation);
+ } else {
+ cachedTextLayout.setText(""); // make sure no previous ranges are cleared //$NON-NLS-1$
+ }
+ return cachedTextLayout;
+ }
+
+ private bool useColors(Event event) {
+ return (event.detail & DWT.SELECTED) is 0
+ || (this.style & COLORS_ON_SELECTION) !is 0;
+ }
+
+ private bool drawFocus(Event event) {
+ return (event.detail & DWT.FOCUSED) !is 0
+ && (this.style & NO_FOCUS) is 0;
+ }
+
+ /**
+ * Returns a {@link TextLayout} instance for the given cell
+ * configured with the style ranges. The text layout instance is managed by
+ * the label provider. Caller of the method must not dispose the text
+ * layout.
+ *
+ * @param diplay
+ * the current display
+ * @param applyColors
+ * if set, create colors in the result
+ * @param cell
+ * the viewer cell
+ * @return a TextLayout instance
+ */
+ private TextLayout getTextLayoutForInfo(Display display, ViewerCell cell, bool applyColors) {
+ TextLayout layout = getSharedTextLayout(display);
+
+ layout.setText(cell.getText());
+ layout.setFont(cell.getFont()); // set also if null to clear previous usages
+
+ StyleRange[] styleRanges = cell.getStyleRanges();
+ if (styleRanges !is null) { // user didn't fill styled ranges
+ for (int i = 0; i < styleRanges.length; i++) {
+ StyleRange curr = prepareStyleRange(styleRanges[i], applyColors);
+ layout.setStyle(curr, curr.start, curr.start + curr.length - 1);
+ }
+ }
+
+ return layout;
+ }
+
+ /**
+ * Prepares the given style range before it is applied to the label. This method makes sure that
+ * no colors are drawn when the element is selected.
+ * The current version of the {@link StyledCellLabelProvider} will also ignore all font settings on the
+ * style range. Clients can override.
+ *
+ * @param styleRange
+ * the style range to prepare. the style range element must not be modified
+ * @param applyColors
+ * specifies if colors should be applied.
+ * @return
+ * returns the style range to use on the label
+ */
+ protected StyleRange prepareStyleRange(StyleRange styleRange, bool applyColors) {
+ // if no colors apply or font is set, create a clone and clear the
+ // colors and font
+ if (styleRange.font !is null || !applyColors
+ && (styleRange.foreground !is null || styleRange.background !is null)) {
+ styleRange = (StyleRange) styleRange.clone();
+ styleRange.font = null; // ignore font settings until bug 168807 is resolved
+ if (!applyColors) {
+ styleRange.foreground = null;
+ styleRange.background = null;
+ }
+ }
+ return styleRange;
+ }
+
+ private ViewerCell getViewerCell(Event event, Object element) {
+ ViewerRow row= viewer.getViewerRowFromItem(event.item);
+ return new ViewerCell(row, event.index, element);
+ }
+
+ /**
+ * Handle the erase event. The default implementation does nothing to ensure
+ * keep native selection highlighting working.
+ *
+ * @param event
+ * the erase event
+ * @param element
+ * the model object
+ * @see DWT#EraseItem
+ */
+ protected void erase(Event event, Object element) {
+ // use native erase
+ if (isOwnerDrawEnabled()) {
+ // info has been set by 'update': announce that we paint ourselves
+ event.detail &= ~DWT.FOREGROUND;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.OwnerDrawLabelProvider#measure(dwt.widgets.Event,
+ * java.lang.Object)
+ */
+ protected void measure(Event event, Object element) {
+ // use native measuring
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.OwnerDrawLabelProvider#paint(dwt.widgets.Event,
+ * java.lang.Object)
+ */
+ protected void paint(Event event, Object element) {
+ if (!isOwnerDrawEnabled())
+ return;
+
+ ViewerCell cell= getViewerCell(event, element);
+
+ bool applyColors = useColors(event);
+ GC gc = event.gc;
+ // remember colors to restore the GC later
+ Color oldForeground = gc.getForeground();
+ Color oldBackground = gc.getBackground();
+
+ if (applyColors) {
+ Color foreground= cell.getForeground();
+ if (foreground !is null) {
+ gc.setForeground(foreground);
+ }
+
+ Color background= cell.getBackground();
+ if (background !is null) {
+ gc.setBackground(background);
+ }
+ }
+
+ Image image = cell.getImage();
+ if (image !is null) {
+ Rectangle imageBounds = cell.getImageBounds();
+ if (imageBounds !is null) {
+ Rectangle bounds = image.getBounds();
+
+ // center the image in the given space
+ int x = imageBounds.x
+ + Math.max(0, (imageBounds.width - bounds.width) / 2);
+ int y = imageBounds.y
+ + Math.max(0, (imageBounds.height - bounds.height) / 2);
+ gc.drawImage(image, x, y);
+ }
+ }
+
+ TextLayout textLayout = getTextLayoutForInfo(event.display, cell, applyColors);
+
+ Rectangle textBounds = cell.getTextBounds();
+ if (textBounds !is null) {
+ Rectangle layoutBounds = textLayout.getBounds();
+
+ int x = textBounds.x;
+ int y = textBounds.y
+ + Math.max(0, (textBounds.height - layoutBounds.height) / 2);
+
+ textLayout.draw(gc, x, y);
+ }
+
+ if (drawFocus(event)) {
+ Rectangle focusBounds = cell.getViewerRow().getBounds();
+ gc.drawFocus(focusBounds.x, focusBounds.y, focusBounds.width,
+ focusBounds.height);
+ }
+
+ if (applyColors) {
+ gc.setForeground(oldForeground);
+ gc.setBackground(oldBackground);
+ }
+ }
+
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/StyledString.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/viewers/StyledString.d Thu May 22 01:36:46 2008 +0200
@@ -0,0 +1,511 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * Port to the D programming language:
+ * Frank Benoit
+ *******************************************************************************/
+module dwtx.jface.viewers.StyledString;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import dwt.custom.StyleRange;
+import dwt.graphics.TextStyle;
+import dwtx.jface.preference.JFacePreferences;
+import dwtx.jface.resource.ColorRegistry;
+import dwtx.jface.resource.JFaceResources;
+
+/**
+ * A mutable string with styled ranges. All ranges mark substrings of the string
+ * and do not overlap. Styles are applied using instances of {@link Styler} to
+ * compute the result of {@link #getStyleRanges()}.
+ *
+ * The styled string can be built in the following two ways:
+ *
+ * - new strings with stylers can be appended
+ * - stylers can by applied to ranges of the existing string
+ *
+ *
+ *
+ * This class may be instantiated; it is not intended to be subclassed.
+ *
+ *
+ * @since 3.4
+ */
+public class StyledString {
+
+ /**
+ * A styler will be asked to apply its styles to one ore more ranges in the
+ * {@link StyledString}.
+ *
+ */
+ public static abstract class Styler {
+
+ /**
+ * Applies the styles represented by this object to the given textStyle.
+ *
+ * @param textStyle
+ * the {@link TextStyle} to modify
+ */
+ public abstract void applyStyles(TextStyle textStyle);
+ }
+
+ /**
+ * A built-in styler using the {@link JFacePreferences#QUALIFIER_COLOR}
+ * managed in the JFace color registry (See
+ * {@link JFaceResources#getColorRegistry()}).
+ */
+ public static final Styler QUALIFIER_STYLER = createColorRegistryStyler(
+ JFacePreferences.QUALIFIER_COLOR, null);
+
+ /**
+ * A built-in styler using the {@link JFacePreferences#COUNTER_COLOR}
+ * managed in the JFace color registry (See
+ * {@link JFaceResources#getColorRegistry()}).
+ */
+ public static final Styler COUNTER_STYLER = createColorRegistryStyler(
+ JFacePreferences.COUNTER_COLOR, null);
+
+ /**
+ * A built-in styler using the {@link JFacePreferences#DECORATIONS_COLOR}
+ * managed in the JFace color registry (See
+ * {@link JFaceResources#getColorRegistry()}).
+ */
+ public static final Styler DECORATIONS_STYLER = createColorRegistryStyler(
+ JFacePreferences.DECORATIONS_COLOR, null);
+
+ /**
+ * Creates a styler that takes the given foreground and background colors
+ * from the JFace color registry.
+ *
+ * @param foregroundColorName
+ * the color name for the foreground color
+ * @param backgroundColorName
+ * the color name for the background color
+ *
+ * @return the created style
+ */
+ public static Styler createColorRegistryStyler(String foregroundColorName,
+ String backgroundColorName) {
+ return new DefaultStyler(foregroundColorName, backgroundColorName);
+ }
+
+ private static final StyleRange[] EMPTY = new StyleRange[0];
+ private StringBuffer fBuffer;
+ private StyleRunList fStyleRuns;
+
+ /**
+ * Creates an empty {@link StyledString}.
+ */
+ public StyledString() {
+ fBuffer = new StringBuffer();
+ fStyleRuns = null;
+ }
+
+ /**
+ * Creates an {@link StyledString} initialized with a string without
+ * a style associated.
+ *
+ * @param string
+ * the string
+ */
+ public StyledString(String string) {
+ this(string, null);
+ }
+
+ /**
+ * Creates an {@link StyledString} initialized with a string and a
+ * style.
+ *
+ * @param string
+ * the string
+ * @param styler
+ * the styler for the string or null
to not
+ * associated a styler.
+ */
+ public StyledString(String string, Styler styler) {
+ this();
+ append(string, styler);
+ }
+
+ /**
+ * Returns the string of this {@link StyledString}.
+ *
+ * @return the current string of this {@link StyledString}.
+ */
+ public String getString() {
+ return fBuffer.toString();
+ }
+
+ /**
+ * Returns the string of this {@link StyledString}.
+ *
+ * @return the current string of this {@link StyledString}.
+ */
+ public String toString() {
+ return getString();
+ }
+
+ /**
+ * Returns the length of the string of this {@link StyledString}.
+ *
+ * @return the length of the current string
+ */
+ public int length() {
+ return fBuffer.length();
+ }
+
+ /**
+ * Appends a string to the {@link StyledString}. The appended string
+ * will have no associated styler.
+ *
+ * @param string
+ * the string to append
+ * @return returns a reference to this object
+ */
+ public StyledString append(String string) {
+ return append(string, null);
+ }
+
+ /**
+ * Appends the string representation of the given character array
+ * to the {@link StyledString}. The appended
+ * character array will have no associated styler.
+ *
+ * @param chars
+ * the character array to append
+ * @return returns a reference to this object
+ */
+ public StyledString append(char[] chars) {
+ return append(chars, null);
+ }
+
+ /**
+ * Appends the string representation of the given character
+ * to the {@link StyledString}. The appended
+ * character will have no associated styler.
+ *
+ * @param ch
+ * the character to append
+ * @return returns a reference to this object
+ */
+ public StyledString append(char ch) {
+ return append(String.valueOf(ch), null);
+ }
+
+ /**
+ * Appends a string with styles to the {@link StyledString}.
+ *
+ * @param string
+ * the string to append
+ * @return returns a reference to this object
+ */
+ public StyledString append(StyledString string) {
+ if (string.length() is 0) {
+ return this;
+ }
+
+ int offset = fBuffer.length();
+ fBuffer.append(string.toString());
+
+ List otherRuns = string.fStyleRuns;
+ if (otherRuns !is null && !otherRuns.isEmpty()) {
+ for (int i = 0; i < otherRuns.size(); i++) {
+ StyleRun curr = (StyleRun) otherRuns.get(i);
+ if (i is 0 && curr.offset !is 0) {
+ appendStyleRun(null, offset); // appended string will
+ // start with the default
+ // color
+ }
+ appendStyleRun(curr.style, offset + curr.offset);
+ }
+ } else {
+ appendStyleRun(null, offset); // appended string will start with
+ // the default color
+ }
+ return this;
+ }
+
+ /**
+ * Appends the string representation of the given character
+ * with a style to the {@link StyledString}. The
+ * appended character will have the given style associated.
+ *
+ * @param ch
+ * the character to append
+ * @param styler
+ * the styler to use for styling the character to append or
+ * null
if no styler should be associated with the
+ * appended character
+ * @return returns a reference to this object
+ */
+ public StyledString append(char ch, Styler styler) {
+ return append(String.valueOf(ch), styler);
+ }
+
+ /**
+ * Appends a string with a style to the {@link StyledString}. The
+ * appended string will be styled using the given styler.
+ *
+ * @param string
+ * the string to append
+ * @param styler
+ * the styler to use for styling the string to append or
+ * null
if no styler should be associated with the
+ * appended string.
+ * @return returns a reference to this object
+ */
+ public StyledString append(String string, Styler styler) {
+ if (string.length() is 0)
+ return this;
+
+ int offset = fBuffer.length(); // the length before appending
+ fBuffer.append(string);
+ appendStyleRun(styler, offset);
+ return this;
+ }
+
+ /**
+ * Appends the string representation of the given character array
+ * with a style to the {@link StyledString}. The
+ * appended character array will be styled using the given styler.
+ *
+ * @param chars
+ * the character array to append
+ * @param styler
+ * the styler to use for styling the character array to append or
+ * null
if no styler should be associated with the
+ * appended character array
+ * @return returns a reference to this object
+ */
+ public StyledString append(char[] chars, Styler styler) {
+ if (chars.length is 0)
+ return this;
+
+ int offset = fBuffer.length(); // the length before appending
+ fBuffer.append(chars);
+ appendStyleRun(styler, offset);
+ return this;
+ }
+
+ /**
+ * Sets a styler to use for the given source range. The range must be
+ * subrange of actual string of this {@link StyledString}. Stylers
+ * previously set for that range will be overwritten.
+ *
+ * @param offset
+ * the start offset of the range
+ * @param length
+ * the length of the range
+ * @param styler
+ * the styler to set
+ *
+ * @throws StringIndexOutOfBoundsException
+ * if start
is less than zero, or if offset plus
+ * length is greater than the length of this object.
+ */
+ public void setStyle(int offset, int length, Styler styler) {
+ if (offset < 0 || offset + length > fBuffer.length()) {
+ throw new StringIndexOutOfBoundsException(
+ "Invalid offset (" + offset + ") or length (" + length + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ }
+ if (length is 0) {
+ return;
+ }
+ if (!hasRuns() || getLastRun().offset <= offset) {
+ appendStyleRun(styler, offset);
+ if (offset + length !is fBuffer.length()) {
+ appendStyleRun(null, offset + length);
+ }
+ return;
+ }
+
+ int endRun = findRun(offset + length);
+ if (endRun >= 0) {
+ // run with the same end index, nothing to change
+ } else {
+ endRun = -(endRun + 1);
+ if (offset + length < fBuffer.length()) {
+ Styler prevStyle = endRun > 0 ? fStyleRuns.getRun(endRun - 1).style
+ : null;
+ fStyleRuns
+ .add(endRun, new StyleRun(offset + length, prevStyle));
+ }
+ }
+
+ int startRun = findRun(offset);
+ if (startRun >= 0) {
+ // run with the same start index
+ StyleRun styleRun = fStyleRuns.getRun(startRun);
+ styleRun.style = styler;
+ } else {
+ startRun = -(startRun + 1);
+
+ Styler prevStyle = startRun > 0 ? fStyleRuns.getRun(startRun - 1).style
+ : null;
+ if (isDifferentStyle(prevStyle, styler)
+ || (startRun is 0 && styler !is null)) {
+ fStyleRuns.add(startRun, new StyleRun(offset, styler));
+ endRun++; // endrun is moved one back
+ } else {
+ startRun--; // we use the previous
+ }
+ }
+ if (startRun + 1 < endRun) {
+ fStyleRuns.removeRange(startRun + 1, endRun);
+ }
+ }
+
+ /**
+ * Returns an array of {@link StyleRange} resulting from applying all
+ * associated stylers for this string builder.
+ *
+ * @return an array of all {@link StyleRange} resulting from applying the
+ * stored stylers to this string.
+ */
+ public StyleRange[] getStyleRanges() {
+ if (hasRuns()) {
+ ArrayList res = new ArrayList();
+
+ List styleRuns = getStyleRuns();
+ int offset = 0;
+ Styler style = null;
+ for (int i = 0; i < styleRuns.size(); i++) {
+ StyleRun curr = (StyleRun) styleRuns.get(i);
+ if (isDifferentStyle(curr.style, style)) {
+ if (curr.offset > offset && style !is null) {
+ res.add(createStyleRange(offset, curr.offset, style));
+ }
+ offset = curr.offset;
+ style = curr.style;
+ }
+ }
+ if (fBuffer.length() > offset && style !is null) {
+ res.add(createStyleRange(offset, fBuffer.length(), style));
+ }
+ return (StyleRange[]) res.toArray(new StyleRange[res.size()]);
+ }
+ return EMPTY;
+ }
+
+ private int findRun(int offset) {
+ // method assumes that fStyleRuns is not null
+ int low = 0;
+ int high = fStyleRuns.size() - 1;
+ while (low <= high) {
+ int mid = (low + high) / 2;
+ StyleRun styleRun = fStyleRuns.getRun(mid);
+ if (styleRun.offset < offset) {
+ low = mid + 1;
+ } else if (styleRun.offset > offset) {
+ high = mid - 1;
+ } else {
+ return mid; // key found
+ }
+ }
+ return -(low + 1); // key not found.
+ }
+
+ private StyleRange createStyleRange(int start, int end, Styler style) {
+ StyleRange styleRange = new StyleRange();
+ styleRange.start = start;
+ styleRange.length = end - start;
+ style.applyStyles(styleRange);
+ return styleRange;
+ }
+
+ private bool hasRuns() {
+ return fStyleRuns !is null && !fStyleRuns.isEmpty();
+ }
+
+ private void appendStyleRun(Styler style, int offset) {
+ StyleRun lastRun = getLastRun();
+ if (lastRun !is null && lastRun.offset is offset) {
+ lastRun.style = style;
+ return;
+ }
+
+ if (lastRun is null && style !is null || lastRun !is null
+ && isDifferentStyle(style, lastRun.style)) {
+ getStyleRuns().add(new StyleRun(offset, style));
+ }
+ }
+
+ private bool isDifferentStyle(Styler style1, Styler style2) {
+ if (style1 is null) {
+ return style2 !is null;
+ }
+ return !style1.equals(style2);
+ }
+
+ private StyleRun getLastRun() {
+ if (fStyleRuns is null || fStyleRuns.isEmpty()) {
+ return null;
+ }
+ return fStyleRuns.getRun(fStyleRuns.size() - 1);
+ }
+
+ private List getStyleRuns() {
+ if (fStyleRuns is null)
+ fStyleRuns = new StyleRunList();
+ return fStyleRuns;
+ }
+
+ private static class StyleRun {
+ public int offset;
+ public Styler style;
+
+ public StyleRun(int offset, Styler style) {
+ this.offset = offset;
+ this.style = style;
+ }
+
+ public String toString() {
+ return "Offset " + offset + ", style: " + style; //$NON-NLS-1$//$NON-NLS-2$
+ }
+ }
+
+ private static class StyleRunList extends ArrayList {
+ private static final long serialVersionUID = 123L;
+
+ public StyleRunList() {
+ super(3);
+ }
+
+ public StyleRun getRun(int index) {
+ return (StyleRun) get(index);
+ }
+
+ public void removeRange(int fromIndex, int toIndex) {
+ super.removeRange(fromIndex, toIndex);
+ }
+ }
+
+ private static class DefaultStyler extends Styler {
+ private final String fForegroundColorName;
+ private final String fBackgroundColorName;
+
+ public DefaultStyler(String foregroundColorName,
+ String backgroundColorName) {
+ fForegroundColorName = foregroundColorName;
+ fBackgroundColorName = backgroundColorName;
+ }
+
+ public void applyStyles(TextStyle textStyle) {
+ ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
+ if (fForegroundColorName !is null) {
+ textStyle.foreground = colorRegistry.get(fForegroundColorName);
+ }
+ if (fBackgroundColorName !is null) {
+ textStyle.background = colorRegistry.get(fBackgroundColorName);
+ }
+ }
+ }
+
+}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TableLayout.d
--- a/dwtx/jface/viewers/TableLayout.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TableLayout.d Thu May 22 01:36:46 2008 +0200
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Florian Priester - bug 106059
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -48,12 +49,16 @@
*
* @since 3.1
*/
- private static int COLUMN_TRIM_ = -1;
- private static int COLUMN_TRIM(){
- if( COLUMN_TRIM_ is -1 ){
- COLUMN_TRIM_ = "carbon".equals(DWT.getPlatform()) ? 24 : 3; //$NON-NLS-1$
+ private static int COLUMN_TRIM;
+
+ static {
+ if ("win32".equals(DWT.getPlatform())) { //$NON-NLS-1$
+ COLUMN_TRIM = 4;
+ } else if ("carbon".equals(DWT.getPlatform())) { //$NON-NLS-1$
+ COLUMN_TRIM = 24;
+ } else {
+ COLUMN_TRIM = 3;
}
- return COLUMN_TRIM_;
}
/**
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TableViewer.d
--- a/dwtx/jface/viewers/TableViewer.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TableViewer.d Thu May 22 01:36:46 2008 +0200
@@ -23,7 +23,6 @@
import dwtx.jface.viewers.ViewerRow;
import dwtx.jface.viewers.TableViewerEditor;
import dwtx.jface.viewers.ColumnViewerEditorActivationStrategy;
-
import dwt.DWT;
import dwt.graphics.Point;
import dwt.widgets.Composite;
@@ -47,16 +46,16 @@
*
*
* Label providers for table viewers must implement either the
- * ITableLabelProvider
or the ILabelProvider
- * interface (see TableViewer.setLabelProvider
for more details).
+ * ITableLabelProvider
or the ILabelProvider
interface
+ * (see TableViewer.setLabelProvider
for more details).
*
*
* As of 3.1 the TableViewer now supports the DWT.VIRTUAL flag. If the
- * underlying table is DWT.VIRTUAL, the content provider may implement
- * {@link ILazyContentProvider} instead of {@link IStructuredContentProvider}.
- * Note that in this case, the viewer does not support sorting or filtering.
- * Also note that in this case, the Widget based APIs may return null if the
- * element is not specified or not created yet.
+ * underlying table is DWT.VIRTUAL, the content provider may implement {@link
+ * ILazyContentProvider} instead of {@link IStructuredContentProvider} . Note
+ * that in this case, the viewer does not support sorting or filtering. Also
+ * note that in this case, the Widget based APIs may return null if the element
+ * is not specified or not created yet.
*
*
* Users of DWT.VIRTUAL should also avoid using getItems() from the Table within
@@ -64,7 +63,11 @@
* TreeViewer to populate the items. It also has the side effect of creating all
* of the items thereby eliminating the performance improvements of DWT.VIRTUAL.
*
- *
+ *
+ * Users setting up an editable table with more than 1 column have to pass the
+ * DWT.FULL_SELECTION style bit
+ *
+ *
* @see DWT#VIRTUAL
* @see #doFindItem(Object)
* @see #internalRefresh(Object, bool)
@@ -89,9 +92,9 @@
* MULTI, H_SCROLL, V_SCROLL,
and BORDER
. The
* viewer has no input, no content provider, a default label provider, no
* sorter, and no filters. The table has no columns.
- *
+ *
* @param parent
- * the parent control
+ * the parent control
*/
public this(Composite parent) {
this(parent, DWT.MULTI | DWT.H_SCROLL | DWT.V_SCROLL | DWT.BORDER);
@@ -102,11 +105,11 @@
* parent. The table control is created using the given style bits. The
* viewer has no input, no content provider, a default label provider, no
* sorter, and no filters. The table has no columns.
- *
+ *
* @param parent
- * the parent control
+ * the parent control
* @param style
- * DWT style bits
+ * DWT style bits
*/
public this(Composite parent, int style) {
this(new Table(parent, style));
@@ -116,9 +119,9 @@
* Creates a table viewer on the given table control. The viewer has no
* input, no content provider, a default label provider, no sorter, and no
* filters.
- *
+ *
* @param table
- * the table control
+ * the table control
*/
public this(Table table) {
this.table = table;
@@ -131,7 +134,7 @@
/**
* Returns this table viewer's table control.
- *
+ *
* @return the table control
*/
public Table getTable() {
@@ -139,7 +142,9 @@
}
protected override ColumnViewerEditor createViewerEditor() {
- return new TableViewerEditor(this,null,new ColumnViewerEditorActivationStrategy(this),ColumnViewerEditor.DEFAULT);
+ return new TableViewerEditor(this, null,
+ new ColumnViewerEditorActivationStrategy(this),
+ ColumnViewerEditor.DEFAULT);
}
/**
@@ -153,12 +158,12 @@
* Use Table#setSelection(int[] indices) and Table#showSelection() if you
* wish to set selection more efficiently when using a ILazyContentProvider.
*
- *
+ *
* @param selection
- * the new selection
+ * the new selection
* @param reveal
- * true
if the selection is to be made visible,
- * and false
otherwise
+ * true
if the selection is to be made visible, and
+ * false
otherwise
* @see Table#setSelection(int[])
* @see Table#showSelection()
*/
@@ -167,7 +172,7 @@
}
protected override ViewerRow getViewerRowFromItem(Widget item) {
- if( cachedRow is null ) {
+ if (cachedRow is null) {
cachedRow = new TableViewerRow(cast(TableItem) item);
} else {
cachedRow.setItem(cast(TableItem) item);
@@ -178,7 +183,7 @@
/**
* Create a new row with style at index
- *
+ *
* @param style
* @param rowIndex
* @return ViewerRow
@@ -199,11 +204,11 @@
protected override Item getItemAt(Point p) {
TableItem[] selection = table.getSelection();
- if( selection.length is 1 ) {
+ if (selection.length is 1) {
int columnCount = table.getColumnCount();
- for( int i = 0; i < columnCount; i++ ) {
- if( selection[0].getBounds(i).contains(p) ) {
+ for (int i = 0; i < columnCount; i++) {
+ if (selection[0].getBounds(i).contains(p)) {
return selection[0];
}
}
@@ -219,7 +224,7 @@
}
protected override int doIndexOf(Item item) {
- return table.indexOf(cast(TableItem)item);
+ return table.indexOf(cast(TableItem) item);
}
protected override void doSetItemCount(int count) {
@@ -278,7 +283,7 @@
}
protected override void doShowItem(Item item) {
- table.showItem(cast(TableItem)item);
+ table.showItem(cast(TableItem) item);
}
protected override void doDeselectAll() {
@@ -312,38 +317,37 @@
/**
* Refreshes this viewer starting with the given element. Labels are updated
- * as described in refresh(bool updateLabels)
. The
- * methods attempts to preserve the selection.
+ * as described in refresh(bool updateLabels)
. The methods
+ * attempts to preserve the selection.
*
* Unlike the update
methods, this handles structural changes
* to the given element (e.g. addition or removal of children). If only the
* given element needs updating, it is more efficient to use the
* update
methods.
*
- *
+ *
*
* Subclasses who can provide this feature can open this method for the
* public
*
- *
+ *
* @param element
- * the element
+ * the element
* @param updateLabels
- * true
to update labels for existing elements,
- * false
to only update labels as needed, assuming
- * that labels for existing elements are unchanged.
+ * true
to update labels for existing elements,
+ * false
to only update labels as needed, assuming that labels
+ * for existing elements are unchanged.
* @param reveal
- * true
to make the preserved selection visible
- * afterwards
- *
+ * true
to make the preserved selection visible afterwards
+ *
* @since 3.3
*/
public void refresh(Object element, bool updateLabels,
bool reveal) {
- if (isBusy())
+ if (checkBusy())
return;
- if( isCellEditorActive() ) {
+ if (isCellEditorActive()) {
cancelEditing();
}
@@ -362,26 +366,25 @@
/**
* Refreshes this viewer with information freshly obtained from this
- * viewer's model. If updateLabels
is true
- * then labels for otherwise unaffected elements are updated as well.
- * Otherwise, it assumes labels for existing elements are unchanged, and
- * labels are only obtained as needed (for example, for new elements).
+ * viewer's model. If updateLabels
is true
then
+ * labels for otherwise unaffected elements are updated as well. Otherwise,
+ * it assumes labels for existing elements are unchanged, and labels are
+ * only obtained as needed (for example, for new elements).
*
* Calling refresh(true)
has the same effect as
* refresh()
.
*
* Note that the implementation may still obtain labels for existing
- * elements even if updateLabels
is false. The intent is
- * simply to allow optimization where possible.
- *
+ * elements even if updateLabels
is false. The intent is simply
+ * to allow optimization where possible.
+ *
* @param updateLabels
- * true
to update labels for existing elements,
- * false
to only update labels as needed, assuming
- * that labels for existing elements are unchanged.
+ * true
to update labels for existing elements,
+ * false
to only update labels as needed, assuming that labels
+ * for existing elements are unchanged.
* @param reveal
- * true
to make the preserved selection visible
- * afterwards
- *
+ * true
to make the preserved selection visible afterwards
+ *
* @since 3.3
*/
public void refresh(bool updateLabels, bool reveal) {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TableViewerEditor.d
--- a/dwtx/jface/viewers/TableViewerEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TableViewerEditor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2008 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
@@ -8,10 +8,10 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - initial API and implementation
- * fixes in bug 198665
+ * fixes in bug 198665, 200731
* Port to the D programming language:
* Frank Benoit
- ******************************************************************************/
+ *******************************************************************************/
module dwtx.jface.viewers.TableViewerEditor;
@@ -26,6 +26,7 @@
// import tango.util.collection.model.Seq;
+import dwt.DWT;
import dwt.custom.TableEditor;
import dwt.widgets.Control;
import dwt.widgets.Item;
@@ -129,6 +130,11 @@
tableEditor.grabHorizontal = layoutData.grabHorizontal;
tableEditor.horizontalAlignment = layoutData.horizontalAlignment;
tableEditor.minimumWidth = layoutData.minimumWidth;
+ tableEditor.verticalAlignment = layoutData.verticalAlignment;
+
+ if( layoutData.minimumHeight !is DWT.DEFAULT ) {
+ tableEditor.minimumHeight = layoutData.minimumHeight;
+ }
}
public override ViewerCell getFocusCell() {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TableViewerFocusCellManager.d
--- a/dwtx/jface/viewers/TableViewerFocusCellManager.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TableViewerFocusCellManager.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2008 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
@@ -7,9 +7,11 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Tom Schindl - initial API and implementation
+ * fix in bug: 210752
* Port to the D programming language:
* Frank Benoit
- ******************************************************************************/
+ *******************************************************************************/
module dwtx.jface.viewers.TableViewerFocusCellManager;
@@ -34,8 +36,27 @@
public class TableViewerFocusCellManager : SWTFocusCellManager {
private static const CellNavigationStrategy TABLE_NAVIGATE;
static this(){
- TABLE_NAVIGATE = new CellNavigationStrategy();
+ /**
+ * Create a new manager with a default navigation strategy:
+ *
+ * DWT.ARROW_UP
: navigate to cell above
+ * DWT.ARROW_DOWN
: navigate to cell below
+ * DWT.ARROW_RIGHT
: navigate to next visible cell on
+ * the right
+ * DWT.ARROW_LEFT
: navigate to next visible cell on the
+ * left
+ *
+ *
+ * @param viewer
+ * the viewer the manager is bound to
+ * @param focusDrawingDelegate
+ * the delegate responsible to highlight selected cell
+ */
+ public TableViewerFocusCellManager(TableViewer viewer,
+ FocusCellHighlighter focusDrawingDelegate) {
+ this(viewer, focusDrawingDelegate, TABLE_NAVIGATE);
}
+
/**
* Create a new manager
*
@@ -43,10 +64,13 @@
* the viewer the manager is bound to
* @param focusDrawingDelegate
* the delegate responsible to highlight selected cell
+ * @param navigationStrategy
+ * the strategy used to navigate the cells
*/
- public this(TableViewer viewer,
- FocusCellHighlighter focusDrawingDelegate) {
- super(viewer, focusDrawingDelegate, TABLE_NAVIGATE);
+ public TableViewerFocusCellManager(TableViewer viewer,
+ FocusCellHighlighter focusDrawingDelegate,
+ CellNavigationStrategy navigationStrategy) {
+ super(viewer, focusDrawingDelegate, navigationStrategy);
}
override ViewerCell getInitialFocusCell() {
@@ -60,4 +84,20 @@
return null;
}
+ public ViewerCell getFocusCell() {
+ ViewerCell cell = super.getFocusCell();
+ Table t = (Table) getViewer().getControl();
+
+ // It is possible that the selection has changed under the hood
+ if (cell !is null) {
+ if (t.getSelection().length is 1
+ && t.getSelection()[0] !is cell.getItem()) {
+ setFocusCell(getViewer().getViewerRowFromItem(
+ t.getSelection()[0]).getCell(cell.getColumnIndex()));
+ }
+ }
+
+ return super.getFocusCell();
+ }
+
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TableViewerRow.d
--- a/dwtx/jface/viewers/TableViewerRow.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TableViewerRow.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -7,8 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Tom Shindl - initial API and implementation
- * - Fix for bug 174355
+ * Tom Schindl - initial API and implementation
+ * - fix in bug: 174355,195908,198035,215069
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -202,4 +202,45 @@
public override Object getElement() {
return item.getData();
}
+
+ public int getVisualIndex(int creationIndex) {
+ int[] order = item.getParent().getColumnOrder();
+
+ for (int i = 0; i < order.length; i++) {
+ if (order[i] is creationIndex) {
+ return i;
+ }
+ }
+
+ return super.getVisualIndex(creationIndex);
+ }
+
+ public int getCreationIndex(int visualIndex) {
+ if( item !is null && ! item.isDisposed() && hasColumns() && isValidOrderIndex(visualIndex) ) {
+ return item.getParent().getColumnOrder()[visualIndex];
+ }
+ return super.getCreationIndex(visualIndex);
+ }
+
+ /* (non-Javadoc)
+ * @see dwtx.jface.viewers.ViewerRow#getTextBounds(int)
+ */
+ public Rectangle getTextBounds(int index) {
+ return item.getTextBounds(index);
+ }
+
+ /* (non-Javadoc)
+ * @see dwtx.jface.viewers.ViewerRow#getImageBounds(int)
+ */
+ public Rectangle getImageBounds(int index) {
+ return item.getImageBounds(index);
+ }
+
+ private bool hasColumns() {
+ return this.item.getParent().getColumnCount() !is 0;
+ }
+
+ private bool isValidOrderIndex(int currentIndex) {
+ return currentIndex < this.item.getParent().getColumnOrder().length;
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TextCellEditor.d
--- a/dwtx/jface/viewers/TextCellEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TextCellEditor.d Thu May 22 01:36:46 2008 +0200
@@ -479,7 +479,16 @@
checkDeleteable();
}
- override bool dependsOnExternalFocusListener() {
+ /**
+ * This implementation of
+ * {@link CellEditor#dependsOnExternalFocusListener()} returns false if the
+ * current instance's class is TextCellEditor, and true otherwise.
+ * Subclasses that hook their own focus listener should override this method
+ * and return false. See also bug 58777.
+ *
+ * @since 3.4
+ */
+ protected override bool dependsOnExternalFocusListener() {
return this.classinfo !is TextCellEditor.classinfo;
}
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TreeNode.d
--- a/dwtx/jface/viewers/TreeNode.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TreeNode.d Thu May 22 01:36:46 2008 +0200
@@ -1,139 +1,140 @@
-/*******************************************************************************
- * 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
- * Port to the D programming language:
- * Frank Benoit
- ******************************************************************************/
-
-module dwtx.jface.viewers.TreeNode;
-
-import dwtx.jface.util.Util;
-
-import dwt.dwthelper.utils;
-
-/**
- * A simple data structure that is useful for implemented tree models. This can
- * be returned by
- * {@link dwtx.jface.viewers.IStructuredContentProvider#getElements(Object)}.
- * It allows simple delegation of methods from
- * {@link dwtx.jface.viewers.ITreeContentProvider} such as
- * {@link dwtx.jface.viewers.ITreeContentProvider#getChildren(Object)},
- * {@link dwtx.jface.viewers.ITreeContentProvider#getParent(Object)} and
- * {@link dwtx.jface.viewers.ITreeContentProvider#hasChildren(Object)}
- *
- * @since 3.2
- */
-public class TreeNode {
-
- /**
- * The array of child tree nodes for this tree node. If there are no
- * children, then this value may either by an empty array or
- * null
. There should be no null
children in
- * the array.
- */
- private TreeNode[] children;
-
- /**
- * The parent tree node for this tree node. This value may be
- * null
if there is no parent.
- */
- private TreeNode parent;
-
- /**
- * The value contained in this node. This value may be anything.
- */
- protected Object value;
-
- /**
- * Constructs a new instance of TreeNode
.
- *
- * @param value
- * The value held by this node; may be anything.
- */
- public this(Object value) {
- this.value = value;
- }
-
- public override int opEquals(Object object) {
- if ( auto tn = cast(TreeNode)object ) {
- return Util.opEquals(this.value, tn.value);
- }
-
- return false;
- }
-
- /**
- * Returns the child nodes. Empty arrays are converted to null
- * before being returned.
- *
- * @return The child nodes; may be null
, but never empty.
- * There should be no null
children in the array.
- */
- public TreeNode[] getChildren() {
- if (children !is null && children.length is 0) {
- return null;
- }
- return children;
- }
-
- /**
- * Returns the parent node.
- *
- * @return The parent node; may be null
if there are no
- * parent nodes.
- */
- public TreeNode getParent() {
- return parent;
- }
-
- /**
- * Returns the value held by this node.
- *
- * @return The value; may be anything.
- */
- public Object getValue() {
- return value;
- }
-
- /**
- * Returns whether the tree has any children.
- *
- * @return true
if its array of children is not
- * null
and is non-empty; false
- * otherwise.
- */
- public bool hasChildren() {
- return children !is null && children.length > 0;
- }
-
- public override hash_t toHash() {
- return Util.toHash(value);
- }
-
- /**
- * Sets the children for this node.
- *
- * @param children
- * The child nodes; may be null
or empty. There
- * should be no null
children in the array.
- */
- public void setChildren(TreeNode[] children) {
- this.children = children;
- }
-
- /**
- * Sets the parent for this node.
- *
- * @param parent
- * The parent node; may be null
.
- */
- public void setParent(TreeNode parent) {
- this.parent = parent;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ * Port to the D programming language:
+ * Frank Benoit
+ *******************************************************************************/
+
+module dwtx.jface.viewers.TreeNode;
+
+import dwtx.jface.util.Util;
+
+import dwt.dwthelper.utils;
+
+/**
+ * A simple data structure that is useful for implemented tree models. This can
+ * be returned by
+ * {@link dwtx.jface.viewers.IStructuredContentProvider#getElements(Object)}.
+ * It allows simple delegation of methods from
+ * {@link dwtx.jface.viewers.ITreeContentProvider} such as
+ * {@link dwtx.jface.viewers.ITreeContentProvider#getChildren(Object)},
+ * {@link dwtx.jface.viewers.ITreeContentProvider#getParent(Object)} and
+ * {@link dwtx.jface.viewers.ITreeContentProvider#hasChildren(Object)}
+ *
+ * @since 3.2
+ */
+public class TreeNode {
+
+ /**
+ * The array of child tree nodes for this tree node. If there are no
+ * children, then this value may either by an empty array or
+ * null
. There should be no null
children in
+ * the array.
+ */
+ private TreeNode[] children;
+
+ /**
+ * The parent tree node for this tree node. This value may be
+ * null
if there is no parent.
+ */
+ private TreeNode parent;
+
+ /**
+ * The value contained in this node. This value may be anything.
+ */
+ protected Object value;
+
+ /**
+ * Constructs a new instance of TreeNode
.
+ *
+ * @param value
+ * The value held by this node; may be anything.
+ */
+ public this(Object value) {
+ this.value = value;
+ }
+
+ public override int opEquals(Object object) {
+ if ( auto tn = cast(TreeNode)object ) {
+ return Util.opEquals(this.value, tn.value);
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the child nodes. Empty arrays are converted to null
+ * before being returned.
+ *
+ * @return The child nodes; may be null
, but never empty.
+ * There should be no null
children in the array.
+ */
+ public TreeNode[] getChildren() {
+ if (children !is null && children.length is 0) {
+ return null;
+ }
+ return children;
+ }
+
+ /**
+ * Returns the parent node.
+ *
+ * @return The parent node; may be null
if there are no
+ * parent nodes.
+ */
+ public TreeNode getParent() {
+ return parent;
+ }
+
+ /**
+ * Returns the value held by this node.
+ *
+ * @return The value; may be anything.
+ */
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * Returns whether the tree has any children.
+ *
+ * @return true
if its array of children is not
+ * null
and is non-empty; false
+ * otherwise.
+ */
+ public bool hasChildren() {
+ return children !is null && children.length > 0;
+ }
+
+ public override hash_t toHash() {
+ return Util.toHash(value);
+ }
+
+ /**
+ * Sets the children for this node.
+ *
+ * @param children
+ * The child nodes; may be null
or empty. There
+ * should be no null
children in the array.
+ */
+ public void setChildren(TreeNode[] children) {
+ this.children = children;
+ }
+
+ /**
+ * Sets the parent for this node.
+ *
+ * @param parent
+ * The parent node; may be null
.
+ */
+ public void setParent(TreeNode parent) {
+ this.parent = parent;
+ }
+}
+
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TreeNodeContentProvider.d
--- a/dwtx/jface/viewers/TreeNodeContentProvider.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TreeNodeContentProvider.d Thu May 22 01:36:46 2008 +0200
@@ -1,98 +1,99 @@
-/*******************************************************************************
- * 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
- * Port to the D programming language:
- * Frank Benoit
- ******************************************************************************/
-
-module dwtx.jface.viewers.TreeNodeContentProvider;
-
-import dwtx.jface.viewers.ITreeContentProvider;
-import dwtx.jface.viewers.Viewer;
-import dwtx.jface.viewers.TreeNode;
-
-import dwt.dwthelper.utils;
-
-/**
- *
- * A content provider that expects every element to be a TreeNode
.
- * Most methods delegate to TreeNode
. dispose()
- * and inputChanged(Viewer, Object, Object)
do nothing by
- * default.
- *
- *
- * This class and all of its methods may be overridden or extended.
- *
- *
- * @since 3.2
- * @see dwtx.jface.viewers.TreeNode
- */
-public class TreeNodeContentProvider : ITreeContentProvider {
- /*
- * (non-Javadoc)
- *
- * @see dwtx.jface.viewers.IContentProvider#dispose()
- */
- public void dispose() {
- // Do nothing
- }
-
- /*
- * (non-Javadoc)
- *
- * @see dwtx.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
- */
- public Object[] getChildren(Object parentElement) {
- TreeNode node = cast(TreeNode) parentElement;
- return node.getChildren();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see dwtx.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
- */
- public Object[] getElements(Object inputElement) {
- if ( auto tn = cast(ArrayWrapperT!(TreeNode)) inputElement ) {
- return tn.array;
- }
- return null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see dwtx.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
- */
- public Object getParent(Object element) {
- TreeNode node = cast(TreeNode) element;
- return node.getParent();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see dwtx.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
- */
- public bool hasChildren(Object element) {
- TreeNode node = cast(TreeNode) element;
- return node.hasChildren();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see dwtx.jface.viewers.IContentProvider#inputChanged(dwtx.jface.viewers.Viewer,
- * java.lang.Object, java.lang.Object)
- */
- public void inputChanged(Viewer viewer, Object oldInput,
- Object newInput) {
- // Do nothing
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ * Port to the D programming language:
+ * Frank Benoit
+ *******************************************************************************/
+
+module dwtx.jface.viewers.TreeNodeContentProvider;
+
+import dwtx.jface.viewers.ITreeContentProvider;
+import dwtx.jface.viewers.Viewer;
+import dwtx.jface.viewers.TreeNode;
+
+import dwt.dwthelper.utils;
+
+/**
+ *
+ * A content provider that expects every element to be a TreeNode
.
+ * Most methods delegate to TreeNode
. dispose()
+ * and inputChanged(Viewer, Object, Object)
do nothing by
+ * default.
+ *
+ *
+ * This class and all of its methods may be overridden or extended.
+ *
+ *
+ * @since 3.2
+ * @see dwtx.jface.viewers.TreeNode
+ */
+public class TreeNodeContentProvider : ITreeContentProvider {
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ // Do nothing
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(Object parentElement) {
+ TreeNode node = cast(TreeNode) parentElement;
+ return node.getChildren();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ if ( auto tn = cast(ArrayWrapperT!(TreeNode)) inputElement ) {
+ return tn.array;
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ public Object getParent(Object element) {
+ TreeNode node = cast(TreeNode) element;
+ return node.getParent();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ public bool hasChildren(Object element) {
+ TreeNode node = cast(TreeNode) element;
+ return node.hasChildren();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.IContentProvider#inputChanged(dwtx.jface.viewers.Viewer,
+ * java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ // Do nothing
+ }
+}
+
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TreeViewer.d
--- a/dwtx/jface/viewers/TreeViewer.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TreeViewer.d Thu May 22 01:36:46 2008 +0200
@@ -8,7 +8,8 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - concept of ViewerRow,
- * refactoring (bug 153993), bug 167323, 191468
+ * refactoring (bug 153993), bug 167323, 191468, 205419
+ * Matthew Hall - bug 221988
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -70,8 +71,13 @@
* {@link ILazyTreePathContentProvider}. If the content provider is an
* ILazyTreeContentProvider
or an
* ILazyTreePathContentProvider
, the underlying Tree must be
- * created using the {@link DWT#VIRTUAL} style bit, and the tree viewer will not
- * support sorting or filtering.
+ * created using the {@link DWT#VIRTUAL} style bit, the tree viewer will not
+ * support sorting or filtering, and hash lookup must be enabled by calling
+ * {@link #setUseHashlookup(bool)}.
+ *
+ *
+ * Users setting up an editable tree with more than 1 column have to pass the
+ * DWT.FULL_SELECTION style bit
*
*/
public class TreeViewer : AbstractTreeViewer {
@@ -431,7 +437,7 @@
* @since 3.2
*/
public void setChildCount(Object elementOrTreePath, int count) {
- if (isBusy())
+ if (checkBusy())
return;
preservingSelection(new class(elementOrTreePath,count) Runnable {
Object elementOrTreePath_;
@@ -480,7 +486,7 @@
*/
public void replace(Object parentElementOrTreePath, int index,
Object element) {
- if (isBusy())
+ if (checkBusy())
return;
Item[] selectedItems = getSelection(getControl());
TreeSelection selection = cast(TreeSelection) getSelection();
@@ -605,8 +611,8 @@
}
protected override Object getParentElement(Object element) {
- bool oldBusy = busy;
- busy = true;
+ bool oldBusy = isBusy();
+ setBusy(true);
try {
if (contentProviderIsLazy && !contentProviderIsTreeBased && !(cast(TreePath)element )) {
ILazyTreeContentProvider lazyTreeContentProvider = cast(ILazyTreeContentProvider) getContentProvider();
@@ -622,7 +628,7 @@
}
return super.getParentElement(element);
} finally {
- busy = oldBusy;
+ setBusy(oldBusy);
}
}
@@ -773,7 +779,7 @@
// only add a dispose listener if item hasn't already on assigned
// because it is reused
if (item.getData(VIRTUAL_DISPOSE_KEY) is null) {
- item.setData(VIRTUAL_DISPOSE_KEY, new ValueWrapperBool(true));
+ item.setData(VIRTUAL_DISPOSE_KEY, Boolean.TRUE);
item.addDisposeListener(new class(item) DisposeListener {
Widget item_;
this(Widget a){
@@ -875,7 +881,7 @@
* @since 3.3
*/
public void remove(Object parentOrTreePath_, int index_) {
- if (isBusy())
+ if (checkBusy())
return;
preservingSelection(new class((cast(TreeSelection) getSelection()).getPaths(),parentOrTreePath_,index_) Runnable {
Seq!(TreePath) oldSelection;
@@ -905,6 +911,8 @@
Widget[] parentItems = internalFindItems(parentOrTreePath);
for (int i = 0; i < parentItems.length; i++) {
TreeItem parentItem = cast(TreeItem) parentItems[i];
+ if (parentItem.isDisposed())
+ continue;
if (index < parentItem.getItemCount()) {
TreeItem item = parentItem.getItem(index);
if (item.getData() !is null) {
@@ -978,7 +986,7 @@
* @since 3.3
*/
public void setHasChildren(Object elementOrTreePath_, bool hasChildren_) {
- if (isBusy())
+ if (checkBusy())
return;
preservingSelection(new class(elementOrTreePath_,hasChildren_) Runnable {
Object elementOrTreePath;
@@ -1025,8 +1033,8 @@
* @param index
*/
private void virtualLazyUpdateWidget(Widget widget, int index) {
- bool oldBusy = busy;
- busy = false;
+ bool oldBusy = isBusy();
+ setBusy(false);
try {
if (contentProviderIsTreeBased) {
TreePath treePath;
@@ -1051,7 +1059,7 @@
widget.getData(), index);
}
} finally {
- busy = oldBusy;
+ setBusy(oldBusy);
}
}
@@ -1061,8 +1069,8 @@
* @param currentChildCount
*/
private void virtualLazyUpdateChildCount(Widget widget, int currentChildCount) {
- bool oldBusy = busy;
- busy = false;
+ bool oldBusy = isBusy();
+ setBusy(false);
try {
if (contentProviderIsTreeBased) {
TreePath treePath;
@@ -1077,7 +1085,7 @@
(cast(ILazyTreeContentProvider) getContentProvider()).updateChildCount(widget.getData(), currentChildCount);
}
} finally {
- busy = oldBusy;
+ setBusy(oldBusy);
}
}
@@ -1087,8 +1095,8 @@
* @param currentChildCount
*/
private void virtualLazyUpdateHasChildren(Item item, int currentChildCount) {
- bool oldBusy = busy;
- busy = false;
+ bool oldBusy = isBusy();
+ setBusy(false);
try {
if (contentProviderIsTreeBased) {
TreePath treePath;
@@ -1105,7 +1113,7 @@
(cast(ILazyTreeContentProvider) getContentProvider()).updateChildCount(item.getData(), currentChildCount);
}
} finally {
- busy = oldBusy;
+ setBusy(oldBusy);
}
}
@@ -1141,26 +1149,27 @@
public override void editElement(Object element, int column) {
if( cast(TreePath)element ) {
- setSelection(new TreeSelection(cast(TreePath) element));
- TreeItem[] items = tree.getSelection();
-
- if( items.length is 1 ) {
- ViewerRow row = getViewerRowFromItem(items[0]);
+ try {
+ getControl().setRedraw(false);
+ setSelection(new TreeSelection(cast(TreePath) element));
+ TreeItem[] items = tree.getSelection();
- if (row !is null) {
- ViewerCell cell = row.getCell(column);
- if (cell !is null) {
- getControl().setRedraw(false);
- try {
+ if( items.length is 1 ) {
+ ViewerRow row = getViewerRowFromItem(items[0]);
+
+ if (row !is null) {
+ ViewerCell cell = row.getCell(column);
+ if (cell !is null) {
triggerEditorActivationEvent(new ColumnViewerEditorActivationEvent(cell));
- } finally {
- getControl().setRedraw(true);
}
}
}
+ } finally {
+ getControl().setRedraw(true);
}
} else {
super.editElement(element, column);
}
}
+
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TreeViewerEditor.d
--- a/dwtx/jface/viewers/TreeViewerEditor.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TreeViewerEditor.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2008 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
@@ -8,10 +8,10 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - initial API and implementation
- * fixes in bug 198665
+ * fixes in bug 198665, 200731, 187963
* Port to the D programming language:
* Frank Benoit
- ******************************************************************************/
+ *******************************************************************************/
module dwtx.jface.viewers.TreeViewerEditor;
@@ -26,6 +26,7 @@
import tango.util.collection.model.Seq;
+import dwt.DWT;
import dwt.custom.TreeEditor;
import dwt.widgets.Control;
import dwt.widgets.Item;
@@ -126,6 +127,10 @@
treeEditor.grabHorizontal = layoutData.grabHorizontal;
treeEditor.horizontalAlignment = layoutData.horizontalAlignment;
treeEditor.minimumWidth = layoutData.minimumWidth;
+ treeEditor.verticalAlignment = layoutData.verticalAlignment;
+ if( layoutData.minimumHeight !is DWT.DEFAULT ) {
+ treeEditor.minimumHeight = layoutData.minimumHeight;
+ }
}
public override ViewerCell getFocusCell() {
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TreeViewerFocusCellManager.d
--- a/dwtx/jface/viewers/TreeViewerFocusCellManager.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TreeViewerFocusCellManager.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2008 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
@@ -7,9 +7,11 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Tom Schindl - initial API and implementation
+ * - fix in bug: 195908, 210752
* Port to the D programming language:
* Frank Benoit
- ******************************************************************************/
+ *******************************************************************************/
module dwtx.jface.viewers.TreeViewerFocusCellManager;
@@ -51,31 +53,53 @@
Event event) {
if (cellToExpand !is null) {
TreeViewer v = cast(TreeViewer) viewer;
- v.setExpandedState(v
- .getTreePathFromItem_package(cast(Item)cellToExpand.getItem()), true);
+ v.setExpandedState(v.getTreePathFromItem_package(cast(Item)cellToExpand
+ .getItem()), true);
}
}
public bool isCollapseEvent(ColumnViewer viewer,
ViewerCell cellToCollapse, Event event) {
+
+ if (cellToCollapse is null) {
+ return false;
+ }
+
return cellToCollapse !is null
&& (cast(TreeItem) cellToCollapse.getItem()).getExpanded()
- && cellToCollapse.getColumnIndex() is 0
- && event.keyCode is DWT.ARROW_LEFT;
+ && event.keyCode is DWT.ARROW_LEFT
+ && isFirstColumnCell(cellToCollapse);
}
public bool isExpandEvent(ColumnViewer viewer,
ViewerCell cellToExpand, Event event) {
+
+ if (cellToExpand is null) {
+ return false;
+ }
+
return cellToExpand !is null
&& (cast(TreeItem) cellToExpand.getItem()).getItemCount() > 0
&& !(cast(TreeItem) cellToExpand.getItem()).getExpanded()
- && cellToExpand.getColumnIndex() is 0
- && event.keyCode is DWT.ARROW_RIGHT;
+ && event.keyCode is DWT.ARROW_RIGHT
+ && isFirstColumnCell(cellToExpand);
+ }
+
+ private bool isFirstColumnCell(ViewerCell cell) {
+ return cell.getViewerRow().getVisualIndex(cell.getColumnIndex()) is 0;
}
};
- }
+
/**
- * Create a new manager
+ * Create a new manager using a default navigation strategy:
+ *
+ * DWT.ARROW_UP
: navigate to cell above
+ * DWT.ARROW_DOWN
: navigate to cell below
+ * DWT.ARROW_RIGHT
: on first column (collapses if item
+ * is expanded) else navigate to next visible cell on the right
+ * DWT.ARROW_LEFT
: on first column (expands if item is
+ * collapsed) else navigate to next visible cell on the left
+ *
*
* @param viewer
* the viewer the manager is bound to
@@ -84,16 +108,48 @@
*/
public this(TreeViewer viewer,
FocusCellHighlighter focusDrawingDelegate) {
- super(viewer, focusDrawingDelegate,TREE_NAVIGATE);
+ this(viewer, focusDrawingDelegate, TREE_NAVIGATE);
+ }
+
+ /**
+ * Create a new manager with a custom navigation strategy
+ *
+ * @param viewer
+ * the viewer the manager is bound to
+ * @param focusDrawingDelegate
+ * the delegate responsible to highlight selected cell
+ * @param navigationStrategy
+ * the strategy used to navigate the cells
+ */
+ public this(TreeViewer viewer,
+ FocusCellHighlighter focusDrawingDelegate,
+ CellNavigationStrategy navigationStrategy) {
+ super(viewer, focusDrawingDelegate, navigationStrategy);
}
override ViewerCell getInitialFocusCell() {
Tree tree = cast(Tree) getViewer().getControl();
- if( tree.getItemCount() > 0 ) {
+ if (tree.getItemCount() > 0) {
return getViewer().getViewerRowFromItem_package(tree.getItem(0)).getCell(0);
}
return null;
}
+
+ public ViewerCell getFocusCell() {
+ ViewerCell cell = super.getFocusCell();
+ Tree t = (Tree) getViewer().getControl();
+
+ // It is possible that the selection has changed under the hood
+ if (cell !is null) {
+ if (t.getSelection().length is 1
+ && t.getSelection()[0] !is cell.getItem()) {
+ setFocusCell(getViewer().getViewerRowFromItem(
+ t.getSelection()[0]).getCell(cell.getColumnIndex()));
+ }
+ }
+
+ return super.getFocusCell();
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/TreeViewerRow.d
--- a/dwtx/jface/viewers/TreeViewerRow.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/TreeViewerRow.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Schindl - initial API and implementation
- * - Fix for bug 174355, 171126
+ * - fix in bug: 174355,171126,,195908,198035,215069
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -34,6 +34,7 @@
/**
* TreeViewerRow is the Tree implementation of ViewerRow.
+ *
* @since 3.3
*
*/
@@ -42,98 +43,129 @@
/**
* Create a new instance of the receiver.
+ *
* @param item
*/
this(TreeItem item) {
this.item = item;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#getBounds(int)
*/
public override Rectangle getBounds(int columnIndex) {
return item.getBounds(columnIndex);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#getBounds()
*/
public override Rectangle getBounds() {
return item.getBounds();
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#getColumnCount()
*/
public override int getColumnCount() {
return item.getParent().getColumnCount();
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#getItem()
*/
public override Widget getItem() {
return item;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#getBackground(int)
*/
public override Color getBackground(int columnIndex) {
return item.getBackground(columnIndex);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#getFont(int)
*/
public override Font getFont(int columnIndex) {
return item.getFont(columnIndex);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#getForeground(int)
*/
public override Color getForeground(int columnIndex) {
return item.getForeground(columnIndex);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#getImage(int)
*/
public override Image getImage(int columnIndex) {
return item.getImage(columnIndex);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#getText(int)
*/
public override String getText(int columnIndex) {
return item.getText(columnIndex);
}
- /* (non-Javadoc)
- * @see dwtx.jface.viewers.ViewerRow#setBackground(int, dwt.graphics.Color)
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.ViewerRow#setBackground(int,
+ * dwt.graphics.Color)
*/
public override void setBackground(int columnIndex, Color color) {
item.setBackground(columnIndex, color);
}
- /* (non-Javadoc)
- * @see dwtx.jface.viewers.ViewerRow#setFont(int, dwt.graphics.Font)
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.ViewerRow#setFont(int,
+ * dwt.graphics.Font)
*/
public override void setFont(int columnIndex, Font font) {
item.setFont(columnIndex, font);
}
- /* (non-Javadoc)
- * @see dwtx.jface.viewers.ViewerRow#setForeground(int, dwt.graphics.Color)
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.ViewerRow#setForeground(int,
+ * dwt.graphics.Color)
*/
public override void setForeground(int columnIndex, Color color) {
item.setForeground(columnIndex, color);
}
- /* (non-Javadoc)
- * @see dwtx.jface.viewers.ViewerRow#setImage(int, dwt.graphics.Image)
+ /*
+ * (non-Javadoc)
+ *
+ * @see dwtx.jface.viewers.ViewerRow#setImage(int,
+ * dwt.graphics.Image)
*/
public override void setImage(int columnIndex, Image image) {
Image oldImage = item.getImage(columnIndex);
@@ -142,14 +174,18 @@
}
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#setText(int, java.lang.String)
*/
public override void setText(int columnIndex, String text) {
item.setText(columnIndex, text is null ? "" : text); //$NON-NLS-1$
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see dwtx.jface.viewers.ViewerRow#getControl()
*/
public override Control getControl() {
@@ -158,12 +194,13 @@
public override ViewerRow getNeighbor(int direction, bool sameLevel) {
- if( direction is ViewerRow.ABOVE ) {
+ if (direction is ViewerRow.ABOVE) {
return getRowAbove(sameLevel);
- } else if( direction is ViewerRow.BELOW ) {
+ } else if (direction is ViewerRow.BELOW) {
return getRowBelow(sameLevel);
} else {
- throw new IllegalArgumentException("Illegal value of direction argument."); //$NON-NLS-1$
+ throw new IllegalArgumentException(
+ "Illegal value of direction argument."); //$NON-NLS-1$
}
}
@@ -171,18 +208,18 @@
Tree tree = item.getParent();
// This means we have top-level item
- if( item.getParentItem() is null ) {
- if( sameLevel || ! item.getExpanded() ) {
+ if (item.getParentItem() is null) {
+ if (sameLevel || !item.getExpanded()) {
int index = tree.indexOf(item) + 1;
- if( index < tree.getItemCount() ) {
+ if (index < tree.getItemCount()) {
return new TreeViewerRow(tree.getItem(index));
}
- } else if( item.getExpanded() && item.getItemCount() > 0 ) {
+ } else if (item.getExpanded() && item.getItemCount() > 0) {
return new TreeViewerRow(item.getItem(0));
}
} else {
- if( sameLevel || ! item.getExpanded() ) {
+ if (sameLevel || !item.getExpanded()) {
TreeItem parentItem = item.getParentItem();
int nextIndex = parentItem.indexOf(item) + 1;
@@ -191,17 +228,17 @@
TreeItem itemAfter;
// This would mean that it was the last item
- if( nextIndex is totalIndex ) {
- itemAfter = findNextItem( parentItem );
+ if (nextIndex is totalIndex) {
+ itemAfter = findNextItem(parentItem);
} else {
itemAfter = parentItem.getItem(nextIndex);
}
- if( itemAfter !is null ) {
+ if (itemAfter !is null) {
return new TreeViewerRow(itemAfter);
}
- } else if( item.getExpanded() && item.getItemCount() > 0 ) {
+ } else if (item.getExpanded() && item.getItemCount() > 0) {
return new TreeViewerRow(item.getItem(0));
}
}
@@ -213,16 +250,16 @@
Tree tree = item.getParent();
// This means we have top-level item
- if( item.getParentItem() is null ) {
+ if (item.getParentItem() is null) {
int index = tree.indexOf(item) - 1;
TreeItem nextTopItem = null;
- if( index >= 0 ) {
+ if (index >= 0) {
nextTopItem = tree.getItem(index);
}
- if( nextTopItem !is null ) {
- if( sameLevel ) {
+ if (nextTopItem !is null) {
+ if (sameLevel) {
return new TreeViewerRow(nextTopItem);
}
@@ -233,17 +270,18 @@
int previousIndex = parentItem.indexOf(item) - 1;
TreeItem itemBefore;
- if( previousIndex >= 0 ) {
- if( sameLevel ) {
+ if (previousIndex >= 0) {
+ if (sameLevel) {
itemBefore = parentItem.getItem(previousIndex);
} else {
- itemBefore = findLastVisibleItem(parentItem.getItem(previousIndex));
+ itemBefore = findLastVisibleItem(parentItem
+ .getItem(previousIndex));
}
} else {
itemBefore = parentItem;
}
- if( itemBefore !is null ) {
+ if (itemBefore !is null) {
return new TreeViewerRow(itemBefore);
}
}
@@ -254,8 +292,8 @@
private TreeItem findLastVisibleItem(TreeItem parentItem) {
TreeItem rv = parentItem;
- while( rv.getExpanded() && rv.getItemCount() > 0 ) {
- rv = rv.getItem(rv.getItemCount()-1);
+ while (rv.getExpanded() && rv.getItemCount() > 0) {
+ rv = rv.getItem(rv.getItemCount() - 1);
}
return rv;
@@ -269,7 +307,7 @@
int nextIndex;
int totalItems;
- if( parentItem is null ) {
+ if (parentItem is null) {
nextIndex = tree.indexOf(item) + 1;
totalItems = tree.getItemCount();
} else {
@@ -279,12 +317,12 @@
// This is once more the last item in the tree
// Search on
- if( nextIndex is totalItems ) {
- if( item.getParentItem() !is null ) {
+ if (nextIndex is totalItems) {
+ if (item.getParentItem() !is null) {
rv = findNextItem(item.getParentItem());
}
} else {
- if( parentItem is null ) {
+ if (parentItem is null) {
rv = tree.getItem(nextIndex);
} else {
rv = parentItem.getItem(nextIndex);
@@ -318,4 +356,45 @@
public override Object getElement() {
return item.getData();
}
+
+ public int getVisualIndex(int creationIndex) {
+ int[] order = item.getParent().getColumnOrder();
+
+ for (int i = 0; i < order.length; i++) {
+ if (order[i] is creationIndex) {
+ return i;
+ }
+ }
+
+ return super.getVisualIndex(creationIndex);
+ }
+
+ public int getCreationIndex(int visualIndex) {
+ if( item !is null && ! item.isDisposed() && hasColumns() && isValidOrderIndex(visualIndex) ) {
+ return item.getParent().getColumnOrder()[visualIndex];
+ }
+ return super.getCreationIndex(visualIndex);
+ }
+
+ /* (non-Javadoc)
+ * @see dwtx.jface.viewers.ViewerRow#getTextBounds(int)
+ */
+ public Rectangle getTextBounds(int index) {
+ return item.getTextBounds(index);
+ }
+
+ /* (non-Javadoc)
+ * @see dwtx.jface.viewers.ViewerRow#getImageBounds(int)
+ */
+ public Rectangle getImageBounds(int index) {
+ return item.getImageBounds(index);
+ }
+
+ private bool hasColumns() {
+ return this.item.getParent().getColumnCount() !is 0;
+ }
+
+ private bool isValidOrderIndex(int currentIndex) {
+ return currentIndex < this.item.getParent().getColumnOrder().length;
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ViewerCell.d
--- a/dwtx/jface/viewers/ViewerCell.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ViewerCell.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -7,13 +7,15 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Tom Shindl - initial API and implementation
+ * Tom Schindl - initial API and implementation
+ * - fix in bug: 195908,198035,215069,215735
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
module dwtx.jface.viewers.ViewerCell;
+import dwt.custom.StyleRange;
import dwtx.jface.viewers.ViewerRow;
import dwt.graphics.Color;
@@ -59,6 +61,7 @@
*/
public static int RIGHT = 1 << 3;
+
/**
* Create a new instance of the receiver on the row.
*
@@ -98,7 +101,12 @@
if (element !is null) {
return element;
}
- return row.getElement();
+
+ if (row !is null) {
+ return row.getElement();
+ }
+
+ return null;
}
/**
@@ -168,6 +176,31 @@
row.setImage(columnIndex, image);
}
+
+ /**
+ * Set the style ranges to be applied on the text label
+ * Note: Requires {@link StyledCellLabelProvider} with owner draw enabled.
+ *
+ * @param styleRanges the styled ranges
+ *
+ * @since 3.4
+ */
+ public void setStyleRanges(StyleRange[] styleRanges) {
+ row.setStyleRanges(columnIndex, styleRanges);
+ }
+
+
+ /**
+ * Returns the style ranges to be applied on the text label or null
if no
+ * style ranges have been set.
+ *
+ * @return styleRanges the styled ranges
+ *
+ * @since 3.4
+ */
+ public StyleRange[] getStyleRanges() {
+ return row.getStyleRanges(columnIndex);
+ }
/**
* Set the columnIndex.
@@ -210,6 +243,17 @@
}
/**
+ * Get the current index. This can be different from the original index when
+ * columns are reordered
+ *
+ * @return the current index (as shown in the UI)
+ * @since 3.4
+ */
+ public int getVisualIndex() {
+ return row.getVisualIndex(getColumnIndex());
+ }
+
+ /**
* Returns the specified neighbor of this cell, or null
if no
* neighbor exists in the given direction. Direction constants can be
* combined by bitwise OR; for example, this method will return the cell to
@@ -226,7 +270,6 @@
*/
public ViewerCell getNeighbor(int directionMask, bool sameLevel) {
ViewerRow row;
- int columnIndex;
if ((directionMask & ABOVE) is ABOVE) {
row = this.row.getNeighbor(ViewerRow.ABOVE, sameLevel);
@@ -237,16 +280,36 @@
}
if (row !is null) {
+ int columnIndex;
+ columnIndex = getVisualIndex();
+
+ int modifier = 0;
+
if ((directionMask & LEFT) is LEFT) {
- columnIndex = getColumnIndex() - 1;
+ modifier = -1;
} else if ((directionMask & RIGHT) is RIGHT) {
- columnIndex = getColumnIndex() + 1;
- } else {
- columnIndex = getColumnIndex();
+ modifier = 1;
}
+ columnIndex += modifier;
+
if (columnIndex >= 0 && columnIndex < row.getColumnCount()) {
- return row.getCell(columnIndex);
+ ViewerCell cell = row.getCellAtVisualIndex(columnIndex);
+ if( cell !is null ) {
+ while( cell !is null ) {
+ if( cell.isVisible() ) {
+ break;
+ }
+
+ columnIndex += modifier;
+ cell = row.getCellAtVisualIndex(columnIndex);
+ if( cell is null ) {
+ break;
+ }
+ }
+ }
+
+ return cell;
}
}
@@ -260,7 +323,67 @@
return row;
}
- /* (non-Javadoc)
+ /**
+ * The location and bounds of the area where the text is drawn depends on
+ * various things (image displayed, control with DWT.CHECK)
+ *
+ * @return The bounds of the of the text area. May return null
+ * if the underlying widget implementation doesn't provide this
+ * information
+ * @since 3.4
+ */
+ public Rectangle getTextBounds() {
+ return row.getTextBounds(columnIndex);
+ }
+
+ /**
+ * Returns the location and bounds of the area where the image is drawn
+ *
+ * @return The bounds of the of the image area. May return null
+ * if the underlying widget implementation doesn't provide this
+ * information
+ * @since 3.4
+ */
+ public Rectangle getImageBounds() {
+ return row.getImageBounds(columnIndex);
+ }
+
+ /**
+ * Gets the foreground color of the cell.
+ *
+ * @return the foreground of the cell or null
for the default foreground
+ *
+ * @since 3.4
+ */
+ public Color getForeground() {
+ return row.getForeground(columnIndex);
+ }
+
+ /**
+ * Gets the background color of the cell.
+ *
+ * @return the background of the cell or null
for the default background
+ *
+ * @since 3.4
+ */
+ public Color getBackground() {
+ return row.getBackground(columnIndex);
+ }
+
+ /**
+ * Gets the font of the cell.
+ *
+ * @return the font of the cell or null
for the default font
+ *
+ * @since 3.4
+ */
+ public Font getFont() {
+ return row.getFont(columnIndex);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
* @see java.lang.Object#hashCode()
*/
public override hash_t toHash() {
@@ -271,7 +394,9 @@
return result;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
public override int opEquals(Object obj) {
@@ -291,4 +416,8 @@
return false;
return true;
}
+
+ private bool isVisible() {
+ return getBounds().width > 0;
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ViewerColumn.d
--- a/dwtx/jface/viewers/ViewerColumn.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ViewerColumn.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Shindl - initial API and implementation
- * fix for bug 163317,200558
+ * fix for bug 163317, 201905
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -34,9 +34,9 @@
* providers and editing support can be configured for each column separately.
* Concrete subclasses of {@link ColumnViewer} should implement a matching
* concrete subclass of {@link ViewerColumn}.
- *
+ *
* @since 3.3
- *
+ *
*/
public abstract class ViewerColumn {
@@ -50,9 +50,11 @@
private bool listenerRegistered = false;
+ private ColumnViewer viewer;
+
/**
* Create a new instance of the receiver at columnIndex.
- *
+ *
* @param viewer
* the viewer the column is part of
* @param columnOwner
@@ -60,6 +62,7 @@
* this could be the widget itself
*/
protected this(ColumnViewer viewer, Widget columnOwner) {
+ this.viewer = viewer;
columnOwner.setData(ViewerColumn.COLUMN_VIEWER_KEY, this);
this.listener = new class(viewer) ILabelProviderListener {
ColumnViewer viewer_;
@@ -84,7 +87,7 @@
/**
* Return the label provider for the receiver.
- *
+ *
* @return ViewerLabelProvider
*/
/* package */CellLabelProvider getLabelProvider() {
@@ -94,7 +97,7 @@
/**
* Set the label provider for the column. Subclasses may extend but must
* call the super implementation.
- *
+ *
* @param labelProvider
* the new {@link CellLabelProvider}
*/
@@ -111,11 +114,15 @@
if (listenerRegistered && this.labelProvider !is null) {
this.labelProvider.removeListener(listener);
listenerRegistered = false;
+ if (registerListener) {
+ this.labelProvider.dispose(viewer, this);
+ }
}
this.labelProvider = labelProvider;
if (registerListener) {
+ this.labelProvider.initialize(viewer, this);
this.labelProvider.addListener(listener);
listenerRegistered = true;
}
@@ -123,7 +130,7 @@
/**
* Return the editing support for the receiver.
- *
+ *
* @return {@link EditingSupport}
*/
/* package */EditingSupport getEditingSupport() {
@@ -133,7 +140,10 @@
/**
* Set the editing support. Subclasses may extend but must call the super
* implementation.
- *
+ *
+ * Users setting up an editable {@link TreeViewer} or {@link TableViewer} with more than 1 column have
+ * to pass the DWT.FULL_SELECTION style bit when creating the viewer
+ *
* @param editingSupport
* The {@link EditingSupport} to set.
*/
@@ -145,7 +155,7 @@
* Refresh the cell for the given columnIndex. NOTE:the
* {@link ViewerCell} provided to this method is no longer valid after this
* method returns. Do not cache the cell for future use.
- *
+ *
* @param cell
* {@link ViewerCell}
*/
@@ -164,14 +174,26 @@
CellLabelProvider cellLabelProvider = labelProvider;
setLabelProvider(null, false);
if (disposeLabelProvider) {
- cellLabelProvider.dispose();
+ cellLabelProvider.dispose(viewer, this);
}
editingSupport = null;
listener = null;
+ viewer = null;
}
private void handleDispose(ColumnViewer viewer) {
handleDispose();
viewer.clearLegacyEditingSetup();
}
+
+ /**
+ * Returns the viewer of this viewer column.
+ *
+ * @return Returns the viewer.
+ *
+ * @since 3.4
+ */
+ public ColumnViewer getViewer() {
+ return viewer;
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ViewerDropAdapter.d
--- a/dwtx/jface/viewers/ViewerDropAdapter.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ViewerDropAdapter.d Thu May 22 01:36:46 2008 +0200
@@ -109,11 +109,17 @@
/**
* A flag that allows adapter users to turn auto scrolling
- * and expanding on or off. Default is true
.
+ * on or off. Default is true
.
*/
- private bool scrollExpandEnabled = true;
+ private bool scrollEnabled = true;
/**
+ * A flag that allows adapter users to turn auto
+ * expanding on or off. Default is true
.
+ */
+ private bool expandEnabled = true;
+
+ /**
* A flag that allows adapter users to turn selection feedback
* on or off. Default is true
.
*/
@@ -401,8 +407,11 @@
event.feedback &= ~DND.FEEDBACK_SELECT;
}
- if (scrollExpandEnabled) {
- event.feedback |= DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL;
+ if (expandEnabled) {
+ event.feedback |= DND.FEEDBACK_EXPAND;
+ }
+ if (scrollEnabled) {
+ event.feedback |= DND.FEEDBACK_SCROLL;
}
}
@@ -441,7 +450,30 @@
* @since 2.0
*/
public void setScrollExpandEnabled(bool value) {
- scrollExpandEnabled = value;
+ expandEnabled = value;
+ scrollEnabled = value;
+ }
+
+ /**
+ * Sets whether auto expanding should be provided during dragging.
+ *
+ * @param value true
if expanding is desired, and
+ * false
if not
+ * @since 3.4
+ */
+ public void setExpandEnabled(bool value) {
+ expandEnabled = value;
+ }
+
+ /**
+ * Sets whether auto scrolling should be provided during dragging.
+ *
+ * @param value true
if scrolling is desired, and
+ * false
if not
+ * @since 3.4
+ */
+ public void setScrollEnabled(bool value) {
+ scrollEnabled = value;
}
/**
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/ViewerRow.d
--- a/dwtx/jface/viewers/ViewerRow.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/ViewerRow.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -7,9 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Tom Shindl - initial API and implementation
- * fix for bug 166346, bug 167325s
- * - Fix for bug 174355
+ * Tom Schindl - initial API and implementation
+ * - fix in bug: 166346,167325,174355,195908,198035,215069
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -20,6 +19,7 @@
import dwtx.jface.viewers.ViewerRow;
import dwtx.jface.viewers.TreePath;
+import dwt.custom.StyleRange;
import dwt.graphics.Color;
import dwt.graphics.Font;
import dwt.graphics.Image;
@@ -27,6 +27,7 @@
import dwt.graphics.Rectangle;
import dwt.widgets.Control;
import dwt.widgets.Widget;
+import dwtx.jface.util.Policy;
import dwt.dwthelper.utils;
@@ -53,6 +54,8 @@
* @see #getNeighbor(int, bool)
*/
public static const int BELOW = 2;
+
+ private static final String KEY_TEXT_LAYOUT = Policy.JFACE + "styled_label_key_"; //$NON-NLS-1$
/**
* Get the bounds of the entry at the columnIndex,
@@ -270,4 +273,107 @@
return true;
}
+ /**
+ * The cell at the current index (as shown in the UI). This can be different
+ * to the original index when columns are reordered.
+ *
+ * @param visualIndex
+ * the current index (as shown in the UI)
+ * @return the cell at the currently visible index
+ */
+ ViewerCell getCellAtVisualIndex(int visualIndex) {
+ return getCell(getCreationIndex(visualIndex));
+ }
+
+ /**
+ * Translate the original column index to the actual one.
+ *
+ * Because of backwards API compatibility the default implementation
+ * returns the original index. Implementators of {@link ColumnViewer} should
+ * overwrite this method if their widget supports reordered columns
+ *
+ *
+ * @param creationIndex
+ * the original index
+ * @return the current index (as shown in the UI)
+ * @since 3.4
+ */
+ protected int getVisualIndex(int creationIndex) {
+ return creationIndex;
+ }
+
+ /**
+ * Translate the current column index (as shown in the UI) to the original
+ * one.
+ *
+ * Because of backwards API compatibility the default implementation
+ * returns the original index. Implementators of {@link ColumnViewer} should
+ * overwrite this method if their widget supports reordered columns
+ *
+ *
+ * @param visualIndex
+ * the current index (as shown in the UI)
+ * @return the original index
+ * @since 3.4
+ */
+ protected int getCreationIndex(int visualIndex) {
+ return visualIndex;
+ }
+
+ /**
+ * The location and bounds of the area where the text is drawn depends on
+ * various things (image displayed, control with DWT.CHECK)
+ *
+ * @param index
+ * the column index
+ * @return the bounds of the of the text area. May return null
+ * if the underlying widget implementation doesn't provide this
+ * information
+ * @since 3.4
+ */
+ public Rectangle getTextBounds(int index) {
+ return null;
+ }
+
+
+ /**
+ * Returns the location and bounds of the area where the image is drawn.
+ *
+ * @param index
+ * the column index
+ * @return the bounds of the of the image area. May return null
+ * if the underlying widget implementation doesn't provide this
+ * information
+ * @since 3.4
+ */
+ public Rectangle getImageBounds(int index) {
+ return null;
+ }
+
+ /**
+ * Set the style ranges to be applied on the text label at the column index
+ * Note: Requires {@link StyledCellLabelProvider} with owner draw enabled.
+ *
+ * @param columnIndex the index of the column
+ * @param styleRanges the styled ranges
+ *
+ * @since 3.4
+ */
+ public void setStyleRanges(int columnIndex, StyleRange[] styleRanges) {
+ getItem().setData(KEY_TEXT_LAYOUT + columnIndex, styleRanges);
+ }
+
+
+ /**
+ * Returns the style ranges to be applied on the text label at the column index or null
if no
+ * style ranges have been set.
+ *
+ * @param columnIndex the index of the column
+ * @return styleRanges the styled ranges
+ *
+ * @since 3.4
+ */
+ public StyleRange[] getStyleRanges(int columnIndex) {
+ return (StyleRange[]) getItem().getData(KEY_TEXT_LAYOUT + columnIndex);
+ }
}
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/viewers/deferred/DeferredContentProvider.d
--- a/dwtx/jface/viewers/deferred/DeferredContentProvider.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/viewers/deferred/DeferredContentProvider.d Thu May 22 01:36:46 2008 +0200
@@ -17,6 +17,7 @@
import dwtx.jface.viewers.deferred.BackgroundContentProvider;
import dwtx.jface.viewers.deferred.IConcurrentModel;
+import dwt.graphics.Rectangle;
import dwt.widgets.Control;
import dwt.widgets.Table;
import dwtx.core.runtime.Assert;
@@ -104,11 +105,11 @@
* @see dwtx.jface.viewers.deferred.AbstractVirtualTable#getVisibleItemCount()
*/
public override int getVisibleItemCount() {
- int start = getTopIndex();
- int itemCount = getItemCount();
Table table = viewer.getTable();
- return Math.min(table.getBounds().height / table.getItemHeight() + 2,
- itemCount - start);
+ Rectangle rect = table.getClientArea ();
+ int itemHeight = table.getItemHeight ();
+ int headerHeight = table.getHeaderHeight ();
+ return (rect.height - headerHeight + itemHeight - 1) / (itemHeight + table.getGridLineWidth());
}
/* (non-Javadoc)
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/window/ToolTip.d
--- a/dwtx/jface/window/ToolTip.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/window/ToolTip.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* Tom Schindl - initial API and implementation
+ * bugfix in: 195137, 198089, 225190
* Port to the D programming language:
* Frank Benoit
*******************************************************************************/
@@ -23,6 +24,7 @@
import dwt.layout.FillLayout;
import dwt.widgets.Composite;
import dwt.widgets.Control;
+import dwt.widgets.Display;
import dwt.widgets.Event;
import dwt.widgets.Listener;
import dwt.widgets.Monitor;
@@ -69,6 +71,8 @@
private TooltipHideListener hideListener;
+ private Listener shellListener;
+
private bool hideOnMouseDown = true;
private bool respectDisplayBounds = true;
@@ -79,6 +83,8 @@
private Object currentArea;
+ private static final bool IS_OSX = DWT.getPlatform().equals("carbon"); //$NON-NLS-1$
+
/**
* Create new instance which add TooltipSupport to the widget
*
@@ -93,7 +99,7 @@
* @param control
* the control to which the tooltip is bound
* @param style
- * style passed to control tooltip behaviour
+ * style passed to control tooltip behavior
*
* @param manualActivation
* true
if the activation is done manually using
@@ -108,12 +114,29 @@
this.control.addDisposeListener(new class DisposeListener {
public void widgetDisposed(DisposeEvent e) {
+ data = null;
deactivate();
}
});
this.listener = new ToolTipOwnerControlListener();
+ this.shellListener = new Listener() {
+ public void handleEvent(final Event event) {
+ if( ToolTip.this.control !is null && ! ToolTip.this.control.isDisposed() ) {
+ ToolTip.this.control.getDisplay().asyncExec(new Runnable() {
+
+ public void run() {
+ // Check if the new active shell is the tooltip itself
+ if( ToolTip.this.control.getDisplay().getActiveShell() !is CURRENT_TOOLTIP) {
+ toolTipHide(CURRENT_TOOLTIP, event);
+ }
+ }
+
+ });
+ }
+ }
+ };
if (!manualActivation) {
activate();
@@ -296,8 +319,8 @@
* the event
* @return the area responsible for the tooltip creation or
* null
this could be any object describing the area
- * (e.g. the {@link Control} onto which the tooltip is bound to, a part of
- * this area e.g. for {@link ColumnViewer} this could be a
+ * (e.g. the {@link Control} onto which the tooltip is bound to, a
+ * part of this area e.g. for {@link ColumnViewer} this could be a
* {@link ViewerCell})
*/
protected Object getToolTipArea(Event event) {
@@ -343,8 +366,18 @@
}
tip.pack();
- tip.setLocation(fixupDisplayBounds(tip.getSize(), getLocation(tip
- .getSize(), event)));
+ Point size = tip.getSize();
+ Point location = fixupDisplayBounds(size, getLocation(size, event));
+
+ // Need to adjust a bit more if the mouse cursor.y is tip.y and
+ // the cursor.x is inside the tip
+ Point cursorLocation = tip.getDisplay().getCursorLocation();
+
+ if( cursorLocation.y is location.y && location.x < cursorLocation.x && location.x + size.x > cursorLocation.x ) {
+ location.y -= 2;
+ }
+
+ tip.setLocation(location);
tip.setVisible(true);
}
}
@@ -377,12 +410,12 @@
}
if (!(bounds.contains(location) && bounds.contains(rightBounds))) {
- if (rightBounds.x > bounds.width) {
- location.x -= rightBounds.x - bounds.width;
+ if (rightBounds.x > bounds.x + bounds.width) {
+ location.x -= rightBounds.x - (bounds.x + bounds.width);
}
- if (rightBounds.y > bounds.height) {
- location.y -= rightBounds.y - bounds.height;
+ if (rightBounds.y > bounds.y + bounds.height) {
+ location.y -= rightBounds.y - (bounds.y + bounds.height);
}
if (location.x < bounds.x) {
@@ -414,13 +447,65 @@
private void toolTipHide(Shell tip, Event event) {
if (tip !is null && !tip.isDisposed() && shouldHideToolTip(event)) {
+ control.getShell().removeListener(DWT.Deactivate, shellListener);
currentArea = null;
+ passOnEvent(tip,event);
tip.dispose();
CURRENT_TOOLTIP = null;
afterHideToolTip(event);
}
}
+ private void passOnEvent(Shell tip,Event event) {
+ if ( control !is null && ! control.isDisposed() && event !is null && event.widget !is control && event.type is DWT.MouseDown) {
+ final Display display = control.getDisplay();
+ Point newPt = display.map(tip, null, new Point(event.x, event.y));
+
+ final Event newEvent = new Event();
+ newEvent.button=event.button;
+ newEvent.character=event.character;
+ newEvent.count = event.count;
+ newEvent.data=event.data;
+ newEvent.detail=event.detail;
+ newEvent.display=event.display;
+ newEvent.doit=event.doit;
+ newEvent.end=event.end;
+ newEvent.gc=event.gc;
+ newEvent.height=event.height;
+ newEvent.index=event.index;
+ newEvent.item=event.item;
+ newEvent.keyCode=event.keyCode;
+ newEvent.start=event.start;
+ newEvent.stateMask=event.stateMask;
+ newEvent.text=event.text;
+ newEvent.time=event.time;
+ newEvent.type=event.type;
+ newEvent.widget=event.widget;
+ newEvent.width=event.width;
+ newEvent.x = newPt.x;
+ newEvent.y = newPt.y;
+
+ tip.close();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if( IS_OSX ) {
+ try {
+ Thread.sleep(300);
+ } catch (InterruptedException e) {
+
+ }
+
+ display.post(newEvent);
+ newEvent.type = DWT.MouseUp;
+ display.post(newEvent);
+ } else {
+ display.post(newEvent);
+ }
+ }
+ });
+ }
+ }
+
private void toolTipOpen(Shell shell, Event event) {
// Ensure that only one Tooltip is shown in time
if (CURRENT_TOOLTIP !is null) {
@@ -429,6 +514,8 @@
CURRENT_TOOLTIP = shell;
+ control.getShell().addListener(DWT.Deactivate, shellListener);
+
if (popupDelay > 0) {
control.getDisplay().timerExec(popupDelay, new class(shell,event) Runnable {
Shell shell_;
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/window/Window.d
--- a/dwtx/jface/window/Window.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/window/Window.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -328,6 +328,11 @@
* This framework method may be extended (super.close
must
* be called).
*
+ *
+ * Note that in order to prevent recursive calls to this method
+ * it does not call Shell#close()
. As a result ShellListener
s
+ * will not receive a shellClosed
event.
+ *
*
* @return true
if the window is (or was already) closed, and
* false
if it is still open
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/wizard/ProgressMonitorPart.d
--- a/dwtx/jface/wizard/ProgressMonitorPart.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/wizard/ProgressMonitorPart.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 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
@@ -59,13 +59,13 @@
/** the cancel component */
protected Control fCancelComponent;
- /** true if cancled */
+ /** true if canceled */
protected bool fIsCanceled;
/** current blocked status */
protected IStatus blockedStatus;
- /** the cancle lister attached to the cancle component */
+ /** the cancel lister attached to the cancel component */
protected Listener fCancelListener;
private void init_fCancelListener(){
fCancelListener = new class Listener {
@@ -165,9 +165,9 @@
/**
* Creates the progress monitor's UI parts and layouts them
- * according to the given layout. If the layou is null
+ * according to the given layout. If the layout is null
* the part's default layout is used.
- * @param layout The layoutfor the receiver.
+ * @param layout The layout for the receiver.
* @param progressIndicatorHeight The suggested height of the indicator
*/
protected void initialize(Layout layout, int progressIndicatorHeight) {
@@ -281,12 +281,21 @@
* @return String
*/
private String taskLabel() {
- String text = fSubTaskName is null ? "" : fSubTaskName; //$NON-NLS-1$
- if (fTaskName !is null && fTaskName.length > 0) {
- text = JFaceResources.format(
- "Set_SubTask", [ fTaskName, text ]);//$NON-NLS-1$
+ bool hasTask= fTaskName !is null && fTaskName.length() > 0;
+ bool hasSubtask= fSubTaskName !is null && fSubTaskName.length > 0;
+
+ if (hasTask) {
+ if (hasSubtask)
+ return escapeMetaCharacters(JFaceResources.format(
+ "Set_SubTask", new Object[] { fTaskName, fSubTaskName }));//$NON-NLS-1$
+ return escapeMetaCharacters(fTaskName);
+
+ } else if (hasSubtask) {
+ return escapeMetaCharacters(fSubTaskName);
+
+ } else {
+ return ""; //$NON-NLS-1$
}
- return escapeMetaCharacters(text);
}
/**
diff -r 07b9d96fd764 -r 46a6e0e6ccd4 dwtx/jface/wizard/WizardDialog.d
--- a/dwtx/jface/wizard/WizardDialog.d Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/wizard/WizardDialog.d Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -888,14 +888,14 @@
* the control
* @param h
* the map (key type: String
, element type:
- * bool
)
+ * Boolean
)
* @param key
* the key
* @see #saveEnableStateAndSet
*/
private void restoreEnableState(Control w, Map!(Object,Object) h, String key) {
if (w !is null) {
- auto b = cast(Boolean) h.get(stringcast(key));
+ Boolean b = (Boolean) h.get(stringcast(key));
if (b !is null) {
w.setEnabled(b.booleanValue());
}
@@ -972,7 +972,7 @@
* the control, or null
if none
* @param h
* the map (key type: String
, element type:
- * bool
)
+ * Boolean
)
* @param key
* the key
* @param enabled
@@ -1220,7 +1220,7 @@
* @see #aboutToStart
*/
private void stopped(Object savedState) {
- if (getShell() !is null) {
+ if (getShell() !is null && !getShell().isDisposed()) {
if (wizard.needsProgressMonitor()) {
progressMonitorPart.setVisible(false);
progressMonitorPart.removeFromCancelComponent(cancelButton);
@@ -1235,7 +1235,7 @@
arrowCursor.dispose();
arrowCursor = null;
Control focusControl = cast(Control) state.get(stringcast(FOCUS_CONTROL));
- if (focusControl !is null) {
+ if (focusControl !is null && !focusControl.isDisposed()) {
focusControl.setFocus();
}
}